diff options
author | Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> | 2020-09-18 12:20:43 -0400 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2021-10-20 18:19:23 -0400 |
commit | d1c9ca86c191ef92d9bcd1242aeb7eaa35381e6c (patch) | |
tree | 43ca7b474c7be83d01e8dc4663966771c6cdd5ea | |
parent | b8a3f2ed6177c753a35feaa4239a47de0a97ee77 (diff) |
Port print_int, movsx. Implement putself.
-rw-r--r-- | ujit_asm.c | 67 | ||||
-rw-r--r-- | ujit_asm.h | 1 | ||||
-rw-r--r-- | ujit_asm_tests.c | 26 | ||||
-rw-r--r-- | ujit_compile.c | 19 | ||||
-rw-r--r-- | ujit_utils.c | 44 | ||||
-rw-r--r-- | ujit_utils.h | 1 |
6 files changed, 127 insertions, 31 deletions
diff --git a/ujit_asm.c b/ujit_asm.c index 55dc517bdb..8a9cc7f287 100644 --- a/ujit_asm.c +++ b/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) { diff --git a/ujit_asm.h b/ujit_asm.h index 595e20eed1..2ed00b1723 100644 --- a/ujit_asm.h +++ b/ujit_asm.h @@ -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); diff --git a/ujit_asm_tests.c b/ujit_asm_tests.c index 406253ba26..5de7978858 100644 --- a/ujit_asm_tests.c +++ b/ujit_asm_tests.c @@ -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"); diff --git a/ujit_compile.c b/ujit_compile.c index 30657f88bf..84bafe52bd 100644 --- a/ujit_compile.c +++ b/ujit_compile.c @@ -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); } diff --git a/ujit_utils.c b/ujit_utils.c index 35fe8f4f8c..5e535685a1 100644 --- a/ujit_utils.c +++ b/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); - } - - size_t opndSz; - if (opnd.isImm) - opndSz = 64; - else if (opnd.isGPR) - opndSz = opnd.reg.size; - else if (opnd.isMem) - opndSz = opnd.mem.size; - else - assert (false); - - as.pushRegs(); + push_regs(cb); - if (opndSz < 64) - as.movsx(cargRegs[0].opnd(64), opnd); + if (opnd.num_bits < 64 && opnd.type != OPND_IMM) + movsx(cb, RDI, 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); diff --git a/ujit_utils.h b/ujit_utils.h index eaaba4288d..5244d59734 100644 --- a/ujit_utils.h +++ b/ujit_utils.h @@ -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 |