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