diff options
Diffstat (limited to 'asm')
-rw-r--r-- | asm/assembler.cpp | 18 | ||||
-rw-r--r-- | asm/assembler.h | 30 | ||||
-rw-r--r-- | asm/intel64/add.cpp | 18 | ||||
-rw-r--r-- | asm/intel64/and.cpp | 12 | ||||
-rw-r--r-- | asm/intel64/bsf.cpp | 6 | ||||
-rw-r--r-- | asm/intel64/bsr.cpp | 6 | ||||
-rw-r--r-- | asm/intel64/codes.cpp | 2 | ||||
-rw-r--r-- | asm/intel64/div.cpp | 9 | ||||
-rw-r--r-- | asm/intel64/encode.cpp | 10 | ||||
-rw-r--r-- | asm/intel64/mov.cpp | 12 | ||||
-rw-r--r-- | asm/intel64/mul.cpp | 9 | ||||
-rw-r--r-- | asm/intel64/or.cpp | 12 |
12 files changed, 95 insertions, 49 deletions
diff --git a/asm/assembler.cpp b/asm/assembler.cpp index 4eb37f0..35e971b 100644 --- a/asm/assembler.cpp +++ b/asm/assembler.cpp @@ -10,6 +10,24 @@ Asm::Args::Immediate32::Immediate32(const Asm::Args::Immediate64& imm64) throw std::runtime_error("Immediate32: Constructed from too big Immediate64"); } +Asm::Args::Mem8Ptr64::Mem8Ptr64(const std::string& reg, int32_t offs): m_reg(reg), m_offs(offs) {} +Asm::Args::Mem8Ptr64::Mem8Ptr64(const std::string& reg, const std::string& reg2, int32_t offs): m_reg(reg), m_reg2(reg2), m_offs(offs) {} +std::string Asm::Args::Mem8Ptr64::reg() const { return "["s + m_reg + "]"s; } +std::string Asm::Args::Mem8Ptr64::reg2() const { return "["s + m_reg2 + "]"s; } +int32_t Asm::Args::Mem8Ptr64::offs() const { return m_offs; } + +Asm::Args::Mem32Ptr64::Mem32Ptr64(const std::string& reg, int32_t offs): m_reg(reg), m_offs(offs) {} +Asm::Args::Mem32Ptr64::Mem32Ptr64(const std::string& reg, const std::string& reg2, int32_t offs): m_reg(reg), m_reg2(reg2), m_offs(offs) {} +std::string Asm::Args::Mem32Ptr64::reg() const { return "["s + m_reg + "]"s; } +std::string Asm::Args::Mem32Ptr64::reg2() const { return "["s + m_reg2 + "]"s; } +int32_t Asm::Args::Mem32Ptr64::offs() const { return m_offs; } + +Asm::Args::Mem64Ptr64::Mem64Ptr64(const std::string& reg, int32_t offs): m_reg(reg), m_offs(offs) {} +Asm::Args::Mem64Ptr64::Mem64Ptr64(const std::string& reg, const std::string& reg2, int32_t offs): m_reg(reg), m_reg2(reg2), m_offs(offs) {} +std::string Asm::Args::Mem64Ptr64::reg() const { return "["s + m_reg + "]"s; } +std::string Asm::Args::Mem64Ptr64::reg2() const { return "["s + m_reg2 + "]"s; } +int32_t Asm::Args::Mem64Ptr64::offs() const { return m_offs; } + namespace { std::unordered_map<std::string, FactoryFunction> ops; diff --git a/asm/assembler.h b/asm/assembler.h index 8cdaa31..1fdc658 100644 --- a/asm/assembler.h +++ b/asm/assembler.h @@ -102,11 +102,11 @@ public: class Mem8Ptr64 { public: - Mem8Ptr64(const std::string& reg, int32_t offs = 0): m_reg(reg), m_offs(offs) {} - Mem8Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0): m_reg(reg), m_reg2(reg2), m_offs(offs) {} - std::string reg() const { return m_reg; } - std::string reg2() const { return m_reg2; } - int32_t offs() const { return m_offs; } + Mem8Ptr64(const std::string& reg, int32_t offs = 0); + Mem8Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0); + std::string reg() const; + std::string reg2() const; + int32_t offs() const; private: std::string m_reg; @@ -118,11 +118,11 @@ public: class Mem32Ptr64 { public: - Mem32Ptr64(const std::string& reg, int32_t offs = 0): m_reg(reg), m_offs(offs) {} - Mem32Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0): m_reg(reg), m_reg2(reg2), m_offs(offs) {} - std::string reg() const { return m_reg; } - std::string reg2() const { return m_reg2; } - int32_t offs() const { return m_offs; } + Mem32Ptr64(const std::string& reg, int32_t offs = 0); + Mem32Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0); + std::string reg() const; + std::string reg2() const; + int32_t offs() const; private: std::string m_reg; @@ -134,11 +134,11 @@ public: class Mem64Ptr64 { public: - Mem64Ptr64(const std::string& reg, int32_t offs = 0): m_reg(reg), m_offs(offs) {} - Mem64Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0): m_reg(reg), m_reg2(reg2), m_offs(offs) {} - std::string reg() const { return m_reg; } - std::string reg2() const { return m_reg2; } - int32_t offs() const { return m_offs; } + Mem64Ptr64(const std::string& reg, int32_t offs = 0); + Mem64Ptr64(const std::string& reg, const std::string& reg2, int32_t offs = 0); + std::string reg() const; + std::string reg2() const; + int32_t offs() const; private: std::string m_reg; diff --git a/asm/intel64/add.cpp b/asm/intel64/add.cpp index 07b14a1..12d1b94 100644 --- a/asm/intel64/add.cpp +++ b/asm/intel64/add.cpp @@ -38,23 +38,29 @@ Op_add::Op_add(const Asm::Args& args) machine_code = REX("W") + std::vector<uint8_t>{ 0x01 } + ModRM(std::any_cast<Asm::Args::Register64>(args[1]).name(), std::any_cast<Asm::Args::Register64>(args[0]).name()); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // add reg32, [reg64] - machine_code = std::vector<uint8_t>{ 0x03 } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[1])}; + machine_code = std::vector<uint8_t>{ 0x03 } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // add reg64, [reg64] - machine_code = REX("W") + std::vector<uint8_t>{ 0x03 } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[1])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x03 } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem8Ptr64) && args[1].type() == typeid(Asm::Args::Immediate8)) { // add [reg64], imm8 - machine_code = std::vector<uint8_t>{ 0x80 } + ModRM("/0", std::any_cast<Asm::Args::Mem8Ptr64>(args[0]).reg()) + std::any_cast<Asm::Args::Immediate8>(args[1]).getCode(); + Asm::Args::Mem8Ptr64 ptr{std::any_cast<Asm::Args::Mem8Ptr64>(args[0])}; + machine_code = std::vector<uint8_t>{ 0x80 } + ModRM("/0", ptr.reg(), ptr.offs()) + std::any_cast<Asm::Args::Immediate8>(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // add [reg64], imm32 - machine_code = std::vector<uint8_t>{ 0x81 } + ModRM("/0", std::any_cast<Asm::Args::Mem32Ptr64>(args[0]).reg()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[0])}; + machine_code = std::vector<uint8_t>{ 0x81 } + ModRM("/0", ptr.reg(), ptr.offs()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // add qword ptr [reg64], imm32 (sign-extended) - machine_code = REX("W") + std::vector<uint8_t>{ 0x81 } + ModRM("/0", std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[0])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x81 } + ModRM("/0", ptr.reg(), ptr.offs()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Immediate64)) { // add qword ptr [reg64], imm32 (sign-extended) - reduce imm64 to imm32! + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[0])}; Asm::Args::Immediate32 imm32{std::any_cast<Asm::Args::Immediate64>(args[1])}; - machine_code = REX("W") + std::vector<uint8_t>{ 0x81 } + ModRM("/0", std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg()) + imm32.getCode(); + machine_code = REX("W") + std::vector<uint8_t>{ 0x81 } + ModRM("/0", ptr.reg(), ptr.offs()) + imm32.getCode(); } else { throw std::runtime_error("Unimplemented: add "s + args[0].type().name() + " "s + args[1].type().name()); diff --git a/asm/intel64/and.cpp b/asm/intel64/and.cpp index a2e110b..b87d408 100644 --- a/asm/intel64/and.cpp +++ b/asm/intel64/and.cpp @@ -30,16 +30,20 @@ Op_and::Op_and(const Asm::Args& args) machine_code = std::vector<uint8_t>{ 0x81 } + ModRM("/4", std::any_cast<Asm::Args::Register32>(args[0]).name()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // and reg32, [reg64] - machine_code = std::vector<uint8_t>{ 0x23 } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[1])}; + machine_code = std::vector<uint8_t>{ 0x23 } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // and reg64, [reg64] - machine_code = REX("W") + std::vector<uint8_t>{ 0x23 } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[1])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x23 } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64) && args[1].type() == typeid(Asm::Args::Register32)) { // and [reg64], reg32 - machine_code = std::vector<uint8_t>{ 0x21 } + ModRM(std::any_cast<Asm::Args::Register32>(args[1]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[0]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[0])}; + machine_code = std::vector<uint8_t>{ 0x21 } + ModRM(std::any_cast<Asm::Args::Register32>(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Register64)) { // and [reg64], reg64 - machine_code = REX("W") + std::vector<uint8_t>{ 0x21 } + ModRM(std::any_cast<Asm::Args::Register64>(args[1]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[0])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x21 } + ModRM(std::any_cast<Asm::Args::Register64>(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // and reg64, imm32 (sign-extended) machine_code = REX("W") + std::vector<uint8_t>{ 0x81 } + ModRM("/4", std::any_cast<Asm::Args::Register64>(args[0]).name()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); diff --git a/asm/intel64/bsf.cpp b/asm/intel64/bsf.cpp index 974be43..24a0ae0 100644 --- a/asm/intel64/bsf.cpp +++ b/asm/intel64/bsf.cpp @@ -16,10 +16,12 @@ Op_bsf::Op_bsf(const Asm::Args& args) machine_code = REX("W") + std::vector<uint8_t>{ 0x0F, 0xBC } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), std::any_cast<Asm::Args::Register64>(args[1]).name()); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // bsf reg32, [reg64] - machine_code = std::vector<uint8_t>{ 0x0F, 0xBC } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[1])}; + machine_code = std::vector<uint8_t>{ 0x0F, 0xBC } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // bsf reg64, [reg64] - machine_code = REX("W") + std::vector<uint8_t>{ 0x0F, 0xBC } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[1])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x0F, 0xBC } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), ptr.reg(), ptr.offs()); } else { throw std::runtime_error("Unimplemented: bsf "s + args[0].type().name() + " "s + args[1].type().name()); diff --git a/asm/intel64/bsr.cpp b/asm/intel64/bsr.cpp index 099c7d2..5935402 100644 --- a/asm/intel64/bsr.cpp +++ b/asm/intel64/bsr.cpp @@ -16,10 +16,12 @@ Op_bsr::Op_bsr(const Asm::Args& args) machine_code = REX("W") + std::vector<uint8_t>{ 0x0F, 0xBD } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), std::any_cast<Asm::Args::Register64>(args[1]).name()); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // bsr reg32, [reg64] - machine_code = std::vector<uint8_t>{ 0x0F, 0xBD } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[1])}; + machine_code = std::vector<uint8_t>{ 0x0F, 0xBD } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // bsr reg64, [reg64] - machine_code = REX("W") + std::vector<uint8_t>{ 0x0F, 0xBD } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[1])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x0F, 0xBD } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), ptr.reg(), ptr.offs()); } else { throw std::runtime_error("Unimplemented: bsr "s + args[0].type().name() + " "s + args[1].type().name()); diff --git a/asm/intel64/codes.cpp b/asm/intel64/codes.cpp index 9f82d37..76108a1 100644 --- a/asm/intel64/codes.cpp +++ b/asm/intel64/codes.cpp @@ -78,7 +78,7 @@ std::vector<uint8_t> ModRM(const std::string& reg, const std::string& rm, int32_ if (disp == 0 && rm_bits != 5) { // no displacement // ignore: keep MOD == 00, no displacement bytes if (rm_bits == 5) - throw std::runtime_error("ICE: [rbp] with now displacement is not supported"); // TODO: Support this, and SIB byte + throw std::runtime_error("ICE: [rbp] with no displacement is not supported"); // TODO: Support this, and SIB byte } else if (disp >= -128 && disp < 128) { result |= 0b01000000; // 8 bit displacement displacement_bytes.push_back(uint8_t(disp)); diff --git a/asm/intel64/div.cpp b/asm/intel64/div.cpp index 1e98b7b..cfe2503 100644 --- a/asm/intel64/div.cpp +++ b/asm/intel64/div.cpp @@ -21,14 +21,17 @@ Op_div::Op_div(const Asm::Args& args) machine_code = REX("W") + std::vector<uint8_t>{ 0xF7 } + ModRM("/6", std::any_cast<Asm::Args::Register64>(args[0]).name()); } else if (args[0].type() == typeid(Asm::Args::Mem8Ptr64)) { // div byte ptr [reg64] (accu is al (remainder=ah) <- ah / x) + Asm::Args::Mem8Ptr64 ptr{std::any_cast<Asm::Args::Mem8Ptr64>(args[0])}; machine_code = std::vector<uint8_t>{ 0xF6 } + - ModRM("/6", std::any_cast<Asm::Args::Mem8Ptr64>(args[0]).reg()); + ModRM("/6", ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64)) { // div dword ptr [reg64] (accu is eax (remainder=edx) <- edx:eax / x) + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[0])}; machine_code = std::vector<uint8_t>{ 0xF7 } + - ModRM("/6", std::any_cast<Asm::Args::Mem32Ptr64>(args[0]).reg()); + ModRM("/6", ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64)) { // div qword ptr [reg64] (accu is rax (remainder=rdx) <- rdx:rax / x) + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[0])}; machine_code = REX("W") + std::vector<uint8_t>{ 0xF7 } + - ModRM("/6", std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg()); + ModRM("/6", ptr.reg(), ptr.offs()); } else { throw std::runtime_error("Unimplemented: div "s + args[0].type().name()); } diff --git a/asm/intel64/encode.cpp b/asm/intel64/encode.cpp index a2434fd..4e72933 100644 --- a/asm/intel64/encode.cpp +++ b/asm/intel64/encode.cpp @@ -33,7 +33,7 @@ std::shared_ptr<Op> makeLoadValue(const FlowGraph::Data& data, const FlowGraph:: //FlowGraph::TemporaryStorage& storage {dynamic_cast<FlowGraph::TemporaryStorage&>(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return makeOp("mov", Asm::Args{{Asm::Args::Register32("eax"), Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}}); + return makeOp("mov", Asm::Args{{Asm::Args::Register32("eax"), Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4)}}); } else throw std::runtime_error("ICE: Unsupported type for operand data at load: "s + demangle(typeid(data_storage))); } @@ -52,7 +52,7 @@ std::shared_ptr<Op> makeStoreValue(const FlowGraph::Data& data, const FlowGraph: //FlowGraph::TemporaryStorage& storage {dynamic_cast<FlowGraph::TemporaryStorage&>(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return makeOp("mov", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4), Asm::Args::Register32("eax")}}); + return makeOp("mov", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4), Asm::Args::Register32("eax")}}); } else throw std::runtime_error("ICE: Unsupported type for operand data at store: "s + demangle(typeid(data_storage))); } @@ -79,7 +79,7 @@ std::shared_ptr<Op> makeAddValue(const FlowGraph::Data& data, const FlowGraph::G //FlowGraph::TemporaryStorage& storage {dynamic_cast<FlowGraph::TemporaryStorage&>(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return makeOp("add", Asm::Args{{Asm::Args::Register32("eax"), Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}}); + return makeOp("add", Asm::Args{{Asm::Args::Register32("eax"), Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4)}}); } else throw std::runtime_error("ICE: Unsupported type for operand data at add: "s + demangle(typeid(data_storage))); } @@ -109,7 +109,7 @@ std::vector<std::shared_ptr<Chunk>> makeMulValue(const FlowGraph::Data& data, co //FlowGraph::TemporaryStorage& storage {dynamic_cast<FlowGraph::TemporaryStorage&>(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return {{makeOp("mul", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}})}}; + return {{makeOp("mul", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4)}})}}; } else throw std::runtime_error("ICE: Unsupported type for operand data at mul: "s + demangle(typeid(data_storage))); } @@ -139,7 +139,7 @@ std::vector<std::shared_ptr<Chunk>> makeDivValue(const FlowGraph::Data& data, co //FlowGraph::TemporaryStorage& storage {dynamic_cast<FlowGraph::TemporaryStorage&>(data_storage)}; index_t index { graph.scope()->indexOfData(data)}; - return {{makeOp("div", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index) * -4)}})}}; + return {{makeOp("div", Asm::Args{{Asm::Args::Mem32Ptr64("rbp", int32_t(index + 1) * -4)}})}}; } else throw std::runtime_error("ICE: Unsupported type for operand data at div: "s + demangle(typeid(data_storage))); } diff --git a/asm/intel64/mov.cpp b/asm/intel64/mov.cpp index 5f09c82..5d09def 100644 --- a/asm/intel64/mov.cpp +++ b/asm/intel64/mov.cpp @@ -33,16 +33,20 @@ Op_mov::Op_mov(const Asm::Args& args) machine_code = std::vector<uint8_t>{ REX("W") + static_cast<uint8_t>(0xB8 + RegNo(std::any_cast<Asm::Args::Register64>(args[0]).name())) } + std::any_cast<Asm::Args::Immediate64>(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // mov reg32, [reg64] - machine_code = std::vector<uint8_t>{ 0x8B } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[1])}; + machine_code = std::vector<uint8_t>{ 0x8B } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // mov reg64, [reg64] - machine_code = REX("W") + std::vector<uint8_t>{ 0x8B } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[1])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x8B } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64) && args[1].type() == typeid(Asm::Args::Register32)) { // mov [reg64], reg32 - machine_code = std::vector<uint8_t>{ 0x89 } + ModRM(std::any_cast<Asm::Args::Register32>(args[1]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[0]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[0])}; + machine_code = std::vector<uint8_t>{ 0x89 } + ModRM(std::any_cast<Asm::Args::Register32>(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Register64)) { // mov [reg64], reg64 - machine_code = REX("W") + std::vector<uint8_t>{ 0x89 } + ModRM(std::any_cast<Asm::Args::Register64>(args[1]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[0])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x89 } + ModRM(std::any_cast<Asm::Args::Register64>(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // mov reg64, imm32 (sign-extended) machine_code = REX("W") + std::vector<uint8_t>{ 0xC7 } + ModRM("/0", std::any_cast<Asm::Args::Register64>(args[0]).name()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); diff --git a/asm/intel64/mul.cpp b/asm/intel64/mul.cpp index 5825e2a..14810dc 100644 --- a/asm/intel64/mul.cpp +++ b/asm/intel64/mul.cpp @@ -21,14 +21,17 @@ Op_mul::Op_mul(const Asm::Args& args) machine_code = REX("W") + std::vector<uint8_t>{ 0xF7 } + ModRM("/4", std::any_cast<Asm::Args::Register64>(args[0]).name()); } else if (args[0].type() == typeid(Asm::Args::Mem8Ptr64)) { // mul byte ptr [reg64] (accu is ax <- al) + Asm::Args::Mem8Ptr64 ptr{std::any_cast<Asm::Args::Mem8Ptr64>(args[0])}; machine_code = std::vector<uint8_t>{ 0xF6 } + - ModRM("/4", std::any_cast<Asm::Args::Mem8Ptr64>(args[0]).reg()); + ModRM("/4", ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64)) { // mul dword ptr [reg64] (accu is edx:eax <- eax) + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[0])}; machine_code = std::vector<uint8_t>{ 0xF7 } + - ModRM("/4", std::any_cast<Asm::Args::Mem32Ptr64>(args[0]).reg()); + ModRM("/4", ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64)) { // mul qword ptr [reg64] (accu is rdx:rax <- rax) + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[0])}; machine_code = REX("W") + std::vector<uint8_t>{ 0xF7 } + - ModRM("/4", std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg()); + ModRM("/4", ptr.reg(), ptr.offs()); } else { throw std::runtime_error("Unimplemented: mul "s + args[0].type().name()); } diff --git a/asm/intel64/or.cpp b/asm/intel64/or.cpp index c5be55c..27daf07 100644 --- a/asm/intel64/or.cpp +++ b/asm/intel64/or.cpp @@ -30,16 +30,20 @@ Op_or::Op_or(const Asm::Args& args) machine_code = std::vector<uint8_t>{ 0x81 } + ModRM("/1", std::any_cast<Asm::Args::Register32>(args[0]).name()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); } else if (args[0].type() == typeid(Asm::Args::Register32) && args[1].type() == typeid(Asm::Args::Mem32Ptr64)) { // or reg32, [reg64] - machine_code = std::vector<uint8_t>{ 0x0B } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[1]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[1])}; + machine_code = std::vector<uint8_t>{ 0x0B } + ModRM(std::any_cast<Asm::Args::Register32>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Mem64Ptr64)) { // or reg64, [reg64] - machine_code = REX("W") + std::vector<uint8_t>{ 0x0B } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[1]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[1])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x0B } + ModRM(std::any_cast<Asm::Args::Register64>(args[0]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem32Ptr64) && args[1].type() == typeid(Asm::Args::Register32)) { // or [reg64], reg32 - machine_code = std::vector<uint8_t>{ 0x09 } + ModRM(std::any_cast<Asm::Args::Register32>(args[1]).name(), std::any_cast<Asm::Args::Mem32Ptr64>(args[0]).reg()); + Asm::Args::Mem32Ptr64 ptr{std::any_cast<Asm::Args::Mem32Ptr64>(args[0])}; + machine_code = std::vector<uint8_t>{ 0x09 } + ModRM(std::any_cast<Asm::Args::Register32>(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Mem64Ptr64) && args[1].type() == typeid(Asm::Args::Register64)) { // or [reg64], reg64 - machine_code = REX("W") + std::vector<uint8_t>{ 0x09 } + ModRM(std::any_cast<Asm::Args::Register64>(args[1]).name(), std::any_cast<Asm::Args::Mem64Ptr64>(args[0]).reg()); + Asm::Args::Mem64Ptr64 ptr{std::any_cast<Asm::Args::Mem64Ptr64>(args[0])}; + machine_code = REX("W") + std::vector<uint8_t>{ 0x09 } + ModRM(std::any_cast<Asm::Args::Register64>(args[1]).name(), ptr.reg(), ptr.offs()); } else if (args[0].type() == typeid(Asm::Args::Register64) && args[1].type() == typeid(Asm::Args::Immediate32)) { // or reg64, imm32 (sign-extended) machine_code = REX("W") + std::vector<uint8_t>{ 0x81 } + ModRM("/1", std::any_cast<Asm::Args::Register64>(args[0]).name()) + std::any_cast<Asm::Args::Immediate32>(args[1]).getCode(); |