Added sub instruction, 32-bit registers, more tests

This commit is contained in:
Maxime Chevalier-Boisvert 2020-09-10 10:57:29 -04:00 committed by Alan Wu
parent 1392a6f2a4
commit efcaa49a7b
4 changed files with 82 additions and 47 deletions

12
iseq.c
View File

@ -3225,6 +3225,18 @@ rb_vm_encoded_insn_data_table_init(void)
head += sizeof(handmade_pop);
memcpy(head, ujit_post_call_bytes, sizeof(ujit_post_call_bytes));
// TODO this is small enough to fit in the page we allocated but that can change
}
int

View File

@ -32,6 +32,24 @@ const x86opnd_t R13 = { OPND_REG, 64, .reg = { REG_GP, 13 }};
const x86opnd_t R14 = { OPND_REG, 64, .reg = { REG_GP, 14 }};
const x86opnd_t R15 = { OPND_REG, 64, .reg = { REG_GP, 15 }};
// 32-bit GP registers
const x86opnd_t EAX = { OPND_REG, 32, .reg = { REG_GP, 0 }};
const x86opnd_t ECX = { OPND_REG, 32, .reg = { REG_GP, 1 }};
const x86opnd_t EDX = { OPND_REG, 32, .reg = { REG_GP, 2 }};
const x86opnd_t EBX = { OPND_REG, 32, .reg = { REG_GP, 3 }};
const x86opnd_t ESP = { OPND_REG, 32, .reg = { REG_GP, 4 }};
const x86opnd_t EBP = { OPND_REG, 32, .reg = { REG_GP, 5 }};
const x86opnd_t ESI = { OPND_REG, 32, .reg = { REG_GP, 6 }};
const x86opnd_t EDI = { OPND_REG, 32, .reg = { REG_GP, 7 }};
const x86opnd_t R8D = { OPND_REG, 32, .reg = { REG_GP, 8 }};
const x86opnd_t R9D = { OPND_REG, 32, .reg = { REG_GP, 9 }};
const x86opnd_t R10D = { OPND_REG, 32, .reg = { REG_GP, 10 }};
const x86opnd_t R11D = { OPND_REG, 32, .reg = { REG_GP, 11 }};
const x86opnd_t R12D = { OPND_REG, 32, .reg = { REG_GP, 12 }};
const x86opnd_t R13D = { OPND_REG, 32, .reg = { REG_GP, 13 }};
const x86opnd_t R14D = { OPND_REG, 32, .reg = { REG_GP, 14 }};
const x86opnd_t R15D = { OPND_REG, 32, .reg = { REG_GP, 15 }};
// Compute the number of bits needed to encode a signed value
size_t sig_imm_size(int64_t imm)
{
@ -874,3 +892,22 @@ void ret(codeblock_t* cb)
//cb.writeASM("ret");
cb_write_byte(cb, 0xC3);
}
/// sub - Integer subtraction
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
{
cb_write_rm_multi(
cb,
"sub",
0x28, // opMemReg8
0x29, // opMemRegPref
0x2A, // opRegMem8
0x2B, // opRegMemPref
0x80, // opMemImm8
0x83, // opMemImmSml
0x81, // opMemImmLrg
0x05, // opExtImm
opnd0,
opnd1
);
}

View File

@ -149,6 +149,24 @@ const x86opnd_t R13;
const x86opnd_t R14;
const x86opnd_t R15;
// 32-bit GP registers
const x86opnd_t EAX;
const x86opnd_t ECX;
const x86opnd_t EDX;
const x86opnd_t EBX;
const x86opnd_t EBP;
const x86opnd_t ESP;
const x86opnd_t ESI;
const x86opnd_t EDI;
const x86opnd_t R8D;
const x86opnd_t R9D;
const x86opnd_t R10D;
const x86opnd_t R11D;
const x86opnd_t R12D;
const x86opnd_t R13D;
const x86opnd_t R14D;
const x86opnd_t R15D;
// Memory operand with base register and displacement/offset
x86opnd_t mem_opnd(size_t num_bits, x86opnd_t base_reg, int32_t disp);
@ -170,16 +188,12 @@ void cb_write_epilogue(codeblock_t* cb);
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
void call(codeblock_t* cb, x86opnd_t opnd);
void jmp(codeblock_t* cb, x86opnd_t opnd);
void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
void nop(codeblock_t* cb, size_t length);
void push(codeblock_t* cb, x86opnd_t reg);
void pop(codeblock_t* cb, x86opnd_t reg);
void ret(codeblock_t* cb);
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
#endif

View File

