mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Added LIR_div/LIR_mod support to x64 Nanojit (bug 516898,
r=njn).
This commit is contained in:
parent
712df10db4
commit
1be03c2e1d
@ -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)));
|
||||||
|
@ -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);
|
||||||
|
@ -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; }
|
||||||
|
Loading…
Reference in New Issue
Block a user