[JSC] Add GPRReg::InvalidGPRReg and FPRReg::InvalidFPRReg
[WebKit-https.git] / Source / JavaScriptCore / assembler / X86Assembler.h
index 0463909..f3a4083 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -41,7 +41,7 @@ inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(sign
 
 namespace X86Registers {
 
-typedef enum {
+typedef enum : int8_t {
     eax,
     ecx,
     edx,
@@ -58,16 +58,17 @@ typedef enum {
     r12,
     r13,
     r14,
-    r15
+    r15,
 #endif
+    InvalidGPRReg = -1,
 } RegisterID;
 
-typedef enum {
+typedef enum : int8_t {
     eip,
     eflags
 } SPRegisterID;
 
-typedef enum {
+typedef enum : int8_t {
     xmm0,
     xmm1,
     xmm2,
@@ -84,8 +85,9 @@ typedef enum {
     xmm12,
     xmm13,
     xmm14,
-    xmm15
+    xmm15,
 #endif
+    InvalidFPRReg = -1,
 } XMMRegisterID;
 
 } // namespace X86Register
@@ -260,6 +262,7 @@ private:
         OP_GROUP1A_Ev                   = 0x8F,
         OP_NOP                          = 0x90,
         OP_XCHG_EAX                     = 0x90,
+        OP_PAUSE                        = 0x90,
         OP_CDQ                          = 0x99,
         OP_MOV_EAXOv                    = 0xA1,
         OP_MOV_OvEAX                    = 0xA3,
@@ -300,6 +303,7 @@ private:
         OP2_CVTTSD2SI_GdWsd = 0x2C,
         OP2_CVTTSS2SI_GdWsd = 0x2C,
         OP2_UCOMISD_VsdWsd  = 0x2E,
+        OP2_RDTSC           = 0x31,
         OP2_3BYTE_ESCAPE_3A = 0x3A,
         OP2_CMOVCC          = 0x40,
         OP2_ADDSD_VsdWsd    = 0x58,
@@ -318,11 +322,13 @@ private:
         OP2_MOVD_EdVd       = 0x7E,
         OP2_JCC_rel32       = 0x80,
         OP_SETCC            = 0x90,
+        OP2_CPUID           = 0xA2,
         OP2_3BYTE_ESCAPE_AE = 0xAE,
         OP2_IMUL_GvEv       = 0xAF,
         OP2_CMPXCHGb        = 0xB0,
         OP2_CMPXCHG         = 0xB1,
         OP2_MOVZX_GvEb      = 0xB6,
+        OP2_POPCNT          = 0xB8,
         OP2_BSF             = 0xBC,
         OP2_TZCNT           = 0xBC,
         OP2_BSR             = 0xBD,
@@ -341,7 +347,9 @@ private:
     typedef enum {
         OP3_ROUNDSS_VssWssIb = 0x0A,
         OP3_ROUNDSD_VsdWsdIb = 0x0B,
+        OP3_LFENCE           = 0xE8,
         OP3_MFENCE           = 0xF0,
+        OP3_SFENCE           = 0xF8,
     } ThreeByteOpcodeID;
 
     struct VexPrefix {
@@ -679,6 +687,18 @@ public:
         m_formatter.oneByteOp(OP_AND_GvEv, dst, base, index, scale, offset);
     }
 
+    void andw_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_OPERAND_SIZE);
+        andl_mr(offset, base, dst);
+    }
+
+    void andw_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_OPERAND_SIZE);
+        andl_mr(offset, base, index, scale, dst);
+    }
+
     void andl_rm(RegisterID src, int offset, RegisterID base)
     {
         m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
@@ -1646,6 +1666,32 @@ public:
     }
 #endif
 
+    void popcnt_rr(RegisterID src, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_POPCNT, dst, src);
+    }
+
+    void popcnt_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp(OP2_POPCNT, dst, base, offset);
+    }
+
+#if CPU(X86_64)
+    void popcntq_rr(RegisterID src, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp64(OP2_POPCNT, dst, src);
+    }
+
+    void popcntq_mr(int offset, RegisterID base, RegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOp64(OP2_POPCNT, dst, base, offset);
+    }
+#endif
+
 private:
     template<GroupOpcodeID op>
     void shiftInstruction32(int imm, RegisterID dst)
@@ -3117,6 +3163,16 @@ public:
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOpAddr(OP2_MOVSD_WsdVsd, (RegisterID)src, bitwise_cast<uint32_t>(address));
     }
+    void movss_mr(const void* address, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOpAddr(OP2_MOVSD_VsdWsd, (RegisterID)dst, bitwise_cast<uint32_t>(address));
+    }
+    void movss_rm(XMMRegisterID src, const void* address)
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.twoByteOpAddr(OP2_MOVSD_WsdVsd, (RegisterID)src, bitwise_cast<uint32_t>(address));
+    }
 #endif
 
     void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
@@ -3538,12 +3594,38 @@ public:
         m_formatter.twoByteOp64(OP2_XADD, src, base, index, scale, offset);
     }
 #endif // CPU(X86_64)
-    
+
+    void lfence()
+    {
+        m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_LFENCE);
+    }
+
     void mfence()
     {
         m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_MFENCE);
     }
 
+    void sfence()
+    {
+        m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_SFENCE);
+    }
+
+    void rdtsc()
+    {
+        m_formatter.twoByteOp(OP2_RDTSC);
+    }
+
+    void pause()
+    {
+        m_formatter.prefix(PRE_SSE_F3);
+        m_formatter.oneByteOp(OP_PAUSE);
+    }
+
+    void cpuid()
+    {
+        m_formatter.twoByteOp(OP2_CPUID);
+    }
+
     // Assembler admin methods:
 
     size_t codeSize() const