Added shift instructions
This commit is contained in:
parent
fe1cd076da
commit
566d4abee5
10
compile.c
10
compile.c
@ -866,12 +866,18 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
VALUE *encoded = (VALUE *)iseq->body->iseq_encoded;
|
VALUE *encoded = (VALUE *)iseq->body->iseq_encoded;
|
||||||
|
|
||||||
for (i = 0; i < iseq->body->iseq_size; /* */ ) {
|
for (i = 0; i < iseq->body->iseq_size; /* */ )
|
||||||
|
{
|
||||||
int insn = (int)iseq->body->iseq_encoded[i];
|
int insn = (int)iseq->body->iseq_encoded[i];
|
||||||
int len = insn_len(insn);
|
int len = insn_len(insn);
|
||||||
encoded[i] = (VALUE)table[insn];
|
encoded[i] = (VALUE)table[insn];
|
||||||
|
|
||||||
if (insn == BIN(pop)) encoded[i] = (VALUE)native_pop_code;
|
if (insn == BIN(pop))
|
||||||
|
encoded[i] = (VALUE)native_pop_code;
|
||||||
|
|
||||||
|
const char* name = insn_name(insn);
|
||||||
|
printf("%s\n", name);
|
||||||
|
|
||||||
|
|
||||||
i += len;
|
i += len;
|
||||||
}
|
}
|
||||||
|
109
ujit_asm.c
109
ujit_asm.c
@ -588,6 +588,56 @@ void cb_write_rm_multi(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Encode a single-operand shift instruction
|
||||||
|
void cb_write_shift(
|
||||||
|
codeblock_t* cb,
|
||||||
|
const char* mnem,
|
||||||
|
uint8_t opMemOnePref,
|
||||||
|
uint8_t opMemClPref,
|
||||||
|
uint8_t opMemImmPref,
|
||||||
|
uint8_t opExt,
|
||||||
|
x86opnd_t opnd0,
|
||||||
|
x86opnd_t opnd1)
|
||||||
|
{
|
||||||
|
// Write a disassembly string
|
||||||
|
//cb.writeASM(mnem, opnd0, opnd1);
|
||||||
|
|
||||||
|
// Check the size of opnd0
|
||||||
|
size_t opndSize;
|
||||||
|
if (opnd0.type == OPND_REG || opnd0.type == OPND_MEM)
|
||||||
|
opndSize = opnd0.num_bits;
|
||||||
|
else
|
||||||
|
assert (false && "shift: invalid first operand");
|
||||||
|
|
||||||
|
assert (opndSize == 16 || opndSize == 32 || opndSize == 64);
|
||||||
|
bool szPref = opndSize == 16;
|
||||||
|
bool rexW = opndSize == 64;
|
||||||
|
|
||||||
|
if (opnd1.type == OPND_IMM)
|
||||||
|
{
|
||||||
|
if (opnd1.imm == 1)
|
||||||
|
{
|
||||||
|
cb_write_rm(cb, szPref, rexW, NO_OPND, opnd0, opExt, 1, opMemOnePref);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (opnd1.num_bits <= 8);
|
||||||
|
cb_write_rm(cb, szPref, rexW, NO_OPND, opnd0, opExt, 1, opMemImmPref);
|
||||||
|
cb_write_byte(cb, (uint8_t)opnd1.imm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
else if (opnd1.isReg && opnd1.reg == CL)
|
||||||
|
{
|
||||||
|
cb.writeRMInstr!('l', opExt, opMemClPref)(szPref, rexW, opnd0, X86Opnd.NONE);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add - Integer addition
|
// add - Integer addition
|
||||||
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
void add(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
||||||
{
|
{
|
||||||
@ -893,6 +943,65 @@ void ret(codeblock_t* cb)
|
|||||||
cb_write_byte(cb, 0xC3);
|
cb_write_byte(cb, 0xC3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sal - Shift arithmetic left
|
||||||
|
void sal(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
||||||
|
{
|
||||||
|
cb_write_shift(
|
||||||
|
cb,
|
||||||
|
"sal",
|
||||||
|
0xD1, // opMemOnePref,
|
||||||
|
0xD3, // opMemClPref,
|
||||||
|
0xC1, // opMemImmPref,
|
||||||
|
0x04,
|
||||||
|
opnd0,
|
||||||
|
opnd1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// sar - Shift arithmetic right (signed)
|
||||||
|
void sar(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
||||||
|
{
|
||||||
|
cb_write_shift(
|
||||||
|
cb,
|
||||||
|
"sar",
|
||||||
|
0xD1, // opMemOnePref,
|
||||||
|
0xD3, // opMemClPref,
|
||||||
|
0xC1, // opMemImmPref,
|
||||||
|
0x07,
|
||||||
|
opnd0,
|
||||||
|
opnd1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// shl - Shift logical left
|
||||||
|
void shl(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
||||||
|
{
|
||||||
|
cb_write_shift(
|
||||||
|
cb,
|
||||||
|
"shl",
|
||||||
|
0xD1, // opMemOnePref,
|
||||||
|
0xD3, // opMemClPref,
|
||||||
|
0xC1, // opMemImmPref,
|
||||||
|
0x04,
|
||||||
|
opnd0,
|
||||||
|
opnd1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// shr - Shift logical right (unsigned)
|
||||||
|
void shr(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
||||||
|
{
|
||||||
|
cb_write_shift(
|
||||||
|
cb,
|
||||||
|
"shr",
|
||||||
|
0xD1, // opMemOnePref,
|
||||||
|
0xD3, // opMemClPref,
|
||||||
|
0xC1, // opMemImmPref,
|
||||||
|
0x05,
|
||||||
|
opnd0,
|
||||||
|
opnd1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// sub - Integer subtraction
|
/// sub - Integer subtraction
|
||||||
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
|
||||||
{
|
{
|
||||||
|
@ -194,6 +194,10 @@ void nop(codeblock_t* cb, size_t length);
|
|||||||
void push(codeblock_t* cb, x86opnd_t reg);
|
void push(codeblock_t* cb, x86opnd_t reg);
|
||||||
void pop(codeblock_t* cb, x86opnd_t reg);
|
void pop(codeblock_t* cb, x86opnd_t reg);
|
||||||
void ret(codeblock_t* cb);
|
void ret(codeblock_t* cb);
|
||||||
|
void sal(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||||
|
void sar(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||||
|
void shl(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||||
|
void shr(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||||
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -156,16 +156,35 @@ void run_tests()
|
|||||||
// ret
|
// ret
|
||||||
cb_set_pos(cb, 0); ret(cb); check_bytes(cb, "C3");
|
cb_set_pos(cb, 0); ret(cb); check_bytes(cb, "C3");
|
||||||
|
|
||||||
|
// sal
|
||||||
|
/*
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.sal(X86Opnd(CX), X86Opnd(1)); },
|
||||||
|
"66D1E1"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
cb_set_pos(cb, 0); sal(cb, ECX, imm_opnd(1)); check_bytes(cb, "D1E1");
|
||||||
|
cb_set_pos(cb, 0); sal(cb, EBP, imm_opnd(5)); check_bytes(cb, "C1E505");
|
||||||
|
cb_set_pos(cb, 0); sal(cb, mem_opnd(32, RSP, 68), imm_opnd(1)); check_bytes(cb, "D1642444");
|
||||||
|
|
||||||
|
// sar
|
||||||
|
cb_set_pos(cb, 0); sar(cb, EDX, imm_opnd(1)); check_bytes(cb, "D1FA");
|
||||||
|
|
||||||
|
// shr
|
||||||
|
cb_set_pos(cb, 0); shr(cb, R14, imm_opnd(7)); check_bytes(cb, "49C1EE07");
|
||||||
|
|
||||||
|
/*
|
||||||
|
// sqrtsd
|
||||||
|
test(
|
||||||
|
delegate void (CodeBlock cb) { cb.sqrtsd(X86Opnd(XMM2), X86Opnd(XMM6)); },
|
||||||
|
"F20F51D6"
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
// sub
|
// sub
|
||||||
cb_set_pos(cb, 0); sub(cb, EAX, imm_opnd(1)); check_bytes(cb, "83E801");
|
cb_set_pos(cb, 0); sub(cb, EAX, imm_opnd(1)); check_bytes(cb, "83E801");
|
||||||
cb_set_pos(cb, 0); sub(cb, RAX, imm_opnd(2)); check_bytes(cb, "4883E802");
|
cb_set_pos(cb, 0); sub(cb, RAX, imm_opnd(2)); check_bytes(cb, "4883E802");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printf("Assembler tests done\n");
|
printf("Assembler tests done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user