diff options
author | Balazs Kilvady <kilvadyb@homejinni.com> | 2013-02-18 19:25:23 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-05-23 13:38:58 +0200 |
commit | fee41053a81024e15303ebf68e6a9a029374ce92 (patch) | |
tree | 96fa2176827f2cd601f789d27170f5222d185d25 /Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h | |
parent | 9147a90a7bdf8a0791efa9d677a0f36ffdb75533 (diff) | |
download | qtwebkit-fee41053a81024e15303ebf68e6a9a029374ce92.tar.gz |
MIPS DFG implementation.
https://bugs.webkit.org/show_bug.cgi?id=101328
Patch by Balazs Kilvady <kilvadyb@homejinni.com> on 2013-02-18
Reviewed by Oliver Hunt.
DFG implementation for MIPS.
Source/JavaScriptCore:
* assembler/MIPSAssembler.h:
(JSC::MIPSAssembler::MIPSAssembler):
(JSC::MIPSAssembler::sllv):
(JSC::MIPSAssembler::movd):
(MIPSAssembler):
(JSC::MIPSAssembler::negd):
(JSC::MIPSAssembler::labelForWatchpoint):
(JSC::MIPSAssembler::label):
(JSC::MIPSAssembler::vmov):
(JSC::MIPSAssembler::linkDirectJump):
(JSC::MIPSAssembler::maxJumpReplacementSize):
(JSC::MIPSAssembler::revertJumpToMove):
(JSC::MIPSAssembler::replaceWithJump):
* assembler/MacroAssembler.h:
(MacroAssembler):
(JSC::MacroAssembler::poke):
* assembler/MacroAssemblerMIPS.h:
(JSC::MacroAssemblerMIPS::add32):
(MacroAssemblerMIPS):
(JSC::MacroAssemblerMIPS::and32):
(JSC::MacroAssemblerMIPS::lshift32):
(JSC::MacroAssemblerMIPS::mul32):
(JSC::MacroAssemblerMIPS::or32):
(JSC::MacroAssemblerMIPS::rshift32):
(JSC::MacroAssemblerMIPS::urshift32):
(JSC::MacroAssemblerMIPS::sub32):
(JSC::MacroAssemblerMIPS::xor32):
(JSC::MacroAssemblerMIPS::store32):
(JSC::MacroAssemblerMIPS::jump):
(JSC::MacroAssemblerMIPS::branchAdd32):
(JSC::MacroAssemblerMIPS::branchMul32):
(JSC::MacroAssemblerMIPS::branchSub32):
(JSC::MacroAssemblerMIPS::branchNeg32):
(JSC::MacroAssemblerMIPS::call):
(JSC::MacroAssemblerMIPS::loadDouble):
(JSC::MacroAssemblerMIPS::moveDouble):
(JSC::MacroAssemblerMIPS::swapDouble):
(JSC::MacroAssemblerMIPS::subDouble):
(JSC::MacroAssemblerMIPS::mulDouble):
(JSC::MacroAssemblerMIPS::divDouble):
(JSC::MacroAssemblerMIPS::negateDouble):
(JSC::MacroAssemblerMIPS::branchEqual):
(JSC::MacroAssemblerMIPS::branchNotEqual):
(JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
(JSC::MacroAssemblerMIPS::branchTruncateDoubleToUint32):
(JSC::MacroAssemblerMIPS::truncateDoubleToInt32):
(JSC::MacroAssemblerMIPS::truncateDoubleToUint32):
(JSC::MacroAssemblerMIPS::branchDoubleNonZero):
(JSC::MacroAssemblerMIPS::branchDoubleZeroOrNaN):
(JSC::MacroAssemblerMIPS::invert):
(JSC::MacroAssemblerMIPS::replaceWithJump):
(JSC::MacroAssemblerMIPS::maxJumpReplacementSize):
* dfg/DFGAssemblyHelpers.h:
(AssemblyHelpers):
(JSC::DFG::AssemblyHelpers::preserveReturnAddressAfterCall):
(JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):
(JSC::DFG::AssemblyHelpers::debugCall):
* dfg/DFGCCallHelpers.h:
(CCallHelpers):
(JSC::DFG::CCallHelpers::setupArguments):
(JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
* dfg/DFGFPRInfo.h:
(DFG):
(FPRInfo):
(JSC::DFG::FPRInfo::toRegister):
(JSC::DFG::FPRInfo::toIndex):
(JSC::DFG::FPRInfo::debugName):
* dfg/DFGGPRInfo.h:
(DFG):
(GPRInfo):
(JSC::DFG::GPRInfo::toRegister):
(JSC::DFG::GPRInfo::toIndex):
(JSC::DFG::GPRInfo::debugName):
* dfg/DFGSpeculativeJIT.h:
(SpeculativeJIT):
* jit/JSInterfaceJIT.h:
(JSInterfaceJIT):
* runtime/JSGlobalData.h:
(JSC::ScratchBuffer::allocationSize):
(ScratchBuffer):
Source/WTF:
* wtf/Platform.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@143247 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Conflicts:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
Source/WTF/ChangeLog
Change-Id: Ibc6c2a2b1d5c70d351ede37c6c111b66b4cf7fef
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h')
-rw-r--r-- | Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h | 480 |
1 files changed, 454 insertions, 26 deletions
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h index 44f94caec..f5298a0ab 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h @@ -114,6 +114,11 @@ public: m_assembler.addu(dest, dest, src); } + void add32(RegisterID op1, RegisterID op2, RegisterID dest) + { + m_assembler.addu(dest, op1, op2); + } + void add32(TrustedImm32 imm, RegisterID dest) { add32(imm, dest, dest); @@ -249,6 +254,11 @@ public: m_assembler.andInsn(dest, dest, src); } + void and32(RegisterID op1, RegisterID op2, RegisterID dest) + { + m_assembler.andInsn(dest, op1, op2); + } + void and32(TrustedImm32 imm, RegisterID dest) { if (!imm.m_value && !m_fixedWidth) @@ -265,9 +275,16 @@ public: } } - void lshift32(TrustedImm32 imm, RegisterID dest) + void and32(TrustedImm32 imm, RegisterID src, RegisterID dest) { - m_assembler.sll(dest, dest, imm.m_value); + if (!imm.m_value && !m_fixedWidth) + move(MIPSRegisters::zero, dest); + else if (imm.m_value > 0 && imm.m_value < 65535 && !m_fixedWidth) + m_assembler.andi(dest, src, imm.m_value); + else { + move(imm, immTempRegister); + m_assembler.andInsn(dest, src, immTempRegister); + } } void lshift32(RegisterID shiftAmount, RegisterID dest) @@ -275,11 +292,33 @@ public: m_assembler.sllv(dest, dest, shiftAmount); } + void lshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) + { + m_assembler.sllv(dest, src, shiftAmount); + } + + void lshift32(TrustedImm32 imm, RegisterID dest) + { + move(imm, immTempRegister); + m_assembler.sllv(dest, dest, immTempRegister); + } + + void lshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + move(imm, immTempRegister); + m_assembler.sllv(dest, src, immTempRegister); + } + void mul32(RegisterID src, RegisterID dest) { m_assembler.mul(dest, dest, src); } + void mul32(RegisterID op1, RegisterID op2, RegisterID dest) + { + m_assembler.mul(dest, op1, op2); + } + void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest) { if (!imm.m_value && !m_fixedWidth) @@ -330,6 +369,24 @@ public: m_assembler.orInsn(dest, dest, dataTempRegister); } + void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + if (!imm.m_value && !m_fixedWidth) + return; + + if (imm.m_value > 0 && imm.m_value < 65535 && !m_fixedWidth) { + m_assembler.ori(dest, src, imm.m_value); + return; + } + + /* + li dataTemp, imm + or dest, src, dataTemp + */ + move(imm, dataTempRegister); + m_assembler.orInsn(dest, src, dataTempRegister); + } + void or32(RegisterID src, AbsoluteAddress dest) { load32(dest.m_ptr, dataTempRegister); @@ -342,6 +399,11 @@ public: m_assembler.srav(dest, dest, shiftAmount); } + void rshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) + { + m_assembler.srav(dest, src, shiftAmount); + } + void rshift32(TrustedImm32 imm, RegisterID dest) { m_assembler.sra(dest, dest, imm.m_value); @@ -357,16 +419,31 @@ public: m_assembler.srlv(dest, dest, shiftAmount); } + void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) + { + m_assembler.srlv(dest, src, shiftAmount); + } + void urshift32(TrustedImm32 imm, RegisterID dest) { m_assembler.srl(dest, dest, imm.m_value); } + void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) + { + m_assembler.srl(dest, src, imm.m_value); + } + void sub32(RegisterID src, RegisterID dest) { m_assembler.subu(dest, dest, src); } + void sub32(RegisterID op1, RegisterID op2, RegisterID dest) + { + m_assembler.subu(dest, op1, op2); + } + void sub32(TrustedImm32 imm, RegisterID dest) { if (imm.m_value >= -32767 && imm.m_value <= 32768 @@ -477,6 +554,11 @@ public: m_assembler.xorInsn(dest, dest, src); } + void xor32(RegisterID op1, RegisterID op2, RegisterID dest) + { + m_assembler.xorInsn(dest, op1, op2); + } + void xor32(TrustedImm32 imm, RegisterID dest) { if (imm.m_value == -1) { @@ -492,6 +574,21 @@ public: m_assembler.xorInsn(dest, dest, immTempRegister); } + void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + if (imm.m_value == -1) { + m_assembler.nor(dest, src, MIPSRegisters::zero); + return; + } + + /* + li immTemp, imm + xor dest, dest, immTemp + */ + move(imm, immTempRegister); + m_assembler.xorInsn(dest, src, immTempRegister); + } + void sqrtDouble(FPRegisterID src, FPRegisterID dst) { m_assembler.sqrtd(dst, src); @@ -971,6 +1068,44 @@ public: } } + void store32(TrustedImm32 imm, BaseIndex address) + { + if (address.offset >= -32768 && address.offset <= 32767 && !m_fixedWidth) { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + sw src, address.offset(addrTemp) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + if (!imm.m_value) + m_assembler.sw(MIPSRegisters::zero, addrTempRegister, address.offset); + else { + move(imm, immTempRegister); + m_assembler.sw(immTempRegister, addrTempRegister, address.offset); + } + } else { + /* + sll addrTemp, address.index, address.scale + addu addrTemp, addrTemp, address.base + lui immTemp, (address.offset + 0x8000) >> 16 + addu addrTemp, addrTemp, immTemp + sw src, (address.offset & 0xffff)(at) + */ + m_assembler.sll(addrTempRegister, address.index, address.scale); + m_assembler.addu(addrTempRegister, addrTempRegister, address.base); + m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16); + m_assembler.addu(addrTempRegister, addrTempRegister, immTempRegister); + if (!imm.m_value && !m_fixedWidth) + m_assembler.sw(MIPSRegisters::zero, addrTempRegister, address.offset); + else { + move(imm, immTempRegister); + m_assembler.sw(immTempRegister, addrTempRegister, address.offset); + } + } + } + + void store32(RegisterID src, const void* address) { /* @@ -1318,6 +1453,15 @@ public: m_fixedWidth = false; } + void jump(AbsoluteAddress address) + { + m_fixedWidth = true; + load32(address.m_ptr, MIPSRegisters::t9); + m_assembler.jr(MIPSRegisters::t9); + m_assembler.nop(); + m_fixedWidth = false; + } + void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) { m_assembler.vmov(dest1, dest2, src); @@ -1386,6 +1530,53 @@ public: return Jump(); } + Jump branchAdd32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + if (cond == Overflow) { + /* + move dataTemp, op1 + xor cmpTemp, dataTemp, op2 + bltz cmpTemp, No_overflow # diff sign bit -> no overflow + addu dest, dataTemp, op2 + xor cmpTemp, dest, dataTemp + bgez cmpTemp, No_overflow # same sign big -> no overflow + nop + b Overflow + nop + nop + nop + nop + nop + No_overflow: + */ + move(op1, dataTempRegister); + m_assembler.xorInsn(cmpTempRegister, dataTempRegister, op2); + m_assembler.bltz(cmpTempRegister, 10); + m_assembler.addu(dest, dataTempRegister, op2); + m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister); + m_assembler.bgez(cmpTempRegister, 7); + m_assembler.nop(); + return jump(); + } + if (cond == Signed) { + add32(op1, op2, dest); + // Check if dest is negative. + m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero); + return branchNotEqual(cmpTempRegister, MIPSRegisters::zero); + } + if (cond == Zero) { + add32(op1, op2, dest); + return branchEqual(dest, MIPSRegisters::zero); + } + if (cond == NonZero) { + add32(op1, op2, dest); + return branchNotEqual(dest, MIPSRegisters::zero); + } + ASSERT(0); + return Jump(); + } + Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest) { move(imm, immTempRegister); @@ -1399,6 +1590,111 @@ public: return branchAdd32(cond, immTempRegister, dest); } + Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + if (cond == Overflow) { + /* + move dataTemp, dest + xori cmpTemp, dataTemp, imm + bltz cmpTemp, No_overflow # diff sign bit -> no overflow + addiu dataTemp, dataTemp, imm + move dest, dataTemp + xori cmpTemp, dataTemp, imm + bgez cmpTemp, No_overflow # same sign big -> no overflow + nop + b Overflow + nop + nop + nop + nop + nop + No_overflow: + */ + if (imm.m_value >= -32768 && imm.m_value <= 32767 && !m_fixedWidth) { + load32(dest.m_ptr, dataTempRegister); + m_assembler.xori(cmpTempRegister, dataTempRegister, imm.m_value); + m_assembler.bltz(cmpTempRegister, 10); + m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value); + store32(dataTempRegister, dest.m_ptr); + m_assembler.xori(cmpTempRegister, dataTempRegister, imm.m_value); + m_assembler.bgez(cmpTempRegister, 7); + m_assembler.nop(); + } else { + load32(dest.m_ptr, dataTempRegister); + move(imm, immTempRegister); + m_assembler.xorInsn(cmpTempRegister, dataTempRegister, immTempRegister); + m_assembler.bltz(cmpTempRegister, 10); + m_assembler.addiu(dataTempRegister, dataTempRegister, immTempRegister); + store32(dataTempRegister, dest.m_ptr); + m_assembler.xori(cmpTempRegister, dataTempRegister, immTempRegister); + m_assembler.bgez(cmpTempRegister, 7); + m_assembler.nop(); + } + return jump(); + } + move(imm, immTempRegister); + load32(dest.m_ptr, dataTempRegister); + add32(immTempRegister, dataTempRegister); + store32(dataTempRegister, dest.m_ptr); + if (cond == Signed) { + // Check if dest is negative. + m_assembler.slt(cmpTempRegister, dataTempRegister, MIPSRegisters::zero); + return branchNotEqual(cmpTempRegister, MIPSRegisters::zero); + } + if (cond == Zero) + return branchEqual(dataTempRegister, MIPSRegisters::zero); + if (cond == NonZero) + return branchNotEqual(dataTempRegister, MIPSRegisters::zero); + ASSERT(0); + return Jump(); + } + + Jump branchMul32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + if (cond == Overflow) { + /* + mult src, dest + mfhi dataTemp + mflo dest + sra addrTemp, dest, 31 + beq dataTemp, addrTemp, No_overflow # all sign bits (bit 63 to bit 31) are the same -> no overflow + nop + b Overflow + nop + nop + nop + nop + nop + No_overflow: + */ + m_assembler.mult(src1, src2); + m_assembler.mfhi(dataTempRegister); + m_assembler.mflo(dest); + m_assembler.sra(addrTempRegister, dest, 31); + m_assembler.beq(dataTempRegister, addrTempRegister, 7); + m_assembler.nop(); + return jump(); + } + if (cond == Signed) { + mul32(src1, src2, dest); + // Check if dest is negative. + m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero); + return branchNotEqual(cmpTempRegister, MIPSRegisters::zero); + } + if (cond == Zero) { + mul32(src1, src2, dest); + return branchEqual(dest, MIPSRegisters::zero); + } + if (cond == NonZero) { + mul32(src1, src2, dest); + return branchNotEqual(dest, MIPSRegisters::zero); + } + ASSERT(0); + return Jump(); + } + Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); @@ -1447,8 +1743,7 @@ public: Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest) { move(imm, immTempRegister); - move(src, dest); - return branchMul32(cond, immTempRegister, dest); + return branchMul32(cond, immTempRegister, src, dest); } Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest) @@ -1507,8 +1802,60 @@ public: Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) { move(imm, immTempRegister); - move(src, dest); - return branchSub32(cond, immTempRegister, dest); + return branchSub32(cond, src, immTempRegister, dest); + } + + Jump branchSub32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + if (cond == Overflow) { + /* + move dataTemp, op1 + xor cmpTemp, dataTemp, op2 + bgez cmpTemp, No_overflow # same sign bit -> no overflow + subu dest, dataTemp, op2 + xor cmpTemp, dest, dataTemp + bgez cmpTemp, No_overflow # same sign bit -> no overflow + nop + b Overflow + nop + nop + nop + nop + nop + No_overflow: + */ + move(op1, dataTempRegister); + m_assembler.xorInsn(cmpTempRegister, dataTempRegister, op2); + m_assembler.bgez(cmpTempRegister, 10); + m_assembler.subu(dest, dataTempRegister, op2); + m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister); + m_assembler.bgez(cmpTempRegister, 7); + m_assembler.nop(); + return jump(); + } + if (cond == Signed) { + sub32(op1, op2, dest); + // Check if dest is negative. + m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero); + return branchNotEqual(cmpTempRegister, MIPSRegisters::zero); + } + if (cond == Zero) { + sub32(op1, op2, dest); + return branchEqual(dest, MIPSRegisters::zero); + } + if (cond == NonZero) { + sub32(op1, op2, dest); + return branchNotEqual(dest, MIPSRegisters::zero); + } + ASSERT(0); + return Jump(); + } + + Jump branchNeg32(ResultCondition cond, RegisterID srcDest) + { + m_assembler.li(dataTempRegister, -1); + return branchMul32(cond, dataTempRegister, srcDest); } Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest) @@ -1560,7 +1907,8 @@ public: Call call(RegisterID target) { - m_assembler.jalr(target); + move(target, MIPSRegisters::t9); + m_assembler.jalr(MIPSRegisters::t9); m_assembler.nop(); return Call(m_assembler.label(), Call::None); } @@ -1804,7 +2152,7 @@ public: lui immTemp, (address.offset + 0x8000) >> 16 addu addrTemp, addrTemp, immTemp lwc1 dest, (address.offset & 0xffff)(at) - lwc1 dest+4, (address.offset & 0xffff + 4)(at) + lwc1 dest+1, (address.offset & 0xffff + 4)(at) */ m_assembler.sll(addrTempRegister, address.index, address.scale); m_assembler.addu(addrTempRegister, addrTempRegister, address.base); @@ -1991,6 +2339,19 @@ public: #endif } + void moveDouble(FPRegisterID src, FPRegisterID dest) + { + if (src != dest || m_fixedWidth) + m_assembler.movd(dest, src); + } + + void swapDouble(FPRegisterID fr1, FPRegisterID fr2) + { + moveDouble(fr1, fpTempRegister); + moveDouble(fr2, fr1); + moveDouble(fpTempRegister, fr2); + } + void addDouble(FPRegisterID src, FPRegisterID dest) { m_assembler.addd(dest, dest, src); @@ -2018,6 +2379,11 @@ public: m_assembler.subd(dest, dest, src); } + void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + m_assembler.subd(dest, op1, op2); + } + void subDouble(Address src, FPRegisterID dest) { loadDouble(src, fpTempRegister); @@ -2035,11 +2401,32 @@ public: m_assembler.muld(dest, dest, fpTempRegister); } + void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + m_assembler.muld(dest, op1, op2); + } + void divDouble(FPRegisterID src, FPRegisterID dest) { m_assembler.divd(dest, dest, src); } + void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + m_assembler.divd(dest, op1, op2); + } + + void divDouble(Address src, FPRegisterID dest) + { + loadDouble(src, fpTempRegister); + m_assembler.divd(dest, dest, fpTempRegister); + } + + void negateDouble(FPRegisterID src, FPRegisterID dest) + { + m_assembler.negd(dest, src); + } + void convertInt32ToDouble(RegisterID src, FPRegisterID dest) { m_assembler.mtc1(src, fpTempRegister); @@ -2099,6 +2486,8 @@ public: Jump branchEqual(RegisterID rs, RegisterID rt) { + m_assembler.nop(); + m_assembler.nop(); m_assembler.appendJump(); m_assembler.beq(rs, rt, 0); m_assembler.nop(); @@ -2108,6 +2497,8 @@ public: Jump branchNotEqual(RegisterID rs, RegisterID rt) { + m_assembler.nop(); + m_assembler.nop(); m_assembler.appendJump(); m_assembler.bne(rs, rt, 0); m_assembler.nop(); @@ -2174,11 +2565,33 @@ public: // If the result is not representable as a 32 bit value, branch. // May also branch for some values that are representable in 32 bits // (specifically, in this case, INT_MAX 0x7fffffff). - Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest) + enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful }; + Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed) + { + m_assembler.truncwd(fpTempRegister, src); + m_assembler.mfc1(dest, fpTempRegister); + return branch32(branchType == BranchIfTruncateFailed ? Equal : NotEqual, dest, TrustedImm32(0x7fffffff)); + } + + Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed) + { + m_assembler.truncwd(fpTempRegister, src); + m_assembler.mfc1(dest, fpTempRegister); + return branch32(branchType == BranchIfTruncateFailed ? Equal : NotEqual, dest, TrustedImm32(0)); + } + + // Result is undefined if the value is outside of the integer range. + void truncateDoubleToInt32(FPRegisterID src, RegisterID dest) + { + m_assembler.truncwd(fpTempRegister, src); + m_assembler.mfc1(dest, fpTempRegister); + } + + // Result is undefined if src > 2^31 + void truncateDoubleToUint32(FPRegisterID src, RegisterID dest) { m_assembler.truncwd(fpTempRegister, src); m_assembler.mfc1(dest, fpTempRegister); - return branch32(Equal, dest, TrustedImm32(0x7fffffff)); } // Convert 'src' to an integer, and places the resulting 'dest'. @@ -2200,28 +2613,43 @@ public: Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch) { -#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64 - m_assembler.mtc1(MIPSRegisters::zero, scratch); - m_assembler.mthc1(MIPSRegisters::zero, scratch); -#else - m_assembler.mtc1(MIPSRegisters::zero, scratch); - m_assembler.mtc1(MIPSRegisters::zero, FPRegisterID(scratch + 1)); -#endif + m_assembler.vmov(scratch, MIPSRegisters::zero, MIPSRegisters::zero); return branchDouble(DoubleNotEqual, reg, scratch); } Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID scratch) { -#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64 - m_assembler.mtc1(MIPSRegisters::zero, scratch); - m_assembler.mthc1(MIPSRegisters::zero, scratch); -#else - m_assembler.mtc1(MIPSRegisters::zero, scratch); - m_assembler.mtc1(MIPSRegisters::zero, FPRegisterID(scratch + 1)); -#endif + m_assembler.vmov(scratch, MIPSRegisters::zero, MIPSRegisters::zero); return branchDouble(DoubleEqualOrUnordered, reg, scratch); } + // Invert a relational condition, e.g. == becomes !=, < becomes >=, etc. + static RelationalCondition invert(RelationalCondition cond) + { + RelationalCondition r; + if (cond == Equal) + r = NotEqual; + else if (cond == NotEqual) + r = Equal; + else if (cond == Above) + r = BelowOrEqual; + else if (cond == AboveOrEqual) + r = Below; + else if (cond == Below) + r = AboveOrEqual; + else if (cond == BelowOrEqual) + r = Above; + else if (cond == GreaterThan) + r = LessThanOrEqual; + else if (cond == GreaterThanOrEqual) + r = LessThan; + else if (cond == LessThan) + r = GreaterThanOrEqual; + else if (cond == LessThanOrEqual) + r = GreaterThan; + return r; + } + void nop() { m_assembler.nop(); @@ -2234,12 +2662,12 @@ public: static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination) { - ASSERT_NOT_REACHED(); + MIPSAssembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation()); } static ptrdiff_t maxJumpReplacementSize() { - ASSERT_NOT_REACHED(); + MIPSAssembler::maxJumpReplacementSize(); return 0; } |