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