mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Port print_int, movsx. Implement putself.
This commit is contained in:
parent
b8a3f2ed61
commit
d1c9ca86c1
6 changed files with 127 additions and 31 deletions
67
ujit_asm.c
67
ujit_asm.c
|
@ -1163,6 +1163,73 @@ void mov(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// movsx - Move with sign extension (signed integers)
|
||||||
|
void movsx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)
|
||||||
|
{
|
||||||
|
assert (dst.type == OPND_REG);
|
||||||
|
assert (src.type == OPND_REG || src.type == OPND_MEM);
|
||||||
|
assert (src.num_bits < dst.num_bits);
|
||||||
|
|
||||||
|
//cb.writeASM("movsx", dst, src);
|
||||||
|
|
||||||
|
if (src.num_bits == 8)
|
||||||
|
{
|
||||||
|
cb_write_rm(cb, dst.num_bits == 16, dst.num_bits == 64, dst, src, 0xFF, 2, 0x0F, 0xBE);
|
||||||
|
}
|
||||||
|
else if (src.num_bits == 16)
|
||||||
|
{
|
||||||
|
cb_write_rm(cb, dst.num_bits == 16, dst.num_bits == 64, dst, src, 0xFF, 2, 0x0F, 0xBF);
|
||||||
|
}
|
||||||
|
else if (src.num_bits == 32)
|
||||||
|
{
|
||||||
|
cb_write_rm(cb, false, true, dst, src, 0xFF, 1, 0x63);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
/// movzx - Move with zero extension (unsigned values)
|
||||||
|
void movzx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src)
|
||||||
|
{
|
||||||
|
cb.writeASM("movzx", dst, src);
|
||||||
|
|
||||||
|
size_t dstSize;
|
||||||
|
if (dst.isReg)
|
||||||
|
dstSize = dst.reg.size;
|
||||||
|
else
|
||||||
|
assert (false, "movzx dst must be a register");
|
||||||
|
|
||||||
|
size_t srcSize;
|
||||||
|
if (src.isReg)
|
||||||
|
srcSize = src.reg.size;
|
||||||
|
else if (src.isMem)
|
||||||
|
srcSize = src.mem.size;
|
||||||
|
else
|
||||||
|
assert (false);
|
||||||
|
|
||||||
|
assert (
|
||||||
|
srcSize < dstSize,
|
||||||
|
"movzx: srcSize >= dstSize"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (srcSize is 8)
|
||||||
|
{
|
||||||
|
cb.writeRMInstr!('r', 0xFF, 0x0F, 0xB6)(dstSize is 16, dstSize is 64, dst, src);
|
||||||
|
}
|
||||||
|
else if (srcSize is 16)
|
||||||
|
{
|
||||||
|
cb.writeRMInstr!('r', 0xFF, 0x0F, 0xB7)(dstSize is 16, dstSize is 64, dst, src);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (false, "invalid src operand size for movxz");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// neg - Integer negation (multiplication by -1)
|
// neg - Integer negation (multiplication by -1)
|
||||||
void neg(codeblock_t* cb, x86opnd_t opnd)
|
void neg(codeblock_t* cb, x86opnd_t opnd)
|
||||||
{
|
{
|
||||||
|
|
|
@ -268,6 +268,7 @@ void jmp_rm(codeblock_t* cb, x86opnd_t opnd);
|
||||||
void jmp32(codeblock_t* cb, int32_t offset);
|
void jmp32(codeblock_t* cb, int32_t offset);
|
||||||
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 movsx(codeblock_t* cb, x86opnd_t dst, x86opnd_t src);
|
||||||
void neg(codeblock_t* cb, x86opnd_t opnd);
|
void neg(codeblock_t* cb, x86opnd_t opnd);
|
||||||
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 not(codeblock_t* cb, x86opnd_t opnd);
|
||||||
|
|
|
@ -218,6 +218,32 @@ void run_tests()
|
||||||
cb_set_pos(cb, 0); mov(cb, mem_opnd(8, RSP, 0), imm_opnd(-3)); check_bytes(cb, "C60424FD");
|
cb_set_pos(cb, 0); mov(cb, mem_opnd(8, RSP, 0), imm_opnd(-3)); check_bytes(cb, "C60424FD");
|
||||||
cb_set_pos(cb, 0); mov(cb, mem_opnd(64, RDI, 8), imm_opnd(1)); check_bytes(cb, "48C7470801000000");
|
cb_set_pos(cb, 0); mov(cb, mem_opnd(64, RDI, 8), imm_opnd(1)); check_bytes(cb, "48C7470801000000");
|
||||||
|
|
||||||
|
// movsx
|
||||||
|
/*
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.movsx(X86Opnd(AX), X86Opnd(AL)); },
|
||||||
|
"660FBEC0"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.movsx(X86Opnd(EDX), X86Opnd(AL)); },
|
||||||
|
"0FBED0"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.movsx(X86Opnd(RAX), X86Opnd(BL)); },
|
||||||
|
"480FBEC3"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.movsx(X86Opnd(ECX), X86Opnd(AX)); },
|
||||||
|
"0FBFC8"
|
||||||
|
);
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.movsx(X86Opnd(R11), X86Opnd(CL)); },
|
||||||
|
"4C0FBED9"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
cb_set_pos(cb, 0); movsx(cb, R10, mem_opnd(32, RSP, 12)); check_bytes(cb, "4C6354240C");
|
||||||
|
cb_set_pos(cb, 0); movsx(cb, RAX, mem_opnd(8, RSP, 0)); check_bytes(cb, "480FBE0424");
|
||||||
|
|
||||||
// neg
|
// neg
|
||||||
cb_set_pos(cb, 0); neg(cb, RAX); check_bytes(cb, "48F7D8");
|
cb_set_pos(cb, 0); neg(cb, RAX); check_bytes(cb, "48F7D8");
|
||||||
|
|
||||||
|
|
|
@ -165,6 +165,7 @@ ujit_compile_insn(rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* next_uji
|
||||||
st_data_t st_gen_fn;
|
st_data_t st_gen_fn;
|
||||||
if (!rb_st_lookup(gen_fns, opcode, &st_gen_fn))
|
if (!rb_st_lookup(gen_fns, opcode, &st_gen_fn))
|
||||||
{
|
{
|
||||||
|
//print_str(cb, insn_name(opcode));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,6 +195,8 @@ ujit_compile_insn(rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* next_uji
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//print_int(cb, imm_opnd(num_instrs));
|
||||||
|
|
||||||
// Write the adjusted SP back into the CFP
|
// Write the adjusted SP back into the CFP
|
||||||
if (ctx.stack_diff != 0)
|
if (ctx.stack_diff != 0)
|
||||||
{
|
{
|
||||||
|
@ -216,6 +219,7 @@ ujit_compile_insn(rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* next_uji
|
||||||
|
|
||||||
void gen_nop(codeblock_t* cb, ctx_t* ctx)
|
void gen_nop(codeblock_t* cb, ctx_t* ctx)
|
||||||
{
|
{
|
||||||
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
void gen_pop(codeblock_t* cb, ctx_t* ctx)
|
void gen_pop(codeblock_t* cb, ctx_t* ctx)
|
||||||
|
@ -253,7 +257,15 @@ void gen_putobject_int2fix(codeblock_t* cb, ctx_t* ctx)
|
||||||
mov(cb, stack_top, imm_opnd(INT2FIX(cst_val)));
|
mov(cb, stack_top, imm_opnd(INT2FIX(cst_val)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: implement putself
|
void gen_putself(codeblock_t* cb, ctx_t* ctx)
|
||||||
|
{
|
||||||
|
// Load self from CFP
|
||||||
|
mov(cb, RAX, mem_opnd(64, RDI, 24));
|
||||||
|
|
||||||
|
// Write it on the stack
|
||||||
|
x86opnd_t stack_top = ctx_stack_push(ctx, 1);
|
||||||
|
mov(cb, stack_top, RAX);
|
||||||
|
}
|
||||||
|
|
||||||
void gen_getlocal_wc0(codeblock_t* cb, ctx_t* ctx)
|
void gen_getlocal_wc0(codeblock_t* cb, ctx_t* ctx)
|
||||||
{
|
{
|
||||||
|
@ -274,9 +286,9 @@ void gen_getlocal_wc0(codeblock_t* cb, ctx_t* ctx)
|
||||||
|
|
||||||
static void ujit_init()
|
static void ujit_init()
|
||||||
{
|
{
|
||||||
// 4MB ought to be enough for anybody
|
// 64MB ought to be enough for anybody
|
||||||
cb = █
|
cb = █
|
||||||
cb_init(cb, 4000000);
|
cb_init(cb, 64 * 1024 * 1024);
|
||||||
|
|
||||||
// Initialize the codegen function table
|
// Initialize the codegen function table
|
||||||
gen_fns = rb_st_init_numtable();
|
gen_fns = rb_st_init_numtable();
|
||||||
|
@ -288,5 +300,6 @@ static void ujit_init()
|
||||||
st_insert(gen_fns, (st_data_t)BIN(putobject), (st_data_t)&gen_putobject);
|
st_insert(gen_fns, (st_data_t)BIN(putobject), (st_data_t)&gen_putobject);
|
||||||
st_insert(gen_fns, (st_data_t)BIN(putobject_INT2FIX_0_), (st_data_t)&gen_putobject_int2fix);
|
st_insert(gen_fns, (st_data_t)BIN(putobject_INT2FIX_0_), (st_data_t)&gen_putobject_int2fix);
|
||||||
st_insert(gen_fns, (st_data_t)BIN(putobject_INT2FIX_1_), (st_data_t)&gen_putobject_int2fix);
|
st_insert(gen_fns, (st_data_t)BIN(putobject_INT2FIX_1_), (st_data_t)&gen_putobject_int2fix);
|
||||||
|
st_insert(gen_fns, (st_data_t)BIN(putself), (st_data_t)&gen_putself);
|
||||||
st_insert(gen_fns, (st_data_t)BIN(getlocal_WC_0), (st_data_t)&gen_getlocal_wc0);
|
st_insert(gen_fns, (st_data_t)BIN(getlocal_WC_0), (st_data_t)&gen_getlocal_wc0);
|
||||||
}
|
}
|
||||||
|
|
44
ujit_utils.c
44
ujit_utils.c
|
@ -33,43 +33,31 @@ void pop_regs(codeblock_t* cb)
|
||||||
pop(cb, RAX);
|
pop(cb, RAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_str_fn(const char* str)
|
static void print_int_cfun(int64_t val)
|
||||||
{
|
{
|
||||||
printf("%s", str);
|
printf("%lld\n", val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void print_int(codeblock_t* cb, x86opnd_t opnd)
|
||||||
void printInt(CodeBlock as, X86Opnd opnd)
|
|
||||||
{
|
{
|
||||||
extern (C) void printIntFn(int64_t v)
|
push_regs(cb);
|
||||||
{
|
|
||||||
writefln("%s", v);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t opndSz;
|
if (opnd.num_bits < 64 && opnd.type != OPND_IMM)
|
||||||
if (opnd.isImm)
|
movsx(cb, RDI, opnd);
|
||||||
opndSz = 64;
|
|
||||||
else if (opnd.isGPR)
|
|
||||||
opndSz = opnd.reg.size;
|
|
||||||
else if (opnd.isMem)
|
|
||||||
opndSz = opnd.mem.size;
|
|
||||||
else
|
else
|
||||||
assert (false);
|
mov(cb, RDI, opnd);
|
||||||
|
|
||||||
as.pushRegs();
|
|
||||||
|
|
||||||
if (opndSz < 64)
|
|
||||||
as.movsx(cargRegs[0].opnd(64), opnd);
|
|
||||||
else
|
|
||||||
as.mov(cargRegs[0].opnd(64), opnd);
|
|
||||||
|
|
||||||
// Call the print function
|
// Call the print function
|
||||||
as.ptr(scrRegs[0], &printIntFn);
|
mov(cb, RAX, const_ptr_opnd(&print_int_cfun));
|
||||||
as.call(scrRegs[0]);
|
call(cb, RAX);
|
||||||
|
|
||||||
as.popRegs();
|
pop_regs(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_str_cfun(const char* str)
|
||||||
|
{
|
||||||
|
printf("%s\n", str);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
// Print a constant string to stdout
|
// Print a constant string to stdout
|
||||||
void print_str(codeblock_t* cb, const char* str)
|
void print_str(codeblock_t* cb, const char* str)
|
||||||
|
@ -89,7 +77,7 @@ void print_str(codeblock_t* cb, const char* str)
|
||||||
cb_write_byte(cb, 0);
|
cb_write_byte(cb, 0);
|
||||||
|
|
||||||
// Call the print function
|
// Call the print function
|
||||||
mov(cb, RAX, const_ptr_opnd(&print_str_fn));
|
mov(cb, RAX, const_ptr_opnd(&print_str_cfun));
|
||||||
call(cb, RAX);
|
call(cb, RAX);
|
||||||
|
|
||||||
pop_regs(cb);
|
pop_regs(cb);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
void push_regs(codeblock_t* cb);
|
void push_regs(codeblock_t* cb);
|
||||||
void pop_regs(codeblock_t* cb);
|
void pop_regs(codeblock_t* cb);
|
||||||
|
void print_int(codeblock_t* cb, x86opnd_t opnd);
|
||||||
void print_str(codeblock_t* cb, const char* str);
|
void print_str(codeblock_t* cb, const char* str);
|
||||||
|
|
||||||
#endif // #ifndef UJIT_UTILS_H
|
#endif // #ifndef UJIT_UTILS_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue