1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Added shift instructions

This commit is contained in:
Maxime Chevalier-Boisvert 2020-09-10 14:31:45 -04:00 committed by Alan Wu
parent fe1cd076da
commit 566d4abee5
4 changed files with 151 additions and 13 deletions

View file

@ -866,14 +866,20 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
unsigned int i;
VALUE *encoded = (VALUE *)iseq->body->iseq_encoded;
for (i = 0; i < iseq->body->iseq_size; /* */ ) {
int insn = (int)iseq->body->iseq_encoded[i];
int len = insn_len(insn);
encoded[i] = (VALUE)table[insn];
for (i = 0; i < iseq->body->iseq_size; /* */ )
{
int insn = (int)iseq->body->iseq_encoded[i];
int len = insn_len(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;
i += len;
const char* name = insn_name(insn);
printf("%s\n", name);
i += len;
}
FL_SET((VALUE)iseq, ISEQ_TRANSLATED);
#endif

View file

@ -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
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);
}
// 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
void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
{
@ -906,7 +1015,7 @@ void sub(codeblock_t* cb, x86opnd_t opnd0, x86opnd_t opnd1)
0x80, // opMemImm8
0x83, // opMemImmSml
0x81, // opMemImmLrg
0x05, // opExtImm
0x05, // opExtImm
opnd0,
opnd1
);

View file

@ -194,6 +194,10 @@ void nop(codeblock_t* cb, size_t length);
void push(codeblock_t* cb, x86opnd_t reg);
void pop(codeblock_t* cb, x86opnd_t reg);
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);
#endif

View file

@ -156,16 +156,35 @@ void run_tests()
// ret
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
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");
printf("Assembler tests done\n");
}