Changeset 38487 in webkit for trunk/JavaScriptCore


Ignore:
Timestamp:
Nov 16, 2008, 10:27:06 PM (17 years ago)
Author:
[email protected]
Message:

2008-11-16 Geoffrey Garen <[email protected]>

Reviewed by Sam Weinig.


Moved masm => assembler and split "AssemblerBuffer.h" out of "X86Assembler.h".


Also renamed ENABLE_MASM to ENABLE_ASSEMBLER.

  • GNUmakefile.am:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler: Added.
  • assembler/AssemblerBuffer.h: Copied from masm/X86Assembler.h. (JSC::AssemblerBuffer::AssemblerBuffer): (JSC::AssemblerBuffer::~AssemblerBuffer): (JSC::AssemblerBuffer::ensureSpace): (JSC::AssemblerBuffer::isAligned): (JSC::AssemblerBuffer::putByteUnchecked): (JSC::AssemblerBuffer::putByte): (JSC::AssemblerBuffer::putShortUnchecked): (JSC::AssemblerBuffer::putShort): (JSC::AssemblerBuffer::putIntUnchecked): (JSC::AssemblerBuffer::putInt): (JSC::AssemblerBuffer::data): (JSC::AssemblerBuffer::size): (JSC::AssemblerBuffer::reset): (JSC::AssemblerBuffer::executableCopy): (JSC::AssemblerBuffer::grow):
  • assembler/X86Assembler.h: Copied from masm/X86Assembler.h.
  • masm: Removed.
  • masm/X86Assembler.h: Removed.
  • wtf/Platform.h:
