Ignore:
Timestamp:
Dec 15, 2008, 3:38:19 PM (16 years ago)
Author:
[email protected]
Message:

2008-12-15 Gavin Barraclough <[email protected]>

Reviewed by Geoff Garen.

Add support to X86Assembler emitting instructions that access all 16 registers on x86-64.
Add a new formating class, that is reponsible for both emitting the opcode bytes and the
ModRm bytes of an instruction in a single call; this can insert the REX byte as necessary
before the opcode, but has access to the register numbers to build the REX.

  • assembler/AssemblerBuffer.h: (JSC::AssemblerBuffer::isAligned): (JSC::AssemblerBuffer::data):
  • assembler/MacroAssembler.h: (JSC::MacroAssembler::addPtr): (JSC::MacroAssembler::add32): (JSC::MacroAssembler::and32): (JSC::MacroAssembler::or32): (JSC::MacroAssembler::sub32): (JSC::MacroAssembler::xor32): (JSC::MacroAssembler::loadPtr): (JSC::MacroAssembler::load32): (JSC::MacroAssembler::load16): (JSC::MacroAssembler::storePtr): (JSC::MacroAssembler::storePtrWithRepatch): (JSC::MacroAssembler::store32): (JSC::MacroAssembler::pop): (JSC::MacroAssembler::push): (JSC::MacroAssembler::compareImm32ForBranch): (JSC::MacroAssembler::compareImm32ForBranchEquality): (JSC::MacroAssembler::testImm32): (JSC::MacroAssembler::jae32): (JSC::MacroAssembler::jb32): (JSC::MacroAssembler::je16): (JSC::MacroAssembler::jg32): (JSC::MacroAssembler::jnePtr): (JSC::MacroAssembler::jne32): (JSC::MacroAssembler::jump):
  • assembler/X86Assembler.h: (JSC::X86::): (JSC::X86Assembler::): (JSC::X86Assembler::size): (JSC::X86Assembler::push_r): (JSC::X86Assembler::pop_r): (JSC::X86Assembler::push_i32): (JSC::X86Assembler::push_m): (JSC::X86Assembler::pop_m): (JSC::X86Assembler::addl_rr): (JSC::X86Assembler::addl_mr): (JSC::X86Assembler::addl_ir): (JSC::X86Assembler::addq_ir): (JSC::X86Assembler::addl_im): (JSC::X86Assembler::andl_rr): (JSC::X86Assembler::andl_ir): (JSC::X86Assembler::orl_rr): (JSC::X86Assembler::orl_mr): (JSC::X86Assembler::orl_ir): (JSC::X86Assembler::subl_rr): (JSC::X86Assembler::subl_mr): (JSC::X86Assembler::subl_ir): (JSC::X86Assembler::subl_im): (JSC::X86Assembler::xorl_rr): (JSC::X86Assembler::xorl_ir): (JSC::X86Assembler::sarl_i8r): (JSC::X86Assembler::sarl_CLr): (JSC::X86Assembler::shll_i8r): (JSC::X86Assembler::shll_CLr): (JSC::X86Assembler::imull_rr): (JSC::X86Assembler::imull_i32r): (JSC::X86Assembler::idivl_r): (JSC::X86Assembler::cmpl_rr): (JSC::X86Assembler::cmpl_rm): (JSC::X86Assembler::cmpl_mr): (JSC::X86Assembler::cmpl_ir): (JSC::X86Assembler::cmpl_ir_force32): (JSC::X86Assembler::cmpl_im): (JSC::X86Assembler::cmpl_im_force32): (JSC::X86Assembler::cmpw_rm): (JSC::X86Assembler::testl_rr): (JSC::X86Assembler::testl_i32r): (JSC::X86Assembler::testl_i32m): (JSC::X86Assembler::testq_rr): (JSC::X86Assembler::testq_i32r): (JSC::X86Assembler::testb_i8r): (JSC::X86Assembler::sete_r): (JSC::X86Assembler::setz_r): (JSC::X86Assembler::setne_r): (JSC::X86Assembler::setnz_r): (JSC::X86Assembler::cdq): (JSC::X86Assembler::xchgl_rr): (JSC::X86Assembler::movl_rr): (JSC::X86Assembler::movl_rm): (JSC::X86Assembler::movl_mr): (JSC::X86Assembler::movl_i32r): (JSC::X86Assembler::movl_i32m): (JSC::X86Assembler::movq_rr): (JSC::X86Assembler::movq_rm): (JSC::X86Assembler::movq_mr): (JSC::X86Assembler::movzwl_mr): (JSC::X86Assembler::movzbl_rr): (JSC::X86Assembler::leal_mr): (JSC::X86Assembler::call): (JSC::X86Assembler::jmp): (JSC::X86Assembler::jmp_r): (JSC::X86Assembler::jmp_m): (JSC::X86Assembler::jne): (JSC::X86Assembler::jnz): (JSC::X86Assembler::je): (JSC::X86Assembler::jl): (JSC::X86Assembler::jb): (JSC::X86Assembler::jle): (JSC::X86Assembler::jbe): (JSC::X86Assembler::jge): (JSC::X86Assembler::jg): (JSC::X86Assembler::ja): (JSC::X86Assembler::jae): (JSC::X86Assembler::jo): (JSC::X86Assembler::jp): (JSC::X86Assembler::js): (JSC::X86Assembler::addsd_rr): (JSC::X86Assembler::addsd_mr): (JSC::X86Assembler::cvtsi2sd_rr): (JSC::X86Assembler::cvttsd2si_rr): (JSC::X86Assembler::movd_rr): (JSC::X86Assembler::movsd_rm): (JSC::X86Assembler::movsd_mr): (JSC::X86Assembler::mulsd_rr): (JSC::X86Assembler::mulsd_mr): (JSC::X86Assembler::pextrw_irr): (JSC::X86Assembler::subsd_rr): (JSC::X86Assembler::subsd_mr): (JSC::X86Assembler::ucomis_rr): (JSC::X86Assembler::int3): (JSC::X86Assembler::ret): (JSC::X86Assembler::predictNotTaken): (JSC::X86Assembler::label): (JSC::X86Assembler::align): (JSC::X86Assembler::link): (JSC::X86Assembler::executableCopy): (JSC::X86Assembler::X86InstructionFormater::prefix): (JSC::X86Assembler::X86InstructionFormater::oneByteOp): (JSC::X86Assembler::X86InstructionFormater::twoByteOp): (JSC::X86Assembler::X86InstructionFormater::oneByteOp64): (JSC::X86Assembler::X86InstructionFormater::oneByteOp8): (JSC::X86Assembler::X86InstructionFormater::twoByteOp8): (JSC::X86Assembler::X86InstructionFormater::instructionImmediate8): (JSC::X86Assembler::X86InstructionFormater::instructionImmediate32): (JSC::X86Assembler::X86InstructionFormater::instructionRel32): (JSC::X86Assembler::X86InstructionFormater::size): (JSC::X86Assembler::X86InstructionFormater::isAligned): (JSC::X86Assembler::X86InstructionFormater::data): (JSC::X86Assembler::X86InstructionFormater::executableCopy): (JSC::X86Assembler::X86InstructionFormater::registerModRM): (JSC::X86Assembler::X86InstructionFormater::memoryModRM):
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompile): (JSC::JIT::privateCompileCTIMachineTrampolines):
  • jit/JITArithmetic.cpp: (JSC::JIT::putDoubleResultToJSNumberCellOrJSImmediate): (JSC::JIT::compileBinaryArithOp):
  • jit/JITCall.cpp: (JSC::JIT::compileOpCall): (JSC::JIT::compileOpCallSlowCase):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::compileGetByIdHotPath): (JSC::JIT::compilePutByIdHotPath): (JSC::JIT::privateCompilePutByIdTransition): (JSC::JIT::privateCompilePatchGetArrayLength): (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/assembler/X86Assembler.h

    r39287 r39316  
    3838namespace JSC {
    3939
    40 #define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm))
    41 #define SIB(type, reg, rm) MODRM(type, reg, rm)
    4240#define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value))
    4341
     
    5351        edi,
    5452
    55         noBase = ebp,
    56         hasSib = esp,
    57         noScale = esp,
     53#if PLATFORM(X86_64)
     54        r8,
     55        r9,
     56        r10,
     57        r11,
     58        r12,
     59        r13,
     60        r14,
     61        r15,
     62#endif
    5863    } RegisterID;
    5964
     
    8893        OP_CMP_EvGv                     = 0x39,
    8994        OP_CMP_GvEv                     = 0x3B,
    90         REX_W                           = 0x48,
     95#if PLATFORM(X86_64)
     96        PRE_REX                         = 0x40,
     97#endif
    9198        OP_PUSH_EAX                     = 0x50,
    9299        OP_POP_EAX                      = 0x58,
     
    104111        OP_GROUP1A_Ev                   = 0x8F,
    105112        OP_CDQ                          = 0x99,
    106         OP_SETE                         = 0x94,
    107         OP_SETNE                        = 0x95,
    108113        OP_GROUP2_EvIb                  = 0xC1,
    109114        OP_RET                          = 0xC3,
     
    120125        OP_GROUP3_EvIz                  = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
    121126        OP_GROUP5_Ev                    = 0xFF,
    122 
     127    } OneByteOpcodeID;
     128
     129    typedef enum {
    123130        OP2_MOVSD_VsdWsd    = 0x10,
    124131        OP2_MOVSD_WsdVsd    = 0x11,
     
    143150        OP2_JLE_rel32       = 0x8E,
    144151        OP2_JG_rel32        = 0x8F,
     152        OP_SETE             = 0x94,
     153        OP_SETNE            = 0x95,
    145154        OP2_IMUL_GvEv       = 0xAF,
    146155        OP2_MOVZX_GvEb      = 0xB6,
    147156        OP2_MOVZX_GvEw      = 0xB7,
    148157        OP2_PEXTRW_GdUdIb   = 0xC5,
    149 
     158    } TwoByteOpcodeID;
     159
     160    typedef enum {
    150161        GROUP1_OP_ADD = 0,
    151162        GROUP1_OP_OR  = 1,
     
    168179
    169180        GROUP11_MOV = 0,
    170     } OpcodeID;
     181    } GroupOpcodeID;
    171182   
    172183    // Opaque label types
    173184   
     185    class X86InstructionFormatter;
     186
    174187    class JmpSrc {
    175188        friend class X86Assembler;
     189        friend class X86InstructionFormatter;
    176190    public:
    177191        JmpSrc()
     
    191205    class JmpDst {
    192206        friend class X86Assembler;
     207        friend class X86InstructionFormatter;
    193208    public:
    194209        JmpDst()
     
    206221    };
    207222
    208     static const int maxInstructionSize = 16;
    209 
    210223    X86Assembler()
    211224    {
    212225    }
    213226
    214     size_t size() const { return m_buffer.size(); }
    215    
    216     void int3()
    217     {
    218         m_buffer.putByte(OP_INT3);
    219     }
    220    
     227    size_t size() const { return m_formatter.size(); }
     228
     229    // Stack operations:
     230
     231    void push_r(RegisterID reg)
     232    {
     233        m_formatter.oneByteOp(OP_PUSH_EAX, reg);
     234    }
     235
     236    void pop_r(RegisterID reg)
     237    {
     238        m_formatter.oneByteOp(OP_POP_EAX, reg);
     239    }
     240
     241    void push_i32(int imm)
     242    {
     243        m_formatter.oneByteOp(OP_PUSH_Iz);
     244        m_formatter.immediate32(imm);
     245    }
     246
     247    void push_m(int offset, RegisterID base)
     248    {
     249        m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
     250    }
     251
     252    void pop_m(int offset, RegisterID base)
     253    {
     254        m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
     255    }
     256
     257    // Arithmetic operations:
     258
     259    void addl_rr(RegisterID src, RegisterID dst)
     260    {
     261        m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
     262    }
     263
     264    void addl_mr(int offset, RegisterID base, RegisterID dst)
     265    {
     266        m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
     267    }
     268
     269    void addl_ir(int imm, RegisterID dst)
     270    {
     271        if (CAN_SIGN_EXTEND_8_32(imm)) {
     272            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
     273            m_formatter.immediate8(imm);
     274        } else {
     275            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
     276            m_formatter.immediate32(imm);
     277        }
     278    }
     279
    221280#if PLATFORM(X86_64)
    222     void pushq_r(RegisterID reg)
    223     {
    224         m_buffer.putByte(OP_PUSH_EAX + reg);
    225     }
    226 
    227     void popq_r(RegisterID reg)
    228     {
    229         m_buffer.putByte(OP_POP_EAX + reg);
     281    void addq_ir(int imm, RegisterID dst)
     282    {
     283        if (CAN_SIGN_EXTEND_8_32(imm)) {
     284            m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
     285            m_formatter.immediate8(imm);
     286        } else {
     287            m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
     288            m_formatter.immediate32(imm);
     289        }
    230290    }
    231291#else
    232     void pushl_r(RegisterID reg)
    233     {
    234         m_buffer.putByte(OP_PUSH_EAX + reg);
    235     }
    236    
    237     void pushl_m(int offset, RegisterID base)
    238     {
    239         m_buffer.putByte(OP_GROUP5_Ev);
    240         modRm_opm(GROUP5_OP_PUSH, base, offset);
    241     }
    242 
    243     void pushl_i32(int imm)
    244     {
    245         m_buffer.putByte(OP_PUSH_Iz);
    246         m_buffer.putInt(imm);
    247     }
    248    
    249     void popl_r(RegisterID reg)
    250     {
    251         m_buffer.putByte(OP_POP_EAX + reg);
    252     }
    253 
    254     void popl_m(int offset, RegisterID base)
    255     {
    256         m_buffer.putByte(OP_GROUP1A_Ev);
    257         modRm_opm(GROUP1A_OP_POP, base, offset);
     292    void addl_im(int imm, void* addr)
     293    {
     294        if (CAN_SIGN_EXTEND_8_32(imm)) {
     295            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
     296            m_formatter.immediate8(imm);
     297        } else {
     298            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
     299            m_formatter.immediate32(imm);
     300        }
    258301    }
    259302#endif
    260    
     303
     304    void andl_rr(RegisterID src, RegisterID dst)
     305    {
     306        m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
     307    }
     308
     309    void andl_ir(int imm, RegisterID dst)
     310    {
     311        if (CAN_SIGN_EXTEND_8_32(imm)) {
     312            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
     313            m_formatter.immediate8(imm);
     314        } else {
     315            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
     316            m_formatter.immediate32(imm);
     317        }
     318    }
     319
     320    void orl_rr(RegisterID src, RegisterID dst)
     321    {
     322        m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
     323    }
     324
     325    void orl_mr(int offset, RegisterID base, RegisterID dst)
     326    {
     327        m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
     328    }
     329
     330    void orl_ir(int imm, RegisterID dst)
     331    {
     332        if (CAN_SIGN_EXTEND_8_32(imm)) {
     333            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
     334            m_formatter.immediate8(imm);
     335        } else {
     336            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
     337            m_formatter.immediate32(imm);
     338        }
     339    }
     340
     341    void subl_rr(RegisterID src, RegisterID dst)
     342    {
     343        m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
     344    }
     345
     346    void subl_mr(int offset, RegisterID base, RegisterID dst)
     347    {
     348        m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
     349    }
     350
     351    void subl_ir(int imm, RegisterID dst)
     352    {
     353        if (CAN_SIGN_EXTEND_8_32(imm)) {
     354            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
     355            m_formatter.immediate8(imm);
     356        } else {
     357            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
     358            m_formatter.immediate32(imm);
     359        }
     360    }
     361   
     362#if !PLATFORM(X86_64)
     363    void subl_im(int imm, void* addr)
     364    {
     365        if (CAN_SIGN_EXTEND_8_32(imm)) {
     366            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
     367            m_formatter.immediate8(imm);
     368        } else {
     369            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
     370            m_formatter.immediate32(imm);
     371        }
     372    }
     373#endif
     374
     375    void xorl_rr(RegisterID src, RegisterID dst)
     376    {
     377        m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
     378    }
     379
     380    void xorl_ir(int imm, RegisterID dst)
     381    {
     382        if (CAN_SIGN_EXTEND_8_32(imm)) {
     383            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
     384            m_formatter.immediate8(imm);
     385        } else {
     386            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
     387            m_formatter.immediate32(imm);
     388        }
     389    }
     390
     391    void sarl_i8r(int imm, RegisterID dst)
     392    {
     393        if (imm == 1)
     394            m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
     395        else {
     396            m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
     397            m_formatter.immediate8(imm);
     398        }
     399    }
     400
     401    void sarl_CLr(RegisterID dst)
     402    {
     403        m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
     404    }
     405
     406    void shll_i8r(int imm, RegisterID dst)
     407    {
     408        if (imm == 1)
     409            m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
     410        else {
     411            m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
     412            m_formatter.immediate8(imm);
     413        }
     414    }
     415
     416    void shll_CLr(RegisterID dst)
     417    {
     418        m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
     419    }
     420
     421    void imull_rr(RegisterID src, RegisterID dst)
     422    {
     423        m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
     424    }
     425   
     426    void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
     427    {
     428        m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
     429        m_formatter.immediate32(value);
     430    }
     431
     432    void idivl_r(RegisterID dst)
     433    {
     434        m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
     435    }
     436
     437    // Comparisons:
     438
     439    void cmpl_rr(RegisterID src, RegisterID dst)
     440    {
     441        m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
     442    }
     443
     444    void cmpl_rm(RegisterID src, int offset, RegisterID base)
     445    {
     446        m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
     447    }
     448
     449    void cmpl_mr(int offset, RegisterID base, RegisterID src)
     450    {
     451        m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
     452    }
     453
     454    void cmpl_ir(int imm, RegisterID dst)
     455    {
     456        if (CAN_SIGN_EXTEND_8_32(imm)) {
     457            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
     458            m_formatter.immediate8(imm);
     459        } else {
     460            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
     461            m_formatter.immediate32(imm);
     462        }
     463    }
     464
     465    void cmpl_ir_force32(int imm, RegisterID dst)
     466    {
     467        m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
     468        m_formatter.immediate32(imm);
     469    }
     470
     471    void cmpl_im(int imm, int offset, RegisterID base)
     472    {
     473        if (CAN_SIGN_EXTEND_8_32(imm)) {
     474            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
     475            m_formatter.immediate8(imm);
     476        } else {
     477            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
     478            m_formatter.immediate32(imm);
     479        }
     480    }
     481
     482    void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
     483    {
     484        if (CAN_SIGN_EXTEND_8_32(imm)) {
     485            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
     486            m_formatter.immediate8(imm);
     487        } else {
     488            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
     489            m_formatter.immediate32(imm);
     490        }
     491    }
     492
     493    void cmpl_im_force32(int imm, int offset, RegisterID base)
     494    {
     495        m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
     496        m_formatter.immediate32(imm);
     497    }
     498
     499#if !PLATFORM(X86_64)
     500    void cmpl_im(int imm, void* addr)
     501    {
     502        if (CAN_SIGN_EXTEND_8_32(imm)) {
     503            m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
     504            m_formatter.immediate8(imm);
     505        } else {
     506            m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
     507            m_formatter.immediate32(imm);
     508        }
     509    }
     510#endif
     511
     512    void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
     513    {
     514        m_formatter.prefix(PRE_OPERAND_SIZE);
     515        m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
     516    }
     517
     518    void testl_rr(RegisterID src, RegisterID dst)
     519    {
     520        m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
     521    }
     522   
     523    void testl_i32r(int imm, RegisterID dst)
     524    {
     525        m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
     526        m_formatter.immediate32(imm);
     527    }
     528
     529    void testl_i32m(int imm, int offset, RegisterID base)
     530    {
     531        m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
     532        m_formatter.immediate32(imm);
     533    }
     534
     535    void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
     536    {
     537        m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
     538        m_formatter.immediate32(imm);
     539    }
     540
     541#if PLATFORM(X86_64)
     542    void testq_rr(RegisterID src, RegisterID dst)
     543    {
     544        m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
     545    }
     546
     547    void testq_i32r(int imm, RegisterID dst)
     548    {
     549        m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP3_OP_TEST, dst);
     550        m_formatter.immediate32(imm);
     551    }
     552#endif
     553
     554    void testb_i8r(int imm, RegisterID dst)
     555    {
     556        m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
     557        m_formatter.immediate8(imm);
     558    }
     559
     560    void sete_r(RegisterID dst)
     561    {
     562        m_formatter.twoByteOp8(OP_SETE, (GroupOpcodeID)0, dst);
     563    }
     564
     565    void setz_r(RegisterID dst)
     566    {
     567        sete_r(dst);
     568    }
     569
     570    void setne_r(RegisterID dst)
     571    {
     572        m_formatter.twoByteOp8(OP_SETNE, (GroupOpcodeID)0, dst);
     573    }
     574
     575    void setnz_r(RegisterID dst)
     576    {
     577        setne_r(dst);
     578    }
     579
     580    // Various move ops:
     581
     582    void cdq()
     583    {
     584        m_formatter.oneByteOp(OP_CDQ);
     585    }
     586
     587    void xchgl_rr(RegisterID src, RegisterID dst)
     588    {
     589        m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
     590    }
     591
     592#if PLATFORM(X86_64)
     593    void xchgq_rr(RegisterID src, RegisterID dst)
     594    {
     595        m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
     596    }
     597#endif
     598
    261599    void movl_rr(RegisterID src, RegisterID dst)
    262600    {
    263         m_buffer.putByte(OP_MOV_EvGv);
    264         modRm_rr(src, dst);
    265     }
    266    
     601        m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
     602    }
     603   
     604    void movl_rm(RegisterID src, int offset, RegisterID base)
     605    {
     606        m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
     607    }
     608
     609    void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
     610    {
     611        m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
     612    }
     613   
     614    void movl_mr(int offset, RegisterID base, RegisterID dst)
     615    {
     616        m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
     617    }
     618
     619    void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
     620    {
     621        m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
     622    }
     623
     624    void movl_i32r(int imm, RegisterID dst)
     625    {
     626        m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, dst);
     627        m_formatter.immediate32(imm);
     628    }
     629
     630    void movl_i32m(int imm, int offset, RegisterID base)
     631    {
     632        m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
     633        m_formatter.immediate32(imm);
     634    }
     635
    267636#if PLATFORM(X86_64)
    268637    void movq_rr(RegisterID src, RegisterID dst)
    269638    {
    270         m_buffer.putByte(REX_W);
    271         m_buffer.putByte(OP_MOV_EvGv);
    272         modRm_rr(src, dst);
     639        m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
     640    }
     641
     642    void movq_rm(RegisterID src, int offset, RegisterID base)
     643    {
     644        m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
     645    }
     646
     647    void movq_mr(int offset, RegisterID base, RegisterID dst)
     648    {
     649        m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
     650    }
     651#else
     652    void movl_mr(void* addr, RegisterID dst)
     653    {
     654        m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
     655    }
     656
     657    void movl_i32m(int imm, void* addr)
     658    {
     659        m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
     660        m_formatter.immediate32(imm);
    273661    }
    274662#endif
    275663
    276     void addl_rr(RegisterID src, RegisterID dst)
    277     {
    278         m_buffer.putByte(OP_ADD_EvGv);
    279         modRm_rr(src, dst);
    280     }
    281 
    282 #if !PLATFORM(X86_64)
    283     void addl_i8m(int imm, void* addr)
    284     {
    285         m_buffer.putByte(OP_GROUP1_EvIb);
    286         modRm_opm(GROUP1_OP_ADD, addr);
    287         m_buffer.putByte(imm);
    288     }
    289 #endif
    290 
    291     void addl_i8r(int imm, RegisterID dst)
    292     {
    293         m_buffer.putByte(OP_GROUP1_EvIb);
    294         modRm_opr(GROUP1_OP_ADD, dst);
    295         m_buffer.putByte(imm);
    296     }
    297 
    298     void addl_i32r(int imm, RegisterID dst)
    299     {
    300         m_buffer.putByte(OP_GROUP1_EvIz);
    301         modRm_opr(GROUP1_OP_ADD, dst);
    302         m_buffer.putInt(imm);
    303     }
    304 
    305 #if PLATFORM(X86_64)
    306     void addq_i8r(int imm, RegisterID dst)
    307     {
    308         m_buffer.putByte(REX_W);
    309         m_buffer.putByte(OP_GROUP1_EvIb);
    310         modRm_opr(GROUP1_OP_ADD, dst);
    311         m_buffer.putByte(imm);
    312     }
    313 
    314     void addq_i32r(int imm, RegisterID dst)
    315     {
    316         m_buffer.putByte(REX_W);
    317         m_buffer.putByte(OP_GROUP1_EvIz);
    318         modRm_opr(GROUP1_OP_ADD, dst);
    319         m_buffer.putInt(imm);
    320     }
    321 #endif
    322 
    323     void addl_mr(RegisterID base, RegisterID dst)
    324     {
    325         m_buffer.putByte(OP_ADD_GvEv);
    326         modRm_rm(dst, base);
    327     }
    328 
    329     void addl_mr(int offset, RegisterID base, RegisterID dst)
    330     {
    331         m_buffer.putByte(OP_ADD_GvEv);
    332         modRm_rm(dst, base, offset);
    333     }
    334 
    335     void andl_rr(RegisterID src, RegisterID dst)
    336     {
    337         m_buffer.putByte(OP_AND_EvGv);
    338         modRm_rr(src, dst);
    339     }
    340 
    341     void andl_i8r(int imm, RegisterID dst)
    342     {
    343         m_buffer.putByte(OP_GROUP1_EvIb);
    344         modRm_opr(GROUP1_OP_AND, dst);
    345         m_buffer.putByte(imm);
    346     }
    347 
    348     void andl_i32r(int imm, RegisterID dst)
    349     {
    350         m_buffer.putByte(OP_GROUP1_EvIz);
    351         modRm_opr(GROUP1_OP_AND, dst);
    352         m_buffer.putInt(imm);
    353     }
    354 
    355     void cmpl_i8r(int imm, RegisterID dst)
    356     {
    357         m_buffer.putByte(OP_GROUP1_EvIb);
    358         modRm_opr(GROUP1_OP_CMP, dst);
    359         m_buffer.putByte(imm);
    360     }
    361 
    362     void cmpl_rr(RegisterID src, RegisterID dst)
    363     {
    364         m_buffer.putByte(OP_CMP_EvGv);
    365         modRm_rr(src, dst);
    366     }
    367 
    368     void cmpl_rm(RegisterID src, RegisterID base)
    369     {
    370         m_buffer.putByte(OP_CMP_EvGv);
    371         modRm_rm(src, base);
    372     }
    373 
    374     void cmpl_rm(RegisterID src, int offset, RegisterID base)
    375     {
    376         m_buffer.putByte(OP_CMP_EvGv);
    377         modRm_rm(src, base, offset);
    378     }
    379 
    380     void cmpl_mr(RegisterID base, RegisterID dst)
    381     {
    382         m_buffer.putByte(OP_CMP_GvEv);
    383         modRm_rm(dst, base);
    384     }
    385 
    386     void cmpl_mr(int offset, RegisterID base, RegisterID dst)
    387     {
    388         m_buffer.putByte(OP_CMP_GvEv);
    389         modRm_rm(dst, base, offset);
    390     }
    391 
    392     void cmpl_i32r(int imm, RegisterID dst)
    393     {
    394         m_buffer.putByte(OP_GROUP1_EvIz);
    395         modRm_opr(GROUP1_OP_CMP, dst);
    396         m_buffer.putInt(imm);
    397     }
    398 
    399     void cmpl_i32m(int imm, RegisterID dst)
    400     {
    401         m_buffer.putByte(OP_GROUP1_EvIz);
    402         modRm_opm(GROUP1_OP_CMP, dst);
    403         m_buffer.putInt(imm);
    404     }
    405 
    406     void cmpl_i32m(int imm, int offset, RegisterID dst)
    407     {
    408         m_buffer.putByte(OP_GROUP1_EvIz);
    409         modRm_opm(GROUP1_OP_CMP, dst, offset);
    410         m_buffer.putInt(imm);
    411     }
    412 
    413 #if !PLATFORM(X86_64)
    414     void cmpl_i32m(int imm, void* addr)
    415     {
    416         m_buffer.putByte(OP_GROUP1_EvIz);
    417         modRm_opm(GROUP1_OP_CMP, addr);
    418         m_buffer.putInt(imm);
    419     }
    420 #endif
    421 
    422     void cmpl_i8m(int imm, RegisterID dst)
    423     {
    424         m_buffer.putByte(OP_GROUP1_EvIb);
    425         modRm_opm(GROUP1_OP_CMP, dst);
    426         m_buffer.putByte(imm);
    427     }
    428 
    429     void cmpl_i8m(int imm, int offset, RegisterID dst)
    430     {
    431         m_buffer.putByte(OP_GROUP1_EvIb);
    432         modRm_opm(GROUP1_OP_CMP, dst, offset);
    433         m_buffer.putByte(imm);
    434     }
    435 
    436     void cmpl_i8m(int imm, RegisterID base, RegisterID index, int scale)
    437     {
    438         m_buffer.putByte(OP_GROUP1_EvIb);
    439         modRm_opmsib(GROUP1_OP_CMP, base, index, scale);
    440         m_buffer.putByte(imm);
    441     }
    442 
    443     void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
    444     {
    445         m_buffer.putByte(OP_GROUP1_EvIb);
    446         modRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset);
    447         m_buffer.putByte(imm);
    448     }
    449 
    450     void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
    451     {
    452         m_buffer.putByte(PRE_OPERAND_SIZE);
    453         m_buffer.putByte(OP_CMP_EvGv);
    454         modRm_rmsib(src, base, index, scale);
    455     }
    456 
    457     void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
    458     {
    459         m_buffer.putByte(PRE_OPERAND_SIZE);
    460         m_buffer.putByte(OP_CMP_EvGv);
    461         modRm_rmsib(src, base, index, scale, offset);
    462     }
    463 
    464     void sete_r(RegisterID dst)
    465     {
    466         m_buffer.putByte(OP_2BYTE_ESCAPE);
    467         m_buffer.putByte(OP_SETE);
    468         m_buffer.putByte(MODRM(3, 0, dst));
    469     }
    470 
    471     void setz_r(RegisterID dst)
    472     {
    473         sete_r(dst);
    474     }
    475 
    476     void setne_r(RegisterID dst)
    477     {
    478         m_buffer.putByte(OP_2BYTE_ESCAPE);
    479         m_buffer.putByte(OP_SETNE);
    480         m_buffer.putByte(MODRM(3, 0, dst));
    481     }
    482 
    483     void setnz_r(RegisterID dst)
    484     {
    485         setne_r(dst);
    486     }
    487 
    488     void orl_rr(RegisterID src, RegisterID dst)
    489     {
    490         m_buffer.putByte(OP_OR_EvGv);
    491         modRm_rr(src, dst);
    492     }
    493 
    494     void orl_mr(int offset, RegisterID base, RegisterID dst)
    495     {
    496         m_buffer.putByte(OP_OR_GvEv);
    497         modRm_rm(dst, base, offset);
    498     }
    499 
    500     void orl_i8r(int imm, RegisterID dst)
    501     {
    502         m_buffer.putByte(OP_GROUP1_EvIb);
    503         modRm_opr(GROUP1_OP_OR, dst);
    504         m_buffer.putByte(imm);
    505     }
    506 
    507     void orl_i32r(int imm, RegisterID dst)
    508     {
    509         m_buffer.putByte(OP_GROUP1_EvIz);
    510         modRm_opr(GROUP1_OP_OR, dst);
    511         m_buffer.putInt(imm);
    512     }
    513 
    514     void subl_rr(RegisterID src, RegisterID dst)
    515     {
    516         m_buffer.putByte(OP_SUB_EvGv);
    517         modRm_rr(src, dst);
    518     }
    519 
    520     void subl_i8r(int imm, RegisterID dst)
    521     {
    522         m_buffer.putByte(OP_GROUP1_EvIb);
    523         modRm_opr(GROUP1_OP_SUB, dst);
    524         m_buffer.putByte(imm);
    525     }
    526    
    527 #if !PLATFORM(X86_64)
    528     void subl_i8m(int imm, void* addr)
    529     {
    530         m_buffer.putByte(OP_GROUP1_EvIb);
    531         modRm_opm(GROUP1_OP_SUB, addr);
    532         m_buffer.putByte(imm);
    533     }
    534 #endif
    535 
    536     void subl_i32r(int imm, RegisterID dst)
    537     {
    538         m_buffer.putByte(OP_GROUP1_EvIz);
    539         modRm_opr(GROUP1_OP_SUB, dst);
    540         m_buffer.putInt(imm);
    541     }
    542 
    543     void subl_mr(RegisterID base, RegisterID dst)
    544     {
    545         m_buffer.putByte(OP_SUB_GvEv);
    546         modRm_rm(dst, base);
    547     }
    548 
    549     void subl_mr(int offset, RegisterID base, RegisterID dst)
    550     {
    551         m_buffer.putByte(OP_SUB_GvEv);
    552         modRm_rm(dst, base, offset);
    553     }
    554 
    555     void testb_i8r(int imm, RegisterID dst)
    556     {
    557         m_buffer.ensureSpace(maxInstructionSize);
    558         m_buffer.putByteUnchecked(OP_GROUP3_EbIb);
    559         modRm_opr_Unchecked(GROUP3_OP_TEST, dst);
    560         m_buffer.putByteUnchecked(imm);
    561     }
    562 
    563     void testl_i32r(int imm, RegisterID dst)
    564     {
    565         m_buffer.ensureSpace(maxInstructionSize);
    566         m_buffer.putByteUnchecked(OP_GROUP3_EvIz);
    567         modRm_opr_Unchecked(GROUP3_OP_TEST, dst);
    568         m_buffer.putIntUnchecked(imm);
    569     }
    570 
    571     void testl_i32m(int imm, RegisterID dst)
    572     {
    573         m_buffer.putByte(OP_GROUP3_EvIz);
    574         modRm_opm(GROUP3_OP_TEST, dst);
    575         m_buffer.putInt(imm);
    576     }
    577 
    578     void testl_i32m(int imm, int offset, RegisterID dst)
    579     {
    580         m_buffer.putByte(OP_GROUP3_EvIz);
    581         modRm_opm(GROUP3_OP_TEST, dst, offset);
    582         m_buffer.putInt(imm);
    583     }
    584 
    585     void testl_i32m(int imm, RegisterID base, RegisterID index, int scale)
    586     {
    587         m_buffer.putByte(OP_GROUP3_EvIz);
    588         modRm_opmsib(GROUP3_OP_TEST, base, index, scale);
    589         m_buffer.putInt(imm);
    590     }
    591 
    592     void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
    593     {
    594         m_buffer.putByte(OP_GROUP3_EvIz);
    595         modRm_opmsib(GROUP3_OP_TEST, base, index, scale, offset);
    596         m_buffer.putInt(imm);
    597     }
    598 
    599     void testl_rr(RegisterID src, RegisterID dst)
    600     {
    601         m_buffer.putByte(OP_TEST_EvGv);
    602         modRm_rr(src, dst);
    603     }
    604    
    605 #if PLATFORM(X86_64)
    606     void testq_i32r(int imm, RegisterID dst)
    607     {
    608         m_buffer.ensureSpace(maxInstructionSize);
    609         m_buffer.putByteUnchecked(REX_W);
    610         m_buffer.putByteUnchecked(OP_GROUP3_EvIz);
    611         modRm_opr_Unchecked(GROUP3_OP_TEST, dst);
    612         m_buffer.putIntUnchecked(imm);
    613     }
    614 
    615     void testq_rr(RegisterID src, RegisterID dst)
    616     {
    617         m_buffer.putByte(REX_W);
    618         m_buffer.putByte(OP_TEST_EvGv);
    619         modRm_rr(src, dst);
    620     }
    621 #endif
    622 
    623     void xorl_i8r(int imm, RegisterID dst)
    624     {
    625         m_buffer.putByte(OP_GROUP1_EvIb);
    626         modRm_opr(GROUP1_OP_XOR, dst);
    627         m_buffer.putByte(imm);
    628     }
    629 
    630     void xorl_i32r(int imm, RegisterID dst)
    631     {
    632         m_buffer.putByte(OP_GROUP1_EvIz);
    633         modRm_opr(GROUP1_OP_XOR, dst);
    634         m_buffer.putInt(imm);
    635     }
    636 
    637     void xorl_rr(RegisterID src, RegisterID dst)
    638     {
    639         m_buffer.putByte(OP_XOR_EvGv);
    640         modRm_rr(src, dst);
    641     }
    642 
    643     void sarl_i8r(int imm, RegisterID dst)
    644     {
    645         if (imm == 1) {
    646             m_buffer.putByte(OP_GROUP2_Ev1);
    647             modRm_opr(GROUP2_OP_SAR, dst);
    648         } else {
    649             m_buffer.putByte(OP_GROUP2_EvIb);
    650             modRm_opr(GROUP2_OP_SAR, dst);
    651             m_buffer.putByte(imm);
    652         }
    653     }
    654 
    655     void sarl_CLr(RegisterID dst)
    656     {
    657         m_buffer.putByte(OP_GROUP2_EvCL);
    658         modRm_opr(GROUP2_OP_SAR, dst);
    659     }
    660 
    661     void shll_i8r(int imm, RegisterID dst)
    662     {
    663         if (imm == 1) {
    664             m_buffer.putByte(OP_GROUP2_Ev1);
    665             modRm_opr(GROUP2_OP_SHL, dst);
    666         } else {
    667             m_buffer.putByte(OP_GROUP2_EvIb);
    668             modRm_opr(GROUP2_OP_SHL, dst);
    669             m_buffer.putByte(imm);
    670         }
    671     }
    672 
    673     void shll_CLr(RegisterID dst)
    674     {
    675         m_buffer.putByte(OP_GROUP2_EvCL);
    676         modRm_opr(GROUP2_OP_SHL, dst);
    677     }
    678 
    679     void xchgl_rr(RegisterID src, RegisterID dst)
    680     {
    681         m_buffer.putByte(OP_XCHG_EvGv);
    682         modRm_rr(src, dst);
    683     }
    684 
    685     void imull_rr(RegisterID src, RegisterID dst)
    686     {
    687         m_buffer.putByte(OP_2BYTE_ESCAPE);
    688         m_buffer.putByte(OP2_IMUL_GvEv);
    689         modRm_rr(dst, src);
    690     }
    691    
    692     void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
    693     {
    694         m_buffer.putByte(OP_IMUL_GvEvIz);
    695         modRm_rr(dst, src);
    696         m_buffer.putInt(value);
    697     }
    698 
    699     void idivl_r(RegisterID dst)
    700     {
    701         m_buffer.putByte(OP_GROUP3_Ev);
    702         modRm_opr(GROUP3_OP_IDIV, dst);
    703     }
    704 
    705     void cdq()
    706     {
    707         m_buffer.putByte(OP_CDQ);
    708     }
    709 
    710     void movl_mr(RegisterID base, RegisterID dst)
    711     {
    712         m_buffer.putByte(OP_MOV_GvEv);
    713         modRm_rm(dst, base);
    714     }
    715 
    716     void movl_mr(int offset, RegisterID base, RegisterID dst)
    717     {
    718         m_buffer.ensureSpace(maxInstructionSize);
    719         m_buffer.putByteUnchecked(OP_MOV_GvEv);
    720         modRm_rm_Unchecked(dst, base, offset);
    721     }
    722 
    723 #if PLATFORM(X86_64)
    724     void movq_mr(RegisterID base, RegisterID dst)
    725     {
    726         m_buffer.putByte(REX_W);
    727         m_buffer.putByte(OP_MOV_GvEv);
    728         modRm_rm(dst, base);
    729     }
    730 
    731     void movq_mr(int offset, RegisterID base, RegisterID dst)
    732     {
    733         m_buffer.ensureSpace(maxInstructionSize);
    734         m_buffer.putByteUnchecked(REX_W);
    735         m_buffer.putByteUnchecked(OP_MOV_GvEv);
    736         modRm_rm_Unchecked(dst, base, offset);
    737     }
    738 #endif
    739 
    740 #if !PLATFORM(X86_64)
    741     void movl_mr(void* addr, RegisterID dst)
    742     {
    743         m_buffer.putByte(OP_MOV_GvEv);
    744         modRm_rm(dst, addr);
    745     }
    746 #endif
    747 
    748     void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    749     {
    750         m_buffer.putByte(OP_MOV_GvEv);
    751         modRm_rmsib(dst, base, index, scale, offset);
    752     }
    753 
    754     void movl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
    755     {
    756         m_buffer.putByte(OP_MOV_GvEv);
    757         modRm_rmsib(dst, base, index, scale);
     664    void movzwl_mr(int offset, RegisterID base, RegisterID dst)
     665    {
     666        m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
     667    }
     668
     669    void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
     670    {
     671        m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
    758672    }
    759673
    760674    void movzbl_rr(RegisterID src, RegisterID dst)
    761675    {
    762         m_buffer.putByte(OP_2BYTE_ESCAPE);
    763         m_buffer.putByte(OP2_MOVZX_GvEb);
    764         modRm_rr(dst, src);
    765     }
    766 
    767     void movzwl_mr(int offset, RegisterID base, RegisterID dst)
    768     {
    769         m_buffer.putByte(OP_2BYTE_ESCAPE);
    770         m_buffer.putByte(OP2_MOVZX_GvEw);
    771         modRm_rm(dst, base, offset);
    772     }
    773 
    774     void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
    775     {
    776         m_buffer.putByte(OP_2BYTE_ESCAPE);
    777         m_buffer.putByte(OP2_MOVZX_GvEw);
    778         modRm_rmsib(dst, base, index, scale);
    779     }
    780 
    781     void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
    782     {
    783         m_buffer.putByte(OP_2BYTE_ESCAPE);
    784         m_buffer.putByte(OP2_MOVZX_GvEw);
    785         modRm_rmsib(dst, base, index, scale, offset);
    786     }
    787 
    788     void movl_rm(RegisterID src, RegisterID base)
    789     {
    790         m_buffer.putByte(OP_MOV_EvGv);
    791         modRm_rm(src, base);
    792     }
    793 
    794     void movl_rm(RegisterID src, int offset, RegisterID base)
    795     {
    796         m_buffer.ensureSpace(maxInstructionSize);
    797         m_buffer.putByteUnchecked(OP_MOV_EvGv);
    798         modRm_rm_Unchecked(src, base, offset);
    799     }
    800 
    801 #if PLATFORM(X86_64)
    802     void movq_rm(RegisterID src, RegisterID base)
    803     {
    804         m_buffer.putByte(REX_W);
    805         m_buffer.putByte(OP_MOV_EvGv);
    806         modRm_rm(src, base);
    807     }
    808 
    809     void movq_rm(RegisterID src, int offset, RegisterID base)
    810     {
    811         m_buffer.ensureSpace(maxInstructionSize);
    812         m_buffer.putByteUnchecked(REX_W);
    813         m_buffer.putByteUnchecked(OP_MOV_EvGv);
    814         modRm_rm_Unchecked(src, base, offset);
    815     }
    816 #endif
    817 
    818     void movl_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
    819     {
    820         m_buffer.putByte(OP_MOV_EvGv);
    821         modRm_rmsib(src, base, index, scale);
    822     }
    823    
    824     void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
    825     {
    826         m_buffer.putByte(OP_MOV_EvGv);
    827         modRm_rmsib(src, base, index, scale, offset);
    828     }
    829    
    830     void movl_i32r(int imm, RegisterID dst)
    831     {
    832         m_buffer.putByte(OP_GROUP11_EvIz);
    833         modRm_opr(GROUP11_MOV, dst);
    834         m_buffer.putInt(imm);
    835     }
    836 
    837     void movl_i32m(int imm, RegisterID base)
    838     {
    839         m_buffer.ensureSpace(maxInstructionSize);
    840         m_buffer.putByteUnchecked(OP_GROUP11_EvIz);
    841         modRm_opm_Unchecked(GROUP11_MOV, base);
    842         m_buffer.putIntUnchecked(imm);
    843     }
    844 
    845     void movl_i32m(int imm, int offset, RegisterID base)
    846     {
    847         m_buffer.ensureSpace(maxInstructionSize);
    848         m_buffer.putByteUnchecked(OP_GROUP11_EvIz);
    849         modRm_opm_Unchecked(GROUP11_MOV, base, offset);
    850         m_buffer.putIntUnchecked(imm);
    851     }
    852 
    853 #if !PLATFORM(X86_64)
    854     void movl_i32m(int imm, void* addr)
    855     {
    856         m_buffer.putByte(OP_GROUP11_EvIz);
    857         modRm_opm(GROUP11_MOV, addr);
    858         m_buffer.putInt(imm);
    859     }
    860 #endif
     676        // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
     677        // is in the range ESP-EDI, and the src would not have required a REX).  Unneeded
     678        // REX prefixes are defined to be silently ignored by the processor.
     679        m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
     680    }
    861681
    862682    void leal_mr(int offset, RegisterID base, RegisterID dst)
    863683    {
    864         m_buffer.putByte(OP_LEA);
    865         modRm_rm(dst, base, offset);
    866     }
    867 
    868     void leal_mr(int offset, RegisterID index, int scale, RegisterID dst)
    869     {
    870         m_buffer.putByte(OP_LEA);
    871         modRm_rmsib(dst, X86::noBase, index, scale, offset);
    872     }
    873 
     684        m_formatter.oneByteOp(OP_LEA, dst, base, offset);
     685    }
     686
     687    // Flow control:
     688
     689    JmpSrc call()
     690    {
     691        m_formatter.oneByteOp(OP_CALL_rel32);
     692        return m_formatter.immediateRel32();
     693    }
     694   
     695    JmpSrc call(RegisterID dst)
     696    {
     697        m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
     698        return JmpSrc(m_formatter.size());
     699    }
     700
     701    JmpSrc jmp()
     702    {
     703        m_formatter.oneByteOp(OP_JMP_rel32);
     704        return m_formatter.immediateRel32();
     705    }
     706   
     707    void jmp_r(RegisterID dst)
     708    {
     709        m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
     710    }
     711   
     712    void jmp_m(int offset, RegisterID base)
     713    {
     714        m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
     715    }
     716
     717    JmpSrc jne()
     718    {
     719        m_formatter.twoByteOp(OP2_JNE_rel32);
     720        return m_formatter.immediateRel32();
     721    }
     722   
     723    JmpSrc jnz()
     724    {
     725        return jne();
     726    }
     727
     728    JmpSrc je()
     729    {
     730        m_formatter.twoByteOp(OP2_JE_rel32);
     731        return m_formatter.immediateRel32();
     732    }
     733   
     734    JmpSrc jl()
     735    {
     736        m_formatter.twoByteOp(OP2_JL_rel32);
     737        return m_formatter.immediateRel32();
     738    }
     739   
     740    JmpSrc jb()
     741    {
     742        m_formatter.twoByteOp(OP2_JB_rel32);
     743        return m_formatter.immediateRel32();
     744    }
     745   
     746    JmpSrc jle()
     747    {
     748        m_formatter.twoByteOp(OP2_JLE_rel32);
     749        return m_formatter.immediateRel32();
     750    }
     751   
     752    JmpSrc jbe()
     753    {
     754        m_formatter.twoByteOp(OP2_JBE_rel32);
     755        return m_formatter.immediateRel32();
     756    }
     757   
     758    JmpSrc jge()
     759    {
     760        m_formatter.twoByteOp(OP2_JGE_rel32);
     761        return m_formatter.immediateRel32();
     762    }
     763
     764    JmpSrc jg()
     765    {
     766        m_formatter.twoByteOp(OP2_JG_rel32);
     767        return m_formatter.immediateRel32();
     768    }
     769
     770    JmpSrc ja()
     771    {
     772        m_formatter.twoByteOp(OP2_JA_rel32);
     773        return m_formatter.immediateRel32();
     774    }
     775   
     776    JmpSrc jae()
     777    {
     778        m_formatter.twoByteOp(OP2_JAE_rel32);
     779        return m_formatter.immediateRel32();
     780    }
     781   
     782    JmpSrc jo()
     783    {
     784        m_formatter.twoByteOp(OP2_JO_rel32);
     785        return m_formatter.immediateRel32();
     786    }
     787
     788    JmpSrc jp()
     789    {
     790        m_formatter.twoByteOp(OP2_JP_rel32);
     791        return m_formatter.immediateRel32();
     792    }
     793   
     794    JmpSrc js()
     795    {
     796        m_formatter.twoByteOp(OP2_JS_rel32);
     797        return m_formatter.immediateRel32();
     798    }
     799
     800    // SSE operations:
     801
     802    void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
     803    {
     804        m_formatter.prefix(PRE_SSE_F2);
     805        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     806    }
     807
     808    void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
     809    {
     810        m_formatter.prefix(PRE_SSE_F2);
     811        m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
     812    }
     813
     814    void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
     815    {
     816        m_formatter.prefix(PRE_SSE_F2);
     817        m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
     818    }
     819
     820    void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
     821    {
     822        m_formatter.prefix(PRE_SSE_F2);
     823        m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
     824    }
     825
     826    void movd_rr(XMMRegisterID src, RegisterID dst)
     827    {
     828        m_formatter.prefix(PRE_SSE_66);
     829        m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
     830    }
     831
     832    void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
     833    {
     834        m_formatter.prefix(PRE_SSE_F2);
     835        m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
     836    }
     837
     838    void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
     839    {
     840        m_formatter.prefix(PRE_SSE_F2);
     841        m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
     842    }
     843
     844    void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
     845    {
     846        m_formatter.prefix(PRE_SSE_F2);
     847        m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     848    }
     849
     850    void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
     851    {
     852        m_formatter.prefix(PRE_SSE_F2);
     853        m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
     854    }
     855
     856    void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
     857    {
     858        m_formatter.prefix(PRE_SSE_66);
     859        m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
     860        m_formatter.immediate8(whichWord);
     861    }
     862
     863    void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
     864    {
     865        m_formatter.prefix(PRE_SSE_F2);
     866        m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     867    }
     868
     869    void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
     870    {
     871        m_formatter.prefix(PRE_SSE_F2);
     872        m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
     873    }
     874
     875    void ucomis_rr(XMMRegisterID src, XMMRegisterID dst)
     876    {
     877        m_formatter.prefix(PRE_SSE_66);
     878        m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
     879    }
     880
     881    // Misc instructions:
     882
     883    void int3()
     884    {
     885        m_formatter.oneByteOp(OP_INT3);
     886    }
     887   
    874888    void ret()
    875889    {
    876         m_buffer.putByte(OP_RET);
    877     }
    878    
    879     void jmp_r(RegisterID dst)
    880     {
    881         m_buffer.putByte(OP_GROUP5_Ev);
    882         modRm_opr(GROUP5_OP_JMPN, dst);
    883     }
    884    
    885     void jmp_m(RegisterID base)
    886     {
    887         m_buffer.putByte(OP_GROUP5_Ev);
    888         modRm_opm(GROUP5_OP_JMPN, base);
    889     }
    890    
    891     void jmp_m(int offset, RegisterID base)
    892     {
    893         m_buffer.putByte(OP_GROUP5_Ev);
    894         modRm_opm(GROUP5_OP_JMPN, base, offset);
    895     }
    896    
    897     void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
    898     {
    899         m_buffer.putByte(PRE_SSE_F2);
    900         m_buffer.putByte(OP_2BYTE_ESCAPE);
    901         m_buffer.putByte(OP2_MOVSD_VsdWsd);
    902         modRm_rm((RegisterID)dst, base, offset);
    903     }
    904 
    905     void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
    906     {
    907         m_buffer.putByte(PRE_SSE_F2);
    908         m_buffer.putByte(OP_2BYTE_ESCAPE);
    909         m_buffer.putByte(OP2_MOVSD_WsdVsd);
    910         modRm_rm((RegisterID)src, base, offset);
    911     }
    912 
    913     void movd_rr(XMMRegisterID src, RegisterID dst)
    914     {
    915         m_buffer.putByte(PRE_SSE_66);
    916         m_buffer.putByte(OP_2BYTE_ESCAPE);
    917         m_buffer.putByte(OP2_MOVD_EdVd);
    918         modRm_rr((RegisterID)src, dst);
    919     }
    920 
    921     void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
    922     {
    923         m_buffer.putByte(PRE_SSE_F2);
    924         m_buffer.putByte(OP_2BYTE_ESCAPE);
    925         m_buffer.putByte(OP2_CVTSI2SD_VsdEd);
    926         modRm_rr((RegisterID)dst, src);
    927     }
    928 
    929     void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
    930     {
    931         m_buffer.putByte(PRE_SSE_F2);
    932         m_buffer.putByte(OP_2BYTE_ESCAPE);
    933         m_buffer.putByte(OP2_CVTTSD2SI_GdWsd);
    934         modRm_rr(dst, (RegisterID)src);
    935     }
    936 
    937     void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
    938     {
    939         m_buffer.putByte(PRE_SSE_F2);
    940         m_buffer.putByte(OP_2BYTE_ESCAPE);
    941         m_buffer.putByte(OP2_ADDSD_VsdWsd);
    942         modRm_rm((RegisterID)dst, base, offset);
    943     }
    944 
    945     void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
    946     {
    947         m_buffer.putByte(PRE_SSE_F2);
    948         m_buffer.putByte(OP_2BYTE_ESCAPE);
    949         m_buffer.putByte(OP2_SUBSD_VsdWsd);
    950         modRm_rm((RegisterID)dst, base, offset);
    951     }
    952 
    953     void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
    954     {
    955         m_buffer.putByte(PRE_SSE_F2);
    956         m_buffer.putByte(OP_2BYTE_ESCAPE);
    957         m_buffer.putByte(OP2_MULSD_VsdWsd);
    958         modRm_rm((RegisterID)dst, base, offset);
    959     }
    960 
    961     void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
    962     {
    963         m_buffer.putByte(PRE_SSE_F2);
    964         m_buffer.putByte(OP_2BYTE_ESCAPE);
    965         m_buffer.putByte(OP2_ADDSD_VsdWsd);
    966         modRm_rr((RegisterID)dst, (RegisterID)src);
    967     }
    968 
    969     void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
    970     {
    971         m_buffer.putByte(PRE_SSE_F2);
    972         m_buffer.putByte(OP_2BYTE_ESCAPE);
    973         m_buffer.putByte(OP2_SUBSD_VsdWsd);
    974         modRm_rr((RegisterID)dst, (RegisterID)src);
    975     }
    976 
    977     void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
    978     {
    979         m_buffer.putByte(PRE_SSE_F2);
    980         m_buffer.putByte(OP_2BYTE_ESCAPE);
    981         m_buffer.putByte(OP2_MULSD_VsdWsd);
    982         modRm_rr((RegisterID)dst, (RegisterID)src);
    983     }
    984 
    985     void ucomis_rr(XMMRegisterID src, XMMRegisterID dst)
    986     {
    987         m_buffer.putByte(PRE_SSE_66);
    988         m_buffer.putByte(OP_2BYTE_ESCAPE);
    989         m_buffer.putByte(OP2_UCOMISD_VsdWsd);
    990         modRm_rr((RegisterID)dst, (RegisterID)src);
    991     }
    992 
    993     void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
    994     {
    995         m_buffer.putByte(PRE_SSE_66);
    996         m_buffer.putByte(OP_2BYTE_ESCAPE);
    997         m_buffer.putByte(OP2_PEXTRW_GdUdIb);
    998         modRm_rr(dst, (RegisterID)src);
    999         m_buffer.putByte(whichWord);
    1000     }
    1001 
    1002     JmpSrc call()
    1003     {
    1004         m_buffer.putByte(OP_CALL_rel32);
    1005         m_buffer.putInt(0); // FIXME: make this point to a global label, linked later.
    1006         return JmpSrc(m_buffer.size());
    1007     }
    1008    
    1009     JmpSrc call(RegisterID dst)
    1010     {
    1011         m_buffer.putByte(OP_GROUP5_Ev);
    1012         modRm_opr(GROUP5_OP_CALLN, dst);
    1013         return JmpSrc(m_buffer.size());
    1014     }
     890        m_formatter.oneByteOp(OP_RET);
     891    }
     892
     893    void predictNotTaken()
     894    {
     895        m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
     896    }
     897
     898    // Assembler admin methods:
    1015899
    1016900    JmpDst label()
    1017901    {
    1018         return JmpDst(m_buffer.size());
     902        return JmpDst(m_formatter.size());
    1019903    }
    1020904   
    1021905    JmpDst align(int alignment)
    1022906    {
    1023         while (!m_buffer.isAligned(alignment))
    1024             m_buffer.putByte(OP_HLT);
     907        while (!m_formatter.isAligned(alignment))
     908            m_formatter.oneByteOp(OP_HLT);
    1025909
    1026910        return label();
    1027911    }
    1028912
    1029     JmpSrc jmp()
    1030     {
    1031         m_buffer.putByte(OP_JMP_rel32);
    1032         m_buffer.putInt(0);
    1033         return JmpSrc(m_buffer.size());
    1034     }
    1035    
    1036     JmpSrc jne()
    1037     {
    1038         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1039         m_buffer.putByte(OP2_JNE_rel32);
    1040         m_buffer.putInt(0);
    1041         return JmpSrc(m_buffer.size());
    1042     }
    1043    
    1044     JmpSrc jnz()
    1045     {
    1046         return jne();
    1047     }
    1048 
    1049     JmpSrc je()
    1050     {
    1051         m_buffer.ensureSpace(maxInstructionSize);
    1052         m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
    1053         m_buffer.putByteUnchecked(OP2_JE_rel32);
    1054         m_buffer.putIntUnchecked(0);
    1055         return JmpSrc(m_buffer.size());
    1056     }
    1057    
    1058     JmpSrc jl()
    1059     {
    1060         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1061         m_buffer.putByte(OP2_JL_rel32);
    1062         m_buffer.putInt(0);
    1063         return JmpSrc(m_buffer.size());
    1064     }
    1065    
    1066     JmpSrc jb()
    1067     {
    1068         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1069         m_buffer.putByte(OP2_JB_rel32);
    1070         m_buffer.putInt(0);
    1071         return JmpSrc(m_buffer.size());
    1072     }
    1073    
    1074     JmpSrc jle()
    1075     {
    1076         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1077         m_buffer.putByte(OP2_JLE_rel32);
    1078         m_buffer.putInt(0);
    1079         return JmpSrc(m_buffer.size());
    1080     }
    1081    
    1082     JmpSrc jbe()
    1083     {
    1084         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1085         m_buffer.putByte(OP2_JBE_rel32);
    1086         m_buffer.putInt(0);
    1087         return JmpSrc(m_buffer.size());
    1088     }
    1089    
    1090     JmpSrc jge()
    1091     {
    1092         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1093         m_buffer.putByte(OP2_JGE_rel32);
    1094         m_buffer.putInt(0);
    1095         return JmpSrc(m_buffer.size());
    1096     }
    1097 
    1098     JmpSrc jg()
    1099     {
    1100         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1101         m_buffer.putByte(OP2_JG_rel32);
    1102         m_buffer.putInt(0);
    1103         return JmpSrc(m_buffer.size());
    1104     }
    1105 
    1106     JmpSrc ja()
    1107     {
    1108         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1109         m_buffer.putByte(OP2_JA_rel32);
    1110         m_buffer.putInt(0);
    1111         return JmpSrc(m_buffer.size());
    1112     }
    1113    
    1114     JmpSrc jae()
    1115     {
    1116         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1117         m_buffer.putByte(OP2_JAE_rel32);
    1118         m_buffer.putInt(0);
    1119         return JmpSrc(m_buffer.size());
    1120     }
    1121    
    1122     JmpSrc jo()
    1123     {
    1124         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1125         m_buffer.putByte(OP2_JO_rel32);
    1126         m_buffer.putInt(0);
    1127         return JmpSrc(m_buffer.size());
    1128     }
    1129 
    1130     JmpSrc jp()
    1131     {
    1132         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1133         m_buffer.putByte(OP2_JP_rel32);
    1134         m_buffer.putInt(0);
    1135         return JmpSrc(m_buffer.size());
    1136     }
    1137    
    1138     JmpSrc js()
    1139     {
    1140         m_buffer.putByte(OP_2BYTE_ESCAPE);
    1141         m_buffer.putByte(OP2_JS_rel32);
    1142         m_buffer.putInt(0);
    1143         return JmpSrc(m_buffer.size());
    1144     }
    1145    
    1146     void predictNotTaken()
    1147     {
    1148         m_buffer.putByte(PRE_PREDICT_BRANCH_NOT_TAKEN);
    1149     }
    1150    
     913    // Linking & repatching:
     914
    1151915    void link(JmpSrc from, JmpDst to)
    1152916    {
     
    1154918        ASSERT(from.m_offset != -1);
    1155919       
    1156         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_buffer.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
     920        reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
    1157921    }
    1158922   
     
    1215979    void* executableCopy(ExecutablePool* allocator)
    1216980    {
    1217         void* copy = m_buffer.executableCopy(allocator);
     981        void* copy = m_formatter.executableCopy(allocator);
    1218982        ASSERT(copy);
    1219983        return copy;
     
    1221985
    1222986private:
    1223     void modRm_rr(RegisterID reg, RegisterID rm)
    1224     {
    1225         m_buffer.ensureSpace(maxInstructionSize);
    1226         modRm_rr_Unchecked(reg, rm);
    1227     }
    1228 
    1229     void modRm_rr_Unchecked(RegisterID reg, RegisterID rm)
    1230     {
    1231         m_buffer.putByteUnchecked(MODRM(3, reg, rm));
    1232     }
     987
     988    class X86InstructionFormatter {
     989
     990        static const int maxInstructionSize = 16;
     991
     992    public:
     993
     994        // Legacy prefix bytes:
     995        //
     996        // These are emmitted prior to the instruction.
     997
     998        void prefix(OneByteOpcodeID pre)
     999        {
     1000            m_buffer.putByte(pre);
     1001        }
     1002
     1003        // Word-sized operands / no operand instruction formatters.
     1004        //
     1005        // In addition to the opcode, the following operand permutations are supported:
     1006        //   * None - instruction takes no operands.
     1007        //   * One register - the low three bits of the RegisterID are added into the opcode.
     1008        //   * 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).
     1009        //   * Three argument ModRM - a register, and a register and an offset describing a memory operand.
     1010        //   * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
     1011        //
     1012        // For 32-bit x86 targets, the address operand may also be provided as a void*.
     1013        // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
     1014        //
     1015        // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
     1016
     1017        void oneByteOp(OneByteOpcodeID opcode)
     1018        {
     1019            m_buffer.ensureSpace(maxInstructionSize);
     1020            m_buffer.putByteUnchecked(opcode);
     1021        }
     1022
     1023        void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
     1024        {
     1025            m_buffer.ensureSpace(maxInstructionSize);
     1026            emitRexIfNeeded(reg, 0, 0);
     1027            m_buffer.putByteUnchecked(opcode + reg);
     1028        }
     1029
     1030        void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
     1031        {
     1032            m_buffer.ensureSpace(maxInstructionSize);
     1033            emitRexIfNeeded(reg, 0, rm);
     1034            m_buffer.putByteUnchecked(opcode);
     1035            registerModRM(reg, rm);
     1036        }
     1037
     1038        void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
     1039        {
     1040            m_buffer.ensureSpace(maxInstructionSize);
     1041            emitRexIfNeeded(reg, 0, base);
     1042            m_buffer.putByteUnchecked(opcode);
     1043            memoryModRM(reg, base, offset);
     1044        }
     1045
     1046        void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
     1047        {
     1048            m_buffer.ensureSpace(maxInstructionSize);
     1049            emitRexIfNeeded(reg, index, base);
     1050            m_buffer.putByteUnchecked(opcode);
     1051            memoryModRM(reg, base, index, scale, offset);
     1052        }
    12331053
    12341054#if !PLATFORM(X86_64)
    1235     void modRm_rm(RegisterID reg, void* addr)
    1236     {
    1237         m_buffer.putByte(MODRM(0, reg, X86::noBase));
    1238         m_buffer.putInt((int)addr);
    1239     }
     1055        void oneByteOp(OneByteOpcodeID opcode, int reg, void* address)
     1056        {
     1057            m_buffer.ensureSpace(maxInstructionSize);
     1058            m_buffer.putByteUnchecked(opcode);
     1059            memoryModRM(reg, address);
     1060        }
    12401061#endif
    12411062
    1242     void modRm_rm_Unchecked(RegisterID reg, RegisterID base)
    1243     {
    1244         if (base == X86::esp) {
    1245             m_buffer.putByteUnchecked(MODRM(0, reg, X86::hasSib));
    1246             m_buffer.putByteUnchecked(SIB(0, X86::noScale, X86::esp));
    1247         } else {
    1248             m_buffer.putByteUnchecked(MODRM(0, reg, base));
    1249         }
    1250     }
    1251 
    1252     void modRm_rm(RegisterID reg, RegisterID base)
    1253     {
    1254         if (base == X86::esp) {
    1255             m_buffer.putByte(MODRM(0, reg, X86::hasSib));
    1256             m_buffer.putByte(SIB(0, X86::noScale, X86::esp));
    1257         } else
    1258             m_buffer.putByte(MODRM(0, reg, base));
    1259     }
    1260 
    1261     void modRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)
    1262     {
    1263         if (base == X86::esp) {
    1264             if (CAN_SIGN_EXTEND_8_32(offset)) {
    1265                 m_buffer.putByteUnchecked(MODRM(1, reg, X86::hasSib));
    1266                 m_buffer.putByteUnchecked(SIB(0, X86::noScale, X86::esp));
     1063        void twoByteOp(TwoByteOpcodeID opcode)
     1064        {
     1065            m_buffer.ensureSpace(maxInstructionSize);
     1066            m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
     1067            m_buffer.putByteUnchecked(opcode);
     1068        }
     1069
     1070        void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
     1071        {
     1072            m_buffer.ensureSpace(maxInstructionSize);
     1073            emitRexIfNeeded(reg, 0, rm);
     1074            m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
     1075            m_buffer.putByteUnchecked(opcode);
     1076            registerModRM(reg, rm);
     1077        }
     1078
     1079        void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
     1080        {
     1081            m_buffer.ensureSpace(maxInstructionSize);
     1082            emitRexIfNeeded(reg, 0, base);
     1083            m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
     1084            m_buffer.putByteUnchecked(opcode);
     1085            memoryModRM(reg, base, offset);
     1086        }
     1087
     1088        void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
     1089        {
     1090            m_buffer.ensureSpace(maxInstructionSize);
     1091            emitRexIfNeeded(reg, index, base);
     1092            m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
     1093            m_buffer.putByteUnchecked(opcode);
     1094            memoryModRM(reg, base, index, scale, offset);
     1095        }
     1096
     1097#if PLATFORM(X86_64)
     1098        // Quad-word-sized operands:
     1099        //
     1100        // Used to format 64-bit operantions, planting a REX.w prefix.
     1101        // When planting d64 or f64 instructions, not requiring a REX.w prefix,
     1102        // the normal (non-'64'-postfixed) formatters should be used.
     1103
     1104        void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
     1105        {
     1106            m_buffer.ensureSpace(maxInstructionSize);
     1107            emitRexW(reg, 0, rm);
     1108            m_buffer.putByteUnchecked(opcode);
     1109            registerModRM(reg, rm);
     1110        }
     1111
     1112        void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
     1113        {
     1114            m_buffer.ensureSpace(maxInstructionSize);
     1115            emitRexW(reg, 0, base);
     1116            m_buffer.putByteUnchecked(opcode);
     1117            memoryModRM(reg, base, offset);
     1118        }
     1119
     1120        void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
     1121        {
     1122            m_buffer.ensureSpace(maxInstructionSize);
     1123            emitRexW(reg, index, base);
     1124            m_buffer.putByteUnchecked(opcode);
     1125            memoryModRM(reg, base, index, scale, offset);
     1126        }
     1127#endif
     1128
     1129        // Byte-operands:
     1130        //
     1131        // These methods format byte operations.  Byte operations differ from the normal
     1132        // formatters in the circumstances under which they will decide to emit REX prefixes.
     1133        // These should be used where any register operand signifies a byte register.
     1134        //
     1135        // The disctinction is due to the handling of register numbers in the range 4..7 on
     1136        // x86-64.  These register numbers may either represent the second byte of the first
     1137        // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
     1138        //
     1139        // Since ah..bh cannot be used in all permutations of operands (specifically cannot
     1140        // be accessed where a REX prefix is present), these are likely best treated as
     1141        // deprecated.  In order to ensure the correct registers spl..dil are selected a
     1142        // REX prefix will be emitted for any byte register operand in the range 4..15.
     1143        //
     1144        // These formatters may be used in instructions where a mix of operand sizes, in which
     1145        // case an unnecessary REX will be emitted, for example:
     1146        //     movzbl %al, %edi
     1147        // In this case a REX will be planted since edi is 7 (and were this a byte operand
     1148        // a REX would be required to specify dil instead of bh).  Unneeded REX prefixes will
     1149        // be silently ignored by the processor.
     1150        //
     1151        // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
     1152        // is provided to check byte register operands.
     1153
     1154        void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
     1155        {
     1156            m_buffer.ensureSpace(maxInstructionSize);
     1157            emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
     1158            m_buffer.putByteUnchecked(opcode);
     1159            registerModRM(groupOp, rm);
     1160        }
     1161
     1162        void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
     1163        {
     1164            m_buffer.ensureSpace(maxInstructionSize);
     1165            emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
     1166            m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
     1167            m_buffer.putByteUnchecked(opcode);
     1168            registerModRM(reg, rm);
     1169        }
     1170
     1171        void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
     1172        {
     1173            m_buffer.ensureSpace(maxInstructionSize);
     1174            emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
     1175            m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
     1176            m_buffer.putByteUnchecked(opcode);
     1177            registerModRM(groupOp, rm);
     1178        }
     1179
     1180        // Immediates:
     1181        //
     1182        // An immedaite should be appended where appropriate after an op has been emitted.
     1183        // The writes are unchecked since the opcode formatters above will have ensured space.
     1184
     1185        void immediate8(int imm)
     1186        {
     1187            m_buffer.putByteUnchecked(imm);
     1188        }
     1189
     1190        void immediate32(int imm)
     1191        {
     1192            m_buffer.putIntUnchecked(imm);
     1193        }
     1194
     1195        JmpSrc immediateRel32()
     1196        {
     1197            m_buffer.putIntUnchecked(0);
     1198            return JmpSrc(m_buffer.size());
     1199        }
     1200
     1201        // Administrative methods:
     1202
     1203        size_t size() const { return m_buffer.size(); }
     1204        bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
     1205        void* data() const { return m_buffer.data(); }
     1206        void* executableCopy(ExecutablePool* allocator) { return m_buffer.executableCopy(allocator); }
     1207
     1208    private:
     1209
     1210        // Internals; ModRm and REX formatters.
     1211
     1212        static const RegisterID noBase = X86::ebp;
     1213        static const RegisterID hasSib = X86::esp;
     1214        static const RegisterID noIndex = X86::esp;
     1215#if PLATFORM(X86_64)
     1216        static const RegisterID noBase2 = X86::r13;
     1217        static const RegisterID hasSib2 = X86::r12;
     1218
     1219        // Registers r8 & above require a REX prefixe.
     1220        inline bool regRequiresRex(int reg)
     1221        {
     1222            return (reg >= X86::r8);
     1223        }
     1224
     1225        // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
     1226        inline bool byteRegRequiresRex(int reg)
     1227        {
     1228            return (reg >= X86::esp);
     1229        }
     1230
     1231        // Format a REX prefix byte.
     1232        inline void emitRex(bool w, int r, int x, int b)
     1233        {
     1234            m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
     1235        }
     1236
     1237        // Used to plant a REX byte with REX.w set (for 64-bit operations).
     1238        inline void emitRexW(int r, int x, int b)
     1239        {
     1240            emitRex(true, r, x, b);
     1241        }
     1242
     1243        // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
     1244        // regRequiresRex() to check other registers (i.e. address base & index).
     1245        inline void emitRexIf(bool condition, int r, int x, int b)
     1246        {
     1247            if (condition) emitRex(false, r, x, b);
     1248        }
     1249
     1250        // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
     1251        inline void emitRexIfNeeded(int r, int x, int b)
     1252        {
     1253            emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b);
     1254        }
     1255#else
     1256        // No REX prefix bytes on 32-bit x86.
     1257        inline bool regRequiresRex(int) { return false; }
     1258        inline bool byteRegRequiresRex(int) { return false; }
     1259        inline void emitRexIf(bool, int, int, int) {}
     1260        inline void emitRexIfNeeded(int, int, int) {}
     1261#endif
     1262
     1263        enum ModRmMode {
     1264            ModRmMemoryNoDisp,
     1265            ModRmMemoryDisp8,
     1266            ModRmMemoryDisp32,
     1267            ModRmRegister,
     1268        };
     1269
     1270        void putModRm(ModRmMode mode, int reg, RegisterID rm)
     1271        {
     1272            m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
     1273        }
     1274
     1275        void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
     1276        {
     1277            ASSERT(mode != ModRmRegister);
     1278
     1279            // Encode sacle of (1,2,4,8) -> (0,1,2,3)
     1280            int shift = 0;
     1281            while (scale >>= 1)
     1282                shift++;
     1283
     1284            putModRm(mode, reg, hasSib);
     1285            m_buffer.putByteUnchecked((shift << 6) | ((index & 7) << 3) | (base & 7));
     1286        }
     1287
     1288        void registerModRM(int reg, RegisterID rm)
     1289        {
     1290            putModRm(ModRmRegister, reg, rm);
     1291        }
     1292
     1293        void memoryModRM(int reg, RegisterID base, int offset)
     1294        {
     1295            // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
     1296#if PLATFORM(X86_64)
     1297            if ((base == hasSib) || (base == hasSib2)) {
     1298#else
     1299            if (base == hasSib) {
     1300#endif
     1301                if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
     1302                    putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
     1303                else if (CAN_SIGN_EXTEND_8_32(offset)) {
     1304                    putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
     1305                    m_buffer.putByteUnchecked(offset);
     1306                } else {
     1307                    putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
     1308                    m_buffer.putIntUnchecked(offset);
     1309                }
     1310            } else {
     1311#if PLATFORM(X86_64)
     1312                if (!offset && (base != noBase) && (base != noBase2))
     1313#else
     1314                if (!offset && (base != noBase))
     1315#endif
     1316                    putModRm(ModRmMemoryNoDisp, reg, base);
     1317                else if (CAN_SIGN_EXTEND_8_32(offset)) {
     1318                    putModRm(ModRmMemoryDisp8, reg, base);
     1319                    m_buffer.putByteUnchecked(offset);
     1320                } else {
     1321                    putModRm(ModRmMemoryDisp32, reg, base);
     1322                    m_buffer.putIntUnchecked(offset);
     1323                }
     1324            }
     1325        }
     1326   
     1327        void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
     1328        {
     1329            ASSERT(index != noIndex);
     1330
     1331#if PLATFORM(X86_64)
     1332            if (!offset && (base != noBase) && (base != noBase2))
     1333#else
     1334            if (!offset && (base != noBase))
     1335#endif
     1336                putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
     1337            else if (CAN_SIGN_EXTEND_8_32(offset)) {
     1338                putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
    12671339                m_buffer.putByteUnchecked(offset);
    12681340            } else {
    1269                 m_buffer.putByteUnchecked(MODRM(2, reg, X86::hasSib));
    1270                 m_buffer.putByteUnchecked(SIB(0, X86::noScale, X86::esp));
     1341                putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
    12711342                m_buffer.putIntUnchecked(offset);
    12721343            }
    1273         } else {
    1274             if (CAN_SIGN_EXTEND_8_32(offset)) {
    1275                 m_buffer.putByteUnchecked(MODRM(1, reg, base));
    1276                 m_buffer.putByteUnchecked(offset);
    1277             } else {
    1278                 m_buffer.putByteUnchecked(MODRM(2, reg, base));
    1279                 m_buffer.putIntUnchecked(offset);
    1280             }
    1281         }
    1282     }
    1283 
    1284     void modRm_rm(RegisterID reg, RegisterID base, int offset)
    1285     {
    1286         m_buffer.ensureSpace(maxInstructionSize);
    1287         modRm_rm_Unchecked(reg, base, offset);
    1288     }
    1289 
    1290     void modRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale)
    1291     {
    1292         int shift = 0;
    1293         while (scale >>= 1)
    1294             shift++;
    1295    
    1296         m_buffer.putByte(MODRM(0, reg, X86::hasSib));
    1297         m_buffer.putByte(SIB(shift, index, base));
    1298     }
    1299 
    1300     void modRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset)
    1301     {
    1302         int shift = 0;
    1303         while (scale >>= 1)
    1304             shift++;
    1305    
    1306         if (CAN_SIGN_EXTEND_8_32(offset)) {
    1307             m_buffer.putByte(MODRM(1, reg, X86::hasSib));
    1308             m_buffer.putByte(SIB(shift, index, base));
    1309             m_buffer.putByte(offset);
    1310         } else {
    1311             m_buffer.putByte(MODRM(2, reg, X86::hasSib));
    1312             m_buffer.putByte(SIB(shift, index, base));
    1313             m_buffer.putInt(offset);
    1314         }
    1315     }
    1316 
    1317     void modRm_opr(OpcodeID opcodeID, RegisterID rm)
    1318     {
    1319         m_buffer.ensureSpace(maxInstructionSize);
    1320         modRm_opr_Unchecked(opcodeID, rm);
    1321     }
    1322 
    1323     void modRm_opr_Unchecked(OpcodeID opcodeID, RegisterID rm)
    1324     {
    1325         modRm_rr_Unchecked(static_cast<RegisterID>(opcodeID), rm);
    1326     }
    1327 
    1328     void modRm_opm(OpcodeID opcodeID, RegisterID base)
    1329     {
    1330         modRm_rm(static_cast<RegisterID>(opcodeID), base);
    1331     }
    1332 
    1333     void modRm_opm_Unchecked(OpcodeID opcodeID, RegisterID base)
    1334     {
    1335         modRm_rm_Unchecked(static_cast<RegisterID>(opcodeID), base);
    1336     }
    1337 
    1338     void modRm_opm_Unchecked(OpcodeID opcodeID, RegisterID base, int offset)
    1339     {
    1340         modRm_rm_Unchecked(static_cast<RegisterID>(opcodeID), base, offset);
    1341     }
    1342 
    1343     void modRm_opm(OpcodeID opcodeID, RegisterID base, int offset)
    1344     {
    1345         modRm_rm(static_cast<RegisterID>(opcodeID), base, offset);
    1346     }
     1344        }
    13471345
    13481346#if !PLATFORM(X86_64)
    1349     void modRm_opm(OpcodeID opcodeID, void* addr)
    1350     {
    1351         modRm_rm(static_cast<RegisterID>(opcodeID), addr);
    1352     }
     1347        void memoryModRM(int reg, void* address)
     1348        {
     1349            // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
     1350            putModRm(ModRmMemoryNoDisp, reg, noBase);
     1351            m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address));
     1352        }
    13531353#endif
    13541354
    1355     void modRm_opmsib(OpcodeID opcodeID, RegisterID base, RegisterID index, int scale, int offset)
    1356     {
    1357         modRm_rmsib(static_cast<RegisterID>(opcodeID), base, index, scale, offset);
    1358     }
    1359 
    1360     void modRm_opmsib(OpcodeID opcodeID, RegisterID base, RegisterID index, int scale)
    1361     {
    1362         modRm_rmsib(static_cast<RegisterID>(opcodeID), base, index, scale);
    1363     }
    1364 
    1365     AssemblerBuffer m_buffer;
     1355        AssemblerBuffer m_buffer;
     1356    } m_formatter;
    13661357};
    13671358
Note: See TracChangeset for help on using the changeset viewer.