mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Added cmp, not. Generate code for nop instruction.
This commit is contained in:
parent
7d0df31d7a
commit
1879a123ca
4 changed files with 216 additions and 7 deletions
66
ujit_asm.c
66
ujit_asm.c
|
@ -548,10 +548,11 @@ void cb_write_rm(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the displacement size
|
// Add the displacement size
|
||||||
if (rm_opnd.type == OPND_MEM && rm_opnd.mem.disp != 0)
|
if (rm_opnd.type == OPND_MEM)
|
||||||
{
|
{
|
||||||
size_t dsize = disp_size(rm_opnd);
|
size_t dsize = disp_size(rm_opnd);
|
||||||
cb_write_int(cb, rm_opnd.mem.disp, dsize);
|
if (dsize > 0)
|
||||||
|
cb_write_int(cb, rm_opnd.mem.disp, dsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,6 +792,39 @@ void call(codeblock_t* cb, x86opnd_t opnd)
|
||||||
cb_write_rm(cb, false, false, NO_OPND, opnd, 2, 1, 0xFF);
|
cb_write_rm(cb, false, false, NO_OPND, opnd, 2, 1, 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// cmp - Compare and set flags
|
||||||
|
void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
||||||
|
{
|
||||||
|
cb_write_rm_multi(
|
||||||
|
cb,
|
||||||
|
"cmp",
|
||||||
|
0x38, // opMemReg8
|
||||||
|
0x39, // opMemRegPref
|
||||||
|
0x3A, // opRegMem8
|
||||||
|
0x3B, // opRegMemPref
|
||||||
|
0x80, // opMemImm8
|
||||||
|
0x83, // opMemImmSml
|
||||||
|
0x81, // opMemImmLrg
|
||||||
|
0x07, // opExtImm
|
||||||
|
opnd0,
|
||||||
|
opnd1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// cdq - Convert doubleword to quadword
|
||||||
|
void cdq(codeblock_t* cb)
|
||||||
|
{
|
||||||
|
//cb.writeASM("cdq");
|
||||||
|
cb_write_byte(cb, 0x99);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// cqo - Convert quadword to octaword
|
||||||
|
void cqo(codeblock_t* cb)
|
||||||
|
{
|
||||||
|
//cb.writeASM("cqo");
|
||||||
|
cb_write_bytes(cb, 2, 0x48, 0x99);
|
||||||
|
}
|
||||||
|
|
||||||
// dec - Decrement integer by 1
|
// dec - Decrement integer by 1
|
||||||
void dec(codeblock_t* cb, x86opnd_t opnd)
|
void dec(codeblock_t* cb, x86opnd_t opnd)
|
||||||
{
|
{
|
||||||
|
@ -1132,6 +1166,34 @@ void nop(codeblock_t* cb, size_t length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// not - Bitwise NOT
|
||||||
|
void not(codeblock_t* cb, x86opnd_t opnd)
|
||||||
|
{
|
||||||
|
write_rm_unary(
|
||||||
|
cb,
|
||||||
|
"not",
|
||||||
|
0xF6, // opMemReg8
|
||||||
|
0xF7, // opMemRegPref
|
||||||
|
0x02, // opExt
|
||||||
|
opnd
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
/// or - Bitwise OR
|
||||||
|
alias or = writeRMMulti!(
|
||||||
|
"or",
|
||||||
|
0x08, // opMemReg8
|
||||||
|
0x09, // opMemRegPref
|
||||||
|
0x0A, // opRegMem8
|
||||||
|
0x0B, // opRegMemPref
|
||||||
|
0x80, // opMemImm8
|
||||||
|
0x83, // opMemImmSml
|
||||||
|
0x81, // opMemImmLrg
|
||||||
|
0x01 // opExtImm
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
/// push - Push a register on the stack
|
/// push - Push a register on the stack
|
||||||
void push(codeblock_t* cb, x86opnd_t reg)
|
void push(codeblock_t* cb, x86opnd_t reg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -196,6 +196,9 @@ void cb_write_epilogue(codeblock_t* cb);
|
||||||
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||||
void call_label(codeblock_t* cb, size_t label_idx);
|
void call_label(codeblock_t* cb, size_t label_idx);
|
||||||
void call(codeblock_t* cb, x86opnd_t opnd);
|
void call(codeblock_t* cb, x86opnd_t opnd);
|
||||||
|
void cmp(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||||
|
void cdq(codeblock_t* cb);
|
||||||
|
void cqo(codeblock_t* cb);
|
||||||
void dec(codeblock_t* cb, x86opnd_t opnd);
|
void dec(codeblock_t* cb, x86opnd_t opnd);
|
||||||
void inc(codeblock_t* cb, x86opnd_t opnd);
|
void inc(codeblock_t* cb, x86opnd_t opnd);
|
||||||
void ja(codeblock_t* cb, size_t label_idx);
|
void ja(codeblock_t* cb, size_t label_idx);
|
||||||
|
@ -233,6 +236,7 @@ void jmp_rm(codeblock_t* cb, x86opnd_t opnd);
|
||||||
void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
|
void lea(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
|
||||||
void mov(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 nop(codeblock_t* cb, size_t length);
|
||||||
|
void not(codeblock_t* cb, x86opnd_t opnd);
|
||||||
void push(codeblock_t* cb, x86opnd_t reg);
|
void push(codeblock_t* cb, x86opnd_t reg);
|
||||||
void pop(codeblock_t* cb, x86opnd_t reg);
|
void pop(codeblock_t* cb, x86opnd_t reg);
|
||||||
void ret(codeblock_t* cb);
|
void ret(codeblock_t* cb);
|
||||||
|
|
124
ujit_asm_tests.c
124
ujit_asm_tests.c
|
@ -93,6 +93,44 @@ void run_tests()
|
||||||
cb_set_pos(cb, 0); call(cb, RAX); check_bytes(cb, "FFD0");
|
cb_set_pos(cb, 0); call(cb, RAX); check_bytes(cb, "FFD0");
|
||||||
cb_set_pos(cb, 0); call(cb, mem_opnd(64, RSP, 8)); check_bytes(cb, "FF542408");
|
cb_set_pos(cb, 0); call(cb, mem_opnd(64, RSP, 8)); check_bytes(cb, "FF542408");
|
||||||
|
|
||||||
|
/*
|
||||||
|
// cmovcc
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.cmovg(ESI, X86Opnd(EDI)); },
|
||||||
|
"0F4FF7"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.cmovg(ESI, X86Opnd(32, RBP, 12)); },
|
||||||
|
"0F4F750C"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.cmovl(EAX, X86Opnd(ECX)); },
|
||||||
|
"0F4CC1"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.cmovl(RBX, X86Opnd(RBP)); },
|
||||||
|
"480F4CDD"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.cmovle(ESI, X86Opnd(32, RSP, 4)); },
|
||||||
|
"0F4E742404"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// cmp
|
||||||
|
/*
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.cmp(X86Opnd(CL), X86Opnd(DL)); },
|
||||||
|
"38D1"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
cb_set_pos(cb, 0); cmp(cb, ECX, EDI); check_bytes(cb, "39F9");
|
||||||
|
cb_set_pos(cb, 0); cmp(cb, RDX, mem_opnd(64, R12, 0)); check_bytes(cb, "493B1424");
|
||||||
|
cb_set_pos(cb, 0); cmp(cb, RAX, imm_opnd(2)); check_bytes(cb, "4883F802");
|
||||||
|
|
||||||
|
// cqo
|
||||||
|
cb_set_pos(cb, 0); cqo(cb); check_bytes(cb, "4899");
|
||||||
|
|
||||||
// dec
|
// dec
|
||||||
/*
|
/*
|
||||||
test(
|
test(
|
||||||
|
@ -178,6 +216,92 @@ void run_tests()
|
||||||
// nop
|
// nop
|
||||||
cb_set_pos(cb, 0); nop(cb, 1); check_bytes(cb, "90");
|
cb_set_pos(cb, 0); nop(cb, 1); check_bytes(cb, "90");
|
||||||
|
|
||||||
|
// not
|
||||||
|
/*
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(AX)); },
|
||||||
|
"66F7D0"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
cb_set_pos(cb, 0); not(cb, EAX); check_bytes(cb, "F7D0");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(64, R12, 0)); check_bytes(cb, "49F71424");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RSP, 301)); check_bytes(cb, "F794242D010000");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RSP, 0)); check_bytes(cb, "F71424");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RSP, 3)); check_bytes(cb, "F7542403");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RBP, 0)); check_bytes(cb, "F75500");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RBP, 13)); check_bytes(cb, "F7550D");
|
||||||
|
cb_set_pos(cb, 0); not(cb, RAX); check_bytes(cb, "48F7D0");
|
||||||
|
cb_set_pos(cb, 0); not(cb, R11); check_bytes(cb, "49F7D3");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RAX, 0)); check_bytes(cb, "F710");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RSI, 0)); check_bytes(cb, "F716");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDI, 0)); check_bytes(cb, "F717");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDX, 55)); check_bytes(cb, "F75237");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDX, 1337)); check_bytes(cb, "F79239050000");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDX, -55)); check_bytes(cb, "F752C9");
|
||||||
|
cb_set_pos(cb, 0); not(cb, mem_opnd(32, RDX, -555)); check_bytes(cb, "F792D5FDFFFF");
|
||||||
|
/*
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RAX, 0, 1, RBX)); },
|
||||||
|
"F71418"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RAX, 0, 1, R12)); },
|
||||||
|
"42F71420"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R15, 0, 1, R12)); },
|
||||||
|
"43F71427"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R15, 5, 1, R12)); },
|
||||||
|
"43F7542705"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R15, 5, 8, R12)); },
|
||||||
|
"43F754E705"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R15, 5, 8, R13)); },
|
||||||
|
"43F754EF05"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R12, 5, 4, R9)); },
|
||||||
|
"43F7548C05"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, R12, 301, 4, R9)); },
|
||||||
|
"43F7948C2D010000"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RAX, 5, 4, RDX)); },
|
||||||
|
"F7549005"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(64, RAX, 0, 2, RDX)); },
|
||||||
|
"48F71450"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RSP, 0, 1, RBX)); },
|
||||||
|
"F7141C"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RSP, 3, 1, RBX)); },
|
||||||
|
"F7541C03"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.not(X86Opnd(32, RBP, 13, 1, RDX)); },
|
||||||
|
"F754150D"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// or
|
||||||
|
/*
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.or(X86Opnd(EDX), X86Opnd(ESI)); },
|
||||||
|
"09F2"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
// pop
|
// pop
|
||||||
cb_set_pos(cb, 0); pop(cb, RAX); check_bytes(cb, "58");
|
cb_set_pos(cb, 0); pop(cb, RAX); check_bytes(cb, "58");
|
||||||
cb_set_pos(cb, 0); pop(cb, RBX); check_bytes(cb, "5B");
|
cb_set_pos(cb, 0); pop(cb, RBX); check_bytes(cb, "5B");
|
||||||
|
|
|
@ -42,18 +42,37 @@ ujit_compile_insn(rb_iseq_t *iseq, size_t insn_idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
int insn = (int)iseq->body->iseq_encoded[insn_idx];
|
int insn = (int)iseq->body->iseq_encoded[insn_idx];
|
||||||
|
|
||||||
//const char* name = insn_name(insn);
|
//const char* name = insn_name(insn);
|
||||||
//printf("%s\n", name);
|
//printf("%s\n", name);
|
||||||
|
|
||||||
|
// Get a pointer to the current write position in the code block
|
||||||
|
uint8_t* code_ptr = &cb->mem_block[cb->write_pos];
|
||||||
|
//printf("write pos: %ld\n", cb->write_pos);
|
||||||
|
|
||||||
// TODO: encode individual instructions, eg
|
// TODO: encode individual instructions, eg
|
||||||
// nop, putnil, putobject, putself, pop, dup, getlocal, nilp
|
// nop, putnil, putobject, putself, pop, dup, getlocal, setlocal, nilp
|
||||||
|
|
||||||
|
// TODO: we should move the codegen for individual instructions
|
||||||
|
// into separate functions
|
||||||
|
if (insn == BIN(nop))
|
||||||
|
{
|
||||||
|
// Write the pre call bytes
|
||||||
|
cb_write_prologue(cb);
|
||||||
|
|
||||||
|
add(cb, RSI, imm_opnd(8)); // increment PC
|
||||||
|
mov(cb, mem_opnd(64, RDI, 0), RSI); // write new PC to EC object, not necessary for nop bytecode?
|
||||||
|
mov(cb, RAX, RSI); // return new PC
|
||||||
|
|
||||||
|
// Write the post call bytes
|
||||||
|
cb_write_epilogue(cb);
|
||||||
|
|
||||||
|
addr2insn_bookkeeping(code_ptr, insn);
|
||||||
|
|
||||||
|
return code_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (insn == BIN(pop))
|
if (insn == BIN(pop))
|
||||||
{
|
{
|
||||||
// Get a pointer to the current write position in the code block
|
|
||||||
uint8_t* code_ptr = &cb->mem_block[cb->write_pos];
|
|
||||||
|
|
||||||
// Write the pre call bytes
|
// Write the pre call bytes
|
||||||
cb_write_prologue(cb);
|
cb_write_prologue(cb);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue