X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174..ed1e77d3adeb83d26fd1dfb16dd84cabdcefd250:/assembler/MacroAssemblerX86.h diff --git a/assembler/MacroAssemblerX86.h b/assembler/MacroAssemblerX86.h index 088fe19..bdd9e57 100644 --- a/assembler/MacroAssemblerX86.h +++ b/assembler/MacroAssemblerX86.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -43,7 +43,9 @@ public: using MacroAssemblerX86Common::sub32; using MacroAssemblerX86Common::or32; using MacroAssemblerX86Common::load32; + using MacroAssemblerX86Common::load8; using MacroAssemblerX86Common::store32; + using MacroAssemblerX86Common::store8; using MacroAssemblerX86Common::branch32; using MacroAssemblerX86Common::call; using MacroAssemblerX86Common::jump; @@ -51,6 +53,8 @@ public: using MacroAssemblerX86Common::loadDouble; using MacroAssemblerX86Common::storeDouble; using MacroAssemblerX86Common::convertInt32ToDouble; + using MacroAssemblerX86Common::branch8; + using MacroAssemblerX86Common::branchTest8; void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) { @@ -62,6 +66,11 @@ public: m_assembler.addl_im(imm.m_value, address.m_ptr); } + void add32(AbsoluteAddress address, RegisterID dest) + { + m_assembler.addl_mr(address.m_ptr, dest); + } + void add64(TrustedImm32 imm, AbsoluteAddress address) { m_assembler.addl_im(imm.m_value, address.m_ptr); @@ -77,7 +86,12 @@ public: { m_assembler.orl_im(imm.m_value, address.m_ptr); } - + + 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); @@ -87,16 +101,41 @@ public: { m_assembler.movl_mr(address, dest); } + + void load8(const void* address, RegisterID dest) + { + m_assembler.movzbl_mr(address, dest); + } + + void abortWithReason(AbortReason reason) + { + move(TrustedImm32(reason), X86Registers::eax); + breakpoint(); + } + + void abortWithReason(AbortReason reason, intptr_t misc) + { + move(TrustedImm32(misc), X86Registers::edx); + abortWithReason(reason); + } + + 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) + void storeDouble(FPRegisterID src, TrustedImmPtr address) { ASSERT(isSSE2Present()); - m_assembler.movsd_rm(src, address); + ASSERT(address.m_value); + m_assembler.movsd_rm(src, address.m_value); } void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest) @@ -113,6 +152,35 @@ public: { m_assembler.movl_rm(src, address); } + + void store8(RegisterID src, void* address) + { + m_assembler.movb_rm(src, address); + } + + void store8(TrustedImm32 imm, void* address) + { + ASSERT(-128 <= imm.m_value && imm.m_value < 128); + m_assembler.movb_i8m(imm.m_value, address); + } + + void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2) + { + ASSERT(isSSE2Present()); + m_assembler.pextrw_irr(3, src, dest1); + m_assembler.pextrw_irr(2, src, dest2); + lshift32(TrustedImm32(16), dest1); + or32(dest1, dest2); + movePackedToInt32(src, dest1); + } + + 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) { @@ -162,12 +230,30 @@ public: DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest) { + padBeforePatch(); m_assembler.movl_i32r(initialValue.asIntptr(), dest); return DataLabelPtr(this); } + + Jump branch8(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right) + { + m_assembler.cmpb_im(right.m_value, left.m_ptr); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + + 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(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))); @@ -175,19 +261,28 @@ public: 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))); } + Jump branch32WithPatch(RelationalCondition cond, Address left, DataLabel32& dataLabel, TrustedImm32 initialRightValue = TrustedImm32(0)) + { + padBeforePatch(); + m_assembler.cmpl_im_force32(initialRightValue.m_value, left.offset, left.base); + dataLabel = DataLabel32(this); + return Jump(m_assembler.jCC(x86Condition(cond))); + } + DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) { + padBeforePatch(); m_assembler.movl_i32m(initialValue.asIntptr(), address.offset, address.base); return DataLabelPtr(this); } 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(); } @@ -198,6 +293,58 @@ public: return FunctionPtr(reinterpret_cast(reinterpret_cast(call.dataLocation()) + offset)); } + static bool canJumpReplacePatchableBranchPtrWithPatch() { return true; } + static bool canJumpReplacePatchableBranch32WithPatch() { 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 CodeLocationLabel startOfPatchableBranch32WithPatchOnAddress(CodeLocationDataLabel32 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); + } + + 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); + } + + static void revertJumpReplacementToPatchableBranch32WithPatch(CodeLocationLabel instructionStart, Address address, int32_t initialValue) + { + ASSERT(!address.offset); + X86Assembler::revertJumpTo_cmpl_im_force32(instructionStart.executableAddress(), initialValue, 0, address.base); + } + private: friend class LinkBuffer; friend class RepatchBuffer;