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