2 * Copyright (C) 2008, 2012-2016 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 "AssemblerCommon.h"
33 #include "JITCompilationEffort.h"
36 #include <wtf/Assertions.h>
37 #include <wtf/Vector.h>
41 inline bool CAN_SIGN_EXTEND_8_32(int32_t value) { return value == (int32_t)(signed char)value; }
43 namespace X86Registers {
45 #define FOR_EACH_CPU_REGISTER(V) \
46 FOR_EACH_CPU_GPREGISTER(V) \
47 FOR_EACH_CPU_SPECIAL_REGISTER(V) \
48 FOR_EACH_CPU_FPREGISTER(V)
50 // The following are defined as pairs of the following value:
51 // 1. type of the storage needed to save the register value by the JIT probe.
52 // 2. name of the register.
53 #define FOR_EACH_CPU_GPREGISTER(V) \
62 FOR_EACH_X86_64_CPU_GPREGISTER(V)
64 #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
68 // Note: the JITs only stores double values in the FP registers.
69 #define FOR_EACH_CPU_FPREGISTER(V) \
78 FOR_EACH_X86_64_CPU_FPREGISTER(V)
82 #define FOR_EACH_X86_64_CPU_GPREGISTER(V) // Nothing to add.
83 #define FOR_EACH_X86_64_CPU_FPREGISTER(V) // Nothing to add.
87 #define FOR_EACH_X86_64_CPU_GPREGISTER(V) \
97 #define FOR_EACH_X86_64_CPU_FPREGISTER(V) \
107 #endif // CPU(X86_64)
110 #define DECLARE_REGISTER(_type, _regName) _regName,
111 FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
112 #undef DECLARE_REGISTER
116 #define DECLARE_REGISTER(_type, _regName) _regName,
117 FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
118 #undef DECLARE_REGISTER
121 } // namespace X86Register
125 typedef X86Registers::RegisterID RegisterID;
127 static constexpr RegisterID firstRegister() { return X86Registers::eax; }
128 static constexpr RegisterID lastRegister()
131 return X86Registers::r15;
133 return X86Registers::edi;
137 typedef X86Registers::XMMRegisterID XMMRegisterID;
138 typedef XMMRegisterID FPRegisterID;
140 static constexpr FPRegisterID firstFPRegister() { return X86Registers::xmm0; }
141 static constexpr FPRegisterID lastFPRegister()
144 return X86Registers::xmm15;
146 return X86Registers::xmm7;
168 ConditionC = ConditionB,
169 ConditionNC = ConditionAE,
173 // OneByteOpcodeID defines the bytecode for 1 byte instruction. It also contains the prefixes
174 // for two bytes instructions.
175 // TwoByteOpcodeID, ThreeByteOpcodeID define the opcodes for the multibytes instructions.
177 // The encoding for each instruction can be found in the Intel Architecture Manual in the appendix
180 // Each opcode can have a suffix describing the type of argument. The full list of suffixes is
181 // in the "Key to Abbreviations" section of the "Opcode Map".
182 // The most common argument types are:
183 // -E: The argument is either a GPR or a memory address.
184 // -G: The argument is a GPR.
185 // -I: The argument is an immediate.
186 // The most common sizes are:
187 // -v: 32 or 64bit depending on the operand-size attribute.
188 // -z: 32bit in both 32bit and 64bit mode. Common for immediate values.
197 OP_2BYTE_ESCAPE = 0x0F,
203 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
216 OP_MOVSXD_GvEv = 0x63,
218 PRE_OPERAND_SIZE = 0x66,
221 OP_IMUL_GvEvIz = 0x69,
222 OP_GROUP1_EbIb = 0x80,
223 OP_GROUP1_EvIz = 0x81,
224 OP_GROUP1_EvIb = 0x83,
232 OP_GROUP1A_Ev = 0x8F,
239 OP_TEST_EAXIv = 0xA9,
241 OP_GROUP2_EvIb = 0xC1,
243 OP_GROUP11_EvIb = 0xC6,
244 OP_GROUP11_EvIz = 0xC7,
246 OP_GROUP2_Ev1 = 0xD1,
247 OP_GROUP2_EvCL = 0xD3,
250 OP_CALL_rel32 = 0xE8,
255 OP_GROUP3_EbIb = 0xF6,
257 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
262 OP2_MOVSD_VsdWsd = 0x10,
263 OP2_MOVSD_WsdVsd = 0x11,
264 OP2_MOVSS_VsdWsd = 0x10,
265 OP2_MOVSS_WsdVsd = 0x11,
266 OP2_MOVAPD_VpdWpd = 0x28,
267 OP2_MOVAPS_VpdWpd = 0x28,
268 OP2_CVTSI2SD_VsdEd = 0x2A,
269 OP2_CVTTSD2SI_GdWsd = 0x2C,
270 OP2_UCOMISD_VsdWsd = 0x2E,
271 OP2_3BYTE_ESCAPE_3A = 0x3A,
273 OP2_ADDSD_VsdWsd = 0x58,
274 OP2_MULSD_VsdWsd = 0x59,
275 OP2_CVTSD2SS_VsdWsd = 0x5A,
276 OP2_CVTSS2SD_VsdWsd = 0x5A,
277 OP2_SUBSD_VsdWsd = 0x5C,
278 OP2_DIVSD_VsdWsd = 0x5E,
279 OP2_MOVMSKPD_VdEd = 0x50,
280 OP2_SQRTSD_VsdWsd = 0x51,
281 OP2_ANDPS_VpdWpd = 0x54,
282 OP2_ANDNPD_VpdWpd = 0x55,
283 OP2_XORPD_VpdWpd = 0x57,
284 OP2_MOVD_VdEd = 0x6E,
285 OP2_MOVD_EdVd = 0x7E,
286 OP2_JCC_rel32 = 0x80,
288 OP2_3BYTE_ESCAPE_AE = 0xAE,
289 OP2_IMUL_GvEv = 0xAF,
290 OP2_MOVZX_GvEb = 0xB6,
293 OP2_MOVSX_GvEb = 0xBE,
294 OP2_MOVZX_GvEw = 0xB7,
295 OP2_MOVSX_GvEw = 0xBF,
296 OP2_PEXTRW_GdUdIb = 0xC5,
297 OP2_PSLLQ_UdqIb = 0x73,
298 OP2_PSRLQ_UdqIb = 0x73,
299 OP2_POR_VdqWdq = 0XEB,
303 OP3_ROUNDSS_VssWssIb = 0x0A,
304 OP3_ROUNDSD_VsdWsdIb = 0x0B,
314 enum class VexImpliedBytes : uint8_t {
320 TwoByteOpcodeID cmovcc(Condition cond)
322 return (TwoByteOpcodeID)(OP2_CMOVCC + cond);
325 TwoByteOpcodeID jccRel32(Condition cond)
327 return (TwoByteOpcodeID)(OP2_JCC_rel32 + cond);
330 TwoByteOpcodeID setccOpcode(Condition cond)
332 return (TwoByteOpcodeID)(OP_SETCC + cond);
367 GROUP14_OP_PSLLQ = 6,
368 GROUP14_OP_PSRLQ = 2,
370 ESCAPE_D9_FSTP_singleReal = 3,
371 ESCAPE_DD_FSTP_doubleReal = 3,
374 class X86InstructionFormatter;
378 : m_indexOfLastWatchpoint(INT_MIN)
379 , m_indexOfTailOfLastWatchpoint(INT_MIN)
383 AssemblerBuffer& buffer() { return m_formatter.m_buffer; }
387 void push_r(RegisterID reg)
389 m_formatter.oneByteOp(OP_PUSH_EAX, reg);
392 void pop_r(RegisterID reg)
394 m_formatter.oneByteOp(OP_POP_EAX, reg);
397 void push_i32(int imm)
399 m_formatter.oneByteOp(OP_PUSH_Iz);
400 m_formatter.immediate32(imm);
403 void push_m(int offset, RegisterID base)
405 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_PUSH, base, offset);
408 void pop_m(int offset, RegisterID base)
410 m_formatter.oneByteOp(OP_GROUP1A_Ev, GROUP1A_OP_POP, base, offset);
413 // Arithmetic operations:
416 void adcl_im(int imm, const void* addr)
418 if (CAN_SIGN_EXTEND_8_32(imm)) {
419 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
420 m_formatter.immediate8(imm);
422 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
423 m_formatter.immediate32(imm);
428 void addl_rr(RegisterID src, RegisterID dst)
430 m_formatter.oneByteOp(OP_ADD_EvGv, src, dst);
433 void addl_mr(int offset, RegisterID base, RegisterID dst)
435 m_formatter.oneByteOp(OP_ADD_GvEv, dst, base, offset);
439 void addl_mr(const void* addr, RegisterID dst)
441 m_formatter.oneByteOp(OP_ADD_GvEv, dst, addr);
445 void addl_rm(RegisterID src, int offset, RegisterID base)
447 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, offset);
450 void addl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
452 m_formatter.oneByteOp(OP_ADD_EvGv, src, base, index, scale, offset);
455 void addb_rm(RegisterID src, int offset, RegisterID base)
457 m_formatter.oneByteOp8(OP_ADD_EbGb, src, base, offset);
460 void addb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
462 m_formatter.oneByteOp8(OP_ADD_EbGb, src, base, index, scale, offset);
465 void addw_rm(RegisterID src, int offset, RegisterID base)
467 m_formatter.prefix(PRE_OPERAND_SIZE);
468 m_formatter.oneByteOp8(OP_ADD_EvGv, src, base, offset);
471 void addw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
473 m_formatter.prefix(PRE_OPERAND_SIZE);
474 m_formatter.oneByteOp8(OP_ADD_EvGv, src, base, index, scale, offset);
477 void addl_ir(int imm, RegisterID dst)
479 if (CAN_SIGN_EXTEND_8_32(imm)) {
480 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
481 m_formatter.immediate8(imm);
483 if (dst == X86Registers::eax)
484 m_formatter.oneByteOp(OP_ADD_EAXIv);
486 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
487 m_formatter.immediate32(imm);
491 void addl_im(int imm, int offset, RegisterID base)
493 if (CAN_SIGN_EXTEND_8_32(imm)) {
494 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
495 m_formatter.immediate8(imm);
497 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
498 m_formatter.immediate32(imm);
502 void addl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
504 if (CAN_SIGN_EXTEND_8_32(imm)) {
505 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, index, scale, offset);
506 m_formatter.immediate8(imm);
508 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, index, scale, offset);
509 m_formatter.immediate32(imm);
513 void addb_im(int imm, int offset, RegisterID base)
515 m_formatter.oneByteOp8(OP_GROUP1_EbIb, GROUP1_OP_ADD, base, offset);
516 m_formatter.immediate8(imm);
519 void addb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
521 m_formatter.oneByteOp8(OP_GROUP1_EbIb, GROUP1_OP_ADD, base, index, scale, offset);
522 m_formatter.immediate8(imm);
525 void addw_im(int imm, int offset, RegisterID base)
527 m_formatter.prefix(PRE_OPERAND_SIZE);
528 if (CAN_SIGN_EXTEND_8_32(imm)) {
529 m_formatter.oneByteOp8(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
530 m_formatter.immediate8(imm);
532 m_formatter.oneByteOp8(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
533 m_formatter.immediate16(imm);
537 void addw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
539 m_formatter.prefix(PRE_OPERAND_SIZE);
540 if (CAN_SIGN_EXTEND_8_32(imm)) {
541 m_formatter.oneByteOp8(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, index, scale, offset);
542 m_formatter.immediate8(imm);
544 m_formatter.oneByteOp8(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, index, scale, offset);
545 m_formatter.immediate16(imm);
550 void addq_rr(RegisterID src, RegisterID dst)
552 m_formatter.oneByteOp64(OP_ADD_EvGv, src, dst);
555 void addq_mr(int offset, RegisterID base, RegisterID dst)
557 m_formatter.oneByteOp64(OP_ADD_GvEv, dst, base, offset);
560 void addq_rm(RegisterID src, int offset, RegisterID base)
562 m_formatter.oneByteOp64(OP_ADD_EvGv, src, base, offset);
565 void addq_ir(int imm, RegisterID dst)
567 if (CAN_SIGN_EXTEND_8_32(imm)) {
568 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, dst);
569 m_formatter.immediate8(imm);
571 if (dst == X86Registers::eax)
572 m_formatter.oneByteOp64(OP_ADD_EAXIv);
574 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, dst);
575 m_formatter.immediate32(imm);
579 void addq_im(int imm, int offset, RegisterID base)
581 if (CAN_SIGN_EXTEND_8_32(imm)) {
582 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_ADD, base, offset);
583 m_formatter.immediate8(imm);
585 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_ADD, base, offset);
586 m_formatter.immediate32(imm);
590 void addl_im(int imm, const void* addr)
592 if (CAN_SIGN_EXTEND_8_32(imm)) {
593 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
594 m_formatter.immediate8(imm);
596 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
597 m_formatter.immediate32(imm);
602 void andl_rr(RegisterID src, RegisterID dst)
604 m_formatter.oneByteOp(OP_AND_EvGv, src, dst);
607 void andl_mr(int offset, RegisterID base, RegisterID dst)
609 m_formatter.oneByteOp(OP_AND_GvEv, dst, base, offset);
612 void andl_rm(RegisterID src, int offset, RegisterID base)
614 m_formatter.oneByteOp(OP_AND_EvGv, src, base, offset);
617 void andl_ir(int imm, RegisterID dst)
619 if (CAN_SIGN_EXTEND_8_32(imm)) {
620 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
621 m_formatter.immediate8(imm);
623 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
624 m_formatter.immediate32(imm);
628 void andl_im(int imm, int offset, RegisterID base)
630 if (CAN_SIGN_EXTEND_8_32(imm)) {
631 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, base, offset);
632 m_formatter.immediate8(imm);
634 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, base, offset);
635 m_formatter.immediate32(imm);
640 void andq_rr(RegisterID src, RegisterID dst)
642 m_formatter.oneByteOp64(OP_AND_EvGv, src, dst);
645 void andq_ir(int imm, RegisterID dst)
647 if (CAN_SIGN_EXTEND_8_32(imm)) {
648 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_AND, dst);
649 m_formatter.immediate8(imm);
651 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_AND, dst);
652 m_formatter.immediate32(imm);
656 void andl_im(int imm, const void* addr)
658 if (CAN_SIGN_EXTEND_8_32(imm)) {
659 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
660 m_formatter.immediate8(imm);
662 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
663 m_formatter.immediate32(imm);
668 void dec_r(RegisterID dst)
670 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP1_OP_OR, dst);
674 void decq_r(RegisterID dst)
676 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_OR, dst);
678 #endif // CPU(X86_64)
680 void inc_r(RegisterID dst)
682 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP1_OP_ADD, dst);
686 void incq_r(RegisterID dst)
688 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, dst);
691 void incq_m(int offset, RegisterID base)
693 m_formatter.oneByteOp64(OP_GROUP5_Ev, GROUP1_OP_ADD, base, offset);
695 #endif // CPU(X86_64)
697 void negl_r(RegisterID dst)
699 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
703 void negq_r(RegisterID dst)
705 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NEG, dst);
709 void negl_m(int offset, RegisterID base)
711 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NEG, base, offset);
714 void notl_r(RegisterID dst)
716 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
719 void notl_m(int offset, RegisterID base)
721 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
725 void notq_r(RegisterID dst)
727 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NOT, dst);
730 void notq_m(int offset, RegisterID base)
732 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_NOT, base, offset);
736 void orl_rr(RegisterID src, RegisterID dst)
738 m_formatter.oneByteOp(OP_OR_EvGv, src, dst);
741 void orl_mr(int offset, RegisterID base, RegisterID dst)
743 m_formatter.oneByteOp(OP_OR_GvEv, dst, base, offset);
746 void orl_rm(RegisterID src, int offset, RegisterID base)
748 m_formatter.oneByteOp(OP_OR_EvGv, src, base, offset);
751 void orl_ir(int imm, RegisterID dst)
753 if (CAN_SIGN_EXTEND_8_32(imm)) {
754 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
755 m_formatter.immediate8(imm);
757 if (dst == X86Registers::eax)
758 m_formatter.oneByteOp(OP_OR_EAXIv);
760 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
761 m_formatter.immediate32(imm);
765 void orl_im(int imm, int offset, RegisterID base)
767 if (CAN_SIGN_EXTEND_8_32(imm)) {
768 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, base, offset);
769 m_formatter.immediate8(imm);
771 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, base, offset);
772 m_formatter.immediate32(imm);
777 void orq_rr(RegisterID src, RegisterID dst)
779 m_formatter.oneByteOp64(OP_OR_EvGv, src, dst);
782 void orq_ir(int imm, RegisterID dst)
784 if (CAN_SIGN_EXTEND_8_32(imm)) {
785 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_OR, dst);
786 m_formatter.immediate8(imm);
788 if (dst == X86Registers::eax)
789 m_formatter.oneByteOp64(OP_OR_EAXIv);
791 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_OR, dst);
792 m_formatter.immediate32(imm);
796 void orl_im(int imm, const void* addr)
798 if (CAN_SIGN_EXTEND_8_32(imm)) {
799 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
800 m_formatter.immediate8(imm);
802 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
803 m_formatter.immediate32(imm);
807 void orl_rm(RegisterID src, const void* addr)
809 m_formatter.oneByteOp(OP_OR_EvGv, src, addr);
813 void subl_rr(RegisterID src, RegisterID dst)
815 m_formatter.oneByteOp(OP_SUB_EvGv, src, dst);
818 void subl_mr(int offset, RegisterID base, RegisterID dst)
820 m_formatter.oneByteOp(OP_SUB_GvEv, dst, base, offset);
823 void subl_rm(RegisterID src, int offset, RegisterID base)
825 m_formatter.oneByteOp(OP_SUB_EvGv, src, base, offset);
828 void subl_ir(int imm, RegisterID dst)
830 if (CAN_SIGN_EXTEND_8_32(imm)) {
831 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
832 m_formatter.immediate8(imm);
834 if (dst == X86Registers::eax)
835 m_formatter.oneByteOp(OP_SUB_EAXIv);
837 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
838 m_formatter.immediate32(imm);
842 void subl_im(int imm, int offset, RegisterID base)
844 if (CAN_SIGN_EXTEND_8_32(imm)) {
845 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
846 m_formatter.immediate8(imm);
848 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
849 m_formatter.immediate32(imm);
854 void subq_rr(RegisterID src, RegisterID dst)
856 m_formatter.oneByteOp64(OP_SUB_EvGv, src, dst);
859 void subq_mr(int offset, RegisterID base, RegisterID dst)
861 m_formatter.oneByteOp64(OP_SUB_GvEv, dst, base, offset);
864 void subq_rm(RegisterID src, int offset, RegisterID base)
866 m_formatter.oneByteOp64(OP_SUB_EvGv, src, base, offset);
869 void subq_ir(int imm, RegisterID dst)
871 if (CAN_SIGN_EXTEND_8_32(imm)) {
872 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, dst);
873 m_formatter.immediate8(imm);
875 if (dst == X86Registers::eax)
876 m_formatter.oneByteOp64(OP_SUB_EAXIv);
878 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, dst);
879 m_formatter.immediate32(imm);
883 void subq_im(int imm, int offset, RegisterID base)
885 if (CAN_SIGN_EXTEND_8_32(imm)) {
886 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_SUB, base, offset);
887 m_formatter.immediate8(imm);
889 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_SUB, base, offset);
890 m_formatter.immediate32(imm);
894 void subl_im(int imm, const void* addr)
896 if (CAN_SIGN_EXTEND_8_32(imm)) {
897 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
898 m_formatter.immediate8(imm);
900 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
901 m_formatter.immediate32(imm);
906 void xorl_rr(RegisterID src, RegisterID dst)
908 m_formatter.oneByteOp(OP_XOR_EvGv, src, dst);
911 void xorl_mr(int offset, RegisterID base, RegisterID dst)
913 m_formatter.oneByteOp(OP_XOR_GvEv, dst, base, offset);
916 void xorl_rm(RegisterID src, int offset, RegisterID base)
918 m_formatter.oneByteOp(OP_XOR_EvGv, src, base, offset);
921 void xorl_im(int imm, int offset, RegisterID base)
923 if (CAN_SIGN_EXTEND_8_32(imm)) {
924 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, base, offset);
925 m_formatter.immediate8(imm);
927 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, base, offset);
928 m_formatter.immediate32(imm);
932 void xorl_ir(int imm, RegisterID dst)
934 if (CAN_SIGN_EXTEND_8_32(imm)) {
935 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
936 m_formatter.immediate8(imm);
938 if (dst == X86Registers::eax)
939 m_formatter.oneByteOp(OP_XOR_EAXIv);
941 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
942 m_formatter.immediate32(imm);
947 void xorq_rr(RegisterID src, RegisterID dst)
949 m_formatter.oneByteOp64(OP_XOR_EvGv, src, dst);
952 void xorq_ir(int imm, RegisterID dst)
954 if (CAN_SIGN_EXTEND_8_32(imm)) {
955 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_XOR, dst);
956 m_formatter.immediate8(imm);
958 if (dst == X86Registers::eax)
959 m_formatter.oneByteOp64(OP_XOR_EAXIv);
961 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_XOR, dst);
962 m_formatter.immediate32(imm);
966 void xorq_rm(RegisterID src, int offset, RegisterID base)
968 m_formatter.oneByteOp64(OP_XOR_EvGv, src, base, offset);
971 void rorq_i8r(int imm, RegisterID dst)
974 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_ROR, dst);
976 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_ROR, dst);
977 m_formatter.immediate8(imm);
983 void lzcnt_rr(RegisterID src, RegisterID dst)
985 m_formatter.prefix(PRE_SSE_F3);
986 m_formatter.twoByteOp(OP2_LZCNT, dst, src);
989 void lzcnt_mr(int offset, RegisterID base, RegisterID dst)
991 m_formatter.prefix(PRE_SSE_F3);
992 m_formatter.twoByteOp(OP2_LZCNT, dst, base, offset);
996 void lzcntq_rr(RegisterID src, RegisterID dst)
998 m_formatter.prefix(PRE_SSE_F3);
999 m_formatter.twoByteOp64(OP2_LZCNT, dst, src);
1002 void lzcntq_mr(int offset, RegisterID base, RegisterID dst)
1004 m_formatter.prefix(PRE_SSE_F3);
1005 m_formatter.twoByteOp64(OP2_LZCNT, dst, base, offset);
1009 void bsr_rr(RegisterID src, RegisterID dst)
1011 m_formatter.twoByteOp(OP2_BSR, dst, src);
1014 void bsr_mr(int offset, RegisterID base, RegisterID dst)
1016 m_formatter.twoByteOp(OP2_BSR, dst, base, offset);
1020 void bsrq_rr(RegisterID src, RegisterID dst)
1022 m_formatter.twoByteOp64(OP2_BSR, dst, src);
1025 void bsrq_mr(int offset, RegisterID base, RegisterID dst)
1027 m_formatter.twoByteOp64(OP2_BSR, dst, base, offset);
1031 void sarl_i8r(int imm, RegisterID dst)
1034 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
1036 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
1037 m_formatter.immediate8(imm);
1041 void sarl_CLr(RegisterID dst)
1043 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
1046 void shrl_i8r(int imm, RegisterID dst)
1049 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
1051 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
1052 m_formatter.immediate8(imm);
1056 void shrl_CLr(RegisterID dst)
1058 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
1061 void shll_i8r(int imm, RegisterID dst)
1064 m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
1066 m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
1067 m_formatter.immediate8(imm);
1071 void shll_CLr(RegisterID dst)
1073 m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
1077 void sarq_CLr(RegisterID dst)
1079 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
1082 void sarq_i8r(int imm, RegisterID dst)
1085 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SAR, dst);
1087 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SAR, dst);
1088 m_formatter.immediate8(imm);
1092 void shrq_i8r(int imm, RegisterID dst)
1095 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
1097 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
1098 m_formatter.immediate8(imm);
1102 void shrq_CLr(RegisterID dst)
1104 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
1107 void shlq_i8r(int imm, RegisterID dst)
1110 m_formatter.oneByteOp64(OP_GROUP2_Ev1, GROUP2_OP_SHL, dst);
1112 m_formatter.oneByteOp64(OP_GROUP2_EvIb, GROUP2_OP_SHL, dst);
1113 m_formatter.immediate8(imm);
1117 void shlq_CLr(RegisterID dst)
1119 m_formatter.oneByteOp64(OP_GROUP2_EvCL, GROUP2_OP_SHL, dst);
1121 #endif // CPU(X86_64)
1123 void imull_rr(RegisterID src, RegisterID dst)
1125 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, src);
1129 void imulq_rr(RegisterID src, RegisterID dst)
1131 m_formatter.twoByteOp64(OP2_IMUL_GvEv, dst, src);
1133 #endif // CPU(X86_64)
1135 void imull_mr(int offset, RegisterID base, RegisterID dst)
1137 m_formatter.twoByteOp(OP2_IMUL_GvEv, dst, base, offset);
1140 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
1142 m_formatter.oneByteOp(OP_IMUL_GvEvIz, dst, src);
1143 m_formatter.immediate32(value);
1146 void divl_r(RegisterID dst)
1148 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_DIV, dst);
1151 void idivl_r(RegisterID dst)
1153 m_formatter.oneByteOp(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
1157 void idivq_r(RegisterID dst)
1159 m_formatter.oneByteOp64(OP_GROUP3_Ev, GROUP3_OP_IDIV, dst);
1161 #endif // CPU(X86_64)
1165 void cmpl_rr(RegisterID src, RegisterID dst)
1167 m_formatter.oneByteOp(OP_CMP_EvGv, src, dst);
1170 void cmpl_rm(RegisterID src, int offset, RegisterID base)
1172 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, offset);
1175 void cmpl_mr(int offset, RegisterID base, RegisterID src)
1177 m_formatter.oneByteOp(OP_CMP_GvEv, src, base, offset);
1180 void cmpl_ir(int imm, RegisterID dst)
1182 if (CAN_SIGN_EXTEND_8_32(imm)) {
1183 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
1184 m_formatter.immediate8(imm);
1186 if (dst == X86Registers::eax)
1187 m_formatter.oneByteOp(OP_CMP_EAXIv);
1189 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1190 m_formatter.immediate32(imm);
1194 void cmpl_ir_force32(int imm, RegisterID dst)
1196 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1197 m_formatter.immediate32(imm);
1200 void cmpl_im(int imm, int offset, RegisterID base)
1202 if (CAN_SIGN_EXTEND_8_32(imm)) {
1203 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
1204 m_formatter.immediate8(imm);
1206 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1207 m_formatter.immediate32(imm);
1211 void cmpb_im(int imm, int offset, RegisterID base)
1213 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
1214 m_formatter.immediate8(imm);
1217 void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1219 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
1220 m_formatter.immediate8(imm);
1224 void cmpb_im(int imm, const void* addr)
1226 m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, addr);
1227 m_formatter.immediate8(imm);
1231 void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1233 if (CAN_SIGN_EXTEND_8_32(imm)) {
1234 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1235 m_formatter.immediate8(imm);
1237 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1238 m_formatter.immediate32(imm);
1242 void cmpl_im_force32(int imm, int offset, RegisterID base)
1244 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1245 m_formatter.immediate32(imm);
1249 void cmpq_rr(RegisterID src, RegisterID dst)
1251 m_formatter.oneByteOp64(OP_CMP_EvGv, src, dst);
1254 void cmpq_rm(RegisterID src, int offset, RegisterID base)
1256 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, offset);
1259 void cmpq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1261 m_formatter.oneByteOp64(OP_CMP_EvGv, src, base, index, scale, offset);
1264 void cmpq_mr(int offset, RegisterID base, RegisterID src)
1266 m_formatter.oneByteOp64(OP_CMP_GvEv, src, base, offset);
1269 void cmpq_ir(int imm, RegisterID dst)
1271 if (CAN_SIGN_EXTEND_8_32(imm)) {
1272 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
1273 m_formatter.immediate8(imm);
1275 if (dst == X86Registers::eax)
1276 m_formatter.oneByteOp64(OP_CMP_EAXIv);
1278 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1279 m_formatter.immediate32(imm);
1283 void cmpq_im(int imm, int offset, RegisterID base)
1285 if (CAN_SIGN_EXTEND_8_32(imm)) {
1286 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, offset);
1287 m_formatter.immediate8(imm);
1289 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, offset);
1290 m_formatter.immediate32(imm);
1294 void cmpq_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1296 if (CAN_SIGN_EXTEND_8_32(imm)) {
1297 m_formatter.oneByteOp64(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1298 m_formatter.immediate8(imm);
1300 m_formatter.oneByteOp64(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1301 m_formatter.immediate32(imm);
1305 void cmpl_rm(RegisterID reg, const void* addr)
1307 m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
1310 void cmpl_im(int imm, const void* addr)
1312 if (CAN_SIGN_EXTEND_8_32(imm)) {
1313 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
1314 m_formatter.immediate8(imm);
1316 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
1317 m_formatter.immediate32(imm);
1322 void cmpw_ir(int imm, RegisterID dst)
1324 if (CAN_SIGN_EXTEND_8_32(imm)) {
1325 m_formatter.prefix(PRE_OPERAND_SIZE);
1326 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, dst);
1327 m_formatter.immediate8(imm);
1329 m_formatter.prefix(PRE_OPERAND_SIZE);
1330 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
1331 m_formatter.immediate16(imm);
1335 void cmpw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1337 m_formatter.prefix(PRE_OPERAND_SIZE);
1338 m_formatter.oneByteOp(OP_CMP_EvGv, src, base, index, scale, offset);
1341 void cmpw_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1343 if (CAN_SIGN_EXTEND_8_32(imm)) {
1344 m_formatter.prefix(PRE_OPERAND_SIZE);
1345 m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, base, index, scale, offset);
1346 m_formatter.immediate8(imm);
1348 m_formatter.prefix(PRE_OPERAND_SIZE);
1349 m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, base, index, scale, offset);
1350 m_formatter.immediate16(imm);
1354 void testl_rr(RegisterID src, RegisterID dst)
1356 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
1359 void testl_i32r(int imm, RegisterID dst)
1361 if (dst == X86Registers::eax)
1362 m_formatter.oneByteOp(OP_TEST_EAXIv);
1364 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
1365 m_formatter.immediate32(imm);
1368 void testl_i32m(int imm, int offset, RegisterID base)
1370 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
1371 m_formatter.immediate32(imm);
1374 void testb_rr(RegisterID src, RegisterID dst)
1376 m_formatter.oneByteOp8(OP_TEST_EbGb, src, dst);
1379 void testb_im(int imm, int offset, RegisterID base)
1381 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
1382 m_formatter.immediate8(imm);
1385 void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
1387 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
1388 m_formatter.immediate8(imm);
1392 void testb_im(int imm, const void* addr)
1394 m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, addr);
1395 m_formatter.immediate8(imm);
1399 void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1401 m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
1402 m_formatter.immediate32(imm);
1406 void testq_rr(RegisterID src, RegisterID dst)
1408 m_formatter.oneByteOp64(OP_TEST_EvGv, src, dst);
1411 void testq_rm(RegisterID src, int offset, RegisterID base)
1413 m_formatter.oneByteOp64(OP_TEST_EvGv, src, base, offset);
1416 void testq_i32r(int imm, RegisterID dst)
1418 if (dst == X86Registers::eax)
1419 m_formatter.oneByteOp64(OP_TEST_EAXIv);
1421 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, dst);
1422 m_formatter.immediate32(imm);
1425 void testq_i32m(int imm, int offset, RegisterID base)
1427 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
1428 m_formatter.immediate32(imm);
1431 void testq_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1433 m_formatter.oneByteOp64(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, index, scale, offset);
1434 m_formatter.immediate32(imm);
1438 void testw_rr(RegisterID src, RegisterID dst)
1440 m_formatter.prefix(PRE_OPERAND_SIZE);
1441 m_formatter.oneByteOp(OP_TEST_EvGv, src, dst);
1444 void testb_i8r(int imm, RegisterID dst)
1446 if (dst == X86Registers::eax)
1447 m_formatter.oneByteOp(OP_TEST_ALIb);
1449 m_formatter.oneByteOp8(OP_GROUP3_EbIb, GROUP3_OP_TEST, dst);
1450 m_formatter.immediate8(imm);
1453 void setCC_r(Condition cond, RegisterID dst)
1455 m_formatter.twoByteOp8(setccOpcode(cond), (GroupOpcodeID)0, dst);
1458 void sete_r(RegisterID dst)
1460 m_formatter.twoByteOp8(setccOpcode(ConditionE), (GroupOpcodeID)0, dst);
1463 void setz_r(RegisterID dst)
1468 void setne_r(RegisterID dst)
1470 m_formatter.twoByteOp8(setccOpcode(ConditionNE), (GroupOpcodeID)0, dst);
1473 void setnz_r(RegisterID dst)
1478 void setnp_r(RegisterID dst)
1480 m_formatter.twoByteOp8(setccOpcode(ConditionNP), (GroupOpcodeID)0, dst);
1483 void setp_r(RegisterID dst)
1485 m_formatter.twoByteOp8(setccOpcode(ConditionP), (GroupOpcodeID)0, dst);
1488 // Various move ops:
1492 m_formatter.oneByteOp(OP_CDQ);
1498 m_formatter.oneByteOp64(OP_CDQ);
1502 void fstps(int offset, RegisterID base)
1504 m_formatter.oneByteOp(OP_ESCAPE_D9, ESCAPE_D9_FSTP_singleReal, base, offset);
1507 void fstpl(int offset, RegisterID base)
1509 m_formatter.oneByteOp(OP_ESCAPE_DD, ESCAPE_DD_FSTP_doubleReal, base, offset);
1512 void xchgl_rr(RegisterID src, RegisterID dst)
1514 if (src == X86Registers::eax)
1515 m_formatter.oneByteOp(OP_XCHG_EAX, dst);
1516 else if (dst == X86Registers::eax)
1517 m_formatter.oneByteOp(OP_XCHG_EAX, src);
1519 m_formatter.oneByteOp(OP_XCHG_EvGv, src, dst);
1522 void xchgl_rm(RegisterID src, int offset, RegisterID base)
1524 m_formatter.oneByteOp(OP_XCHG_EvGv, src, base, offset);
1528 void xchgq_rr(RegisterID src, RegisterID dst)
1530 if (src == X86Registers::eax)
1531 m_formatter.oneByteOp64(OP_XCHG_EAX, dst);
1532 else if (dst == X86Registers::eax)
1533 m_formatter.oneByteOp64(OP_XCHG_EAX, src);
1535 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, dst);
1538 void xchgq_rm(RegisterID src, int offset, RegisterID base)
1540 m_formatter.oneByteOp64(OP_XCHG_EvGv, src, base, offset);
1544 void movl_rr(RegisterID src, RegisterID dst)
1546 m_formatter.oneByteOp(OP_MOV_EvGv, src, dst);
1549 void movl_rm(RegisterID src, int offset, RegisterID base)
1551 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, offset);
1554 void movl_rm_disp32(RegisterID src, int offset, RegisterID base)
1556 m_formatter.oneByteOp_disp32(OP_MOV_EvGv, src, base, offset);
1559 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1561 m_formatter.oneByteOp(OP_MOV_EvGv, src, base, index, scale, offset);
1564 void movl_mEAX(const void* addr)
1566 m_formatter.oneByteOp(OP_MOV_EAXOv);
1568 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1570 m_formatter.immediate32(reinterpret_cast<int>(addr));
1574 void movl_mr(int offset, RegisterID base, RegisterID dst)
1576 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, offset);
1579 void movl_mr_disp32(int offset, RegisterID base, RegisterID dst)
1581 m_formatter.oneByteOp_disp32(OP_MOV_GvEv, dst, base, offset);
1584 void movl_mr_disp8(int offset, RegisterID base, RegisterID dst)
1586 m_formatter.oneByteOp_disp8(OP_MOV_GvEv, dst, base, offset);
1589 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1591 m_formatter.oneByteOp(OP_MOV_GvEv, dst, base, index, scale, offset);
1594 void movl_i32r(int imm, RegisterID dst)
1596 m_formatter.oneByteOp(OP_MOV_EAXIv, dst);
1597 m_formatter.immediate32(imm);
1600 void movl_i32m(int imm, int offset, RegisterID base)
1602 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1603 m_formatter.immediate32(imm);
1606 void movl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1608 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, base, index, scale, offset);
1609 m_formatter.immediate32(imm);
1613 void movb_i8m(int imm, const void* addr)
1615 ASSERT(-128 <= imm && imm < 128);
1616 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, addr);
1617 m_formatter.immediate8(imm);
1621 void movb_i8m(int imm, int offset, RegisterID base)
1623 ASSERT(-128 <= imm && imm < 128);
1624 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, offset);
1625 m_formatter.immediate8(imm);
1628 void movb_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
1630 ASSERT(-128 <= imm && imm < 128);
1631 m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, base, index, scale, offset);
1632 m_formatter.immediate8(imm);
1636 void movb_rm(RegisterID src, const void* addr)
1638 m_formatter.oneByteOp(OP_MOV_EbGb, src, addr);
1642 void movb_rm(RegisterID src, int offset, RegisterID base)
1644 m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, offset);
1647 void movb_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1649 m_formatter.oneByteOp8(OP_MOV_EbGb, src, base, index, scale, offset);
1652 void movw_rm(RegisterID src, int offset, RegisterID base)
1654 m_formatter.prefix(PRE_OPERAND_SIZE);
1656 // FIXME: We often use oneByteOp8 for 16-bit operations. It's not clear that this is
1657 // necessary. https://bugs.webkit.org/show_bug.cgi?id=153433
1658 m_formatter.oneByteOp8(OP_MOV_EvGv, src, base, offset);
1661 void movw_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1663 m_formatter.prefix(PRE_OPERAND_SIZE);
1664 m_formatter.oneByteOp8(OP_MOV_EvGv, src, base, index, scale, offset);
1667 void movl_EAXm(const void* addr)
1669 m_formatter.oneByteOp(OP_MOV_OvEAX);
1671 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1673 m_formatter.immediate32(reinterpret_cast<int>(addr));
1678 void movq_rr(RegisterID src, RegisterID dst)
1680 m_formatter.oneByteOp64(OP_MOV_EvGv, src, dst);
1683 void movq_rm(RegisterID src, int offset, RegisterID base)
1685 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset);
1688 void movq_rm_disp32(RegisterID src, int offset, RegisterID base)
1690 m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset);
1693 void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
1695 m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset);
1698 void movq_mEAX(const void* addr)
1700 m_formatter.oneByteOp64(OP_MOV_EAXOv);
1701 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1704 void movq_EAXm(const void* addr)
1706 m_formatter.oneByteOp64(OP_MOV_OvEAX);
1707 m_formatter.immediate64(reinterpret_cast<int64_t>(addr));
1710 void movq_mr(int offset, RegisterID base, RegisterID dst)
1712 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset);
1715 void movq_mr_disp32(int offset, RegisterID base, RegisterID dst)
1717 m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset);
1720 void movq_mr_disp8(int offset, RegisterID base, RegisterID dst)
1722 m_formatter.oneByteOp64_disp8(OP_MOV_GvEv, dst, base, offset);
1725 void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1727 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
1730 void movq_i32m(int imm, int offset, RegisterID base)
1732 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);
1733 m_formatter.immediate32(imm);
1736 void movq_i64r(int64_t imm, RegisterID dst)
1738 m_formatter.oneByteOp64(OP_MOV_EAXIv, dst);
1739 m_formatter.immediate64(imm);
1742 void mov_i32r(int32_t imm, RegisterID dst)
1744 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, dst);
1745 m_formatter.immediate32(imm);
1748 void movsxd_rr(RegisterID src, RegisterID dst)
1750 m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
1755 void movl_rm(RegisterID src, const void* addr)
1757 if (src == X86Registers::eax)
1760 m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
1763 void movl_mr(const void* addr, RegisterID dst)
1765 if (dst == X86Registers::eax)
1768 m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
1771 void movl_i32m(int imm, const void* addr)
1773 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
1774 m_formatter.immediate32(imm);
1778 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
1780 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset);
1783 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1785 m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset);
1788 void movswl_mr(int offset, RegisterID base, RegisterID dst)
1790 m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, offset);
1793 void movswl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1795 m_formatter.twoByteOp(OP2_MOVSX_GvEw, dst, base, index, scale, offset);
1798 void movzbl_mr(int offset, RegisterID base, RegisterID dst)
1800 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, offset);
1803 void movzbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1805 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, base, index, scale, offset);
1809 void movzbl_mr(const void* address, RegisterID dst)
1811 m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, address);
1815 void movsbl_mr(int offset, RegisterID base, RegisterID dst)
1817 m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, offset);
1820 void movsbl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1822 m_formatter.twoByteOp(OP2_MOVSX_GvEb, dst, base, index, scale, offset);
1825 void movzbl_rr(RegisterID src, RegisterID dst)
1827 // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
1828 // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
1829 // REX prefixes are defined to be silently ignored by the processor.
1830 m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src);
1833 void movsbl_rr(RegisterID src, RegisterID dst)
1835 m_formatter.twoByteOp8(OP2_MOVSX_GvEb, dst, src);
1838 void movzwl_rr(RegisterID src, RegisterID dst)
1840 m_formatter.twoByteOp8(OP2_MOVZX_GvEw, dst, src);
1843 void movswl_rr(RegisterID src, RegisterID dst)
1845 m_formatter.twoByteOp8(OP2_MOVSX_GvEw, dst, src);
1848 void cmovl_rr(Condition cond, RegisterID src, RegisterID dst)
1850 m_formatter.twoByteOp(cmovcc(cond), dst, src);
1853 void cmovl_mr(Condition cond, int offset, RegisterID base, RegisterID dst)
1855 m_formatter.twoByteOp(cmovcc(cond), dst, base, offset);
1858 void cmovl_mr(Condition cond, int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1860 m_formatter.twoByteOp(cmovcc(cond), dst, base, index, scale, offset);
1863 void cmovel_rr(RegisterID src, RegisterID dst)
1865 m_formatter.twoByteOp(cmovcc(ConditionE), dst, src);
1868 void cmovnel_rr(RegisterID src, RegisterID dst)
1870 m_formatter.twoByteOp(cmovcc(ConditionNE), dst, src);
1873 void cmovpl_rr(RegisterID src, RegisterID dst)
1875 m_formatter.twoByteOp(cmovcc(ConditionP), dst, src);
1878 void cmovnpl_rr(RegisterID src, RegisterID dst)
1880 m_formatter.twoByteOp(cmovcc(ConditionNP), dst, src);
1884 void cmovq_rr(Condition cond, RegisterID src, RegisterID dst)
1886 m_formatter.twoByteOp64(cmovcc(cond), dst, src);
1889 void cmovq_mr(Condition cond, int offset, RegisterID base, RegisterID dst)
1891 m_formatter.twoByteOp64(cmovcc(cond), dst, base, offset);
1894 void cmovq_mr(Condition cond, int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1896 m_formatter.twoByteOp64(cmovcc(cond), dst, base, index, scale, offset);
1899 void cmoveq_rr(RegisterID src, RegisterID dst)
1901 m_formatter.twoByteOp64(cmovcc(ConditionE), dst, src);
1904 void cmovneq_rr(RegisterID src, RegisterID dst)
1906 m_formatter.twoByteOp64(cmovcc(ConditionNE), dst, src);
1909 void cmovpq_rr(RegisterID src, RegisterID dst)
1911 m_formatter.twoByteOp64(cmovcc(ConditionP), dst, src);
1914 void cmovnpq_rr(RegisterID src, RegisterID dst)
1916 m_formatter.twoByteOp64(cmovcc(ConditionNP), dst, src);
1919 void cmovl_mr(Condition cond, const void* addr, RegisterID dst)
1921 m_formatter.twoByteOp(cmovcc(cond), dst, addr);
1925 void leal_mr(int offset, RegisterID base, RegisterID dst)
1927 m_formatter.oneByteOp(OP_LEA, dst, base, offset);
1930 void leal_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1932 m_formatter.oneByteOp(OP_LEA, dst, base, index, scale, offset);
1936 void leaq_mr(int offset, RegisterID base, RegisterID dst)
1938 m_formatter.oneByteOp64(OP_LEA, dst, base, offset);
1941 void leaq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
1943 m_formatter.oneByteOp64(OP_LEA, dst, base, index, scale, offset);
1949 AssemblerLabel call()
1951 m_formatter.oneByteOp(OP_CALL_rel32);
1952 return m_formatter.immediateRel32();
1955 AssemblerLabel call(RegisterID dst)
1957 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst);
1958 return m_formatter.label();
1961 void call_m(int offset, RegisterID base)
1963 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, base, offset);
1966 AssemblerLabel jmp()
1968 m_formatter.oneByteOp(OP_JMP_rel32);
1969 return m_formatter.immediateRel32();
1972 // Return a AssemblerLabel so we have a label to the jump, so we can use this
1973 // To make a tail recursive call on x86-64. The MacroAssembler
1974 // really shouldn't wrap this as a Jump, since it can't be linked. :-/
1975 AssemblerLabel jmp_r(RegisterID dst)
1977 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst);
1978 return m_formatter.label();
1981 void jmp_m(int offset, RegisterID base)
1983 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset);
1986 void jmp_m(int offset, RegisterID base, RegisterID index, int scale)
1988 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, index, scale, offset);
1992 void jmp_m(const void* address)
1994 m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, address);
1998 AssemblerLabel jne()
2000 m_formatter.twoByteOp(jccRel32(ConditionNE));
2001 return m_formatter.immediateRel32();
2004 AssemblerLabel jnz()
2011 m_formatter.twoByteOp(jccRel32(ConditionE));
2012 return m_formatter.immediateRel32();
2022 m_formatter.twoByteOp(jccRel32(ConditionL));
2023 return m_formatter.immediateRel32();
2028 m_formatter.twoByteOp(jccRel32(ConditionB));
2029 return m_formatter.immediateRel32();
2032 AssemblerLabel jle()
2034 m_formatter.twoByteOp(jccRel32(ConditionLE));
2035 return m_formatter.immediateRel32();
2038 AssemblerLabel jbe()
2040 m_formatter.twoByteOp(jccRel32(ConditionBE));
2041 return m_formatter.immediateRel32();
2044 AssemblerLabel jge()
2046 m_formatter.twoByteOp(jccRel32(ConditionGE));
2047 return m_formatter.immediateRel32();
2052 m_formatter.twoByteOp(jccRel32(ConditionG));
2053 return m_formatter.immediateRel32();
2058 m_formatter.twoByteOp(jccRel32(ConditionA));
2059 return m_formatter.immediateRel32();
2062 AssemblerLabel jae()
2064 m_formatter.twoByteOp(jccRel32(ConditionAE));
2065 return m_formatter.immediateRel32();
2070 m_formatter.twoByteOp(jccRel32(ConditionO));
2071 return m_formatter.immediateRel32();
2074 AssemblerLabel jnp()
2076 m_formatter.twoByteOp(jccRel32(ConditionNP));
2077 return m_formatter.immediateRel32();
2082 m_formatter.twoByteOp(jccRel32(ConditionP));
2083 return m_formatter.immediateRel32();
2088 m_formatter.twoByteOp(jccRel32(ConditionS));
2089 return m_formatter.immediateRel32();
2092 AssemblerLabel jCC(Condition cond)
2094 m_formatter.twoByteOp(jccRel32(cond));
2095 return m_formatter.immediateRel32();
2100 void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
2102 m_formatter.prefix(PRE_SSE_F2);
2103 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2106 void vaddsd_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
2108 m_formatter.vexNdsLigWigCommutativeTwoByteOp(PRE_SSE_F2, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
2111 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2113 m_formatter.prefix(PRE_SSE_F2);
2114 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
2117 void addsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2119 m_formatter.prefix(PRE_SSE_F2);
2120 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, dst, base, index, scale, offset);
2123 void vaddsd_mr(int offset, RegisterID base, XMMRegisterID b, XMMRegisterID dst)
2125 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
2128 void vaddsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID b, XMMRegisterID dst)
2130 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
2133 void addss_rr(XMMRegisterID src, XMMRegisterID dst)
2135 m_formatter.prefix(PRE_SSE_F3);
2136 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2139 void vaddss_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
2141 m_formatter.vexNdsLigWigCommutativeTwoByteOp(PRE_SSE_F3, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
2144 void addss_mr(int offset, RegisterID base, XMMRegisterID dst)
2146 m_formatter.prefix(PRE_SSE_F3);
2147 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset);
2150 void addss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2152 m_formatter.prefix(PRE_SSE_F3);
2153 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, dst, base, index, scale, offset);
2156 void vaddss_mr(int offset, RegisterID base, XMMRegisterID b, XMMRegisterID dst)
2158 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
2161 void vaddss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID b, XMMRegisterID dst)
2163 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
2167 void addsd_mr(const void* address, XMMRegisterID dst)
2169 m_formatter.prefix(PRE_SSE_F2);
2170 m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, address);
2174 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
2176 m_formatter.prefix(PRE_SSE_F2);
2177 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
2180 void cvtsi2ss_rr(RegisterID src, XMMRegisterID dst)
2182 m_formatter.prefix(PRE_SSE_F3);
2183 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
2187 void cvtsi2sdq_rr(RegisterID src, XMMRegisterID dst)
2189 m_formatter.prefix(PRE_SSE_F2);
2190 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
2193 void cvtsi2ssq_rr(RegisterID src, XMMRegisterID dst)
2195 m_formatter.prefix(PRE_SSE_F3);
2196 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src);
2199 void cvtsi2sdq_mr(int offset, RegisterID base, XMMRegisterID dst)
2201 m_formatter.prefix(PRE_SSE_F2);
2202 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
2205 void cvtsi2ssq_mr(int offset, RegisterID base, XMMRegisterID dst)
2207 m_formatter.prefix(PRE_SSE_F3);
2208 m_formatter.twoByteOp64(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
2212 void cvtsi2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
2214 m_formatter.prefix(PRE_SSE_F2);
2215 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
2218 void cvtsi2ss_mr(int offset, RegisterID base, XMMRegisterID dst)
2220 m_formatter.prefix(PRE_SSE_F3);
2221 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, base, offset);
2225 void cvtsi2sd_mr(const void* address, XMMRegisterID dst)
2227 m_formatter.prefix(PRE_SSE_F2);
2228 m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
2232 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
2234 m_formatter.prefix(PRE_SSE_F2);
2235 m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
2238 void cvtsd2ss_rr(XMMRegisterID src, XMMRegisterID dst)
2240 m_formatter.prefix(PRE_SSE_F2);
2241 m_formatter.twoByteOp(OP2_CVTSD2SS_VsdWsd, dst, (RegisterID)src);
2244 void cvtsd2ss_mr(int offset, RegisterID base, XMMRegisterID dst)
2246 m_formatter.prefix(PRE_SSE_F2);
2247 m_formatter.twoByteOp(OP2_CVTSD2SS_VsdWsd, dst, base, offset);
2250 void cvtss2sd_rr(XMMRegisterID src, XMMRegisterID dst)
2252 m_formatter.prefix(PRE_SSE_F3);
2253 m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, (RegisterID)src);
2256 void cvtss2sd_mr(int offset, RegisterID base, XMMRegisterID dst)
2258 m_formatter.prefix(PRE_SSE_F3);
2259 m_formatter.twoByteOp(OP2_CVTSS2SD_VsdWsd, dst, base, offset);
2263 void cvttsd2siq_rr(XMMRegisterID src, RegisterID dst)
2265 m_formatter.prefix(PRE_SSE_F2);
2266 m_formatter.twoByteOp64(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src);
2270 void movd_rr(XMMRegisterID src, RegisterID dst)
2272 m_formatter.prefix(PRE_SSE_66);
2273 m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst);
2276 void movd_rr(RegisterID src, XMMRegisterID dst)
2278 m_formatter.prefix(PRE_SSE_66);
2279 m_formatter.twoByteOp(OP2_MOVD_VdEd, (RegisterID)dst, src);
2283 void movmskpd_rr(XMMRegisterID src, RegisterID dst)
2285 m_formatter.prefix(PRE_SSE_66);
2286 m_formatter.twoByteOp64(OP2_MOVMSKPD_VdEd, dst, (RegisterID)src);
2289 void movq_rr(XMMRegisterID src, RegisterID dst)
2291 m_formatter.prefix(PRE_SSE_66);
2292 m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst);
2295 void movq_rr(RegisterID src, XMMRegisterID dst)
2297 m_formatter.prefix(PRE_SSE_66);
2298 m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src);
2302 void movapd_rr(XMMRegisterID src, XMMRegisterID dst)
2304 m_formatter.prefix(PRE_SSE_66);
2305 m_formatter.twoByteOp(OP2_MOVAPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
2308 void movaps_rr(XMMRegisterID src, XMMRegisterID dst)
2310 m_formatter.twoByteOp(OP2_MOVAPS_VpdWpd, (RegisterID)dst, (RegisterID)src);
2313 void movsd_rr(XMMRegisterID src, XMMRegisterID dst)
2315 m_formatter.prefix(PRE_SSE_F2);
2316 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2319 void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
2321 m_formatter.prefix(PRE_SSE_F2);
2322 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
2325 void movsd_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2327 m_formatter.prefix(PRE_SSE_F2);
2328 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
2331 void movss_rm(XMMRegisterID src, int offset, RegisterID base)
2333 m_formatter.prefix(PRE_SSE_F3);
2334 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset);
2337 void movss_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
2339 m_formatter.prefix(PRE_SSE_F3);
2340 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, index, scale, offset);
2343 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2345 m_formatter.prefix(PRE_SSE_F2);
2346 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
2349 void movsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2351 m_formatter.prefix(PRE_SSE_F2);
2352 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
2355 void movss_mr(int offset, RegisterID base, XMMRegisterID dst)
2357 m_formatter.prefix(PRE_SSE_F3);
2358 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset);
2361 void movss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2363 m_formatter.prefix(PRE_SSE_F3);
2364 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, dst, base, index, scale, offset);
2368 void movsd_mr(const void* address, XMMRegisterID dst)
2370 m_formatter.prefix(PRE_SSE_F2);
2371 m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
2373 void movsd_rm(XMMRegisterID src, const void* address)
2375 m_formatter.prefix(PRE_SSE_F2);
2376 m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, address);
2380 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
2382 m_formatter.prefix(PRE_SSE_F2);
2383 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2386 void vmulsd_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
2388 m_formatter.vexNdsLigWigCommutativeTwoByteOp(PRE_SSE_F2, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
2391 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2393 m_formatter.prefix(PRE_SSE_F2);
2394 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
2397 void mulsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2399 m_formatter.prefix(PRE_SSE_F2);
2400 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, dst, base, index, scale, offset);
2403 void vmulsd_mr(int offset, RegisterID base, XMMRegisterID b, XMMRegisterID dst)
2405 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
2408 void vmulsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID b, XMMRegisterID dst)
2410 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
2413 void mulss_rr(XMMRegisterID src, XMMRegisterID dst)
2415 m_formatter.prefix(PRE_SSE_F3);
2416 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2419 void vmulss_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
2421 m_formatter.vexNdsLigWigCommutativeTwoByteOp(PRE_SSE_F3, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
2424 void mulss_mr(int offset, RegisterID base, XMMRegisterID dst)
2426 m_formatter.prefix(PRE_SSE_F3);
2427 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset);
2430 void mulss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2432 m_formatter.prefix(PRE_SSE_F3);
2433 m_formatter.twoByteOp(OP2_MULSD_VsdWsd, dst, base, index, scale, offset);
2436 void vmulss_mr(int offset, RegisterID base, XMMRegisterID b, XMMRegisterID dst)
2438 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
2441 void vmulss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID b, XMMRegisterID dst)
2443 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
2446 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
2448 m_formatter.prefix(PRE_SSE_66);
2449 m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src);
2450 m_formatter.immediate8(whichWord);
2453 void psllq_i8r(int imm, XMMRegisterID dst)
2455 m_formatter.prefix(PRE_SSE_66);
2456 m_formatter.twoByteOp8(OP2_PSLLQ_UdqIb, GROUP14_OP_PSLLQ, (RegisterID)dst);
2457 m_formatter.immediate8(imm);
2460 void psrlq_i8r(int imm, XMMRegisterID dst)
2462 m_formatter.prefix(PRE_SSE_66);
2463 m_formatter.twoByteOp8(OP2_PSRLQ_UdqIb, GROUP14_OP_PSRLQ, (RegisterID)dst);
2464 m_formatter.immediate8(imm);
2467 void por_rr(XMMRegisterID src, XMMRegisterID dst)
2469 m_formatter.prefix(PRE_SSE_66);
2470 m_formatter.twoByteOp(OP2_POR_VdqWdq, (RegisterID)dst, (RegisterID)src);
2473 void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
2475 m_formatter.prefix(PRE_SSE_F2);
2476 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2479 void vsubsd_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
2481 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
2484 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2486 m_formatter.prefix(PRE_SSE_F2);
2487 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
2490 void subsd_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2492 m_formatter.prefix(PRE_SSE_F2);
2493 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, dst, base, index, scale, offset);
2496 void vsubsd_mr(XMMRegisterID b, int offset, RegisterID base, XMMRegisterID dst)
2498 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
2501 void vsubsd_mr(XMMRegisterID b, int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2503 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F2, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
2506 void subss_rr(XMMRegisterID src, XMMRegisterID dst)
2508 m_formatter.prefix(PRE_SSE_F3);
2509 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2512 void vsubss_rr(XMMRegisterID a, XMMRegisterID b, XMMRegisterID dst)
2514 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)a, (RegisterID)b);
2517 void subss_mr(int offset, RegisterID base, XMMRegisterID dst)
2519 m_formatter.prefix(PRE_SSE_F3);
2520 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset);
2523 void subss_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2525 m_formatter.prefix(PRE_SSE_F3);
2526 m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, dst, base, index, scale, offset);
2529 void vsubss_mr(XMMRegisterID b, int offset, RegisterID base, XMMRegisterID dst)
2531 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, base, offset);
2534 void vsubss_mr(XMMRegisterID b, int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
2536 m_formatter.vexNdsLigWigTwoByteOp(PRE_SSE_F3, OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)b, offset, base, index, scale);
2539 void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst)
2541 m_formatter.prefix(PRE_SSE_66);
2542 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2545 void ucomisd_mr(int offset, RegisterID base, XMMRegisterID dst)
2547 m_formatter.prefix(PRE_SSE_66);
2548 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
2551 void ucomiss_rr(XMMRegisterID src, XMMRegisterID dst)
2553 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2556 void ucomiss_mr(int offset, RegisterID base, XMMRegisterID dst)
2558 m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, base, offset);
2561 void divsd_rr(XMMRegisterID src, XMMRegisterID dst)
2563 m_formatter.prefix(PRE_SSE_F2);
2564 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2567 void divsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2569 m_formatter.prefix(PRE_SSE_F2);
2570 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
2573 void divss_rr(XMMRegisterID src, XMMRegisterID dst)
2575 m_formatter.prefix(PRE_SSE_F3);
2576 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2579 void divss_mr(int offset, RegisterID base, XMMRegisterID dst)
2581 m_formatter.prefix(PRE_SSE_F3);
2582 m_formatter.twoByteOp(OP2_DIVSD_VsdWsd, (RegisterID)dst, base, offset);
2585 void andps_rr(XMMRegisterID src, XMMRegisterID dst)
2587 m_formatter.twoByteOp(OP2_ANDPS_VpdWpd, (RegisterID)dst, (RegisterID)src);
2590 void xorps_rr(XMMRegisterID src, XMMRegisterID dst)
2592 m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
2595 void xorpd_rr(XMMRegisterID src, XMMRegisterID dst)
2601 m_formatter.prefix(PRE_SSE_66);
2602 m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
2605 void andnpd_rr(XMMRegisterID src, XMMRegisterID dst)
2607 m_formatter.prefix(PRE_SSE_66);
2608 m_formatter.twoByteOp(OP2_ANDNPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
2611 void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
2613 m_formatter.prefix(PRE_SSE_F2);
2614 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2617 void sqrtsd_mr(int offset, RegisterID base, XMMRegisterID dst)
2619 m_formatter.prefix(PRE_SSE_F2);
2620 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, base, offset);
2623 void sqrtss_rr(XMMRegisterID src, XMMRegisterID dst)
2625 m_formatter.prefix(PRE_SSE_F3);
2626 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
2629 void sqrtss_mr(int offset, RegisterID base, XMMRegisterID dst)
2631 m_formatter.prefix(PRE_SSE_F3);
2632 m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, base, offset);
2635 enum class RoundingType : uint8_t {
2636 ToNearestWithTiesToEven = 0,
2637 TowardNegativeInfiniti = 1,
2642 void roundss_rr(XMMRegisterID src, XMMRegisterID dst, RoundingType rounding)
2644 m_formatter.prefix(PRE_SSE_66);
2645 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSS_VssWssIb, (RegisterID)dst, (RegisterID)src);
2646 m_formatter.immediate8(static_cast<uint8_t>(rounding));
2649 void roundss_mr(int offset, RegisterID base, XMMRegisterID dst, RoundingType rounding)
2651 m_formatter.prefix(PRE_SSE_66);
2652 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSS_VssWssIb, (RegisterID)dst, base, offset);
2653 m_formatter.immediate8(static_cast<uint8_t>(rounding));
2656 void roundsd_rr(XMMRegisterID src, XMMRegisterID dst, RoundingType rounding)
2658 m_formatter.prefix(PRE_SSE_66);
2659 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSD_VsdWsdIb, (RegisterID)dst, (RegisterID)src);
2660 m_formatter.immediate8(static_cast<uint8_t>(rounding));
2663 void roundsd_mr(int offset, RegisterID base, XMMRegisterID dst, RoundingType rounding)
2665 m_formatter.prefix(PRE_SSE_66);
2666 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_3A, OP3_ROUNDSD_VsdWsdIb, (RegisterID)dst, base, offset);
2667 m_formatter.immediate8(static_cast<uint8_t>(rounding));
2670 // Misc instructions:
2674 m_formatter.oneByteOp(OP_INT3);
2679 m_formatter.oneByteOp(OP_RET);
2682 void predictNotTaken()
2684 m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN);
2689 m_formatter.threeByteOp(OP2_3BYTE_ESCAPE_AE, OP3_MFENCE);
2692 // Assembler admin methods:
2694 size_t codeSize() const
2696 return m_formatter.codeSize();
2699 AssemblerLabel labelForWatchpoint()
2701 AssemblerLabel result = m_formatter.label();
2702 if (static_cast<int>(result.m_offset) != m_indexOfLastWatchpoint)
2704 m_indexOfLastWatchpoint = result.m_offset;
2705 m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
2709 AssemblerLabel labelIgnoringWatchpoints()
2711 return m_formatter.label();
2714 AssemblerLabel label()
2716 AssemblerLabel result = m_formatter.label();
2717 while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
2719 result = m_formatter.label();
2724 AssemblerLabel align(int alignment)
2726 while (!m_formatter.isAligned(alignment))
2727 m_formatter.oneByteOp(OP_HLT);
2732 // Linking & patching:
2734 // 'link' and 'patch' methods are for use on unprotected code - such as the code
2735 // within the AssemblerBuffer, and code being patched by the patch buffer. Once
2736 // code has been finalized it is (platform support permitting) within a non-
2737 // writable region of memory; to modify the code in an execute-only execuable
2738 // pool the 'repatch' and 'relink' methods should be used.
2740 void linkJump(AssemblerLabel from, AssemblerLabel to)
2742 ASSERT(from.isSet());
2745 char* code = reinterpret_cast<char*>(m_formatter.data());
2746 ASSERT(!reinterpret_cast<int32_t*>(code + from.m_offset)[-1]);
2747 setRel32(code + from.m_offset, code + to.m_offset);
2750 static void linkJump(void* code, AssemblerLabel from, void* to)
2752 ASSERT(from.isSet());
2754 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
2757 static void linkCall(void* code, AssemblerLabel from, void* to)
2759 ASSERT(from.isSet());
2761 setRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
2764 static void linkPointer(void* code, AssemblerLabel where, void* value)
2766 ASSERT(where.isSet());
2768 setPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
2771 static void relinkJump(void* from, void* to)
2776 static void relinkCall(void* from, void* to)
2781 static void repatchCompact(void* where, int32_t value)
2783 ASSERT(value >= std::numeric_limits<int8_t>::min());
2784 ASSERT(value <= std::numeric_limits<int8_t>::max());
2785 setInt8(where, value);
2788 static void repatchInt32(void* where, int32_t value)
2790 setInt32(where, value);
2793 static void repatchPointer(void* where, void* value)
2795 setPointer(where, value);
2798 static void* readPointer(void* where)
2800 return reinterpret_cast<void**>(where)[-1];
2803 static void replaceWithJump(void* instructionStart, void* to)
2805 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2806 uint8_t* dstPtr = reinterpret_cast<uint8_t*>(to);
2807 intptr_t distance = (intptr_t)(dstPtr - (ptr + 5));
2808 ptr[0] = static_cast<uint8_t>(OP_JMP_rel32);
2809 *reinterpret_cast<int32_t*>(ptr + 1) = static_cast<int32_t>(distance);
2812 static ptrdiff_t maxJumpReplacementSize()
2817 static constexpr ptrdiff_t patchableJumpSize()
2823 static void revertJumpTo_movq_i64r(void* instructionStart, int64_t imm, RegisterID dst)
2825 const unsigned instructionSize = 10; // REX.W MOV IMM64
2826 const int rexBytes = 1;
2827 const int opcodeBytes = 1;
2828 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2829 ptr[0] = PRE_REX | (1 << 3) | (dst >> 3);
2830 ptr[1] = OP_MOV_EAXIv | (dst & 7);
2837 for (unsigned i = rexBytes + opcodeBytes; i < instructionSize; ++i)
2838 ptr[i] = u.asBytes[i - rexBytes - opcodeBytes];
2841 static void revertJumpTo_movl_i32r(void* instructionStart, int32_t imm, RegisterID dst)
2843 // We only revert jumps on inline caches, and inline caches always use the scratch register (r11).
2844 // FIXME: If the above is ever false then we need to make this smarter with respect to emitting
2846 ASSERT(dst == X86Registers::r11);
2847 const unsigned instructionSize = 6; // REX MOV IMM32
2848 const int rexBytes = 1;
2849 const int opcodeBytes = 1;
2850 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2851 ptr[0] = PRE_REX | (dst >> 3);
2852 ptr[1] = OP_MOV_EAXIv | (dst & 7);
2859 for (unsigned i = rexBytes + opcodeBytes; i < instructionSize; ++i)
2860 ptr[i] = u.asBytes[i - rexBytes - opcodeBytes];
2864 static void revertJumpTo_cmpl_ir_force32(void* instructionStart, int32_t imm, RegisterID dst)
2866 const int opcodeBytes = 1;
2867 const int modRMBytes = 1;
2868 ASSERT(opcodeBytes + modRMBytes <= maxJumpReplacementSize());
2869 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2870 ptr[0] = OP_GROUP1_EvIz;
2871 ptr[1] = (X86InstructionFormatter::ModRmRegister << 6) | (GROUP1_OP_CMP << 3) | dst;
2877 for (unsigned i = opcodeBytes + modRMBytes; i < static_cast<unsigned>(maxJumpReplacementSize()); ++i)
2878 ptr[i] = u.asBytes[i - opcodeBytes - modRMBytes];
2881 static void revertJumpTo_cmpl_im_force32(void* instructionStart, int32_t imm, int offset, RegisterID dst)
2883 ASSERT_UNUSED(offset, !offset);
2884 const int opcodeBytes = 1;
2885 const int modRMBytes = 1;
2886 ASSERT(opcodeBytes + modRMBytes <= maxJumpReplacementSize());
2887 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2888 ptr[0] = OP_GROUP1_EvIz;
2889 ptr[1] = (X86InstructionFormatter::ModRmMemoryNoDisp << 6) | (GROUP1_OP_CMP << 3) | dst;
2895 for (unsigned i = opcodeBytes + modRMBytes; i < static_cast<unsigned>(maxJumpReplacementSize()); ++i)
2896 ptr[i] = u.asBytes[i - opcodeBytes - modRMBytes];
2899 static void replaceWithLoad(void* instructionStart)
2901 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2903 if ((*ptr & ~15) == PRE_REX)
2913 RELEASE_ASSERT_NOT_REACHED();
2917 static void replaceWithAddressComputation(void* instructionStart)
2919 uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
2921 if ((*ptr & ~15) == PRE_REX)
2931 RELEASE_ASSERT_NOT_REACHED();
2935 static unsigned getCallReturnOffset(AssemblerLabel call)
2937 ASSERT(call.isSet());
2938 return call.m_offset;
2941 static void* getRelocatedAddress(void* code, AssemblerLabel label)
2943 ASSERT(label.isSet());
2944 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + label.m_offset);
2947 static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b)
2949 return b.m_offset - a.m_offset;
2952 unsigned debugOffset() { return m_formatter.debugOffset(); }
2956 m_formatter.oneByteOp(OP_NOP);
2959 static void fillNops(void* base, size_t size, bool isCopyingToExecutableMemory)
2961 UNUSED_PARAM(isCopyingToExecutableMemory);
2963 static const uint8_t nops[10][10] = {
2971 {0x0f, 0x1f, 0x40, 0x08},
2972 // nopl 8(%[re]ax,%[re]ax,1)
2973 {0x0f, 0x1f, 0x44, 0x00, 0x08},
2974 // nopw 8(%[re]ax,%[re]ax,1)
2975 {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x08},
2976 // nopl 512(%[re]ax)
2977 {0x0f, 0x1f, 0x80, 0x00, 0x02, 0x00, 0x00},
2978 // nopl 512(%[re]ax,%[re]ax,1)
2979 {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00},
2980 // nopw 512(%[re]ax,%[re]ax,1)
2981 {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00},
2982 // nopw %cs:512(%[re]ax,%[re]ax,1)
2983 {0x66, 0x2e, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x02, 0x00, 0x00}
2986 uint8_t* where = reinterpret_cast<uint8_t*>(base);
2988 unsigned nopSize = static_cast<unsigned>(std::min<size_t>(size, 15));
2989 unsigned numPrefixes = nopSize <= 10 ? 0 : nopSize - 10;
2990 for (unsigned i = 0; i != numPrefixes; ++i)
2993 unsigned nopRest = nopSize - numPrefixes;
2994 for (unsigned i = 0; i != nopRest; ++i)
2995 *where++ = nops[nopRest-1][i];
3000 memset(base, OP_NOP, size);
3004 // This is a no-op on x86
3005 ALWAYS_INLINE static void cacheFlush(void*, size_t) { }
3009 static void setPointer(void* where, void* value)
3011 reinterpret_cast<void**>(where)[-1] = value;
3014 static void setInt32(void* where, int32_t value)
3016 reinterpret_cast<int32_t*>(where)[-1] = value;
3019 static void setInt8(void* where, int8_t value)
3021 reinterpret_cast<int8_t*>(where)[-1] = value;
3024 static void setRel32(void* from, void* to)
3026 intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
3027 ASSERT(offset == static_cast<int32_t>(offset));
3029 setInt32(from, offset);
3032 class X86InstructionFormatter {
3033 static const int maxInstructionSize = 16;
3037 ModRmMemoryNoDisp = 0,
3038 ModRmMemoryDisp8 = 1 << 6,
3039 ModRmMemoryDisp32 = 2 << 6,
3040 ModRmRegister = 3 << 6,
3043 // Legacy prefix bytes:
3045 // These are emmitted prior to the instruction.
3047 void prefix(OneByteOpcodeID pre)
3049 m_buffer.putByte(pre);
3053 // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
3054 static bool byteRegRequiresRex(int reg)
3056 static_assert(X86Registers::esp == 4, "Necessary condition for OR-masking");
3057 return (reg >= X86Registers::esp);
3059 static bool byteRegRequiresRex(int a, int b)
3061 return byteRegRequiresRex(a | b);
3064 // Registers r8 & above require a REX prefixe.
3065 static bool regRequiresRex(int reg)
3067 static_assert(X86Registers::r8 == 8, "Necessary condition for OR-masking");
3068 return (reg >= X86Registers::r8);
3070 static bool regRequiresRex(int a, int b)
3072 return regRequiresRex(a | b);
3074 static bool regRequiresRex(int a, int b, int c)
3076 return regRequiresRex(a | b | c);
3079 static bool byteRegRequiresRex(int) { return false; }
3080 static bool byteRegRequiresRex(int, int) { return false; }
3081 static bool regRequiresRex(int) { return false; }
3082 static bool regRequiresRex(int, int) { return false; }
3083 static bool regRequiresRex(int, int, int) { return false; }
3086 class SingleInstructionBufferWriter : public AssemblerBuffer::LocalWriter {
3088 SingleInstructionBufferWriter(AssemblerBuffer& buffer)
3089 : AssemblerBuffer::LocalWriter(buffer, maxInstructionSize)
3093 // Internals; ModRm and REX formatters.
3095 static constexpr RegisterID noBase = X86Registers::ebp;
3096 static constexpr RegisterID hasSib = X86Registers::esp;
3097 static constexpr RegisterID noIndex = X86Registers::esp;
3100 static constexpr RegisterID noBase2 = X86Registers::r13;
3101 static constexpr RegisterID hasSib2 = X86Registers::r12;
3103 // Format a REX prefix byte.
3104 ALWAYS_INLINE void emitRex(bool w, int r, int x, int b)
3109 putByteUnchecked(PRE_REX | ((int)w << 3) | ((r>>3)<<2) | ((x>>3)<<1) | (b>>3));
3112 // Used to plant a REX byte with REX.w set (for 64-bit operations).
3113 ALWAYS_INLINE void emitRexW(int r, int x, int b)
3115 emitRex(true, r, x, b);
3118 // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
3119 // regRequiresRex() to check other registers (i.e. address base & index).
3120 ALWAYS_INLINE void emitRexIf(bool condition, int r, int x, int b)
3123 emitRex(false, r, x, b);
3126 // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
3127 ALWAYS_INLINE void emitRexIfNeeded(int r, int x, int b)
3129 emitRexIf(regRequiresRex(r, x, b), r, x, b);
3132 // No REX prefix bytes on 32-bit x86.
3133 ALWAYS_INLINE void emitRexIf(bool, int, int, int) { }
3134 ALWAYS_INLINE void emitRexIfNeeded(int, int, int) { }
3137 ALWAYS_INLINE void putModRm(ModRmMode mode, int reg, RegisterID rm)
3139 putByteUnchecked(mode | ((reg & 7) << 3) | (rm & 7));
3142 ALWAYS_INLINE void putModRmSib(ModRmMode mode, int reg, RegisterID base, RegisterID index, int scale)
3144 ASSERT(mode != ModRmRegister);
3146 putModRm(mode, reg, hasSib);
3147 putByteUnchecked((scale << 6) | ((index & 7) << 3) | (base & 7));
3150 ALWAYS_INLINE void registerModRM(int reg, RegisterID rm)
3152 putModRm(ModRmRegister, reg, rm);
3155 ALWAYS_INLINE void memoryModRM(int reg, RegisterID base, int offset)
3157 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
3159 if ((base == hasSib) || (base == hasSib2)) {
3161 if (base == hasSib) {
3163 if (!offset) // No need to check if the base is noBase, since we know it is hasSib!
3164 putModRmSib(ModRmMemoryNoDisp, reg, base, noIndex, 0);
3165 else if (CAN_SIGN_EXTEND_8_32(offset)) {
3166 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
3167 putByteUnchecked(offset);
3169 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
3170 putIntUnchecked(offset);
3174 if (!offset && (base != noBase) && (base != noBase2))
3176 if (!offset && (base != noBase))
3178 putModRm(ModRmMemoryNoDisp, reg, base);
3179 else if (CAN_SIGN_EXTEND_8_32(offset)) {
3180 putModRm(ModRmMemoryDisp8, reg, base);
3181 putByteUnchecked(offset);
3183 putModRm(ModRmMemoryDisp32, reg, base);
3184 putIntUnchecked(offset);
3189 ALWAYS_INLINE void memoryModRM_disp8(int reg, RegisterID base, int offset)
3191 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
3192 ASSERT(CAN_SIGN_EXTEND_8_32(offset));
3194 if ((base == hasSib) || (base == hasSib2)) {
3196 if (base == hasSib) {
3198 putModRmSib(ModRmMemoryDisp8, reg, base, noIndex, 0);
3199 putByteUnchecked(offset);
3201 putModRm(ModRmMemoryDisp8, reg, base);
3202 putByteUnchecked(offset);
3206 ALWAYS_INLINE void memoryModRM_disp32(int reg, RegisterID base, int offset)
3208 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
3210 if ((base == hasSib) || (base == hasSib2)) {
3212 if (base == hasSib) {
3214 putModRmSib(ModRmMemoryDisp32, reg, base, noIndex, 0);
3215 putIntUnchecked(offset);
3217 putModRm(ModRmMemoryDisp32, reg, base);
3218 putIntUnchecked(offset);
3222 ALWAYS_INLINE void memoryModRM(int reg, RegisterID base, RegisterID index, int scale, int offset)
3224 ASSERT(index != noIndex);
3227 if (!offset && (base != noBase) && (base != noBase2))
3229 if (!offset && (base != noBase))
3231 putModRmSib(ModRmMemoryNoDisp, reg, base, index, scale);
3232 else if (CAN_SIGN_EXTEND_8_32(offset)) {
3233 putModRmSib(ModRmMemoryDisp8, reg, base, index, scale);
3234 putByteUnchecked(offset);
3236 putModRmSib(ModRmMemoryDisp32, reg, base, index, scale);
3237 putIntUnchecked(offset);
3242 ALWAYS_INLINE void memoryModRM(int reg, const void* address)
3244 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
3245 putModRm(ModRmMemoryNoDisp, reg, noBase);
3246 putIntUnchecked(reinterpret_cast<int32_t>(address));
3249 ALWAYS_INLINE void twoBytesVex(OneByteOpcodeID simdPrefix, RegisterID inOpReg, RegisterID r)
3251 putByteUnchecked(VexPrefix::TwoBytes);
3253 uint8_t secondByte = vexEncodeSimdPrefix(simdPrefix);
3254 secondByte |= (~inOpReg & 0xf) << 3;
3255 secondByte |= !regRequiresRex(r) << 7;
3256 putByteUnchecked(secondByte);
3259 ALWAYS_INLINE void threeBytesVexNds(OneByteOpcodeID simdPrefix, VexImpliedBytes impliedBytes, RegisterID r, RegisterID inOpReg, RegisterID x, RegisterID b)
3261 putByteUnchecked(VexPrefix::ThreeBytes);
3263 uint8_t secondByte = static_cast<uint8_t>(impliedBytes);
3264 secondByte |= !regRequiresRex(r) << 7;
3265 secondByte |= !regRequiresRex(x) << 6;
3266 secondByte |= !regRequiresRex(b) << 5;
3267 putByteUnchecked(secondByte);
3269 uint8_t thirdByte = vexEncodeSimdPrefix(simdPrefix);
3270 thirdByte |= (~inOpReg & 0xf) << 3;
3271 putByteUnchecked(thirdByte);
3274 ALWAYS_INLINE void threeBytesVexNds(OneByteOpcodeID simdPrefix, VexImpliedBytes impliedBytes, RegisterID r, RegisterID inOpReg, RegisterID b)
3276 putByteUnchecked(VexPrefix::ThreeBytes);
3278 uint8_t secondByte = static_cast<uint8_t>(impliedBytes);
3279 secondByte |= !regRequiresRex(r) << 7;
3280 secondByte |= 1 << 6; // REX.X
3281 secondByte |= !regRequiresRex(b) << 5;
3282 putByteUnchecked(secondByte);
3284 uint8_t thirdByte = vexEncodeSimdPrefix(simdPrefix);
3285 thirdByte |= (~inOpReg & 0xf) << 3;
3286 putByteUnchecked(thirdByte);
3289 uint8_t vexEncodeSimdPrefix(OneByteOpcodeID simdPrefix)
3291 switch (simdPrefix) {
3299 RELEASE_ASSERT_NOT_REACHED();
3306 // Word-sized operands / no operand instruction formatters.
3308 // In addition to the opcode, the following operand permutations are supported:
3309 // * None - instruction takes no operands.
3310 // * One register - the low three bits of the RegisterID are added into the opcode.
3311 // * 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).
3312 // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
3313 // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
3315 // For 32-bit x86 targets, the address operand may also be provided as a void*.
3316 // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
3318 // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
3320 void oneByteOp(OneByteOpcodeID opcode)
3322 SingleInstructionBufferWriter writer(m_buffer);
3323 writer.putByteUnchecked(opcode);
3326 void oneByteOp(OneByteOpcodeID opcode, RegisterID reg)
3328 SingleInstructionBufferWriter writer(m_buffer);
3329 writer.emitRexIfNeeded(0, 0, reg);
3330 writer.putByteUnchecked(opcode + (reg & 7));
3333 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID rm)
3335 SingleInstructionBufferWriter writer(m_buffer);
3336 writer.emitRexIfNeeded(reg, 0, rm);
3337 writer.putByteUnchecked(opcode);
3338 writer.registerModRM(reg, rm);
3341 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
3343 SingleInstructionBufferWriter writer(m_buffer);
3344 writer.emitRexIfNeeded(reg, 0, base);
3345 writer.putByteUnchecked(opcode);
3346 writer.memoryModRM(reg, base, offset);
3349 void oneByteOp_disp32(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
3351 SingleInstructionBufferWriter writer(m_buffer);
3352 writer.emitRexIfNeeded(reg, 0, base);
3353 writer.putByteUnchecked(opcode);
3354 writer.memoryModRM_disp32(reg, base, offset);
3357 void oneByteOp_disp8(OneByteOpcodeID opcode, int reg, RegisterID base, int offset)
3359 SingleInstructionBufferWriter writer(m_buffer);
3360 writer.emitRexIfNeeded(reg, 0, base);
3361 writer.putByteUnchecked(opcode);
3362 writer.memoryModRM_disp8(reg, base, offset);
3365 void oneByteOp(OneByteOpcodeID opcode, int reg, RegisterID base, RegisterID index, int scale, int offset)
3367 SingleInstructionBufferWriter writer(m_buffer);
3368 writer.emitRexIfNeeded(reg, index, base);
3369 writer.putByteUnchecked(opcode);
3370 writer.memoryModRM(reg, base, index, scale, offset);
3374 void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
3376 SingleInstructionBufferWriter writer(m_buffer);
3377 writer.putByteUnchecked(opcode);
3378 writer.memoryModRM(reg, address);