M new/include/viua/arch/ins.h => new/include/viua/arch/ins.h +6 -6
@@ 240,12 240,6 @@ struct STRING : Instruction {
STRING(viua::arch::ops::S i) : instruction{i}
{}
};
-struct FLOAT : Instruction {
- viua::arch::ops::S instruction;
-
- FLOAT(viua::arch::ops::S i) : instruction{i}
- {}
-};
struct DOUBLE : Instruction {
viua::arch::ops::S instruction;
@@ 277,6 271,12 @@ struct LLI : Instruction {
LLI(viua::arch::ops::F i) : instruction{i}
{}
};
+struct FLOAT : Instruction {
+ viua::arch::ops::F instruction;
+
+ FLOAT(viua::arch::ops::F i) : instruction{i}
+ {}
+};
struct CAST : Instruction {
viua::arch::ops::E instruction;
M new/include/viua/arch/ops.h => new/include/viua/arch/ops.h +7 -7
@@ 269,13 269,13 @@ enum class OPCODE : opcode_type {
FRAME = (FORMAT_S | 0x0001),
RETURN = (FORMAT_S | 0x0002),
ATOM = (FORMAT_S | 0x0003),
- FLOAT = (FORMAT_S | 0x0004),
- DOUBLE = (FORMAT_S | 0x0005),
- SELF = (FORMAT_S | 0x0006),
+ DOUBLE = (FORMAT_S | 0x0004),
+ SELF = (FORMAT_S | 0x0005),
- LUI = (FORMAT_F | 0x0001),
- LUIU = (FORMAT_F | 0x0001 | UNSIGNED),
- LLI = (FORMAT_F | 0x0002),
+ LUI = (FORMAT_F | 0x0001),
+ LUIU = (FORMAT_F | 0x0001 | UNSIGNED),
+ LLI = (FORMAT_F | 0x0002),
+ FLOAT = (FORMAT_F | 0x0003),
CAST = (FORMAT_E | 0x0001),
ARODP = (FORMAT_E | 0x0002),
@@ 345,7 345,6 @@ enum class OPCODE_S : opcode_type {
Make_entry(FRAME),
Make_entry(RETURN),
Make_entry(ATOM),
- Make_entry(FLOAT),
Make_entry(DOUBLE),
Make_entry(SELF),
};
@@ 353,6 352,7 @@ enum class OPCODE_F : opcode_type {
Make_entry(LUI),
Make_entry(LUIU),
Make_entry(LLI),
+ Make_entry(FLOAT),
};
enum class OPCODE_E : opcode_type {
Make_entry(CAST),
M new/src/arch/ops.cpp => new/src/arch/ops.cpp +12 -3
@@ 17,6 17,8 @@
* along with Viua VM. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <string.h>
+
#include <stdexcept>
#include <string>
#include <string_view>
@@ 116,20 118,27 @@ auto F::decode(instruction_type const raw) -> F
auto opcode =
static_cast<viua::arch::opcode_type>(raw & 0x000000000000ffff);
auto out = Register_access::decode((raw & 0x00000000ffff0000) >> 16);
- auto value = static_cast<uint32_t>(raw >> 32);
+ auto value = le32toh(static_cast<uint32_t>(raw >> 32));
return F{opcode, out, value};
}
auto F::encode() const -> instruction_type
{
auto base = uint64_t{opcode};
auto output_register = uint64_t{out.encode()};
- auto value = uint64_t{immediate};
+ auto value = uint64_t{htole32(immediate)};
return base | (output_register << 16) | (value << 32);
}
auto F::to_string() const -> std::string
{
+ auto imm_str = std::to_string(immediate);
+ using viua::arch::ops::OPCODE;
+ if (static_cast<OPCODE>(opcode) == OPCODE::FLOAT) {
+ auto tmp = float{};
+ memcpy(&tmp, &immediate, sizeof(immediate));
+ imm_str = std::to_string(tmp);
+ }
return (viua::arch::ops::to_string(opcode) + " " + out.to_string() + ", "
- + std::to_string(immediate));
+ + imm_str);
}
} // namespace viua::arch::ops
namespace viua::arch::ops {
M new/src/tools/exec/dis.cpp => new/src/tools/exec/dis.cpp +0 -13
@@ 245,19 245,6 @@ auto demangle_symbol_load(Cooked_text& raw,
++i;
return;
}
- if (m(i + 1, FLOAT) and S::decode(ins_at(i + 1)).out == out) {
- auto ins = raw.at(i + 1);
- cooked.pop_back();
-
- auto const sv = view_data(rodata, immediate);
- auto x = float{};
- memcpy(&x, sv.data(), sizeof(x));
-
- cooked.emplace_back(ins.with_text(
- ("float " + out.to_string() + ", " + std::to_string(x))));
- ++i;
- return;
- }
if (m(i + 1, DOUBLE) and S::decode(ins_at(i + 1)).out == out) {
auto ins = raw.at(i + 1);
cooked.pop_back();
M new/src/tools/libs/stage.cpp => new/src/tools/libs/stage.cpp +10 -28
@@ 675,28 675,6 @@ auto cook_long_immediates(viua::libs::parser::ast::Instruction insn,
std::to_string(saved_at) + 'u';
cooked.push_back(synth);
- } else if (insn.opcode == "float" or insn.opcode == "g.float") {
- constexpr auto SIZE_OF_SINGLE_PRECISION_FLOAT = size_t{4};
- auto f = std::stof(insn.operands.back().ingredients.front().text);
- auto s = std::string(SIZE_OF_SINGLE_PRECISION_FLOAT, '\0');
- memcpy(s.data(), &f, SIZE_OF_SINGLE_PRECISION_FLOAT);
- auto const saved_at = save_buffer_to_rodata(rodata_buf, s);
-
- auto synth = viua::libs::parser::ast::Instruction{};
- {
- synth.opcode = insn.opcode;
- synth.opcode.text = "g.li";
- synth.physical_index = insn.physical_index;
-
- synth.operands.push_back(insn.operands.front());
- synth.operands.push_back(insn.operands.back());
- synth.operands.back().ingredients.front().text =
- std::to_string(saved_at) + 'u';
- }
- expand_li(cooked, synth, true);
-
- insn.operands.pop_back();
- cooked.push_back(std::move(insn));
} else if (insn.opcode == "double" or insn.opcode == "g.double") {
constexpr auto SIZE_OF_DOUBLE_PRECISION_FLOAT = size_t{8};
auto f = std::stod(insn.operands.back().ingredients.front().text);
@@ 1352,6 1330,7 @@ auto emit_instruction(viua::libs::parser::ast::Instruction const insn)
{
using viua::arch::opcode_type;
using viua::arch::ops::FORMAT;
+ using viua::arch::ops::OPCODE;
using viua::arch::ops::FORMAT_MASK;
auto opcode = opcode_type{};
@@ 1384,14 1363,17 @@ auto emit_instruction(viua::libs::parser::ast::Instruction const insn)
operand_or_throw(insn, 0).make_access()}
.encode();
case FORMAT::F:
+ {
+ auto const raw = operand_or_throw(insn, 1).ingredients.front().text;
+ auto val = static_cast<uint32_t>(std::stoul(raw, nullptr, 0));
+ if (static_cast<OPCODE>(opcode) == OPCODE::FLOAT) {
+ auto tmp = std::stof(raw);
+ memcpy(&val, &tmp, sizeof(val));
+ }
return viua::arch::ops::F{
- opcode,
- operand_or_throw(insn, 0).make_access(),
- static_cast<uint32_t>(
- std::stoul(operand_or_throw(insn, 1).ingredients.front().text,
- nullptr,
- 0))}
+ opcode, operand_or_throw(insn, 0).make_access(), val}
.encode();
+ }
case FORMAT::E:
return viua::arch::ops::E{
opcode,
M new/src/vm/ins.cpp => new/src/vm/ins.cpp +5 -20
@@ 118,7 118,6 @@ auto execute(viua::vm::Stack& stack,
Work(FRAME);
Flow(RETURN);
Work(ATOM);
- Work(FLOAT);
Work(DOUBLE);
Work(SELF);
#undef Work
@@ 143,6 142,7 @@ auto execute(viua::vm::Stack& stack,
Work(LUI);
Work(LUIU);
Work(LLI);
+ Work(FLOAT);
#undef Work
}
break;
@@ 1148,30 1148,15 @@ auto execute(ARODP const op, Stack& stack, ip_type const) -> void
auto execute(FLOAT const op, Stack& stack, ip_type const) -> void
{
- auto target = mutable_proxy(stack, op.instruction.out);
-
- auto const& strtab = *stack.proc->strtab;
-
- auto const data_offset = target.get<uint64_t>();
- if (not data_offset.has_value()) {
- throw abort_execution{stack, "invalid operand"};
- }
-
- auto const data_size = [&strtab, data_offset]() -> uint64_t {
- auto const size_offset = (*data_offset - sizeof(uint64_t));
- auto tmp = uint64_t{};
- memcpy(&tmp, &strtab[size_offset], sizeof(uint64_t));
- return le64toh(tmp);
- }();
+ auto out = mutable_proxy(stack, op.instruction.out);
auto tmp = uint32_t{};
- memcpy(&tmp, (&strtab[0] + *data_offset), data_size);
- tmp = le32toh(tmp);
+ memcpy(&tmp, &op.instruction.immediate, sizeof(tmp));
auto v = float{};
- memcpy(&v, &tmp, data_size);
+ memcpy(&v, &tmp, sizeof(v));
- target = v;
+ out = v;
}
auto execute(DOUBLE const op, Stack& stack, ip_type const) -> void
{