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