summaryrefslogtreecommitdiffhomepage
path: root/asm
diff options
context:
space:
mode:
Diffstat (limited to 'asm')
-rw-r--r--asm/assembler.cpp18
-rw-r--r--asm/assembler.h30
-rw-r--r--asm/intel64/add.cpp18
-rw-r--r--asm/intel64/and.cpp12
-rw-r--r--asm/intel64/bsf.cpp6
-rw-r--r--asm/intel64/bsr.cpp6
-rw-r--r--asm/intel64/codes.cpp2
-rw-r--r--asm/intel64/div.cpp9
-rw-r--r--asm/intel64/encode.cpp10
-rw-r--r--asm/intel64/mov.cpp12
-rw-r--r--asm/intel64/mul.cpp9
-rw-r--r--asm/intel64/or.cpp12
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();