OSDN Git Service

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