X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/93a3786624b2768d89bfa27e46598dc64e2fb70a..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/assembler/MacroAssemblerARM.h?ds=sidebyside diff --git a/assembler/MacroAssemblerARM.h b/assembler/MacroAssemblerARM.h index 494fe64..6cda896 100644 --- a/assembler/MacroAssemblerARM.h +++ b/assembler/MacroAssemblerARM.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. + * Copyright (C) 2008, 2013, 2014 Apple Inc. * Copyright (C) 2009, 2010 University of Szeged * All rights reserved. * @@ -35,7 +35,7 @@ namespace JSC { -class MacroAssemblerARM : public AbstractMacroAssembler { +class MacroAssemblerARM : public AbstractMacroAssembler { static const int DoubleConditionMask = 0x0f; static const int DoubleConditionBitSpecial = 0x10; COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes); @@ -81,6 +81,7 @@ public: }; static const RegisterID stackPointerRegister = ARMRegisters::sp; + static const RegisterID framePointerRegister = ARMRegisters::fp; static const RegisterID linkRegister = ARMRegisters::lr; static const Scale ScalePtr = TimesFour; @@ -363,7 +364,13 @@ public: m_assembler.baseIndexTransfer32(ARMAssembler::LoadUint8, dest, address.base, address.index, static_cast(address.scale), address.offset); } - void load8Signed(BaseIndex address, RegisterID dest) + void load8(const void* address, RegisterID dest) + { + move(TrustedImmPtr(address), ARMRegisters::S0); + m_assembler.dataTransfer32(ARMAssembler::LoadUint8, dest, ARMRegisters::S0, 0); + } + + void load8SignedExtendTo32(BaseIndex address, RegisterID dest) { m_assembler.baseIndexTransfer16(ARMAssembler::LoadInt8, dest, address.base, address.index, static_cast(address.scale), address.offset); } @@ -378,7 +385,7 @@ public: m_assembler.baseIndexTransfer16(ARMAssembler::LoadUint16, dest, address.base, address.index, static_cast(address.scale), address.offset); } - void load16Signed(BaseIndex address, RegisterID dest) + void load16SignedExtendTo32(BaseIndex address, RegisterID dest) { m_assembler.baseIndexTransfer16(ARMAssembler::LoadInt16, dest, address.base, address.index, static_cast(address.scale), address.offset); } @@ -407,6 +414,18 @@ public: load16(address, dest); } + void abortWithReason(AbortReason reason) + { + move(TrustedImm32(reason), ARMRegisters::S0); + breakpoint(); + } + + void abortWithReason(AbortReason reason, intptr_t misc) + { + move(TrustedImm32(misc), ARMRegisters::S1); + abortWithReason(reason); + } + ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest) { ConvertibleLoadLabel result(this); @@ -452,6 +471,23 @@ public: m_assembler.baseIndexTransfer32(ARMAssembler::StoreUint8, src, address.base, address.index, static_cast(address.scale), address.offset); } + void store8(RegisterID src, ImplicitAddress address) + { + m_assembler.dtrUp(ARMAssembler::StoreUint8, src, address.base, address.offset); + } + + void store8(RegisterID src, const void* address) + { + move(TrustedImmPtr(address), ARMRegisters::S0); + m_assembler.dtrUp(ARMAssembler::StoreUint8, src, ARMRegisters::S0, 0); + } + + void store8(TrustedImm32 imm, ImplicitAddress address) + { + move(imm, ARMRegisters::S1); + store8(ARMRegisters::S1, address); + } + void store8(TrustedImm32 imm, const void* address) { move(TrustedImm32(reinterpret_cast(address)), ARMRegisters::S0); @@ -504,6 +540,12 @@ public: m_assembler.pop(dest); } + void popPair(RegisterID dest1, RegisterID dest2) + { + m_assembler.pop(dest1); + m_assembler.pop(dest2); + } + void push(RegisterID src) { m_assembler.push(src); @@ -521,6 +563,12 @@ public: push(ARMRegisters::S0); } + void pushPair(RegisterID src1, RegisterID src2) + { + m_assembler.push(src2); + m_assembler.push(src1); + } + void move(TrustedImm32 imm, RegisterID dest) { m_assembler.moveImm(imm.m_value, dest); @@ -569,6 +617,13 @@ public: return branch32(cond, ARMRegisters::S1, right); } + Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right) + { + move(TrustedImmPtr(left.m_ptr), ARMRegisters::S1); + load8(Address(ARMRegisters::S1), ARMRegisters::S1); + return branch32(cond, ARMRegisters::S1, right); + } + Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right, int useConstantPool = 0) { m_assembler.cmp(left, right); @@ -617,6 +672,12 @@ public: return branchTest32(cond, ARMRegisters::S1, mask); } + Jump branchTest8(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1)) + { + load8(address, ARMRegisters::S1); + return branchTest32(cond, ARMRegisters::S1, mask); + } + Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) { move(TrustedImmPtr(address.m_ptr), ARMRegisters::S1); @@ -725,6 +786,11 @@ public: return Jump(m_assembler.jmp(ARMCondition(cond))); } + Jump branchAdd32(ResultCondition cond, Address src, RegisterID dest) + { + load32(src, ARMRegisters::S0); + return branchAdd32(cond, dest, ARMRegisters::S0, dest); + } void mull32(RegisterID op1, RegisterID op2, RegisterID dest) { if (op2 == dest) { @@ -814,6 +880,11 @@ public: return Jump(m_assembler.jmp(ARMCondition(cond))); } + PatchableJump patchableJump() + { + return PatchableJump(m_assembler.jmp(ARMAssembler::AL, 1)); + } + PatchableJump patchableBranch32(RelationalCondition cond, RegisterID reg, TrustedImm32 imm) { internalCompare32(reg, imm); @@ -871,7 +942,7 @@ public: void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest) { if (mask.m_value == -1) - m_assembler.cmp(0, reg); + m_assembler.tst(reg, reg); else m_assembler.tst(reg, m_assembler.getImm(mask.m_value, ARMRegisters::S0)); m_assembler.mov(dest, ARMAssembler::getOp2Byte(0)); @@ -985,6 +1056,13 @@ public: return dataLabel; } + DataLabel32 moveWithPatch(TrustedImm32 initialValue, RegisterID dest) + { + DataLabel32 dataLabel(this); + m_assembler.ldrUniqueImmediate(dest, static_cast(initialValue.m_value)); + return dataLabel; + } + Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { ensureSpace(3 * sizeof(ARMWord), 2 * sizeof(ARMWord)); @@ -1002,6 +1080,15 @@ public: return jump; } + Jump branch32WithPatch(RelationalCondition cond, Address left, DataLabel32& dataLabel, TrustedImm32 initialRightValue = TrustedImm32(0)) + { + load32(left, ARMRegisters::S1); + ensureSpace(3 * sizeof(ARMWord), 2 * sizeof(ARMWord)); + dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S0); + Jump jump = branch32(cond, ARMRegisters::S0, ARMRegisters::S1, true); + return jump; + } + DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) { DataLabelPtr dataLabel = moveWithPatch(initialValue, ARMRegisters::S1); @@ -1046,9 +1133,9 @@ public: m_assembler.baseIndexTransferFloat(ARMAssembler::LoadDouble, dest, address.base, address.index, static_cast(address.scale), address.offset); } - void loadDouble(const void* address, FPRegisterID dest) + void loadDouble(TrustedImmPtr address, FPRegisterID dest) { - move(TrustedImm32(reinterpret_cast(address)), ARMRegisters::S0); + move(TrustedImm32(reinterpret_cast(address.m_value)), ARMRegisters::S0); m_assembler.doubleDtrUp(ARMAssembler::LoadDouble, dest, ARMRegisters::S0, 0); } @@ -1067,9 +1154,9 @@ public: m_assembler.baseIndexTransferFloat(ARMAssembler::StoreDouble, src, address.base, address.index, static_cast(address.scale), address.offset); } - void storeDouble(FPRegisterID src, const void* address) + void storeDouble(FPRegisterID src, TrustedImmPtr address) { - move(TrustedImm32(reinterpret_cast(address)), ARMRegisters::S0); + move(TrustedImm32(reinterpret_cast(address.m_value)), ARMRegisters::S0); m_assembler.dataTransferFloat(ARMAssembler::StoreDouble, src, ARMRegisters::S0, 0); } @@ -1097,7 +1184,7 @@ public: void addDouble(AbsoluteAddress address, FPRegisterID dest) { - loadDouble(address.m_ptr, ARMRegisters::SD0); + loadDouble(TrustedImmPtr(address.m_ptr), ARMRegisters::SD0); addDouble(ARMRegisters::SD0, dest); } @@ -1289,6 +1376,11 @@ public: m_assembler.nop(); } + void memoryFence() + { + m_assembler.dmbSY(); + } + static FunctionPtr readCallTarget(CodeLocationCall call) { return FunctionPtr(reinterpret_cast(ARMAssembler::readCallTarget(call.dataLocation()))); @@ -1306,6 +1398,13 @@ public: } static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; } + static bool canJumpReplacePatchableBranch32WithPatch() { return false; } + + static CodeLocationLabel startOfPatchableBranch32WithPatchOnAddress(CodeLocationDataLabel32) + { + UNREACHABLE_FOR_PLATFORM(); + return CodeLocationLabel(); + } static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr) { @@ -1323,11 +1422,25 @@ public: ARMAssembler::revertBranchPtrWithPatch(instructionStart.dataLocation(), reg, reinterpret_cast(initialValue) & 0xffff); } + static void revertJumpReplacementToPatchableBranch32WithPatch(CodeLocationLabel, Address, int32_t) + { + UNREACHABLE_FOR_PLATFORM(); + } + static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel, Address, void*) { UNREACHABLE_FOR_PLATFORM(); } +#if ENABLE(MASM_PROBE) + // Methods required by the MASM_PROBE mechanism as defined in + // AbstractMacroAssembler.h. + static void printCPURegisters(CPUState&, int indentation = 0); + static void printRegister(CPUState&, RegisterID); + static void printRegister(CPUState&, FPRegisterID); + void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); +#endif // ENABLE(MASM_PROBE) + protected: ARMAssembler::Condition ARMCondition(RelationalCondition cond) { @@ -1383,6 +1496,23 @@ private: ARMAssembler::relinkCall(call.dataLocation(), destination.executableAddress()); } +#if ENABLE(MASM_PROBE) + inline TrustedImm32 trustedImm32FromPtr(void* ptr) + { + return TrustedImm32(TrustedImmPtr(ptr)); + } + + inline TrustedImm32 trustedImm32FromPtr(ProbeFunction function) + { + return TrustedImm32(TrustedImmPtr(reinterpret_cast(function))); + } + + inline TrustedImm32 trustedImm32FromPtr(void (*function)()) + { + return TrustedImm32(TrustedImmPtr(reinterpret_cast(function))); + } +#endif + static const bool s_isVFPPresent; };