summaryrefslogtreecommitdiffhomepage
path: root/asm/intel64
diff options
context:
space:
mode:
Diffstat (limited to 'asm/intel64')
-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
10 files changed, 62 insertions, 34 deletions
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();