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