summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/assembler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/JavaScriptCore/assembler
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/JavaScriptCore/assembler')
-rw-r--r--Source/JavaScriptCore/assembler/ARMv7Assembler.h83
-rw-r--r--Source/JavaScriptCore/assembler/AbstractMacroAssembler.h59
-rw-r--r--Source/JavaScriptCore/assembler/LinkBuffer.h28
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssembler.h33
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARM.h66
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h151
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h50
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerSH4.h188
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h11
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h19
-rw-r--r--Source/JavaScriptCore/assembler/RepatchBuffer.h2
-rw-r--r--Source/JavaScriptCore/assembler/SH4Assembler.h28
12 files changed, 541 insertions, 177 deletions
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index 51788da08..5b523c277 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -531,9 +531,11 @@ private:
OP_STR_reg_T1 = 0x5000,
OP_STRH_reg_T1 = 0x5200,
OP_STRB_reg_T1 = 0x5400,
+ OP_LDRSB_reg_T1 = 0x5600,
OP_LDR_reg_T1 = 0x5800,
OP_LDRH_reg_T1 = 0x5A00,
OP_LDRB_reg_T1 = 0x5C00,
+ OP_LDRSH_reg_T1 = 0x5E00,
OP_STR_imm_T1 = 0x6000,
OP_LDR_imm_T1 = 0x6800,
OP_STRB_imm_T1 = 0x7000,
@@ -570,7 +572,9 @@ private:
OP_CMP_reg_T2 = 0xEBB0,
OP_VMOV_CtoD = 0xEC00,
OP_VMOV_DtoC = 0xEC10,
+ OP_FSTS = 0xED00,
OP_VSTR = 0xED00,
+ OP_FLDS = 0xED10,
OP_VLDR = 0xED10,
OP_VMOV_CtoS = 0xEE00,
OP_VMOV_StoC = 0xEE10,
@@ -586,6 +590,8 @@ private:
OP_VMRS = 0xEEB0,
OP_VNEG_T2 = 0xEEB0,
OP_VSQRT_T1 = 0xEEB0,
+ OP_VCVTSD_T1 = 0xEEB0,
+ OP_VCVTDS_T1 = 0xEEB0,
OP_B_T3a = 0xF000,
OP_B_T4a = 0xF000,
OP_AND_imm_T1 = 0xF000,
@@ -627,6 +633,8 @@ private:
OP_LDRH_imm_T2 = 0xF8B0,
OP_STR_imm_T3 = 0xF8C0,
OP_LDR_imm_T3 = 0xF8D0,
+ OP_LDRSB_reg_T2 = 0xF910,
+ OP_LDRSH_reg_T2 = 0xF930,
OP_LSL_reg_T2 = 0xFA00,
OP_LSR_reg_T2 = 0xFA20,
OP_ASR_reg_T2 = 0xFA40,
@@ -638,10 +646,12 @@ private:
typedef enum {
OP_VADD_T2b = 0x0A00,
OP_VDIVb = 0x0A00,
+ OP_FLDSb = 0x0A00,
OP_VLDRb = 0x0A00,
OP_VMOV_IMM_T2b = 0x0A00,
OP_VMOV_T2b = 0x0A40,
OP_VMUL_T2b = 0x0A00,
+ OP_FSTSb = 0x0A00,
OP_VSTRb = 0x0A00,
OP_VMOV_StoCb = 0x0A10,
OP_VMOV_CtoSb = 0x0A10,
@@ -654,6 +664,8 @@ private:
OP_VNEG_T2b = 0x0A40,
OP_VSUB_T2b = 0x0A40,
OP_VSQRT_T1b = 0x0A40,
+ OP_VCVTSD_T1b = 0x0A40,
+ OP_VCVTDS_T1b = 0x0A40,
OP_NOP_T2b = 0x8000,
OP_B_T3b = 0x8000,
OP_B_T4b = 0x9000,
@@ -739,6 +751,7 @@ public:
ASSERT(imm.isValid());
if (rn == ARMRegisters::sp) {
+ ASSERT(!(imm.getUInt16() & 3));
if (!(rd & 8) && imm.isUInt10()) {
m_formatter.oneWordOp5Reg3Imm8(OP_ADD_SP_imm_T1, rd, static_cast<uint8_t>(imm.getUInt10() >> 2));
return;
@@ -1157,6 +1170,30 @@ public:
else
m_formatter.twoWordOp12Reg4FourFours(OP_LDRB_reg_T2, rn, FourFours(rt, 0, shift, rm));
}
+
+ void ldrsb(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
+ {
+ ASSERT(rn != ARMRegisters::pc);
+ ASSERT(!BadReg(rm));
+ ASSERT(shift <= 3);
+
+ if (!shift && !((rt | rn | rm) & 8))
+ m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRSB_reg_T1, rm, rn, rt);
+ else
+ m_formatter.twoWordOp12Reg4FourFours(OP_LDRSB_reg_T2, rn, FourFours(rt, 0, shift, rm));
+ }
+
+ void ldrsh(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
+ {
+ ASSERT(rn != ARMRegisters::pc);
+ ASSERT(!BadReg(rm));
+ ASSERT(shift <= 3);
+
+ if (!shift && !((rt | rn | rm) & 8))
+ m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRSH_reg_T1, rm, rn, rt);
+ else
+ m_formatter.twoWordOp12Reg4FourFours(OP_LDRSH_reg_T2, rn, FourFours(rt, 0, shift, rm));
+ }
void lsl(RegisterID rd, RegisterID rm, int32_t shiftAmount)
{
@@ -1511,6 +1548,7 @@ public:
ASSERT(imm.isValid());
if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) {
+ ASSERT(!(imm.getUInt16() & 3));
m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, static_cast<uint8_t>(imm.getUInt9() >> 2));
return;
} else if (!((rd | rn) & 8)) {
@@ -1572,6 +1610,7 @@ public:
ASSERT(imm.isValid());
if ((rn == ARMRegisters::sp) && (rd == ARMRegisters::sp) && imm.isUInt9()) {
+ ASSERT(!(imm.getUInt16() & 3));
m_formatter.oneWordOp9Imm7(OP_SUB_SP_imm_T1, static_cast<uint8_t>(imm.getUInt9() >> 2));
return;
} else if (!((rd | rn) & 8)) {
@@ -1689,6 +1728,11 @@ public:
{
m_formatter.vfpMemOp(OP_VLDR, OP_VLDRb, true, rn, rd, imm);
}
+
+ void flds(FPSingleRegisterID rd, RegisterID rn, int32_t imm)
+ {
+ m_formatter.vfpMemOp(OP_FLDS, OP_FLDSb, false, rn, rd, imm);
+ }
void vmov(RegisterID rd, FPSingleRegisterID rn)
{
@@ -1737,6 +1781,11 @@ public:
m_formatter.vfpMemOp(OP_VSTR, OP_VSTRb, true, rn, rd, imm);
}
+ void fsts(FPSingleRegisterID rd, RegisterID rn, int32_t imm)
+ {
+ m_formatter.vfpMemOp(OP_FSTS, OP_FSTSb, false, rn, rd, imm);
+ }
+
void vsub(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
{
m_formatter.vfpOp(OP_VSUB_T2, OP_VSUB_T2b, true, rn, rd, rm);
@@ -1756,6 +1805,16 @@ public:
{
m_formatter.vfpOp(OP_VSQRT_T1, OP_VSQRT_T1b, true, VFPOperand(17), rd, rm);
}
+
+ void vcvtds(FPDoubleRegisterID rd, FPSingleRegisterID rm)
+ {
+ m_formatter.vfpOp(OP_VCVTDS_T1, OP_VCVTDS_T1b, false, VFPOperand(23), rd, rm);
+ }
+
+ void vcvtsd(FPSingleRegisterID rd, FPDoubleRegisterID rm)
+ {
+ m_formatter.vfpOp(OP_VCVTSD_T1, OP_VCVTSD_T1b, true, VFPOperand(23), rd, rm);
+ }
void nop()
{
@@ -1827,29 +1886,29 @@ public:
if (jumpType == JumpCondition) {
// 2-byte conditional T1
- const uint16_t* jumpT1Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT1)));
+ const uint16_t* jumpT1Location = reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT1)));
if (canBeJumpT1(jumpT1Location, to))
return LinkJumpT1;
// 4-byte conditional T3
- const uint16_t* jumpT3Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT3)));
+ const uint16_t* jumpT3Location = reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT3)));
if (canBeJumpT3(jumpT3Location, to, mayTriggerErrata)) {
if (!mayTriggerErrata)
return LinkJumpT3;
}
// 4-byte conditional T4 with IT
const uint16_t* conditionalJumpT4Location =
- reinterpret_cast<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkConditionalJumpT4)));
+ reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkConditionalJumpT4)));
if (canBeJumpT4(conditionalJumpT4Location, to, mayTriggerErrata)) {
if (!mayTriggerErrata)
return LinkConditionalJumpT4;
}
} else {
// 2-byte unconditional T2
- const uint16_t* jumpT2Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT2)));
+ const uint16_t* jumpT2Location = reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT2)));
if (canBeJumpT2(jumpT2Location, to))
return LinkJumpT2;
// 4-byte unconditional T4
- const uint16_t* jumpT4Location = reinterpret_cast<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT4)));
+ const uint16_t* jumpT4Location = reinterpret_cast_ptr<const uint16_t*>(from - (paddingSize - JUMP_ENUM_SIZE(LinkJumpT4)));
if (canBeJumpT4(jumpT4Location, to, mayTriggerErrata)) {
if (!mayTriggerErrata)
return LinkJumpT4;
@@ -1888,25 +1947,25 @@ public:
{
switch (record.linkType()) {
case LinkJumpT1:
- linkJumpT1(record.condition(), reinterpret_cast<uint16_t*>(from), to);
+ linkJumpT1(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), to);
break;
case LinkJumpT2:
- linkJumpT2(reinterpret_cast<uint16_t*>(from), to);
+ linkJumpT2(reinterpret_cast_ptr<uint16_t*>(from), to);
break;
case LinkJumpT3:
- linkJumpT3(record.condition(), reinterpret_cast<uint16_t*>(from), to);
+ linkJumpT3(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), to);
break;
case LinkJumpT4:
- linkJumpT4(reinterpret_cast<uint16_t*>(from), to);
+ linkJumpT4(reinterpret_cast_ptr<uint16_t*>(from), to);
break;
case LinkConditionalJumpT4:
- linkConditionalJumpT4(record.condition(), reinterpret_cast<uint16_t*>(from), to);
+ linkConditionalJumpT4(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), to);
break;
case LinkConditionalBX:
- linkConditionalBX(record.condition(), reinterpret_cast<uint16_t*>(from), to);
+ linkConditionalBX(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), to);
break;
case LinkBX:
- linkBX(reinterpret_cast<uint16_t*>(from), to);
+ linkBX(reinterpret_cast_ptr<uint16_t*>(from), to);
break;
default:
ASSERT_NOT_REACHED();
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
index ab343977e..4fb60dd2d 100644
--- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -26,6 +26,7 @@
#ifndef AbstractMacroAssembler_h
#define AbstractMacroAssembler_h
+#include "AssemblerBuffer.h"
#include "CodeLocation.h"
#include "MacroAssemblerCodeRef.h"
#include <wtf/CryptographicallyRandomNumber.h>
@@ -220,33 +221,17 @@ public:
struct TrustedImm32 {
explicit TrustedImm32(int32_t value)
: m_value(value)
-#if CPU(ARM) || CPU(MIPS)
- , m_isPointer(false)
-#endif
{
}
#if !CPU(X86_64)
explicit TrustedImm32(TrustedImmPtr ptr)
: m_value(ptr.asIntptr())
-#if CPU(ARM) || CPU(MIPS)
- , m_isPointer(true)
-#endif
{
}
#endif
int32_t m_value;
-#if CPU(ARM) || CPU(MIPS)
- // We rely on being able to regenerate code to recover exception handling
- // information. Since ARMv7 supports 16-bit immediates there is a danger
- // that if pointer values change the layout of the generated code will change.
- // To avoid this problem, always generate pointers (and thus Imm32s constructed
- // from ImmPtrs) with a code sequence that is able to represent any pointer
- // value - don't use a more compact form in these cases.
- // Same for MIPS.
- bool m_isPointer;
-#endif
};
@@ -450,6 +435,12 @@ public:
, m_condition(condition)
{
}
+#elif CPU(SH4)
+ Jump(AssemblerLabel jmp, SH4Assembler::JumpType type = SH4Assembler::JumpFar)
+ : m_label(jmp)
+ , m_type(type)
+ {
+ }
#else
Jump(AssemblerLabel jmp)
: m_label(jmp)
@@ -461,6 +452,8 @@ public:
{
#if CPU(ARM_THUMB2)
masm->m_assembler.linkJump(m_label, masm->m_assembler.label(), m_type, m_condition);
+#elif CPU(SH4)
+ masm->m_assembler.linkJump(m_label, masm->m_assembler.label(), m_type);
#else
masm->m_assembler.linkJump(m_label, masm->m_assembler.label());
#endif
@@ -483,6 +476,24 @@ public:
ARMv7Assembler::JumpType m_type;
ARMv7Assembler::Condition m_condition;
#endif
+#if CPU(SH4)
+ SH4Assembler::JumpType m_type;
+#endif
+ };
+
+ struct PatchableJump {
+ PatchableJump()
+ {
+ }
+
+ explicit PatchableJump(Jump jump)
+ : m_jump(jump)
+ {
+ }
+
+ operator Jump&() { return m_jump; }
+
+ Jump m_jump;
};
// JumpList:
@@ -551,7 +562,7 @@ public:
}
template<typename T, typename U>
- ptrdiff_t differenceBetween(T from, U to)
+ static ptrdiff_t differenceBetween(T from, U to)
{
return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label);
}
@@ -561,27 +572,15 @@ public:
return reinterpret_cast<ptrdiff_t>(b.executableAddress()) - reinterpret_cast<ptrdiff_t>(a.executableAddress());
}
- void beginUninterruptedSequence() { m_inUninterruptedSequence = true; }
- void endUninterruptedSequence() { m_inUninterruptedSequence = false; }
-
unsigned debugOffset() { return m_assembler.debugOffset(); }
protected:
AbstractMacroAssembler()
- : m_inUninterruptedSequence(false)
- , m_randomSource(cryptographicallyRandomNumber())
+ : m_randomSource(cryptographicallyRandomNumber())
{
}
AssemblerType m_assembler;
-
- bool inUninterruptedSequence()
- {
- return m_inUninterruptedSequence;
- }
-
- bool m_inUninterruptedSequence;
-
uint32_t random()
{
diff --git a/Source/JavaScriptCore/assembler/LinkBuffer.h b/Source/JavaScriptCore/assembler/LinkBuffer.h
index 6ec9a7eb9..5e91ef3ce 100644
--- a/Source/JavaScriptCore/assembler/LinkBuffer.h
+++ b/Source/JavaScriptCore/assembler/LinkBuffer.h
@@ -63,6 +63,7 @@ class LinkBuffer {
typedef MacroAssemblerCodePtr CodePtr;
typedef MacroAssembler::Label Label;
typedef MacroAssembler::Jump Jump;
+ typedef MacroAssembler::PatchableJump PatchableJump;
typedef MacroAssembler::JumpList JumpList;
typedef MacroAssembler::Call Call;
typedef MacroAssembler::DataLabelCompact DataLabelCompact;
@@ -154,9 +155,9 @@ public:
return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_label)));
}
- CodeLocationLabel locationOf(Jump jump)
+ CodeLocationLabel locationOf(PatchableJump jump)
{
- return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), applyOffset(jump.m_label)));
+ return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), applyOffset(jump.m_jump.m_label)));
}
CodeLocationLabel locationOf(Label label)
@@ -260,9 +261,9 @@ private:
// Copy the instructions from the last jump to the current one.
size_t regionSize = jumpsToLink[i].from() - readPtr;
- uint16_t* copySource = reinterpret_cast<uint16_t*>(inData + readPtr);
- uint16_t* copyEnd = reinterpret_cast<uint16_t*>(inData + readPtr + regionSize);
- uint16_t* copyDst = reinterpret_cast<uint16_t*>(outData + writePtr);
+ uint16_t* copySource = reinterpret_cast_ptr<uint16_t*>(inData + readPtr);
+ uint16_t* copyEnd = reinterpret_cast_ptr<uint16_t*>(inData + readPtr + regionSize);
+ uint16_t* copyDst = reinterpret_cast_ptr<uint16_t*>(outData + writePtr);
ASSERT(!(regionSize % 2));
ASSERT(!(readPtr % 2));
ASSERT(!(writePtr % 2));
@@ -374,6 +375,23 @@ private:
for (unsigned i = 0; i < tsize; i++)
dataLog("\t.short\t0x%x\n", tcode[i]);
+#elif CPU(ARM_TRADITIONAL)
+ // gcc -c jit.s
+ // objdump -D jit.o
+ static unsigned codeCount = 0;
+ unsigned int* tcode = static_cast<unsigned int*>(code);
+ size_t tsize = size / sizeof(unsigned int);
+ char nameBuf[128];
+ snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++);
+ dataLog("\t.globl\t%s\n"
+ "\t.align 4\n"
+ "\t.code 32\n"
+ "\t.text\n"
+ "# %p\n"
+ "%s:\n", nameBuf, code, nameBuf);
+
+ for (unsigned i = 0; i < tsize; i++)
+ dataLog("\t.long\t0x%x\n", tcode[i]);
#endif
}
#endif
diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h
index 4c54e29aa..516ffac16 100644
--- a/Source/JavaScriptCore/assembler/MacroAssembler.h
+++ b/Source/JavaScriptCore/assembler/MacroAssembler.h
@@ -229,6 +229,18 @@ public:
branchTestPtr(cond, reg).linkTo(target, this);
}
+#if !CPU(ARM_THUMB2)
+ PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
+ {
+ return PatchableJump(branchPtrWithPatch(cond, left, dataLabel, initialRightValue));
+ }
+
+ PatchableJump patchableJump()
+ {
+ return PatchableJump(jump());
+ }
+#endif
+
void jump(Label target)
{
jump().linkTo(target, this);
@@ -529,7 +541,6 @@ public:
bool shouldBlind(ImmPtr imm)
{
- ASSERT(!inUninterruptedSequence());
#if !defined(NDEBUG)
UNUSED_PARAM(imm);
// Debug always blind all constants, if only so we know
@@ -636,7 +647,6 @@ public:
#if ENABLE(JIT_CONSTANT_BLINDING)
bool shouldBlind(Imm32 imm)
{
- ASSERT(!inUninterruptedSequence());
#if !defined(NDEBUG)
UNUSED_PARAM(imm);
// Debug always blind all constants, if only so we know
@@ -699,8 +709,11 @@ public:
BlindedImm32 additionBlindedConstant(Imm32 imm)
{
+ // The addition immediate may be used as a pointer offset. Keep aligned based on "imm".
+ static uint32_t maskTable[4] = { 0xfffffffc, 0xffffffff, 0xfffffffe, 0xffffffff };
+
uint32_t baseValue = imm.asTrustedImm32().m_value;
- uint32_t key = keyForConstant(baseValue);
+ uint32_t key = keyForConstant(baseValue) & maskTable[baseValue & 3];
if (key > baseValue)
key = key - baseValue;
return BlindedImm32(baseValue - key, key);
@@ -828,9 +841,17 @@ public:
store32(blind.value1, dest);
xor32(blind.value2, dest);
#else
- RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding();
- loadXorBlindedConstant(xorBlindConstant(imm), scratchRegister);
- store32(scratchRegister, dest);
+ if (RegisterID scratchRegister = (RegisterID)scratchRegisterForBlinding()) {
+ loadXorBlindedConstant(xorBlindConstant(imm), scratchRegister);
+ store32(scratchRegister, dest);
+ } else {
+ // If we don't have a scratch register available for use, we'll just
+ // place a random number of nops.
+ uint32_t nopCount = random() & 3;
+ while (nopCount--)
+ nop();
+ store32(imm.asTrustedImm32(), dest);
+ }
#endif
} else
store32(imm.asTrustedImm32(), dest);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index c0cd766cb..1775cb4cf 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -150,6 +150,11 @@ public:
m_assembler.movs_r(dest, m_assembler.lsl(dest, imm.m_value & 0x1f));
}
+ void lshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ m_assembler.movs_r(dest, m_assembler.lsl(src, imm.m_value & 0x1f));
+ }
+
void mul32(RegisterID src, RegisterID dest)
{
if (src == dest) {
@@ -180,6 +185,11 @@ public:
m_assembler.orrs_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
}
+ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ m_assembler.orrs_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
+ }
+
void or32(RegisterID op1, RegisterID op2, RegisterID dest)
{
m_assembler.orrs_r(dest, op1, op2);
@@ -217,6 +227,11 @@ public:
{
m_assembler.movs_r(dest, m_assembler.lsr(dest, imm.m_value & 0x1f));
}
+
+ void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
+ {
+ m_assembler.movs_r(dest, m_assembler.lsr(src, imm.m_value & 0x1f));
+ }
void sub32(RegisterID src, RegisterID dest)
{
@@ -259,6 +274,14 @@ public:
m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
}
+ void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ if (imm.m_value == -1)
+ m_assembler.mvns_r(dest, src);
+ else
+ m_assembler.eors_r(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
+ }
+
void countLeadingZeros32(RegisterID src, RegisterID dest)
{
#if WTF_ARM_ARCH_AT_LEAST(5)
@@ -353,10 +376,7 @@ public:
void store32(TrustedImm32 imm, ImplicitAddress address)
{
- if (imm.m_isPointer)
- m_assembler.ldr_un_imm(ARMRegisters::S1, imm.m_value);
- else
- move(imm, ARMRegisters::S1);
+ move(imm, ARMRegisters::S1);
store32(ARMRegisters::S1, address);
}
@@ -369,10 +389,7 @@ public:
void store32(TrustedImm32 imm, void* address)
{
m_assembler.ldr_un_imm(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
- if (imm.m_isPointer)
- m_assembler.ldr_un_imm(ARMRegisters::S1, imm.m_value);
- else
- m_assembler.moveImm(imm.m_value, ARMRegisters::S1);
+ m_assembler.moveImm(imm.m_value, ARMRegisters::S1);
m_assembler.dtr_u(false, ARMRegisters::S1, ARMRegisters::S0, 0);
}
@@ -400,10 +417,7 @@ public:
void move(TrustedImm32 imm, RegisterID dest)
{
- if (imm.m_isPointer)
- m_assembler.ldr_un_imm(dest, imm.m_value);
- else
- m_assembler.moveImm(imm.m_value, dest);
+ m_assembler.moveImm(imm.m_value, dest);
}
void move(RegisterID src, RegisterID dest)
@@ -456,16 +470,11 @@ public:
Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right, int useConstantPool = 0)
{
- if (right.m_isPointer) {
- m_assembler.ldr_un_imm(ARMRegisters::S0, right.m_value);
- m_assembler.cmp_r(left, ARMRegisters::S0);
- } else {
- ARMWord tmp = (right.m_value == 0x80000000) ? ARMAssembler::INVALID_IMM : m_assembler.getOp2(-right.m_value);
- if (tmp != ARMAssembler::INVALID_IMM)
- m_assembler.cmn_r(left, tmp);
- else
- m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
- }
+ ARMWord tmp = (right.m_value == 0x80000000) ? ARMAssembler::INVALID_IMM : m_assembler.getOp2(-right.m_value);
+ if (tmp != ARMAssembler::INVALID_IMM)
+ m_assembler.cmn_r(left, tmp);
+ else
+ m_assembler.cmp_r(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool));
}
@@ -627,6 +636,13 @@ public:
return Jump(m_assembler.jmp(ARMCondition(cond)));
}
+ Jump branchSub32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
+ {
+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+ m_assembler.subs_r(dest, op1, op2);
+ return Jump(m_assembler.jmp(ARMCondition(cond)));
+ }
+
Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
{
ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -687,6 +703,12 @@ public:
m_assembler.mov_r(dest, ARMAssembler::getOp2(1), ARMCondition(cond));
}
+ void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest)
+ {
+ load8(left, ARMRegisters::S1);
+ compare32(cond, ARMRegisters::S1, right, dest);
+ }
+
void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest)
{
if (mask.m_value == -1)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index 43ea2ed5a..3b62cb5be 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -45,6 +45,11 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); }
public:
+ MacroAssemblerARMv7()
+ : m_makeJumpPatchable(false)
+ {
+ }
+
typedef ARMv7Assembler::LinkRecord LinkRecord;
typedef ARMv7Assembler::JumpType JumpType;
typedef ARMv7Assembler::JumpLinkType JumpLinkType;
@@ -499,9 +504,10 @@ private:
}
}
- void load16Signed(ArmAddress, RegisterID)
+ void load16Signed(ArmAddress address, RegisterID dest)
{
- unreachableForPlatform();
+ ASSERT(address.type == ArmAddress::HasIndex);
+ m_assembler.ldrsh(dest, address.base, address.u.index, address.u.scale);
}
void load8(ArmAddress address, RegisterID dest)
@@ -518,9 +524,10 @@ private:
}
}
- void load8Signed(ArmAddress, RegisterID)
+ void load8Signed(ArmAddress address, RegisterID dest)
{
- unreachableForPlatform();
+ ASSERT(address.type == ArmAddress::HasIndex);
+ m_assembler.ldrsb(dest, address.base, address.u.index, address.u.scale);
}
protected:
@@ -609,9 +616,9 @@ public:
load8(setupArmAddress(address), dest);
}
- void load8Signed(BaseIndex, RegisterID)
+ void load8Signed(BaseIndex address, RegisterID dest)
{
- unreachableForPlatform();
+ load8Signed(setupArmAddress(address), dest);
}
DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
@@ -649,9 +656,9 @@ public:
m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale);
}
- void load16Signed(BaseIndex, RegisterID)
+ void load16Signed(BaseIndex address, RegisterID dest)
{
- unreachableForPlatform();
+ load16Signed(setupArmAddress(address), dest);
}
void load16(ImplicitAddress address, RegisterID dest)
@@ -722,7 +729,6 @@ public:
}
#if ENABLE(JIT_CONSTANT_BLINDING)
- static RegisterID scratchRegisterForBlinding() { return dataTempRegister; }
static bool shouldBlindForSpecificArch(uint32_t value)
{
ARMThumbImmediate immediate = ARMThumbImmediate::makeEncodedImm(value);
@@ -764,18 +770,35 @@ public:
m_assembler.vldr(dest, base, offset);
}
+ void loadFloat(ImplicitAddress address, FPRegisterID dest)
+ {
+ RegisterID base = address.base;
+ int32_t offset = address.offset;
+
+ // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
+ if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) {
+ add32(TrustedImm32(offset), base, addressTempRegister);
+ base = addressTempRegister;
+ offset = 0;
+ }
+
+ m_assembler.flds(ARMRegisters::asSingle(dest), base, offset);
+ }
+
void loadDouble(BaseIndex address, FPRegisterID dest)
{
- UNUSED_PARAM(address);
- UNUSED_PARAM(dest);
- unreachableForPlatform();
+ move(address.index, addressTempRegister);
+ lshift32(TrustedImm32(address.scale), addressTempRegister);
+ add32(address.base, addressTempRegister);
+ loadDouble(Address(addressTempRegister, address.offset), dest);
}
void loadFloat(BaseIndex address, FPRegisterID dest)
{
- UNUSED_PARAM(address);
- UNUSED_PARAM(dest);
- unreachableForPlatform();
+ move(address.index, addressTempRegister);
+ lshift32(TrustedImm32(address.scale), addressTempRegister);
+ add32(address.base, addressTempRegister);
+ loadFloat(Address(addressTempRegister, address.offset), dest);
}
void moveDouble(FPRegisterID src, FPRegisterID dest)
@@ -805,6 +828,21 @@ public:
m_assembler.vstr(src, base, offset);
}
+ void storeFloat(FPRegisterID src, ImplicitAddress address)
+ {
+ RegisterID base = address.base;
+ int32_t offset = address.offset;
+
+ // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
+ if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) {
+ add32(TrustedImm32(offset), base, addressTempRegister);
+ base = addressTempRegister;
+ offset = 0;
+ }
+
+ m_assembler.fsts(ARMRegisters::asSingle(src), base, offset);
+ }
+
void storeDouble(FPRegisterID src, const void* address)
{
move(TrustedImmPtr(address), addressTempRegister);
@@ -814,7 +852,7 @@ public:
void storeDouble(FPRegisterID src, BaseIndex address)
{
move(address.index, addressTempRegister);
- mul32(TrustedImm32(1 << address.scale), addressTempRegister, addressTempRegister);
+ lshift32(TrustedImm32(address.scale), addressTempRegister);
add32(address.base, addressTempRegister);
storeDouble(src, Address(addressTempRegister, address.offset));
}
@@ -822,11 +860,11 @@ public:
void storeFloat(FPRegisterID src, BaseIndex address)
{
move(address.index, addressTempRegister);
- mul32(TrustedImm32(1 << address.scale), addressTempRegister, addressTempRegister);
+ lshift32(TrustedImm32(address.scale), addressTempRegister);
add32(address.base, addressTempRegister);
- storeDouble(src, Address(addressTempRegister, address.offset));
+ storeFloat(src, Address(addressTempRegister, address.offset));
}
-
+
void addDouble(FPRegisterID src, FPRegisterID dest)
{
m_assembler.vadd(dest, dest, src);
@@ -908,7 +946,7 @@ public:
void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
{
- m_assembler.vmov(fpTempRegisterAsSingle(), src);
+ m_assembler.vmov(fpTempRegister, src, src);
m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle());
}
@@ -916,7 +954,7 @@ public:
{
// Fixme: load directly into the fpr!
load32(address, dataTempRegister);
- m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister);
+ m_assembler.vmov(fpTempRegister, dataTempRegister, dataTempRegister);
m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle());
}
@@ -924,22 +962,18 @@ public:
{
// Fixme: load directly into the fpr!
load32(address.m_ptr, dataTempRegister);
- m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister);
+ m_assembler.vmov(fpTempRegister, dataTempRegister, dataTempRegister);
m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle());
}
void convertFloatToDouble(FPRegisterID src, FPRegisterID dst)
{
- UNUSED_PARAM(src);
- UNUSED_PARAM(dst);
- unreachableForPlatform();
+ m_assembler.vcvtds(dst, ARMRegisters::asSingle(src));
}
void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst)
{
- UNUSED_PARAM(src);
- UNUSED_PARAM(dst);
- unreachableForPlatform();
+ m_assembler.vcvtsd(ARMRegisters::asSingle(dst), src);
}
Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
@@ -995,8 +1029,17 @@ public:
{
m_assembler.vcvt_floatingPointToSigned(fpTempRegisterAsSingle(), src);
m_assembler.vmov(dest, fpTempRegisterAsSingle());
+
+ Jump overflow = branch32(Equal, dest, TrustedImm32(0x7fffffff));
+ Jump success = branch32(GreaterThanOrEqual, dest, TrustedImm32(0));
+ overflow.link(this);
- return branch32(branchType ? GreaterThanOrEqual : LessThan, dest, TrustedImm32(0));
+ if (branchType == BranchIfTruncateSuccessful)
+ return success;
+
+ Jump failure = jump();
+ success.link(this);
+ return failure;
}
// Result is undefined if the value is outside of the integer range.
@@ -1092,20 +1135,16 @@ public:
{
uint32_t value = imm.m_value;
- if (imm.m_isPointer)
- moveFixedWidthEncoding(imm, dest);
- else {
- ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(value);
+ ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(value);
- if (armImm.isValid())
- m_assembler.mov(dest, armImm);
- else if ((armImm = ARMThumbImmediate::makeEncodedImm(~value)).isValid())
- m_assembler.mvn(dest, armImm);
- else {
- m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(value));
- if (value & 0xffff0000)
- m_assembler.movt(dest, ARMThumbImmediate::makeUInt16(value >> 16));
- }
+ if (armImm.isValid())
+ m_assembler.mov(dest, armImm);
+ else if ((armImm = ARMThumbImmediate::makeEncodedImm(~value)).isValid())
+ m_assembler.mvn(dest, armImm);
+ else {
+ m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(value));
+ if (value & 0xffff0000)
+ m_assembler.movt(dest, ARMThumbImmediate::makeUInt16(value >> 16));
}
}
@@ -1527,6 +1566,12 @@ public:
compare32(cond, dataTempRegister, right, dest);
}
+ void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest)
+ {
+ load8(left, addressTempRegister);
+ compare32(cond, addressTempRegister, right, dest);
+ }
+
void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
{
compare32(left, right);
@@ -1582,6 +1627,22 @@ public:
return branch32(cond, addressTempRegister, dataTempRegister);
}
+ PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
+ {
+ m_makeJumpPatchable = true;
+ Jump result = branchPtrWithPatch(cond, left, dataLabel, initialRightValue);
+ m_makeJumpPatchable = false;
+ return PatchableJump(result);
+ }
+
+ PatchableJump patchableJump()
+ {
+ m_makeJumpPatchable = true;
+ Jump result = jump();
+ m_makeJumpPatchable = false;
+ return PatchableJump(result);
+ }
+
ALWAYS_INLINE DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
{
DataLabelPtr label = moveWithPatch(initialValue, dataTempRegister);
@@ -1616,18 +1677,17 @@ public:
}
protected:
-
ALWAYS_INLINE Jump jump()
{
moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
- return Jump(m_assembler.bx(dataTempRegister), inUninterruptedSequence() ? ARMv7Assembler::JumpNoConditionFixedSize : ARMv7Assembler::JumpNoCondition);
+ return Jump(m_assembler.bx(dataTempRegister), m_makeJumpPatchable ? ARMv7Assembler::JumpNoConditionFixedSize : ARMv7Assembler::JumpNoCondition);
}
ALWAYS_INLINE Jump makeBranch(ARMv7Assembler::Condition cond)
{
m_assembler.it(cond, true, true);
moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
- return Jump(m_assembler.bx(dataTempRegister), inUninterruptedSequence() ? ARMv7Assembler::JumpConditionFixedSize : ARMv7Assembler::JumpCondition, cond);
+ return Jump(m_assembler.bx(dataTempRegister), m_makeJumpPatchable ? ARMv7Assembler::JumpConditionFixedSize : ARMv7Assembler::JumpCondition, cond);
}
ALWAYS_INLINE Jump makeBranch(RelationalCondition cond) { return makeBranch(armV7Condition(cond)); }
ALWAYS_INLINE Jump makeBranch(ResultCondition cond) { return makeBranch(armV7Condition(cond)); }
@@ -1724,6 +1784,7 @@ private:
ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
}
+ bool m_makeJumpPatchable;
};
} // namespace JSC
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index 910bc5a47..f9c3457b5 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -116,7 +116,7 @@ public:
void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
- if (!imm.m_isPointer && imm.m_value >= -32768 && imm.m_value <= 32767
+ if (imm.m_value >= -32768 && imm.m_value <= 32767
&& !m_fixedWidth) {
/*
addiu dest, src, imm
@@ -148,8 +148,7 @@ public:
sw dataTemp, offset(base)
*/
m_assembler.lw(dataTempRegister, address.base, address.offset);
- if (!imm.m_isPointer
- && imm.m_value >= -32768 && imm.m_value <= 32767
+ if (imm.m_value >= -32768 && imm.m_value <= 32767
&& !m_fixedWidth)
m_assembler.addiu(dataTempRegister, dataTempRegister,
imm.m_value);
@@ -228,7 +227,7 @@ public:
*/
move(TrustedImmPtr(address.m_ptr), addrTempRegister);
m_assembler.lw(dataTempRegister, addrTempRegister, 0);
- if (!imm.m_isPointer && imm.m_value >= -32768 && imm.m_value <= 32767
+ if (imm.m_value >= -32768 && imm.m_value <= 32767
&& !m_fixedWidth)
m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value);
else {
@@ -245,9 +244,9 @@ public:
void and32(TrustedImm32 imm, RegisterID dest)
{
- if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+ if (!imm.m_value && !m_fixedWidth)
move(MIPSRegisters::zero, dest);
- else if (!imm.m_isPointer && imm.m_value > 0 && imm.m_value < 65535
+ else if (imm.m_value > 0 && imm.m_value < 65535
&& !m_fixedWidth)
m_assembler.andi(dest, dest, imm.m_value);
else {
@@ -277,9 +276,9 @@ public:
void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
- if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+ if (!imm.m_value && !m_fixedWidth)
move(MIPSRegisters::zero, dest);
- else if (!imm.m_isPointer && imm.m_value == 1 && !m_fixedWidth)
+ else if (imm.m_value == 1 && !m_fixedWidth)
move(src, dest);
else {
/*
@@ -308,10 +307,10 @@ public:
void or32(TrustedImm32 imm, RegisterID dest)
{
- if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+ if (!imm.m_value && !m_fixedWidth)
return;
- if (!imm.m_isPointer && imm.m_value > 0 && imm.m_value < 65535
+ if (imm.m_value > 0 && imm.m_value < 65535
&& !m_fixedWidth) {
m_assembler.ori(dest, dest, imm.m_value);
return;
@@ -357,7 +356,7 @@ public:
void sub32(TrustedImm32 imm, RegisterID dest)
{
- if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
+ if (imm.m_value >= -32767 && imm.m_value <= 32768
&& !m_fixedWidth) {
/*
addiu dest, src, imm
@@ -375,7 +374,7 @@ public:
void sub32(RegisterID src, TrustedImm32 imm, RegisterID dest)
{
- if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
+ if (imm.m_value >= -32767 && imm.m_value <= 32768
&& !m_fixedWidth) {
/*
addiu dest, src, imm
@@ -402,8 +401,7 @@ public:
sw dataTemp, offset(base)
*/
m_assembler.lw(dataTempRegister, address.base, address.offset);
- if (!imm.m_isPointer
- && imm.m_value >= -32767 && imm.m_value <= 32768
+ if (imm.m_value >= -32767 && imm.m_value <= 32768
&& !m_fixedWidth)
m_assembler.addiu(dataTempRegister, dataTempRegister,
-imm.m_value);
@@ -426,8 +424,7 @@ public:
m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
m_assembler.lw(dataTempRegister, addrTempRegister, address.offset);
- if (!imm.m_isPointer
- && imm.m_value >= -32767 && imm.m_value <= 32768
+ if (imm.m_value >= -32767 && imm.m_value <= 32768
&& !m_fixedWidth)
m_assembler.addiu(dataTempRegister, dataTempRegister,
-imm.m_value);
@@ -458,7 +455,7 @@ public:
move(TrustedImmPtr(address.m_ptr), addrTempRegister);
m_assembler.lw(dataTempRegister, addrTempRegister, 0);
- if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
+ if (imm.m_value >= -32767 && imm.m_value <= 32768
&& !m_fixedWidth) {
m_assembler.addiu(dataTempRegister, dataTempRegister,
-imm.m_value);
@@ -807,7 +804,7 @@ public:
{
if (address.offset >= -32768 && address.offset <= 32767
&& !m_fixedWidth) {
- if (!imm.m_isPointer && !imm.m_value)
+ if (!imm.m_value)
m_assembler.sw(MIPSRegisters::zero, address.base,
address.offset);
else {
@@ -822,7 +819,7 @@ public:
*/
m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
- if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+ if (!imm.m_value && !m_fixedWidth)
m_assembler.sw(MIPSRegisters::zero, addrTempRegister,
address.offset);
else {
@@ -850,7 +847,7 @@ public:
li addrTemp, address
sw src, 0(addrTemp)
*/
- if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth) {
+ if (!imm.m_value && !m_fixedWidth) {
move(TrustedImmPtr(address), addrTempRegister);
m_assembler.sw(MIPSRegisters::zero, addrTempRegister, 0);
} else {
@@ -928,9 +925,9 @@ public:
void move(TrustedImm32 imm, RegisterID dest)
{
- if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+ if (!imm.m_value && !m_fixedWidth)
move(MIPSRegisters::zero, dest);
- else if (imm.m_isPointer || m_fixedWidth) {
+ else if (m_fixedWidth) {
m_assembler.lui(dest, imm.m_value >> 16);
m_assembler.ori(dest, dest, imm.m_value);
} else
@@ -994,6 +991,15 @@ public:
return branch32(cond, dataTempRegister, immTempRegister);
}
+ void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest)
+ {
+ // Make sure the immediate value is unsigned 8 bits.
+ ASSERT(!(right.m_value & 0xFFFFFF00));
+ load8(left, dataTempRegister);
+ move(right, immTempRegister);
+ compare32(cond, dataTempRegister, immTempRegister, dest);
+ }
+
Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
{
ASSERT(!(right.m_value & 0xFFFFFF00));
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
index 2b5c0cc44..c132ad642 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
@@ -156,6 +156,17 @@ public:
releaseScratch(scr);
}
+ void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ if (src != dest) {
+ move(imm, dest);
+ and32(src, dest);
+ return;
+ }
+
+ and32(imm, dest);
+ }
+
void lshift32(RegisterID shiftamount, RegisterID dest)
{
if (shiftamount == SH4Registers::r0)
@@ -193,6 +204,14 @@ public:
releaseScratch(scr);
}
+ void lshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+
+ lshift32(shiftamount, dest);
+ }
+
void mul32(RegisterID src, RegisterID dest)
{
m_assembler.imullRegReg(src, dest);
@@ -239,6 +258,29 @@ public:
}
}
+
+void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ if (src != dest) {
+ move(imm, dest);
+ or32(src, dest);
+ return;
+ }
+
+ or32(imm, dest);
+ }
+
+ void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ if (src != dest) {
+ move(imm, dest);
+ xor32(src, dest);
+ return;
+ }
+
+ xor32(imm, dest);
+ }
+
void rshift32(RegisterID shiftamount, RegisterID dest)
{
if (shiftamount == SH4Registers::r0)
@@ -681,8 +723,7 @@ public:
load8(scr, scr1);
add32(TrustedImm32(1), scr);
load8(scr, dest);
- move(TrustedImm32(8), scr);
- m_assembler.shllRegReg(dest, scr);
+ m_assembler.shllImm8r(8, dest);
or32(scr1, dest);
releaseScratch(scr);
@@ -942,6 +983,12 @@ public:
void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
{
RegisterID scr = claimScratch();
+ RegisterID scr1 = claimScratch();
+ Jump m_jump;
+ JumpList end;
+
+ if (dest != SH4Registers::r0)
+ move(SH4Registers::r0, scr1);
move(address.index, scr);
lshift32(TrustedImm32(address.scale), scr);
@@ -950,13 +997,44 @@ public:
if (address.offset)
add32(TrustedImm32(address.offset), scr);
- RegisterID scr1 = claimScratch();
+ m_assembler.ensureSpace(m_assembler.maxInstructionSize + 68, sizeof(uint32_t));
+ move(scr, SH4Registers::r0);
+ m_assembler.andlImm8r(0x3, SH4Registers::r0);
+ m_assembler.cmpEqImmR0(0x0, SH4Registers::r0);
+ m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear);
+ if (dest != SH4Registers::r0)
+ move(scr1, SH4Registers::r0);
+
+ load32(scr, 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);
+
+ if (dest != SH4Registers::r0)
+ move(scr1, SH4Registers::r0);
+
+ m_jump = Jump(m_assembler.jne(), SH4Assembler::JumpNear);
load16(scr, scr1);
add32(TrustedImm32(2), scr);
load16(scr, dest);
- move(TrustedImm32(16), scr);
- m_assembler.shllRegReg(dest, scr);
+ 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);
+ 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);
+ or32(scr1, dest);
+ end.link(this);
releaseScratch(scr);
releaseScratch(scr1);
@@ -999,19 +1077,22 @@ public:
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.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- m_assembler.branch(BT_OPCODE, 8);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcnvds(left);
m_assembler.stsfpulReg(scr);
m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.branch(BT_OPCODE, 4);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcmppeq(right, left);
releaseScratch(scr);
- return branchFalse();
+ Jump m_jump = branchFalse();
+ end.link(this);
+ return m_jump;
}
if (cond == DoubleGreaterThan) {
@@ -1036,113 +1117,135 @@ public:
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));
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- m_assembler.branch(BT_OPCODE, 5);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcnvds(left);
m_assembler.stsfpulReg(scr);
m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.branch(BT_OPCODE, 1);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcmppeq(left, right);
+ Jump m_jump = Jump(m_assembler.je());
+ end.link(this);
+ m_assembler.extraInstrForBranch(scr);
releaseScratch(scr);
- return branchTrue();
+ 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));
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- m_assembler.branch(BT_OPCODE, 5);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcnvds(left);
m_assembler.stsfpulReg(scr);
m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.branch(BT_OPCODE, 1);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcmppgt(right, left);
+ Jump m_jump = Jump(m_assembler.je());
+ end.link(this);
+ m_assembler.extraInstrForBranch(scr);
releaseScratch(scr);
- return branchTrue();
+ 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));
- m_assembler.branch(BT_OPCODE, 5);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcnvds(left);
m_assembler.stsfpulReg(scr);
m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.branch(BT_OPCODE, 1);
+ 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 branchFalse();
+ return m_jump;
}
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));
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 22, sizeof(uint32_t));
- m_assembler.branch(BT_OPCODE, 5);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcnvds(left);
m_assembler.stsfpulReg(scr);
m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.branch(BT_OPCODE, 1);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcmppgt(left, right);
+ Jump m_jump = Jump(m_assembler.je());
+ end.link(this);
+ m_assembler.extraInstrForBranch(scr);
releaseScratch(scr);
- return branchTrue();
+ 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));
- m_assembler.branch(BT_OPCODE, 5);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcnvds(left);
m_assembler.stsfpulReg(scr);
m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.branch(BT_OPCODE, 1);
+ 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 branchFalse();
+ return m_jump;
}
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));
- m_assembler.branch(BT_OPCODE, 5);
+ end.append(Jump(m_assembler.je(), SH4Assembler::JumpNear));
m_assembler.dcnvds(left);
m_assembler.stsfpulReg(scr);
m_assembler.cmplRegReg(scratchReg3, scr, SH4Condition(Equal));
- m_assembler.branch(BT_OPCODE, 1);
+ 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 branchFalse();
+ return m_jump;
}
Jump branchTrue()
{
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t));
Jump m_jump = Jump(m_assembler.je());
- m_assembler.loadConstantUnReusable(0x0, scratchReg3);
- m_assembler.nop();
- m_assembler.nop();
+ m_assembler.extraInstrForBranch(scratchReg3);
return m_jump;
}
@@ -1150,9 +1253,7 @@ public:
{
m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t));
Jump m_jump = Jump(m_assembler.jne());
- m_assembler.loadConstantUnReusable(0x0, scratchReg3);
- m_assembler.nop();
- m_assembler.nop();
+ m_assembler.extraInstrForBranch(scratchReg3);
return m_jump;
}
@@ -1207,6 +1308,14 @@ public:
return jmp;
}
+ void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest)
+ {
+ RegisterID addressTempRegister = claimScratch();
+ load8(left, addressTempRegister);
+ compare32(cond, addressTempRegister, right, dest);
+ releaseScratch(addressTempRegister);
+ }
+
Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
{
m_assembler.ftrcdrmfpul(src);
@@ -1677,6 +1786,13 @@ public:
return branchSub32(cond, scratchReg3, dest);
}
+ Jump branchSub32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
+ {
+ if (src1 != dest)
+ move(src1, dest);
+ return branchSub32(cond, src2, dest);
+ }
+
Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -1738,6 +1854,14 @@ public:
releaseScratch(scr);
}
+ void urshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
+ {
+ if (src != dest)
+ move(src, dest);
+
+ urshift32(shiftamount, dest);
+ }
+
Call call()
{
return Call(m_assembler.call(), Call::Linkable);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index 8cb442cc5..e398dcdad 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -129,6 +129,11 @@ public:
{
m_assembler.addl_rm(src, dest.offset, dest.base);
}
+
+ void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
+ {
+ m_assembler.leal_mr(imm.m_value, src, dest);
+ }
void and32(RegisterID src, RegisterID dest)
{
@@ -1348,6 +1353,12 @@ public:
m_assembler.ret();
}
+ void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest)
+ {
+ m_assembler.cmpb_im(right.m_value, left.offset, left.base);
+ set32(x86Condition(cond), dest);
+ }
+
void compare32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
{
m_assembler.cmpl_rr(right, left);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
index a2b4311e5..41479f996 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -402,7 +402,7 @@ public:
m_assembler.testq_rr(reg, mask);
return Jump(m_assembler.jCC(x86Condition(cond)));
}
-
+
Jump branchTestPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
{
// if we are only interested in the low seven bits, this can be tested with a testb
@@ -415,6 +415,23 @@ public:
return Jump(m_assembler.jCC(x86Condition(cond)));
}
+ void testPtr(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest)
+ {
+ if (mask.m_value == -1)
+ m_assembler.testq_rr(reg, reg);
+ else if ((mask.m_value & ~0x7f) == 0)
+ m_assembler.testb_i8r(mask.m_value, reg);
+ else
+ m_assembler.testq_i32r(mask.m_value, reg);
+ set32(x86Condition(cond), dest);
+ }
+
+ void testPtr(ResultCondition cond, RegisterID reg, RegisterID mask, RegisterID dest)
+ {
+ m_assembler.testq_rr(reg, mask);
+ set32(x86Condition(cond), dest);
+ }
+
Jump branchTestPtr(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
{
loadPtr(address.m_ptr, scratchRegister);
diff --git a/Source/JavaScriptCore/assembler/RepatchBuffer.h b/Source/JavaScriptCore/assembler/RepatchBuffer.h
index e56185fdb..a87294b1b 100644
--- a/Source/JavaScriptCore/assembler/RepatchBuffer.h
+++ b/Source/JavaScriptCore/assembler/RepatchBuffer.h
@@ -26,7 +26,7 @@
#ifndef RepatchBuffer_h
#define RepatchBuffer_h
-#if ENABLE(ASSEMBLER)
+#if ENABLE(JIT)
#include "CodeBlock.h"
#include <MacroAssembler.h>
diff --git a/Source/JavaScriptCore/assembler/SH4Assembler.h b/Source/JavaScriptCore/assembler/SH4Assembler.h
index 1cf96b735..11e954cad 100644
--- a/Source/JavaScriptCore/assembler/SH4Assembler.h
+++ b/Source/JavaScriptCore/assembler/SH4Assembler.h
@@ -326,6 +326,10 @@ public:
padForAlign32 = 0x00090009,
};
+ enum JumpType { JumpFar,
+ JumpNear
+ };
+
SH4Assembler()
{
m_claimscratchReg = 0x0;
@@ -1188,6 +1192,13 @@ public:
return label;
}
+ void extraInstrForBranch(RegisterID dst)
+ {
+ loadConstantUnReusable(0x0, dst);
+ nop();
+ nop();
+ }
+
AssemblerLabel jmp(RegisterID dst)
{
jmpReg(dst);
@@ -1215,6 +1226,13 @@ public:
return label;
}
+ AssemblerLabel bra()
+ {
+ AssemblerLabel label = m_buffer.label();
+ branch(BRA_OPCODE, 0);
+ return label;
+ }
+
void ret()
{
m_buffer.ensureSpace(maxInstructionSize + 2);
@@ -1424,7 +1442,7 @@ public:
// Linking & patching
- void linkJump(AssemblerLabel from, AssemblerLabel to)
+ void linkJump(AssemblerLabel from, AssemblerLabel to, JumpType type = JumpFar)
{
ASSERT(to.isSet());
ASSERT(from.isSet());
@@ -1433,6 +1451,14 @@ public:
uint16_t instruction = *instructionPtr;
int offsetBits;
+ if (type == JumpNear) {
+ ASSERT((instruction == BT_OPCODE) || (instruction == BF_OPCODE) || (instruction == BRA_OPCODE));
+ int offset = (codeSize() - from.m_offset) - 4;
+ *instructionPtr++ = instruction | (offset >> 1);
+ printInstr(*instructionPtr, from.m_offset + 2);
+ return;
+ }
+
if (((instruction & 0xff00) == BT_OPCODE) || ((instruction & 0xff00) == BF_OPCODE)) {
/* BT label => BF 2
nop LDR reg