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

source code of qtscript/src/3rdparty/javascriptcore/JavaScriptCore/assembler/X86Assembler.h