1
0
Fork 0
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:
Maxime Chevalier-Boisvert 2020-09-18 12:20:43 -04:00 committed by Alan Wu
parent b8a3f2ed61
commit d1c9ca86c1
6 changed files with 127 additions and 31 deletions

View file

@ -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)
{

View file

@ -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);

View file

@ -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");

View file

@ -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 = &block;
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);
}

View file

@ -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);

View file

@ -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