• 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