Added LIR_div/LIR_mod support to x64 Nanojit (bug 516898,

r=njn).
This commit is contained in:
David Anderson 2009-09-17 14:32:12 -07:00
parent 712df10db4
commit 1be03c2e1d
3 changed files with 45 additions and 4 deletions

View File

@ -7526,7 +7526,7 @@ TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1)
if (r == 0.0) if (r == 0.0)
goto out; goto out;
break; break;
#ifdef NANOJIT_IA32 #if defined NANOJIT_IA32 || defined NANOJIT_X64
case LIR_fdiv: case LIR_fdiv:
if (v1 == 0) if (v1 == 0)
goto out; goto out;
@ -7559,7 +7559,7 @@ TraceRecorder::alu(LOpcode v, jsdouble v0, jsdouble v1, LIns* s0, LIns* s1)
VMSideExit* exit; VMSideExit* exit;
LIns* result; LIns* result;
switch (v) { switch (v) {
#ifdef NANOJIT_IA32 #if defined NANOJIT_IA32 || defined NANOJIT_X64
case LIR_fdiv: case LIR_fdiv:
if (d0->isconst() && d1->isconst()) if (d0->isconst() && d1->isconst())
return lir->ins1(LIR_i2f, lir->insImm(jsint(r))); return lir->ins1(LIR_i2f, lir->insImm(jsint(r)));

View File

@ -423,14 +423,53 @@ namespace nanojit
MR(rr, ra); MR(rr, ra);
} }
void Assembler::asm_div_mod(LIns *ins) {
LIns *div;
if (ins->opcode() == LIR_mod) {
// LIR_mod expects the LIR_div to be near
div = ins->oprnd1();
prepResultReg(ins, rmask(RDX));
} else {
div = ins;
evictIfActive(RDX);
}
NanoAssert(div->isop(LIR_div));
LIns *lhs = div->oprnd1();
LIns *rhs = div->oprnd2();
prepResultReg(div, rmask(RAX));
Register rhsReg = findRegFor(rhs, (GpRegs ^ (rmask(RAX)|rmask(RDX))));
Register lhsReg = lhs->isUnusedOrHasUnknownReg()
? findSpecificRegFor(lhs, RAX)
: lhs->getReg();
emitr(X64_idiv, rhsReg);
emit8(rexrb(X64_sari | uint64_t(RDX&7)<<48, (Register)0, RDX), 31);
MR(RDX, RAX);
if (RAX != lhsReg)
MR(RAX, lhsReg);
}
// binary op with integer registers // binary op with integer registers
void Assembler::asm_arith(LIns *ins) { void Assembler::asm_arith(LIns *ins) {
Register rr, ra, rb; Register rr, ra, rb;
LOpcode op = ins->opcode();
if ((op & ~LIR64) >= LIR_lsh && (op & ~LIR64) <= LIR_ush) { switch (ins->opcode() & ~LIR64) {
case LIR_lsh:
case LIR_rsh:
case LIR_ush:
asm_shift(ins); asm_shift(ins);
return; return;
case LIR_mod:
case LIR_div:
asm_div_mod(ins);
return;
default:
break;
} }
LIns *b = ins->oprnd2(); LIns *b = ins->oprnd2();
if (isImm32(b)) { if (isImm32(b)) {
asm_arith_imm(ins); asm_arith_imm(ins);

View File

@ -194,6 +194,7 @@ namespace nanojit
X64_divsd = 0xC05E0F40F2000005LL, // divide scalar double r /= b X64_divsd = 0xC05E0F40F2000005LL, // divide scalar double r /= b
X64_mulsd = 0xC0590F40F2000005LL, // multiply scalar double r *= b X64_mulsd = 0xC0590F40F2000005LL, // multiply scalar double r *= b
X64_addsd = 0xC0580F40F2000005LL, // add scalar double r += b X64_addsd = 0xC0580F40F2000005LL, // add scalar double r += b
X64_idiv = 0xF8F7400000000003LL, // 32bit signed div (rax = rdx:rax/r, rdx=rdx:rax%r)
X64_imul = 0xC0AF0F4000000004LL, // 32bit signed mul r *= b X64_imul = 0xC0AF0F4000000004LL, // 32bit signed mul r *= b
X64_imuli = 0xC069400000000003LL, // 32bit signed mul r = b * imm32 X64_imuli = 0xC069400000000003LL, // 32bit signed mul r = b * imm32
X64_imul8 = 0x00C06B4000000004LL, // 32bit signed mul r = b * imm8 X64_imul8 = 0x00C06B4000000004LL, // 32bit signed mul r = b * imm8
@ -371,6 +372,7 @@ namespace nanojit
void asm_cmp_imm(LIns*);\ void asm_cmp_imm(LIns*);\
void fcmp(LIns*, LIns*);\ void fcmp(LIns*, LIns*);\
NIns* asm_fbranch(bool, LIns*, NIns*);\ NIns* asm_fbranch(bool, LIns*, NIns*);\
void asm_div_mod(LIns *i);\
int max_stk_used; int max_stk_used;
#define swapptrs() { NIns* _tins = _nIns; _nIns=_nExitIns; _nExitIns=_tins; } #define swapptrs() { NIns* _tins = _nIns; _nIns=_nExitIns; _nExitIns=_tins; }