From 74bff1a4c4d258707e6b1602b678bb2e19c71ad0 Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Sun, 11 Aug 2024 02:25:44 +0100 Subject: [PATCH] Implement writing of opcodes --- CMakeLists.txt | 1 + src/opcode.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/opcode.hpp | 16 ++++++++- src/writer.cpp | 54 ++++++++++++++++++++++++++++- 4 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 src/opcode.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index ad21dcf..852dea1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ target_sources(vm_lib src/writer.cpp src/utf8.cpp src/compiler.cpp + src/opcode.cpp PUBLIC FILE_SET HEADERS diff --git a/src/opcode.cpp b/src/opcode.cpp new file mode 100644 index 0000000..5f1c6c6 --- /dev/null +++ b/src/opcode.cpp @@ -0,0 +1,92 @@ +#include "opcode.hpp" + +#include "die.hpp" + +struct op_t { + const char* opname; + OpcodeType optype; +}; + +static const op_t opcode_tbl[] = {}; + +op_t get_op(Oc op) { + switch (op) { + case Oc::Unknown: + return op_t{0, OpcodeType::Reg0}; + case Oc::Add: + return op_t{"add", OpcodeType::Reg3}; + case Oc::Sub: + return op_t{"sub", OpcodeType::Reg3}; + case Oc::Mul: + return op_t{"mul", OpcodeType::Reg3}; + case Oc::Div: + return op_t{"div", OpcodeType::Reg3}; + case Oc::Mod: + return op_t{"mod", OpcodeType::Reg3}; + case Oc::Mov: + return op_t{"mov", OpcodeType::Reg2}; + case Oc::LoadConst: + return op_t{"loadc", OpcodeType::Reg1I}; + case Oc::LoadStack: + return op_t{"lfi", OpcodeType::Reg1I}; + case Oc::Jump: + return op_t{"jmp", OpcodeType::Reg0I}; + case Oc::JumpEqual: + return op_t{"jeq", OpcodeType::Reg2I}; + case Oc::JumpLess: + return op_t{"jlt", OpcodeType::Reg2I}; + case Oc::JumpLessEqual: + return op_t{"jle", OpcodeType::Reg2I}; + case Oc::JumpNotEqual: + return op_t{"jne", OpcodeType::Reg2I}; + case Oc::Call: + return op_t{"call", OpcodeType::Reg1I}; + case Oc::TailCall: + return op_t{"tailcall", OpcodeType::Reg1I}; + case Oc::Ret: + return op_t{"ret", OpcodeType::Reg1}; + case Oc::RetNil: + return op_t{"retnil", OpcodeType::Reg0}; + case Oc::ShiftRight: + return op_t{"sri", OpcodeType::Reg2I}; + case Oc::ShiftLeft: + return op_t{"sli", OpcodeType::Reg2I}; + case Oc::BitwiseAnd: + return op_t{"band", OpcodeType::Reg3}; + case Oc::BitwiseOr: + return op_t{"bor", OpcodeType::Reg3}; + case Oc::BitwiseXor: + return op_t{"bxor", OpcodeType::Reg3}; + case Oc::BitwiseNeg: + return op_t{"bneg", OpcodeType::Reg2}; + case Oc::MakeArray: + return op_t{"make-array", OpcodeType::Reg1I}; + case Oc::ArrayLoad: + return op_t{"al", OpcodeType::Reg3}; + case Oc::ArrayStore: + return op_t{"as", OpcodeType::Reg4}; + case Oc::Push: + return op_t{"push", OpcodeType::Reg1}; + case Oc::Pop: + return op_t{"pop", OpcodeType::Reg1}; + case Oc::StackReserve: + return op_t{"sr", OpcodeType::Reg0I}; + case Oc::AssertEqual: + return op_t{"assert-equal", OpcodeType::Reg2}; + case Oc::MakeDict: + return op_t{"make-dict", OpcodeType::Reg1}; + case Oc::SetJump: + return op_t{"setjump", OpcodeType::Reg1I}; + case Oc::SetGlobal: + return op_t{"setglobal", OpcodeType::Reg2}; + case Oc::GetGlobal: + return op_t{"getglobal", OpcodeType::Reg2}; + + default: + die("Unknown opcode\n"); + } +} + +const char* opcode_name(Oc op) { return get_op(op).opname; } + +OpcodeType opcode_type(Oc op) { return get_op(op).optype; } diff --git a/src/opcode.hpp b/src/opcode.hpp index 6175aa5..033c02a 100644 --- a/src/opcode.hpp +++ b/src/opcode.hpp @@ -2,6 +2,18 @@ #include +enum class OpcodeType : uint8_t { + Unknown = 0, + Reg0, + Reg0I, + Reg1, + Reg1I, + Reg2, + Reg2I, + Reg3, + Reg4, +}; + enum class Oc : uint8_t { Unknown = 0, Add, @@ -10,7 +22,6 @@ enum class Oc : uint8_t { Div, Mod, Mov, - LoadImmediate, // constants LoadConst, // Load/store @@ -57,3 +68,6 @@ struct OpArg { uint8_t is_const : 1 = 0; int64_t arg : 63 = 0; }; + +const char* opcode_name(Oc op); +OpcodeType opcode_type(Oc op); diff --git a/src/writer.cpp b/src/writer.cpp index 86238b9..b6f396c 100644 --- a/src/writer.cpp +++ b/src/writer.cpp @@ -1,5 +1,8 @@ #include "writer.hpp" +#include "error.hpp" +#include "opcode.hpp" + Result Writer::write_one(Value& obj) { switch (obj.tag()) { case Tag::Nil: @@ -215,8 +218,57 @@ Result Writer::write_dict(Dict& val) { } Result Writer::write_opcode(Opcode& val) { - String res = TRY(String::create("#")); + String res = TRY(String::create("#")); return res; }