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)
|
||||
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 lea(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 nop(codeblock_t* cb, size_t length);
|
||||
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(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
|
||||
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;
|
||||
if (!rb_st_lookup(gen_fns, opcode, &st_gen_fn))
|
||||
{
|
||||
//print_str(cb, insn_name(opcode));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -194,6 +195,8 @@ ujit_compile_insn(rb_iseq_t *iseq, unsigned int insn_idx, unsigned int* next_uji
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//print_int(cb, imm_opnd(num_instrs));
|
||||
|
||||
// Write the adjusted SP back into the CFP
|
||||
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)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
|
@ -274,9 +286,9 @@ void gen_getlocal_wc0(codeblock_t* cb, ctx_t* ctx)
|
|||
|
||||
static void ujit_init()
|
||||
{
|
||||
// 4MB ought to be enough for anybody
|
||||
// 64MB ought to be enough for anybody
|
||||
cb = █
|
||||
cb_init(cb, 4000000);
|
||||
cb_init(cb, 64 * 1024 * 1024);
|
||||
|
||||
// Initialize the codegen function table
|
||||
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_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(putself), (st_data_t)&gen_putself);
|
||||
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);
|
||||
}
|
||||
|
||||
static void print_str_fn(const char* str)
|
||||
static void print_int_cfun(int64_t val)
|
||||
{
|
||||
printf("%s", str);
|
||||
printf("%lld\n", val);
|
||||
}
|
||||
|
||||
/*
|
||||
void printInt(CodeBlock as, X86Opnd opnd)
|
||||
void print_int(codeblock_t* cb, x86opnd_t opnd)
|
||||
{
|
||||
extern (C) void printIntFn(int64_t v)
|
||||
{
|
||||
writefln("%s", v);
|
||||
}
|
||||
push_regs(cb);
|
||||
|
||||
size_t opndSz;
|
||||
if (opnd.isImm)
|
||||
opndSz = 64;
|
||||
else if (opnd.isGPR)
|
||||
opndSz = opnd.reg.size;
|
||||
else if (opnd.isMem)
|
||||
opndSz = opnd.mem.size;
|
||||
if (opnd.num_bits < 64 && opnd.type != OPND_IMM)
|
||||
movsx(cb, RDI, opnd);
|
||||
else
|
||||
assert (false);
|
||||
|
||||
as.pushRegs();
|
||||
|
||||
if (opndSz < 64)
|
||||
as.movsx(cargRegs[0].opnd(64), opnd);
|
||||
else
|
||||
as.mov(cargRegs[0].opnd(64), opnd);
|
||||
mov(cb, RDI, opnd);
|
||||
|
||||
// Call the print function
|
||||
as.ptr(scrRegs[0], &printIntFn);
|
||||
as.call(scrRegs[0]);
|
||||
mov(cb, RAX, const_ptr_opnd(&print_int_cfun));
|
||||
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
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
pop_regs(cb);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
void push_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);
|
||||
|
||||
#endif // #ifndef UJIT_UTILS_H
|
||||
|
|
Loading…
Add table
Reference in a new issue