summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/assembler
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/assembler')
-rw-r--r--Source/JavaScriptCore/assembler/MIPSAssembler.h25
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h12
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerSH4.h202
-rw-r--r--Source/JavaScriptCore/assembler/SH4Assembler.h46
4 files changed, 266 insertions, 19 deletions
diff --git a/Source/JavaScriptCore/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h
index 30f172fb8..026f87e52 100644
--- a/Source/JavaScriptCore/assembler/MIPSAssembler.h
+++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h
@@ -825,6 +825,31 @@ public:
#endif
}
+ static void revertJumpToMove(void* instructionStart, RegisterID rt, int imm)
+ {
+ MIPSWord* insn = static_cast<MIPSWord*>(instructionStart) + 1;
+ ASSERT((*insn & 0xfc000000) == 0x34000000);
+ *insn = (*insn & 0xfc1f0000) | (imm & 0xffff);
+ cacheFlush(insn, sizeof(MIPSWord));
+ }
+
+ static void replaceWithJump(void* instructionStart, void* to)
+ {
+ MIPSWord* instruction = reinterpret_cast<MIPSWord*>(instructionStart);
+ intptr_t jumpTo = reinterpret_cast<intptr_t>(to);
+
+ // lui
+ instruction[0] = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((jumpTo >> 16) & 0xffff);
+ // ori
+ instruction[1] = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (jumpTo & 0xffff);
+ // jr
+ instruction[2] = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
+ // nop
+ instruction[3] = 0x0;
+
+ cacheFlush(instruction, sizeof(MIPSWord) * 4);
+ }
+
static void replaceWithLoad(void* instructionStart)
{
MIPSWord* insn = reinterpret_cast<MIPSWord*>(instructionStart);
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index 5b6da9663..4f81b4599 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -2244,7 +2244,17 @@ public:
static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; }
- static CodeLocationLabel startOfPatchableBranchPtrWithPatch(CodeLocationDataLabelPtr label)
+ static CodeLocationLabel startOfBranchPtrWithPatchOnRegister(CodeLocationDataLabelPtr label)
+ {
+ return label.labelAtOffset(0);
+ }
+
+ static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID, void* initialValue)
+ {
+ MIPSAssembler::revertJumpToMove(instructionStart.dataLocation(), immTempRegister, reinterpret_cast<int>(initialValue) & 0xffff);
+ }
+
+ static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr)
{
UNREACHABLE_FOR_PLATFORM();
return CodeLocationLabel();
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
index ca410afa8..b6f3e6d57 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
@@ -602,6 +602,16 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(scr);
}
+ void load8Signed(BaseIndex address, RegisterID dest)
+ {
+ RegisterID scr = claimScratch();
+ move(address.index, scr);
+ lshift32(TrustedImm32(address.scale), scr);
+ add32(address.base, scr);
+ load8Signed(scr, address.offset, dest);
+ releaseScratch(scr);
+ }
+
void load32(BaseIndex address, RegisterID dest)
{
RegisterID scr = claimScratch();
@@ -649,6 +659,32 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(scr);
}
+ void load8Signed(RegisterID base, int offset, RegisterID dest)
+ {
+ if (!offset) {
+ m_assembler.movbMemReg(base, dest);
+ return;
+ }
+
+ if ((offset > 0) && (offset < 64) && (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 = claimScratch();
+ m_assembler.loadConstant((offset), scr);
+ m_assembler.addlRegReg(base, scr);
+ m_assembler.movbMemReg(scr, dest);
+ releaseScratch(scr);
+ }
+
void load8(RegisterID base, int offset, RegisterID dest)
{
if (!offset) {
@@ -749,6 +785,11 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
extuw(dest, dest);
}
+ void load16Signed(RegisterID src, RegisterID dest)
+ {
+ m_assembler.movwMemReg(src, dest);
+ }
+
void load16(RegisterID r0, RegisterID src, RegisterID dest)
{
ASSERT(r0 == SH4Registers::r0);
@@ -756,6 +797,12 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
extuw(dest, dest);
}
+ void load16Signed(RegisterID r0, RegisterID src, RegisterID dest)
+ {
+ ASSERT(r0 == SH4Registers::r0);
+ m_assembler.movwR0mr(src, dest);
+ }
+
void load16(BaseIndex address, RegisterID dest)
{
RegisterID scr = claimScratch();
@@ -775,6 +822,51 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(scr);
}
+ void load16Signed(BaseIndex address, RegisterID dest)
+ {
+ RegisterID scr = claimScratch();
+
+ move(address.index, scr);
+ lshift32(TrustedImm32(address.scale), scr);
+
+ if (address.offset)
+ add32(TrustedImm32(address.offset), scr);
+ if (address.base == SH4Registers::r0)
+ load16Signed(address.base, scr, dest);
+ else {
+ add32(address.base, scr);
+ load16Signed(scr, dest);
+ }
+
+ releaseScratch(scr);
+ }
+
+ void store8(RegisterID src, BaseIndex address)
+ {
+ RegisterID scr = claimScratch();
+
+ move(address.index, scr);
+ lshift32(TrustedImm32(address.scale), scr);
+ add32(address.base, scr);
+
+ m_assembler.movbRegMem(src, scr);
+
+ releaseScratch(scr);
+ }
+
+ void store16(RegisterID src, BaseIndex address)
+ {
+ RegisterID scr = claimScratch();
+
+ move(address.index, scr);
+ lshift32(TrustedImm32(address.scale), scr);
+ add32(address.base, scr);
+
+ m_assembler.movwRegMem(src, scr);
+
+ releaseScratch(scr);
+ }
+
void store32(RegisterID src, ImplicitAddress address)
{
RegisterID scr = claimScratch();
@@ -900,13 +992,59 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
return result;
}
- // Floating-point operations
+ // Floating-point operations
static bool supportsFloatingPoint() { return true; }
static bool supportsFloatingPointTruncate() { return true; }
static bool supportsFloatingPointSqrt() { return true; }
static bool supportsFloatingPointAbs() { return false; }
+ void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
+ {
+ m_assembler.fldsfpul((FPRegisterID)(src + 1));
+ m_assembler.stsfpulReg(dest1);
+ m_assembler.fldsfpul(src);
+ m_assembler.stsfpulReg(dest2);
+ }
+
+ void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch)
+ {
+ UNUSED_PARAM(scratch);
+ m_assembler.ldsrmfpul(src1);
+ m_assembler.fstsfpul((FPRegisterID)(dest + 1));
+ m_assembler.ldsrmfpul(src2);
+ m_assembler.fstsfpul(dest);
+ }
+
+ 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);
+
+ m_assembler.fmovsReadrm(scr, dest);
+ releaseScratch(scr);
+ }
+
+ void loadDouble(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);
+
+ m_assembler.fmovsReadrminc(scr, (FPRegisterID)(dest + 1));
+ m_assembler.fmovsReadrm(scr, dest);
+ releaseScratch(scr);
+ }
+
void loadDouble(ImplicitAddress address, FPRegisterID dest)
{
RegisterID scr = claimScratch();
@@ -935,6 +1073,21 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(scr);
}
+ 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);
+
+ m_assembler.fmovsWriterm(src, scr);
+
+ releaseScratch(scr);
+ }
+
void storeDouble(FPRegisterID src, ImplicitAddress address)
{
RegisterID scr = claimScratch();
@@ -946,11 +1099,44 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
releaseScratch(scr);
}
+ void storeDouble(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);
+
+ m_assembler.fmovsWriterm((FPRegisterID)(src + 1), scr);
+ m_assembler.addlImm8r(4, scr);
+ m_assembler.fmovsWriterm(src, scr);
+
+ releaseScratch(scr);
+ }
+
+ void addDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
+ {
+ if (op1 == dest)
+ m_assembler.daddRegReg(op2, dest);
+ else {
+ m_assembler.dmovRegReg(op1, dest);
+ m_assembler.daddRegReg(op2, dest);
+ }
+ }
+
void addDouble(FPRegisterID src, FPRegisterID dest)
{
m_assembler.daddRegReg(src, dest);
}
+ void addDouble(AbsoluteAddress address, FPRegisterID dest)
+ {
+ loadDouble(address.m_ptr, fscratch);
+ addDouble(fscratch, dest);
+ }
+
void addDouble(Address address, FPRegisterID dest)
{
loadDouble(address, fscratch);
@@ -984,6 +1170,18 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
m_assembler.ddivRegReg(src, dest);
}
+ void convertFloatToDouble(FPRegisterID src, FPRegisterID dst)
+ {
+ m_assembler.fldsfpul(src);
+ m_assembler.dcnvsd(dst);
+ }
+
+ void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst)
+ {
+ m_assembler.dcnvds(src);
+ m_assembler.fstsfpul(dst);
+ }
+
void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
{
m_assembler.ldsrmfpul(src);
@@ -1893,7 +2091,7 @@ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
void urshift32(RegisterID src, TrustedImm32 shiftamount, RegisterID dest)
{
if (src != dest)
- move(src, dest);
+ move(src, dest);
urshift32(shiftamount, dest);
}
diff --git a/Source/JavaScriptCore/assembler/SH4Assembler.h b/Source/JavaScriptCore/assembler/SH4Assembler.h
index 3dbde2fa5..2cd0aa82e 100644
--- a/Source/JavaScriptCore/assembler/SH4Assembler.h
+++ b/Source/JavaScriptCore/assembler/SH4Assembler.h
@@ -166,6 +166,7 @@ enum {
FMOVS_WRITE_RN_DEC_OPCODE = 0xf00b,
FMOVS_WRITE_R0RN_OPCODE = 0xf007,
FCNVDS_DRM_FPUL_OPCODE = 0xf0bd,
+ FCNVSD_FPUL_DRN_OPCODE = 0xf0ad,
LDS_RM_FPUL_OPCODE = 0x405a,
FLDS_FRM_FPUL_OPCODE = 0xf01d,
STS_FPUL_RN_OPCODE = 0x005a,
@@ -326,8 +327,9 @@ public:
padForAlign32 = 0x00090009,
};
- enum JumpType { JumpFar,
- JumpNear
+ enum JumpType {
+ JumpFar,
+ JumpNear
};
SH4Assembler()
@@ -491,14 +493,14 @@ public:
void sublRegReg(RegisterID src, RegisterID dst)
{
- uint16_t opc = getOpcodeGroup1(SUB_OPCODE, dst, src);
- oneShortOp(opc);
+ uint16_t opc = getOpcodeGroup1(SUB_OPCODE, dst, src);
+ oneShortOp(opc);
}
void subvlRegReg(RegisterID src, RegisterID dst)
{
- uint16_t opc = getOpcodeGroup1(SUBV_OPCODE, dst, src);
- oneShortOp(opc);
+ uint16_t opc = getOpcodeGroup1(SUBV_OPCODE, dst, src);
+ oneShortOp(opc);
}
void xorlRegReg(RegisterID src, RegisterID dst)
@@ -803,7 +805,7 @@ public:
oneShortOp(opc);
}
- void floatfpulfrn(RegisterID src)
+ void floatfpulfrn(FPRegisterID src)
{
uint16_t opc = getOpcodeGroup2(FLOAT_OPCODE, src);
oneShortOp(opc, true, false);
@@ -857,13 +859,13 @@ public:
oneShortOp(opc, true, false);
}
- void fldsfpul(RegisterID src)
+ void fldsfpul(FPRegisterID src)
{
uint16_t opc = getOpcodeGroup2(FLDS_FRM_FPUL_OPCODE, src);
oneShortOp(opc);
}
- void fstsfpul(RegisterID src)
+ void fstsfpul(FPRegisterID src)
{
uint16_t opc = getOpcodeGroup2(FSTS_FPUL_FRN_OPCODE, src);
oneShortOp(opc);
@@ -889,6 +891,12 @@ public:
oneShortOp(opc);
}
+ void dcnvsd(FPRegisterID dst)
+ {
+ uint16_t opc = getOpcodeGroup7(FCNVSD_FPUL_DRN_OPCODE, dst >> 1);
+ oneShortOp(opc);
+ }
+
void dcmppeq(FPRegisterID src, FPRegisterID dst)
{
uint16_t opc = getOpcodeGroup8(FCMPEQ_OPCODE, dst >> 1, src >> 1);
@@ -1082,6 +1090,12 @@ public:
oneShortOp(getOpcodeGroup4(MOVL_READ_OFFRM_OPCODE, dst, base, offset));
}
+ void movbRegMem(RegisterID src, RegisterID base)
+ {
+ uint16_t opc = getOpcodeGroup1(MOVB_WRITE_RN_OPCODE, base, src);
+ oneShortOp(opc);
+ }
+
void movbMemReg(int offset, RegisterID base, RegisterID dst)
{
ASSERT(dst == SH4Registers::r0);
@@ -1253,7 +1267,7 @@ public:
int sizeOfConstantPool()
{
- return m_buffer.sizeOfConstantPool();
+ return m_buffer.sizeOfConstantPool();
}
AssemblerLabel align(int alignment)
@@ -1305,7 +1319,7 @@ public:
*instructionPtr = instruction;
printBlockInstr(instructionPtr - 2, from.m_offset, 3);
return;
- }
+ }
/* MOV #imm, reg => LDR reg
braf @reg braf @reg
@@ -1592,7 +1606,7 @@ public:
size_t codeSize() const { return m_buffer.codeSize(); }
#ifdef SH4_ASSEMBLER_TRACING
- static void printInstr(uint16_t opc, unsigned int size, bool isdoubleInst = true)
+ static void printInstr(uint16_t opc, unsigned size, bool isdoubleInst = true)
{
if (!getenv("JavaScriptCoreDumpJIT"))
return;
@@ -2073,16 +2087,16 @@ public:
WTF::dataLogFV(format, args);
}
- static void printBlockInstr(uint16_t* first, unsigned int offset, int nbInstr)
+ static void printBlockInstr(uint16_t* first, unsigned offset, int nbInstr)
{
printfStdoutInstr(">> repatch instructions after link\n");
for (int i = 0; i <= nbInstr; i++)
- printInstr(*(first + i), offset + i);
+ printInstr(*(first + i), offset + i);
printfStdoutInstr(">> end repatch\n");
}
#else
- static void printInstr(uint16_t opc, unsigned int size, bool isdoubleInst = true) {};
- static void printBlockInstr(uint16_t* first, unsigned int offset, int nbInstr) {};
+ static void printInstr(uint16_t opc, unsigned size, bool isdoubleInst = true) { };
+ static void printBlockInstr(uint16_t* first, unsigned offset, int nbInstr) { };
#endif
static void replaceWithLoad(void* instructionStart)