X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/f9bf01c6616d5ddcf65b13b33cedf9e387ff7a63..8b637bb680022adfddad653280734877951535a9:/assembler/MacroAssemblerX86.h?ds=inline diff --git a/assembler/MacroAssemblerX86.h b/assembler/MacroAssemblerX86.h index ca7c31a..27a030e 100644 --- a/assembler/MacroAssemblerX86.h +++ b/assembler/MacroAssemblerX86.h @@ -26,8 +26,6 @@ #ifndef MacroAssemblerX86_h #define MacroAssemblerX86_h -#include - #if ENABLE(ASSEMBLER) && CPU(X86) #include "MacroAssemblerX86Common.h" @@ -36,63 +34,88 @@ namespace JSC { class MacroAssemblerX86 : public MacroAssemblerX86Common { public: - MacroAssemblerX86() - : m_isSSE2Present(isSSE2Present()) - { - } - static const Scale ScalePtr = TimesFour; using MacroAssemblerX86Common::add32; using MacroAssemblerX86Common::and32; + using MacroAssemblerX86Common::branchAdd32; + using MacroAssemblerX86Common::branchSub32; using MacroAssemblerX86Common::sub32; using MacroAssemblerX86Common::or32; using MacroAssemblerX86Common::load32; using MacroAssemblerX86Common::store32; + using MacroAssemblerX86Common::store8; using MacroAssemblerX86Common::branch32; using MacroAssemblerX86Common::call; + using MacroAssemblerX86Common::jump; + using MacroAssemblerX86Common::addDouble; using MacroAssemblerX86Common::loadDouble; + using MacroAssemblerX86Common::storeDouble; using MacroAssemblerX86Common::convertInt32ToDouble; + using MacroAssemblerX86Common::branchTest8; - void add32(Imm32 imm, RegisterID src, RegisterID dest) + void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) { m_assembler.leal_mr(imm.m_value, src, dest); } - void add32(Imm32 imm, AbsoluteAddress address) + void add32(TrustedImm32 imm, AbsoluteAddress address) { m_assembler.addl_im(imm.m_value, address.m_ptr); } - void addWithCarry32(Imm32 imm, AbsoluteAddress address) + void add32(AbsoluteAddress address, RegisterID dest) { - m_assembler.adcl_im(imm.m_value, address.m_ptr); + m_assembler.addl_mr(address.m_ptr, dest); } - void and32(Imm32 imm, AbsoluteAddress address) + void add64(TrustedImm32 imm, AbsoluteAddress address) + { + m_assembler.addl_im(imm.m_value, address.m_ptr); + m_assembler.adcl_im(imm.m_value >> 31, reinterpret_cast(address.m_ptr) + sizeof(int32_t)); + } + + void and32(TrustedImm32 imm, AbsoluteAddress address) { m_assembler.andl_im(imm.m_value, address.m_ptr); } - void or32(Imm32 imm, AbsoluteAddress address) + void or32(TrustedImm32 imm, AbsoluteAddress address) { m_assembler.orl_im(imm.m_value, address.m_ptr); } - - void sub32(Imm32 imm, AbsoluteAddress address) + + void or32(RegisterID reg, AbsoluteAddress address) + { + m_assembler.orl_rm(reg, address.m_ptr); + } + + void sub32(TrustedImm32 imm, AbsoluteAddress address) { m_assembler.subl_im(imm.m_value, address.m_ptr); } - void load32(void* address, RegisterID dest) + void load32(const void* address, RegisterID dest) { m_assembler.movl_mr(address, dest); } - void loadDouble(void* address, FPRegisterID dest) + ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest) + { + ConvertibleLoadLabel result = ConvertibleLoadLabel(this); + m_assembler.movl_mr(address.offset, address.base, dest); + return result; + } + + void addDouble(AbsoluteAddress address, FPRegisterID dest) + { + m_assembler.addsd_mr(address.m_ptr, dest); + } + + void storeDouble(FPRegisterID src, const void* address) { ASSERT(isSSE2Present()); - m_assembler.movsd_mr(address, dest); + m_assembler.movsd_rm(src, address); } void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest) @@ -100,7 +123,7 @@ public: m_assembler.cvtsi2sd_mr(src.m_ptr, dest); } - void store32(Imm32 imm, void* address) + void store32(TrustedImm32 imm, void* address) { m_assembler.movl_i32m(imm.m_value, address); } @@ -110,13 +133,47 @@ public: m_assembler.movl_rm(src, address); } - Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right) + void store8(TrustedImm32 imm, void* address) + { + ASSERT(-128 <= imm.m_value && imm.m_value < 128); + m_assembler.movb_i8m(imm.m_value, address); + } + + // Possibly clobbers src. + void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) + { + movePackedToInt32(src, dest1); + rshiftPacked(TrustedImm32(32), src); + movePackedToInt32(src, dest2); + } + + void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID scratch) + { + moveInt32ToPacked(src1, dest); + moveInt32ToPacked(src2, scratch); + lshiftPacked(TrustedImm32(32), scratch); + orPacked(scratch, dest); + } + + Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) + { + m_assembler.addl_im(imm.m_value, dest.m_ptr); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branchSub32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) + { + m_assembler.subl_im(imm.m_value, dest.m_ptr); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + Jump branch32(RelationalCondition cond, AbsoluteAddress left, RegisterID right) { m_assembler.cmpl_rm(right, left.m_ptr); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right) + Jump branch32(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right) { m_assembler.cmpl_im(right.m_value, left.m_ptr); return Jump(m_assembler.jCC(x86Condition(cond))); @@ -127,6 +184,12 @@ public: return Call(m_assembler.call(), Call::Linkable); } + // Address is a memory location containing the address to jump to + void jump(AbsoluteAddress address) + { + m_assembler.jmp_m(address.m_ptr); + } + Call tailRecursiveCall() { return Call::fromTailJump(jump()); @@ -138,52 +201,99 @@ public: } - DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest) + DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest) { + padBeforePatch(); m_assembler.movl_i32r(initialValue.asIntptr(), dest); return DataLabelPtr(this); } + + Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) + { + ASSERT(mask.m_value >= -128 && mask.m_value <= 255); + if (mask.m_value == -1) + m_assembler.cmpb_im(0, address.m_ptr); + else + m_assembler.testb_im(mask.m_value, address.m_ptr); + return Jump(m_assembler.jCC(x86Condition(cond))); + } - Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) + Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { + padBeforePatch(); m_assembler.cmpl_ir_force32(initialRightValue.asIntptr(), left); dataLabel = DataLabelPtr(this); return Jump(m_assembler.jCC(x86Condition(cond))); } - Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0)) + Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { + padBeforePatch(); m_assembler.cmpl_im_force32(initialRightValue.asIntptr(), left.offset, left.base); dataLabel = DataLabelPtr(this); return Jump(m_assembler.jCC(x86Condition(cond))); } - DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address) + DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) { + padBeforePatch(); m_assembler.movl_i32m(initialValue.asIntptr(), address.offset, address.base); return DataLabelPtr(this); } - Label loadPtrWithPatchToLEA(Address address, RegisterID dest) + static bool supportsFloatingPoint() { return isSSE2Present(); } + // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate() + static bool supportsFloatingPointTruncate() { return isSSE2Present(); } + static bool supportsFloatingPointSqrt() { return isSSE2Present(); } + static bool supportsFloatingPointAbs() { return isSSE2Present(); } + + static FunctionPtr readCallTarget(CodeLocationCall call) { - Label label(this); - load32(address, dest); - return label; + intptr_t offset = reinterpret_cast(call.dataLocation())[-1]; + return FunctionPtr(reinterpret_cast(reinterpret_cast(call.dataLocation()) + offset)); } - bool supportsFloatingPoint() const { return m_isSSE2Present; } - // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate() - bool supportsFloatingPointTruncate() const { return m_isSSE2Present; } + static bool canJumpReplacePatchableBranchPtrWithPatch() { return true; } + + static CodeLocationLabel startOfBranchPtrWithPatchOnRegister(CodeLocationDataLabelPtr label) + { + const int opcodeBytes = 1; + const int modRMBytes = 1; + const int immediateBytes = 4; + const int totalBytes = opcodeBytes + modRMBytes + immediateBytes; + ASSERT(totalBytes >= maxJumpReplacementSize()); + return label.labelAtOffset(-totalBytes); + } + + static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr label) + { + const int opcodeBytes = 1; + const int modRMBytes = 1; + const int offsetBytes = 0; + const int immediateBytes = 4; + const int totalBytes = opcodeBytes + modRMBytes + offsetBytes + immediateBytes; + ASSERT(totalBytes >= maxJumpReplacementSize()); + return label.labelAtOffset(-totalBytes); + } + + static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID reg, void* initialValue) + { + X86Assembler::revertJumpTo_cmpl_ir_force32(instructionStart.executableAddress(), reinterpret_cast(initialValue), reg); + } -private: - const bool m_isSSE2Present; + static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel instructionStart, Address address, void* initialValue) + { + ASSERT(!address.offset); + X86Assembler::revertJumpTo_cmpl_im_force32(instructionStart.executableAddress(), reinterpret_cast(initialValue), 0, address.base); + } +private: friend class LinkBuffer; friend class RepatchBuffer; static void linkCall(void* code, Call call, FunctionPtr function) { - X86Assembler::linkCall(code, call.m_jmp, function.value()); + X86Assembler::linkCall(code, call.m_label, function.value()); } static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)