diff options
author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
tree | e367e64a75991c554930278175d403c072de6bb8 /Source/JavaScriptCore/assembler/MacroAssemblerSH4.h | |
parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/assembler/MacroAssemblerSH4.h')
-rw-r--r-- | Source/JavaScriptCore/assembler/MacroAssemblerSH4.h | 1404 |
1 files changed, 810 insertions, 594 deletions
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h index 0c7fe12c6..ad5acfaeb 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2013 Cisco Systems, Inc. All rights reserved. * Copyright (C) 2009-2011 STMicroelectronics. All rights reserved. * Copyright (C) 2008 Apple Inc. All rights reserved. * @@ -40,7 +41,7 @@ public: typedef SH4Assembler::FPRegisterID FPRegisterID; static const Scale ScalePtr = TimesFour; - static const FPRegisterID fscratch = SH4Registers::fr10; + static const FPRegisterID fscratch = SH4Registers::dr10; static const RegisterID stackPointerRegister = SH4Registers::sp; static const RegisterID linkRegister = SH4Registers::pr; static const RegisterID scratchReg3 = SH4Registers::r13; @@ -49,7 +50,7 @@ public: static bool isCompactPtrAlignedAddressOffset(ptrdiff_t value) { - return (value >= 0) && (value <= MaximumCompactPtrAlignedAddressOffset); + return (value >= 0) && (value <= MaximumCompactPtrAlignedAddressOffset) && (!(value & 3)); } enum RelationalCondition { @@ -68,6 +69,7 @@ public: enum ResultCondition { Overflow = SH4Assembler::OF, Signed = SH4Assembler::SI, + PositiveOrZero = SH4Assembler::NS, Zero = SH4Assembler::EQ, NonZero = SH4Assembler::NE }; @@ -99,6 +101,34 @@ public: m_assembler.releaseScratch(reg); } + static RelationalCondition invert(RelationalCondition cond) + { + switch (cond) { + case Equal: + return NotEqual; + case NotEqual: + return Equal; + case Above: + return BelowOrEqual; + case AboveOrEqual: + return Below; + case Below: + return AboveOrEqual; + case BelowOrEqual: + return Above; + case GreaterThan: + return LessThanOrEqual; + case GreaterThanOrEqual: + return LessThan; + case LessThan: + return GreaterThanOrEqual; + case LessThanOrEqual: + return GreaterThan; + default: + RELEASE_ASSERT_NOT_REACHED(); + } + } + // Integer arithmetic operations void add32(RegisterID src, RegisterID dest) @@ -106,8 +136,21 @@ public: m_assembler.addlRegReg(src, dest); } + void add32(RegisterID src1, RegisterID src2, RegisterID dest) + { + if (src1 == dest) + add32(src2, dest); + else { + move(src2, dest); + add32(src1, dest); + } + } + void add32(TrustedImm32 imm, RegisterID dest) { + if (!imm.m_value) + return; + if (m_assembler.isImmediate(imm.m_value)) { m_assembler.addlImm8r(imm.m_value, dest); return; @@ -121,13 +164,15 @@ public: void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) { - if (src != dest) - m_assembler.movlRegReg(src, dest); + move(src, dest); add32(imm, dest); } void add32(TrustedImm32 imm, Address address) { + if (!imm.m_value) + return; + RegisterID scr = claimScratch(); load32(address, scr); add32(imm, scr); @@ -156,15 +201,38 @@ public: m_assembler.andlRegReg(src, dest); } + void and32(RegisterID src1, RegisterID src2, RegisterID dest) + { + if (src1 == dest) + and32(src2, dest); + else { + move(src2, dest); + and32(src1, dest); + } + } + + void and32(Address src, RegisterID dest) + { + RegisterID scr = claimScratch(); + load32(src, scr); + and32(scr, dest); + releaseScratch(scr); + } + void and32(TrustedImm32 imm, RegisterID dest) { + if (!imm.m_value) { + m_assembler.movImm8(0, dest); + return; + } + if ((imm.m_value <= 255) && (imm.m_value >= 0) && (dest == SH4Registers::r0)) { m_assembler.andlImm8r(imm.m_value, dest); return; } RegisterID scr = claimScratch(); - m_assembler.loadConstant((imm.m_value), scr); + m_assembler.loadConstant(imm.m_value, scr); m_assembler.andlRegReg(scr, dest); releaseScratch(scr); } @@ -182,63 +250,64 @@ public: void lshift32(RegisterID shiftamount, RegisterID dest) { - if (shiftamount == SH4Registers::r0) - m_assembler.andlImm8r(0x1f, shiftamount); - else { - RegisterID scr = claimScratch(); - m_assembler.loadConstant(0x1f, scr); - m_assembler.andlRegReg(scr, shiftamount); - releaseScratch(scr); - } - m_assembler.shllRegReg(dest, shiftamount); + RegisterID shiftTmp = claimScratch(); + m_assembler.loadConstant(0x1f, shiftTmp); + m_assembler.andlRegReg(shiftamount, shiftTmp); + m_assembler.shldRegReg(dest, shiftTmp); + releaseScratch(shiftTmp); } - void rshift32(int imm, RegisterID dest) + void lshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) { - RegisterID scr = claimScratch(); - m_assembler.loadConstant(-imm, scr); - m_assembler.shaRegReg(dest, scr); - releaseScratch(scr); + move(src, dest); + lshift32(shiftAmount, dest); } void lshift32(TrustedImm32 imm, RegisterID dest) { - if (!imm.m_value) + int immMasked = imm.m_value & 0x1f; + if (!immMasked) return; - if ((imm.m_value == 1) || (imm.m_value == 2) || (imm.m_value == 8) || (imm.m_value == 16)) { - m_assembler.shllImm8r(imm.m_value, dest); + if ((immMasked == 1) || (immMasked == 2) || (immMasked == 8) || (immMasked == 16)) { + m_assembler.shllImm8r(immMasked, dest); return; } - RegisterID scr = claimScratch(); - m_assembler.loadConstant((imm.m_value & 0x1f) , scr); - m_assembler.shllRegReg(dest, scr); - releaseScratch(scr); + RegisterID shiftTmp = claimScratch(); + m_assembler.loadConstant(immMasked, shiftTmp); + m_assembler.shldRegReg(dest, shiftTmp); + releaseScratch(shiftTmp); } void lshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest) { - if (src != dest) - move(src, dest); - + move(src, dest); lshift32(shiftamount, dest); } void mul32(RegisterID src, RegisterID dest) { - m_assembler.imullRegReg(src, dest); + mul32(src, dest, dest); + } + + void mul32(RegisterID src1, RegisterID src2, RegisterID dest) + { + m_assembler.imullRegReg(src1, src2); m_assembler.stsmacl(dest); } void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest) { - RegisterID scr = claimScratch(); - move(imm, scr); - if (src != dest) - move(src, dest); - mul32(scr, dest); - releaseScratch(scr); + if (src == dest) { + RegisterID immval = claimScratch(); + move(imm, immval); + mul32(immval, dest); + releaseScratch(immval); + } else { + move(imm, dest); + mul32(src, dest); + } } void or32(RegisterID src, RegisterID dest) @@ -271,10 +340,9 @@ public: } } - -void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) + void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { - if (src != dest) { + if (src != dest) { move(imm, dest); or32(src, dest); return; @@ -283,9 +351,21 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) or32(imm, dest); } + void or32(RegisterID src, AbsoluteAddress address) + { + RegisterID destptr = claimScratch(); + move(TrustedImmPtr(address.m_ptr), destptr); + RegisterID destval = claimScratch(); + m_assembler.movlMemReg(destptr, destval); + m_assembler.orlRegReg(src, destval); + m_assembler.movlRegMem(destval, destptr); + releaseScratch(destval); + releaseScratch(destptr); + } + void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest) { - if (src != dest) { + if (src != dest) { move(imm, dest); xor32(src, dest); return; @@ -296,28 +376,40 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void rshift32(RegisterID shiftamount, RegisterID dest) { - if (shiftamount == SH4Registers::r0) - m_assembler.andlImm8r(0x1f, shiftamount); - else { - RegisterID scr = claimScratch(); - m_assembler.loadConstant(0x1f, scr); - m_assembler.andlRegReg(scr, shiftamount); - releaseScratch(scr); - } - m_assembler.neg(shiftamount, shiftamount); - m_assembler.shaRegReg(dest, shiftamount); + RegisterID shiftTmp = claimScratch(); + m_assembler.loadConstant(0x1f, shiftTmp); + m_assembler.andlRegReg(shiftamount, shiftTmp); + m_assembler.neg(shiftTmp, shiftTmp); + m_assembler.shadRegReg(dest, shiftTmp); + releaseScratch(shiftTmp); + } + + void rshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) + { + move(src, dest); + rshift32(shiftAmount, dest); } void rshift32(TrustedImm32 imm, RegisterID dest) { - if (imm.m_value & 0x1f) - rshift32(imm.m_value & 0x1f, dest); + int immMasked = imm.m_value & 0x1f; + if (!immMasked) + return; + + if (immMasked == 1) { + m_assembler.sharImm8r(immMasked, dest); + return; + } + + RegisterID shiftTmp = claimScratch(); + m_assembler.loadConstant(-immMasked, shiftTmp); + m_assembler.shadRegReg(dest, shiftTmp); + releaseScratch(shiftTmp); } void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) { - if (src != dest) - move(src, dest); + move(src, dest); rshift32(imm, dest); } @@ -326,30 +418,15 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.sublRegReg(src, dest); } - void sub32(TrustedImm32 imm, AbsoluteAddress address, RegisterID scratchReg) - { - RegisterID result = claimScratch(); - - m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg); - m_assembler.movlMemReg(scratchReg, result); - - if (m_assembler.isImmediate(-imm.m_value)) - m_assembler.addlImm8r(-imm.m_value, result); - else { - m_assembler.loadConstant(imm.m_value, scratchReg3); - m_assembler.sublRegReg(scratchReg3, result); - } - - store32(result, scratchReg); - releaseScratch(result); - } - void sub32(TrustedImm32 imm, AbsoluteAddress address) { + if (!imm.m_value) + return; + RegisterID result = claimScratch(); RegisterID scratchReg = claimScratch(); - m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg); + move(TrustedImmPtr(address.m_ptr), scratchReg); m_assembler.movlMemReg(scratchReg, result); if (m_assembler.isImmediate(-imm.m_value)) @@ -364,30 +441,20 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) releaseScratch(scratchReg); } - void add32(TrustedImm32 imm, AbsoluteAddress address, RegisterID scratchReg) + void sub32(TrustedImm32 imm, Address address) { - RegisterID result = claimScratch(); - - m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg); - m_assembler.movlMemReg(scratchReg, result); - - if (m_assembler.isImmediate(imm.m_value)) - m_assembler.addlImm8r(imm.m_value, result); - else { - m_assembler.loadConstant(imm.m_value, scratchReg3); - m_assembler.addlRegReg(scratchReg3, result); - } - - store32(result, scratchReg); - releaseScratch(result); + add32(TrustedImm32(-imm.m_value), address); } void add32(TrustedImm32 imm, AbsoluteAddress address) { + if (!imm.m_value) + return; + RegisterID result = claimScratch(); RegisterID scratchReg = claimScratch(); - m_assembler.loadConstant(reinterpret_cast<uint32_t>(address.m_ptr), scratchReg); + move(TrustedImmPtr(address.m_ptr), scratchReg); m_assembler.movlMemReg(scratchReg, result); if (m_assembler.isImmediate(imm.m_value)) @@ -402,8 +469,37 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) releaseScratch(scratchReg); } + void add64(TrustedImm32 imm, AbsoluteAddress address) + { + RegisterID scr1 = claimScratch(); + RegisterID scr2 = claimScratch(); + + // Add 32-bit LSB first. + move(TrustedImmPtr(address.m_ptr), scratchReg3); + m_assembler.movlMemReg(scratchReg3, scr1); // scr1 = 32-bit LSB of int64 @ address + m_assembler.loadConstant(imm.m_value, scr2); + m_assembler.clrt(); + m_assembler.addclRegReg(scr1, scr2); + m_assembler.movlRegMem(scr2, scratchReg3); // Update address with 32-bit LSB result. + + // Then add 32-bit MSB. + m_assembler.addlImm8r(4, scratchReg3); + m_assembler.movlMemReg(scratchReg3, scr1); // scr1 = 32-bit MSB of int64 @ address + m_assembler.movt(scr2); + if (imm.m_value < 0) + m_assembler.addlImm8r(-1, scr2); // Sign extend imm value if needed. + m_assembler.addvlRegReg(scr2, scr1); + m_assembler.movlRegMem(scr1, scratchReg3); // Update (address + 4) with 32-bit MSB result. + + releaseScratch(scr2); + releaseScratch(scr1); + } + void sub32(TrustedImm32 imm, RegisterID dest) { + if (!imm.m_value) + return; + if (m_assembler.isImmediate(-imm.m_value)) { m_assembler.addlImm8r(-imm.m_value, dest); return; @@ -428,6 +524,16 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.xorlRegReg(src, dest); } + void xor32(RegisterID src1, RegisterID src2, RegisterID dest) + { + if (src1 == dest) + xor32(src2, dest); + else { + move(src2, dest); + xor32(src1, dest); + } + } + void xor32(TrustedImm32 imm, RegisterID srcDest) { if (imm.m_value == -1) { @@ -437,7 +543,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) if ((srcDest != SH4Registers::r0) || (imm.m_value > 255) || (imm.m_value < 0)) { RegisterID scr = claimScratch(); - m_assembler.loadConstant((imm.m_value), scr); + m_assembler.loadConstant(imm.m_value, scr); m_assembler.xorlRegReg(scr, srcDest); releaseScratch(scr); return; @@ -453,6 +559,11 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) return; } + if (((cond == Equal) || (cond == NotEqual)) && !imm) { + m_assembler.testlRegReg(dst, dst); + return; + } + RegisterID scr = claimScratch(); m_assembler.loadConstant(imm, scr); m_assembler.cmplRegReg(scr, dst, SH4Condition(cond)); @@ -486,20 +597,10 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void testImm(int imm, int offset, RegisterID base) { RegisterID scr = claimScratch(); - RegisterID scr1 = claimScratch(); + load32(base, offset, scr); - if ((offset < 0) || (offset >= 64)) { - m_assembler.loadConstant(offset, scr); - m_assembler.addlRegReg(base, scr); - m_assembler.movlMemReg(scr, scr); - } else if (offset) - m_assembler.movlMemReg(offset >> 2, base, scr); - else - m_assembler.movlMemReg(base, scr); - if (m_assembler.isImmediate(imm)) - m_assembler.movImm8(imm, scr1); - else - m_assembler.loadConstant(imm, scr1); + RegisterID scr1 = claimScratch(); + move(TrustedImm32(imm), scr1); m_assembler.testlRegReg(scr, scr1); releaseScratch(scr); @@ -547,41 +648,37 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void compare32(int imm, int offset, RegisterID base, RelationalCondition cond) { - if (!offset) { - RegisterID scr = claimScratch(); - RegisterID scr1 = claimScratch(); - m_assembler.movlMemReg(base, scr); - m_assembler.loadConstant(imm, scr1); - m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond)); - releaseScratch(scr1); - releaseScratch(scr); - return; - } - - if ((offset < 0) || (offset >= 64)) { - RegisterID scr = claimScratch(); - RegisterID scr1 = claimScratch(); - m_assembler.loadConstant(offset, scr); - m_assembler.addlRegReg(base, scr); - m_assembler.movlMemReg(scr, scr); - m_assembler.loadConstant(imm, scr1); - m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond)); - releaseScratch(scr1); - releaseScratch(scr); - return; - } - RegisterID scr = claimScratch(); + load32(base, offset, scr); + RegisterID scr1 = claimScratch(); - m_assembler.movlMemReg(offset >> 2, base, scr); - m_assembler.loadConstant(imm, scr1); + move(TrustedImm32(imm), scr1); + m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond)); + releaseScratch(scr1); releaseScratch(scr); } // Memory access operation + ALWAYS_INLINE void loadEffectiveAddress(BaseIndex address, RegisterID dest, int extraoffset = 0) + { + if (dest == address.base) { + RegisterID scaledIndex = claimScratch(); + move(address.index, scaledIndex); + lshift32(TrustedImm32(address.scale), scaledIndex); + add32(scaledIndex, dest); + releaseScratch(scaledIndex); + } else { + move(address.index, dest); + lshift32(TrustedImm32(address.scale), dest); + add32(address.base, dest); + } + + add32(TrustedImm32(address.offset + extraoffset), dest); + } + void load32(ImplicitAddress address, RegisterID dest) { load32(address.base, address.offset, dest); @@ -602,6 +699,12 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) releaseScratch(scr); } + void load8PostInc(RegisterID base, RegisterID dest) + { + m_assembler.movbMemRegIn(base, dest); + m_assembler.extub(dest, dest); + } + void load8Signed(BaseIndex address, RegisterID dest) { RegisterID scr = claimScratch(); @@ -624,7 +727,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void load32(const void* address, RegisterID dest) { - m_assembler.loadConstant(reinterpret_cast<uint32_t>(const_cast<void*>(address)), dest); + move(TrustedImmPtr(address), dest); m_assembler.movlMemReg(dest, dest); } @@ -640,20 +743,15 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) return; } - if ((dest == SH4Registers::r0) && (dest != base)) { - m_assembler.loadConstant((offset), dest); - m_assembler.movlR0mr(base, dest); - return; - } + RegisterID scr = (dest == base) ? claimScratch() : dest; - RegisterID scr; - if (dest == base) - scr = claimScratch(); - else - scr = dest; - m_assembler.loadConstant((offset), scr); - m_assembler.addlRegReg(base, scr); - m_assembler.movlMemReg(scr, dest); + m_assembler.loadConstant(offset, scr); + if (base == SH4Registers::r0) + m_assembler.movlR0mr(scr, dest); + else { + m_assembler.addlRegReg(base, scr); + m_assembler.movlMemReg(scr, dest); + } if (dest == base) releaseScratch(scr); @@ -666,59 +764,29 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) return; } - if ((offset > 0) && (offset < 64) && (dest == SH4Registers::r0)) { + if ((offset > 0) && (offset <= 15) && (dest == SH4Registers::r0)) { m_assembler.movbMemReg(offset, base, dest); return; } - if (base != dest) { - m_assembler.loadConstant((offset), dest); - m_assembler.addlRegReg(base, dest); - m_assembler.movbMemReg(dest, dest); - return; + RegisterID scr = (dest == base) ? claimScratch() : dest; + + m_assembler.loadConstant(offset, scr); + if (base == SH4Registers::r0) + m_assembler.movbR0mr(scr, dest); + else { + m_assembler.addlRegReg(base, scr); + m_assembler.movbMemReg(scr, dest); } - RegisterID scr = claimScratch(); - m_assembler.loadConstant((offset), scr); - m_assembler.addlRegReg(base, scr); - m_assembler.movbMemReg(scr, dest); - releaseScratch(scr); + if (dest == base) + releaseScratch(scr); } void load8(RegisterID base, int offset, RegisterID dest) { - if (!offset) { - m_assembler.movbMemReg(base, dest); - m_assembler.extub(dest, dest); - return; - } - - if ((offset > 0) && (offset < 64) && (dest == SH4Registers::r0)) { - m_assembler.movbMemReg(offset, base, dest); - m_assembler.extub(dest, dest); - return; - } - - if (base != dest) { - m_assembler.loadConstant((offset), dest); - m_assembler.addlRegReg(base, dest); - m_assembler.movbMemReg(dest, dest); - m_assembler.extub(dest, dest); - return; - } - - RegisterID scr = claimScratch(); - m_assembler.loadConstant((offset), scr); - m_assembler.addlRegReg(base, scr); - m_assembler.movbMemReg(scr, dest); + load8Signed(base, offset, dest); m_assembler.extub(dest, dest); - releaseScratch(scr); - } - - void load32(RegisterID r0, RegisterID src, RegisterID dst) - { - ASSERT(r0 == SH4Registers::r0); - m_assembler.movlR0mr(src, dst); } void load32(RegisterID src, RegisterID dst) @@ -730,47 +798,39 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { if (!address.offset) { m_assembler.movwMemReg(address.base, dest); - extuw(dest, dest); + m_assembler.extuw(dest, dest); return; } - if ((address.offset > 0) && (address.offset < 64) && (dest == SH4Registers::r0)) { - m_assembler.movwMemReg(address.offset, address.base, dest); - extuw(dest, dest); + if ((address.offset > 0) && (address.offset <= 30) && (dest == SH4Registers::r0)) { + m_assembler.movwMemReg(address.offset >> 1, address.base, dest); + m_assembler.extuw(dest, dest); return; } - if (address.base != dest) { - m_assembler.loadConstant((address.offset), dest); - m_assembler.addlRegReg(address.base, dest); - m_assembler.movwMemReg(dest, dest); - extuw(dest, dest); - return; + RegisterID scr = (dest == address.base) ? claimScratch() : dest; + + m_assembler.loadConstant(address.offset, scr); + if (address.base == SH4Registers::r0) + m_assembler.movwR0mr(scr, dest); + else { + m_assembler.addlRegReg(address.base, scr); + m_assembler.movwMemReg(scr, dest); } + m_assembler.extuw(dest, dest); - RegisterID scr = claimScratch(); - m_assembler.loadConstant((address.offset), scr); - m_assembler.addlRegReg(address.base, scr); - m_assembler.movwMemReg(scr, dest); - extuw(dest, dest); - releaseScratch(scr); + if (dest == address.base) + releaseScratch(scr); } void load16Unaligned(BaseIndex address, RegisterID dest) { - RegisterID scr = claimScratch(); - RegisterID scr1 = claimScratch(); - - move(address.index, scr); - lshift32(TrustedImm32(address.scale), scr); - if (address.offset) - add32(TrustedImm32(address.offset), scr); + loadEffectiveAddress(address, scr); - add32(address.base, scr); - load8(scr, scr1); - add32(TrustedImm32(1), scr); + RegisterID scr1 = claimScratch(); + load8PostInc(scr, scr1); load8(scr, dest); m_assembler.shllImm8r(8, dest); or32(scr1, dest); @@ -782,7 +842,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void load16(RegisterID src, RegisterID dest) { m_assembler.movwMemReg(src, dest); - extuw(dest, dest); + m_assembler.extuw(dest, dest); } void load16Signed(RegisterID src, RegisterID dest) @@ -790,68 +850,63 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.movwMemReg(src, dest); } - void load16(RegisterID r0, RegisterID src, RegisterID dest) + void load16(BaseIndex address, RegisterID dest) { - ASSERT(r0 == SH4Registers::r0); - m_assembler.movwR0mr(src, dest); - extuw(dest, dest); + load16Signed(address, dest); + m_assembler.extuw(dest, dest); } - void load16Signed(RegisterID r0, RegisterID src, RegisterID dest) + void load16PostInc(RegisterID base, RegisterID dest) { - ASSERT(r0 == SH4Registers::r0); - m_assembler.movwR0mr(src, dest); + m_assembler.movwMemRegIn(base, dest); + m_assembler.extuw(dest, dest); } - void load16(BaseIndex address, RegisterID dest) + void load16Signed(BaseIndex address, RegisterID dest) { RegisterID scr = claimScratch(); move(address.index, scr); lshift32(TrustedImm32(address.scale), scr); + add32(TrustedImm32(address.offset), scr); - if (address.offset) - add32(TrustedImm32(address.offset), scr); if (address.base == SH4Registers::r0) - load16(address.base, scr, dest); + m_assembler.movwR0mr(scr, dest); else { add32(address.base, scr); - load16(scr, dest); + load16Signed(scr, dest); } releaseScratch(scr); } - void load16Signed(BaseIndex address, RegisterID dest) + void store8(RegisterID src, BaseIndex address) { RegisterID scr = claimScratch(); move(address.index, scr); lshift32(TrustedImm32(address.scale), scr); + add32(TrustedImm32(address.offset), scr); - if (address.offset) - add32(TrustedImm32(address.offset), scr); if (address.base == SH4Registers::r0) - load16Signed(address.base, scr, dest); + m_assembler.movbRegMemr0(src, scr); else { add32(address.base, scr); - load16Signed(scr, dest); + m_assembler.movbRegMem(src, scr); } releaseScratch(scr); } - void store8(RegisterID src, BaseIndex address) + void store8(TrustedImm32 imm, void* address) { - RegisterID scr = claimScratch(); - - move(address.index, scr); - lshift32(TrustedImm32(address.scale), scr); - add32(address.base, scr); - - m_assembler.movbRegMem(src, scr); - - releaseScratch(scr); + RegisterID srcval = claimScratch(); + RegisterID dstptr = claimScratch(); + move(imm, srcval); + m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), dstptr); + m_assembler.movbRegMem(srcval, dstptr); + releaseScratch(dstptr); + releaseScratch(srcval); } void store16(RegisterID src, BaseIndex address) @@ -860,46 +915,39 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) move(address.index, scr); lshift32(TrustedImm32(address.scale), scr); - add32(address.base, scr); + add32(TrustedImm32(address.offset), scr); - m_assembler.movwRegMem(src, scr); + if (address.base == SH4Registers::r0) + m_assembler.movwRegMemr0(src, scr); + else { + add32(address.base, scr); + m_assembler.movwRegMem(src, scr); + } releaseScratch(scr); } void store32(RegisterID src, ImplicitAddress address) { - RegisterID scr = claimScratch(); - store32(src, address.offset, address.base, scr); - releaseScratch(scr); - } - - void store32(RegisterID src, int offset, RegisterID base, RegisterID scr) - { - if (!offset) { - m_assembler.movlRegMem(src, base); + if (!address.offset) { + m_assembler.movlRegMem(src, address.base); return; } - if ((offset >=0) && (offset < 64)) { - m_assembler.movlRegMem(src, offset >> 2, base); + if ((address.offset >= 0) && (address.offset < 64)) { + m_assembler.movlRegMem(src, address.offset >> 2, address.base); return; } - m_assembler.loadConstant((offset), scr); - if (scr == SH4Registers::r0) { - m_assembler.movlRegMemr0(src, base); - return; + RegisterID scr = claimScratch(); + m_assembler.loadConstant(address.offset, scr); + if (address.base == SH4Registers::r0) + m_assembler.movlRegMemr0(src, scr); + else { + m_assembler.addlRegReg(address.base, scr); + m_assembler.movlRegMem(src, scr); } - - m_assembler.addlRegReg(base, scr); - m_assembler.movlRegMem(src, scr); - } - - void store32(RegisterID src, RegisterID offset, RegisterID base) - { - ASSERT(offset == SH4Registers::r0); - m_assembler.movlRegMemr0(src, base); + releaseScratch(scr); } void store32(RegisterID src, RegisterID dst) @@ -910,11 +958,9 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void store32(TrustedImm32 imm, ImplicitAddress address) { RegisterID scr = claimScratch(); - RegisterID scr1 = claimScratch(); - m_assembler.loadConstant((imm.m_value), scr); - store32(scr, address.offset, address.base, scr1); + m_assembler.loadConstant(imm.m_value, scr); + store32(scr, address); releaseScratch(scr); - releaseScratch(scr1); } void store32(RegisterID src, BaseIndex address) @@ -933,8 +979,8 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { RegisterID scr = claimScratch(); RegisterID scr1 = claimScratch(); - m_assembler.loadConstant((imm.m_value), scr); - m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr1); + m_assembler.loadConstant(imm.m_value, scr); + move(TrustedImmPtr(address), scr1); m_assembler.movlRegMem(scr, scr1); releaseScratch(scr); releaseScratch(scr1); @@ -943,11 +989,24 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void store32(RegisterID src, void* address) { RegisterID scr = claimScratch(); - m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr); + move(TrustedImmPtr(address), scr); m_assembler.movlRegMem(src, scr); releaseScratch(scr); } + void store32(TrustedImm32 imm, BaseIndex address) + { + RegisterID destptr = claimScratch(); + + loadEffectiveAddress(address, destptr); + + RegisterID srcval = claimScratch(); + move(imm, srcval); + m_assembler.movlRegMem(srcval, destptr); + releaseScratch(srcval); + releaseScratch(destptr); + } + DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest) { RegisterID scr = claimScratch(); @@ -973,8 +1032,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) DataLabelCompact load32WithCompactAddressOffsetPatch(Address address, RegisterID dest) { DataLabelCompact dataLabel(this); - ASSERT(address.offset <= MaximumCompactPtrAlignedAddressOffset); - ASSERT(address.offset >= 0); + ASSERT(isCompactPtrAlignedAddressOffset(address.offset)); m_assembler.movlMemRegCompact(address.offset >> 2, address.base, dest); return dataLabel; } @@ -997,7 +1055,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) static bool supportsFloatingPoint() { return true; } static bool supportsFloatingPointTruncate() { return true; } static bool supportsFloatingPointSqrt() { return true; } - static bool supportsFloatingPointAbs() { return false; } + static bool supportsFloatingPointAbs() { return true; } void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) { @@ -1007,24 +1065,39 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.stsfpulReg(dest2); } - void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch) + void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID) { - UNUSED_PARAM(scratch); m_assembler.ldsrmfpul(src1); m_assembler.fstsfpul((FPRegisterID)(dest + 1)); m_assembler.ldsrmfpul(src2); m_assembler.fstsfpul(dest); } + void moveDouble(FPRegisterID src, FPRegisterID dest) + { + if (src != dest) { + m_assembler.fmovsRegReg((FPRegisterID)(src + 1), (FPRegisterID)(dest + 1)); + m_assembler.fmovsRegReg(src, dest); + } + } + + void swapDouble(FPRegisterID fr1, FPRegisterID fr2) + { + if (fr1 != fr2) { + m_assembler.fldsfpul((FPRegisterID)(fr1 + 1)); + m_assembler.fmovsRegReg((FPRegisterID)(fr2 + 1), (FPRegisterID)(fr1 + 1)); + m_assembler.fstsfpul((FPRegisterID)(fr2 + 1)); + m_assembler.fldsfpul(fr1); + m_assembler.fmovsRegReg(fr2, fr1); + m_assembler.fstsfpul(fr2); + } + } + void loadFloat(BaseIndex address, FPRegisterID dest) { RegisterID scr = claimScratch(); - move(address.index, scr); - lshift32(TrustedImm32(address.scale), scr); - add32(address.base, scr); - if (address.offset) - add32(TrustedImm32(address.offset), scr); + loadEffectiveAddress(address, scr); m_assembler.fmovsReadrm(scr, dest); releaseScratch(scr); @@ -1034,11 +1107,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { RegisterID scr = claimScratch(); - move(address.index, scr); - lshift32(TrustedImm32(address.scale), scr); - add32(address.base, scr); - if (address.offset) - add32(TrustedImm32(address.offset), scr); + loadEffectiveAddress(address, scr); m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1)); m_assembler.fmovsReadrm(scr, dest); @@ -1067,7 +1136,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void loadDouble(const void* address, FPRegisterID dest) { RegisterID scr = claimScratch(); - m_assembler.loadConstant(reinterpret_cast<uint32_t>(address), scr); + move(TrustedImmPtr(address), scr); m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1)); m_assembler.fmovsReadrm(scr, dest); releaseScratch(scr); @@ -1076,26 +1145,18 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void storeFloat(FPRegisterID src, BaseIndex address) { RegisterID scr = claimScratch(); - - move(address.index, scr); - lshift32(TrustedImm32(address.scale), scr); - add32(address.base, scr); - if (address.offset) - add32(TrustedImm32(address.offset), scr); - + loadEffectiveAddress(address, scr); m_assembler.fmovsWriterm(src, scr); - releaseScratch(scr); } void storeDouble(FPRegisterID src, ImplicitAddress address) { RegisterID scr = claimScratch(); - m_assembler.loadConstant(address.offset, scr); + m_assembler.loadConstant(address.offset + 8, scr); m_assembler.addlRegReg(address.base, scr); - m_assembler.fmovsWriterm((FPRegisterID)(src + 1), scr); - m_assembler.addlImm8r(4, scr); - m_assembler.fmovsWriterm(src, scr); + m_assembler.fmovsWriterndec(src, scr); + m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr); releaseScratch(scr); } @@ -1103,15 +1164,10 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { RegisterID scr = claimScratch(); - move(address.index, scr); - lshift32(TrustedImm32(address.scale), scr); - add32(address.base, scr); - if (address.offset) - add32(TrustedImm32(address.offset), scr); + loadEffectiveAddress(address, scr, 8); - m_assembler.fmovsWriterm((FPRegisterID)(src + 1), scr); - m_assembler.addlImm8r(4, scr); - m_assembler.fmovsWriterm(src, scr); + m_assembler.fmovsWriterndec(src, scr); + m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr); releaseScratch(scr); } @@ -1119,13 +1175,22 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void addDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) { if (op1 == dest) - m_assembler.daddRegReg(op2, dest); + addDouble(op2, dest); else { - m_assembler.dmovRegReg(op1, dest); - m_assembler.daddRegReg(op2, dest); + moveDouble(op2, dest); + addDouble(op1, dest); } } + void storeDouble(FPRegisterID src, const void* address) + { + RegisterID scr = claimScratch(); + m_assembler.loadConstant(reinterpret_cast<uint32_t>(const_cast<void*>(address)) + 8, scr); + m_assembler.fmovsWriterndec(src, scr); + m_assembler.fmovsWriterndec((FPRegisterID)(src + 1), scr); + releaseScratch(scr); + } + void addDouble(FPRegisterID src, FPRegisterID dest) { m_assembler.daddRegReg(src, dest); @@ -1148,6 +1213,18 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.dsubRegReg(src, dest); } + void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + if (op2 == dest) { + moveDouble(op1, fscratch); + subDouble(op2, fscratch); + moveDouble(fscratch, dest); + } else { + moveDouble(op1, dest); + subDouble(op2, dest); + } + } + void subDouble(Address address, FPRegisterID dest) { loadDouble(address, fscratch); @@ -1159,6 +1236,16 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.dmulRegReg(src, dest); } + void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + if (op1 == dest) + mulDouble(op2, dest); + else { + moveDouble(op2, dest); + mulDouble(op1, dest); + } + } + void mulDouble(Address address, FPRegisterID dest) { loadDouble(address, fscratch); @@ -1170,6 +1257,24 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.ddivRegReg(src, dest); } + void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest) + { + if (op2 == dest) { + moveDouble(op1, fscratch); + divDouble(op2, fscratch); + moveDouble(fscratch, dest); + } else { + moveDouble(op1, dest); + divDouble(op2, dest); + } + } + + void negateDouble(FPRegisterID src, FPRegisterID dest) + { + moveDouble(src, dest); + m_assembler.dneg(dest); + } + void convertFloatToDouble(FPRegisterID src, FPRegisterID dst) { m_assembler.fldsfpul(src); @@ -1191,7 +1296,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest) { RegisterID scr = claimScratch(); - m_assembler.loadConstant(reinterpret_cast<uint32_t>(src.m_ptr), scr); + load32(src.m_ptr, scr); convertInt32ToDouble(scr, dest); releaseScratch(scr); } @@ -1214,18 +1319,13 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) if (dest != SH4Registers::r0) move(SH4Registers::r0, scr1); - move(address.index, scr); - lshift32(TrustedImm32(address.scale), scr); - add32(address.base, scr); - - if (address.offset) - add32(TrustedImm32(address.offset), scr); + loadEffectiveAddress(address, scr); - m_assembler.ensureSpace(m_assembler.maxInstructionSize + 68, sizeof(uint32_t)); + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 58, sizeof(uint32_t)); move(scr, SH4Registers::r0); - m_assembler.andlImm8r(0x3, SH4Registers::r0); - m_assembler.cmpEqImmR0(0x0, SH4Registers::r0); + m_assembler.testlImm8r(0x3, SH4Registers::r0); m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear); + if (dest != SH4Registers::r0) move(scr1, SH4Registers::r0); @@ -1233,27 +1333,23 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) end.append(Jump(m_assembler.bra(), SH4Assembler::JumpNear)); m_assembler.nop(); m_jump.link(this); - m_assembler.andlImm8r(0x1, SH4Registers::r0); - m_assembler.cmpEqImmR0(0x0, SH4Registers::r0); + m_assembler.testlImm8r(0x1, SH4Registers::r0); if (dest != SH4Registers::r0) move(scr1, SH4Registers::r0); m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear); - load16(scr, scr1); - add32(TrustedImm32(2), scr); + load16PostInc(scr, scr1); load16(scr, dest); m_assembler.shllImm8r(16, dest); or32(scr1, dest); end.append(Jump(m_assembler.bra(), SH4Assembler::JumpNear)); m_assembler.nop(); m_jump.link(this); - load8(scr, scr1); - add32(TrustedImm32(1), scr); - load16(scr, dest); + load8PostInc(scr, scr1); + load16PostInc(scr, dest); m_assembler.shllImm8r(8, dest); or32(dest, scr1); - add32(TrustedImm32(2), scr); load8(scr, dest); m_assembler.shllImm8r(8, dest); m_assembler.shllImm8r(16, dest); @@ -1300,20 +1396,13 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) } if (cond == DoubleNotEqual) { - RegisterID scr = claimScratch(); JumpList end; - m_assembler.loadConstant(0x7fbfffff, scratchReg3); - m_assembler.dcnvds(right); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); + m_assembler.dcmppeq(left, left); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); - m_assembler.dcnvds(left); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); + end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); + m_assembler.dcmppeq(right, right); + end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppeq(right, left); - releaseScratch(scr); Jump m_jump = branchFalse(); end.link(this); return m_jump; @@ -1325,8 +1414,16 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) } if (cond == DoubleGreaterThanOrEqual) { + JumpList end; + m_assembler.dcmppeq(left, left); + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); + end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); + m_assembler.dcmppeq(right, right); + end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(left, right); - return branchFalse(); + Jump m_jump = branchFalse(); + end.link(this); + return m_jump; } if (cond == DoubleLessThan) { @@ -1335,134 +1432,73 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) } if (cond == DoubleLessThanOrEqual) { + JumpList end; + m_assembler.dcmppeq(left, left); + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); + end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); + m_assembler.dcmppeq(right, right); + end.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(right, left); - return branchFalse(); + Jump m_jump = branchFalse(); + end.link(this); + return m_jump; } if (cond == DoubleEqualOrUnordered) { - RegisterID scr = claimScratch(); - JumpList end; - m_assembler.loadConstant(0x7fbfffff, scratchReg3); - m_assembler.dcnvds(right); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); + JumpList takeBranch; + m_assembler.dcmppeq(left, left); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); - m_assembler.dcnvds(left); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); + takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); + m_assembler.dcmppeq(right, right); + takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppeq(left, right); Jump m_jump = Jump(m_assembler.je()); - end.link(this); - m_assembler.extraInstrForBranch(scr); - releaseScratch(scr); + takeBranch.link(this); + m_assembler.extraInstrForBranch(scratchReg3); return m_jump; } if (cond == DoubleGreaterThanOrUnordered) { - RegisterID scr = claimScratch(); - JumpList end; - m_assembler.loadConstant(0x7fbfffff, scratchReg3); - m_assembler.dcnvds(right); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); + JumpList takeBranch; + m_assembler.dcmppeq(left, left); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); - m_assembler.dcnvds(left); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); + takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); + m_assembler.dcmppeq(right, right); + takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(right, left); Jump m_jump = Jump(m_assembler.je()); - end.link(this); - m_assembler.extraInstrForBranch(scr); - releaseScratch(scr); + takeBranch.link(this); + m_assembler.extraInstrForBranch(scratchReg3); return m_jump; } if (cond == DoubleGreaterThanOrEqualOrUnordered) { - RegisterID scr = claimScratch(); - JumpList end; - m_assembler.loadConstant(0x7fbfffff, scratchReg3); - m_assembler.dcnvds(right); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); - m_assembler.dcnvds(left); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(left, right); - Jump m_jump = Jump(m_assembler.jne()); - end.link(this); - m_assembler.extraInstrForBranch(scr); - releaseScratch(scr); - return m_jump; + return branchFalse(); } if (cond == DoubleLessThanOrUnordered) { - RegisterID scr = claimScratch(); - JumpList end; - m_assembler.loadConstant(0x7fbfffff, scratchReg3); - m_assembler.dcnvds(right); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); + JumpList takeBranch; + m_assembler.dcmppeq(left, left); m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); - m_assembler.dcnvds(left); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); + takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); + m_assembler.dcmppeq(right, right); + takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(left, right); Jump m_jump = Jump(m_assembler.je()); - end.link(this); - m_assembler.extraInstrForBranch(scr); - releaseScratch(scr); + takeBranch.link(this); + m_assembler.extraInstrForBranch(scratchReg3); return m_jump; } if (cond == DoubleLessThanOrEqualOrUnordered) { - RegisterID scr = claimScratch(); - JumpList end; - m_assembler.loadConstant(0x7fbfffff, scratchReg3); - m_assembler.dcnvds(right); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); - m_assembler.dcnvds(left); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(right, left); - Jump m_jump = Jump(m_assembler.jne()); - end.link(this); - m_assembler.extraInstrForBranch(scr); - releaseScratch(scr); - return m_jump; + return branchFalse(); } ASSERT(cond == DoubleNotEqualOrUnordered); - RegisterID scr = claimScratch(); - JumpList end; - m_assembler.loadConstant(0x7fbfffff, scratchReg3); - m_assembler.dcnvds(right); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); - m_assembler.dcnvds(left); - m_assembler.stsfpulReg(scr); - m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal)); - end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear)); m_assembler.dcmppeq(right, left); - Jump m_jump = Jump(m_assembler.jne()); - end.link(this); - m_assembler.extraInstrForBranch(scr); - releaseScratch(scr); - return m_jump; + return branchFalse(); } Jump branchTrue() @@ -1498,14 +1534,14 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void sqrtDouble(FPRegisterID src, FPRegisterID dest) { - if (dest != src) - m_assembler.dmovRegReg(src, dest); + moveDouble(src, dest); m_assembler.dsqrt(dest); } - void absDouble(FPRegisterID, FPRegisterID) + void absDouble(FPRegisterID src, FPRegisterID dest) { - ASSERT_NOT_REACHED(); + moveDouble(src, dest); + m_assembler.dabs(dest); } Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) @@ -1529,8 +1565,12 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void signExtend32ToPtr(RegisterID src, RegisterID dest) { - if (src != dest) - move(src, dest); + move(src, dest); + } + + void zeroExtend32ToPtr(RegisterID src, RegisterID dest) + { + move(src, dest); } Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right) @@ -1550,17 +1590,77 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) releaseScratch(addressTempRegister); } - Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest) + enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful }; + Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed) + { + Jump result; + truncateDoubleToInt32(src, dest); + RegisterID intscr = claimScratch(); + m_assembler.loadConstant(0x7fffffff, intscr); + m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal)); + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 12, sizeof(uint32_t)); + if (branchType == BranchIfTruncateFailed) { + m_assembler.branch(BT_OPCODE, 2); + m_assembler.addlImm8r(1, intscr); + m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal)); + result = branchTrue(); + } else { + Jump out = Jump(m_assembler.je(), SH4Assembler::JumpNear); + m_assembler.addlImm8r(1, intscr); + m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal)); + result = branchFalse(); + out.link(this); + } + releaseScratch(intscr); + return result; + } + + Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed) + { + Jump result; + RegisterID intscr = claimScratch(); + m_assembler.loadConstant(0x80000000, intscr); + convertInt32ToDouble(intscr, fscratch); + addDouble(src, fscratch); + truncateDoubleToInt32(fscratch, dest); + m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal)); + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 16, sizeof(uint32_t)); + if (branchType == BranchIfTruncateFailed) { + m_assembler.branch(BT_OPCODE, 4); + m_assembler.addlImm8r(-1, intscr); + m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal)); + m_assembler.addlImm8r(1, intscr); + m_assembler.sublRegReg(intscr, dest); + result = branchTrue(); + } else { + Jump out = Jump(m_assembler.je(), SH4Assembler::JumpNear); + m_assembler.addlImm8r(-1, intscr); + m_assembler.cmplRegReg(dest, intscr, SH4Condition(Equal)); + m_assembler.addlImm8r(1, intscr); + m_assembler.sublRegReg(intscr, dest); + result = branchFalse(); + out.link(this); + } + releaseScratch(intscr); + return result; + } + + void truncateDoubleToInt32(FPRegisterID src, RegisterID dest) { m_assembler.ftrcdrmfpul(src); m_assembler.stsfpulReg(dest); - m_assembler.loadConstant(0x7fffffff, scratchReg3); - m_assembler.cmplRegReg(dest, scratchReg3, SH4Condition(Equal)); - m_assembler.ensureSpace(m_assembler.maxInstructionSize + 14, sizeof(uint32_t)); - m_assembler.branch(BT_OPCODE, 2); - m_assembler.addlImm8r(1, scratchReg3); - m_assembler.cmplRegReg(dest, scratchReg3, SH4Condition(Equal)); - return branchTrue(); + } + + void truncateDoubleToUint32(FPRegisterID src, RegisterID dest) + { + RegisterID intscr = claimScratch(); + m_assembler.loadConstant(0x80000000, intscr); + convertInt32ToDouble(intscr, fscratch); + addDouble(src, fscratch); + m_assembler.ftrcdrmfpul(fscratch); + m_assembler.stsfpulReg(dest); + m_assembler.sublRegReg(intscr, dest); + releaseScratch(intscr); } // Stack manipulation operations @@ -1575,27 +1675,6 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.pushReg(src); } - void push(Address address) - { - if (!address.offset) { - push(address.base); - return; - } - - if ((address.offset < 0) || (address.offset >= 64)) { - RegisterID scr = claimScratch(); - m_assembler.loadConstant(address.offset, scr); - m_assembler.addlRegReg(address.base, scr); - m_assembler.movlMemReg(scr, SH4Registers::sp); - m_assembler.addlImm8r(-4, SH4Registers::sp); - releaseScratch(scr); - return; - } - - m_assembler.movlMemReg(address.offset >> 2, address.base, SH4Registers::sp); - m_assembler.addlImm8r(-4, SH4Registers::sp); - } - void push(TrustedImm32 imm) { RegisterID scr = claimScratch(); @@ -1630,9 +1709,13 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.loadConstant(imm.asIntptr(), dest); } - void extuw(RegisterID src, RegisterID dst) + void swap(RegisterID reg1, RegisterID reg2) { - m_assembler.extuw(src, dst); + if (reg1 != reg2) { + xor32(reg1, reg2); + xor32(reg2, reg1); + xor32(reg1, reg2); + } } void compare32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest) @@ -1744,7 +1827,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { RegisterID scr = claimScratch(); - move(TrustedImm32(reinterpret_cast<uint32_t>(left.m_ptr)), scr); + load32(left.m_ptr, scr); m_assembler.cmplRegReg(right, scr, SH4Condition(cond)); releaseScratch(scr); @@ -1757,7 +1840,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { RegisterID addressTempRegister = claimScratch(); - m_assembler.loadConstant(reinterpret_cast<uint32_t>(left.m_ptr), addressTempRegister); + move(TrustedImmPtr(left.m_ptr), addressTempRegister); m_assembler.movlMemReg(addressTempRegister, addressTempRegister); compare32(right.m_value, addressTempRegister, cond); releaseScratch(addressTempRegister); @@ -1770,21 +1853,18 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right) { ASSERT(!(right.m_value & 0xFFFFFF00)); - RegisterID scr = claimScratch(); + RegisterID lefttmp = claimScratch(); - move(left.index, scr); - lshift32(TrustedImm32(left.scale), scr); + loadEffectiveAddress(left, lefttmp); - if (left.offset) - add32(TrustedImm32(left.offset), scr); - add32(left.base, scr); - load8(scr, scr); - RegisterID scr1 = claimScratch(); - m_assembler.loadConstant(right.m_value, scr1); - releaseScratch(scr); - releaseScratch(scr1); + load8(lefttmp, lefttmp); + RegisterID righttmp = claimScratch(); + m_assembler.loadConstant(right.m_value, righttmp); - return branch32(cond, scr, scr1); + Jump result = branch32(cond, lefttmp, righttmp); + releaseScratch(lefttmp); + releaseScratch(righttmp); + return result; } Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask) @@ -1828,6 +1908,8 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) Jump branchTest32(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1)) { + ASSERT((cond == Zero) || (cond == NonZero)); + RegisterID scr = claimScratch(); move(address.index, scr); @@ -1860,60 +1942,102 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void jump(Address address) { RegisterID scr = claimScratch(); - - if ((address.offset < 0) || (address.offset >= 64)) { - m_assembler.loadConstant(address.offset, scr); - m_assembler.addlRegReg(address.base, scr); - m_assembler.movlMemReg(scr, scr); - } else if (address.offset) - m_assembler.movlMemReg(address.offset >> 2, address.base, scr); - else - m_assembler.movlMemReg(address.base, scr); + load32(address, scr); m_assembler.jmpReg(scr); + releaseScratch(scr); + } + void jump(AbsoluteAddress address) + { + RegisterID scr = claimScratch(); + + move(TrustedImmPtr(address.m_ptr), scr); + m_assembler.movlMemReg(scr, scr); + m_assembler.jmpReg(scr); releaseScratch(scr); } // Arithmetic control flow operations - Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest) + Jump branchNeg32(ResultCondition cond, RegisterID srcDest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + if (cond == Overflow) + return branchMul32(cond, TrustedImm32(-1), srcDest, srcDest); + + neg32(srcDest); + + if (cond == Signed) { + m_assembler.cmppz(srcDest); + return branchFalse(); + } + + compare32(0, srcDest, Equal); + return (cond == NonZero) ? branchFalse() : branchTrue(); + } + + Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero)); + if (cond == Overflow) { m_assembler.addvlRegReg(src, dest); return branchTrue(); } - if (cond == Signed) { - m_assembler.addlRegReg(src, dest); - // Check if dest is negative + m_assembler.addlRegReg(src, dest); + + if ((cond == Signed) || (cond == PositiveOrZero)) { m_assembler.cmppz(dest); - return branchFalse(); + return (cond == Signed) ? branchFalse() : branchTrue(); } - m_assembler.addlRegReg(src, dest); compare32(0, dest, Equal); + return (cond == NonZero) ? branchFalse() : branchTrue(); + } - if (cond == NonZero) // NotEqual - return branchFalse(); - return branchTrue(); + Jump branchAdd32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero)); + + if (cond == Overflow) { + if (src1 == dest) + m_assembler.addvlRegReg(src2, dest); + else { + move(src2, dest); + m_assembler.addvlRegReg(src1, dest); + } + return branchTrue(); + } + + add32(src1, src2, dest); + + if ((cond == Signed) || (cond == PositiveOrZero)) { + m_assembler.cmppz(dest); + return (cond == Signed) ? branchFalse() : branchTrue(); + } + + compare32(0, dest, Equal); + return (cond == NonZero) ? branchFalse() : branchTrue(); } Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest) { - ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero)); - move(imm, scratchReg3); - return branchAdd32(cond, scratchReg3, dest); + RegisterID immval = claimScratch(); + move(imm, immval); + Jump result = branchAdd32(cond, immval, dest); + releaseScratch(immval); + return result; } Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) { - ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero)); - if (src != dest) - move(src, dest); + move(src, dest); if (cond == Overflow) { move(imm, scratchReg3); @@ -1923,16 +2047,42 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) add32(imm, dest); - if (cond == Signed) { + if ((cond == Signed) || (cond == PositiveOrZero)) { m_assembler.cmppz(dest); - return branchFalse(); + return (cond == Signed) ? branchFalse() : branchTrue(); } compare32(0, dest, Equal); + return (cond == NonZero) ? branchFalse() : branchTrue(); + } - if (cond == NonZero) // NotEqual - return branchFalse(); - return branchTrue(); + Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == PositiveOrZero) || (cond == Zero) || (cond == NonZero)); + bool result; + + move(imm, scratchReg3); + RegisterID destptr = claimScratch(); + RegisterID destval = claimScratch(); + move(TrustedImmPtr(dest.m_ptr), destptr); + m_assembler.movlMemReg(destptr, destval); + if (cond == Overflow) { + m_assembler.addvlRegReg(scratchReg3, destval); + result = true; + } else { + m_assembler.addlRegReg(scratchReg3, destval); + if ((cond == Signed) || (cond == PositiveOrZero)) { + m_assembler.cmppz(destval); + result = (cond == PositiveOrZero); + } else { + m_assembler.testlRegReg(destval, destval); + result = (cond != NonZero); + } + } + m_assembler.movlRegMem(destval, destptr); + releaseScratch(destval); + releaseScratch(destptr); + return result ? branchTrue() : branchFalse(); } Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest) @@ -1940,44 +2090,72 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); if (cond == Overflow) { - RegisterID scr1 = claimScratch(); - RegisterID scr = claimScratch(); - m_assembler.dmullRegReg(src, dest); + RegisterID scrsign = claimScratch(); + RegisterID msbres = claimScratch(); + m_assembler.dmulslRegReg(src, dest); m_assembler.stsmacl(dest); - m_assembler.movImm8(-31, scr); - m_assembler.movlRegReg(dest, scr1); - m_assembler.shaRegReg(scr1, scr); - m_assembler.stsmach(scr); - m_assembler.cmplRegReg(scr, scr1, SH4Condition(Equal)); - releaseScratch(scr1); - releaseScratch(scr); + m_assembler.cmppz(dest); + m_assembler.movt(scrsign); + m_assembler.addlImm8r(-1, scrsign); + m_assembler.stsmach(msbres); + m_assembler.cmplRegReg(msbres, scrsign, SH4Condition(Equal)); + releaseScratch(msbres); + releaseScratch(scrsign); return branchFalse(); } - m_assembler.imullRegReg(src, dest); - m_assembler.stsmacl(dest); + mul32(src, dest); + if (cond == Signed) { - // Check if dest is negative m_assembler.cmppz(dest); return branchFalse(); } compare32(0, dest, static_cast<RelationalCondition>(cond)); + return (cond == NonZero) ? branchFalse() : branchTrue(); + } - if (cond == NonZero) // NotEqual + Jump branchMul32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest) + { + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + + if (cond == Overflow) { + RegisterID scrsign = claimScratch(); + RegisterID msbres = claimScratch(); + m_assembler.dmulslRegReg(src1, src2); + m_assembler.stsmacl(dest); + m_assembler.cmppz(dest); + m_assembler.movt(scrsign); + m_assembler.addlImm8r(-1, scrsign); + m_assembler.stsmach(msbres); + m_assembler.cmplRegReg(msbres, scrsign, SH4Condition(Equal)); + releaseScratch(msbres); + releaseScratch(scrsign); return branchFalse(); - return branchTrue(); + } + + mul32(src1, src2, dest); + + if (cond == Signed) { + m_assembler.cmppz(dest); + return branchFalse(); + } + + compare32(0, dest, Equal); + return (cond == NonZero) ? branchFalse() : branchTrue(); } Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); - move(imm, scratchReg3); - if (src != dest) - move(src, dest); + if (src == dest) { + move(imm, scratchReg3); + return branchMul32(cond, scratchReg3, dest); + } - return branchMul32(cond, scratchReg3, dest); + move(imm, dest); + return branchMul32(cond, src, dest); } Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest) @@ -1989,76 +2167,92 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) return branchTrue(); } + sub32(src, dest); + if (cond == Signed) { - // Check if dest is negative - m_assembler.sublRegReg(src, dest); - compare32(0, dest, LessThan); - return branchTrue(); + m_assembler.cmppz(dest); + return branchFalse(); } - sub32(src, dest); compare32(0, dest, static_cast<RelationalCondition>(cond)); - - if (cond == NonZero) // NotEqual - return branchFalse(); - return branchTrue(); + return (cond == NonZero) ? branchFalse() : branchTrue(); } Jump branchSub32(ResultCondition cond, TrustedImm32 imm, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); - move(imm, scratchReg3); - return branchSub32(cond, scratchReg3, dest); + RegisterID immval = claimScratch(); + move(imm, immval); + Jump result = branchSub32(cond, immval, dest); + releaseScratch(immval); + return result; } Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) { - move(imm, scratchReg3); - if (src != dest) - move(src, dest); - return branchSub32(cond, scratchReg3, dest); + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + + move(src, dest); + return branchSub32(cond, imm, dest); } Jump branchSub32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest) { - if (src1 != dest) + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero)); + + if (src2 != dest) { move(src1, dest); - return branchSub32(cond, src2, dest); + return branchSub32(cond, src2, dest); + } + + if (cond == Overflow) { + RegisterID tmpval = claimScratch(); + move(src1, tmpval); + m_assembler.subvlRegReg(src2, tmpval); + move(tmpval, dest); + releaseScratch(tmpval); + return branchTrue(); + } + + RegisterID tmpval = claimScratch(); + move(src1, tmpval); + sub32(src2, tmpval); + move(tmpval, dest); + releaseScratch(tmpval); + + if (cond == Signed) { + m_assembler.cmppz(dest); + return branchFalse(); + } + + compare32(0, dest, static_cast<RelationalCondition>(cond)); + return (cond == NonZero) ? branchFalse() : branchTrue(); } Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero)); + or32(src, dest); + if (cond == Signed) { - or32(src, dest); - compare32(0, dest, static_cast<RelationalCondition>(LessThan)); - return branchTrue(); + m_assembler.cmppz(dest); + return branchFalse(); } - or32(src, dest); compare32(0, dest, static_cast<RelationalCondition>(cond)); - - if (cond == NonZero) // NotEqual - return branchFalse(); - return branchTrue(); + return (cond == NonZero) ? branchFalse() : branchTrue(); } - void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp) + void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID, bool negZeroCheck = true) { - m_assembler.ftrcdrmfpul(src); - m_assembler.stsfpulReg(dest); + truncateDoubleToInt32(src, dest); convertInt32ToDouble(dest, fscratch); failureCases.append(branchDouble(DoubleNotEqualOrUnordered, fscratch, src)); - if (dest == SH4Registers::r0) - m_assembler.cmpEqImmR0(0, dest); - else { - m_assembler.movImm8(0, scratchReg3); - m_assembler.cmplRegReg(scratchReg3, dest, SH4Condition(Equal)); - } - failureCases.append(branchTrue()); + if (negZeroCheck) + failureCases.append(branch32(Equal, dest, TrustedImm32(0))); } void neg32(RegisterID dst) @@ -2068,31 +2262,40 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void urshift32(RegisterID shiftamount, RegisterID dest) { - if (shiftamount == SH4Registers::r0) - m_assembler.andlImm8r(0x1f, shiftamount); - else { - RegisterID scr = claimScratch(); - m_assembler.loadConstant(0x1f, scr); - m_assembler.andlRegReg(scr, shiftamount); - releaseScratch(scr); - } - m_assembler.neg(shiftamount, shiftamount); - m_assembler.shllRegReg(dest, shiftamount); + RegisterID shiftTmp = claimScratch(); + m_assembler.loadConstant(0x1f, shiftTmp); + m_assembler.andlRegReg(shiftamount, shiftTmp); + m_assembler.neg(shiftTmp, shiftTmp); + m_assembler.shldRegReg(dest, shiftTmp); + releaseScratch(shiftTmp); + } + + void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest) + { + move(src, dest); + urshift32(shiftAmount, dest); } void urshift32(TrustedImm32 imm, RegisterID dest) { - RegisterID scr = claimScratch(); - m_assembler.loadConstant(-(imm.m_value & 0x1f), scr); - m_assembler.shaRegReg(dest, scr); - releaseScratch(scr); + int immMasked = imm.m_value & 0x1f; + if (!immMasked) + return; + + if ((immMasked == 1) || (immMasked == 2) || (immMasked == 8) || (immMasked == 16)) { + m_assembler.shlrImm8r(immMasked, dest); + return; + } + + RegisterID shiftTmp = claimScratch(); + m_assembler.loadConstant(-immMasked, shiftTmp); + m_assembler.shldRegReg(dest, shiftTmp); + releaseScratch(shiftTmp); } void urshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest) { - if (src != dest) - move(src, dest); - + move(src, dest); urshift32(shiftamount, dest); } @@ -2121,6 +2324,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) void breakpoint() { + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 2); m_assembler.bkpt(); m_assembler.nop(); } @@ -2129,6 +2333,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) { RegisterID dataTempRegister = claimScratch(); + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 10, 2 * sizeof(uint32_t)); dataLabel = moveWithPatch(initialRightValue, dataTempRegister); m_assembler.cmplRegReg(dataTempRegister, left, SH4Condition(cond)); releaseScratch(dataTempRegister); @@ -2146,6 +2351,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) m_assembler.addlRegReg(left.base, scr); m_assembler.movlMemReg(scr, scr); RegisterID scr1 = claimScratch(); + m_assembler.ensureSpace(m_assembler.maxInstructionSize + 10, 2 * sizeof(uint32_t)); dataLabel = moveWithPatch(initialRightValue, scr1); m_assembler.cmplRegReg(scr1, scr, SH4Condition(cond)); releaseScratch(scr); @@ -2207,13 +2413,12 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination) { - ASSERT_NOT_REACHED(); + SH4Assembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation()); } static ptrdiff_t maxJumpReplacementSize() { - ASSERT_NOT_REACHED(); - return 0; + return SH4Assembler::maxJumpReplacementSize(); } static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; } @@ -2223,9 +2428,9 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest) return label.labelAtOffset(0); } - static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID, void* initialValue) + static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID rd, void* initialValue) { - SH4Assembler::revertJump(instructionStart.dataLocation(), reinterpret_cast<uintptr_t>(initialValue) & 0xffff); + SH4Assembler::revertJumpToMove(instructionStart.dataLocation(), rd, reinterpret_cast<int>(initialValue)); } static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr) @@ -2253,9 +2458,20 @@ private: friend class LinkBuffer; friend class RepatchBuffer; - static void linkCall(void*, Call, FunctionPtr); - static void repatchCall(CodeLocationCall, CodeLocationLabel); - static void repatchCall(CodeLocationCall, FunctionPtr); + static void linkCall(void* code, Call call, FunctionPtr function) + { + SH4Assembler::linkCall(code, call.m_label, function.value()); + } + + static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) + { + SH4Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); + } + + static void repatchCall(CodeLocationCall call, FunctionPtr destination) + { + SH4Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); + } }; } // namespace JSC |