]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - dfg/DFGGPRInfo.h
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGGPRInfo.h
index f4e9f76f711d8e99cc824547634cf7704639a5b9..4a250328f18f50a570d2b84c6b411f8a513c87bc 100644 (file)
@@ -36,12 +36,289 @@ namespace JSC { namespace DFG {
 typedef MacroAssembler::RegisterID GPRReg;
 #define InvalidGPRReg ((GPRReg)-1)
 
+#if USE(JSVALUE64)
+class JSValueRegs {
+public:
+    JSValueRegs()
+        : m_gpr(InvalidGPRReg)
+    {
+    }
+    
+    explicit JSValueRegs(GPRReg gpr)
+        : m_gpr(gpr)
+    {
+    }
+    
+    bool operator!() const { return m_gpr == InvalidGPRReg; }
+    
+    GPRReg gpr() const { return m_gpr; }
+    
+private:
+    GPRReg m_gpr;
+};
+
+class JSValueSource {
+public:
+    JSValueSource()
+        : m_offset(notAddress())
+        , m_base(InvalidGPRReg)
+    {
+    }
+    
+    JSValueSource(JSValueRegs regs)
+        : m_offset(notAddress())
+        , m_base(regs.gpr())
+    {
+    }
+    
+    explicit JSValueSource(GPRReg gpr)
+        : m_offset(notAddress())
+        , m_base(gpr)
+    {
+    }
+    
+    JSValueSource(MacroAssembler::Address address)
+        : m_offset(address.offset)
+        , m_base(address.base)
+    {
+        ASSERT(m_offset != notAddress());
+        ASSERT(m_base != InvalidGPRReg);
+    }
+    
+    static JSValueSource unboxedCell(GPRReg payloadGPR)
+    {
+        return JSValueSource(payloadGPR);
+    }
+    
+    bool operator!() const { return m_base == InvalidGPRReg; }
+    
+    bool isAddress() const { return m_offset != notAddress(); }
+    
+    int32_t offset() const
+    {
+        ASSERT(isAddress());
+        return m_offset;
+    }
+    
+    GPRReg base() const
+    {
+        ASSERT(isAddress());
+        return m_base;
+    }
+    
+    GPRReg gpr() const
+    {
+        ASSERT(!isAddress());
+        return m_base;
+    }
+    
+    MacroAssembler::Address asAddress() const { return MacroAssembler::Address(base(), offset()); }
+    
+private:
+    static inline int32_t notAddress() { return 0x80000000; }     
+          
+    int32_t m_offset;
+    GPRReg m_base;
+};
+#endif
+
+#if USE(JSVALUE32_64)
+class JSValueRegs {
+public:
+    JSValueRegs()
+        : m_tagGPR(static_cast<int8_t>(InvalidGPRReg))
+        , m_payloadGPR(static_cast<int8_t>(InvalidGPRReg))
+    {
+    }
+    
+    JSValueRegs(GPRReg tagGPR, GPRReg payloadGPR)
+        : m_tagGPR(tagGPR)
+        , m_payloadGPR(payloadGPR)
+    {
+        ASSERT((static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg) == (static_cast<GPRReg>(payloadGPR) == InvalidGPRReg));
+    }
+    
+    bool operator!() const { return static_cast<GPRReg>(m_tagGPR) == InvalidGPRReg; }
+    
+    GPRReg tagGPR() const { return static_cast<GPRReg>(m_tagGPR); }
+    GPRReg payloadGPR() const { return static_cast<GPRReg>(m_payloadGPR); }
+
+private:
+    int8_t m_tagGPR;
+    int8_t m_payloadGPR;
+};
+
+class JSValueSource {
+public:
+    JSValueSource()
+        : m_offset(notAddress())
+        , m_baseOrTag(static_cast<int8_t>(InvalidGPRReg))
+        , m_payload(static_cast<int8_t>(InvalidGPRReg))
+        , m_tagType(0)
+    {
+    }
+    
+    JSValueSource(JSValueRegs regs)
+        : m_offset(notAddress())
+        , m_baseOrTag(regs.tagGPR())
+        , m_payload(regs.payloadGPR())
+        , m_tagType(0)
+    {
+    }
+    
+    JSValueSource(GPRReg tagGPR, GPRReg payloadGPR)
+        : m_offset(notAddress())
+        , m_baseOrTag(static_cast<int8_t>(tagGPR))
+        , m_payload(static_cast<int8_t>(payloadGPR))
+        , m_tagType(0)
+    {
+    }
+    
+    JSValueSource(MacroAssembler::Address address)
+        : m_offset(address.offset)
+        , m_baseOrTag(static_cast<int8_t>(address.base))
+        , m_payload(static_cast<int8_t>(InvalidGPRReg))
+        , m_tagType(0)
+    {
+        ASSERT(m_offset != notAddress());
+        ASSERT(static_cast<GPRReg>(m_baseOrTag) != InvalidGPRReg);
+    }
+    
+    static JSValueSource unboxedCell(GPRReg payloadGPR)
+    {
+        JSValueSource result;
+        result.m_offset = notAddress();
+        result.m_baseOrTag = static_cast<int8_t>(InvalidGPRReg);
+        result.m_payload = static_cast<int8_t>(payloadGPR);
+        result.m_tagType = static_cast<int8_t>(JSValue::CellTag);
+        return result;
+    }
+    
+    bool operator!() const { return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg && static_cast<GPRReg>(m_payload) == InvalidGPRReg; }
+    
+    bool isAddress() const
+    {
+        ASSERT(!!*this);
+        return m_offset != notAddress();
+    }
+    
+    int32_t offset() const
+    {
+        ASSERT(isAddress());
+        return m_offset;
+    }
+    
+    GPRReg base() const
+    {
+        ASSERT(isAddress());
+        return static_cast<GPRReg>(m_baseOrTag);
+    }
+    
+    GPRReg tagGPR() const
+    {
+        ASSERT(!isAddress() && m_baseOrTag != InvalidGPRReg);
+        return static_cast<GPRReg>(m_baseOrTag);
+    }
+    
+    GPRReg payloadGPR() const
+    {
+        ASSERT(!isAddress());
+        return static_cast<GPRReg>(m_payload);
+    }
+    
+    bool hasKnownTag() const
+    {
+        ASSERT(!!*this);
+        ASSERT(!isAddress());
+        return static_cast<GPRReg>(m_baseOrTag) == InvalidGPRReg;
+    }
+    
+    uint32_t tag() const
+    {
+        return static_cast<int32_t>(m_tagType);
+    }
+    
+    MacroAssembler::Address asAddress(unsigned additionalOffset = 0) const { return MacroAssembler::Address(base(), offset() + additionalOffset); }
+    
+private:
+    static inline int32_t notAddress() { return 0x80000000; }     
+          
+    int32_t m_offset;
+    int8_t m_baseOrTag;
+    int8_t m_payload; 
+    int8_t m_tagType; // Contains the low bits of the tag.
+};
+#endif
+
+#if CPU(X86)
+#define NUMBER_OF_ARGUMENT_REGISTERS 0
+
+class GPRInfo {
+public:
+    typedef GPRReg RegisterType;
+    static const unsigned numberOfRegisters = 5;
+
+    // Temporary registers.
+    static const GPRReg regT0 = X86Registers::eax;
+    static const GPRReg regT1 = X86Registers::edx;
+    static const GPRReg regT2 = X86Registers::ecx;
+    static const GPRReg regT3 = X86Registers::ebx;
+    static const GPRReg regT4 = X86Registers::esi;
+    // These registers match the baseline JIT.
+    static const GPRReg cachedResultRegister = regT0;
+    static const GPRReg cachedResultRegister2 = regT1;
+    static const GPRReg callFrameRegister = X86Registers::edi;
+    // These constants provide the names for the general purpose argument & return value registers.
+    static const GPRReg argumentGPR0 = X86Registers::ecx; // regT2
+    static const GPRReg argumentGPR1 = X86Registers::edx; // regT1
+    static const GPRReg returnValueGPR = X86Registers::eax; // regT0
+    static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
+    static const GPRReg nonPreservedNonReturnGPR = X86Registers::ecx;
+
+    static GPRReg toRegister(unsigned index)
+    {
+        ASSERT(index < numberOfRegisters);
+        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4 };
+        return registerForIndex[index];
+    }
+
+    static unsigned toIndex(GPRReg reg)
+    {
+        ASSERT(reg != InvalidGPRReg);
+        ASSERT(reg < 8);
+        static const unsigned indexForRegister[8] = { 0, 2, 1, 3, InvalidIndex, InvalidIndex, 4, InvalidIndex };
+        unsigned result = indexForRegister[reg];
+        ASSERT(result != InvalidIndex);
+        return result;
+    }
+
+    static const char* debugName(GPRReg reg)
+    {
+        ASSERT(reg != InvalidGPRReg);
+        ASSERT(reg < 8);
+        static const char* nameForRegister[8] = {
+            "eax", "ecx", "edx", "ebx",
+            "esp", "ebp", "esi", "edi",
+        };
+        return nameForRegister[reg];
+    }
+private:
+
+    static const unsigned InvalidIndex = 0xffffffff;
+};
+
+#endif
+
+#if CPU(X86_64)
+#define NUMBER_OF_ARGUMENT_REGISTERS 6
+
 class GPRInfo {
 public:
     typedef GPRReg RegisterType;
     static const unsigned numberOfRegisters = 9;
 
-    // These registers match the old JIT.
+    // These registers match the baseline JIT.
+    static const GPRReg cachedResultRegister = X86Registers::eax;
     static const GPRReg timeoutCheckRegister = X86Registers::r12;
     static const GPRReg callFrameRegister = X86Registers::r13;
     static const GPRReg tagTypeNumberRegister = X86Registers::r14;
@@ -61,8 +338,11 @@ public:
     static const GPRReg argumentGPR1 = X86Registers::esi; // regT5
     static const GPRReg argumentGPR2 = X86Registers::edx; // regT1
     static const GPRReg argumentGPR3 = X86Registers::ecx; // regT2
+    static const GPRReg argumentGPR4 = X86Registers::r8;  // regT6
+    static const GPRReg argumentGPR5 = X86Registers::r9;  // regT7
     static const GPRReg returnValueGPR = X86Registers::eax; // regT0
     static const GPRReg returnValueGPR2 = X86Registers::edx; // regT1
+    static const GPRReg nonPreservedNonReturnGPR = X86Registers::esi;
 
     static GPRReg toRegister(unsigned index)
     {
@@ -81,7 +361,6 @@ public:
         return result;
     }
 
-#ifndef NDEBUG
     static const char* debugName(GPRReg reg)
     {
         ASSERT(reg != InvalidGPRReg);
@@ -94,12 +373,83 @@ public:
         };
         return nameForRegister[reg];
     }
+private:
+
+    static const unsigned InvalidIndex = 0xffffffff;
+};
+
 #endif
