]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - assembler/MacroAssemblerX86.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / assembler / MacroAssemblerX86.h
index 088fe196b9f84a2c23375de9f8a43f3c2f77f098..bdd9e57ba91f4f78e914e63637d9edc394e57aef 100644 (file)
@@ -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
  *
  * 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::sub32;
     using MacroAssemblerX86Common::or32;
     using MacroAssemblerX86Common::load32;
+    using MacroAssemblerX86Common::load8;
     using MacroAssemblerX86Common::store32;
     using MacroAssemblerX86Common::store32;
+    using MacroAssemblerX86Common::store8;
     using MacroAssemblerX86Common::branch32;
     using MacroAssemblerX86Common::call;
     using MacroAssemblerX86Common::jump;
     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::loadDouble;
     using MacroAssemblerX86Common::storeDouble;
     using MacroAssemblerX86Common::convertInt32ToDouble;
+    using MacroAssemblerX86Common::branch8;
+    using MacroAssemblerX86Common::branchTest8;
 
     void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
     {
 
     void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
     {
@@ -62,6 +66,11 @@ public:
         m_assembler.addl_im(imm.m_value, address.m_ptr);
     }
     
         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);
     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);
     }
     {
         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);
     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);
     }
     {
         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 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());
     {
         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)
     }
 
     void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
@@ -113,6 +152,35 @@ public:
     {
         m_assembler.movl_rm(src, address);
     }
     {
         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)
     {
 
     Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
     {
@@ -162,12 +230,30 @@ public:
 
     DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
     {
 
     DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
     {
+        padBeforePatch();
         m_assembler.movl_i32r(initialValue.asIntptr(), dest);
         return DataLabelPtr(this);
     }
         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))
     {
 
     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)));
         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))
     {
 
     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)));
     }
 
         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)
     {
     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(); }
         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(); }
     static bool supportsFloatingPointTruncate() { return isSSE2Present(); }
     static bool supportsFloatingPointSqrt() { return isSSE2Present(); }
     static bool supportsFloatingPointAbs() { return isSSE2Present(); }
@@ -198,6 +293,58 @@ public:
         return FunctionPtr(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(call.dataLocation()) + offset));
     }
 
         return FunctionPtr(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(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<intptr_t>(initialValue), reg);
+    }
+
+    static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel instructionStart, Address address, void* initialValue)
+    {
+        ASSERT(!address.offset);
+        X86Assembler::revertJumpTo_cmpl_im_force32(instructionStart.executableAddress(), reinterpret_cast<intptr_t>(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;
 private:
     friend class LinkBuffer;
     friend class RepatchBuffer;