JavaScriptCore/assembler/X86Assembler.h
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2008 Apple Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  * 1. Redistributions of source code must retain the above copyright
       
     8  *    notice, this list of conditions and the following disclaimer.
       
     9  * 2. Redistributions in binary form must reproduce the above copyright
       
    10  *    notice, this list of conditions and the following disclaimer in the
       
    11  *    documentation and/or other materials provided with the distribution.
       
    12  *
       
    13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
       
    14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
       
    15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
       
    17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
       
    18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
       
    20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
       
    21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
       
    24  */
       
    25 
       
    26 #ifndef X86Assembler_h
       
    27 #define X86Assembler_h
       
    28 
       
    29 #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
       
    30 
       
    31 #include "AssemblerBuffer.h"
       
    32 #include <stdint.h>
       
    33 #include <wtf/Assertions.h>
       
    34 #include <wtf/Vector.h>
       
    35 
       
    36 namespace JSC {
       
    37 
       
    38 inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
       
    39 
       
    40 namespace X86Registers {
       
    41     typedef enum {
       
    42         eax,
       
    43         ecx,
       
    44         edx,
       
    45         ebx,
       
    46         esp,
       
    47         ebp,
       
    48         esi,
       
    49         edi,
       
    50 
       
    51 #if CPU(X86_64)
       
    52         r8,
       
    53         r9,
       
    54         r10,
       
    55         r11,
       
    56         r12,
       
    57         r13,
       
    58         r14,
       
    59         r15,
       
    60 #endif
       
    61     } RegisterID;
       
    62 
       
    63     typedef enum {
       
    64         xmm0,
       
    65         xmm1,
       
    66         xmm2,
       
    67         xmm3,
       
    68         xmm4,
       
    69         xmm5,
       
    70         xmm6,
       
    71         xmm7,
       
    72     } XMMRegisterID;
       
    73 }
       
    74 
       
    75 class X86Assembler {
       
    76 public:
       
    77     typedef X86Registers::RegisterID RegisterID;
       
    78     typedef X86Registers::XMMRegisterID XMMRegisterID;
       
    79     typedef XMMRegisterID FPRegisterID;
       
    80 
       
    81     typedef enum {
       
    82         ConditionO,
       
    83         ConditionNO,
       
    84         ConditionB,
       
    85         ConditionAE,
       
    86         ConditionE,
       
    87         ConditionNE,
       
    88         ConditionBE,
       
    89         ConditionA,
       
    90         ConditionS,
       
    91         ConditionNS,
       
    92         ConditionP,
       
    93         ConditionNP,
       
    94         ConditionL,
       
    95         ConditionGE,
       
    96         ConditionLE,
       
    97         ConditionG,
       
    98 
       
    99         ConditionC  = ConditionB,
       
   100         ConditionNC = ConditionAE,
       
   101     } Condition;
       
   102 
       
   103 private:
       
   104     typedef enum {
       
   105         OP_ADD_EvGv                     = 0x01,
       
   106         OP_ADD_GvEv                     = 0x03,
       
   107         OP_OR_EvGv                      = 0x09,
       
   108         OP_OR_GvEv                      = 0x0B,
       
   109         OP_2BYTE_ESCAPE                 = 0x0F,
       
   110         OP_AND_EvGv                     = 0x21,
       
   111         OP_AND_GvEv                     = 0x23,
       
   112         OP_SUB_EvGv                     = 0x29,
       
   113         OP_SUB_GvEv                     = 0x2B,
       
   114         PRE_PREDICT_BRANCH_NOT_TAKEN    = 0x2E,
       
   115         OP_XOR_EvGv                     = 0x31,
       
   116         OP_XOR_GvEv                     = 0x33,
       
   117         OP_CMP_EvGv                     = 0x39,
       
   118         OP_CMP_GvEv                     = 0x3B,
       
   119 #if CPU(X86_64)
       
   120         PRE_REX                         = 0x40,
       
   121 #endif
       
   122         OP_PUSH_EAX                     = 0x50,
       
   123         OP_POP_EAX                      = 0x58,
       
   124 #if CPU(X86_64)
       
   125         OP_MOVSXD_GvEv                  = 0x63,
       
   126 #endif
       
   127         PRE_OPERAND_SIZE                = 0x66,
       
   128         PRE_SSE_66                      = 0x66,
       
   129         OP_PUSH_Iz                      = 0x68,
       
   130         OP_IMUL_GvEvIz                  = 0x69,
       
   131         OP_GROUP1_EbIb                  = 0x80,
       
   132         OP_GROUP1_EvIz                  = 0x81,
       
   133         OP_GROUP1_EvIb                  = 0x83,
       
   134         OP_TEST_EvGv                    = 0x85,
       
   135         OP_XCHG_EvGv                    = 0x87,
       
   136         OP_MOV_EvGv                     = 0x89,
       
   137         OP_MOV_GvEv                     = 0x8B,
       
   138         OP_LEA                          = 0x8D,
       
   139         OP_GROUP1A_Ev                   = 0x8F,
       
   140         OP_CDQ                          = 0x99,
       
   141         OP_MOV_EAXOv                    = 0xA1,
       
   142         OP_MOV_OvEAX                    = 0xA3,
       
   143         OP_MOV_EAXIv                    = 0xB8,
       
   144         OP_GROUP2_EvIb                  = 0xC1,
       
   145         OP_RET                          = 0xC3,
       
   146         OP_GROUP11_EvIz                 = 0xC7,
       
   147         OP_INT3                         = 0xCC,
       
   148         OP_GROUP2_Ev1                   = 0xD1,
       
   149         OP_GROUP2_EvCL                  = 0xD3,
       
   150         OP_CALL_rel32                   = 0xE8,
       
   151         OP_JMP_rel32                    = 0xE9,
       
   152         PRE_SSE_F2                      = 0xF2,
       
   153         OP_HLT                          = 0xF4,
       
   154         OP_GROUP3_EbIb                  = 0xF6,
       
   155         OP_GROUP3_Ev                    = 0xF7,
       
   156         OP_GROUP3_EvIz                  = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test. 
       
   157         OP_GROUP5_Ev                    = 0xFF,
       
   158     } OneByteOpcodeID;
       
   159 
       
   160     typedef enum {
       
   161         OP2_MOVSD_VsdWsd    = 0x10,
       
   162         OP2_MOVSD_WsdVsd    = 0x11,
       
   163         OP2_CVTSI2SD_VsdEd  = 0x2A,
       
   164         OP2_CVTTSD2SI_GdWsd = 0x2C,
       
   165         OP2_UCOMISD_VsdWsd  = 0x2E,
       
   166         OP2_ADDSD_VsdWsd    = 0x58,
       
   167         OP2_MULSD_VsdWsd    = 0x59,
       
   168         OP2_SUBSD_VsdWsd    = 0x5C,
       
   169         OP2_DIVSD_VsdWsd    = 0x5E,
       
   170         OP2_SQRTSD_VsdWsd   = 0x51,
       
   171         OP2_XORPD_VpdWpd    = 0x57,
       
   172         OP2_MOVD_VdEd       = 0x6E,
       
   173         OP2_MOVD_EdVd       = 0x7E,
       
   174         OP2_JCC_rel32       = 0x80,
       
   175         OP_SETCC            = 0x90,
       
   176         OP2_IMUL_GvEv       = 0xAF,
       
   177         OP2_MOVZX_GvEb      = 0xB6,
       
   178         OP2_MOVZX_GvEw      = 0xB7,
       
   179         OP2_PEXTRW_GdUdIb   = 0xC5,
       
   180     } TwoByteOpcodeID;
       
   181 
       
   182     TwoByteOpcodeID jccRel32(Condition cond)
       
   183     {
       
   184         return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
       
   185     }
       
   186 
       
   187     TwoByteOpcodeID setccOpcode(Condition cond)
       
   188     {
       
   189         return (TwoByteOpcodeID)(OP_SETCC + cond);
       
   190     }
       
   191 
       
   192     typedef enum {
       
   193         GROUP1_OP_ADD = 0,
       
   194         GROUP1_OP_OR  = 1,
       
   195         GROUP1_OP_ADC = 2,
       
   196         GROUP1_OP_AND = 4,
       
   197         GROUP1_OP_SUB = 5,
       
   198         GROUP1_OP_XOR = 6,
       
   199         GROUP1_OP_CMP = 7,
       
   200 
       
   201         GROUP1A_OP_POP = 0,
       
   202 
       
   203         GROUP2_OP_SHL = 4,
       
   204         GROUP2_OP_SHR = 5,
       
   205         GROUP2_OP_SAR = 7,
       
   206 
       
   207         GROUP3_OP_TEST = 0,
       
   208         GROUP3_OP_NOT  = 2,
       
   209         GROUP3_OP_NEG  = 3,
       
   210         GROUP3_OP_IDIV = 7,
       
   211 
       
   212         GROUP5_OP_CALLN = 2,
       
   213         GROUP5_OP_JMPN  = 4,
       
   214         GROUP5_OP_PUSH  = 6,
       
   215 
       
   216         GROUP11_MOV = 0,
       
   217     } GroupOpcodeID;
       
   218     
       
   219     class X86InstructionFormatter;
       
   220 public:
       
   221 
       
   222     class JmpSrc {
       
   223         friend class X86Assembler;
       
   224         friend class X86InstructionFormatter;
       
   225     public:
       
   226         JmpSrc()
       
   227             : m_offset(-1)
       
   228         {
       
   229         }
       
   230 
       
   231     private:
       
   232         JmpSrc(int offset)
       
   233             : m_offset(offset)
       
   234         {
       
   235         }
       
   236 
       
   237         int m_offset;
       
   238     };
       
   239     
       
   240     class JmpDst {
       
   241         friend class X86Assembler;
       
   242         friend class X86InstructionFormatter;
       
   243     public:
       
   244         JmpDst()
       
   245             : m_offset(-1)
       
   246             , m_used(false)
       
   247         {
       
   248         }
       
   249 
       
   250         bool isUsed() const { return m_used; }
       
   251         void used() { m_used = true; }
       
   252     private:
       
   253         JmpDst(int offset)
       
   254             : m_offset(offset)
       
   255             , m_used(false)
       
   256         {
       
   257             ASSERT(m_offset == offset);
       
   258         }
       
   259 
       
   260         int m_offset : 31;
       
   261         bool m_used : 1;
       
   262     };
       
   263 
       
   264     X86Assembler()
       
   265     {
       
   266     }
       
   267 
       
   268     size_t size() const { return m_formatter.size(); }
       
   269 
       
   270     // Stack operations:
       
   271 
       
   272     void push_r(RegisterID reg)
       
   273     {
       
   274         m_formatter.oneByteOp(OP_PUSH_EAX, reg);
       
   275     }
       
   276 
       
   277     void pop_r(RegisterID reg)
       
   278     {
       
   279         m_formatter.oneByteOp(OP_POP_EAX, reg);
       
   280     }
       
   281 
       
   282     void push_i32(int imm)
       
   283     {
       
   284         m_formatter.oneByteOp(OP_PUSH_Iz);
       
   285         m_formatter.immediate32(imm);
       
   286     }
       
   287 
       
   288     void push_m(int offset, RegisterID base)
       
   289     {
       
   290         m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
       
   291     }
       
   292 
       
   293     void pop_m(int offset, RegisterID base)
       
   294     {
       
   295         m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
       
   296     }
       
   297 
       
   298     // Arithmetic operations:
       
   299 
       
   300 #if !CPU(X86_64)
       
   301     void adcl_im(int imm, void* addr)
       
   302     {
       
   303         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   304             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
       
   305             m_formatter.immediate8(imm);
       
   306         } else {
       
   307             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
       
   308             m_formatter.immediate32(imm);
       
   309         }
       
   310     }
       
   311 #endif
       
   312 
       
   313     void addl_rr(RegisterID src, RegisterID dst)
       
   314     {
       
   315         m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
       
   316     }
       
   317 
       
   318     void addl_mr(int offset, RegisterID base, RegisterID dst)
       
   319     {
       
   320         m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
       
   321     }
       
   322 
       
   323     void addl_rm(RegisterID src, int offset, RegisterID base)
       
   324     {
       
   325         m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
       
   326     }
       
   327 
       
   328     void addl_ir(int imm, RegisterID dst)
       
   329     {
       
   330         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   331             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
       
   332             m_formatter.immediate8(imm);
       
   333         } else {
       
   334             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
       
   335             m_formatter.immediate32(imm);
       
   336         }
       
   337     }
       
   338 
       
   339     void addl_im(int imm, int offset, RegisterID base)
       
   340     {
       
   341         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   342             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
       
   343             m_formatter.immediate8(imm);
       
   344         } else {
       
   345             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
       
   346             m_formatter.immediate32(imm);
       
   347         }
       
   348     }
       
   349 
       
   350 #if CPU(X86_64)
       
   351     void addq_rr(RegisterID src, RegisterID dst)
       
   352     {
       
   353         m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
       
   354     }
       
   355 
       
   356     void addq_ir(int imm, RegisterID dst)
       
   357     {
       
   358         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   359             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
       
   360             m_formatter.immediate8(imm);
       
   361         } else {
       
   362             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
       
   363             m_formatter.immediate32(imm);
       
   364         }
       
   365     }
       
   366 
       
   367     void addq_im(int imm, int offset, RegisterID base)
       
   368     {
       
   369         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   370             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
       
   371             m_formatter.immediate8(imm);
       
   372         } else {
       
   373             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
       
   374             m_formatter.immediate32(imm);
       
   375         }
       
   376     }
       
   377 #else
       
   378     void addl_im(int imm, void* addr)
       
   379     {
       
   380         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   381             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
       
   382             m_formatter.immediate8(imm);
       
   383         } else {
       
   384             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
       
   385             m_formatter.immediate32(imm);
       
   386         }
       
   387     }
       
   388 #endif
       
   389 
       
   390     void andl_rr(RegisterID src, RegisterID dst)
       
   391     {
       
   392         m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
       
   393     }
       
   394 
       
   395     void andl_mr(int offset, RegisterID base, RegisterID dst)
       
   396     {
       
   397         m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
       
   398     }
       
   399 
       
   400     void andl_rm(RegisterID src, int offset, RegisterID base)
       
   401     {
       
   402         m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
       
   403     }
       
   404 
       
   405     void andl_ir(int imm, RegisterID dst)
       
   406     {
       
   407         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   408             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
       
   409             m_formatter.immediate8(imm);
       
   410         } else {
       
   411             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
       
   412             m_formatter.immediate32(imm);
       
   413         }
       
   414     }
       
   415 
       
   416     void andl_im(int imm, int offset, RegisterID base)
       
   417     {
       
   418         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   419             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
       
   420             m_formatter.immediate8(imm);
       
   421         } else {
       
   422             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
       
   423             m_formatter.immediate32(imm);
       
   424         }
       
   425     }
       
   426 
       
   427 #if CPU(X86_64)
       
   428     void andq_rr(RegisterID src, RegisterID dst)
       
   429     {
       
   430         m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
       
   431     }
       
   432 
       
   433     void andq_ir(int imm, RegisterID dst)
       
   434     {
       
   435         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   436             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
       
   437             m_formatter.immediate8(imm);
       
   438         } else {
       
   439             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
       
   440             m_formatter.immediate32(imm);
       
   441         }
       
   442     }
       
   443 #else
       
   444     void andl_im(int imm, void* addr)
       
   445     {
       
   446         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   447             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
       
   448             m_formatter.immediate8(imm);
       
   449         } else {
       
   450             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
       
   451             m_formatter.immediate32(imm);
       
   452         }
       
   453     }
       
   454 #endif
       
   455 
       
   456     void negl_r(RegisterID dst)
       
   457     {
       
   458         m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
       
   459     }
       
   460 
       
   461     void negl_m(int offset, RegisterID base)
       
   462     {
       
   463         m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
       
   464     }
       
   465 
       
   466     void notl_r(RegisterID dst)
       
   467     {
       
   468         m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
       
   469     }
       
   470 
       
   471     void notl_m(int offset, RegisterID base)
       
   472     {
       
   473         m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
       
   474     }
       
   475 
       
   476     void orl_rr(RegisterID src, RegisterID dst)
       
   477     {
       
   478         m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
       
   479     }
       
   480 
       
   481     void orl_mr(int offset, RegisterID base, RegisterID dst)
       
   482     {
       
   483         m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
       
   484     }
       
   485 
       
   486     void orl_rm(RegisterID src, int offset, RegisterID base)
       
   487     {
       
   488         m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
       
   489     }
       
   490 
       
   491     void orl_ir(int imm, RegisterID dst)
       
   492     {
       
   493         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   494             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
       
   495             m_formatter.immediate8(imm);
       
   496         } else {
       
   497             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
       
   498             m_formatter.immediate32(imm);
       
   499         }
       
   500     }
       
   501 
       
   502     void orl_im(int imm, int offset, RegisterID base)
       
   503     {
       
   504         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   505             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
       
   506             m_formatter.immediate8(imm);
       
   507         } else {
       
   508             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
       
   509             m_formatter.immediate32(imm);
       
   510         }
       
   511     }
       
   512 
       
   513 #if CPU(X86_64)
       
   514     void orq_rr(RegisterID src, RegisterID dst)
       
   515     {
       
   516         m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
       
   517     }
       
   518 
       
   519     void orq_ir(int imm, RegisterID dst)
       
   520     {
       
   521         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   522             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
       
   523             m_formatter.immediate8(imm);
       
   524         } else {
       
   525             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
       
   526             m_formatter.immediate32(imm);
       
   527         }
       
   528     }
       
   529 #else
       
   530     void orl_im(int imm, void* addr)
       
   531     {
       
   532         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   533             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
       
   534             m_formatter.immediate8(imm);
       
   535         } else {
       
   536             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
       
   537             m_formatter.immediate32(imm);
       
   538         }
       
   539     }
       
   540 #endif
       
   541 
       
   542     void subl_rr(RegisterID src, RegisterID dst)
       
   543     {
       
   544         m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
       
   545     }
       
   546 
       
   547     void subl_mr(int offset, RegisterID base, RegisterID dst)
       
   548     {
       
   549         m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
       
   550     }
       
   551 
       
   552     void subl_rm(RegisterID src, int offset, RegisterID base)
       
   553     {
       
   554         m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
       
   555     }
       
   556 
       
   557     void subl_ir(int imm, RegisterID dst)
       
   558     {
       
   559         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   560             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
       
   561             m_formatter.immediate8(imm);
       
   562         } else {
       
   563             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
       
   564             m_formatter.immediate32(imm);
       
   565         }
       
   566     }
       
   567     
       
   568     void subl_im(int imm, int offset, RegisterID base)
       
   569     {
       
   570         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   571             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
       
   572             m_formatter.immediate8(imm);
       
   573         } else {
       
   574             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
       
   575             m_formatter.immediate32(imm);
       
   576         }
       
   577     }
       
   578 
       
   579 #if CPU(X86_64)
       
   580     void subq_rr(RegisterID src, RegisterID dst)
       
   581     {
       
   582         m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
       
   583     }
       
   584 
       
   585     void subq_ir(int imm, RegisterID dst)
       
   586     {
       
   587         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   588             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
       
   589             m_formatter.immediate8(imm);
       
   590         } else {
       
   591             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
       
   592             m_formatter.immediate32(imm);
       
   593         }
       
   594     }
       
   595 #else
       
   596     void subl_im(int imm, void* addr)
       
   597     {
       
   598         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   599             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
       
   600             m_formatter.immediate8(imm);
       
   601         } else {
       
   602             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
       
   603             m_formatter.immediate32(imm);
       
   604         }
       
   605     }
       
   606 #endif
       
   607 
       
   608     void xorl_rr(RegisterID src, RegisterID dst)
       
   609     {
       
   610         m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
       
   611     }
       
   612 
       
   613     void xorl_mr(int offset, RegisterID base, RegisterID dst)
       
   614     {
       
   615         m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
       
   616     }
       
   617 
       
   618     void xorl_rm(RegisterID src, int offset, RegisterID base)
       
   619     {
       
   620         m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
       
   621     }
       
   622 
       
   623     void xorl_im(int imm, int offset, RegisterID base)
       
   624     {
       
   625         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   626             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
       
   627             m_formatter.immediate8(imm);
       
   628         } else {
       
   629             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
       
   630             m_formatter.immediate32(imm);
       
   631         }
       
   632     }
       
   633 
       
   634     void xorl_ir(int imm, RegisterID dst)
       
   635     {
       
   636         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   637             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
       
   638             m_formatter.immediate8(imm);
       
   639         } else {
       
   640             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
       
   641             m_formatter.immediate32(imm);
       
   642         }
       
   643     }
       
   644 
       
   645 #if CPU(X86_64)
       
   646     void xorq_rr(RegisterID src, RegisterID dst)
       
   647     {
       
   648         m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
       
   649     }
       
   650 
       
   651     void xorq_ir(int imm, RegisterID dst)
       
   652     {
       
   653         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   654             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
       
   655             m_formatter.immediate8(imm);
       
   656         } else {
       
   657             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
       
   658             m_formatter.immediate32(imm);
       
   659         }
       
   660     }
       
   661 #endif
       
   662 
       
   663     void sarl_i8r(int imm, RegisterID dst)
       
   664     {
       
   665         if (imm == 1)
       
   666             m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
       
   667         else {
       
   668             m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
       
   669             m_formatter.immediate8(imm);
       
   670         }
       
   671     }
       
   672 
       
   673     void sarl_CLr(RegisterID dst)
       
   674     {
       
   675         m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
       
   676     }
       
   677     
       
   678     void shrl_i8r(int imm, RegisterID dst)
       
   679     {
       
   680         if (imm == 1)
       
   681             m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
       
   682         else {
       
   683             m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
       
   684             m_formatter.immediate8(imm);
       
   685         }
       
   686     }
       
   687     
       
   688     void shrl_CLr(RegisterID dst)
       
   689     {
       
   690         m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
       
   691     }
       
   692 
       
   693     void shll_i8r(int imm, RegisterID dst)
       
   694     {
       
   695         if (imm == 1)
       
   696             m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
       
   697         else {
       
   698             m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
       
   699             m_formatter.immediate8(imm);
       
   700         }
       
   701     }
       
   702 
       
   703     void shll_CLr(RegisterID dst)
       
   704     {
       
   705         m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
       
   706     }
       
   707 
       
   708 #if CPU(X86_64)
       
   709     void sarq_CLr(RegisterID dst)
       
   710     {
       
   711         m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
       
   712     }
       
   713 
       
   714     void sarq_i8r(int imm, RegisterID dst)
       
   715     {
       
   716         if (imm == 1)
       
   717             m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
       
   718         else {
       
   719             m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
       
   720             m_formatter.immediate8(imm);
       
   721         }
       
   722     }
       
   723 #endif
       
   724 
       
   725     void imull_rr(RegisterID src, RegisterID dst)
       
   726     {
       
   727         m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
       
   728     }
       
   729 
       
   730     void imull_mr(int offset, RegisterID base, RegisterID dst)
       
   731     {
       
   732         m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
       
   733     }
       
   734 
       
   735     void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
       
   736     {
       
   737         m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
       
   738         m_formatter.immediate32(value);
       
   739     }
       
   740 
       
   741     void idivl_r(RegisterID dst)
       
   742     {
       
   743         m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
       
   744     }
       
   745 
       
   746     // Comparisons:
       
   747 
       
   748     void cmpl_rr(RegisterID src, RegisterID dst)
       
   749     {
       
   750         m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
       
   751     }
       
   752 
       
   753     void cmpl_rm(RegisterID src, int offset, RegisterID base)
       
   754     {
       
   755         m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
       
   756     }
       
   757 
       
   758     void cmpl_mr(int offset, RegisterID base, RegisterID src)
       
   759     {
       
   760         m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
       
   761     }
       
   762 
       
   763     void cmpl_ir(int imm, RegisterID dst)
       
   764     {
       
   765         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   766             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
       
   767             m_formatter.immediate8(imm);
       
   768         } else {
       
   769             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
       
   770             m_formatter.immediate32(imm);
       
   771         }
       
   772     }
       
   773 
       
   774     void cmpl_ir_force32(int imm, RegisterID dst)
       
   775     {
       
   776         m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
       
   777         m_formatter.immediate32(imm);
       
   778     }
       
   779     
       
   780     void cmpl_im(int imm, int offset, RegisterID base)
       
   781     {
       
   782         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   783             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
       
   784             m_formatter.immediate8(imm);
       
   785         } else {
       
   786             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
       
   787             m_formatter.immediate32(imm);
       
   788         }
       
   789     }
       
   790     
       
   791     void cmpb_im(int imm, int offset, RegisterID base)
       
   792     {
       
   793         m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
       
   794         m_formatter.immediate8(imm);
       
   795     }
       
   796     
       
   797     void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
       
   798     {
       
   799         m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
       
   800         m_formatter.immediate8(imm);
       
   801     }
       
   802 
       
   803     void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
       
   804     {
       
   805         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   806             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
       
   807             m_formatter.immediate8(imm);
       
   808         } else {
       
   809             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
       
   810             m_formatter.immediate32(imm);
       
   811         }
       
   812     }
       
   813 
       
   814     void cmpl_im_force32(int imm, int offset, RegisterID base)
       
   815     {
       
   816         m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
       
   817         m_formatter.immediate32(imm);
       
   818     }
       
   819 
       
   820 #if CPU(X86_64)
       
   821     void cmpq_rr(RegisterID src, RegisterID dst)
       
   822     {
       
   823         m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
       
   824     }
       
   825 
       
   826     void cmpq_rm(RegisterID src, int offset, RegisterID base)
       
   827     {
       
   828         m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
       
   829     }
       
   830 
       
   831     void cmpq_mr(int offset, RegisterID base, RegisterID src)
       
   832     {
       
   833         m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
       
   834     }
       
   835 
       
   836     void cmpq_ir(int imm, RegisterID dst)
       
   837     {
       
   838         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   839             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
       
   840             m_formatter.immediate8(imm);
       
   841         } else {
       
   842             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
       
   843             m_formatter.immediate32(imm);
       
   844         }
       
   845     }
       
   846 
       
   847     void cmpq_im(int imm, int offset, RegisterID base)
       
   848     {
       
   849         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   850             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
       
   851             m_formatter.immediate8(imm);
       
   852         } else {
       
   853             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
       
   854             m_formatter.immediate32(imm);
       
   855         }
       
   856     }
       
   857 
       
   858     void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
       
   859     {
       
   860         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   861             m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
       
   862             m_formatter.immediate8(imm);
       
   863         } else {
       
   864             m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
       
   865             m_formatter.immediate32(imm);
       
   866         }
       
   867     }
       
   868 #else
       
   869     void cmpl_rm(RegisterID reg, void* addr)
       
   870     {
       
   871         m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
       
   872     }
       
   873 
       
   874     void cmpl_im(int imm, void* addr)
       
   875     {
       
   876         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   877             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
       
   878             m_formatter.immediate8(imm);
       
   879         } else {
       
   880             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
       
   881             m_formatter.immediate32(imm);
       
   882         }
       
   883     }
       
   884 #endif
       
   885 
       
   886     void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
       
   887     {
       
   888         m_formatter.prefix(PRE_OPERAND_SIZE);
       
   889         m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
       
   890     }
       
   891 
       
   892     void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
       
   893     {
       
   894         if (CAN_SIGN_EXTEND_8_32(imm)) {
       
   895             m_formatter.prefix(PRE_OPERAND_SIZE);
       
   896             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
       
   897             m_formatter.immediate8(imm);
       
   898         } else {
       
   899             m_formatter.prefix(PRE_OPERAND_SIZE);
       
   900             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
       
   901             m_formatter.immediate16(imm);
       
   902         }
       
   903     }
       
   904 
       
   905     void testl_rr(RegisterID src, RegisterID dst)
       
   906     {
       
   907         m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
       
   908     }
       
   909     
       
   910     void testl_i32r(int imm, RegisterID dst)
       
   911     {
       
   912         m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
       
   913         m_formatter.immediate32(imm);
       
   914     }
       
   915 
       
   916     void testl_i32m(int imm, int offset, RegisterID base)
       
   917     {
       
   918         m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
       
   919         m_formatter.immediate32(imm);
       
   920     }
       
   921     
       
   922     void testb_im(int imm, int offset, RegisterID base)
       
   923     {
       
   924         m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
       
   925         m_formatter.immediate8(imm);
       
   926     }
       
   927     
       
   928     void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
       
   929     {
       
   930         m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
       
   931         m_formatter.immediate8(imm);
       
   932     }
       
   933 
       
   934     void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
       
   935     {
       
   936         m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
       
   937         m_formatter.immediate32(imm);
       
   938     }
       
   939 
       
   940 #if CPU(X86_64)
       
   941     void testq_rr(RegisterID src, RegisterID dst)
       
   942     {
       
   943         m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
       
   944     }
       
   945 
       
   946     void testq_i32r(int imm, RegisterID dst)
       
   947     {
       
   948         m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
       
   949         m_formatter.immediate32(imm);
       
   950     }
       
   951 
       
   952     void testq_i32m(int imm, int offset, RegisterID base)
       
   953     {
       
   954         m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
       
   955         m_formatter.immediate32(imm);
       
   956     }
       
   957 
       
   958     void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
       
   959     {
       
   960         m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
       
   961         m_formatter.immediate32(imm);
       
   962     }
       
   963 #endif 
       
   964 
       
   965     void testw_rr(RegisterID src, RegisterID dst)
       
   966     {
       
   967         m_formatter.prefix(PRE_OPERAND_SIZE);
       
   968         m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
       
   969     }
       
   970     
       
   971     void testb_i8r(int imm, RegisterID dst)
       
   972     {
       
   973         m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
       
   974         m_formatter.immediate8(imm);
       
   975     }
       
   976 
       
   977     void setCC_r(Condition cond, RegisterID dst)
       
   978     {
       
   979         m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
       
   980     }
       
   981 
       
   982     void sete_r(RegisterID dst)
       
   983     {
       
   984         m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
       
   985     }
       
   986 
       
   987     void setz_r(RegisterID dst)
       
   988     {
       
   989         sete_r(dst);
       
   990     }
       
   991 
       
   992     void setne_r(RegisterID dst)
       
   993     {
       
   994         m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
       
   995     }
       
   996 
       
   997     void setnz_r(RegisterID dst)
       
   998     {
       
   999         setne_r(dst);
       
  1000     }
       
  1001 
       
  1002     // Various move ops:
       
  1003 
       
  1004     void cdq()
       
  1005     {
       
  1006         m_formatter.oneByteOp(OP_CDQ);
       
  1007     }
       
  1008 
       
  1009     void xchgl_rr(RegisterID src, RegisterID dst)
       
  1010     {
       
  1011         m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
       
  1012     }
       
  1013 
       
  1014 #if CPU(X86_64)
       
  1015     void xchgq_rr(RegisterID src, RegisterID dst)
       
  1016     {
       
  1017         m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
       
  1018     }
       
  1019 #endif
       
  1020 
       
  1021     void movl_rr(RegisterID src, RegisterID dst)
       
  1022     {
       
  1023         m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
       
  1024     }
       
  1025     
       
  1026     void movl_rm(RegisterID src, int offset, RegisterID base)
       
  1027     {
       
  1028         m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
       
  1029     }
       
  1030 
       
  1031     void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
       
  1032     {
       
  1033         m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
       
  1034     }
       
  1035 
       
  1036     void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
       
  1037     {
       
  1038         m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
       
  1039     }
       
  1040     
       
  1041     void movl_mEAX(void* addr)
       
  1042     {
       
  1043         m_formatter.oneByteOp(OP_MOV_EAXOv);
       
  1044 #if CPU(X86_64)
       
  1045         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
       
  1046 #else
       
  1047         m_formatter.immediate32(reinterpret_cast<int>(addr));
       
  1048 #endif
       
  1049     }
       
  1050 
       
  1051     void movl_mr(int offset, RegisterID base, RegisterID dst)
       
  1052     {
       
  1053         m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
       
  1054     }
       
  1055 
       
  1056     void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
       
  1057     {
       
  1058         m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
       
  1059     }
       
  1060 
       
  1061     void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
       
  1062     {
       
  1063         m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
       
  1064     }
       
  1065 
       
  1066     void movl_i32r(int imm, RegisterID dst)
       
  1067     {
       
  1068         m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
       
  1069         m_formatter.immediate32(imm);
       
  1070     }
       
  1071 
       
  1072     void movl_i32m(int imm, int offset, RegisterID base)
       
  1073     {
       
  1074         m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
       
  1075         m_formatter.immediate32(imm);
       
  1076     }
       
  1077 
       
  1078     void movl_EAXm(void* addr)
       
  1079     {
       
  1080         m_formatter.oneByteOp(OP_MOV_OvEAX);
       
  1081 #if CPU(X86_64)
       
  1082         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
       
  1083 #else
       
  1084         m_formatter.immediate32(reinterpret_cast<int>(addr));
       
  1085 #endif
       
  1086     }
       
  1087 
       
  1088 #if CPU(X86_64)
       
  1089     void movq_rr(RegisterID src, RegisterID dst)
       
  1090     {
       
  1091         m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
       
  1092     }
       
  1093 
       
  1094     void movq_rm(RegisterID src, int offset, RegisterID base)
       
  1095     {
       
  1096         m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
       
  1097     }
       
  1098 
       
  1099     void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
       
  1100     {
       
  1101         m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
       
  1102     }
       
  1103 
       
  1104     void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
       
  1105     {
       
  1106         m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
       
  1107     }
       
  1108 
       
  1109     void movq_mEAX(void* addr)
       
  1110     {
       
  1111         m_formatter.oneByteOp64(OP_MOV_EAXOv);
       
  1112         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
       
  1113     }
       
  1114 
       
  1115     void movq_EAXm(void* addr)
       
  1116     {
       
  1117         m_formatter.oneByteOp64(OP_MOV_OvEAX);
       
  1118         m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
       
  1119     }
       
  1120 
       
  1121     void movq_mr(int offset, RegisterID base, RegisterID dst)
       
  1122     {
       
  1123         m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
       
  1124     }
       
  1125 
       
  1126     void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
       
  1127     {
       
  1128         m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
       
  1129     }
       
  1130 
       
  1131     void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
       
  1132     {
       
  1133         m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
       
  1134     }
       
  1135 
       
  1136     void movq_i32m(int imm, int offset, RegisterID base)
       
  1137     {
       
  1138         m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
       
  1139         m_formatter.immediate32(imm);
       
  1140     }
       
  1141 
       
  1142     void movq_i64r(int64_t imm, RegisterID dst)
       
  1143     {
       
  1144         m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
       
  1145         m_formatter.immediate64(imm);
       
  1146     }
       
  1147     
       
  1148     void movsxd_rr(RegisterID src, RegisterID dst)
       
  1149     {
       
  1150         m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
       
  1151     }
       
  1152     
       
  1153     
       
  1154 #else
       
  1155     void movl_rm(RegisterID src, void* addr)
       
  1156     {
       
  1157         if (src == X86Registers::eax)
       
  1158             movl_EAXm(addr);
       
  1159         else 
       
  1160             m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
       
  1161     }
       
  1162     
       
  1163     void movl_mr(void* addr, RegisterID dst)
       
  1164     {
       
  1165         if (dst == X86Registers::eax)
       
  1166             movl_mEAX(addr);
       
  1167         else
       
  1168             m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
       
  1169     }
       
  1170 
       
  1171     void movl_i32m(int imm, void* addr)
       
  1172     {
       
  1173         m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
       
  1174         m_formatter.immediate32(imm);
       
  1175     }
       
  1176 #endif
       
  1177 
       
  1178     void movzwl_mr(int offset, RegisterID base, RegisterID dst)
       
  1179     {
       
  1180         m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
       
  1181     }
       
  1182 
       
  1183     void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
       
  1184     {
       
  1185         m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
       
  1186     }
       
  1187 
       
  1188     void movzbl_rr(RegisterID src, RegisterID dst)
       
  1189     {
       
  1190         // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
       
  1191         // is in the range ESP-EDI, and the src would not have required a REX).  Unneeded
       
  1192         // REX prefixes are defined to be silently ignored by the processor.
       
  1193         m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
       
  1194     }
       
  1195 
       
  1196     void leal_mr(int offset, RegisterID base, RegisterID dst)
       
  1197     {
       
  1198         m_formatter.oneByteOp(OP_LEA, dst, base, offset);
       
  1199     }
       
  1200 #if CPU(X86_64)
       
  1201     void leaq_mr(int offset, RegisterID base, RegisterID dst)
       
  1202     {
       
  1203         m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
       
  1204     }
       
  1205 #endif
       
  1206 
       
  1207     // Flow control:
       
  1208 
       
  1209     JmpSrc call()
       
  1210     {
       
  1211         m_formatter.oneByteOp(OP_CALL_rel32);
       
  1212         return m_formatter.immediateRel32();
       
  1213     }
       
  1214     
       
  1215     JmpSrc call(RegisterID dst)
       
  1216     {
       
  1217         m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
       
  1218         return JmpSrc(m_formatter.size());
       
  1219     }
       
  1220     
       
  1221     void call_m(int offset, RegisterID base)
       
  1222     {
       
  1223         m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
       
  1224     }
       
  1225 
       
  1226     JmpSrc jmp()
       
  1227     {
       
  1228         m_formatter.oneByteOp(OP_JMP_rel32);
       
  1229         return m_formatter.immediateRel32();
       
  1230     }
       
  1231     
       
  1232     // Return a JmpSrc so we have a label to the jump, so we can use this
       
  1233     // To make a tail recursive call on x86-64.  The MacroAssembler
       
  1234     // really shouldn't wrap this as a Jump, since it can't be linked. :-/
       
  1235     JmpSrc jmp_r(RegisterID dst)
       
  1236     {
       
  1237         m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
       
  1238         return JmpSrc(m_formatter.size());
       
  1239     }
       
  1240     
       
  1241     void jmp_m(int offset, RegisterID base)
       
  1242     {
       
  1243         m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
       
  1244     }
       
  1245 
       
  1246     JmpSrc jne()
       
  1247     {
       
  1248         m_formatter.twoByteOp(jccRel32(ConditionNE));
       
  1249         return m_formatter.immediateRel32();
       
  1250     }
       
  1251     
       
  1252     JmpSrc jnz()
       
  1253     {
       
  1254         return jne();
       
  1255     }
       
  1256 
       
  1257     JmpSrc je()
       
  1258     {
       
  1259         m_formatter.twoByteOp(jccRel32(ConditionE));
       
  1260         return m_formatter.immediateRel32();
       
  1261     }
       
  1262     
       
  1263     JmpSrc jz()
       
  1264     {
       
  1265         return je();
       
  1266     }
       
  1267 
       
  1268     JmpSrc jl()
       
  1269     {
       
  1270         m_formatter.twoByteOp(jccRel32(ConditionL));
       
  1271         return m_formatter.immediateRel32();
       
  1272     }
       
  1273     
       
  1274     JmpSrc jb()
       
  1275     {
       
  1276         m_formatter.twoByteOp(jccRel32(ConditionB));
       
  1277         return m_formatter.immediateRel32();
       
  1278     }
       
  1279     
       
  1280     JmpSrc jle()
       
  1281     {
       
  1282         m_formatter.twoByteOp(jccRel32(ConditionLE));
       
  1283         return m_formatter.immediateRel32();
       
  1284     }
       
  1285     
       
  1286     JmpSrc jbe()
       
  1287     {
       
  1288         m_formatter.twoByteOp(jccRel32(ConditionBE));
       
  1289         return m_formatter.immediateRel32();
       
  1290     }
       
  1291     
       
  1292     JmpSrc jge()
       
  1293     {
       
  1294         m_formatter.twoByteOp(jccRel32(ConditionGE));
       
  1295         return m_formatter.immediateRel32();
       
  1296     }
       
  1297 
       
  1298     JmpSrc jg()
       
  1299     {
       
  1300         m_formatter.twoByteOp(jccRel32(ConditionG));
       
  1301         return m_formatter.immediateRel32();
       
  1302     }
       
  1303 
       
  1304     JmpSrc ja()
       
  1305     {
       
  1306         m_formatter.twoByteOp(jccRel32(ConditionA));
       
  1307         return m_formatter.immediateRel32();
       
  1308     }
       
  1309     
       
  1310     JmpSrc jae()
       
  1311     {
       
  1312         m_formatter.twoByteOp(jccRel32(ConditionAE));
       
  1313         return m_formatter.immediateRel32();
       
  1314     }
       
  1315     
       
  1316     JmpSrc jo()
       
  1317     {
       
  1318         m_formatter.twoByteOp(jccRel32(ConditionO));
       
  1319         return m_formatter.immediateRel32();
       
  1320     }
       
  1321 
       
  1322     JmpSrc jp()
       
  1323     {
       
  1324         m_formatter.twoByteOp(jccRel32(ConditionP));
       
  1325         return m_formatter.immediateRel32();
       
  1326     }
       
  1327     
       
  1328     JmpSrc js()
       
  1329     {
       
  1330         m_formatter.twoByteOp(jccRel32(ConditionS));
       
  1331         return m_formatter.immediateRel32();
       
  1332     }
       
  1333 
       
  1334     JmpSrc jCC(Condition cond)
       
  1335     {
       
  1336         m_formatter.twoByteOp(jccRel32(cond));
       
  1337         return m_formatter.immediateRel32();
       
  1338     }
       
  1339 
       
  1340     // SSE operations:
       
  1341 
       
  1342     void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
       
  1343     {
       
  1344         m_formatter.prefix(PRE_SSE_F2);
       
  1345         m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
       
  1346     }
       
  1347 
       
  1348     void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
       
  1349     {
       
  1350         m_formatter.prefix(PRE_SSE_F2);
       
  1351         m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
       
  1352     }
       
  1353 
       
  1354     void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
       
  1355     {
       
  1356         m_formatter.prefix(PRE_SSE_F2);
       
  1357         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
       
  1358     }
       
  1359 
       
  1360     void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
       
  1361     {
       
  1362         m_formatter.prefix(PRE_SSE_F2);
       
  1363         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
       
  1364     }
       
  1365 
       
  1366 #if !CPU(X86_64)
       
  1367     void cvtsi2sd_mr(void* address, XMMRegisterID dst)
       
  1368     {
       
  1369         m_formatter.prefix(PRE_SSE_F2);
       
  1370         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
       
  1371     }
       
  1372 #endif
       
  1373 
       
  1374     void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
       
  1375     {
       
  1376         m_formatter.prefix(PRE_SSE_F2);
       
  1377         m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
       
  1378     }
       
  1379 
       
  1380     void movd_rr(XMMRegisterID src, RegisterID dst)
       
  1381     {
       
  1382         m_formatter.prefix(PRE_SSE_66);
       
  1383         m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
       
  1384     }
       
  1385 
       
  1386 #if CPU(X86_64)
       
  1387     void movq_rr(XMMRegisterID src, RegisterID dst)
       
  1388     {
       
  1389         m_formatter.prefix(PRE_SSE_66);
       
  1390         m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
       
  1391     }
       
  1392 
       
  1393     void movq_rr(RegisterID src, XMMRegisterID dst)
       
  1394     {
       
  1395         m_formatter.prefix(PRE_SSE_66);
       
  1396         m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
       
  1397     }
       
  1398 #endif
       
  1399 
       
  1400     void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
       
  1401     {
       
  1402         m_formatter.prefix(PRE_SSE_F2);
       
  1403         m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
       
  1404     }
       
  1405 
       
  1406     void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
       
  1407     {
       
  1408         m_formatter.prefix(PRE_SSE_F2);
       
  1409         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
       
  1410     }
       
  1411 
       
  1412 #if !CPU(X86_64)
       
  1413     void movsd_mr(const void* address, XMMRegisterID dst)
       
  1414     {
       
  1415         m_formatter.prefix(PRE_SSE_F2);
       
  1416         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
       
  1417     }
       
  1418 #endif
       
  1419 
       
  1420     void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
       
  1421     {
       
  1422         m_formatter.prefix(PRE_SSE_F2);
       
  1423         m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
       
  1424     }
       
  1425 
       
  1426     void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
       
  1427     {
       
  1428         m_formatter.prefix(PRE_SSE_F2);
       
  1429         m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
       
  1430     }
       
  1431 
       
  1432     void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
       
  1433     {
       
  1434         m_formatter.prefix(PRE_SSE_66);
       
  1435         m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
       
  1436         m_formatter.immediate8(whichWord);
       
  1437     }
       
  1438 
       
  1439     void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
       
  1440     {
       
  1441         m_formatter.prefix(PRE_SSE_F2);
       
  1442         m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
       
  1443     }
       
  1444 
       
  1445     void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
       
  1446     {
       
  1447         m_formatter.prefix(PRE_SSE_F2);
       
  1448         m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
       
  1449     }
       
  1450 
       
  1451     void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
       
  1452     {
       
  1453         m_formatter.prefix(PRE_SSE_66);
       
  1454         m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
       
  1455     }
       
  1456 
       
  1457     void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
       
  1458     {
       
  1459         m_formatter.prefix(PRE_SSE_66);
       
  1460         m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
       
  1461     }
       
  1462 
       
  1463     void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
       
  1464     {
       
  1465         m_formatter.prefix(PRE_SSE_F2);
       
  1466         m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
       
  1467     }
       
  1468 
       
  1469     void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
       
  1470     {
       
  1471         m_formatter.prefix(PRE_SSE_F2);
       
  1472         m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
       
  1473     }
       
  1474 
       
  1475     void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
       
  1476     {
       
  1477         m_formatter.prefix(PRE_SSE_66);
       
  1478         m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
       
  1479     }
       
  1480 
       
  1481     void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
       
  1482     {
       
  1483         m_formatter.prefix(PRE_SSE_F2);
       
  1484         m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
       
  1485     }
       
  1486 
       
  1487     // Misc instructions:
       
  1488 
       
  1489     void int3()
       
  1490     {
       
  1491         m_formatter.oneByteOp(OP_INT3);
       
  1492     }
       
  1493     
       
  1494     void ret()
       
  1495     {
       
  1496         m_formatter.oneByteOp(OP_RET);
       
  1497     }
       
  1498 
       
  1499     void predictNotTaken()
       
  1500     {
       
  1501         m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
       
  1502     }
       
  1503 
       
  1504     // Assembler admin methods:
       
  1505 
       
  1506     JmpDst label()
       
  1507     {
       
  1508         return JmpDst(m_formatter.size());
       
  1509     }
       
  1510     
       
  1511     static JmpDst labelFor(JmpSrc jump, intptr_t offset = 0)
       
  1512     {
       
  1513         return JmpDst(jump.m_offset + offset);
       
  1514     }
       
  1515     
       
  1516     JmpDst align(int alignment)
       
  1517     {
       
  1518         while (!m_formatter.isAligned(alignment))
       
  1519             m_formatter.oneByteOp(OP_HLT);
       
  1520 
       
  1521         return label();
       
  1522     }
       
  1523 
       
  1524     // Linking & patching:
       
  1525     //
       
  1526     // 'link' and 'patch' methods are for use on unprotected code - such as the code
       
  1527     // within the AssemblerBuffer, and code being patched by the patch buffer.  Once
       
  1528     // code has been finalized it is (platform support permitting) within a non-
       
  1529     // writable region of memory; to modify the code in an execute-only execuable
       
  1530     // pool the 'repatch' and 'relink' methods should be used.
       
  1531 
       
  1532     void linkJump(JmpSrc from, JmpDst to)
       
  1533     {
       
  1534         ASSERT(from.m_offset != -1);
       
  1535         ASSERT(to.m_offset != -1);
       
  1536 
       
  1537         char* code = reinterpret_cast<char*>(m_formatter.data());
       
  1538         setRel32(code + from.m_offset, code + to.m_offset);
       
  1539     }
       
  1540     
       
  1541     static void linkJump(void* code, JmpSrc from, void* to)
       
  1542     {
       
  1543         ASSERT(from.m_offset != -1);
       
  1544 
       
  1545         setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
       
  1546     }
       
  1547 
       
  1548     static void linkCall(void* code, JmpSrc from, void* to)
       
  1549     {
       
  1550         ASSERT(from.m_offset != -1);
       
  1551 
       
  1552         setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
       
  1553     }
       
  1554 
       
  1555     static void linkPointer(void* code, JmpDst where, void* value)
       
  1556     {
       
  1557         ASSERT(where.m_offset != -1);
       
  1558 
       
  1559         setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
       
  1560     }
       
  1561 
       
  1562     static void relinkJump(void* from, void* to)
       
  1563     {
       
  1564         setRel32(from, to);
       
  1565     }
       
  1566     
       
  1567     static void relinkCall(void* from, void* to)
       
  1568     {
       
  1569         setRel32(from, to);
       
  1570     }
       
  1571 
       
  1572     static void repatchInt32(void* where, int32_t value)
       
  1573     {
       
  1574         setInt32(where, value);
       
  1575     }
       
  1576 
       
  1577     static void repatchPointer(void* where, void* value)
       
  1578     {
       
  1579         setPointer(where, value);
       
  1580     }
       
  1581 
       
  1582     static void repatchLoadPtrToLEA(void* where)
       
  1583     {
       
  1584 #if CPU(X86_64)
       
  1585         // On x86-64 pointer memory accesses require a 64-bit operand, and as such a REX prefix.
       
  1586         // Skip over the prefix byte.
       
  1587         where = reinterpret_cast<char*>(where) + 1;
       
  1588 #endif
       
  1589         *reinterpret_cast<unsigned char*>(where) = static_cast<unsigned char>(OP_LEA);
       
  1590     }
       
  1591     
       
  1592     static unsigned getCallReturnOffset(JmpSrc call)
       
  1593     {
       
  1594         ASSERT(call.m_offset >= 0);
       
  1595         return call.m_offset;
       
  1596     }
       
  1597 
       
  1598     static void* getRelocatedAddress(void* code, JmpSrc jump)
       
  1599     {
       
  1600         ASSERT(jump.m_offset != -1);
       
  1601 
       
  1602         return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
       
  1603     }
       
  1604     
       
  1605     static void* getRelocatedAddress(void* code, JmpDst destination)
       
  1606     {
       
  1607         ASSERT(destination.m_offset != -1);
       
  1608 
       
  1609         return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset);
       
  1610     }
       
  1611     
       
  1612     static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
       
  1613     {
       
  1614         return dst.m_offset - src.m_offset;
       
  1615     }
       
  1616     
       
  1617     static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
       
  1618     {
       
  1619         return dst.m_offset - src.m_offset;
       
  1620     }
       
  1621     
       
  1622     static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
       
  1623     {
       
  1624         return dst.m_offset - src.m_offset;
       
  1625     }
       
  1626     
       
  1627     void* executableCopy(ExecutablePool* allocator)
       
  1628     {
       
  1629         void* copy = m_formatter.executableCopy(allocator);
       
  1630         ASSERT(copy);
       
  1631         return copy;
       
  1632     }
       
  1633 
       
  1634 private:
       
  1635 
       
  1636     static void setPointer(void* where, void* value)
       
  1637     {
       
  1638         reinterpret_cast<void**>(where)[-1] = value;
       
  1639     }
       
  1640 
       
  1641     static void setInt32(void* where, int32_t value)
       
  1642     {
       
  1643         reinterpret_cast<int32_t*>(where)[-1] = value;
       
  1644     }
       
  1645 
       
  1646     static void setRel32(void* from, void* to)
       
  1647     {
       
  1648         intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
       
  1649         ASSERT(offset == static_cast<int32_t>(offset));
       
  1650 
       
  1651         setInt32(from, offset);
       
  1652     }
       
  1653 
       
  1654     class X86InstructionFormatter {
       
  1655 
       
  1656         static const int maxInstructionSize = 16;
       
  1657 
       
  1658     public:
       
  1659 
       
  1660         // Legacy prefix bytes:
       
  1661         //
       
  1662         // These are emmitted prior to the instruction.
       
  1663 
       
  1664         void prefix(OneByteOpcodeID pre)
       
  1665         {
       
  1666             m_buffer.putByte(pre);
       
  1667         }
       
  1668 
       
  1669         // Word-sized operands / no operand instruction formatters.
       
  1670         //
       
  1671         // In addition to the opcode, the following operand permutations are supported:
       
  1672         //   * None - instruction takes no operands.
       
  1673         //   * One register - the low three bits of the RegisterID are added into the opcode.
       
  1674         //   * Two registers - encode a register form ModRm (for all ModRm formats, the reg field is passed first, and a GroupOpcodeID may be passed in its place).
       
  1675         //   * Three argument ModRM - a register, and a register and an offset describing a memory operand.
       
  1676         //   * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
       
  1677         //
       
  1678         // For 32-bit x86 targets, the address operand may also be provided as a void*.
       
  1679         // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
       
  1680         //
       
  1681         // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
       
  1682 
       
  1683         void oneByteOp(OneByteOpcodeID opcode)
       
  1684         {
       
  1685             m_buffer.ensureSpace(maxInstructionSize);
       
  1686             m_buffer.putByteUnchecked(opcode);
       
  1687         }
       
  1688 
       
  1689         void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
       
  1690         {
       
  1691             m_buffer.ensureSpace(maxInstructionSize);
       
  1692             emitRexIfNeeded(0, 0, reg);
       
  1693             m_buffer.putByteUnchecked(opcode + (reg & 7));
       
  1694         }
       
  1695 
       
  1696         void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
       
  1697         {
       
  1698             m_buffer.ensureSpace(maxInstructionSize);
       
  1699             emitRexIfNeeded(reg, 0, rm);
       
  1700             m_buffer.putByteUnchecked(opcode);
       
  1701             registerModRM(reg, rm);
       
  1702         }
       
  1703 
       
  1704         void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
       
  1705         {
       
  1706             m_buffer.ensureSpace(maxInstructionSize);
       
  1707             emitRexIfNeeded(reg, 0, base);
       
  1708             m_buffer.putByteUnchecked(opcode);
       
  1709             memoryModRM(reg, base, offset);
       
  1710         }
       
  1711 
       
  1712         void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
       
  1713         {
       
  1714             m_buffer.ensureSpace(maxInstructionSize);
       
  1715             emitRexIfNeeded(reg, 0, base);
       
  1716             m_buffer.putByteUnchecked(opcode);
       
  1717             memoryModRM_disp32(reg, base, offset);
       
  1718         }
       
  1719 
       
  1720         void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
       
  1721         {
       
  1722             m_buffer.ensureSpace(maxInstructionSize);
       
  1723             emitRexIfNeeded(reg, index, base);
       
  1724             m_buffer.putByteUnchecked(opcode);
       
  1725             memoryModRM(reg, base, index, scale, offset);
       
  1726         }
       
  1727 
       
  1728 #if !CPU(X86_64)
       
  1729         void oneByteOp(OneByteOpcodeID opcode, int reg, void* address)
       
  1730         {
       
  1731             m_buffer.ensureSpace(maxInstructionSize);
       
  1732             m_buffer.putByteUnchecked(opcode);
       
  1733             memoryModRM(reg, address);
       
  1734         }
       
  1735 #endif
       
  1736 
       
  1737         void twoByteOp(TwoByteOpcodeID opcode)
       
  1738         {
       
  1739             m_buffer.ensureSpace(maxInstructionSize);
       
  1740             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
       
  1741             m_buffer.putByteUnchecked(opcode);
       
  1742         }
       
  1743 
       
  1744         void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
       
  1745         {
       
  1746             m_buffer.ensureSpace(maxInstructionSize);
       
  1747             emitRexIfNeeded(reg, 0, rm);
       
  1748             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
       
  1749             m_buffer.putByteUnchecked(opcode);
       
  1750             registerModRM(reg, rm);
       
  1751         }
       
  1752 
       
  1753         void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
       
  1754         {
       
  1755             m_buffer.ensureSpace(maxInstructionSize);
       
  1756             emitRexIfNeeded(reg, 0, base);
       
  1757             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
       
  1758             m_buffer.putByteUnchecked(opcode);
       
  1759             memoryModRM(reg, base, offset);
       
  1760         }
       
  1761 
       
  1762         void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
       
  1763         {
       
  1764             m_buffer.ensureSpace(maxInstructionSize);
       
  1765             emitRexIfNeeded(reg, index, base);
       
  1766             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
       
  1767             m_buffer.putByteUnchecked(opcode);
       
  1768             memoryModRM(reg, base, index, scale, offset);
       
  1769         }
       
  1770 
       
  1771 #if !CPU(X86_64)
       
  1772         void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
       
  1773         {
       
  1774             m_buffer.ensureSpace(maxInstructionSize);
       
  1775             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
       
  1776             m_buffer.putByteUnchecked(opcode);
       
  1777             memoryModRM(reg, address);
       
  1778         }
       
  1779 #endif
       
  1780 
       
  1781 #if CPU(X86_64)
       
  1782         // Quad-word-sized operands:
       
  1783         //
       
  1784         // Used to format 64-bit operantions, planting a REX.w prefix.
       
  1785         // When planting d64 or f64 instructions, not requiring a REX.w prefix,
       
  1786         // the normal (non-'64'-postfixed) formatters should be used.
       
  1787 
       
  1788         void oneByteOp64(OneByteOpcodeID opcode)
       
  1789         {
       
  1790             m_buffer.ensureSpace(maxInstructionSize);
       
  1791             emitRexW(0, 0, 0);
       
  1792             m_buffer.putByteUnchecked(opcode);
       
  1793         }
       
  1794 
       
  1795         void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
       
  1796         {
       
  1797             m_buffer.ensureSpace(maxInstructionSize);
       
  1798             emitRexW(0, 0, reg);
       
  1799             m_buffer.putByteUnchecked(opcode + (reg & 7));
       
  1800         }
       
  1801 
       
  1802         void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
       
  1803         {
       
  1804             m_buffer.ensureSpace(maxInstructionSize);
       
  1805             emitRexW(reg, 0, rm);
       
  1806             m_buffer.putByteUnchecked(opcode);
       
  1807             registerModRM(reg, rm);
       
  1808         }
       
  1809 
       
  1810         void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
       
  1811         {
       
  1812             m_buffer.ensureSpace(maxInstructionSize);
       
  1813             emitRexW(reg, 0, base);
       
  1814             m_buffer.putByteUnchecked(opcode);
       
  1815             memoryModRM(reg, base, offset);
       
  1816         }
       
  1817 
       
  1818         void oneByteOp64_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
       
  1819         {
       
  1820             m_buffer.ensureSpace(maxInstructionSize);
       
  1821             emitRexW(reg, 0, base);
       
  1822             m_buffer.putByteUnchecked(opcode);
       
  1823             memoryModRM_disp32(reg, base, offset);
       
  1824         }
       
  1825 
       
  1826         void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
       
  1827         {
       
  1828             m_buffer.ensureSpace(maxInstructionSize);
       
  1829             emitRexW(reg, index, base);
       
  1830             m_buffer.putByteUnchecked(opcode);
       
  1831             memoryModRM(reg, base, index, scale, offset);
       
  1832         }
       
  1833 
       
  1834         void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
       
  1835         {
       
  1836             m_buffer.ensureSpace(maxInstructionSize);
       
  1837             emitRexW(reg, 0, rm);
       
  1838             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
       
  1839             m_buffer.putByteUnchecked(opcode);
       
  1840             registerModRM(reg, rm);
       
  1841         }
       
  1842 #endif
       
  1843 
       
  1844         // Byte-operands:
       
  1845         //
       
  1846         // These methods format byte operations.  Byte operations differ from the normal
       
  1847         // formatters in the circumstances under which they will decide to emit REX prefixes.
       
  1848         // These should be used where any register operand signifies a byte register.
       
  1849         //
       
  1850         // The disctinction is due to the handling of register numbers in the range 4..7 on
       
  1851         // x86-64.  These register numbers may either represent the second byte of the first
       
  1852         // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
       
  1853         //
       
  1854         // Since ah..bh cannot be used in all permutations of operands (specifically cannot
       
  1855         // be accessed where a REX prefix is present), these are likely best treated as
       
  1856         // deprecated.  In order to ensure the correct registers spl..dil are selected a
       
  1857         // REX prefix will be emitted for any byte register operand in the range 4..15.
       
  1858         //
       
  1859         // These formatters may be used in instructions where a mix of operand sizes, in which
       
  1860         // case an unnecessary REX will be emitted, for example:
       
  1861         //     movzbl %al, %edi
       
  1862         // In this case a REX will be planted since edi is 7 (and were this a byte operand
       
  1863         // a REX would be required to specify dil instead of bh).  Unneeded REX prefixes will
       
  1864         // be silently ignored by the processor.
       
  1865         //
       
  1866         // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
       
  1867         // is provided to check byte register operands.
       
  1868 
       
  1869         void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
       
  1870         {
       
  1871             m_buffer.ensureSpace(maxInstructionSize);
       
  1872             emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
       
  1873             m_buffer.putByteUnchecked(opcode);
       
  1874             registerModRM(groupOp, rm);
       
  1875         }
       
  1876 
       
  1877         void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
       
  1878         {
       
  1879             m_buffer.ensureSpace(maxInstructionSize);
       
  1880             emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
       
  1881             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
       
  1882             m_buffer.putByteUnchecked(opcode);
       
  1883             registerModRM(reg, rm);
       
  1884         }
       
  1885 
       
  1886         void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
       
  1887         {
       
  1888             m_buffer.ensureSpace(maxInstructionSize);
       
  1889             emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
       
  1890             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
       
  1891             m_buffer.putByteUnchecked(opcode);
       
  1892             registerModRM(groupOp, rm);
       
  1893         }
       
  1894 
       
  1895         // Immediates:
       
  1896         //
       
  1897         // An immedaite should be appended where appropriate after an op has been emitted.
       
  1898         // The writes are unchecked since the opcode formatters above will have ensured space.
       
  1899 
       
  1900         void immediate8(int imm)
       
  1901         {
       
  1902             m_buffer.putByteUnchecked(imm);
       
  1903         }
       
  1904 
       
  1905         void immediate16(int imm)
       
  1906         {
       
  1907             m_buffer.putShortUnchecked(imm);
       
  1908         }
       
  1909 
       
  1910         void immediate32(int imm)
       
  1911         {
       
  1912             m_buffer.putIntUnchecked(imm);
       
  1913         }
       
  1914 
       
  1915         void immediate64(int64_t imm)
       
  1916         {
       
  1917             m_buffer.putInt64Unchecked(imm);
       
  1918         }
       
  1919 
       
  1920         JmpSrc immediateRel32()
       
  1921         {
       
  1922             m_buffer.putIntUnchecked(0);
       
  1923             return JmpSrc(m_buffer.size());
       
  1924         }
       
  1925 
       
  1926         // Administrative methods:
       
  1927 
       
  1928         size_t size() const { return m_buffer.size(); }
       
  1929         bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
       
  1930         void* data() const { return m_buffer.data(); }
       
  1931         void* executableCopy(ExecutablePool* allocator) { return m_buffer.executableCopy(allocator); }
       
  1932 
       
  1933     private:
       
  1934 
       
  1935         // Internals; ModRm and REX formatters.
       
  1936 
       
  1937         static const RegisterID noBase = X86Registers::ebp;
       
  1938         static const RegisterID hasSib = X86Registers::esp;
       
  1939         static const RegisterID noIndex = X86Registers::esp;
       
  1940 #if CPU(X86_64)
       
  1941         static const RegisterID noBase2 = X86Registers::r13;
       
  1942         static const RegisterID hasSib2 = X86Registers::r12;
       
  1943 
       
  1944         // Registers r8 & above require a REX prefixe.
       
  1945         inline bool regRequiresRex(int reg)
       
  1946         {
       
  1947             return (reg >= X86Registers::r8);
       
  1948         }
       
  1949 
       
  1950         // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
       
  1951         inline bool byteRegRequiresRex(int reg)
       
  1952         {
       
  1953             return (reg >= X86Registers::esp);
       
  1954         }
       
  1955 
       
  1956         // Format a REX prefix byte.
       
  1957         inline void emitRex(bool w, int r, int x, int b)
       
  1958         {
       
  1959             m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
       
  1960         }
       
  1961 
       
  1962         // Used to plant a REX byte with REX.w set (for 64-bit operations).
       
  1963         inline void emitRexW(int r, int x, int b)
       
  1964         {
       
  1965             emitRex(true, r, x, b);
       
  1966         }
       
  1967 
       
  1968         // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
       
  1969         // regRequiresRex() to check other registers (i.e. address base & index).
       
  1970         inline void emitRexIf(bool condition, int r, int x, int b)
       
  1971         {
       
  1972             if (condition) emitRex(false, r, x, b);
       
  1973         }
       
  1974 
       
  1975         // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
       
  1976         inline void emitRexIfNeeded(int r, int x, int b)
       
  1977         {
       
  1978             emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b);
       
  1979         }
       
  1980 #else
       
  1981         // No REX prefix bytes on 32-bit x86.
       
  1982         inline bool regRequiresRex(int) { return false; }
       
  1983         inline bool byteRegRequiresRex(int) { return false; }
       
  1984         inline void emitRexIf(bool, int, int, int) {}
       
  1985         inline void emitRexIfNeeded(int, int, int) {}
       
  1986 #endif
       
  1987 
       
  1988         enum ModRmMode {
       
  1989             ModRmMemoryNoDisp,
       
  1990             ModRmMemoryDisp8,
       
  1991             ModRmMemoryDisp32,
       
  1992             ModRmRegister,
       
  1993         };
       
  1994 
       
  1995         void putModRm(ModRmMode mode, int reg, RegisterID rm)
       
  1996         {
       
  1997             m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
       
  1998         }
       
  1999 
       
  2000         void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
       
  2001         {
       
  2002             ASSERT(mode != ModRmRegister);
       
  2003 
       
  2004             putModRm(mode, reg, hasSib);
       
  2005             m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
       
  2006         }
       
  2007 
       
  2008         void registerModRM(int reg, RegisterID rm)
       
  2009         {
       
  2010             putModRm(ModRmRegister, reg, rm);
       
  2011         }
       
  2012 
       
  2013         void memoryModRM(int reg, RegisterID base, int offset)
       
  2014         {
       
  2015             // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
       
  2016 #if CPU(X86_64)
       
  2017             if ((base == hasSib) || (base == hasSib2)) {
       
  2018 #else
       
  2019             if (base == hasSib) {
       
  2020 #endif
       
  2021                 if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
       
  2022                     putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
       
  2023                 else if (CAN_SIGN_EXTEND_8_32(offset)) {
       
  2024                     putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
       
  2025                     m_buffer.putByteUnchecked(offset);
       
  2026                 } else {
       
  2027                     putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
       
  2028                     m_buffer.putIntUnchecked(offset);
       
  2029                 }
       
  2030             } else {
       
  2031 #if CPU(X86_64)
       
  2032                 if (!offset && (base != noBase) && (base != noBase2))
       
  2033 #else
       
  2034                 if (!offset && (base != noBase))
       
  2035 #endif
       
  2036                     putModRm(ModRmMemoryNoDisp, reg, base);
       
  2037                 else if (CAN_SIGN_EXTEND_8_32(offset)) {
       
  2038                     putModRm(ModRmMemoryDisp8, reg, base);
       
  2039                     m_buffer.putByteUnchecked(offset);
       
  2040                 } else {
       
  2041                     putModRm(ModRmMemoryDisp32, reg, base);
       
  2042                     m_buffer.putIntUnchecked(offset);
       
  2043                 }
       
  2044             }
       
  2045         }
       
  2046     
       
  2047         void memoryModRM_disp32(int reg, RegisterID base, int offset)
       
  2048         {
       
  2049             // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
       
  2050 #if CPU(X86_64)
       
  2051             if ((base == hasSib) || (base == hasSib2)) {
       
  2052 #else
       
  2053             if (base == hasSib) {
       
  2054 #endif
       
  2055                 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
       
  2056                 m_buffer.putIntUnchecked(offset);
       
  2057             } else {
       
  2058                 putModRm(ModRmMemoryDisp32, reg, base);
       
  2059                 m_buffer.putIntUnchecked(offset);
       
  2060             }
       
  2061         }
       
  2062     
       
  2063         void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
       
  2064         {
       
  2065             ASSERT(index != noIndex);
       
  2066 
       
  2067 #if CPU(X86_64)
       
  2068             if (!offset && (base != noBase) && (base != noBase2))
       
  2069 #else
       
  2070             if (!offset && (base != noBase))
       
  2071 #endif
       
  2072                 putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
       
  2073             else if (CAN_SIGN_EXTEND_8_32(offset)) {
       
  2074                 putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
       
  2075                 m_buffer.putByteUnchecked(offset);
       
  2076             } else {
       
  2077                 putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
       
  2078                 m_buffer.putIntUnchecked(offset);
       
  2079             }
       
  2080         }
       
  2081 
       
  2082 #if !CPU(X86_64)
       
  2083         void memoryModRM(int reg, const void* address)
       
  2084         {
       
  2085             // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
       
  2086             putModRm(ModRmMemoryNoDisp, reg, noBase);
       
  2087             m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address));
       
  2088         }
       
  2089 #endif
       
  2090 
       
  2091         AssemblerBuffer m_buffer;
       
  2092     } m_formatter;
       
  2093 };
       
  2094 
       
  2095 } // namespace JSC
       
  2096 
       
  2097 #endif // ENABLE(ASSEMBLER) && CPU(X86)
       
  2098 
       
  2099 #endif // X86Assembler_h