2 * Copyright (C) 2008, 2012 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"
32 #include "JITCompilationEffort.h"
34 #include <wtf/Assertions.h>
35 #include <wtf/Vector.h>
39 inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
41 namespace X86Registers {
78 typedef X86Registers::RegisterID RegisterID;
79 typedef X86Registers::XMMRegisterID XMMRegisterID;
80 typedef XMMRegisterID FPRegisterID;
100 ConditionC = ConditionB,
101 ConditionNC = ConditionAE,
110 OP_2BYTE_ESCAPE = 0x0F,
115 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
126 OP_MOVSXD_GvEv = 0x63,
128 PRE_OPERAND_SIZE = 0x66,
131 OP_IMUL_GvEvIz = 0x69,
132 OP_GROUP1_EbIb = 0x80,
133 OP_GROUP1_EvIz = 0x81,
134 OP_GROUP1_EvIb = 0x83,
142 OP_GROUP1A_Ev = 0x8F,
148 OP_GROUP2_EvIb = 0xC1,
150 OP_GROUP11_EvIb = 0xC6,
151 OP_GROUP11_EvIz = 0xC7,
153 OP_GROUP2_Ev1 = 0xD1,
154 OP_GROUP2_EvCL = 0xD3,
156 OP_CALL_rel32 = 0xE8,
161 OP_GROUP3_EbIb = 0xF6,
163 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
168 OP2_MOVSD_VsdWsd = 0x10,
169 OP2_MOVSD_WsdVsd = 0x11,
170 OP2_MOVSS_VsdWsd = 0x10,
171 OP2_MOVSS_WsdVsd = 0x11,
172 OP2_CVTSI2SD_VsdEd = 0x2A,
173 OP2_CVTTSD2SI_GdWsd = 0x2C,
174 OP2_UCOMISD_VsdWsd = 0x2E,
175 OP2_ADDSD_VsdWsd = 0x58,
176 OP2_MULSD_VsdWsd = 0x59,
177 OP2_CVTSD2SS_VsdWsd = 0x5A,
178 OP2_CVTSS2SD_VsdWsd = 0x5A,
179 OP2_SUBSD_VsdWsd = 0x5C,
180 OP2_DIVSD_VsdWsd = 0x5E,
181 OP2_SQRTSD_VsdWsd = 0x51,
182 OP2_ANDNPD_VpdWpd = 0x55,
183 OP2_XORPD_VpdWpd = 0x57,
184 OP2_MOVD_VdEd = 0x6E,
185 OP2_MOVD_EdVd = 0x7E,
186 OP2_JCC_rel32 = 0x80,
188 OP2_IMUL_GvEv = 0xAF,
189 OP2_MOVZX_GvEb = 0xB6,
190 OP2_MOVSX_GvEb = 0xBE,
191 OP2_MOVZX_GvEw = 0xB7,
192 OP2_MOVSX_GvEw = 0xBF,
193 OP2_PEXTRW_GdUdIb = 0xC5,
194 OP2_PSLLQ_UdqIb = 0x73,
195 OP2_PSRLQ_UdqIb = 0x73,
196 OP2_POR_VdqWdq = 0XEB,
199 TwoByteOpcodeID jccRel32(Condition cond)
201 return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
204 TwoByteOpcodeID setccOpcode(Condition cond)
206 return (TwoByteOpcodeID)(OP_SETCC + cond);
240 GROUP14_OP_PSLLQ = 6,
241 GROUP14_OP_PSRLQ = 2,
243 ESCAPE_DD_FSTP_doubleReal = 3,
246 class X86InstructionFormatter;
250 : m_indexOfLastWatchpoint(INT_MIN)
251 , m_indexOfTailOfLastWatchpoint(INT_MIN)
257 void push_r(RegisterID reg)
259 m_formatter.oneByteOp(OP_PUSH_EAX, reg);
262 void pop_r(RegisterID reg)
264 m_formatter.oneByteOp(OP_POP_EAX, reg);
267 void push_i32(int imm)
269 m_formatter.oneByteOp(OP_PUSH_Iz);
270 m_formatter.immediate32(imm);
273 void push_m(int offset, RegisterID base)
275 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
278 void pop_m(int offset, RegisterID base)
280 m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
283 // Arithmetic operations:
286 void adcl_im(int imm, const void* addr)
288 if (CAN_SIGN_EXTEND_8_32(imm)) {
289 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
290 m_formatter.immediate8(imm);
292 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
293 m_formatter.immediate32(imm);
298 void addl_rr(RegisterID src, RegisterID dst)
300 m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
303 void addl_mr(int offset, RegisterID base, RegisterID dst)
305 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
309 void addl_mr(const void* addr, RegisterID dst)
311 m_formatter.oneByteOp(OP_ADD_GvEv, dst, addr);
315 void addl_rm(RegisterID src, int offset, RegisterID base)
317 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
320 void addl_ir(int imm, RegisterID dst)
322 if (CAN_SIGN_EXTEND_8_32(imm)) {
323 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
324 m_formatter.immediate8(imm);
326 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
327 m_formatter.immediate32(imm);
331 void addl_im(int imm, int offset, RegisterID base)
333 if (CAN_SIGN_EXTEND_8_32(imm)) {
334 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
335 m_formatter.immediate8(imm);
337 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
338 m_formatter.immediate32(imm);
343 void addq_rr(RegisterID src, RegisterID dst)
345 m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
348 void addq_mr(int offset, RegisterID base, RegisterID dst)
350 m_formatter.oneByteOp64(OP_ADD_GvEv, dst, base, offset);
353 void addq_ir(int imm, RegisterID dst)
355 if (CAN_SIGN_EXTEND_8_32(imm)) {
356 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
357 m_formatter.immediate8(imm);
359 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
360 m_formatter.immediate32(imm);
364 void addq_im(int imm, int offset, RegisterID base)
366 if (CAN_SIGN_EXTEND_8_32(imm)) {
367 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
368 m_formatter.immediate8(imm);
370 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
371 m_formatter.immediate32(imm);
375 void addl_im(int imm, const void* addr)
377 if (CAN_SIGN_EXTEND_8_32(imm)) {
378 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
379 m_formatter.immediate8(imm);
381 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
382 m_formatter.immediate32(imm);
387 void andl_rr(RegisterID src, RegisterID dst)
389 m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
392 void andl_mr(int offset, RegisterID base, RegisterID dst)
394 m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
397 void andl_rm(RegisterID src, int offset, RegisterID base)
399 m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
402 void andl_ir(int imm, RegisterID dst)
404 if (CAN_SIGN_EXTEND_8_32(imm)) {
405 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
406 m_formatter.immediate8(imm);
408 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
409 m_formatter.immediate32(imm);
413 void andl_im(int imm, int offset, RegisterID base)
415 if (CAN_SIGN_EXTEND_8_32(imm)) {
416 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
417 m_formatter.immediate8(imm);
419 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
420 m_formatter.immediate32(imm);
425 void andq_rr(RegisterID src, RegisterID dst)
427 m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
430 void andq_ir(int imm, RegisterID dst)
432 if (CAN_SIGN_EXTEND_8_32(imm)) {
433 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
434 m_formatter.immediate8(imm);
436 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
437 m_formatter.immediate32(imm);
441 void andl_im(int imm, const void* addr)
443 if (CAN_SIGN_EXTEND_8_32(imm)) {
444 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
445 m_formatter.immediate8(imm);
447 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
448 m_formatter.immediate32(imm);
453 void negl_r(RegisterID dst)
455 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
459 void negq_r(RegisterID dst)
461 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
465 void negl_m(int offset, RegisterID base)
467 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
470 void notl_r(RegisterID dst)
472 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
475 void notl_m(int offset, RegisterID base)
477 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
480 void orl_rr(RegisterID src, RegisterID dst)
482 m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
485 void orl_mr(int offset, RegisterID base, RegisterID dst)
487 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
490 void orl_rm(RegisterID src, int offset, RegisterID base)
492 m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
495 void orl_ir(int imm, RegisterID dst)
497 if (CAN_SIGN_EXTEND_8_32(imm)) {
498 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
499 m_formatter.immediate8(imm);
501 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
502 m_formatter.immediate32(imm);
506 void orl_im(int imm, int offset, RegisterID base)
508 if (CAN_SIGN_EXTEND_8_32(imm)) {
509 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
510 m_formatter.immediate8(imm);
512 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
513 m_formatter.immediate32(imm);
518 void orq_rr(RegisterID src, RegisterID dst)
520 m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
523 void orq_ir(int imm, RegisterID dst)
525 if (CAN_SIGN_EXTEND_8_32(imm)) {
526 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
527 m_formatter.immediate8(imm);
529 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
530 m_formatter.immediate32(imm);
534 void orl_im(int imm, const void* addr)
536 if (CAN_SIGN_EXTEND_8_32(imm)) {
537 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
538 m_formatter.immediate8(imm);
540 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
541 m_formatter.immediate32(imm);
546 void subl_rr(RegisterID src, RegisterID dst)
548 m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
551 void subl_mr(int offset, RegisterID base, RegisterID dst)
553 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
556 void subl_rm(RegisterID src, int offset, RegisterID base)
558 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
561 void subl_ir(int imm, RegisterID dst)
563 if (CAN_SIGN_EXTEND_8_32(imm)) {
564 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
565 m_formatter.immediate8(imm);
567 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
568 m_formatter.immediate32(imm);
572 void subl_im(int imm, int offset, RegisterID base)
574 if (CAN_SIGN_EXTEND_8_32(imm)) {
575 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
576 m_formatter.immediate8(imm);
578 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
579 m_formatter.immediate32(imm);
584 void subq_rr(RegisterID src, RegisterID dst)
586 m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
589 void subq_ir(int imm, RegisterID dst)
591 if (CAN_SIGN_EXTEND_8_32(imm)) {
592 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
593 m_formatter.immediate8(imm);
595 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
596 m_formatter.immediate32(imm);
600 void subl_im(int imm, const void* addr)
602 if (CAN_SIGN_EXTEND_8_32(imm)) {
603 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
604 m_formatter.immediate8(imm);
606 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
607 m_formatter.immediate32(imm);
612 void xorl_rr(RegisterID src, RegisterID dst)
614 m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
617 void xorl_mr(int offset, RegisterID base, RegisterID dst)
619 m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
622 void xorl_rm(RegisterID src, int offset, RegisterID base)
624 m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
627 void xorl_im(int imm, int offset, RegisterID base)
629 if (CAN_SIGN_EXTEND_8_32(imm)) {
630 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
631 m_formatter.immediate8(imm);
633 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
634 m_formatter.immediate32(imm);
638 void xorl_ir(int imm, RegisterID dst)
640 if (CAN_SIGN_EXTEND_8_32(imm)) {
641 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
642 m_formatter.immediate8(imm);
644 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
645 m_formatter.immediate32(imm);
650 void xorq_rr(RegisterID src, RegisterID dst)
652 m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
655 void xorq_ir(int imm, RegisterID dst)
657 if (CAN_SIGN_EXTEND_8_32(imm)) {
658 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
659 m_formatter.immediate8(imm);
661 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
662 m_formatter.immediate32(imm);
666 void xorq_rm(RegisterID src, int offset, RegisterID base)
668 m_formatter.oneByteOp64(OP_XOR_EvGv, src, base, offset);
671 void rorq_i8r(int imm, RegisterID dst)
674 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_ROR, dst);
676 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_ROR, dst);
677 m_formatter.immediate8(imm);
683 void sarl_i8r(int imm, RegisterID dst)
686 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
688 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
689 m_formatter.immediate8(imm);
693 void sarl_CLr(RegisterID dst)
695 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
698 void shrl_i8r(int imm, RegisterID dst)
701 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
703 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
704 m_formatter.immediate8(imm);
708 void shrl_CLr(RegisterID dst)
710 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
713 void shll_i8r(int imm, RegisterID dst)
716 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
718 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
719 m_formatter.immediate8(imm);
723 void shll_CLr(RegisterID dst)
725 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
729 void sarq_CLr(RegisterID dst)
731 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
734 void sarq_i8r(int imm, RegisterID dst)
737 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
739 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
740 m_formatter.immediate8(imm);
745 void imull_rr(RegisterID src, RegisterID dst)
747 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
750 void imull_mr(int offset, RegisterID base, RegisterID dst)
752 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
755 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
757 m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
758 m_formatter.immediate32(value);
761 void idivl_r(RegisterID dst)
763 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
768 void cmpl_rr(RegisterID src, RegisterID dst)
770 m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
773 void cmpl_rm(RegisterID src, int offset, RegisterID base)
775 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
778 void cmpl_mr(int offset, RegisterID base, RegisterID src)
780 m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
783 void cmpl_ir(int imm, RegisterID dst)
785 if (CAN_SIGN_EXTEND_8_32(imm)) {
786 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
787 m_formatter.immediate8(imm);
789 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
790 m_formatter.immediate32(imm);
794 void cmpl_ir_force32(int imm, RegisterID dst)
796 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
797 m_formatter.immediate32(imm);
800 void cmpl_im(int imm, int offset, RegisterID base)
802 if (CAN_SIGN_EXTEND_8_32(imm)) {
803 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
804 m_formatter.immediate8(imm);
806 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
807 m_formatter.immediate32(imm);
811 void cmpb_im(int imm, int offset, RegisterID base)
813 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
814 m_formatter.immediate8(imm);
817 void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
819 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
820 m_formatter.immediate8(imm);
824 void cmpb_im(int imm, const void* addr)
826 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, addr);
827 m_formatter.immediate8(imm);
831 void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
833 if (CAN_SIGN_EXTEND_8_32(imm)) {
834 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
835 m_formatter.immediate8(imm);
837 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
838 m_formatter.immediate32(imm);
842 void cmpl_im_force32(int imm, int offset, RegisterID base)
844 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
845 m_formatter.immediate32(imm);
849 void cmpq_rr(RegisterID src, RegisterID dst)
851 m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
854 void cmpq_rm(RegisterID src, int offset, RegisterID base)
856 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
859 void cmpq_mr(int offset, RegisterID base, RegisterID src)
861 m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
864 void cmpq_ir(int imm, RegisterID dst)
866 if (CAN_SIGN_EXTEND_8_32(imm)) {
867 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
868 m_formatter.immediate8(imm);
870 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
871 m_formatter.immediate32(imm);
875 void cmpq_im(int imm, int offset, RegisterID base)
877 if (CAN_SIGN_EXTEND_8_32(imm)) {
878 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
879 m_formatter.immediate8(imm);
881 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
882 m_formatter.immediate32(imm);
886 void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
888 if (CAN_SIGN_EXTEND_8_32(imm)) {
889 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
890 m_formatter.immediate8(imm);
892 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
893 m_formatter.immediate32(imm);
897 void cmpl_rm(RegisterID reg, const void* addr)
899 m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
902 void cmpl_im(int imm, const void* addr)
904 if (CAN_SIGN_EXTEND_8_32(imm)) {
905 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
906 m_formatter.immediate8(imm);
908 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
909 m_formatter.immediate32(imm);
914 void cmpw_ir(int imm, RegisterID dst)
916 if (CAN_SIGN_EXTEND_8_32(imm)) {
917 m_formatter.prefix(PRE_OPERAND_SIZE);
918 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
919 m_formatter.immediate8(imm);
921 m_formatter.prefix(PRE_OPERAND_SIZE);
922 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
923 m_formatter.immediate16(imm);
927 void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
929 m_formatter.prefix(PRE_OPERAND_SIZE);
930 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
933 void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
935 if (CAN_SIGN_EXTEND_8_32(imm)) {
936 m_formatter.prefix(PRE_OPERAND_SIZE);
937 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
938 m_formatter.immediate8(imm);
940 m_formatter.prefix(PRE_OPERAND_SIZE);
941 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
942 m_formatter.immediate16(imm);
946 void testl_rr(RegisterID src, RegisterID dst)
948 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
951 void testl_i32r(int imm, RegisterID dst)
953 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
954 m_formatter.immediate32(imm);
957 void testl_i32m(int imm, int offset, RegisterID base)
959 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
960 m_formatter.immediate32(imm);
963 void testb_rr(RegisterID src, RegisterID dst)
965 m_formatter.oneByteOp8(OP_TEST_EbGb, src, dst);
968 void testb_im(int imm, int offset, RegisterID base)
970 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
971 m_formatter.immediate8(imm);
974 void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
976 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
977 m_formatter.immediate8(imm);
981 void testb_im(int imm, const void* addr)
983 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, addr);
984 m_formatter.immediate8(imm);
988 void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
990 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
991 m_formatter.immediate32(imm);
995 void testq_rr(RegisterID src, RegisterID dst)
997 m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
1000 void testq_rm(RegisterID src, int offset, RegisterID base)
1002 m_formatter.oneByteOp64(OP_TEST_EvGv, src, base, offset);
1005 void testq_i32r(int imm, RegisterID dst)
1007 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
1008 m_formatter.immediate32(imm);
1011 void testq_i32m(int imm, int offset, RegisterID base)
1013 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
1014 m_formatter.immediate32(imm);
1017 void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1019 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
1020 m_formatter.immediate32(imm);
1024 void testw_rr(RegisterID src, RegisterID dst)
1026 m_formatter.prefix(PRE_OPERAND_SIZE);
1027 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
1030 void testb_i8r(int imm, RegisterID dst)
1032 m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
1033 m_formatter.immediate8(imm);
1036 void setCC_r(Condition cond, RegisterID dst)
1038 m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
1041 void sete_r(RegisterID dst)
1043 m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
1046 void setz_r(RegisterID dst)
1051 void setne_r(RegisterID dst)
1053 m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
1056 void setnz_r(RegisterID dst)
1061 // Various move ops:
1065 m_formatter.oneByteOp(OP_CDQ);
1068 void fstpl(int offset, RegisterID base)
1070 m_formatter.oneByteOp(OP_ESCAPE_DD, ESCAPE_DD_FSTP_doubleReal, base, offset);
1073 void xchgl_rr(RegisterID src, RegisterID dst)
1075 m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
1079 void xchgq_rr(RegisterID src, RegisterID dst)
1081 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
1085 void movl_rr(RegisterID src, RegisterID dst)
1087 m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
1090 void movl_rm(RegisterID src, int offset, RegisterID base)
1092 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
1095 void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
1097 m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
1100 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1102 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
1105 void movl_mEAX(const void* addr)
1107 m_formatter.oneByteOp(OP_MOV_EAXOv);
1109 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1111 m_formatter.immediate32(reinterpret_cast<int>(addr));
1115 void movl_mr(int offset, RegisterID base, RegisterID dst)
1117 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
1120 void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
1122 m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
1125 void movl_mr_disp8(int offset, RegisterID base, RegisterID dst)
1127 m_formatter.oneByteOp_disp8(OP_MOV_GvEv, dst, base, offset);
1130 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1132 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
1135 void movl_i32r(int imm, RegisterID dst)
1137 m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
1138 m_formatter.immediate32(imm);
1141 void movl_i32m(int imm, int offset, RegisterID base)
1143 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1144 m_formatter.immediate32(imm);
1147 void movl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1149 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
1150 m_formatter.immediate32(imm);
1153 void movb_i8m(int imm, int offset, RegisterID base)
1155 ASSERT(-128 <= imm && imm < 128);
1156 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, offset);
1157 m_formatter.immediate8(imm);
1160 void movb_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1162 ASSERT(-128 <= imm && imm < 128);
1163 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, index, scale, offset);
1164 m_formatter.immediate8(imm);
1167 void movb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1169 m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, index, scale, offset);
1172 void movw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1174 m_formatter.prefix(PRE_OPERAND_SIZE);
1175 m_formatter.oneByteOp8(OP_MOV_EvGv, src, base, index, scale, offset);
1178 void movl_EAXm(const void* addr)
1180 m_formatter.oneByteOp(OP_MOV_OvEAX);
1182 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1184 m_formatter.immediate32(reinterpret_cast<int>(addr));
1189 void movq_rr(RegisterID src, RegisterID dst)
1191 m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
1194 void movq_rm(RegisterID src, int offset, RegisterID base)
1196 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
1199 void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
1201 m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
1204 void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1206 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
1209 void movq_mEAX(const void* addr)
1211 m_formatter.oneByteOp64(OP_MOV_EAXOv);
1212 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1215 void movq_EAXm(const void* addr)
1217 m_formatter.oneByteOp64(OP_MOV_OvEAX);
1218 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1221 void movq_mr(int offset, RegisterID base, RegisterID dst)
1223 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
1226 void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
1228 m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
1231 void movq_mr_disp8(int offset, RegisterID base, RegisterID dst)
1233 m_formatter.oneByteOp64_disp8(OP_MOV_GvEv, dst, base, offset);
1236 void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1238 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
1241 void movq_i32m(int imm, int offset, RegisterID base)
1243 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1244 m_formatter.immediate32(imm);
1247 void movq_i64r(int64_t imm, RegisterID dst)
1249 m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
1250 m_formatter.immediate64(imm);
1253 void movsxd_rr(RegisterID src, RegisterID dst)
1255 m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
1260 void movl_rm(RegisterID src, const void* addr)
1262 if (src == X86Registers::eax)
1265 m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
1268 void movl_mr(const void* addr, RegisterID dst)
1270 if (dst == X86Registers::eax)
1273 m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
1276 void movl_i32m(int imm, const void* addr)
1278 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
1279 m_formatter.immediate32(imm);
1283 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
1285 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
1288 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1290 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
1293 void movswl_mr(int offset, RegisterID base, RegisterID dst)
1295 m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, offset);
1298 void movswl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1300 m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, index, scale, offset);
1303 void movzbl_mr(int offset, RegisterID base, RegisterID dst)
1305 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, offset);
1308 void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1310 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset);
1313 void movsbl_mr(int offset, RegisterID base, RegisterID dst)
1315 m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, offset);
1318 void movsbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1320 m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, index, scale, offset);
1323 void movzbl_rr(RegisterID src, RegisterID dst)
1325 // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
1326 // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
1327 // REX prefixes are defined to be silently ignored by the processor.
1328 m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
1331 void leal_mr(int offset, RegisterID base, RegisterID dst)
1333 m_formatter.oneByteOp(OP_LEA, dst, base, offset);
1336 void leaq_mr(int offset, RegisterID base, RegisterID dst)
1338 m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
1344 AssemblerLabel call()
1346 m_formatter.oneByteOp(OP_CALL_rel32);
1347 return m_formatter.immediateRel32();
1350 AssemblerLabel call(RegisterID dst)
1352 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
1353 return m_formatter.label();
1356 void call_m(int offset, RegisterID base)
1358 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
1361 AssemblerLabel jmp()
1363 m_formatter.oneByteOp(OP_JMP_rel32);
1364 return m_formatter.immediateRel32();
1367 // Return a AssemblerLabel so we have a label to the jump, so we can use this
1368 // To make a tail recursive call on x86-64. The MacroAssembler
1369 // really shouldn't wrap this as a Jump, since it can't be linked. :-/
1370 AssemblerLabel jmp_r(RegisterID dst)
1372 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
1373 return m_formatter.label();
1376 void jmp_m(int offset, RegisterID base)
1378 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
1382 void jmp_m(const void* address)
1384 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, address);
1388 AssemblerLabel jne()
1390 m_formatter.twoByteOp(jccRel32(ConditionNE));
1391 return m_formatter.immediateRel32();
1394 AssemblerLabel jnz()
1401 m_formatter.twoByteOp(jccRel32(ConditionE));
1402 return m_formatter.immediateRel32();
1412 m_formatter.twoByteOp(jccRel32(ConditionL));
1413 return m_formatter.immediateRel32();
1418 m_formatter.twoByteOp(jccRel32(ConditionB));
1419 return m_formatter.immediateRel32();
1422 AssemblerLabel jle()
1424 m_formatter.twoByteOp(jccRel32(ConditionLE));
1425 return m_formatter.immediateRel32();
1428 AssemblerLabel jbe()
1430 m_formatter.twoByteOp(jccRel32(ConditionBE));
1431 return m_formatter.immediateRel32();
1434 AssemblerLabel jge()
1436 m_formatter.twoByteOp(jccRel32(ConditionGE));
1437 return m_formatter.immediateRel32();
1442 m_formatter.twoByteOp(jccRel32(ConditionG));
1443 return m_formatter.immediateRel32();
1448 m_formatter.twoByteOp(jccRel32(ConditionA));
1449 return m_formatter.immediateRel32();
1452 AssemblerLabel jae()
1454 m_formatter.twoByteOp(jccRel32(ConditionAE));
1455 return m_formatter.immediateRel32();
1460 m_formatter.twoByteOp(jccRel32(ConditionO));
1461 return m_formatter.immediateRel32();
1466 m_formatter.twoByteOp(jccRel32(ConditionP));
1467 return m_formatter.immediateRel32();
1472 m_formatter.twoByteOp(jccRel32(ConditionS));
1473 return m_formatter.immediateRel32();
1476 AssemblerLabel jCC(Condition cond)
1478 m_formatter.twoByteOp(jccRel32(cond));
1479 return m_formatter.immediateRel32();
1484 void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
1486 m_formatter.prefix(PRE_SSE_F2);
1487 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1490 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1492 m_formatter.prefix(PRE_SSE_F2);
1493 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
1497 void addsd_mr(const void* address, XMMRegisterID dst)
1499 m_formatter.prefix(PRE_SSE_F2);
1500 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, address);
1504 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
1506 m_formatter.prefix(PRE_SSE_F2);
1507 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
1510 void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
1512 m_formatter.prefix(PRE_SSE_F2);
1513 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
1517 void cvtsi2sd_mr(const void* address, XMMRegisterID dst)
1519 m_formatter.prefix(PRE_SSE_F2);
1520 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
1524 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
1526 m_formatter.prefix(PRE_SSE_F2);
1527 m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
1530 void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst)
1532 m_formatter.prefix(PRE_SSE_F2);
1533 m_formatter.twoByteOp(OP2_CVTSD2SS_VsdWsd, dst, (RegisterID)src);
1536 void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst)
1538 m_formatter.prefix(PRE_SSE_F3);
1539 m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, (RegisterID)src);
1543 void cvttsd2siq_rr(XMMRegisterID src, RegisterID dst)
1545 m_formatter.prefix(PRE_SSE_F2);
1546 m_formatter.twoByteOp64(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
1550 void movd_rr(XMMRegisterID src, RegisterID dst)
1552 m_formatter.prefix(PRE_SSE_66);
1553 m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
1556 void movd_rr(RegisterID src, XMMRegisterID dst)
1558 m_formatter.prefix(PRE_SSE_66);
1559 m_formatter.twoByteOp(OP2_MOVD_VdEd, (RegisterID)dst, src);
1563 void movq_rr(XMMRegisterID src, RegisterID dst)
1565 m_formatter.prefix(PRE_SSE_66);
1566 m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
1569 void movq_rr(RegisterID src, XMMRegisterID dst)
1571 m_formatter.prefix(PRE_SSE_66);
1572 m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
1576 void movsd_rr(XMMRegisterID src, XMMRegisterID dst)
1578 m_formatter.prefix(PRE_SSE_F2);
1579 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1582 void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
1584 m_formatter.prefix(PRE_SSE_F2);
1585 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
1588 void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1590 m_formatter.prefix(PRE_SSE_F2);
1591 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
1594 void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1596 m_formatter.prefix(PRE_SSE_F3);
1597 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
1600 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1602 m_formatter.prefix(PRE_SSE_F2);
1603 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
1606 void movsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
1608 m_formatter.prefix(PRE_SSE_F2);
1609 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
1612 void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
1614 m_formatter.prefix(PRE_SSE_F3);
1615 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
1619 void movsd_mr(const void* address, XMMRegisterID dst)
1621 m_formatter.prefix(PRE_SSE_F2);
1622 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
1624 void movsd_rm(XMMRegisterID src, const void* address)
1626 m_formatter.prefix(PRE_SSE_F2);
1627 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, address);
1631 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
1633 m_formatter.prefix(PRE_SSE_F2);
1634 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1637 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1639 m_formatter.prefix(PRE_SSE_F2);
1640 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
1643 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
1645 m_formatter.prefix(PRE_SSE_66);
1646 m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
1647 m_formatter.immediate8(whichWord);
1650 void psllq_i8r(int imm, XMMRegisterID dst)
1652 m_formatter.prefix(PRE_SSE_66);
1653 m_formatter.twoByteOp8(OP2_PSLLQ_UdqIb, GROUP14_OP_PSLLQ, (RegisterID)dst);
1654 m_formatter.immediate8(imm);
1657 void psrlq_i8r(int imm, XMMRegisterID dst)
1659 m_formatter.prefix(PRE_SSE_66);
1660 m_formatter.twoByteOp8(OP2_PSRLQ_UdqIb, GROUP14_OP_PSRLQ, (RegisterID)dst);
1661 m_formatter.immediate8(imm);
1664 void por_rr(XMMRegisterID src, XMMRegisterID dst)
1666 m_formatter.prefix(PRE_SSE_66);
1667 m_formatter.twoByteOp(OP2_POR_VdqWdq, (RegisterID)dst, (RegisterID)src);
1670 void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
1672 m_formatter.prefix(PRE_SSE_F2);
1673 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1676 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1678 m_formatter.prefix(PRE_SSE_F2);
1679 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
1682 void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
1684 m_formatter.prefix(PRE_SSE_66);
1685 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1688 void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
1690 m_formatter.prefix(PRE_SSE_66);
1691 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
1694 void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
1696 m_formatter.prefix(PRE_SSE_F2);
1697 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1700 void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
1702 m_formatter.prefix(PRE_SSE_F2);
1703 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
1706 void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
1708 m_formatter.prefix(PRE_SSE_66);
1709 m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
1712 void andnpd_rr(XMMRegisterID src, XMMRegisterID dst)
1714 m_formatter.prefix(PRE_SSE_66);
1715 m_formatter.twoByteOp(OP2_ANDNPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
1718 void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
1720 m_formatter.prefix(PRE_SSE_F2);
1721 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
1724 // Misc instructions:
1728 m_formatter.oneByteOp(OP_INT3);
1733 m_formatter.oneByteOp(OP_RET);
1736 void predictNotTaken()
1738 m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
1741 // Assembler admin methods:
1743 size_t codeSize() const
1745 return m_formatter.codeSize();
1748 AssemblerLabel labelForWatchpoint()
1750 AssemblerLabel result = m_formatter.label();
1751 if (static_cast<int>(result.m_offset) != m_indexOfLastWatchpoint)
1753 m_indexOfLastWatchpoint = result.m_offset;
1754 m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
1758 AssemblerLabel labelIgnoringWatchpoints()
1760 return m_formatter.label();
1763 AssemblerLabel label()
1765 AssemblerLabel result = m_formatter.label();
1766 while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
1768 result = m_formatter.label();
1773 AssemblerLabel align(int alignment)
1775 while (!m_formatter.isAligned(alignment))
1776 m_formatter.oneByteOp(OP_HLT);
1781 // Linking & patching:
1783 // 'link' and 'patch' methods are for use on unprotected code - such as the code
1784 // within the AssemblerBuffer, and code being patched by the patch buffer. Once
1785 // code has been finalized it is (platform support permitting) within a non-
1786 // writable region of memory; to modify the code in an execute-only execuable
1787 // pool the 'repatch' and 'relink' methods should be used.
1789 void linkJump(AssemblerLabel from, AssemblerLabel to)
1791 ASSERT(from.isSet());
1794 char* code = reinterpret_cast<char*>(m_formatter.data());
1795 ASSERT(!reinterpret_cast<int32_t*>(code + from.m_offset)[-1]);
1796 setRel32(code + from.m_offset, code + to.m_offset);
1799 static void linkJump(void* code, AssemblerLabel from, void* to)
1801 ASSERT(from.isSet());
1803 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
1806 static void linkCall(void* code, AssemblerLabel from, void* to)
1808 ASSERT(from.isSet());
1810 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
1813 static void linkPointer(void* code, AssemblerLabel where, void* value)
1815 ASSERT(where.isSet());
1817 setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
1820 static void relinkJump(void* from, void* to)
1825 static void relinkCall(void* from, void* to)
1830 static void repatchCompact(void* where, int32_t value)
1832 ASSERT(value >= std::numeric_limits<int8_t>::min());
1833 ASSERT(value <= std::numeric_limits<int8_t>::max());
1834 setInt8(where, value);
1837 static void repatchInt32(void* where, int32_t value)
1839 setInt32(where, value);
1842 static void repatchPointer(void* where, void* value)
1844 setPointer(where, value);
1847 static void* readPointer(void* where)
1849 return reinterpret_cast<void**>(where)[-1];
1852 static void replaceWithJump(void* instructionStart, void* to)
1854 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
1855 uint8_t* dstPtr = reinterpret_cast<uint8_t*>(to);
1856 intptr_t distance = (intptr_t)(dstPtr - (ptr + 5));
1857 ptr[0] = static_cast<uint8_t>(OP_JMP_rel32);
1858 *reinterpret_cast<int32_t*>(ptr + 1) = static_cast<int32_t>(distance);
1861 static ptrdiff_t maxJumpReplacementSize()
1866 static void replaceWithLoad(void* instructionStart)
1868 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
1870 if ((*ptr & ~15) == PRE_REX)
1880 ASSERT_NOT_REACHED();
1884 static void replaceWithAddressComputation(void* instructionStart)
1886 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
1888 if ((*ptr & ~15) == PRE_REX)
1898 ASSERT_NOT_REACHED();
1902 static unsigned getCallReturnOffset(AssemblerLabel call)
1904 ASSERT(call.isSet());
1905 return call.m_offset;
1908 static void* getRelocatedAddress(void* code, AssemblerLabel label)
1910 ASSERT(label.isSet());
1911 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + label.m_offset);
1914 static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b)
1916 return b.m_offset - a.m_offset;
1919 PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
1921 return m_formatter.executableCopy(globalData, ownerUID, effort);
1924 unsigned debugOffset() { return m_formatter.debugOffset(); }
1928 m_formatter.oneByteOp(OP_NOP);
1931 // This is a no-op on x86
1932 ALWAYS_INLINE static void cacheFlush(void*, size_t) { }
1936 static void setPointer(void* where, void* value)
1938 reinterpret_cast<void**>(where)[-1] = value;
1941 static void setInt32(void* where, int32_t value)
1943 reinterpret_cast<int32_t*>(where)[-1] = value;
1946 static void setInt8(void* where, int8_t value)
1948 reinterpret_cast<int8_t*>(where)[-1] = value;
1951 static void setRel32(void* from, void* to)
1953 intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
1954 ASSERT(offset == static_cast<int32_t>(offset));
1956 setInt32(from, offset);
1959 class X86InstructionFormatter {
1961 static const int maxInstructionSize = 16;
1965 // Legacy prefix bytes:
1967 // These are emmitted prior to the instruction.
1969 void prefix(OneByteOpcodeID pre)
1971 m_buffer.putByte(pre);
1974 // Word-sized operands / no operand instruction formatters.
1976 // In addition to the opcode, the following operand permutations are supported:
1977 // * None - instruction takes no operands.
1978 // * One register - the low three bits of the RegisterID are added into the opcode.
1979 // * 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).
1980 // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
1981 // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
1983 // For 32-bit x86 targets, the address operand may also be provided as a void*.
1984 // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
1986 // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
1988 void oneByteOp(OneByteOpcodeID opcode)
1990 m_buffer.ensureSpace(maxInstructionSize);
1991 m_buffer.putByteUnchecked(opcode);
1994 void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
1996 m_buffer.ensureSpace(maxInstructionSize);
1997 emitRexIfNeeded(0, 0, reg);
1998 m_buffer.putByteUnchecked(opcode + (reg & 7));
2001 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
2003 m_buffer.ensureSpace(maxInstructionSize);
2004 emitRexIfNeeded(reg, 0, rm);
2005 m_buffer.putByteUnchecked(opcode);
2006 registerModRM(reg, rm);
2009 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2011 m_buffer.ensureSpace(maxInstructionSize);
2012 emitRexIfNeeded(reg, 0, base);
2013 m_buffer.putByteUnchecked(opcode);
2014 memoryModRM(reg, base, offset);
2017 void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2019 m_buffer.ensureSpace(maxInstructionSize);
2020 emitRexIfNeeded(reg, 0, base);
2021 m_buffer.putByteUnchecked(opcode);
2022 memoryModRM_disp32(reg, base, offset);
2025 void oneByteOp_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2027 m_buffer.ensureSpace(maxInstructionSize);
2028 emitRexIfNeeded(reg, 0, base);
2029 m_buffer.putByteUnchecked(opcode);
2030 memoryModRM_disp8(reg, base, offset);
2033 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2035 m_buffer.ensureSpace(maxInstructionSize);
2036 emitRexIfNeeded(reg, index, base);
2037 m_buffer.putByteUnchecked(opcode);
2038 memoryModRM(reg, base, index, scale, offset);
2042 void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
2044 m_buffer.ensureSpace(maxInstructionSize);
2045 m_buffer.putByteUnchecked(opcode);
2046 memoryModRM(reg, address);
2050 void twoByteOp(TwoByteOpcodeID opcode)
2052 m_buffer.ensureSpace(maxInstructionSize);
2053 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2054 m_buffer.putByteUnchecked(opcode);
2057 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID rm)
2059 m_buffer.ensureSpace(maxInstructionSize);
2060 emitRexIfNeeded(reg, 0, rm);
2061 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2062 m_buffer.putByteUnchecked(opcode);
2063 registerModRM(reg, rm);
2066 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, int offset)
2068 m_buffer.ensureSpace(maxInstructionSize);
2069 emitRexIfNeeded(reg, 0, base);
2070 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2071 m_buffer.putByteUnchecked(opcode);
2072 memoryModRM(reg, base, offset);
2075 void twoByteOp(TwoByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2077 m_buffer.ensureSpace(maxInstructionSize);
2078 emitRexIfNeeded(reg, index, base);
2079 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2080 m_buffer.putByteUnchecked(opcode);
2081 memoryModRM(reg, base, index, scale, offset);
2085 void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
2087 m_buffer.ensureSpace(maxInstructionSize);
2088 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2089 m_buffer.putByteUnchecked(opcode);
2090 memoryModRM(reg, address);
2095 // Quad-word-sized operands:
2097 // Used to format 64-bit operantions, planting a REX.w prefix.
2098 // When planting d64 or f64 instructions, not requiring a REX.w prefix,
2099 // the normal (non-'64'-postfixed) formatters should be used.
2101 void oneByteOp64(OneByteOpcodeID opcode)
2103 m_buffer.ensureSpace(maxInstructionSize);
2105 m_buffer.putByteUnchecked(opcode);
2108 void oneByteOp64(OneByteOpcodeID opcode, RegisterID reg)
2110 m_buffer.ensureSpace(maxInstructionSize);
2111 emitRexW(0, 0, reg);
2112 m_buffer.putByteUnchecked(opcode + (reg & 7));
2115 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID rm)
2117 m_buffer.ensureSpace(maxInstructionSize);
2118 emitRexW(reg, 0, rm);
2119 m_buffer.putByteUnchecked(opcode);
2120 registerModRM(reg, rm);
2123 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2125 m_buffer.ensureSpace(maxInstructionSize);
2126 emitRexW(reg, 0, base);
2127 m_buffer.putByteUnchecked(opcode);
2128 memoryModRM(reg, base, offset);
2131 void oneByteOp64_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2133 m_buffer.ensureSpace(maxInstructionSize);
2134 emitRexW(reg, 0, base);
2135 m_buffer.putByteUnchecked(opcode);
2136 memoryModRM_disp32(reg, base, offset);
2139 void oneByteOp64_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
2141 m_buffer.ensureSpace(maxInstructionSize);
2142 emitRexW(reg, 0, base);
2143 m_buffer.putByteUnchecked(opcode);
2144 memoryModRM_disp8(reg, base, offset);
2147 void oneByteOp64(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2149 m_buffer.ensureSpace(maxInstructionSize);
2150 emitRexW(reg, index, base);
2151 m_buffer.putByteUnchecked(opcode);
2152 memoryModRM(reg, base, index, scale, offset);
2155 void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
2157 m_buffer.ensureSpace(maxInstructionSize);
2158 emitRexW(reg, 0, rm);
2159 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2160 m_buffer.putByteUnchecked(opcode);
2161 registerModRM(reg, rm);
2167 // These methods format byte operations. Byte operations differ from the normal
2168 // formatters in the circumstances under which they will decide to emit REX prefixes.
2169 // These should be used where any register operand signifies a byte register.
2171 // The disctinction is due to the handling of register numbers in the range 4..7 on
2172 // x86-64. These register numbers may either represent the second byte of the first
2173 // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
2175 // Since ah..bh cannot be used in all permutations of operands (specifically cannot
2176 // be accessed where a REX prefix is present), these are likely best treated as
2177 // deprecated. In order to ensure the correct registers spl..dil are selected a
2178 // REX prefix will be emitted for any byte register operand in the range 4..15.
2180 // These formatters may be used in instructions where a mix of operand sizes, in which
2181 // case an unnecessary REX will be emitted, for example:
2183 // In this case a REX will be planted since edi is 7 (and were this a byte operand
2184 // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will
2185 // be silently ignored by the processor.
2187 // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
2188 // is provided to check byte register operands.
2190 void oneByteOp8(OneByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
2192 m_buffer.ensureSpace(maxInstructionSize);
2193 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
2194 m_buffer.putByteUnchecked(opcode);
2195 registerModRM(groupOp, rm);
2198 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID rm)
2200 m_buffer.ensureSpace(maxInstructionSize);
2201 emitRexIf(byteRegRequiresRex(reg) || byteRegRequiresRex(rm), reg, 0, rm);
2202 m_buffer.putByteUnchecked(opcode);
2203 registerModRM(reg, rm);
2206 void oneByteOp8(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
2208 m_buffer.ensureSpace(maxInstructionSize);
2209 emitRexIf(byteRegRequiresRex(reg) || regRequiresRex(index) || regRequiresRex(base), reg, index, base);
2210 m_buffer.putByteUnchecked(opcode);
2211 memoryModRM(reg, base, index, scale, offset);
2214 void twoByteOp8(TwoByteOpcodeID opcode, RegisterID reg, RegisterID rm)
2216 m_buffer.ensureSpace(maxInstructionSize);
2217 emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
2218 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2219 m_buffer.putByteUnchecked(opcode);
2220 registerModRM(reg, rm);
2223 void twoByteOp8(TwoByteOpcodeID opcode, GroupOpcodeID groupOp, RegisterID rm)
2225 m_buffer.ensureSpace(maxInstructionSize);
2226 emitRexIf(byteRegRequiresRex(rm), 0, 0, rm);
2227 m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
2228 m_buffer.putByteUnchecked(opcode);
2229 registerModRM(groupOp, rm);
2234 // An immedaite should be appended where appropriate after an op has been emitted.
2235 // The writes are unchecked since the opcode formatters above will have ensured space.
2237 void immediate8(int imm)
2239 m_buffer.putByteUnchecked(imm);
2242 void immediate16(int imm)
2244 m_buffer.putShortUnchecked(imm);
2247 void immediate32(int imm)
2249 m_buffer.putIntUnchecked(imm);
2252 void immediate64(int64_t imm)
2254 m_buffer.putInt64Unchecked(imm);
2257 AssemblerLabel immediateRel32()
2259 m_buffer.putIntUnchecked(0);
2263 // Administrative methods:
2265 size_t codeSize() const { return m_buffer.codeSize(); }
2266 AssemblerLabel label() const { return m_buffer.label(); }
2267 bool isAligned(int alignment) const { return m_buffer.isAligned(alignment); }
2268 void* data() const { return m_buffer.data(); }
2270 PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
2272 return m_buffer.executableCopy(globalData, ownerUID, effort);
2275 unsigned debugOffset() { return m_buffer.debugOffset(); }
2279 // Internals; ModRm and REX formatters.
2281 static const RegisterID noBase = X86Registers::ebp;
2282 static const RegisterID hasSib = X86Registers::esp;
2283 static const RegisterID noIndex = X86Registers::esp;
2285 static const RegisterID noBase2 = X86Registers::r13;
2286 static const RegisterID hasSib2 = X86Registers::r12;
2288 // Registers r8 & above require a REX prefixe.
2289 inline bool regRequiresRex(int reg)
2291 return (reg >= X86Registers::r8);
2294 // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
2295 inline bool byteRegRequiresRex(int reg)
2297 return (reg >= X86Registers::esp);
2300 // Format a REX prefix byte.
2301 inline void emitRex(bool w, int r, int x, int b)
2303 m_buffer.putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
2306 // Used to plant a REX byte with REX.w set (for 64-bit operations).
2307 inline void emitRexW(int r, int x, int b)
2309 emitRex(true, r, x, b);
2312 // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
2313 // regRequiresRex() to check other registers (i.e. address base & index).
2314 inline void emitRexIf(bool condition, int r, int x, int b)
2316 if (condition) emitRex(false, r, x, b);
2319 // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
2320 inline void emitRexIfNeeded(int r, int x, int b)
2322 emitRexIf(regRequiresRex(r) || regRequiresRex(x) || regRequiresRex(b), r, x, b);
2325 // No REX prefix bytes on 32-bit x86.
2326 inline bool regRequiresRex(int) { return false; }
2327 inline bool byteRegRequiresRex(int) { return false; }
2328 inline void emitRexIf(bool, int, int, int) {}
2329 inline void emitRexIfNeeded(int, int, int) {}
2339 void putModRm(ModRmMode mode, int reg, RegisterID rm)
2341 m_buffer.putByteUnchecked((mode << 6) | ((reg & 7) << 3) | (rm & 7));
2344 void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
2346 ASSERT(mode != ModRmRegister);
2348 putModRm(mode, reg, hasSib);
2349 m_buffer.putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
2352 void registerModRM(int reg, RegisterID rm)
2354 putModRm(ModRmRegister, reg, rm);
2357 void memoryModRM(int reg, RegisterID base, int offset)
2359 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2361 if ((base == hasSib) || (base == hasSib2)) {
2363 if (base == hasSib) {
2365 if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
2366 putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
2367 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2368 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
2369 m_buffer.putByteUnchecked(offset);
2371 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2372 m_buffer.putIntUnchecked(offset);
2376 if (!offset && (base != noBase) && (base != noBase2))
2378 if (!offset && (base != noBase))
2380 putModRm(ModRmMemoryNoDisp, reg, base);
2381 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2382 putModRm(ModRmMemoryDisp8, reg, base);
2383 m_buffer.putByteUnchecked(offset);
2385 putModRm(ModRmMemoryDisp32, reg, base);
2386 m_buffer.putIntUnchecked(offset);
2391 void memoryModRM_disp8(int reg, RegisterID base, int offset)
2393 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2394 ASSERT(CAN_SIGN_EXTEND_8_32(offset));
2396 if ((base == hasSib) || (base == hasSib2)) {
2398 if (base == hasSib) {
2400 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
2401 m_buffer.putByteUnchecked(offset);
2403 putModRm(ModRmMemoryDisp8, reg, base);
2404 m_buffer.putByteUnchecked(offset);
2408 void memoryModRM_disp32(int reg, RegisterID base, int offset)
2410 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2412 if ((base == hasSib) || (base == hasSib2)) {
2414 if (base == hasSib) {
2416 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
2417 m_buffer.putIntUnchecked(offset);
2419 putModRm(ModRmMemoryDisp32, reg, base);
2420 m_buffer.putIntUnchecked(offset);
2424 void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
2426 ASSERT(index != noIndex);
2429 if (!offset && (base != noBase) && (base != noBase2))
2431 if (!offset && (base != noBase))
2433 putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
2434 else if (CAN_SIGN_EXTEND_8_32(offset)) {
2435 putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
2436 m_buffer.putByteUnchecked(offset);
2438 putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
2439 m_buffer.putIntUnchecked(offset);
2444 void memoryModRM(int reg, const void* address)
2446 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
2447 putModRm(ModRmMemoryNoDisp, reg, noBase);
2448 m_buffer.putIntUnchecked(reinterpret_cast<int32_t>(address));
2452 AssemblerBuffer m_buffer;
2454 int m_indexOfLastWatchpoint;
2455 int m_indexOfTailOfLastWatchpoint;
2460 #endif // ENABLE(ASSEMBLER) && CPU(X86)
2462 #endif // X86Assembler_h