summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ujit_asm.c67
-rw-r--r--ujit_asm.h1
-rw-r--r--ujit_asm_tests.c26
-rw-r--r--ujit_compile.c19
-rw-r--r--ujit_utils.c44
-rw-r--r--ujit_utils.h1
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 = &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);
}
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