@ -70,30 +70,17 @@ void run_tests()
);
*/
cb_set_pos(cb, 0); add(cb, RAX, RBX); check_bytes(cb, "4801D8");
//cb_set_pos(cb, 0); add(cb, ECX, EDX); check_bytes(cb, "01D1");
cb_set_pos(cb, 0); add(cb, ECX, EDX); check_bytes(cb, "01D1");
cb_set_pos(cb, 0); add(cb, RDX, R14); check_bytes(cb, "4C01F2");
cb_set_pos(cb, 0); add(cb, mem_opnd(64, RAX, 0), RDX); check_bytes(cb, "480110");
cb_set_pos(cb, 0); add(cb, RDX, mem_opnd(64, RAX, 0)); check_bytes(cb, "480310");
cb_set_pos(cb, 0); add(cb, RDX, mem_opnd(64, RAX, 8)); check_bytes(cb, "48035008");
cb_set_pos(cb, 0); add(cb, RDX, mem_opnd(64, RAX, 255)); check_bytes(cb, "480390FF000000");
cb_set_pos(cb, 0); add(cb, mem_opnd(64, RAX, 127), imm_opnd(255)); check_bytes(cb, "4881407FFF000000");
/*
test(
delegate void (CodeBlock cb) { cb.add(X86Opnd(32, RAX), X86Opnd(EDX)); },
"0110"
);
*/
cb_set_pos(cb, 0); add(cb, mem_opnd(32, RAX, 0), EDX); check_bytes(cb, "0110");
cb_set_pos(cb, 0); add(cb, RSP, imm_opnd(8)); check_bytes(cb, "4883C408");
/*
test(
delegate void (CodeBlock cb) { cb.add(X86Opnd(ECX), X86Opnd(8)); },
"83C108"
);
test(
delegate void (CodeBlock cb) { cb.add(X86Opnd(ECX), X86Opnd(255)); },
"81C1FF000000"
);
*/
cb_set_pos(cb, 0); add(cb, ECX, imm_opnd(8)); check_bytes(cb, "83C108");
cb_set_pos(cb, 0); add(cb, ECX, imm_opnd(255)); check_bytes(cb, "81C1FF000000");
// call
/*
@ -121,33 +108,16 @@ void run_tests()
cb_set_pos(cb, 0); jmp(cb, R12); check_bytes(cb, "41FFE4");
// lea
//cb_set_pos(cb, 0); mov(cb, EBX, mem_opnd(32, RSP, 4))); check_bytes(cb, "8D5C2404");
//cb_set_pos(cb, 0); lea(cb, EBX, mem_opnd(32, RSP, 4)); check_bytes(cb, "8D5C2404");
// mov
/*
test(
delegate void (CodeBlock cb) { cb.mov(X86Opnd(EAX), X86Opnd(7)); },
"B807000000"
);
test(
delegate void (CodeBlock cb) { cb.mov(X86Opnd(EAX), X86Opnd(-3)); },
"B8FDFFFFFF"
);
*/
cb_set_pos(cb, 0); mov(cb, EAX, imm_opnd(7)); check_bytes(cb, "B807000000");
cb_set_pos(cb, 0); mov(cb, EAX, imm_opnd(-3)); check_bytes(cb, "B8FDFFFFFF");
cb_set_pos(cb, 0); mov(cb, R15, imm_opnd(3)); check_bytes(cb, "49BF0300000000000000");
cb_set_pos(cb, 0); mov(cb, EAX, EBX); check_bytes(cb, "89D8");
cb_set_pos(cb, 0); mov(cb, EAX, ECX); check_bytes(cb, "89C8");
cb_set_pos(cb, 0); mov(cb, EDX, mem_opnd(32, RBX, 128)); check_bytes(cb, "8B9380000000");
/*
test(
delegate void (CodeBlock cb) { cb.mov(X86Opnd(EAX), X86Opnd(EBX)); },
"89D8"
);
test(
delegate void (CodeBlock cb) { cb.mov(X86Opnd(EAX), X86Opnd(ECX)); },
"89C8"
);
test(
delegate void (CodeBlock cb) { cb.mov(X86Opnd(EDX), X86Opnd(32, RBX, 128)); },
"8B9380000000"
);
test(
delegate void (CodeBlock cb) { cb.mov(X86Opnd(AL), X86Opnd(8, RCX, 0, 1, RDX)); },
"8A0411"
@ -185,7 +155,9 @@ void run_tests()
// ret
cb_set_pos(cb, 0); ret(cb); check_bytes(cb, "C3");
// sub
cb_set_pos(cb, 0); sub(cb, EAX, imm_opnd(1)); check_bytes(cb, "83E801");
cb_set_pos(cb, 0); sub(cb, RAX, imm_opnd(2)); check_bytes(cb, "4883E802");