srctree

Robin Linden parent 72228589 8c966473
azm: Support add w/ registers that aren't eax as well

inlinesplit
azm/amd64/assembler.h added: 28, removed: 17, total 11
@@ -8,7 +8,6 @@
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iostream>
#include <optional>
#include <utility>
#include <variant>
@@ -82,13 +81,14 @@ public:
 
// Instructions
void add(Reg32 dst, Imm32 imm32) {
if (dst != Reg32::Eax) {
std::cerr << "add: Unhandled dst " << static_cast<int>(dst) << '\n';
ud2();
if (dst == Reg32::Eax) {
emit(0x05);
emit(imm32);
return;
}
 
emit(0x05);
emit(0x81);
mod_rm(0b11, 0, register_index(dst).value());
emit(imm32);
}
 
@@ -129,6 +129,13 @@ private:
}
}
 
void mod_rm(std::uint8_t mod, std::uint8_t reg, std::uint8_t rm) {
assert(mod < 4);
assert(reg < 8);
assert(rm < 8);
emit((mod << 6) | (reg << 3) | rm);
}
 
std::vector<std::uint8_t> assembled_;
};
 
 
azm/amd64/assembler_test.cpp added: 28, removed: 17, total 11
@@ -24,21 +24,20 @@ int main() {
a.expect_eq(register_index(static_cast<Reg32>(std::underlying_type_t<Reg32>{30})), std::nullopt);
});
 
s.add_test("ADD EAX, imm32", [](etest::IActions &a) {
s.add_test("ADD reg32, imm32", [](etest::IActions &a) {
Assembler assembler;
 
// ADD EAX,imm32 generates slightly shorter asm than ADD w/ other registers.
assembler.add(Reg32::Eax, Imm32{0x42});
a.expect_eq(assembler.take_assembled(), CodeVec{0x05, 0x42, 0, 0, 0});
});
 
s.add_test("ADD w/ unsupported dst is ud2", [](etest::IActions &a) {
Assembler assembler;
 
// More general mod_rm-encoding for these registers.
assembler.add(Reg32::Ecx, Imm32{0x42});
a.expect_eq(assembler.take_assembled(), CodeVec{0x81, 0xc1, 0x42, 0, 0, 0});
assembler.add(Reg32::Edx, Imm32{0x42});
auto unsupported_add_code = assembler.take_assembled();
 
assembler.ud2();
a.expect_eq(unsupported_add_code, assembler.take_assembled());
a.expect_eq(assembler.take_assembled(), CodeVec{0x81, 0xc2, 0x42, 0, 0, 0});
assembler.add(Reg32::Ebx, Imm32{0x42});
a.expect_eq(assembler.take_assembled(), CodeVec{0x81, 0xc3, 0x42, 0, 0, 0});
});
 
s.add_test("JMP, backwards", [](etest::IActions &a) {
 
azm/azm_example.cpp added: 28, removed: 17, total 11
@@ -23,6 +23,11 @@ int main() {
assembler.link(forward);
assembler.mov(Reg32::Edx, Imm32{0x12345678});
assembler.mov(Reg32::Ebx, Imm32{0x1234});
 
assembler.add(Reg32::Ecx, Imm32{0x1234});
assembler.add(Reg32::Edx, Imm32{0x1234'5678});
assembler.add(Reg32::Ebx, Imm32{0x5678});
 
assembler.jmp(end);
 
assembler.ud2();