+
+#if CPU(ARM_THUMB2)
+#define NUMBER_OF_ARGUMENT_REGISTERS 4
+
+class GPRInfo {
+public:
+    typedef GPRReg RegisterType;
+    static const unsigned numberOfRegisters = 8;
+
+    // Temporary registers.
+    static const GPRReg regT0 = ARMRegisters::r0;
+    static const GPRReg regT1 = ARMRegisters::r1;
+    static const GPRReg regT2 = ARMRegisters::r2;
+    static const GPRReg regT3 = ARMRegisters::r4;
+    static const GPRReg regT4 = ARMRegisters::r8;
+    static const GPRReg regT5 = ARMRegisters::r9;
+    static const GPRReg regT6 = ARMRegisters::r10;
+    static const GPRReg regT7 = ARMRegisters::r11;
+    // These registers match the baseline JIT.
+    static const GPRReg cachedResultRegister = regT0;
+    static const GPRReg cachedResultRegister2 = regT1;
+    static const GPRReg callFrameRegister = ARMRegisters::r5;
+    // These constants provide the names for the general purpose argument & return value registers.
+    static const GPRReg argumentGPR0 = ARMRegisters::r0; // regT0
+    static const GPRReg argumentGPR1 = ARMRegisters::r1; // regT1
+    static const GPRReg argumentGPR2 = ARMRegisters::r2; // regT2
+    // FIXME: r3 is currently used be the MacroAssembler as a temporary - it seems
+    // This could threoretically be a problem if theis is used in code generation
+    // between the arguments being set up, and the call being made. That said,
+    // any change introducing a problem here is likely to be immediately apparent!
+    static const GPRReg argumentGPR3 = ARMRegisters::r3; // FIXME!
+    static const GPRReg returnValueGPR = ARMRegisters::r0; // regT0
+    static const GPRReg returnValueGPR2 = ARMRegisters::r1; // regT1
+    static const GPRReg nonPreservedNonReturnGPR = ARMRegisters::r2;
+
+    static GPRReg toRegister(unsigned index)
+    {
+        ASSERT(index < numberOfRegisters);
+        static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5, regT6, regT7 };
+        return registerForIndex[index];
+    }
+
+    static unsigned toIndex(GPRReg reg)
+    {
+        ASSERT(reg != InvalidGPRReg);
+        ASSERT(reg < 16);
+        static const unsigned indexForRegister[16] = { 0, 1, 2, InvalidIndex, 3, InvalidIndex, InvalidIndex, InvalidIndex, 4, 5, 6, 7, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex };
+        unsigned result = indexForRegister[reg];
+        ASSERT(result != InvalidIndex);
+        return result;
+    }
+
+    static const char* debugName(GPRReg reg)
+    {
+        ASSERT(reg != InvalidGPRReg);
+        ASSERT(reg < 16);
+        static const char* nameForRegister[16] = {
+            "r0", "r1", "r2", "r3",
+            "r4", "r5", "r6", "r7",
+            "r8", "r9", "r10", "r11",
+            "r12", "r13", "r14", "r15"
+        };
+        return nameForRegister[reg];
+    }
 private:
 
     static const unsigned InvalidIndex = 0xffffffff;
 };
 
+#endif
+
 typedef RegisterBank<GPRInfo>::iterator gpr_iterator;
 
 } } // namespace JSC::DFG