Location:
trunk/JavaScriptCore
Files:
1 added
1 deleted
4 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r38482 r38487  
     12008-11-16  Geoffrey Garen  <[email protected]>
     2
     3        Reviewed by Sam Weinig.
     4       
     5        Moved masm => assembler and split "AssemblerBuffer.h" out of "X86Assembler.h".
     6       
     7        Also renamed ENABLE_MASM to ENABLE_ASSEMBLER.
     8
     9        * GNUmakefile.am:
     10        * JavaScriptCore.xcodeproj/project.pbxproj:
     11        * assembler: Added.
     12        * assembler/AssemblerBuffer.h: Copied from masm/X86Assembler.h.
     13        (JSC::AssemblerBuffer::AssemblerBuffer):
     14        (JSC::AssemblerBuffer::~AssemblerBuffer):
     15        (JSC::AssemblerBuffer::ensureSpace):
     16        (JSC::AssemblerBuffer::isAligned):
     17        (JSC::AssemblerBuffer::putByteUnchecked):
     18        (JSC::AssemblerBuffer::putByte):
     19        (JSC::AssemblerBuffer::putShortUnchecked):
     20        (JSC::AssemblerBuffer::putShort):
     21        (JSC::AssemblerBuffer::putIntUnchecked):
     22        (JSC::AssemblerBuffer::putInt):
     23        (JSC::AssemblerBuffer::data):
     24        (JSC::AssemblerBuffer::size):
     25        (JSC::AssemblerBuffer::reset):
     26        (JSC::AssemblerBuffer::executableCopy):
     27        (JSC::AssemblerBuffer::grow):
     28        * assembler/X86Assembler.h: Copied from masm/X86Assembler.h.
     29        * masm: Removed.
     30        * masm/X86Assembler.h: Removed.
     31        * wtf/Platform.h:
     32
    1332008-11-16  Geoffrey Garen  <[email protected]>
    234
  • trunk/JavaScriptCore/GNUmakefile.am

    r38482 r38487  
    99        -I$(srcdir)/JavaScriptCore/runtime \
    1010        -I$(srcdir)/JavaScriptCore/wrec \
    11         -I$(srcdir)/JavaScriptCore/masm \
     11        -I$(srcdir)/JavaScriptCore/assembler \
    1212        -I$(srcdir)/JavaScriptCore/wtf/unicode \
    1313        -I$(top_builddir)/JavaScriptCore/pcre \
     
    114114        JavaScriptCore/icu/unicode/utypes.h \
    115115        JavaScriptCore/icu/unicode/uversion.h \
    116         JavaScriptCore/masm/X86Assembler.h \
     116        JavaScriptCore/assembler/X86Assembler.h \
     117        JavaScriptCore/assembler/AssemblerBuffer.h \
    117118        JavaScriptCore/os-win32/stdbool.h \
    118119        JavaScriptCore/os-win32/stdint.h \
  • trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r38440 r38487  
    9191                8683B02E0E636482004C19EE /* CTI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8683B02B0E636482004C19EE /* CTI.cpp */; };
    9292                8683B02F0E636482004C19EE /* CTI.h in Headers */ = {isa = PBXBuildFile; fileRef = 8683B02C0E636482004C19EE /* CTI.h */; settings = {ATTRIBUTES = (Private, ); }; };
    93                 869081410E640C89000D36ED /* X86Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 869081400E640C89000D36ED /* X86Assembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
    9493                869083150E6518D7000D36ED /* WREC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 869083130E6518D7000D36ED /* WREC.cpp */; };
    9594                869083160E6518D7000D36ED /* WREC.h in Headers */ = {isa = PBXBuildFile; fileRef = 869083140E6518D7000D36ED /* WREC.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    124123                95FDFA160E2299980006FB00 /* HeavyProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 95FDFA150E2299980006FB00 /* HeavyProfile.h */; };
    125124                960097A60EBABB58007A7297 /* LabelScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 960097A50EBABB58007A7297 /* LabelScope.h */; };
     125                9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */; };
     126                9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 9688CB140ED12B4E001D649F /* X86Assembler.h */; };
    126127                A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; };
    127128                A72701B60DADE94900E548D7 /* ExceptionHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72701B40DADE94900E548D7 /* ExceptionHelpers.cpp */; };
     
    535536                8683B02B0E636482004C19EE /* CTI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CTI.cpp; path = VM/CTI.cpp; sourceTree = "<group>"; };
    536537                8683B02C0E636482004C19EE /* CTI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CTI.h; path = VM/CTI.h; sourceTree = "<group>"; };
    537                 869081400E640C89000D36ED /* X86Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86Assembler.h; sourceTree = "<group>"; };
    538538                869083130E6518D7000D36ED /* WREC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WREC.cpp; sourceTree = "<group>"; };
    539539                869083140E6518D7000D36ED /* WREC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WREC.h; sourceTree = "<group>"; };
     
    592592                95FDFA150E2299980006FB00 /* HeavyProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HeavyProfile.h; path = profiler/HeavyProfile.h; sourceTree = "<group>"; };
    593593                960097A50EBABB58007A7297 /* LabelScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelScope.h; sourceTree = "<group>"; };
     594                9688CB130ED12B4E001D649F /* AssemblerBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerBuffer.h; sourceTree = "<group>"; };
     595                9688CB140ED12B4E001D649F /* X86Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86Assembler.h; sourceTree = "<group>"; };
    594596                A72700770DAC605600E548D7 /* JSNotAnObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNotAnObject.h; sourceTree = "<group>"; };
    595597                A72700780DAC605600E548D7 /* JSNotAnObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNotAnObject.cpp; sourceTree = "<group>"; };
     
    826828                                F68EBB8C0255D4C601FF60F7 /* config.h */,
    827829                                1432EBD70A34CAD400717B9F /* API */,
     830                                9688CB120ED12B4E001D649F /* assembler */,
    828831                                7E39D81D0EC38EFA003AF11A /* bytecompiler */,
    829832                                149B15DF0D81F887009CB8C7 /* compiler */,
    830833                                1480DB9A0DDC2231003CFDF2 /* debugger */,
    831                                 8690813F0E640C89000D36ED /* masm */,
    832834                                7E39D8370EC3A388003AF11A /* parser */,
    833835                                65417203039E01F90058BFEB /* pcre */,
     
    12881290                        sourceTree = "<group>";
    12891291                };
    1290                 8690813F0E640C89000D36ED /* masm */ = {
    1291                         isa = PBXGroup;
    1292                         children = (
    1293                                 869081400E640C89000D36ED /* X86Assembler.h */,
    1294                         );
    1295                         path = masm;
    1296                         sourceTree = "<group>";
    1297                 };
    12981292                869083120E6518D7000D36ED /* wrec */ = {
    12991293                        isa = PBXGroup;
     
    13391333                        sourceTree = "<group>";
    13401334                        usesTabs = 0;
     1335                };
     1336                9688CB120ED12B4E001D649F /* assembler */ = {
     1337                        isa = PBXGroup;
     1338                        children = (
     1339                                9688CB130ED12B4E001D649F /* AssemblerBuffer.h */,
     1340                                9688CB140ED12B4E001D649F /* X86Assembler.h */,
     1341                        );
     1342                        path = assembler;
     1343                        sourceTree = "<group>";
    13411344                };
    13421345                E195678D09E7CF1200B89D13 /* unicode */ = {
     
    15611564                                9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
    15621565                                8683B02F0E636482004C19EE /* CTI.h in Headers */,
    1563                                 869081410E640C89000D36ED /* X86Assembler.h in Headers */,
    15641566                                869083160E6518D7000D36ED /* WREC.h in Headers */,
    15651567                                933040040E6A749400786E6A /* SmallStrings.h in Headers */,
     
    15791581                                7E4C89140ECA0F9A00DBEEEC /* EvalCodeCache.h in Headers */,
    15801582                                FE1B447A0ECCD73B004F4DD1 /* StdLibExtras.h in Headers */,
     1583                                9688CB150ED12B4E001D649F /* AssemblerBuffer.h in Headers */,
     1584                                9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
    15811585                        );
    15821586                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/JavaScriptCore/assembler/AssemblerBuffer.h

    r38466 r38487  
    2424 */
    2525
    26 #ifndef X86Assembler_h
    27 #define X86Assembler_h
     26#ifndef AssemblerBuffer_h
     27#define AssemblerBuffer_h
    2828
    29 #if ENABLE(MASM) && PLATFORM(X86)
     29#include <wtf/Platform.h>
     30
     31#if ENABLE(ASSEMBLER)
    3032
    3133#include <wtf/Assertions.h>
    32 #include <wtf/AlwaysInline.h>
    3334#include <wtf/FastMalloc.h>
    34 
    35 #if HAVE(MMAN)
    36 #include <sys/mman.h>
    37 #endif
    38 
    39 #include <string.h>
    4035
    4136namespace JSC {
    4237
    43 class AssemblerBuffer {
    44 public:
    45     AssemblerBuffer(int capacity)
    46         : m_buffer(static_cast<char*>(fastMalloc(capacity)))
    47         , m_capacity(capacity)
    48         , m_size(0)
    49     {
    50     }
    51 
    52     ~AssemblerBuffer()
    53     {
    54         fastFree(m_buffer);
    55     }
    56 
    57     void ensureSpace(int space)
    58     {
    59         if (m_size > m_capacity - space)
    60             grow();
    61     }
    62 
    63     bool isAligned(int alignment)
    64     {
    65         return !(m_size & (alignment - 1));
    66     }
    67    
    68     void putByteUnchecked(int value)
    69     {
    70         ASSERT(!(m_size > m_capacity - 4));
    71         m_buffer[m_size] = value;
    72         m_size++;
    73     }
    74 
    75     void putByte(int value)
    76     {
    77         if (m_size > m_capacity - 4)
    78             grow();
    79         putByteUnchecked(value);
    80     }
    81    
    82     void putShortUnchecked(int value)
    83     {
    84         ASSERT(!(m_size > m_capacity - 4));
    85         *reinterpret_cast<short*>(&m_buffer[m_size]) = value;
    86         m_size += 2;
    87     }
    88 
    89     void putShort(int value)
    90     {
    91         if (m_size > m_capacity - 4)
    92             grow();
    93         putShortUnchecked(value);
    94     }
    95    
    96     void putIntUnchecked(int value)
    97     {
    98         *reinterpret_cast<int*>(&m_buffer[m_size]) = value;
    99         m_size += 4;
    100     }
    101 
    102     void putInt(int value)
    103     {
    104         if (m_size > m_capacity - 4)
    105             grow();
    106         putIntUnchecked(value);
    107     }
    108 
    109     void* data()
    110     {
    111         return m_buffer;
    112     }
    113    
    114     int size()
    115     {
    116         return m_size;
    117     }
    118 
    119     AssemblerBuffer* reset()
    120     {
    121         m_size = 0;
    122         return this;
    123     }
    124    
    125     void* executableCopy()
    126     {
    127         if (!m_size)
    128             return 0;
    129 
    130         void* result = WTF::fastMallocExecutable(m_size);
    131 
    132         if (!result)
    133             return 0;
    134 
    135         return memcpy(result, m_buffer, m_size);
    136     }
    137 
    138 private:
    139     void grow()
    140     {
    141         m_capacity += m_capacity / 2;
    142         m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
    143     }
    144 
    145     char* m_buffer;
    146     int m_capacity;
    147     int m_size;
    148 };
    149 
    150 #define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm))
    151 #define SIB(type, reg, rm) MODRM(type, reg, rm)
    152 #define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value))
    153 
    154 namespace X86 {
    155     typedef enum {
    156         eax,
    157         ecx,
    158         edx,
    159         ebx,
    160         esp,
    161         ebp,
    162         esi,
    163         edi,
    164 
    165         noBase = ebp,
    166         hasSib = esp,
    167         noScale = esp,
    168     } RegisterID;
    169 
    170     typedef enum {
    171         xmm0,
    172         xmm1,
    173         xmm2,
    174         xmm3,
    175         xmm4,
    176         xmm5,
    177         xmm6,
    178         xmm7,
    179     } XMMRegisterID;
    180 }
    181 
    182 class X86Assembler {
    183 public:
    184     typedef X86::RegisterID RegisterID;
    185     typedef X86::XMMRegisterID XMMRegisterID;
    186 
    187     typedef enum {
    188         OP_ADD_EvGv                     = 0x01,
    189         OP_ADD_GvEv                     = 0x03,
    190         OP_OR_EvGv                      = 0x09,
    191         OP_OR_GvEv                      = 0x0B,
    192         OP_2BYTE_ESCAPE                 = 0x0F,
    193         OP_AND_EvGv                     = 0x21,
    194         OP_SUB_EvGv                     = 0x29,
    195         OP_SUB_GvEv                     = 0x2B,
    196         PRE_PREDICT_BRANCH_NOT_TAKEN    = 0x2E,
    197         OP_XOR_EvGv                     = 0x31,
    198         OP_CMP_EvGv                     = 0x39,
    199         OP_CMP_GvEv                     = 0x3B,
    200         OP_PUSH_EAX                     = 0x50,
    201         OP_POP_EAX                      = 0x58,
    202         PRE_OPERAND_SIZE                = 0x66,
    203         PRE_SSE_66                      = 0x66,
    204         OP_PUSH_Iz                      = 0x68,
    205         OP_IMUL_GvEvIz                  = 0x69,
    206         OP_GROUP1_EvIz                  = 0x81,
    207         OP_GROUP1_EvIb                  = 0x83,
    208         OP_TEST_EvGv                    = 0x85,
    209         OP_MOV_EvGv                     = 0x89,
    210         OP_MOV_GvEv                     = 0x8B,
    211         OP_LEA                          = 0x8D,
    212         OP_GROUP1A_Ev                   = 0x8F,
    213         OP_CDQ                          = 0x99,
    214         OP_SETE                         = 0x94,
    215         OP_SETNE                        = 0x95,
    216         OP_GROUP2_EvIb                  = 0xC1,
    217         OP_RET                          = 0xC3,
    218         OP_GROUP11_EvIz                 = 0xC7,
    219         OP_INT3                         = 0xCC,
    220         OP_GROUP2_Ev1                   = 0xD1,
    221         OP_GROUP2_EvCL                  = 0xD3,
    222         OP_CALL_rel32                   = 0xE8,
    223         OP_JMP_rel32                    = 0xE9,
    224         PRE_SSE_F2                      = 0xF2,
    225         OP_HLT                          = 0xF4,
    226         OP_GROUP3_Ev                    = 0xF7,
    227         OP_GROUP3_EvIz                  = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
    228         OP_GROUP5_Ev                    = 0xFF,
    229 
    230         OP2_MOVSD_VsdWsd    = 0x10,
    231         OP2_MOVSD_WsdVsd    = 0x11,
    232         OP2_CVTSI2SD_VsdEd  = 0x2A,
    233         OP2_CVTTSD2SI_GdWsd = 0x2C,
    234         OP2_UCOMISD_VsdWsd  = 0x2E,
    235         OP2_XORPD_VsdWsd    = 0x57,
    236         OP2_ADDSD_VsdWsd    = 0x58,
    237         OP2_MULSD_VsdWsd    = 0x59,
    238         OP2_SUBSD_VsdWsd    = 0x5C,
    239         OP2_MOVD_EdVd       = 0x7E,
    240         OP2_JO_rel32        = 0x80,
    241         OP2_JB_rel32        = 0x82,
    242         OP2_JAE_rel32       = 0x83,
    243         OP2_JE_rel32        = 0x84,
    244         OP2_JNE_rel32       = 0x85,
    245         OP2_JBE_rel32       = 0x86,
    246         OP2_JA_rel32        = 0x87,
    247         OP2_JS_rel32        = 0x88,
    248         OP2_JP_rel32        = 0x8A,
    249         OP2_JL_rel32        = 0x8C,
    250         OP2_JGE_rel32       = 0x8D,
    251         OP2_JLE_rel32       = 0x8E,
    252         OP2_JG_rel32        = 0x8F,
    253         OP2_IMUL_GvEv       = 0xAF,
    254         OP2_MOVZX_GvEb      = 0xB6,
    255         OP2_MOVZX_GvEw      = 0xB7,
    256         OP2_PEXTRW_GdUdIb   = 0xC5,
    257 
    258         GROUP1_OP_ADD = 0,
    259         GROUP1_OP_OR  = 1,
    260         GROUP1_OP_AND = 4,
    261         GROUP1_OP_SUB = 5,
    262         GROUP1_OP_XOR = 6,
    263         GROUP1_OP_CMP = 7,
    264 
    265         GROUP1A_OP_POP = 0,
    266 
    267         GROUP2_OP_SHL = 4,
    268         GROUP2_OP_SAR = 7,
    269 
    270         GROUP3_OP_TEST = 0,
    271         GROUP3_OP_NEG  = 3,
    272         GROUP3_OP_IDIV = 7,
    273 
    274         GROUP5_OP_CALLN = 2,
    275         GROUP5_OP_JMPN  = 4,
    276         GROUP5_OP_PUSH  = 6,
    277 
    278         GROUP11_MOV = 0,
    279     } OpcodeID;
    280    
    281     static const int maxInstructionSize = 16;
    282 
    283     X86Assembler(AssemblerBuffer* m_buffer)
    284         : m_buffer(m_buffer)
    285     {
    286         m_buffer->reset();
    287     }
    288 
    289     void emitInt3()
    290     {
    291         m_buffer->putByte(OP_INT3);
    292     }
    293    
    294     void pushl_r(RegisterID reg)
    295     {
    296         m_buffer->putByte(OP_PUSH_EAX + reg);
    297     }
    298    
    299     void pushl_m(int offset, RegisterID base)
    300     {
    301         m_buffer->putByte(OP_GROUP5_Ev);
    302         emitModRm_opm(GROUP5_OP_PUSH, base, offset);
    303     }
    304 
    305     void pushl_i32(int imm)
    306     {
    307         m_buffer->putByte(OP_PUSH_Iz);
    308         m_buffer->putInt(imm);
    309     }
    310    
    311     void popl_r(RegisterID reg)
    312     {
    313         m_buffer->putByte(OP_POP_EAX + reg);
    314     }
    315 
    316     void popl_m(int offset, RegisterID base)
    317     {
    318         m_buffer->putByte(OP_GROUP1A_Ev);
    319         emitModRm_opm(GROUP1A_OP_POP, base, offset);
    320     }
    321    
    322     void movl_rr(RegisterID src, RegisterID dst)
    323     {
    324         m_buffer->putByte(OP_MOV_EvGv);
    325         emitModRm_rr(src, dst);
    326     }
    327    
    328     void addl_rr(RegisterID src, RegisterID dst)
    329     {
    330         m_buffer->putByte(OP_ADD_EvGv);
    331         emitModRm_rr(src, dst);
    332     }
    333 
    334     void addl_i8r(int imm, RegisterID dst)
    335     {
    336         m_buffer->putByte(OP_GROUP1_EvIb);
    337         emitModRm_opr(GROUP1_OP_ADD, dst);
    338         m_buffer->putByte(imm);
    339     }
    340 
    341     void addl_i8m(int imm, void* addr)
    342     {
    343         m_buffer->putByte(OP_GROUP1_EvIb);
    344         emitModRm_opm(GROUP1_OP_ADD, addr);
    345         m_buffer->putByte(imm);
    346     }
    347 
    348     void addl_i32r(int imm, RegisterID dst)
    349     {
    350         m_buffer->putByte(OP_GROUP1_EvIz);
    351         emitModRm_opr(GROUP1_OP_ADD, dst);
    352         m_buffer->putInt(imm);
    353     }
    354 
    355     void addl_mr(int offset, RegisterID base, RegisterID dst)
    356     {
    357         m_buffer->putByte(OP_ADD_GvEv);
    358         emitModRm_rm(dst, base, offset);
    359     }
    360 
    361     void andl_rr(RegisterID src, RegisterID dst)
    362     {
    363         m_buffer->putByte(OP_AND_EvGv);
    364         emitModRm_rr(src, dst);
    365     }
    366 
    367     void andl_i32r(int imm, RegisterID dst)
    368     {
    369         m_buffer->putByte(OP_GROUP1_EvIz);
    370         emitModRm_opr(GROUP1_OP_AND, dst);
    371         m_buffer->putInt(imm);
    372     }
    373 
    374     void cmpl_i8r(int imm, RegisterID dst)
    375     {
    376         m_buffer->putByte(OP_GROUP1_EvIb);
    377         emitModRm_opr(GROUP1_OP_CMP, dst);
    378         m_buffer->putByte(imm);
    379     }
    380 
    381     void cmpl_rr(RegisterID src, RegisterID dst)
    382     {
    383         m_buffer->putByte(OP_CMP_EvGv);
    384         emitModRm_rr(src, dst);
    385     }
    386 
    387     void cmpl_rm(RegisterID src, int offset, RegisterID base)
    388     {
    389         m_buffer->putByte(OP_CMP_EvGv);
    390         emitModRm_rm(src, base, offset);
    391     }
    392 
    393     void cmpl_mr(int offset, RegisterID base, RegisterID dst)
    394     {
    395         m_buffer->putByte(OP_CMP_GvEv);
    396         emitModRm_rm(dst, base, offset);
    397     }
    398 
    399     void cmpl_i32r(int imm, RegisterID dst)
    400     {
    401         m_buffer->putByte(OP_GROUP1_EvIz);
    402         emitModRm_opr(GROUP1_OP_CMP, dst);
    403         m_buffer->putInt(imm);
    404     }
    405 
    406     void cmpl_i32m(int imm, RegisterID dst)
    407     {
    408         m_buffer->putByte(OP_GROUP1_EvIz);
    409         emitModRm_opm(GROUP1_OP_CMP, dst);
    410         m_buffer->putInt(imm);
    411     }
    412 
    413     void cmpl_i32m(int imm, int offset, RegisterID dst)
    414     {
    415         m_buffer->putByte(OP_GROUP1_EvIz);
    416         emitModRm_opm(GROUP1_OP_CMP, dst, offset);
    417         m_buffer->putInt(imm);
    418     }
    419 
    420     void cmpl_i32m(int imm, void* addr)
    421     {
    422         m_buffer->putByte(OP_GROUP1_EvIz);
    423         emitModRm_opm(GROUP1_OP_CMP, addr);
    424         m_buffer->putInt(imm);
    425     }
    426 
    427     void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
    428     {
    429         m_buffer->putByte(OP_GROUP1_EvIb);
    430         emitModRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset);
    431         m_buffer->putByte(imm);
    432     }
    433 
    434     void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
    435     {
    436         m_buffer->putByte(PRE_OPERAND_SIZE);
    437         m_buffer->putByte(OP_CMP_EvGv);
    438         emitModRm_rmsib(src, base, index, scale);
    439     }
    440 
    441     void sete_r(RegisterID dst)
    442     {
    443         m_buffer->putByte(OP_2BYTE_ESCAPE);
    444         m_buffer->putByte(OP_SETE);
    445         m_buffer->putByte(MODRM(3, 0, dst));
    446     }
    447 
    448     void setz_r(RegisterID dst)
    449     {
    450         sete_r(dst);
    451     }
    452 
    453     void setne_r(RegisterID dst)
    454     {
    455         m_buffer->putByte(OP_2BYTE_ESCAPE);
    456         m_buffer->putByte(OP_SETNE);
    457         m_buffer->putByte(MODRM(3, 0, dst));
    458     }
    459 
    460     void setnz_r(RegisterID dst)
    461     {
    462         setne_r(dst);
    463     }
    464 
    465     void orl_rr(RegisterID src, RegisterID dst)
    466     {
    467         m_buffer->putByte(OP_OR_EvGv);
    468         emitModRm_rr(src, dst);
    469     }
    470 
    471     void orl_mr(int offset, RegisterID base, RegisterID dst)
    472     {
    473         m_buffer->putByte(OP_OR_GvEv);
    474         emitModRm_rm(dst, base, offset);
    475     }
    476 
    477     void orl_i32r(int imm, RegisterID dst)
    478     {
    479         m_buffer->putByte(OP_GROUP1_EvIb);
    480         emitModRm_opr(GROUP1_OP_OR, dst);
    481         m_buffer->putByte(imm);
    482     }
    483 
    484     void subl_rr(RegisterID src, RegisterID dst)
    485     {
    486         m_buffer->putByte(OP_SUB_EvGv);
    487         emitModRm_rr(src, dst);
    488     }
    489 
    490     void subl_i8r(int imm, RegisterID dst)
    491     {
    492         m_buffer->putByte(OP_GROUP1_EvIb);
    493         emitModRm_opr(GROUP1_OP_SUB, dst);
    494         m_buffer->putByte(imm);
    495     }
    496    
    497     void subl_i8m(int imm, void* addr)
    498     {
    499         m_buffer->putByte(OP_GROUP1_EvIb);
    500         emitModRm_opm(GROUP1_OP_SUB, addr);
    501         m_buffer->putByte(imm);
    502     }
    503 
    504     void subl_i32r(int imm, RegisterID dst)
    505     {
    506         m_buffer->putByte(OP_GROUP1_EvIz);
    507         emitModRm_opr(GROUP1_OP_SUB, dst);
    508         m_buffer->putInt(imm);
    509     }
    510 
    511     void subl_mr(int offset, RegisterID base, RegisterID dst)
    512     {
    513         m_buffer->putByte(OP_SUB_GvEv);
    514         emitModRm_rm(dst, base, offset);
    515     }
    516 
    517     void testl_i32r(int imm, RegisterID dst)
    518     {
    519         m_buffer->ensureSpace(maxInstructionSize);
    520         m_buffer->putByteUnchecked(OP_GROUP3_EvIz);
    521         emitModRm_opr_Unchecked(GROUP3_OP_TEST, dst);
    522         m_buffer->putIntUnchecked(imm);
    523     }
    524 
    525     void testl_i32m(int imm, RegisterID dst)
    526     {
    527         m_buffer->putByte(OP_GROUP3_EvIz);
    528         emitModRm_opm(GROUP3_OP_TEST, dst);
    529         m_buffer->putInt(imm);
    530     }
    531 
    532     void testl_i32m(int imm, int offset, RegisterID dst)
    533     {
    534         m_buffer->putByte(OP_GROUP3_EvIz);
    535         emitModRm_opm(GROUP3_OP_TEST, dst, offset);
    536         m_buffer->putInt(imm);
    537     }
    538 
    539     void testl_rr(RegisterID src, RegisterID dst)
    540     {
    541         m_buffer->putByte(OP_TEST_EvGv);
    542         emitModRm_rr(src, dst);
    543     }
    544    
    545     void xorl_i8r(int imm, RegisterID dst)
    546     {
    547         m_buffer->putByte(OP_GROUP1_EvIb);
    548         emitModRm_opr(GROUP1_OP_XOR, dst);
    549         m_buffer->putByte(imm);
    550     }
    551 
    552     void xorl_rr(RegisterID src, RegisterID dst)
    553     {
    554         m_buffer->putByte(OP_XOR_EvGv);
    555         emitModRm_rr(src, dst);
    556     }
    557 
    558     void sarl_i8r(int imm, RegisterID dst)
    559     {
    560         if (imm == 1) {
    561             m_buffer->putByte(OP_GROUP2_Ev1);
    562             emitModRm_opr(GROUP2_OP_SAR, dst);
    563         } else {
    564             m_buffer->putByte(OP_GROUP2_EvIb);
    565             emitModRm_opr(GROUP2_OP_SAR, dst);
    566             m_buffer->putByte(imm);
    567         }
    568     }
    569 
    570     void sarl_CLr(RegisterID dst)
    571     {
    572         m_buffer->putByte(OP_GROUP2_EvCL);
    573         emitModRm_opr(GROUP2_OP_SAR, dst);
    574     }
    575 
    576     void shl_i8r(int imm, RegisterID dst)
    577     {
    578         if (imm == 1) {
    579             m_buffer->putByte(OP_GROUP2_Ev1);
    580             emitModRm_opr(GROUP2_OP_SHL, dst);
    581         } else {
    582             m_buffer->putByte(OP_GROUP2_EvIb);
    583             emitModRm_opr(GROUP2_OP_SHL, dst);
    584             m_buffer->putByte(imm);
    585         }
    586     }
    587 
    588     void shll_CLr(RegisterID dst)
    589     {
    590         m_buffer->putByte(OP_GROUP2_EvCL);
    591         emitModRm_opr(GROUP2_OP_SHL, dst);
    592     }
    593 
    594     void imull_rr(RegisterID src, RegisterID dst)
    595     {
    596         m_buffer->putByte(OP_2BYTE_ESCAPE);
    597         m_buffer->putByte(OP2_IMUL_GvEv);
    598         emitModRm_rr(dst, src);
    599     }
    600    
    601     void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
    602     {
    603         m_buffer->putByte(OP_IMUL_GvEvIz);
    604         emitModRm_rr(dst, src);
    605         m_buffer->putInt(value);
    606     }
    607 
    608     void idivl_r(RegisterID dst)
    609     {
    610         m_buffer->putByte(OP_GROUP3_Ev);
    611         emitModRm_opr(GROUP3_OP_IDIV, dst);
    612     }
    613 
    614     void negl_r(RegisterID dst)
    615     {
    616         m_buffer->putByte(OP_GROUP3_Ev);
    617         emitModRm_opr(GROUP3_OP_NEG, dst);
    618     }
    619 
    620     void cdq()
    621     {
    622         m_buffer->putByte(OP_CDQ);
    623     }
    624 
    625     void movl_mr(RegisterID base, RegisterID dst)
    626     {
    627         m_buffer->putByte(OP_MOV_GvEv);
    628         emitModRm_rm(dst, base);
    629     }
    630 
    631     void movl_mr(int offset, RegisterID base, RegisterID dst)
    632     {
    633         m_buffer->ensureSpace(maxInstructionSize);
    634         m_buffer->putByteUnchecked(OP_MOV_GvEv);
    635         emitModRm_rm_Unchecked(dst, base, offset);
    636     }
    637 
    638     void movl_mr(void* addr, RegisterID dst)
    639     {
    640         m_buffer->putByte(OP_MOV_GvEv);
    641         emitModRm_rm(dst, addr);
    642     }
    643 
    644     void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    645     {
    646         m_buffer->putByte(OP_MOV_GvEv);
    647         emitModRm_rmsib(dst, base, index, scale, offset);
    648     }
    649 
    650     void movzbl_rr(RegisterID src, RegisterID dst)
    651     {
    652         m_buffer->putByte(OP_2BYTE_ESCAPE);
    653         m_buffer->putByte(OP2_MOVZX_GvEb);
    654         emitModRm_rr(dst, src);
    655     }
    656 
    657     void movzwl_mr(int offset, RegisterID base, RegisterID dst)
    658     {
    659         m_buffer->putByte(OP_2BYTE_ESCAPE);
    660         m_buffer->putByte(OP2_MOVZX_GvEw);
    661         emitModRm_rm(dst, base, offset);
    662     }
    663 
    664     void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
    665     {
    666         m_buffer->putByte(OP_2BYTE_ESCAPE);
    667         m_buffer->putByte(OP2_MOVZX_GvEw);
    668         emitModRm_rmsib(dst, base, index, scale);
    669     }
    670 
    671     void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    672     {
    673         m_buffer->putByte(OP_2BYTE_ESCAPE);
    674         m_buffer->putByte(OP2_MOVZX_GvEw);
    675         emitModRm_rmsib(dst, base, index, scale, offset);
    676     }
    677 
    678     void movl_rm(RegisterID src, RegisterID base)
    679     {
    680         m_buffer->putByte(OP_MOV_EvGv);
    681         emitModRm_rm(src, base);
    682     }
    683 
    684     void movl_rm(RegisterID src, int offset, RegisterID base)
    685     {
    686         m_buffer->ensureSpace(maxInstructionSize);
    687         m_buffer->putByteUnchecked(OP_MOV_EvGv);
    688         emitModRm_rm_Unchecked(src, base, offset);
    689     }
    690    
    691     void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
    692     {
    693         m_buffer->putByte(OP_MOV_EvGv);
    694         emitModRm_rmsib(src, base, index, scale, offset);
    695     }
    696    
    697     void movl_i32r(int imm, RegisterID dst)
    698     {
    699         m_buffer->putByte(OP_GROUP11_EvIz);
    700         emitModRm_opr(GROUP11_MOV, dst);
    701         m_buffer->putInt(imm);
    702     }
    703 
    704     void movl_i32m(int imm, int offset, RegisterID base)
    705     {
    706         m_buffer->ensureSpace(maxInstructionSize);
    707         m_buffer->putByteUnchecked(OP_GROUP11_EvIz);
    708         emitModRm_opm_Unchecked(GROUP11_MOV, base, offset);
    709         m_buffer->putIntUnchecked(imm);
    710     }
    711 
    712     void movl_i32m(int imm, void* addr)
    713     {
    714         m_buffer->putByte(OP_GROUP11_EvIz);
    715         emitModRm_opm(GROUP11_MOV, addr);
    716         m_buffer->putInt(imm);
    717     }
    718 
    719     void leal_mr(int offset, RegisterID base, RegisterID dst)
    720     {
    721         m_buffer->putByte(OP_LEA);
    722         emitModRm_rm(dst, base, offset);
    723     }
    724 
    725     void leal_mr(int offset, RegisterID index, int scale, RegisterID dst)
    726     {
    727         m_buffer->putByte(OP_LEA);
    728         emitModRm_rmsib(dst, X86::noBase, index, scale, offset);
    729     }
    730 
    731     void ret()
    732     {
    733         m_buffer->putByte(OP_RET);
    734     }
    735    
    736     void jmp_r(RegisterID dst)
    737     {
    738         m_buffer->putByte(OP_GROUP5_Ev);
    739         emitModRm_opr(GROUP5_OP_JMPN, dst);
    740     }
    741    
    742     void jmp_m(int offset, RegisterID base)
    743     {
    744         m_buffer->putByte(OP_GROUP5_Ev);
    745         emitModRm_opm(GROUP5_OP_JMPN, base, offset);
    746     }
    747    
    748     void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
    749     {
    750         m_buffer->putByte(PRE_SSE_F2);
    751         m_buffer->putByte(OP_2BYTE_ESCAPE);
    752         m_buffer->putByte(OP2_MOVSD_VsdWsd);
    753         emitModRm_rm((RegisterID)dst, base, offset);
    754     }
    755 
    756     void xorpd_mr(void* addr, XMMRegisterID dst)
    757     {
    758         m_buffer->putByte(PRE_SSE_66);
    759         m_buffer->putByte(OP_2BYTE_ESCAPE);
    760         m_buffer->putByte(OP2_XORPD_VsdWsd);
    761         emitModRm_rm((RegisterID)dst, addr);
    762     }
    763 
    764     void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
    765     {
    766         m_buffer->putByte(PRE_SSE_F2);
    767         m_buffer->putByte(OP_2BYTE_ESCAPE);
    768         m_buffer->putByte(OP2_MOVSD_WsdVsd);
    769         emitModRm_rm((RegisterID)src, base, offset);
    770     }
    771 
    772     void movd_rr(XMMRegisterID src, RegisterID dst)
    773     {
    774         m_buffer->putByte(PRE_SSE_66);
    775         m_buffer->putByte(OP_2BYTE_ESCAPE);
    776         m_buffer->putByte(OP2_MOVD_EdVd);
    777         emitModRm_rr((RegisterID)src, dst);
    778     }
    779 
    780     void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
    781     {
    782         m_buffer->putByte(PRE_SSE_F2);
    783         m_buffer->putByte(OP_2BYTE_ESCAPE);
    784         m_buffer->putByte(OP2_CVTSI2SD_VsdEd);
    785         emitModRm_rr((RegisterID)dst, src);
    786     }
    787 
    788     void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
    789     {
    790         m_buffer->putByte(PRE_SSE_F2);
    791         m_buffer->putByte(OP_2BYTE_ESCAPE);
    792         m_buffer->putByte(OP2_CVTTSD2SI_GdWsd);
    793         emitModRm_rr(dst, (RegisterID)src);
    794     }
    795 
    796     void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
    797     {
    798         m_buffer->putByte(PRE_SSE_F2);
    799         m_buffer->putByte(OP_2BYTE_ESCAPE);
    800         m_buffer->putByte(OP2_ADDSD_VsdWsd);
    801         emitModRm_rm((RegisterID)dst, base, offset);
    802     }
    803 
    804     void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
    805     {
    806         m_buffer->putByte(PRE_SSE_F2);
    807         m_buffer->putByte(OP_2BYTE_ESCAPE);
    808         m_buffer->putByte(OP2_SUBSD_VsdWsd);
    809         emitModRm_rm((RegisterID)dst, base, offset);
    810     }
    811 
    812     void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
    813     {
    814         m_buffer->putByte(PRE_SSE_F2);
    815         m_buffer->putByte(OP_2BYTE_ESCAPE);
    816         m_buffer->putByte(OP2_MULSD_VsdWsd);
    817         emitModRm_rm((RegisterID)dst, base, offset);
    818     }
    819 
    820     void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
    821     {
    822         m_buffer->putByte(PRE_SSE_F2);
    823         m_buffer->putByte(OP_2BYTE_ESCAPE);
    824         m_buffer->putByte(OP2_ADDSD_VsdWsd);
    825         emitModRm_rr((RegisterID)dst, (RegisterID)src);
    826     }
    827 
    828     void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
    829     {
    830         m_buffer->putByte(PRE_SSE_F2);
    831         m_buffer->putByte(OP_2BYTE_ESCAPE);
    832         m_buffer->putByte(OP2_SUBSD_VsdWsd);
    833         emitModRm_rr((RegisterID)dst, (RegisterID)src);
    834     }
    835 
    836     void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
    837     {
    838         m_buffer->putByte(PRE_SSE_F2);
    839         m_buffer->putByte(OP_2BYTE_ESCAPE);
    840         m_buffer->putByte(OP2_MULSD_VsdWsd);
    841         emitModRm_rr((RegisterID)dst, (RegisterID)src);
    842     }
    843 
    844     void ucomis_rr(XMMRegisterID src, XMMRegisterID dst)
    845     {
    846         m_buffer->putByte(PRE_SSE_66);
    847         m_buffer->putByte(OP_2BYTE_ESCAPE);
    848         m_buffer->putByte(OP2_UCOMISD_VsdWsd);
    849         emitModRm_rr((RegisterID)dst, (RegisterID)src);
    850     }
    851 
    852     void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
    853     {
    854         m_buffer->putByte(PRE_SSE_66);
    855         m_buffer->putByte(OP_2BYTE_ESCAPE);
    856         m_buffer->putByte(OP2_PEXTRW_GdUdIb);
    857         emitModRm_rr(dst, (RegisterID)src);
    858         m_buffer->putByte(whichWord);
    859     }
    860 
    861     // Opaque label types
    862    
    863     class JmpSrc {
    864         friend class X86Assembler;
     38    class AssemblerBuffer {
    86539    public:
    866         JmpSrc()
    867             : m_offset(-1)
     40        AssemblerBuffer(int capacity)
     41            : m_buffer(static_cast<char*>(fastMalloc(capacity)))
     42            , m_capacity(capacity)
     43            , m_size(0)
    86844        {
    86945        }
    87046
    871     private:
    872         JmpSrc(int offset)
    873             : m_offset(offset)
     47        ~AssemblerBuffer()
    87448        {
     49            fastFree(m_buffer);
    87550        }
    87651
    877         int m_offset;
    878     };
    879    
    880     class JmpDst {
    881         friend class X86Assembler;
    882     public:
    883         JmpDst()
    884             : m_offset(-1)
     52        void ensureSpace(int space)
    88553        {
     54            if (m_size > m_capacity - space)
     55                grow();
     56        }
     57
     58        bool isAligned(int alignment)
     59        {
     60            return !(m_size & (alignment - 1));
     61        }
     62
     63        void putByteUnchecked(int value)
     64        {
     65            ASSERT(!(m_size > m_capacity - 4));
     66            m_buffer[m_size] = value;
     67            m_size++;
     68        }
     69
     70        void putByte(int value)
     71        {
     72            if (m_size > m_capacity - 4)
     73                grow();
     74            putByteUnchecked(value);
     75        }
     76
     77        void putShortUnchecked(int value)
     78        {
     79            ASSERT(!(m_size > m_capacity - 4));
     80            *reinterpret_cast<short*>(&m_buffer[m_size]) = value;
     81            m_size += 2;
     82        }
     83
     84        void putShort(int value)
     85        {
     86            if (m_size > m_capacity - 4)
     87                grow();
     88            putShortUnchecked(value);
     89        }
     90
     91        void putIntUnchecked(int value)
     92        {
     93            *reinterpret_cast<int*>(&m_buffer[m_size]) = value;
     94            m_size += 4;
     95        }
     96
     97        void putInt(int value)
     98        {
     99            if (m_size > m_capacity - 4)
     100                grow();
     101            putIntUnchecked(value);
     102        }
     103
     104        void* data()
     105        {
     106            return m_buffer;
     107        }
     108
     109        int size()
     110        {
     111            return m_size;
     112        }
     113
     114        AssemblerBuffer* reset()
     115        {
     116            m_size = 0;
     117            return this;
     118        }
     119
     120        void* executableCopy()
     121        {
     122            if (!m_size)
     123                return 0;
     124
     125            void* result = WTF::fastMallocExecutable(m_size);
     126
     127            if (!result)
     128                return 0;
     129
     130            return memcpy(result, m_buffer, m_size);
    886131        }
    887132
    888133    private:
    889         JmpDst(int offset)
    890             : m_offset(offset)
     134        void grow()
    891135        {
     136            m_capacity += m_capacity / 2;
     137            m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
    892138        }
    893139
    894         int m_offset;
     140        char* m_buffer;
     141        int m_capacity;
     142        int m_size;
    895143    };
    896 
    897     // FIXME: make this point to a global label, linked later.
    898     JmpSrc emitCall()
    899     {
    900         m_buffer->putByte(OP_CALL_rel32);
    901         m_buffer->putInt(0);
    902         return JmpSrc(m_buffer->size());
    903     }
    904    
    905     JmpSrc emitCall(RegisterID dst)
    906     {
    907         m_buffer->putByte(OP_GROUP5_Ev);
    908         emitModRm_opr(GROUP5_OP_CALLN, dst);
    909         return JmpSrc(m_buffer->size());
    910     }
    911 
    912     JmpDst label()
    913     {
    914         return JmpDst(m_buffer->size());
    915     }
    916    
    917     JmpDst align(int alignment)
    918     {
    919         while (!m_buffer->isAligned(alignment))
    920             m_buffer->putByte(OP_HLT);
    921 
    922         return label();
    923     }
    924 
    925     JmpSrc emitUnlinkedJmp()
    926     {
    927         m_buffer->putByte(OP_JMP_rel32);
    928         m_buffer->putInt(0);
    929         return JmpSrc(m_buffer->size());
    930     }
    931    
    932     JmpSrc emitUnlinkedJne()
    933     {
    934         m_buffer->putByte(OP_2BYTE_ESCAPE);
    935         m_buffer->putByte(OP2_JNE_rel32);
    936         m_buffer->putInt(0);
    937         return JmpSrc(m_buffer->size());
    938     }
    939    
    940     JmpSrc emitUnlinkedJnz()
    941     {
    942         return emitUnlinkedJne();
    943     }
    944 
    945     JmpSrc emitUnlinkedJe()
    946     {
    947         m_buffer->ensureSpace(maxInstructionSize);
    948         m_buffer->putByteUnchecked(OP_2BYTE_ESCAPE);
    949         m_buffer->putByteUnchecked(OP2_JE_rel32);
    950         m_buffer->putIntUnchecked(0);
    951         return JmpSrc(m_buffer->size());
    952     }
    953    
    954     JmpSrc emitUnlinkedJl()
    955     {
    956         m_buffer->putByte(OP_2BYTE_ESCAPE);
    957         m_buffer->putByte(OP2_JL_rel32);
    958         m_buffer->putInt(0);
    959         return JmpSrc(m_buffer->size());
    960     }
    961    
    962     JmpSrc emitUnlinkedJb()
    963     {
    964         m_buffer->putByte(OP_2BYTE_ESCAPE);
    965         m_buffer->putByte(OP2_JB_rel32);
    966         m_buffer->putInt(0);
    967         return JmpSrc(m_buffer->size());
    968     }
    969    
    970     JmpSrc emitUnlinkedJle()
    971     {
    972         m_buffer->putByte(OP_2BYTE_ESCAPE);
    973         m_buffer->putByte(OP2_JLE_rel32);
    974         m_buffer->putInt(0);
    975         return JmpSrc(m_buffer->size());
    976     }
    977    
    978     JmpSrc emitUnlinkedJbe()
    979     {
    980         m_buffer->putByte(OP_2BYTE_ESCAPE);
    981         m_buffer->putByte(OP2_JBE_rel32);
    982         m_buffer->putInt(0);
    983         return JmpSrc(m_buffer->size());
    984     }
    985    
    986     JmpSrc emitUnlinkedJge()
    987     {
    988         m_buffer->putByte(OP_2BYTE_ESCAPE);
    989         m_buffer->putByte(OP2_JGE_rel32);
    990         m_buffer->putInt(0);
    991         return JmpSrc(m_buffer->size());
    992     }
    993 
    994     JmpSrc emitUnlinkedJg()
    995     {
    996         m_buffer->putByte(OP_2BYTE_ESCAPE);
    997         m_buffer->putByte(OP2_JG_rel32);
    998         m_buffer->putInt(0);
    999         return JmpSrc(m_buffer->size());
    1000     }
    1001 
    1002     JmpSrc emitUnlinkedJa()
    1003     {
    1004         m_buffer->putByte(OP_2BYTE_ESCAPE);
    1005         m_buffer->putByte(OP2_JA_rel32);
    1006         m_buffer->putInt(0);
    1007         return JmpSrc(m_buffer->size());
    1008     }
    1009    
    1010     JmpSrc emitUnlinkedJae()
    1011     {
    1012         m_buffer->putByte(OP_2BYTE_ESCAPE);
    1013         m_buffer->putByte(OP2_JAE_rel32);
    1014         m_buffer->putInt(0);
    1015         return JmpSrc(m_buffer->size());
    1016     }
    1017    
    1018     JmpSrc emitUnlinkedJo()
    1019     {
    1020         m_buffer->putByte(OP_2BYTE_ESCAPE);
    1021         m_buffer->putByte(OP2_JO_rel32);
    1022         m_buffer->putInt(0);
    1023         return JmpSrc(m_buffer->size());
    1024     }
    1025 
    1026     JmpSrc emitUnlinkedJp()
    1027     {
    1028         m_buffer->putByte(OP_2BYTE_ESCAPE);
    1029         m_buffer->putByte(OP2_JP_rel32);
    1030         m_buffer->putInt(0);
    1031         return JmpSrc(m_buffer->size());
    1032     }
    1033    
    1034     JmpSrc emitUnlinkedJs()
    1035     {
    1036         m_buffer->putByte(OP_2BYTE_ESCAPE);
    1037         m_buffer->putByte(OP2_JS_rel32);
    1038         m_buffer->putInt(0);
    1039         return JmpSrc(m_buffer->size());
    1040     }
    1041    
    1042     void emitPredictionNotTaken()
    1043     {
    1044         m_buffer->putByte(PRE_PREDICT_BRANCH_NOT_TAKEN);
    1045     }
    1046    
    1047     void link(JmpSrc from, JmpDst to)
    1048     {
    1049         ASSERT(to.m_offset != -1);
    1050         ASSERT(from.m_offset != -1);
    1051        
    1052         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_buffer->data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
    1053     }
    1054    
    1055     static void linkAbsoluteAddress(void* code, JmpDst useOffset, JmpDst address)
    1056     {
    1057         ASSERT(useOffset.m_offset != -1);
    1058         ASSERT(address.m_offset != -1);
    1059        
    1060         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + useOffset.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(code) + address.m_offset;
    1061     }
    1062    
    1063     static void link(void* code, JmpSrc from, void* to)
    1064     {
    1065         ASSERT(from.m_offset != -1);
    1066        
    1067         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
    1068     }
    1069    
    1070     static void* getRelocatedAddress(void* code, JmpSrc jump)
    1071     {
    1072         return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
    1073     }
    1074    
    1075     static void* getRelocatedAddress(void* code, JmpDst jump)
    1076     {
    1077         return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
    1078     }
    1079    
    1080     static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
    1081     {
    1082         return dst.m_offset - src.m_offset;
    1083     }
    1084    
    1085     static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
    1086     {
    1087         return dst.m_offset - src.m_offset;
    1088     }
    1089    
    1090     static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
    1091     {
    1092         return dst.m_offset - src.m_offset;
    1093     }
    1094    
    1095     static void repatchImmediate(intptr_t where, int32_t value)
    1096     {
    1097         reinterpret_cast<int32_t*>(where)[-1] = value;
    1098     }
    1099    
    1100     static void repatchDisplacement(intptr_t where, intptr_t value)
    1101     {
    1102         reinterpret_cast<intptr_t*>(where)[-1] = value;
    1103     }
    1104    
    1105     static void repatchBranchOffset(intptr_t where, void* destination)
    1106     {
    1107         reinterpret_cast<intptr_t*>(where)[-1] = (reinterpret_cast<intptr_t>(destination) - where);
    1108     }
    1109    
    1110     void* executableCopy()
    1111     {
    1112         return m_buffer->executableCopy();
    1113     }
    1114 
    1115 #if COMPILER(MSVC)
    1116     void emitConvertToFastCall()
    1117     {
    1118         movl_mr(4, X86::esp, X86::eax);
    1119         movl_mr(8, X86::esp, X86::edx);
    1120         movl_mr(12, X86::esp, X86::ecx);
    1121     }
    1122 #else
    1123     void emitConvertToFastCall() {}
    1124 #endif
    1125 
    1126 #if USE(CTI_ARGUMENT)
    1127     void emitRestoreArgumentReference()
    1128     {
    1129 #if USE(FAST_CALL_CTI_ARGUMENT)
    1130         movl_rr(X86::esp, X86::ecx);
    1131 #else
    1132         movl_rm(X86::esp, 0, X86::esp);
    1133 #endif
    1134     }
    1135 
    1136     void emitRestoreArgumentReferenceForTrampoline()
    1137     {
    1138 #if USE(FAST_CALL_CTI_ARGUMENT)
    1139         movl_rr(X86::esp, X86::ecx);
    1140         addl_i32r(4, X86::ecx);
    1141 #endif
    1142     }
    1143 #else
    1144     void emitRestoreArgumentReference() {}
    1145     void emitRestoreArgumentReferenceForTrampoline() {}
    1146 #endif
    1147 
    1148 private:
    1149     void emitModRm_rr(RegisterID reg, RegisterID rm)
    1150     {
    1151         m_buffer->ensureSpace(maxInstructionSize);
    1152         emitModRm_rr_Unchecked(reg, rm);
    1153     }
    1154 
    1155     void emitModRm_rr_Unchecked(RegisterID reg, RegisterID rm)
    1156     {
    1157         m_buffer->putByteUnchecked(MODRM(3, reg, rm));
    1158     }
    1159 
    1160     void emitModRm_rm(RegisterID reg, void* addr)
    1161     {
    1162         m_buffer->putByte(MODRM(0, reg, X86::noBase));
    1163         m_buffer->putInt((int)addr);
    1164     }
    1165 
    1166     void emitModRm_rm(RegisterID reg, RegisterID base)
    1167     {
    1168         if (base == X86::esp) {
    1169             m_buffer->putByte(MODRM(0, reg, X86::hasSib));
    1170             m_buffer->putByte(SIB(0, X86::noScale, X86::esp));
    1171         } else
    1172             m_buffer->putByte(MODRM(0, reg, base));
    1173     }
    1174 
    1175     void emitModRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)
    1176     {
    1177         if (base == X86::esp) {
    1178             if (CAN_SIGN_EXTEND_8_32(offset)) {
    1179                 m_buffer->putByteUnchecked(MODRM(1, reg, X86::hasSib));
    1180                 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
    1181                 m_buffer->putByteUnchecked(offset);
    1182             } else {
    1183                 m_buffer->putByteUnchecked(MODRM(2, reg, X86::hasSib));
    1184                 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
    1185                 m_buffer->putIntUnchecked(offset);
    1186             }
    1187         } else {
    1188             if (CAN_SIGN_EXTEND_8_32(offset)) {
    1189                 m_buffer->putByteUnchecked(MODRM(1, reg, base));
    1190                 m_buffer->putByteUnchecked(offset);
    1191             } else {
    1192                 m_buffer->putByteUnchecked(MODRM(2, reg, base));
    1193                 m_buffer->putIntUnchecked(offset);
    1194             }
    1195         }
    1196     }
    1197 
    1198     void emitModRm_rm(RegisterID reg, RegisterID base, int offset)
    1199     {
    1200         m_buffer->ensureSpace(maxInstructionSize);
    1201         emitModRm_rm_Unchecked(reg, base, offset);
    1202     }
    1203 
    1204     void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale)
    1205     {
    1206         int shift = 0;
    1207         while (scale >>= 1)
    1208             shift++;
    1209    
    1210         m_buffer->putByte(MODRM(0, reg, X86::hasSib));
    1211         m_buffer->putByte(SIB(shift, index, base));
    1212     }
    1213 
    1214     void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset)
    1215     {
    1216         int shift = 0;
    1217         while (scale >>= 1)
    1218             shift++;
    1219    
    1220         if (CAN_SIGN_EXTEND_8_32(offset)) {
    1221             m_buffer->putByte(MODRM(1, reg, X86::hasSib));
    1222             m_buffer->putByte(SIB(shift, index, base));
    1223             m_buffer->putByte(offset);
    1224         } else {
    1225             m_buffer->putByte(MODRM(2, reg, X86::hasSib));
    1226             m_buffer->putByte(SIB(shift, index, base));
    1227             m_buffer->putInt(offset);
    1228         }
    1229     }
    1230 
    1231     void emitModRm_opr(OpcodeID opcodeID, RegisterID rm)
    1232     {
    1233         m_buffer->ensureSpace(maxInstructionSize);
    1234         emitModRm_opr_Unchecked(opcodeID, rm);
    1235     }
    1236 
    1237     void emitModRm_opr_Unchecked(OpcodeID opcodeID, RegisterID rm)
    1238     {
    1239         emitModRm_rr_Unchecked(static_cast<RegisterID>(opcodeID), rm);
    1240     }
    1241 
    1242     void emitModRm_opm(OpcodeID opcodeID, RegisterID base)
    1243     {
    1244         emitModRm_rm(static_cast<RegisterID>(opcodeID), base);
    1245     }
    1246 
    1247     void emitModRm_opm_Unchecked(OpcodeID opcodeID, RegisterID base, int offset)
    1248     {
    1249         emitModRm_rm_Unchecked(static_cast<RegisterID>(opcodeID), base, offset);
    1250     }
    1251 
    1252     void emitModRm_opm(OpcodeID opcodeID, RegisterID base, int offset)
    1253     {
    1254         emitModRm_rm(static_cast<RegisterID>(opcodeID), base, offset);
    1255     }
    1256 
    1257     void emitModRm_opm(OpcodeID opcodeID, void* addr)
    1258     {
    1259         emitModRm_rm(static_cast<RegisterID>(opcodeID), addr);
    1260     }
    1261 
    1262     void emitModRm_opmsib(OpcodeID opcodeID, RegisterID base, RegisterID index, int scale, int offset)
    1263     {
    1264         emitModRm_rmsib(static_cast<RegisterID>(opcodeID), base, index, scale, offset);
    1265     }
    1266 
    1267     AssemblerBuffer* m_buffer;
    1268 };
    1269 
    1270 typedef Vector<X86Assembler::JmpSrc> JmpSrcVector;
    1271144
    1272145} // namespace JSC
    1273146
    1274 #endif // ENABLE(MASM) && PLATFORM(X86)
     147#endif // ENABLE(ASSEMBLER)
    1275148
    1276 #endif // X86Assembler_h
     149#endif // AssemblerBuffer_h
  • trunk/JavaScriptCore/assembler/X86Assembler.h

    r38466 r38487  
    2727#define X86Assembler_h
    2828
    29 #if ENABLE(MASM) && PLATFORM(X86)
    30 
     29#include <wtf/Platform.h>
     30
     31#if ENABLE(ASSEMBLER) && PLATFORM(X86)
     32
     33#include "AssemblerBuffer.h"
    3134#include <wtf/Assertions.h>
    32 #include <wtf/AlwaysInline.h>
    33 #include <wtf/FastMalloc.h>
    34 
    35 #if HAVE(MMAN)
    36 #include <sys/mman.h>
    37 #endif
    38 
    39 #include <string.h>
    4035
    4136namespace JSC {
    42 
    43 class AssemblerBuffer {
    44 public:
    45     AssemblerBuffer(int capacity)
    46         : m_buffer(static_cast<char*>(fastMalloc(capacity)))
    47         , m_capacity(capacity)
    48         , m_size(0)
    49     {
    50     }
    51 
    52     ~AssemblerBuffer()
    53     {
    54         fastFree(m_buffer);
    55     }
    56 
    57     void ensureSpace(int space)
    58     {
    59         if (m_size > m_capacity - space)
    60             grow();
    61     }
    62 
    63     bool isAligned(int alignment)
    64     {
    65         return !(m_size & (alignment - 1));
    66     }
    67    
    68     void putByteUnchecked(int value)
    69     {
    70         ASSERT(!(m_size > m_capacity - 4));
    71         m_buffer[m_size] = value;
    72         m_size++;
    73     }
    74 
    75     void putByte(int value)
    76     {
    77         if (m_size > m_capacity - 4)
    78             grow();
    79         putByteUnchecked(value);
    80     }
    81    
    82     void putShortUnchecked(int value)
    83     {
    84         ASSERT(!(m_size > m_capacity - 4));
    85         *reinterpret_cast<short*>(&m_buffer[m_size]) = value;
    86         m_size += 2;
    87     }
    88 
    89     void putShort(int value)
    90     {
    91         if (m_size > m_capacity - 4)
    92             grow();
    93         putShortUnchecked(value);
    94     }
    95    
    96     void putIntUnchecked(int value)
    97     {
    98         *reinterpret_cast<int*>(&m_buffer[m_size]) = value;
    99         m_size += 4;
    100     }
    101 
    102     void putInt(int value)
    103     {
    104         if (m_size > m_capacity - 4)
    105             grow();
    106         putIntUnchecked(value);
    107     }
    108 
    109     void* data()
    110     {
    111         return m_buffer;
    112     }
    113    
    114     int size()
    115     {
    116         return m_size;
    117     }
    118 
    119     AssemblerBuffer* reset()
    120     {
    121         m_size = 0;
    122         return this;
    123     }
    124    
    125     void* executableCopy()
    126     {
    127         if (!m_size)
    128             return 0;
    129 
    130         void* result = WTF::fastMallocExecutable(m_size);
    131 
    132         if (!result)
    133             return 0;
    134 
    135         return memcpy(result, m_buffer, m_size);
    136     }
    137 
    138 private:
    139     void grow()
    140     {
    141         m_capacity += m_capacity / 2;
    142         m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_capacity));
    143     }
    144 
    145     char* m_buffer;
    146     int m_capacity;
    147     int m_size;
    148 };
    14937
    15038#define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm))
     
    12721160} // namespace JSC
    12731161
    1274 #endif // ENABLE(MASM) && PLATFORM(X86)
     1162#endif // ENABLE(ASSEMBLER) && PLATFORM(X86)
    12751163
    12761164#endif // X86Assembler_h
  • trunk/JavaScriptCore/wtf/Platform.h

    r38477 r38487  
    415415
    416416#if ENABLE(JIT) || ENABLE(WREC)
    417 #define ENABLE_MASM 1
     417#define ENABLE_ASSEMBLER 1
    418418#endif
    419419
Note: See TracChangeset for help on using the changeset viewer.