2 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef X86Assembler_h
27 #define X86Assembler_h
29 #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
31 #include "AssemblerBuffer.h"
33 #include <wtf/Assertions.h>
34 #include <wtf/Vector.h>
38 inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
40 namespace X86Registers {
77 typedef X86Registers::RegisterID RegisterID;
78 typedef X86Registers::XMMRegisterID XMMRegisterID;
79 typedef XMMRegisterID FPRegisterID;
99 ConditionC = ConditionB,
100 ConditionNC = ConditionAE,
109 OP_2BYTE_ESCAPE = 0x0F,
114 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
125 OP_MOVSXD_GvEv = 0x63,
127 PRE_OPERAND_SIZE = 0x66,
130 OP_IMUL_GvEvIz = 0x69,
131 OP_GROUP1_EbIb = 0x80,
132 OP_GROUP1_EvIz = 0x81,
133 OP_GROUP1_EvIb = 0x83,
140 OP_GROUP1A_Ev = 0x8F,
146 OP_GROUP2_EvIb = 0xC1,
148 OP_GROUP11_EvIz = 0xC7,
150 OP_GROUP2_Ev1 = 0xD1,
151 OP_GROUP2_EvCL = 0xD3,
152 OP_CALL_rel32 = 0xE8,
156 OP_GROUP3_EbIb = 0xF6,
158 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
163 OP2_MOVSD_VsdWsd = 0x10,
164 OP2_MOVSD_WsdVsd = 0x11,
165 OP2_CVTSI2SD_VsdEd = 0x2A,
166 OP2_CVTTSD2SI_GdWsd = 0x2C,
167 OP2_UCOMISD_VsdWsd = 0x2E,
168 OP2_ADDSD_VsdWsd = 0x58,
169 OP2_MULSD_VsdWsd = 0x59,
170 OP2_SUBSD_VsdWsd = 0x5C,
171 OP2_DIVSD_VsdWsd = 0x5E,
172 OP2_SQRTSD_VsdWsd = 0x51,
173 OP2_ANDNPD_VpdWpd = 0x55,
174 OP2_XORPD_VpdWpd = 0x57,
175 OP2_MOVD_VdEd = 0x6E,
176 OP2_MOVD_EdVd = 0x7E,
177 OP2_JCC_rel32 = 0x80,
179 OP2_IMUL_GvEv = 0xAF,
180 OP2_MOVZX_GvEb = 0xB6,
181 OP2_MOVZX_GvEw = 0xB7,
182 OP2_PEXTRW_GdUdIb = 0xC5,
185 TwoByteOpcodeID jccRel32(Condition cond)
187 return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
190 TwoByteOpcodeID setccOpcode(Condition cond)
192 return (TwoByteOpcodeID)(OP_SETCC + cond);
222 class X86InstructionFormatter;
231 void push_r(RegisterID reg)
233 m_formatter.oneByteOp(OP_PUSH_EAX, reg);
236 void pop_r(RegisterID reg)
238 m_formatter.oneByteOp(OP_POP_EAX, reg);
241 void push_i32(int imm)
243 m_formatter.oneByteOp(OP_PUSH_Iz);
244 m_formatter.immediate32(imm);
247 void push_m(int offset, RegisterID base)
249 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
252 void pop_m(int offset, RegisterID base)
254 m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
257 // Arithmetic operations:
260 void adcl_im(int imm, const void* addr)
262 if (CAN_SIGN_EXTEND_8_32(imm)) {
263 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
264 m_formatter.immediate8(imm);
266 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
267 m_formatter.immediate32(imm);
272 void addl_rr(RegisterID src, RegisterID dst)
274 m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
277 void addl_mr(int offset, RegisterID base, RegisterID dst)
279 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
282 void addl_rm(RegisterID src, int offset, RegisterID base)
284 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
287 void addl_ir(int imm, RegisterID dst)
289 if (CAN_SIGN_EXTEND_8_32(imm)) {
290 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
291 m_formatter.immediate8(imm);
293 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
294 m_formatter.immediate32(imm);
298 void addl_im(int imm, int offset, RegisterID base)
300 if (CAN_SIGN_EXTEND_8_32(imm)) {
301 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
302 m_formatter.immediate8(imm);
304 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
305 m_formatter.immediate32(imm);
310 void addq_rr(RegisterID src, RegisterID dst)
312 m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
315 void addq_ir(int imm, RegisterID dst)
317 if (CAN_SIGN_EXTEND_8_32(imm)) {
318 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
319 m_formatter.immediate8(imm);
321 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
322 m_formatter.immediate32(imm);
326 void addq_im(int imm, int offset, RegisterID base)
328 if (CAN_SIGN_EXTEND_8_32(imm)) {
329 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
330 m_formatter.immediate8(imm);
332 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
333 m_formatter.immediate32(imm);
337 void addl_im(int imm, const void* addr)
339 if (CAN_SIGN_EXTEND_8_32(imm)) {
340 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
341 m_formatter.immediate8(imm);
343 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
344 m_formatter.immediate32(imm);
349 void andl_rr(RegisterID src, RegisterID dst)
351 m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
354 void andl_mr(int offset, RegisterID base, RegisterID dst)
356 m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
359 void andl_rm(RegisterID src, int offset, RegisterID base)
361 m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
364 void andl_ir(int imm, RegisterID dst)
366 if (CAN_SIGN_EXTEND_8_32(imm)) {
367 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
368 m_formatter.immediate8(imm);
370 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
371 m_formatter.immediate32(imm);
375 void andl_im(int imm, int offset, RegisterID base)
377 if (CAN_SIGN_EXTEND_8_32(imm)) {
378 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
379 m_formatter.immediate8(imm);
381 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
382 m_formatter.immediate32(imm);
387 void andq_rr(RegisterID src, RegisterID dst)
389 m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
392 void andq_ir(int imm, RegisterID dst)
394 if (CAN_SIGN_EXTEND_8_32(imm)) {
395 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
396 m_formatter.immediate8(imm);
398 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
399 m_formatter.immediate32(imm);
403 void andl_im(int imm, const void* addr)
405 if (CAN_SIGN_EXTEND_8_32(imm)) {
406 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
407 m_formatter.immediate8(imm);
409 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
410 m_formatter.immediate32(imm);
415 void negl_r(RegisterID dst)
417 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
420 void negl_m(int offset, RegisterID base)
422 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
425 void notl_r(RegisterID dst)
427 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
430 void notl_m(int offset, RegisterID base)
432 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
435 void orl_rr(RegisterID src, RegisterID dst)
437 m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
440 void orl_mr(int offset, RegisterID base, RegisterID dst)
442 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
445 void orl_rm(RegisterID src, int offset, RegisterID base)
447 m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
450 void orl_ir(int imm, RegisterID dst)
452 if (CAN_SIGN_EXTEND_8_32(imm)) {
453 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
454 m_formatter.immediate8(imm);
456 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
457 m_formatter.immediate32(imm);
461 void orl_im(int imm, int offset, RegisterID base)
463 if (CAN_SIGN_EXTEND_8_32(imm)) {
464 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
465 m_formatter.immediate8(imm);
467 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
468 m_formatter.immediate32(imm);
473 void orq_rr(RegisterID src, RegisterID dst)
475 m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
478 void orq_ir(int imm, RegisterID dst)
480 if (CAN_SIGN_EXTEND_8_32(imm)) {
481 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
482 m_formatter.immediate8(imm);
484 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
485 m_formatter.immediate32(imm);
489 void orl_im(int imm, const void* addr)
491 if (CAN_SIGN_EXTEND_8_32(imm)) {
492 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
493 m_formatter.immediate8(imm);
495 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
496 m_formatter.immediate32(imm);
501 void subl_rr(RegisterID src, RegisterID dst)
503 m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
506 void subl_mr(int offset, RegisterID base, RegisterID dst)
508 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
511 void subl_rm(RegisterID src, int offset, RegisterID base)
513 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
516 void subl_ir(int imm, RegisterID dst)
518 if (CAN_SIGN_EXTEND_8_32(imm)) {
519 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
520 m_formatter.immediate8(imm);
522 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
523 m_formatter.immediate32(imm);
527 void subl_im(int imm, int offset, RegisterID base)
529 if (CAN_SIGN_EXTEND_8_32(imm)) {
530 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
531 m_formatter.immediate8(imm);
533 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
534 m_formatter.immediate32(imm);
539 void subq_rr(RegisterID src, RegisterID dst)
541 m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
544 void subq_ir(int imm, RegisterID dst)
546 if (CAN_SIGN_EXTEND_8_32(imm)) {
547 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
548 m_formatter.immediate8(imm);
550 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
551 m_formatter.immediate32(imm);
555 void subl_im(int imm, const void* addr)
557 if (CAN_SIGN_EXTEND_8_32(imm)) {
558 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
559 m_formatter.immediate8(imm);
561 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
562 m_formatter.immediate32(imm);
567 void xorl_rr(RegisterID src, RegisterID dst)
569 m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
572 void xorl_mr(int offset, RegisterID base, RegisterID dst)
574 m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
577 void xorl_rm(RegisterID src, int offset, RegisterID base)
579 m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
582 void xorl_im(int imm, int offset, RegisterID base)
584 if (CAN_SIGN_EXTEND_8_32(imm)) {
585 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
586 m_formatter.immediate8(imm);
588 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
589 m_formatter.immediate32(imm);
593 void xorl_ir(int imm, RegisterID dst)
595 if (CAN_SIGN_EXTEND_8_32(imm)) {
596 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
597 m_formatter.immediate8(imm);
599 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
600 m_formatter.immediate32(imm);
605 void xorq_rr(RegisterID src, RegisterID dst)
607 m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
610 void xorq_ir(int imm, RegisterID dst)
612 if (CAN_SIGN_EXTEND_8_32(imm)) {
613 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
614 m_formatter.immediate8(imm);
616 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
617 m_formatter.immediate32(imm);
622 void sarl_i8r(int imm, RegisterID dst)
625 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
627 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
628 m_formatter.immediate8(imm);
632 void sarl_CLr(RegisterID dst)
634 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
637 void shrl_i8r(int imm, RegisterID dst)
640 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
642 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
643 m_formatter.immediate8(imm);
647 void shrl_CLr(RegisterID dst)
649 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
652 void shll_i8r(int imm, RegisterID dst)
655 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
657 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
658 m_formatter.immediate8(imm);
662 void shll_CLr(RegisterID dst)
664 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
668 void sarq_CLr(RegisterID dst)
670 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
673 void sarq_i8r(int imm, RegisterID dst)
676 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
678 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
679 m_formatter.immediate8(imm);
684 void imull_rr(RegisterID src, RegisterID dst)
686 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
689 void imull_mr(int offset, RegisterID base, RegisterID dst)
691 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
694 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
696 m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
697 m_formatter.immediate32(value);
700 void idivl_r(RegisterID dst)
702 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
707 void cmpl_rr(RegisterID src, RegisterID dst)
709 m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
712 void cmpl_rm(RegisterID src, int offset, RegisterID base)
714 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
717 void cmpl_mr(int offset, RegisterID base, RegisterID src)
719 m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
722 void cmpl_ir(int imm, RegisterID dst)
724 if (CAN_SIGN_EXTEND_8_32(imm)) {
725 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
726 m_formatter.immediate8(imm);
728 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
729 m_formatter.immediate32(imm);
733 void cmpl_ir_force32(int imm, RegisterID dst)
735 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
736 m_formatter.immediate32(imm);
739 void cmpl_im(int imm, int offset, RegisterID base)
741 if (CAN_SIGN_EXTEND_8_32(imm)) {
742 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
743 m_formatter.immediate8(imm);
745 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
746 m_formatter.immediate32(imm);
750 void cmpb_im(int imm, int offset, RegisterID base)
752 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
753 m_formatter.immediate8(imm);
756 void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
758 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
759 m_formatter.immediate8(imm);
762 void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
764 if (CAN_SIGN_EXTEND_8_32(imm)) {
765 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
766 m_formatter.immediate8(imm);
768 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
769 m_formatter.immediate32(imm);
773 void cmpl_im_force32(int imm, int offset, RegisterID base)
775 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
776 m_formatter.immediate32(imm);
780 void cmpq_rr(RegisterID src, RegisterID dst)
782 m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
785 void cmpq_rm(RegisterID src, int offset, RegisterID base)
787 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
790 void cmpq_mr(int offset, RegisterID base, RegisterID src)
792 m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
795 void cmpq_ir(int imm, RegisterID dst)
797 if (CAN_SIGN_EXTEND_8_32(imm)) {
798 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
799 m_formatter.immediate8(imm);
801 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
802 m_formatter.immediate32(imm);
806 void cmpq_im(int imm, int offset, RegisterID base)
808 if (CAN_SIGN_EXTEND_8_32(imm)) {
809 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
810 m_formatter.immediate8(imm);
812 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
813 m_formatter.immediate32(imm);
817 void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
819 if (CAN_SIGN_EXTEND_8_32(imm)) {
820 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
821 m_formatter.immediate8(imm);
823 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
824 m_formatter.immediate32(imm);
828 void cmpl_rm(RegisterID reg, const void* addr)
830 m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
833 void cmpl_im(int imm, const void* addr)
835 if (CAN_SIGN_EXTEND_8_32(imm)) {
836 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
837 m_formatter.immediate8(imm);
839 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
840 m_formatter.immediate32(imm);
845 void cmpw_ir(int imm, RegisterID dst)
847 if (CAN_SIGN_EXTEND_8_32(imm)) {
848 m_formatter.prefix(PRE_OPERAND_SIZE);
849 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
850 m_formatter.immediate8(imm);
852 m_formatter.prefix(PRE_OPERAND_SIZE);
853 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
854 m_formatter.immediate16(imm);
858 void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
860 m_formatter.prefix(PRE_OPERAND_SIZE);
861 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
864 void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
866 if (CAN_SIGN_EXTEND_8_32(imm)) {
867 m_formatter.prefix(PRE_OPERAND_SIZE);
868 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
869 m_formatter.immediate8(imm);
871 m_formatter.prefix(PRE_OPERAND_SIZE);
872 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
873 m_formatter.immediate16(imm);
877 void testl_rr(RegisterID src, RegisterID dst)
879 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
882 void testl_i32r(int imm, RegisterID dst)
884 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
885 m_formatter.immediate32(imm);
888 void testl_i32m(int imm, int offset, RegisterID base)
890 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
891 m_formatter.immediate32(imm);
894 void testb_rr(RegisterID src, RegisterID dst)
896 m_formatter.oneByteOp8(OP_TEST_EbGb, src, dst);
899 void testb_im(int imm, int offset, RegisterID base)
901 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
902 m_formatter.immediate8(imm);
905 void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
907 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
908 m_formatter.immediate8(imm);
911 void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
913 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
914 m_formatter.immediate32(imm);
918 void testq_rr(RegisterID src, RegisterID dst)
920 m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
923 void testq_i32r(int imm, RegisterID dst)
925 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
926 m_formatter.immediate32(imm);
929 void testq_i32m(int imm, int offset, RegisterID base)
931 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
932 m_formatter.immediate32(imm);
935 void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
937 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
938 m_formatter.immediate32(imm);
942 void testw_rr(RegisterID src, RegisterID dst)
944 m_formatter.prefix(PRE_OPERAND_SIZE);
945 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
948 void testb_i8r(int imm, RegisterID dst)
950 m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
951 m_formatter.immediate8(imm);
954 void setCC_r(Condition cond, RegisterID dst)
956 m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
959 void sete_r(RegisterID dst)
961 m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
964 void setz_r(RegisterID dst)
969 void setne_r(RegisterID dst)
971 m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
974 void setnz_r(RegisterID dst)
983 m_formatter.oneByteOp(OP_CDQ);
986 void xchgl_rr(RegisterID src, RegisterID dst)
988 m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
992 void xchgq_rr(RegisterID src, RegisterID dst)
994 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
998 void movl_rr(RegisterID src, RegisterID dst)
1000 m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
1003 void movl_rm(RegisterID src, int offset, RegisterID base)
1005 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
1008 void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
1010 m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
1013 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1015 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
1018 void movl_mEAX(const void* addr)
1020 m_formatter.oneByteOp(OP_MOV_EAXOv);
1022 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1024 m_formatter.immediate32(reinterpret_cast<int>(addr));
1028 void movl_mr(int offset, RegisterID base, RegisterID dst)
1030 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
1033 void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
1035 m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
1038 void movl_mr_disp8(int offset, RegisterID base, RegisterID dst)
1040 m_formatter.oneByteOp_disp8(OP_MOV_GvEv, dst, base, offset);
1043 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1045 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
1048 void movl_i32r(int imm, RegisterID dst)
1050 m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
1051 m_formatter.immediate32(imm);
1054 void movl_i32m(int imm, int offset, RegisterID base)
1056 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1057 m_formatter.immediate32(imm);
1060 void movl_EAXm(const void* addr)
1062 m_formatter.oneByteOp(OP_MOV_OvEAX);
1064 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1066 m_formatter.immediate32(reinterpret_cast<int>(addr));
1071 void movq_rr(RegisterID src, RegisterID dst)
1073 m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
1076 void movq_rm(RegisterID src, int offset, RegisterID base)
1078 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
1081 void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
1083 m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
1086 void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1088 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
1091 void movq_mEAX(const void* addr)
1093 m_formatter.oneByteOp64(OP_MOV_EAXOv);
1094 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1097 void movq_EAXm(const void* addr)
1099 m_formatter.oneByteOp64(OP_MOV_OvEAX);
1100 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1103 void movq_mr(int offset, RegisterID base, RegisterID dst)
1105 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
1108 void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
1110 m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
1113 void movq_mr_disp8(int offset, RegisterID base, RegisterID dst)
1115 m_formatter.oneByteOp64_disp8(OP_MOV_GvEv, dst, base, offset);
1118 void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1120 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
1123 void movq_i32m(int imm, int offset, RegisterID base)
1125 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1126 m_formatter.immediate32(imm);
1129 void movq_i64r(int64_t imm, RegisterID dst)
1131 m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
1132 m_formatter.immediate64(imm);
1135 void movsxd_rr(RegisterID src, RegisterID dst)
1137 m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
1142 void movl_rm(RegisterID src, const void* addr)
1144 if (src == X86Registers::eax)
1147 m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
1150 void movl_mr(const void* addr, RegisterID dst)
1152 if (dst == X86Registers::eax)
1155 m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
1158 void movl_i32m(int imm, const void* addr)
1160 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
1161 m_formatter.immediate32(imm);
1165 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
1167 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
1170 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1172 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
1175 void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1177 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset);
1180 void movzbl_rr(RegisterID src, RegisterID dst)
1182 // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
1183 // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
1184 // REX prefixes are defined to be silently ignored by the processor.
1185 m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
1188 void leal_mr(int offset, RegisterID base, RegisterID dst)
1190 m_formatter.oneByteOp(OP_LEA, dst, base, offset);
1193 void leaq_mr(int offset, RegisterID base, RegisterID dst)
1195 m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
1201 AssemblerLabel call()
1203 m_formatter.oneByteOp(OP_CALL_rel32);
1204 return m_formatter.immediateRel32();
1207 AssemblerLabel call(RegisterID dst)
1209 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
1210 return m_formatter.label();
1213 void call_m(int offset, RegisterID base)
1215 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
1218 AssemblerLabel jmp()
1220 m_formatter.oneByteOp(OP_JMP_rel32);
1221 return m_formatter.immediateRel32();
1224 // Return a AssemblerLabel so we have a label to the jump, so we can use this
1225 // To make a tail recursive call on x86-64. The MacroAssembler
1226 // really shouldn't wrap this as a Jump, since it can't be linked. :-/
1227 AssemblerLabel jmp_r(RegisterID dst)
1229 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
1230 return m_formatter.label();
1233 void jmp_m(int offset, RegisterID base)
1235 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
1238 AssemblerLabel jne()
1240 m_formatter.twoByteOp(jccRel32(ConditionNE));
1241 return m_formatter.immediateRel32();
1244 AssemblerLabel jnz()
1251 m_formatter.twoByteOp(jccRel32(ConditionE));
1252 return m_formatter.immediateRel32();
1262 m_formatter.twoByteOp(jccRel32(ConditionL));
1263 return m_formatter.immediateRel32();
1268 m_formatter.twoByteOp(jccRel32(ConditionB));
1269 return m_formatter.immediateRel32();
1272 AssemblerLabel jle()
1274 m_formatter.twoByteOp(jccRel32(ConditionLE));
1275 return m_formatter.immediateRel32();
1278 AssemblerLabel jbe()
1280 m_formatter.twoByteOp(jccRel32(ConditionBE));
1281 return m_formatter.immediateRel32();
1284 AssemblerLabel jge()
1286 m_formatter.twoByteOp(jccRel32(ConditionGE));
1287 return m_formatter.immediateRel32();
1292 m_formatter.twoByteOp(jccRel32(ConditionG));
1293 return m_formatter.immediateRel32();
1298 m_formatter.twoByteOp(jccRel32(ConditionA));
1299 return m_formatter.immediateRel32();
1302 AssemblerLabel jae()
1304 m_formatter.twoByteOp(jccRel32(ConditionAE));
1305 return m_formatter.immediateRel32();
1310 m_formatter.twoByteOp(jccRel32(ConditionO));
1311 return m_formatter.immediateRel32();
1316 m_formatter.twoByteOp(jccRel32(ConditionP));
1317 return m_formatter.immediateRel32();
1322 m_formatter.twoByteOp(jccRel32(ConditionS));
1323 return m_formatter.immediateRel32();
1326 AssemblerLabel jCC(Condition cond)
1328 m_formatter.twoByteOp(jccRel32(cond));
1329 return m_formatter.immediateRel32();
1334 void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
1336 m_formatter.prefix(PRE_SSE_F2);
1337 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1340 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1342 m_formatter.prefix(PRE_SSE_F2);
1343 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
1346 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
1348 m_formatter.prefix(PRE_SSE_F2);
1349 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
1352 void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
1354 m_formatter.prefix(PRE_SSE_F2);
1355 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
1359 void cvtsi2sd_mr(const void* address, XMMRegisterID dst)
1361 m_formatter.prefix(PRE_SSE_F2);
1362 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
1366 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
1368 m_formatter.prefix(PRE_SSE_F2);
1369 m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
1372 void movd_rr(XMMRegisterID src, RegisterID dst)
1374 m_formatter.prefix(PRE_SSE_66);
1375 m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
1379 void movq_rr(XMMRegisterID src, RegisterID dst)
1381 m_formatter.prefix(PRE_SSE_66);
1382 m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
1385 void movq_rr(RegisterID src, XMMRegisterID dst)
1387 m_formatter.prefix(PRE_SSE_66);
1388 m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
1392 void movsd_rr(XMMRegisterID src, XMMRegisterID dst)
1394 m_formatter.prefix(PRE_SSE_F2);
1395 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1398 void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
1400 m_formatter.prefix(PRE_SSE_F2);
1401 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
1404 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1406 m_formatter.prefix(PRE_SSE_F2);
1407 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
1411 void movsd_mr(const void* address, XMMRegisterID dst)
1413 m_formatter.prefix(PRE_SSE_F2);
1414 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
1418 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
1420 m_formatter.prefix(PRE_SSE_F2);
1421 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1424 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1426 m_formatter.prefix(PRE_SSE_F2);
1427 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
1430 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
1432 m_formatter.prefix(PRE_SSE_66);
1433 m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
1434 m_formatter.immediate8(whichWord);
1437 void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
1439 m_formatter.prefix(PRE_SSE_F2);
1440 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1443 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1445 m_formatter.prefix(PRE_SSE_F2);
1446 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
1449 void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
1451 m_formatter.prefix(PRE_SSE_66);
1452 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1455 void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
1457 m_formatter.prefix(PRE_SSE_66);
1458 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
1461 void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
1463 m_formatter.prefix(PRE_SSE_F2);
1464 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1467 void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1469 m_formatter.prefix(PRE_SSE_F2);
1470 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
1473 void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
1475 m_formatter.prefix(PRE_SSE_66);
1476 m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
1479 void andnpd_rr(XMMRegisterID src, XMMRegisterID dst)
1481 m_formatter.prefix(PRE_SSE_66);
1482 m_formatter.twoByteOp(OP2_ANDNPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
1485 void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
1487 m_formatter.prefix(PRE_SSE_F2);
1488 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1491 // Misc instructions:
1495 m_formatter.oneByteOp(OP_INT3);
1500 m_formatter.oneByteOp(OP_RET);
1503 void predictNotTaken()
1505 m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
1508 // Assembler admin methods:
1510 size_t codeSize() const
1512 return m_formatter.codeSize();
1515 AssemblerLabel label()
1517 return m_formatter.label();
1520 AssemblerLabel align(int alignment)
1522 while (!m_formatter.isAligned(alignment))
1523 m_formatter.oneByteOp(OP_HLT);
1528 // Linking & patching:
1530 // 'link' and 'patch' methods are for use on unprotected code - such as the code
1531 // within the AssemblerBuffer, and code being patched by the patch buffer. Once
1532 // code has been finalized it is (platform support permitting) within a non-
1533 // writable region of memory; to modify the code in an execute-only execuable
1534 // pool the 'repatch' and 'relink' methods should be used.
1536 void linkJump(AssemblerLabel from, AssemblerLabel to)
1538 ASSERT(from.isSet());
1541 char* code = reinterpret_cast<char*>(m_formatter.data());
1542 ASSERT(!reinterpret_cast<int32_t*>(code + from.m_offset)[-1]);
1543 setRel32(code + from.m_offset, code + to.m_offset);
1546 static void linkJump(void* code, AssemblerLabel from, void* to)
1548 ASSERT(from.isSet());
1550 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
1553 static void linkCall(void* code, AssemblerLabel from, void* to)
1555 ASSERT(from.isSet());
1557 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
1560 static void linkPointer(void* code, AssemblerLabel where, void* value)
1562 ASSERT(where.isSet());
1564 setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
1567 static void relinkJump(void* from, void* to)
1572 static void relinkCall(void* from, void* to)
1577 static void repatchCompact(void* where, int32_t value)
1580 ASSERT(value <= std::numeric_limits<int8_t>::max());
1581 setInt8(where, value);
1584 static void repatchInt32(void* where, int32_t value)
1586 setInt32(where, value);
1589 static void repatchPointer(void* where, void* value)
1591 setPointer(where, value);
1594 static void* readPointer(void* where)
1596 return reinterpret_cast<void**>(where)[-1];
1599 static unsigned getCallReturnOffset(AssemblerLabel call)
1601 ASSERT(call.isSet());
1602 return call.m_offset;
1605 static void* getRelocatedAddress(void* code, AssemblerLabel label)
1607 ASSERT(label.isSet());
1608 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + label.m_offset);
1611 static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b)
1613 return b.m_offset - a.m_offset;
1616 PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData)
1618 return m_formatter.executableCopy(globalData);
1621 void rewindToLabel(AssemblerLabel rewindTo) { m_formatter.rewindToLabel(rewindTo); }
1624 unsigned debugOffset() { return m_formatter.debugOffset(); }
1629 m_formatter.oneByteOp(OP_NOP);
1634 static void setPointer(void* where, void* value)
1636 reinterpret_cast<void**>(where)[-1] = value;
1639 static void setInt32(void* where, int32_t value)
1641 reinterpret_cast<int32_t*>(where)[-1] = value;
1644 static void setInt8(void* where, int8_t value)
1646 reinterpret_cast<int8_t*>(where)[-1] = value;
1649 static void setRel32(void* from, void* to)
1651 intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
1652 ASSERT(offset == static_cast<int32_t>(offset));
1654 setInt32(from, offset);
1657 class X86InstructionFormatter {
1659 static const int maxInstructionSize = 16;
1663 // Legacy prefix bytes:
1665 // These are emmitted prior to the instruction.
1667 void prefix(OneByteOpcodeID pre)
1669 m_buffer.putByte(pre);
1672 // Word-sized operands / no operand instruction formatters.
1674 // In addition to the opcode, the following operand permutations are supported:
1675 // * None - instruction takes no operands.
1676 // * One register - the low three bits of the RegisterID are added into the opcode.
1677 // * 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).
1678 // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
1679 // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
1681 // For 32-bit x86 targets, the address operand may also be provided as a void*.
1682 // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
1684 // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
1686 void oneByteOp(OneByteOpcodeID opcode)
1688 m_buffer.ensureSpace(maxInstructionSize);
1689 m_buffer.putByteUnchecked(opcode);
1692 void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
1694 m_buffer.ensureSpace(maxInstructionSize);
1695 emitRexIfNeeded(0, 0, reg);
1696 m_buffer.putByteUnchecked(opcode + (reg & 7));
1699 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
1701 m_buffer.ensureSpace(maxInstructionSize);
1702 emitRexIfNeeded(reg, 0, rm);
1703 m_buffer.putByteUnchecked(opcode);
1704 registerModRM(reg, rm);
1707 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1709 m_buffer.ensureSpace(maxInstructionSize);
1710 emitRexIfNeeded(reg, 0, base);
1711 m_buffer.putByteUnchecked(opcode);
1712 memoryModRM(reg, base, offset);
1715 void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1717 m_buffer.ensureSpace(maxInstructionSize);
1718 emitRexIfNeeded(reg, 0, base);
1719 m_buffer.putByteUnchecked(opcode);
1720 memoryModRM_disp32(reg, base, offset);
1723 void oneByteOp_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1725 m_buffer.ensureSpace(maxInstructionSize);
1726 emitRexIfNeeded(reg, 0, base);
1727 m_buffer.putByteUnchecked(opcode);
1728 memoryModRM_disp8(reg, base, offset);
1731 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
1733 m_buffer.ensureSpace(maxInstructionSize);
1734 emitRexIfNeeded(reg, index, base);
1735 m_buffer.putByteUnchecked(opcode);
1736 memoryModRM(reg, base, index, scale, offset);
1740 void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
1742 m_buffer.ensureSpace(maxInstructionSize);
1743 m_buffer.putByteUnchecked(opcode);
1744 memoryModRM(reg, address);
1748 void twoByteOp(TwoByteOpcodeID opcode)
1750 m_buffer.ensureSpace(maxInstructionSize);
1751 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1752 m_buffer.putByteUnchecked(opcode);
1755 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
1757 m_buffer.ensureSpace(maxInstructionSize);
1758 emitRexIfNeeded(reg, 0, rm);
1759 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1760 m_buffer.putByteUnchecked(opcode);
1761 registerModRM(reg, rm);
1764 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
1766 m_buffer.ensureSpace(maxInstructionSize);
1767 emitRexIfNeeded(reg, 0, base);
1768 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1769 m_buffer.putByteUnchecked(opcode);
1770 memoryModRM(reg, base, offset);
1773 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
1775 m_buffer.ensureSpace(maxInstructionSize);
1776 emitRexIfNeeded(reg, index, base);
1777 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1778 m_buffer.putByteUnchecked(opcode);
1779 memoryModRM(reg, base, index, scale, offset);
1783 void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
1785 m_buffer.ensureSpace(maxInstructionSize);
1786 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1787 m_buffer.putByteUnchecked(opcode);
1788 memoryModRM(reg, address);
1793 // Quad-word-sized operands:
1795 // Used to format 64-bit operantions, planting a REX.w prefix.
1796 // When planting d64 or f64 instructions, not requiring a REX.w prefix,
1797 // the normal (non-'64'-postfixed) formatters should be used.
1799 void oneByteOp64(OneByteOpcodeID opcode)
1801 m_buffer.ensureSpace(maxInstructionSize);
1803 m_buffer.putByteUnchecked(opcode);
1806 void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
1808 m_buffer.ensureSpace(maxInstructionSize);
1809 emitRexW(0, 0, reg);
1810 m_buffer.putByteUnchecked(opcode + (reg & 7));
1813 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
1815 m_buffer.ensureSpace(maxInstructionSize);
1816 emitRexW(reg, 0, rm);
1817 m_buffer.putByteUnchecked(opcode);
1818 registerModRM(reg, rm);
1821 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1823 m_buffer.ensureSpace(maxInstructionSize);
1824 emitRexW(reg, 0, base);
1825 m_buffer.putByteUnchecked(opcode);
1826 memoryModRM(reg, base, offset);
1829 void oneByteOp64_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1831 m_buffer.ensureSpace(maxInstructionSize);
1832 emitRexW(reg, 0, base);
1833 m_buffer.putByteUnchecked(opcode);
1834 memoryModRM_disp32(reg, base, offset);
1837 void oneByteOp64_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
1839 m_buffer.ensureSpace(maxInstructionSize);
1840 emitRexW(reg, 0, base);
1841 m_buffer.putByteUnchecked(opcode);
1842 memoryModRM_disp8(reg, base, offset);
1845 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
1847 m_buffer.ensureSpace(maxInstructionSize);
1848 emitRexW(reg, index, base);
1849 m_buffer.putByteUnchecked(opcode);
1850 memoryModRM(reg, base, index, scale, offset);
1853 void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
1855 m_buffer.ensureSpace(maxInstructionSize);
1856 emitRexW(reg, 0, rm);
1857 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1858 m_buffer.putByteUnchecked(opcode);
1859 registerModRM(reg, rm);
1865 // These methods format byte operations. Byte operations differ from the normal
1866 // formatters in the circumstances under which they will decide to emit REX prefixes.
1867 // These should be used where any register operand signifies a byte register.
1869 // The disctinction is due to the handling of register numbers in the range 4..7 on
1870 // x86-64. These register numbers may either represent the second byte of the first
1871 // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
1873 // Since ah..bh cannot be used in all permutations of operands (specifically cannot
1874 // be accessed where a REX prefix is present), these are likely best treated as
1875 // deprecated. In order to ensure the correct registers spl..dil are selected a
1876 // REX prefix will be emitted for any byte register operand in the range 4..15.
1878 // These formatters may be used in instructions where a mix of operand sizes, in which
1879 // case an unnecessary REX will be emitted, for example:
1881 // In this case a REX will be planted since edi is 7 (and were this a byte operand
1882 // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will
1883 // be silently ignored by the processor.
1885 // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
1886 // is provided to check byte register operands.
1888 void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
1890 m_buffer.ensureSpace(maxInstructionSize);
1891 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
1892 m_buffer.putByteUnchecked(opcode);
1893 registerModRM(groupOp, rm);
1896 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID rm)
1898 m_buffer.ensureSpace(maxInstructionSize);
1899 emitRexIf(byteRegRequiresRex(reg) || byteRegRequiresRex(rm), reg, 0, rm);
1900 m_buffer.putByteUnchecked(opcode);
1901 registerModRM(reg, rm);
1904 void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
1906 m_buffer.ensureSpace(maxInstructionSize);
1907 emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
1908 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1909 m_buffer.putByteUnchecked(opcode);
1910 registerModRM(reg, rm);
1913 void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
1915 m_buffer.ensureSpace(maxInstructionSize);
1916 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
1917 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
1918 m_buffer.putByteUnchecked(opcode);
1919 registerModRM(groupOp, rm);
1924 // An immedaite should be appended where appropriate after an op has been emitted.
1925 // The writes are unchecked since the opcode formatters above will have ensured space.
1927 void immediate8(int imm)
1929 m_buffer.putByteUnchecked(imm);
1932 void immediate16(int imm)
1934 m_buffer.putShortUnchecked(imm);
1937 void immediate32(int imm)
1939 m_buffer.putIntUnchecked(imm);
1942 void immediate64(int64_t imm)
1944 m_buffer.putInt64Unchecked(imm);
1947 AssemblerLabel immediateRel32()
1949 m_buffer.putIntUnchecked(0);
1953 // Administrative methods:
1955 size_t codeSize() const { return m_buffer.codeSize(); }
1956 AssemblerLabel label() const { return m_buffer.label(); }
1957 bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
1958 void* data() const { return m_buffer.data(); }
1960 PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData)
1962 return m_buffer.executableCopy(globalData);
1965 void rewindToLabel(AssemblerLabel rewindTo) { m_buffer.rewindToLabel(rewindTo); }
1968 unsigned debugOffset() { return m_buffer.debugOffset(); }
1973 // Internals; ModRm and REX formatters.
1975 static const RegisterID noBase = X86Registers::ebp;
1976 static const RegisterID hasSib = X86Registers::esp;
1977 static const RegisterID noIndex = X86Registers::esp;
1979 static const RegisterID noBase2 = X86Registers::r13;
1980 static const RegisterID hasSib2 = X86Registers::r12;
1982 // Registers r8 & above require a REX prefixe.
1983 inline bool regRequiresRex(int reg)
1985 return (reg >= X86Registers::r8);
1988 // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
1989 inline bool byteRegRequiresRex(int reg)
1991 return (reg >= X86Registers::esp);
1994 // Format a REX prefix byte.
1995 inline void emitRex(bool w, int r, int x, int b)
1997 m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
2000 // Used to plant a REX byte with REX.w set (for 64-bit operations).
2001 inline void emitRexW(int r, int x, int b)
2003 emitRex(true, r, x, b);
2006 // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
2007 // regRequiresRex() to check other registers (i.e. address base & index).
2008 inline void emitRexIf(bool condition, int r, int x, int b)
2010 if (condition) emitRex(false, r, x, b);
2013 // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
2014 inline void emitRexIfNeeded(int r, int x, int b)
2016 emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b);
2019 // No REX prefix bytes on 32-bit x86.
2020 inline bool regRequiresRex(int) { return false; }
2021 inline bool byteRegRequiresRex(int) { return false; }
2022 inline void emitRexIf(bool, int, int, int) {}
2023 inline void emitRexIfNeeded(int, int, int) {}
2033 void putModRm(ModRmMode mode, int reg, RegisterID rm)
2035 m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
2038 void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
2040 ASSERT(mode != ModRmRegister);
2042 putModRm(mode, reg, hasSib);
2043 m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
2046 void registerModRM(int reg, RegisterID rm)
2048 putModRm(ModRmRegister, reg, rm);
2051 void memoryModRM(int reg, RegisterID base, int offset)
2053 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2055 if ((base == hasSib) || (base == hasSib2)) {
2057 if (base == hasSib) {
2059 if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
2060 putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
2061 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2062 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
2063 m_buffer.putByteUnchecked(offset);
2065 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2066 m_buffer.putIntUnchecked(offset);
2070 if (!offset && (base != noBase) && (base != noBase2))
2072 if (!offset && (base != noBase))
2074 putModRm(ModRmMemoryNoDisp, reg, base);
2075 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2076 putModRm(ModRmMemoryDisp8, reg, base);
2077 m_buffer.putByteUnchecked(offset);
2079 putModRm(ModRmMemoryDisp32, reg, base);
2080 m_buffer.putIntUnchecked(offset);
2085 void memoryModRM_disp8(int reg, RegisterID base, int offset)
2087 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2088 ASSERT(CAN_SIGN_EXTEND_8_32(offset));
2090 if ((base == hasSib) || (base == hasSib2)) {
2092 if (base == hasSib) {
2094 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
2095 m_buffer.putByteUnchecked(offset);
2097 putModRm(ModRmMemoryDisp8, reg, base);
2098 m_buffer.putByteUnchecked(offset);
2102 void memoryModRM_disp32(int reg, RegisterID base, int offset)
2104 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2106 if ((base == hasSib) || (base == hasSib2)) {
2108 if (base == hasSib) {
2110 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2111 m_buffer.putIntUnchecked(offset);
2113 putModRm(ModRmMemoryDisp32, reg, base);
2114 m_buffer.putIntUnchecked(offset);
2118 void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
2120 ASSERT(index != noIndex);
2123 if (!offset && (base != noBase) && (base != noBase2))
2125 if (!offset && (base != noBase))
2127 putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
2128 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2129 putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
2130 m_buffer.putByteUnchecked(offset);
2132 putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
2133 m_buffer.putIntUnchecked(offset);
2138 void memoryModRM(int reg, const void* address)
2140 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
2141 putModRm(ModRmMemoryNoDisp, reg, noBase);
2142 m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address));
2146 AssemblerBuffer m_buffer;
2152 #endif // ENABLE(ASSEMBLER) && CPU(X86)
2154 #endif // X86Assembler_h