Added sub instruction, 32-bit registers, more tests
This commit is contained in:
parent
1392a6f2a4
commit
efcaa49a7b
12
iseq.c
12
iseq.c
@ -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
|
||||
|
37
ujit_asm.c
37
ujit_asm.c
@ -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
|
||||
);
|
||||
}
|
||||
|
26
ujit_asm.h
26
ujit_asm.h
@ -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
|
||||
|
@ -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");
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user