2 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 #ifndef X86Assembler_h
27 #define X86Assembler_h
29 #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
31 #include "AssemblerBuffer.h"
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
;
255 void push_r(RegisterID reg
)
257 m_formatter
.oneByteOp(OP_PUSH_EAX
, reg
);
260 void pop_r(RegisterID reg
)
262 m_formatter
.oneByteOp(OP_POP_EAX
, reg
);
265 void push_i32(int imm
)
267 m_formatter
.oneByteOp(OP_PUSH_Iz
);
268 m_formatter
.immediate32(imm
);
271 void push_m(int offset
, RegisterID base
)
273 m_formatter
.oneByteOp(OP_GROUP5_Ev
, GROUP5_OP_PUSH
, base
, offset
);
276 void pop_m(int offset
, RegisterID base
)
278 m_formatter
.oneByteOp(OP_GROUP1A_Ev
, GROUP1A_OP_POP
, base
, offset
);
281 // Arithmetic operations:
284 void adcl_im(int imm
, const void* addr
)
286 if (CAN_SIGN_EXTEND_8_32(imm
)) {
287 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_ADC
, addr
);
288 m_formatter
.immediate8(imm
);
290 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_ADC
, addr
);
291 m_formatter
.immediate32(imm
);
296 void addl_rr(RegisterID src
, RegisterID dst
)
298 m_formatter
.oneByteOp(OP_ADD_EvGv
, src
, dst
);
301 void addl_mr(int offset
, RegisterID base
, RegisterID dst
)
303 m_formatter
.oneByteOp(OP_ADD_GvEv
, dst
, base
, offset
);
306 void addl_rm(RegisterID src
, int offset
, RegisterID base
)
308 m_formatter
.oneByteOp(OP_ADD_EvGv
, src
, base
, offset
);
311 void addl_ir(int imm
, RegisterID dst
)
313 if (CAN_SIGN_EXTEND_8_32(imm
)) {
314 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_ADD
, dst
);
315 m_formatter
.immediate8(imm
);
317 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_ADD
, dst
);
318 m_formatter
.immediate32(imm
);
322 void addl_im(int imm
, int offset
, RegisterID base
)
324 if (CAN_SIGN_EXTEND_8_32(imm
)) {
325 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_ADD
, base
, offset
);
326 m_formatter
.immediate8(imm
);
328 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_ADD
, base
, offset
);
329 m_formatter
.immediate32(imm
);
334 void addq_rr(RegisterID src
, RegisterID dst
)
336 m_formatter
.oneByteOp64(OP_ADD_EvGv
, src
, dst
);
339 void addq_ir(int imm
, RegisterID dst
)
341 if (CAN_SIGN_EXTEND_8_32(imm
)) {
342 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_ADD
, dst
);
343 m_formatter
.immediate8(imm
);
345 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_ADD
, dst
);
346 m_formatter
.immediate32(imm
);
350 void addq_im(int imm
, int offset
, RegisterID base
)
352 if (CAN_SIGN_EXTEND_8_32(imm
)) {
353 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_ADD
, base
, offset
);
354 m_formatter
.immediate8(imm
);
356 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_ADD
, base
, offset
);
357 m_formatter
.immediate32(imm
);
361 void addl_im(int imm
, const void* addr
)
363 if (CAN_SIGN_EXTEND_8_32(imm
)) {
364 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_ADD
, addr
);
365 m_formatter
.immediate8(imm
);
367 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_ADD
, addr
);
368 m_formatter
.immediate32(imm
);
373 void andl_rr(RegisterID src
, RegisterID dst
)
375 m_formatter
.oneByteOp(OP_AND_EvGv
, src
, dst
);
378 void andl_mr(int offset
, RegisterID base
, RegisterID dst
)
380 m_formatter
.oneByteOp(OP_AND_GvEv
, dst
, base
, offset
);
383 void andl_rm(RegisterID src
, int offset
, RegisterID base
)
385 m_formatter
.oneByteOp(OP_AND_EvGv
, src
, base
, offset
);
388 void andl_ir(int imm
, RegisterID dst
)
390 if (CAN_SIGN_EXTEND_8_32(imm
)) {
391 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_AND
, dst
);
392 m_formatter
.immediate8(imm
);
394 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_AND
, dst
);
395 m_formatter
.immediate32(imm
);
399 void andl_im(int imm
, int offset
, RegisterID base
)
401 if (CAN_SIGN_EXTEND_8_32(imm
)) {
402 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_AND
, base
, offset
);
403 m_formatter
.immediate8(imm
);
405 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_AND
, base
, offset
);
406 m_formatter
.immediate32(imm
);
411 void andq_rr(RegisterID src
, RegisterID dst
)
413 m_formatter
.oneByteOp64(OP_AND_EvGv
, src
, dst
);
416 void andq_ir(int imm
, RegisterID dst
)
418 if (CAN_SIGN_EXTEND_8_32(imm
)) {
419 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_AND
, dst
);
420 m_formatter
.immediate8(imm
);
422 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_AND
, dst
);
423 m_formatter
.immediate32(imm
);
427 void andl_im(int imm
, const void* addr
)
429 if (CAN_SIGN_EXTEND_8_32(imm
)) {
430 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_AND
, addr
);
431 m_formatter
.immediate8(imm
);
433 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_AND
, addr
);
434 m_formatter
.immediate32(imm
);
439 void negl_r(RegisterID dst
)
441 m_formatter
.oneByteOp(OP_GROUP3_Ev
, GROUP3_OP_NEG
, dst
);
444 void negl_m(int offset
, RegisterID base
)
446 m_formatter
.oneByteOp(OP_GROUP3_Ev
, GROUP3_OP_NEG
, base
, offset
);
449 void notl_r(RegisterID dst
)
451 m_formatter
.oneByteOp(OP_GROUP3_Ev
, GROUP3_OP_NOT
, dst
);
454 void notl_m(int offset
, RegisterID base
)
456 m_formatter
.oneByteOp(OP_GROUP3_Ev
, GROUP3_OP_NOT
, base
, offset
);
459 void orl_rr(RegisterID src
, RegisterID dst
)
461 m_formatter
.oneByteOp(OP_OR_EvGv
, src
, dst
);
464 void orl_mr(int offset
, RegisterID base
, RegisterID dst
)
466 m_formatter
.oneByteOp(OP_OR_GvEv
, dst
, base
, offset
);
469 void orl_rm(RegisterID src
, int offset
, RegisterID base
)
471 m_formatter
.oneByteOp(OP_OR_EvGv
, src
, base
, offset
);
474 void orl_ir(int imm
, RegisterID dst
)
476 if (CAN_SIGN_EXTEND_8_32(imm
)) {
477 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_OR
, dst
);
478 m_formatter
.immediate8(imm
);
480 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_OR
, dst
);
481 m_formatter
.immediate32(imm
);
485 void orl_im(int imm
, int offset
, RegisterID base
)
487 if (CAN_SIGN_EXTEND_8_32(imm
)) {
488 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_OR
, base
, offset
);
489 m_formatter
.immediate8(imm
);
491 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_OR
, base
, offset
);
492 m_formatter
.immediate32(imm
);
497 void orq_rr(RegisterID src
, RegisterID dst
)
499 m_formatter
.oneByteOp64(OP_OR_EvGv
, src
, dst
);
502 void orq_ir(int imm
, RegisterID dst
)
504 if (CAN_SIGN_EXTEND_8_32(imm
)) {
505 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_OR
, dst
);
506 m_formatter
.immediate8(imm
);
508 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_OR
, dst
);
509 m_formatter
.immediate32(imm
);
513 void orl_im(int imm
, const void* addr
)
515 if (CAN_SIGN_EXTEND_8_32(imm
)) {
516 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_OR
, addr
);
517 m_formatter
.immediate8(imm
);
519 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_OR
, addr
);
520 m_formatter
.immediate32(imm
);
525 void subl_rr(RegisterID src
, RegisterID dst
)
527 m_formatter
.oneByteOp(OP_SUB_EvGv
, src
, dst
);
530 void subl_mr(int offset
, RegisterID base
, RegisterID dst
)
532 m_formatter
.oneByteOp(OP_SUB_GvEv
, dst
, base
, offset
);
535 void subl_rm(RegisterID src
, int offset
, RegisterID base
)
537 m_formatter
.oneByteOp(OP_SUB_EvGv
, src
, base
, offset
);
540 void subl_ir(int imm
, RegisterID dst
)
542 if (CAN_SIGN_EXTEND_8_32(imm
)) {
543 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_SUB
, dst
);
544 m_formatter
.immediate8(imm
);
546 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_SUB
, dst
);
547 m_formatter
.immediate32(imm
);
551 void subl_im(int imm
, int offset
, RegisterID base
)
553 if (CAN_SIGN_EXTEND_8_32(imm
)) {
554 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_SUB
, base
, offset
);
555 m_formatter
.immediate8(imm
);
557 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_SUB
, base
, offset
);
558 m_formatter
.immediate32(imm
);
563 void subq_rr(RegisterID src
, RegisterID dst
)
565 m_formatter
.oneByteOp64(OP_SUB_EvGv
, src
, dst
);
568 void subq_ir(int imm
, RegisterID dst
)
570 if (CAN_SIGN_EXTEND_8_32(imm
)) {
571 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_SUB
, dst
);
572 m_formatter
.immediate8(imm
);
574 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_SUB
, dst
);
575 m_formatter
.immediate32(imm
);
579 void subl_im(int imm
, const void* addr
)
581 if (CAN_SIGN_EXTEND_8_32(imm
)) {
582 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_SUB
, addr
);
583 m_formatter
.immediate8(imm
);
585 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_SUB
, addr
);
586 m_formatter
.immediate32(imm
);
591 void xorl_rr(RegisterID src
, RegisterID dst
)
593 m_formatter
.oneByteOp(OP_XOR_EvGv
, src
, dst
);
596 void xorl_mr(int offset
, RegisterID base
, RegisterID dst
)
598 m_formatter
.oneByteOp(OP_XOR_GvEv
, dst
, base
, offset
);
601 void xorl_rm(RegisterID src
, int offset
, RegisterID base
)
603 m_formatter
.oneByteOp(OP_XOR_EvGv
, src
, base
, offset
);
606 void xorl_im(int imm
, int offset
, RegisterID base
)
608 if (CAN_SIGN_EXTEND_8_32(imm
)) {
609 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_XOR
, base
, offset
);
610 m_formatter
.immediate8(imm
);
612 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_XOR
, base
, offset
);
613 m_formatter
.immediate32(imm
);
617 void xorl_ir(int imm
, RegisterID dst
)
619 if (CAN_SIGN_EXTEND_8_32(imm
)) {
620 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_XOR
, dst
);
621 m_formatter
.immediate8(imm
);
623 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_XOR
, dst
);
624 m_formatter
.immediate32(imm
);
629 void xorq_rr(RegisterID src
, RegisterID dst
)
631 m_formatter
.oneByteOp64(OP_XOR_EvGv
, src
, dst
);
634 void xorq_ir(int imm
, RegisterID dst
)
636 if (CAN_SIGN_EXTEND_8_32(imm
)) {
637 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_XOR
, dst
);
638 m_formatter
.immediate8(imm
);
640 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_XOR
, dst
);
641 m_formatter
.immediate32(imm
);
645 void xorq_rm(RegisterID src
, int offset
, RegisterID base
)
647 m_formatter
.oneByteOp64(OP_XOR_EvGv
, src
, base
, offset
);
650 void rorq_i8r(int imm
, RegisterID dst
)
653 m_formatter
.oneByteOp64(OP_GROUP2_Ev1
, GROUP2_OP_ROR
, dst
);
655 m_formatter
.oneByteOp64(OP_GROUP2_EvIb
, GROUP2_OP_ROR
, dst
);
656 m_formatter
.immediate8(imm
);
662 void sarl_i8r(int imm
, RegisterID dst
)
665 m_formatter
.oneByteOp(OP_GROUP2_Ev1
, GROUP2_OP_SAR
, dst
);
667 m_formatter
.oneByteOp(OP_GROUP2_EvIb
, GROUP2_OP_SAR
, dst
);
668 m_formatter
.immediate8(imm
);
672 void sarl_CLr(RegisterID dst
)
674 m_formatter
.oneByteOp(OP_GROUP2_EvCL
, GROUP2_OP_SAR
, dst
);
677 void shrl_i8r(int imm
, RegisterID dst
)
680 m_formatter
.oneByteOp(OP_GROUP2_Ev1
, GROUP2_OP_SHR
, dst
);
682 m_formatter
.oneByteOp(OP_GROUP2_EvIb
, GROUP2_OP_SHR
, dst
);
683 m_formatter
.immediate8(imm
);
687 void shrl_CLr(RegisterID dst
)
689 m_formatter
.oneByteOp(OP_GROUP2_EvCL
, GROUP2_OP_SHR
, dst
);
692 void shll_i8r(int imm
, RegisterID dst
)
695 m_formatter
.oneByteOp(OP_GROUP2_Ev1
, GROUP2_OP_SHL
, dst
);
697 m_formatter
.oneByteOp(OP_GROUP2_EvIb
, GROUP2_OP_SHL
, dst
);
698 m_formatter
.immediate8(imm
);
702 void shll_CLr(RegisterID dst
)
704 m_formatter
.oneByteOp(OP_GROUP2_EvCL
, GROUP2_OP_SHL
, dst
);
708 void sarq_CLr(RegisterID dst
)
710 m_formatter
.oneByteOp64(OP_GROUP2_EvCL
, GROUP2_OP_SAR
, dst
);
713 void sarq_i8r(int imm
, RegisterID dst
)
716 m_formatter
.oneByteOp64(OP_GROUP2_Ev1
, GROUP2_OP_SAR
, dst
);
718 m_formatter
.oneByteOp64(OP_GROUP2_EvIb
, GROUP2_OP_SAR
, dst
);
719 m_formatter
.immediate8(imm
);
724 void imull_rr(RegisterID src
, RegisterID dst
)
726 m_formatter
.twoByteOp(OP2_IMUL_GvEv
, dst
, src
);
729 void imull_mr(int offset
, RegisterID base
, RegisterID dst
)
731 m_formatter
.twoByteOp(OP2_IMUL_GvEv
, dst
, base
, offset
);
734 void imull_i32r(RegisterID src
, int32_t value
, RegisterID dst
)
736 m_formatter
.oneByteOp(OP_IMUL_GvEvIz
, dst
, src
);
737 m_formatter
.immediate32(value
);
740 void idivl_r(RegisterID dst
)
742 m_formatter
.oneByteOp(OP_GROUP3_Ev
, GROUP3_OP_IDIV
, dst
);
747 void cmpl_rr(RegisterID src
, RegisterID dst
)
749 m_formatter
.oneByteOp(OP_CMP_EvGv
, src
, dst
);
752 void cmpl_rm(RegisterID src
, int offset
, RegisterID base
)
754 m_formatter
.oneByteOp(OP_CMP_EvGv
, src
, base
, offset
);
757 void cmpl_mr(int offset
, RegisterID base
, RegisterID src
)
759 m_formatter
.oneByteOp(OP_CMP_GvEv
, src
, base
, offset
);
762 void cmpl_ir(int imm
, RegisterID dst
)
764 if (CAN_SIGN_EXTEND_8_32(imm
)) {
765 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, dst
);
766 m_formatter
.immediate8(imm
);
768 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, dst
);
769 m_formatter
.immediate32(imm
);
773 void cmpl_ir_force32(int imm
, RegisterID dst
)
775 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, dst
);
776 m_formatter
.immediate32(imm
);
779 void cmpl_im(int imm
, int offset
, RegisterID base
)
781 if (CAN_SIGN_EXTEND_8_32(imm
)) {
782 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, base
, offset
);
783 m_formatter
.immediate8(imm
);
785 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, base
, offset
);
786 m_formatter
.immediate32(imm
);
790 void cmpb_im(int imm
, int offset
, RegisterID base
)
792 m_formatter
.oneByteOp(OP_GROUP1_EbIb
, GROUP1_OP_CMP
, base
, offset
);
793 m_formatter
.immediate8(imm
);
796 void cmpb_im(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
798 m_formatter
.oneByteOp(OP_GROUP1_EbIb
, GROUP1_OP_CMP
, base
, index
, scale
, offset
);
799 m_formatter
.immediate8(imm
);
802 void cmpl_im(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
804 if (CAN_SIGN_EXTEND_8_32(imm
)) {
805 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, base
, index
, scale
, offset
);
806 m_formatter
.immediate8(imm
);
808 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, base
, index
, scale
, offset
);
809 m_formatter
.immediate32(imm
);
813 void cmpl_im_force32(int imm
, int offset
, RegisterID base
)
815 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, base
, offset
);
816 m_formatter
.immediate32(imm
);
820 void cmpq_rr(RegisterID src
, RegisterID dst
)
822 m_formatter
.oneByteOp64(OP_CMP_EvGv
, src
, dst
);
825 void cmpq_rm(RegisterID src
, int offset
, RegisterID base
)
827 m_formatter
.oneByteOp64(OP_CMP_EvGv
, src
, base
, offset
);
830 void cmpq_mr(int offset
, RegisterID base
, RegisterID src
)
832 m_formatter
.oneByteOp64(OP_CMP_GvEv
, src
, base
, offset
);
835 void cmpq_ir(int imm
, RegisterID dst
)
837 if (CAN_SIGN_EXTEND_8_32(imm
)) {
838 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, dst
);
839 m_formatter
.immediate8(imm
);
841 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, dst
);
842 m_formatter
.immediate32(imm
);
846 void cmpq_im(int imm
, int offset
, RegisterID base
)
848 if (CAN_SIGN_EXTEND_8_32(imm
)) {
849 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, base
, offset
);
850 m_formatter
.immediate8(imm
);
852 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, base
, offset
);
853 m_formatter
.immediate32(imm
);
857 void cmpq_im(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
859 if (CAN_SIGN_EXTEND_8_32(imm
)) {
860 m_formatter
.oneByteOp64(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, base
, index
, scale
, offset
);
861 m_formatter
.immediate8(imm
);
863 m_formatter
.oneByteOp64(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, base
, index
, scale
, offset
);
864 m_formatter
.immediate32(imm
);
868 void cmpl_rm(RegisterID reg
, const void* addr
)
870 m_formatter
.oneByteOp(OP_CMP_EvGv
, reg
, addr
);
873 void cmpl_im(int imm
, const void* addr
)
875 if (CAN_SIGN_EXTEND_8_32(imm
)) {
876 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, addr
);
877 m_formatter
.immediate8(imm
);
879 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, addr
);
880 m_formatter
.immediate32(imm
);
885 void cmpw_ir(int imm
, RegisterID dst
)
887 if (CAN_SIGN_EXTEND_8_32(imm
)) {
888 m_formatter
.prefix(PRE_OPERAND_SIZE
);
889 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, dst
);
890 m_formatter
.immediate8(imm
);
892 m_formatter
.prefix(PRE_OPERAND_SIZE
);
893 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, dst
);
894 m_formatter
.immediate16(imm
);
898 void cmpw_rm(RegisterID src
, int offset
, RegisterID base
, RegisterID index
, int scale
)
900 m_formatter
.prefix(PRE_OPERAND_SIZE
);
901 m_formatter
.oneByteOp(OP_CMP_EvGv
, src
, base
, index
, scale
, offset
);
904 void cmpw_im(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
906 if (CAN_SIGN_EXTEND_8_32(imm
)) {
907 m_formatter
.prefix(PRE_OPERAND_SIZE
);
908 m_formatter
.oneByteOp(OP_GROUP1_EvIb
, GROUP1_OP_CMP
, base
, index
, scale
, offset
);
909 m_formatter
.immediate8(imm
);
911 m_formatter
.prefix(PRE_OPERAND_SIZE
);
912 m_formatter
.oneByteOp(OP_GROUP1_EvIz
, GROUP1_OP_CMP
, base
, index
, scale
, offset
);
913 m_formatter
.immediate16(imm
);
917 void testl_rr(RegisterID src
, RegisterID dst
)
919 m_formatter
.oneByteOp(OP_TEST_EvGv
, src
, dst
);
922 void testl_i32r(int imm
, RegisterID dst
)
924 m_formatter
.oneByteOp(OP_GROUP3_EvIz
, GROUP3_OP_TEST
, dst
);
925 m_formatter
.immediate32(imm
);
928 void testl_i32m(int imm
, int offset
, RegisterID base
)
930 m_formatter
.oneByteOp(OP_GROUP3_EvIz
, GROUP3_OP_TEST
, base
, offset
);
931 m_formatter
.immediate32(imm
);
934 void testb_rr(RegisterID src
, RegisterID dst
)
936 m_formatter
.oneByteOp8(OP_TEST_EbGb
, src
, dst
);
939 void testb_im(int imm
, int offset
, RegisterID base
)
941 m_formatter
.oneByteOp(OP_GROUP3_EbIb
, GROUP3_OP_TEST
, base
, offset
);
942 m_formatter
.immediate8(imm
);
945 void testb_im(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
947 m_formatter
.oneByteOp(OP_GROUP3_EbIb
, GROUP3_OP_TEST
, base
, index
, scale
, offset
);
948 m_formatter
.immediate8(imm
);
951 void testl_i32m(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
953 m_formatter
.oneByteOp(OP_GROUP3_EvIz
, GROUP3_OP_TEST
, base
, index
, scale
, offset
);
954 m_formatter
.immediate32(imm
);
958 void testq_rr(RegisterID src
, RegisterID dst
)
960 m_formatter
.oneByteOp64(OP_TEST_EvGv
, src
, dst
);
963 void testq_i32r(int imm
, RegisterID dst
)
965 m_formatter
.oneByteOp64(OP_GROUP3_EvIz
, GROUP3_OP_TEST
, dst
);
966 m_formatter
.immediate32(imm
);
969 void testq_i32m(int imm
, int offset
, RegisterID base
)
971 m_formatter
.oneByteOp64(OP_GROUP3_EvIz
, GROUP3_OP_TEST
, base
, offset
);
972 m_formatter
.immediate32(imm
);
975 void testq_i32m(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
977 m_formatter
.oneByteOp64(OP_GROUP3_EvIz
, GROUP3_OP_TEST
, base
, index
, scale
, offset
);
978 m_formatter
.immediate32(imm
);
982 void testw_rr(RegisterID src
, RegisterID dst
)
984 m_formatter
.prefix(PRE_OPERAND_SIZE
);
985 m_formatter
.oneByteOp(OP_TEST_EvGv
, src
, dst
);
988 void testb_i8r(int imm
, RegisterID dst
)
990 m_formatter
.oneByteOp8(OP_GROUP3_EbIb
, GROUP3_OP_TEST
, dst
);
991 m_formatter
.immediate8(imm
);
994 void setCC_r(Condition cond
, RegisterID dst
)
996 m_formatter
.twoByteOp8(setccOpcode(cond
), (GroupOpcodeID
)0, dst
);
999 void sete_r(RegisterID dst
)
1001 m_formatter
.twoByteOp8(setccOpcode(ConditionE
), (GroupOpcodeID
)0, dst
);
1004 void setz_r(RegisterID dst
)
1009 void setne_r(RegisterID dst
)
1011 m_formatter
.twoByteOp8(setccOpcode(ConditionNE
), (GroupOpcodeID
)0, dst
);
1014 void setnz_r(RegisterID dst
)
1019 // Various move ops:
1023 m_formatter
.oneByteOp(OP_CDQ
);
1026 void fstpl(int offset
, RegisterID base
)
1028 m_formatter
.oneByteOp(OP_ESCAPE_DD
, ESCAPE_DD_FSTP_doubleReal
, base
, offset
);
1031 void xchgl_rr(RegisterID src
, RegisterID dst
)
1033 m_formatter
.oneByteOp(OP_XCHG_EvGv
, src
, dst
);
1037 void xchgq_rr(RegisterID src
, RegisterID dst
)
1039 m_formatter
.oneByteOp64(OP_XCHG_EvGv
, src
, dst
);
1043 void movl_rr(RegisterID src
, RegisterID dst
)
1045 m_formatter
.oneByteOp(OP_MOV_EvGv
, src
, dst
);
1048 void movl_rm(RegisterID src
, int offset
, RegisterID base
)
1050 m_formatter
.oneByteOp(OP_MOV_EvGv
, src
, base
, offset
);
1053 void movl_rm_disp32(RegisterID src
, int offset
, RegisterID base
)
1055 m_formatter
.oneByteOp_disp32(OP_MOV_EvGv
, src
, base
, offset
);
1058 void movl_rm(RegisterID src
, int offset
, RegisterID base
, RegisterID index
, int scale
)
1060 m_formatter
.oneByteOp(OP_MOV_EvGv
, src
, base
, index
, scale
, offset
);
1063 void movl_mEAX(const void* addr
)
1065 m_formatter
.oneByteOp(OP_MOV_EAXOv
);
1067 m_formatter
.immediate64(reinterpret_cast<int64_t>(addr
));
1069 m_formatter
.immediate32(reinterpret_cast<int>(addr
));
1073 void movl_mr(int offset
, RegisterID base
, RegisterID dst
)
1075 m_formatter
.oneByteOp(OP_MOV_GvEv
, dst
, base
, offset
);
1078 void movl_mr_disp32(int offset
, RegisterID base
, RegisterID dst
)
1080 m_formatter
.oneByteOp_disp32(OP_MOV_GvEv
, dst
, base
, offset
);
1083 void movl_mr_disp8(int offset
, RegisterID base
, RegisterID dst
)
1085 m_formatter
.oneByteOp_disp8(OP_MOV_GvEv
, dst
, base
, offset
);
1088 void movl_mr(int offset
, RegisterID base
, RegisterID index
, int scale
, RegisterID dst
)
1090 m_formatter
.oneByteOp(OP_MOV_GvEv
, dst
, base
, index
, scale
, offset
);
1093 void movl_i32r(int imm
, RegisterID dst
)
1095 m_formatter
.oneByteOp(OP_MOV_EAXIv
, dst
);
1096 m_formatter
.immediate32(imm
);
1099 void movl_i32m(int imm
, int offset
, RegisterID base
)
1101 m_formatter
.oneByteOp(OP_GROUP11_EvIz
, GROUP11_MOV
, base
, offset
);
1102 m_formatter
.immediate32(imm
);
1105 void movl_i32m(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
1107 m_formatter
.oneByteOp(OP_GROUP11_EvIz
, GROUP11_MOV
, base
, index
, scale
, offset
);
1108 m_formatter
.immediate32(imm
);
1111 void movb_i8m(int imm
, int offset
, RegisterID base
)
1113 ASSERT(-128 <= imm
&& imm
< 128);
1114 m_formatter
.oneByteOp(OP_GROUP11_EvIb
, GROUP11_MOV
, base
, offset
);
1115 m_formatter
.immediate8(imm
);
1118 void movb_i8m(int imm
, int offset
, RegisterID base
, RegisterID index
, int scale
)
1120 ASSERT(-128 <= imm
&& imm
< 128);
1121 m_formatter
.oneByteOp(OP_GROUP11_EvIb
, GROUP11_MOV
, base
, index
, scale
, offset
);
1122 m_formatter
.immediate8(imm
);
1125 void movb_rm(RegisterID src
, int offset
, RegisterID base
, RegisterID index
, int scale
)
1127 m_formatter
.oneByteOp8(OP_MOV_EbGb
, src
, base
, index
, scale
, offset
);
1130 void movw_rm(RegisterID src
, int offset
, RegisterID base
, RegisterID index
, int scale
)
1132 m_formatter
.prefix(PRE_OPERAND_SIZE
);
1133 m_formatter
.oneByteOp8(OP_MOV_EvGv
, src
, base
, index
, scale
, offset
);
1136 void movl_EAXm(const void* addr
)
1138 m_formatter
.oneByteOp(OP_MOV_OvEAX
);
1140 m_formatter
.immediate64(reinterpret_cast<int64_t>(addr
));
1142 m_formatter
.immediate32(reinterpret_cast<int>(addr
));
1147 void movq_rr(RegisterID src
, RegisterID dst
)
1149 m_formatter
.oneByteOp64(OP_MOV_EvGv
, src
, dst
);
1152 void movq_rm(RegisterID src
, int offset
, RegisterID base
)
1154 m_formatter
.oneByteOp64(OP_MOV_EvGv
, src
, base
, offset
);
1157 void movq_rm_disp32(RegisterID src
, int offset
, RegisterID base
)
1159 m_formatter
.oneByteOp64_disp32(OP_MOV_EvGv
, src
, base
, offset
);
1162 void movq_rm(RegisterID src
, int offset
, RegisterID base
, RegisterID index
, int scale
)
1164 m_formatter
.oneByteOp64(OP_MOV_EvGv
, src
, base
, index
, scale
, offset
);
1167 void movq_mEAX(const void* addr
)
1169 m_formatter
.oneByteOp64(OP_MOV_EAXOv
);
1170 m_formatter
.immediate64(reinterpret_cast<int64_t>(addr
));
1173 void movq_EAXm(const void* addr
)
1175 m_formatter
.oneByteOp64(OP_MOV_OvEAX
);
1176 m_formatter
.immediate64(reinterpret_cast<int64_t>(addr
));
1179 void movq_mr(int offset
, RegisterID base
, RegisterID dst
)
1181 m_formatter
.oneByteOp64(OP_MOV_GvEv
, dst
, base
, offset
);
1184 void movq_mr_disp32(int offset
, RegisterID base
, RegisterID dst
)
1186 m_formatter
.oneByteOp64_disp32(OP_MOV_GvEv
, dst
, base
, offset
);
1189 void movq_mr_disp8(int offset
, RegisterID base
, RegisterID dst
)
1191 m_formatter
.oneByteOp64_disp8(OP_MOV_GvEv
, dst
, base
, offset
);
1194 void movq_mr(int offset
, RegisterID base
, RegisterID index
, int scale
, RegisterID dst
)
1196 m_formatter
.oneByteOp64(OP_MOV_GvEv
, dst
, base
, index
, scale
, offset
);
1199 void movq_i32m(int imm
, int offset
, RegisterID base
)
1201 m_formatter
.oneByteOp64(OP_GROUP11_EvIz
, GROUP11_MOV
, base
, offset
);
1202 m_formatter
.immediate32(imm
);
1205 void movq_i64r(int64_t imm
, RegisterID dst
)
1207 m_formatter
.oneByteOp64(OP_MOV_EAXIv
, dst
);
1208 m_formatter
.immediate64(imm
);
1211 void movsxd_rr(RegisterID src
, RegisterID dst
)
1213 m_formatter
.oneByteOp64(OP_MOVSXD_GvEv
, dst
, src
);
1218 void movl_rm(RegisterID src
, const void* addr
)
1220 if (src
== X86Registers::eax
)
1223 m_formatter
.oneByteOp(OP_MOV_EvGv
, src
, addr
);
1226 void movl_mr(const void* addr
, RegisterID dst
)
1228 if (dst
== X86Registers::eax
)
1231 m_formatter
.oneByteOp(OP_MOV_GvEv
, dst
, addr
);
1234 void movl_i32m(int imm
, const void* addr
)
1236 m_formatter
.oneByteOp(OP_GROUP11_EvIz
, GROUP11_MOV
, addr
);
1237 m_formatter
.immediate32(imm
);
1241 void movzwl_mr(int offset
, RegisterID base
, RegisterID dst
)
1243 m_formatter
.twoByteOp(OP2_MOVZX_GvEw
, dst
, base
, offset
);
1246 void movzwl_mr(int offset
, RegisterID base
, RegisterID index
, int scale
, RegisterID dst
)
1248 m_formatter
.twoByteOp(OP2_MOVZX_GvEw
, dst
, base
, index
, scale
, offset
);
1251 void movswl_mr(int offset
, RegisterID base
, RegisterID dst
)
1253 m_formatter
.twoByteOp(OP2_MOVSX_GvEw
, dst
, base
, offset
);
1256 void movswl_mr(int offset
, RegisterID base
, RegisterID index
, int scale
, RegisterID dst
)
1258 m_formatter
.twoByteOp(OP2_MOVSX_GvEw
, dst
, base
, index
, scale
, offset
);
1261 void movzbl_mr(int offset
, RegisterID base
, RegisterID dst
)
1263 m_formatter
.twoByteOp(OP2_MOVZX_GvEb
, dst
, base
, offset
);
1266 void movzbl_mr(int offset
, RegisterID base
, RegisterID index
, int scale
, RegisterID dst
)
1268 m_formatter
.twoByteOp(OP2_MOVZX_GvEb
, dst
, base
, index
, scale
, offset
);
1271 void movsbl_mr(int offset
, RegisterID base
, RegisterID dst
)
1273 m_formatter
.twoByteOp(OP2_MOVSX_GvEb
, dst
, base
, offset
);
1276 void movsbl_mr(int offset
, RegisterID base
, RegisterID index
, int scale
, RegisterID dst
)
1278 m_formatter
.twoByteOp(OP2_MOVSX_GvEb
, dst
, base
, index
, scale
, offset
);
1281 void movzbl_rr(RegisterID src
, RegisterID dst
)
1283 // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register
1284 // is in the range ESP-EDI, and the src would not have required a REX). Unneeded
1285 // REX prefixes are defined to be silently ignored by the processor.
1286 m_formatter
.twoByteOp8(OP2_MOVZX_GvEb
, dst
, src
);
1289 void leal_mr(int offset
, RegisterID base
, RegisterID dst
)
1291 m_formatter
.oneByteOp(OP_LEA
, dst
, base
, offset
);
1294 void leaq_mr(int offset
, RegisterID base
, RegisterID dst
)
1296 m_formatter
.oneByteOp64(OP_LEA
, dst
, base
, offset
);
1302 AssemblerLabel
call()
1304 m_formatter
.oneByteOp(OP_CALL_rel32
);
1305 return m_formatter
.immediateRel32();
1308 AssemblerLabel
call(RegisterID dst
)
1310 m_formatter
.oneByteOp(OP_GROUP5_Ev
, GROUP5_OP_CALLN
, dst
);
1311 return m_formatter
.label();
1314 void call_m(int offset
, RegisterID base
)
1316 m_formatter
.oneByteOp(OP_GROUP5_Ev
, GROUP5_OP_CALLN
, base
, offset
);
1319 AssemblerLabel
jmp()
1321 m_formatter
.oneByteOp(OP_JMP_rel32
);
1322 return m_formatter
.immediateRel32();
1325 // Return a AssemblerLabel so we have a label to the jump, so we can use this
1326 // To make a tail recursive call on x86-64. The MacroAssembler
1327 // really shouldn't wrap this as a Jump, since it can't be linked. :-/
1328 AssemblerLabel
jmp_r(RegisterID dst
)
1330 m_formatter
.oneByteOp(OP_GROUP5_Ev
, GROUP5_OP_JMPN
, dst
);
1331 return m_formatter
.label();
1334 void jmp_m(int offset
, RegisterID base
)
1336 m_formatter
.oneByteOp(OP_GROUP5_Ev
, GROUP5_OP_JMPN
, base
, offset
);
1340 void jmp_m(const void* address
)
1342 m_formatter
.oneByteOp(OP_GROUP5_Ev
, GROUP5_OP_JMPN
, address
);
1346 AssemblerLabel
jne()
1348 m_formatter
.twoByteOp(jccRel32(ConditionNE
));
1349 return m_formatter
.immediateRel32();
1352 AssemblerLabel
jnz()
1359 m_formatter
.twoByteOp(jccRel32(ConditionE
));
1360 return m_formatter
.immediateRel32();
1370 m_formatter
.twoByteOp(jccRel32(ConditionL
));
1371 return m_formatter
.immediateRel32();
1376 m_formatter
.twoByteOp(jccRel32(ConditionB
));
1377 return m_formatter
.immediateRel32();
1380 AssemblerLabel
jle()
1382 m_formatter
.twoByteOp(jccRel32(ConditionLE
));
1383 return m_formatter
.immediateRel32();
1386 AssemblerLabel
jbe()
1388 m_formatter
.twoByteOp(jccRel32(ConditionBE
));
1389 return m_formatter
.immediateRel32();
1392 AssemblerLabel
jge()
1394 m_formatter
.twoByteOp(jccRel32(ConditionGE
));
1395 return m_formatter
.immediateRel32();
1400 m_formatter
.twoByteOp(jccRel32(ConditionG
));
1401 return m_formatter
.immediateRel32();
1406 m_formatter
.twoByteOp(jccRel32(ConditionA
));
1407 return m_formatter
.immediateRel32();
1410 AssemblerLabel
jae()
1412 m_formatter
.twoByteOp(jccRel32(ConditionAE
));
1413 return m_formatter
.immediateRel32();
1418 m_formatter
.twoByteOp(jccRel32(ConditionO
));
1419 return m_formatter
.immediateRel32();
1424 m_formatter
.twoByteOp(jccRel32(ConditionP
));
1425 return m_formatter
.immediateRel32();
1430 m_formatter
.twoByteOp(jccRel32(ConditionS
));
1431 return m_formatter
.immediateRel32();
1434 AssemblerLabel
jCC(Condition cond
)
1436 m_formatter
.twoByteOp(jccRel32(cond
));
1437 return m_formatter
.immediateRel32();
1442 void addsd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1444 m_formatter
.prefix(PRE_SSE_F2
);
1445 m_formatter
.twoByteOp(OP2_ADDSD_VsdWsd
, (RegisterID
)dst
, (RegisterID
)src
);
1448 void addsd_mr(int offset
, RegisterID base
, XMMRegisterID dst
)
1450 m_formatter
.prefix(PRE_SSE_F2
);
1451 m_formatter
.twoByteOp(OP2_ADDSD_VsdWsd
, (RegisterID
)dst
, base
, offset
);
1455 void addsd_mr(const void* address
, XMMRegisterID dst
)
1457 m_formatter
.prefix(PRE_SSE_F2
);
1458 m_formatter
.twoByteOp(OP2_ADDSD_VsdWsd
, (RegisterID
)dst
, address
);
1462 void cvtsi2sd_rr(RegisterID src
, XMMRegisterID dst
)
1464 m_formatter
.prefix(PRE_SSE_F2
);
1465 m_formatter
.twoByteOp(OP2_CVTSI2SD_VsdEd
, (RegisterID
)dst
, src
);
1468 void cvtsi2sd_mr(int offset
, RegisterID base
, XMMRegisterID dst
)
1470 m_formatter
.prefix(PRE_SSE_F2
);
1471 m_formatter
.twoByteOp(OP2_CVTSI2SD_VsdEd
, (RegisterID
)dst
, base
, offset
);
1475 void cvtsi2sd_mr(const void* address
, XMMRegisterID dst
)
1477 m_formatter
.prefix(PRE_SSE_F2
);
1478 m_formatter
.twoByteOp(OP2_CVTSI2SD_VsdEd
, (RegisterID
)dst
, address
);
1482 void cvttsd2si_rr(XMMRegisterID src
, RegisterID dst
)
1484 m_formatter
.prefix(PRE_SSE_F2
);
1485 m_formatter
.twoByteOp(OP2_CVTTSD2SI_GdWsd
, dst
, (RegisterID
)src
);
1488 void cvtsd2ss_rr(XMMRegisterID src
, XMMRegisterID dst
)
1490 m_formatter
.prefix(PRE_SSE_F2
);
1491 m_formatter
.twoByteOp(OP2_CVTSD2SS_VsdWsd
, dst
, (RegisterID
)src
);
1494 void cvtss2sd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1496 m_formatter
.prefix(PRE_SSE_F3
);
1497 m_formatter
.twoByteOp(OP2_CVTSS2SD_VsdWsd
, dst
, (RegisterID
)src
);
1501 void cvttsd2siq_rr(XMMRegisterID src
, RegisterID dst
)
1503 m_formatter
.prefix(PRE_SSE_F2
);
1504 m_formatter
.twoByteOp64(OP2_CVTTSD2SI_GdWsd
, dst
, (RegisterID
)src
);
1508 void movd_rr(XMMRegisterID src
, RegisterID dst
)
1510 m_formatter
.prefix(PRE_SSE_66
);
1511 m_formatter
.twoByteOp(OP2_MOVD_EdVd
, (RegisterID
)src
, dst
);
1514 void movd_rr(RegisterID src
, XMMRegisterID dst
)
1516 m_formatter
.prefix(PRE_SSE_66
);
1517 m_formatter
.twoByteOp(OP2_MOVD_VdEd
, (RegisterID
)dst
, src
);
1521 void movq_rr(XMMRegisterID src
, RegisterID dst
)
1523 m_formatter
.prefix(PRE_SSE_66
);
1524 m_formatter
.twoByteOp64(OP2_MOVD_EdVd
, (RegisterID
)src
, dst
);
1527 void movq_rr(RegisterID src
, XMMRegisterID dst
)
1529 m_formatter
.prefix(PRE_SSE_66
);
1530 m_formatter
.twoByteOp64(OP2_MOVD_VdEd
, (RegisterID
)dst
, src
);
1534 void movsd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1536 m_formatter
.prefix(PRE_SSE_F2
);
1537 m_formatter
.twoByteOp(OP2_MOVSD_VsdWsd
, (RegisterID
)dst
, (RegisterID
)src
);
1540 void movsd_rm(XMMRegisterID src
, int offset
, RegisterID base
)
1542 m_formatter
.prefix(PRE_SSE_F2
);
1543 m_formatter
.twoByteOp(OP2_MOVSD_WsdVsd
, (RegisterID
)src
, base
, offset
);
1546 void movsd_rm(XMMRegisterID src
, int offset
, RegisterID base
, RegisterID index
, int scale
)
1548 m_formatter
.prefix(PRE_SSE_F2
);
1549 m_formatter
.twoByteOp(OP2_MOVSD_WsdVsd
, (RegisterID
)src
, base
, index
, scale
, offset
);
1552 void movss_rm(XMMRegisterID src
, int offset
, RegisterID base
, RegisterID index
, int scale
)
1554 m_formatter
.prefix(PRE_SSE_F3
);
1555 m_formatter
.twoByteOp(OP2_MOVSD_WsdVsd
, (RegisterID
)src
, base
, index
, scale
, offset
);
1558 void movsd_mr(int offset
, RegisterID base
, XMMRegisterID dst
)
1560 m_formatter
.prefix(PRE_SSE_F2
);
1561 m_formatter
.twoByteOp(OP2_MOVSD_VsdWsd
, (RegisterID
)dst
, base
, offset
);
1564 void movsd_mr(int offset
, RegisterID base
, RegisterID index
, int scale
, XMMRegisterID dst
)
1566 m_formatter
.prefix(PRE_SSE_F2
);
1567 m_formatter
.twoByteOp(OP2_MOVSD_VsdWsd
, dst
, base
, index
, scale
, offset
);
1570 void movss_mr(int offset
, RegisterID base
, RegisterID index
, int scale
, XMMRegisterID dst
)
1572 m_formatter
.prefix(PRE_SSE_F3
);
1573 m_formatter
.twoByteOp(OP2_MOVSD_VsdWsd
, dst
, base
, index
, scale
, offset
);
1577 void movsd_mr(const void* address
, XMMRegisterID dst
)
1579 m_formatter
.prefix(PRE_SSE_F2
);
1580 m_formatter
.twoByteOp(OP2_MOVSD_VsdWsd
, (RegisterID
)dst
, address
);
1582 void movsd_rm(XMMRegisterID src
, const void* address
)
1584 m_formatter
.prefix(PRE_SSE_F2
);
1585 m_formatter
.twoByteOp(OP2_MOVSD_WsdVsd
, (RegisterID
)src
, address
);
1589 void mulsd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1591 m_formatter
.prefix(PRE_SSE_F2
);
1592 m_formatter
.twoByteOp(OP2_MULSD_VsdWsd
, (RegisterID
)dst
, (RegisterID
)src
);
1595 void mulsd_mr(int offset
, RegisterID base
, XMMRegisterID dst
)
1597 m_formatter
.prefix(PRE_SSE_F2
);
1598 m_formatter
.twoByteOp(OP2_MULSD_VsdWsd
, (RegisterID
)dst
, base
, offset
);
1601 void pextrw_irr(int whichWord
, XMMRegisterID src
, RegisterID dst
)
1603 m_formatter
.prefix(PRE_SSE_66
);
1604 m_formatter
.twoByteOp(OP2_PEXTRW_GdUdIb
, (RegisterID
)dst
, (RegisterID
)src
);
1605 m_formatter
.immediate8(whichWord
);
1608 void psllq_i8r(int imm
, XMMRegisterID dst
)
1610 m_formatter
.prefix(PRE_SSE_66
);
1611 m_formatter
.twoByteOp8(OP2_PSLLQ_UdqIb
, GROUP14_OP_PSLLQ
, (RegisterID
)dst
);
1612 m_formatter
.immediate8(imm
);
1615 void psrlq_i8r(int imm
, XMMRegisterID dst
)
1617 m_formatter
.prefix(PRE_SSE_66
);
1618 m_formatter
.twoByteOp8(OP2_PSRLQ_UdqIb
, GROUP14_OP_PSRLQ
, (RegisterID
)dst
);
1619 m_formatter
.immediate8(imm
);
1622 void por_rr(XMMRegisterID src
, XMMRegisterID dst
)
1624 m_formatter
.prefix(PRE_SSE_66
);
1625 m_formatter
.twoByteOp(OP2_POR_VdqWdq
, (RegisterID
)dst
, (RegisterID
)src
);
1628 void subsd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1630 m_formatter
.prefix(PRE_SSE_F2
);
1631 m_formatter
.twoByteOp(OP2_SUBSD_VsdWsd
, (RegisterID
)dst
, (RegisterID
)src
);
1634 void subsd_mr(int offset
, RegisterID base
, XMMRegisterID dst
)
1636 m_formatter
.prefix(PRE_SSE_F2
);
1637 m_formatter
.twoByteOp(OP2_SUBSD_VsdWsd
, (RegisterID
)dst
, base
, offset
);
1640 void ucomisd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1642 m_formatter
.prefix(PRE_SSE_66
);
1643 m_formatter
.twoByteOp(OP2_UCOMISD_VsdWsd
, (RegisterID
)dst
, (RegisterID
)src
);
1646 void ucomisd_mr(int offset
, RegisterID base
, XMMRegisterID dst
)
1648 m_formatter
.prefix(PRE_SSE_66
);
1649 m_formatter
.twoByteOp(OP2_UCOMISD_VsdWsd
, (RegisterID
)dst
, base
, offset
);
1652 void divsd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1654 m_formatter
.prefix(PRE_SSE_F2
);
1655 m_formatter
.twoByteOp(OP2_DIVSD_VsdWsd
, (RegisterID
)dst
, (RegisterID
)src
);
1658 void divsd_mr(int offset
, RegisterID base
, XMMRegisterID dst
)
1660 m_formatter
.prefix(PRE_SSE_F2
);
1661 m_formatter
.twoByteOp(OP2_DIVSD_VsdWsd
, (RegisterID
)dst
, base
, offset
);
1664 void xorpd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1666 m_formatter
.prefix(PRE_SSE_66
);
1667 m_formatter
.twoByteOp(OP2_XORPD_VpdWpd
, (RegisterID
)dst
, (RegisterID
)src
);
1670 void andnpd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1672 m_formatter
.prefix(PRE_SSE_66
);
1673 m_formatter
.twoByteOp(OP2_ANDNPD_VpdWpd
, (RegisterID
)dst
, (RegisterID
)src
);
1676 void sqrtsd_rr(XMMRegisterID src
, XMMRegisterID dst
)
1678 m_formatter
.prefix(PRE_SSE_F2
);
1679 m_formatter
.twoByteOp(OP2_SQRTSD_VsdWsd
, (RegisterID
)dst
, (RegisterID
)src
);
1682 // Misc instructions:
1686 m_formatter
.oneByteOp(OP_INT3
);
1691 m_formatter
.oneByteOp(OP_RET
);
1694 void predictNotTaken()
1696 m_formatter
.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN
);
1699 // Assembler admin methods:
1701 size_t codeSize() const
1703 return m_formatter
.codeSize();
1706 AssemblerLabel
label()
1708 return m_formatter
.label();
1711 AssemblerLabel
align(int alignment
)
1713 while (!m_formatter
.isAligned(alignment
))
1714 m_formatter
.oneByteOp(OP_HLT
);
1719 // Linking & patching:
1721 // 'link' and 'patch' methods are for use on unprotected code - such as the code
1722 // within the AssemblerBuffer, and code being patched by the patch buffer. Once
1723 // code has been finalized it is (platform support permitting) within a non-
1724 // writable region of memory; to modify the code in an execute-only execuable
1725 // pool the 'repatch' and 'relink' methods should be used.
1727 void linkJump(AssemblerLabel from
, AssemblerLabel to
)
1729 ASSERT(from
.isSet());
1732 char* code
= reinterpret_cast<char*>(m_formatter
.data());
1733 ASSERT(!reinterpret_cast<int32_t*>(code
+ from
.m_offset
)[-1]);
1734 setRel32(code
+ from
.m_offset
, code
+ to
.m_offset
);
1737 static void linkJump(void* code
, AssemblerLabel from
, void* to
)
1739 ASSERT(from
.isSet());
1741 setRel32(reinterpret_cast<char*>(code
) + from
.m_offset
, to
);
1744 static void linkCall(void* code
, AssemblerLabel from
, void* to
)
1746 ASSERT(from
.isSet());
1748 setRel32(reinterpret_cast<char*>(code
) + from
.m_offset
, to
);
1751 static void linkPointer(void* code
, AssemblerLabel where
, void* value
)
1753 ASSERT(where
.isSet());
1755 setPointer(reinterpret_cast<char*>(code
) + where
.m_offset
, value
);
1758 static void relinkJump(void* from
, void* to
)
1763 static void relinkCall(void* from
, void* to
)
1768 static void repatchCompact(void* where
, int32_t value
)
1771 ASSERT(value
<= std::numeric_limits
<int8_t>::max());
1772 setInt8(where
, value
);
1775 static void repatchInt32(void* where
, int32_t value
)
1777 setInt32(where
, value
);
1780 static void repatchPointer(void* where
, void* value
)
1782 setPointer(where
, value
);
1785 static void* readPointer(void* where
)
1787 return reinterpret_cast<void**>(where
)[-1];
1790 static unsigned getCallReturnOffset(AssemblerLabel call
)
1792 ASSERT(call
.isSet());
1793 return call
.m_offset
;
1796 static void* getRelocatedAddress(void* code
, AssemblerLabel label
)
1798 ASSERT(label
.isSet());
1799 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code
) + label
.m_offset
);
1802 static int getDifferenceBetweenLabels(AssemblerLabel a
, AssemblerLabel b
)
1804 return b
.m_offset
- a
.m_offset
;
1807 PassRefPtr
<ExecutableMemoryHandle
> executableCopy(JSGlobalData
& globalData
, void* ownerUID
, JITCompilationEffort effort
)
1809 return m_formatter
.executableCopy(globalData
, ownerUID
, effort
);
1812 unsigned debugOffset() { return m_formatter
.debugOffset(); }
1816 m_formatter
.oneByteOp(OP_NOP
);
1819 // This is a no-op on x86
1820 ALWAYS_INLINE
static void cacheFlush(void*, size_t) { }
1824 static void setPointer(void* where
, void* value
)
1826 reinterpret_cast<void**>(where
)[-1] = value
;
1829 static void setInt32(void* where
, int32_t value
)
1831 reinterpret_cast<int32_t*>(where
)[-1] = value
;
1834 static void setInt8(void* where
, int8_t value
)
1836 reinterpret_cast<int8_t*>(where
)[-1] = value
;
1839 static void setRel32(void* from
, void* to
)
1841 intptr_t offset
= reinterpret_cast<intptr_t>(to
) - reinterpret_cast<intptr_t>(from
);
1842 ASSERT(offset
== static_cast<int32_t>(offset
));
1844 setInt32(from
, offset
);
1847 class X86InstructionFormatter
{
1849 static const int maxInstructionSize
= 16;
1853 // Legacy prefix bytes:
1855 // These are emmitted prior to the instruction.
1857 void prefix(OneByteOpcodeID pre
)
1859 m_buffer
.putByte(pre
);
1862 // Word-sized operands / no operand instruction formatters.
1864 // In addition to the opcode, the following operand permutations are supported:
1865 // * None - instruction takes no operands.
1866 // * One register - the low three bits of the RegisterID are added into the opcode.
1867 // * 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).
1868 // * Three argument ModRM - a register, and a register and an offset describing a memory operand.
1869 // * Five argument ModRM - a register, and a base register, an index, scale, and offset describing a memory operand.
1871 // For 32-bit x86 targets, the address operand may also be provided as a void*.
1872 // On 64-bit targets REX prefixes will be planted as necessary, where high numbered registers are used.
1874 // The twoByteOp methods plant two-byte Intel instructions sequences (first opcode byte 0x0F).
1876 void oneByteOp(OneByteOpcodeID opcode
)
1878 m_buffer
.ensureSpace(maxInstructionSize
);
1879 m_buffer
.putByteUnchecked(opcode
);
1882 void oneByteOp(OneByteOpcodeID opcode
, RegisterID reg
)
1884 m_buffer
.ensureSpace(maxInstructionSize
);
1885 emitRexIfNeeded(0, 0, reg
);
1886 m_buffer
.putByteUnchecked(opcode
+ (reg
& 7));
1889 void oneByteOp(OneByteOpcodeID opcode
, int reg
, RegisterID rm
)
1891 m_buffer
.ensureSpace(maxInstructionSize
);
1892 emitRexIfNeeded(reg
, 0, rm
);
1893 m_buffer
.putByteUnchecked(opcode
);
1894 registerModRM(reg
, rm
);
1897 void oneByteOp(OneByteOpcodeID opcode
, int reg
, RegisterID base
, int offset
)
1899 m_buffer
.ensureSpace(maxInstructionSize
);
1900 emitRexIfNeeded(reg
, 0, base
);
1901 m_buffer
.putByteUnchecked(opcode
);
1902 memoryModRM(reg
, base
, offset
);
1905 void oneByteOp_disp32(OneByteOpcodeID opcode
, int reg
, RegisterID base
, int offset
)
1907 m_buffer
.ensureSpace(maxInstructionSize
);
1908 emitRexIfNeeded(reg
, 0, base
);
1909 m_buffer
.putByteUnchecked(opcode
);
1910 memoryModRM_disp32(reg
, base
, offset
);
1913 void oneByteOp_disp8(OneByteOpcodeID opcode
, int reg
, RegisterID base
, int offset
)
1915 m_buffer
.ensureSpace(maxInstructionSize
);
1916 emitRexIfNeeded(reg
, 0, base
);
1917 m_buffer
.putByteUnchecked(opcode
);
1918 memoryModRM_disp8(reg
, base
, offset
);
1921 void oneByteOp(OneByteOpcodeID opcode
, int reg
, RegisterID base
, RegisterID index
, int scale
, int offset
)
1923 m_buffer
.ensureSpace(maxInstructionSize
);
1924 emitRexIfNeeded(reg
, index
, base
);
1925 m_buffer
.putByteUnchecked(opcode
);
1926 memoryModRM(reg
, base
, index
, scale
, offset
);
1930 void oneByteOp(OneByteOpcodeID opcode
, int reg
, const void* address
)
1932 m_buffer
.ensureSpace(maxInstructionSize
);
1933 m_buffer
.putByteUnchecked(opcode
);
1934 memoryModRM(reg
, address
);
1938 void twoByteOp(TwoByteOpcodeID opcode
)
1940 m_buffer
.ensureSpace(maxInstructionSize
);
1941 m_buffer
.putByteUnchecked(OP_2BYTE_ESCAPE
);
1942 m_buffer
.putByteUnchecked(opcode
);
1945 void twoByteOp(TwoByteOpcodeID opcode
, int reg
, RegisterID rm
)
1947 m_buffer
.ensureSpace(maxInstructionSize
);
1948 emitRexIfNeeded(reg
, 0, rm
);
1949 m_buffer
.putByteUnchecked(OP_2BYTE_ESCAPE
);
1950 m_buffer
.putByteUnchecked(opcode
);
1951 registerModRM(reg
, rm
);
1954 void twoByteOp(TwoByteOpcodeID opcode
, int reg
, RegisterID base
, int offset
)
1956 m_buffer
.ensureSpace(maxInstructionSize
);
1957 emitRexIfNeeded(reg
, 0, base
);
1958 m_buffer
.putByteUnchecked(OP_2BYTE_ESCAPE
);
1959 m_buffer
.putByteUnchecked(opcode
);
1960 memoryModRM(reg
, base
, offset
);
1963 void twoByteOp(TwoByteOpcodeID opcode
, int reg
, RegisterID base
, RegisterID index
, int scale
, int offset
)
1965 m_buffer
.ensureSpace(maxInstructionSize
);
1966 emitRexIfNeeded(reg
, index
, base
);
1967 m_buffer
.putByteUnchecked(OP_2BYTE_ESCAPE
);
1968 m_buffer
.putByteUnchecked(opcode
);
1969 memoryModRM(reg
, base
, index
, scale
, offset
);
1973 void twoByteOp(TwoByteOpcodeID opcode
, int reg
, const void* address
)
1975 m_buffer
.ensureSpace(maxInstructionSize
);
1976 m_buffer
.putByteUnchecked(OP_2BYTE_ESCAPE
);
1977 m_buffer
.putByteUnchecked(opcode
);
1978 memoryModRM(reg
, address
);
1983 // Quad-word-sized operands:
1985 // Used to format 64-bit operantions, planting a REX.w prefix.
1986 // When planting d64 or f64 instructions, not requiring a REX.w prefix,
1987 // the normal (non-'64'-postfixed) formatters should be used.
1989 void oneByteOp64(OneByteOpcodeID opcode
)
1991 m_buffer
.ensureSpace(maxInstructionSize
);
1993 m_buffer
.putByteUnchecked(opcode
);
1996 void oneByteOp64(OneByteOpcodeID opcode
, RegisterID reg
)
1998 m_buffer
.ensureSpace(maxInstructionSize
);
1999 emitRexW(0, 0, reg
);
2000 m_buffer
.putByteUnchecked(opcode
+ (reg
& 7));
2003 void oneByteOp64(OneByteOpcodeID opcode
, int reg
, RegisterID rm
)
2005 m_buffer
.ensureSpace(maxInstructionSize
);
2006 emitRexW(reg
, 0, rm
);
2007 m_buffer
.putByteUnchecked(opcode
);
2008 registerModRM(reg
, rm
);
2011 void oneByteOp64(OneByteOpcodeID opcode
, int reg
, RegisterID base
, int offset
)
2013 m_buffer
.ensureSpace(maxInstructionSize
);
2014 emitRexW(reg
, 0, base
);
2015 m_buffer
.putByteUnchecked(opcode
);
2016 memoryModRM(reg
, base
, offset
);
2019 void oneByteOp64_disp32(OneByteOpcodeID opcode
, int reg
, RegisterID base
, int offset
)
2021 m_buffer
.ensureSpace(maxInstructionSize
);
2022 emitRexW(reg
, 0, base
);
2023 m_buffer
.putByteUnchecked(opcode
);
2024 memoryModRM_disp32(reg
, base
, offset
);
2027 void oneByteOp64_disp8(OneByteOpcodeID opcode
, int reg
, RegisterID base
, int offset
)
2029 m_buffer
.ensureSpace(maxInstructionSize
);
2030 emitRexW(reg
, 0, base
);
2031 m_buffer
.putByteUnchecked(opcode
);
2032 memoryModRM_disp8(reg
, base
, offset
);
2035 void oneByteOp64(OneByteOpcodeID opcode
, int reg
, RegisterID base
, RegisterID index
, int scale
, int offset
)
2037 m_buffer
.ensureSpace(maxInstructionSize
);
2038 emitRexW(reg
, index
, base
);
2039 m_buffer
.putByteUnchecked(opcode
);
2040 memoryModRM(reg
, base
, index
, scale
, offset
);
2043 void twoByteOp64(TwoByteOpcodeID opcode
, int reg
, RegisterID rm
)
2045 m_buffer
.ensureSpace(maxInstructionSize
);
2046 emitRexW(reg
, 0, rm
);
2047 m_buffer
.putByteUnchecked(OP_2BYTE_ESCAPE
);
2048 m_buffer
.putByteUnchecked(opcode
);
2049 registerModRM(reg
, rm
);
2055 // These methods format byte operations. Byte operations differ from the normal
2056 // formatters in the circumstances under which they will decide to emit REX prefixes.
2057 // These should be used where any register operand signifies a byte register.
2059 // The disctinction is due to the handling of register numbers in the range 4..7 on
2060 // x86-64. These register numbers may either represent the second byte of the first
2061 // four registers (ah..bh) or the first byte of the second four registers (spl..dil).
2063 // Since ah..bh cannot be used in all permutations of operands (specifically cannot
2064 // be accessed where a REX prefix is present), these are likely best treated as
2065 // deprecated. In order to ensure the correct registers spl..dil are selected a
2066 // REX prefix will be emitted for any byte register operand in the range 4..15.
2068 // These formatters may be used in instructions where a mix of operand sizes, in which
2069 // case an unnecessary REX will be emitted, for example:
2071 // In this case a REX will be planted since edi is 7 (and were this a byte operand
2072 // a REX would be required to specify dil instead of bh). Unneeded REX prefixes will
2073 // be silently ignored by the processor.
2075 // Address operands should still be checked using regRequiresRex(), while byteRegRequiresRex()
2076 // is provided to check byte register operands.
2078 void oneByteOp8(OneByteOpcodeID opcode
, GroupOpcodeID groupOp
, RegisterID rm
)
2080 m_buffer
.ensureSpace(maxInstructionSize
);
2081 emitRexIf(byteRegRequiresRex(rm
), 0, 0, rm
);
2082 m_buffer
.putByteUnchecked(opcode
);
2083 registerModRM(groupOp
, rm
);
2086 void oneByteOp8(OneByteOpcodeID opcode
, int reg
, RegisterID rm
)
2088 m_buffer
.ensureSpace(maxInstructionSize
);
2089 emitRexIf(byteRegRequiresRex(reg
) || byteRegRequiresRex(rm
), reg
, 0, rm
);
2090 m_buffer
.putByteUnchecked(opcode
);
2091 registerModRM(reg
, rm
);
2094 void oneByteOp8(OneByteOpcodeID opcode
, int reg
, RegisterID base
, RegisterID index
, int scale
, int offset
)
2096 m_buffer
.ensureSpace(maxInstructionSize
);
2097 emitRexIf(byteRegRequiresRex(reg
) || regRequiresRex(index
) || regRequiresRex(base
), reg
, index
, base
);
2098 m_buffer
.putByteUnchecked(opcode
);
2099 memoryModRM(reg
, base
, index
, scale
, offset
);
2102 void twoByteOp8(TwoByteOpcodeID opcode
, RegisterID reg
, RegisterID rm
)
2104 m_buffer
.ensureSpace(maxInstructionSize
);
2105 emitRexIf(byteRegRequiresRex(reg
)|byteRegRequiresRex(rm
), reg
, 0, rm
);
2106 m_buffer
.putByteUnchecked(OP_2BYTE_ESCAPE
);
2107 m_buffer
.putByteUnchecked(opcode
);
2108 registerModRM(reg
, rm
);
2111 void twoByteOp8(TwoByteOpcodeID opcode
, GroupOpcodeID groupOp
, RegisterID rm
)
2113 m_buffer
.ensureSpace(maxInstructionSize
);
2114 emitRexIf(byteRegRequiresRex(rm
), 0, 0, rm
);
2115 m_buffer
.putByteUnchecked(OP_2BYTE_ESCAPE
);
2116 m_buffer
.putByteUnchecked(opcode
);
2117 registerModRM(groupOp
, rm
);
2122 // An immedaite should be appended where appropriate after an op has been emitted.
2123 // The writes are unchecked since the opcode formatters above will have ensured space.
2125 void immediate8(int imm
)
2127 m_buffer
.putByteUnchecked(imm
);
2130 void immediate16(int imm
)
2132 m_buffer
.putShortUnchecked(imm
);
2135 void immediate32(int imm
)
2137 m_buffer
.putIntUnchecked(imm
);
2140 void immediate64(int64_t imm
)
2142 m_buffer
.putInt64Unchecked(imm
);
2145 AssemblerLabel
immediateRel32()
2147 m_buffer
.putIntUnchecked(0);
2151 // Administrative methods:
2153 size_t codeSize() const { return m_buffer
.codeSize(); }
2154 AssemblerLabel
label() const { return m_buffer
.label(); }
2155 bool isAligned(int alignment
) const { return m_buffer
.isAligned(alignment
); }
2156 void* data() const { return m_buffer
.data(); }
2158 PassRefPtr
<ExecutableMemoryHandle
> executableCopy(JSGlobalData
& globalData
, void* ownerUID
, JITCompilationEffort effort
)
2160 return m_buffer
.executableCopy(globalData
, ownerUID
, effort
);
2163 unsigned debugOffset() { return m_buffer
.debugOffset(); }
2167 // Internals; ModRm and REX formatters.
2169 static const RegisterID noBase
= X86Registers::ebp
;
2170 static const RegisterID hasSib
= X86Registers::esp
;
2171 static const RegisterID noIndex
= X86Registers::esp
;
2173 static const RegisterID noBase2
= X86Registers::r13
;
2174 static const RegisterID hasSib2
= X86Registers::r12
;
2176 // Registers r8 & above require a REX prefixe.
2177 inline bool regRequiresRex(int reg
)
2179 return (reg
>= X86Registers::r8
);
2182 // Byte operand register spl & above require a REX prefix (to prevent the 'H' registers be accessed).
2183 inline bool byteRegRequiresRex(int reg
)
2185 return (reg
>= X86Registers::esp
);
2188 // Format a REX prefix byte.
2189 inline void emitRex(bool w
, int r
, int x
, int b
)
2191 m_buffer
.putByteUnchecked(PRE_REX
| ((int)w
<< 3) | ((r
>>3)<<2) | ((x
>>3)<<1) | (b
>>3));
2194 // Used to plant a REX byte with REX.w set (for 64-bit operations).
2195 inline void emitRexW(int r
, int x
, int b
)
2197 emitRex(true, r
, x
, b
);
2200 // Used for operations with byte operands - use byteRegRequiresRex() to check register operands,
2201 // regRequiresRex() to check other registers (i.e. address base & index).
2202 inline void emitRexIf(bool condition
, int r
, int x
, int b
)
2204 if (condition
) emitRex(false, r
, x
, b
);
2207 // Used for word sized operations, will plant a REX prefix if necessary (if any register is r8 or above).
2208 inline void emitRexIfNeeded(int r
, int x
, int b
)
2210 emitRexIf(regRequiresRex(r
) || regRequiresRex(x
) || regRequiresRex(b
), r
, x
, b
);
2213 // No REX prefix bytes on 32-bit x86.
2214 inline bool regRequiresRex(int) { return false; }
2215 inline bool byteRegRequiresRex(int) { return false; }
2216 inline void emitRexIf(bool, int, int, int) {}
2217 inline void emitRexIfNeeded(int, int, int) {}
2227 void putModRm(ModRmMode mode
, int reg
, RegisterID rm
)
2229 m_buffer
.putByteUnchecked((mode
<< 6) | ((reg
& 7) << 3) | (rm
& 7));
2232 void putModRmSib(ModRmMode mode
, int reg
, RegisterID base
, RegisterID index
, int scale
)
2234 ASSERT(mode
!= ModRmRegister
);
2236 putModRm(mode
, reg
, hasSib
);
2237 m_buffer
.putByteUnchecked((scale
<< 6) | ((index
& 7) << 3) | (base
& 7));
2240 void registerModRM(int reg
, RegisterID rm
)
2242 putModRm(ModRmRegister
, reg
, rm
);
2245 void memoryModRM(int reg
, RegisterID base
, int offset
)
2247 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2249 if ((base
== hasSib
) || (base
== hasSib2
)) {
2251 if (base
== hasSib
) {
2253 if (!offset
) // No need to check if the base is noBase, since we know it is hasSib!
2254 putModRmSib(ModRmMemoryNoDisp
, reg
, base
, noIndex
, 0);
2255 else if (CAN_SIGN_EXTEND_8_32(offset
)) {
2256 putModRmSib(ModRmMemoryDisp8
, reg
, base
, noIndex
, 0);
2257 m_buffer
.putByteUnchecked(offset
);
2259 putModRmSib(ModRmMemoryDisp32
, reg
, base
, noIndex
, 0);
2260 m_buffer
.putIntUnchecked(offset
);
2264 if (!offset
&& (base
!= noBase
) && (base
!= noBase2
))
2266 if (!offset
&& (base
!= noBase
))
2268 putModRm(ModRmMemoryNoDisp
, reg
, base
);
2269 else if (CAN_SIGN_EXTEND_8_32(offset
)) {
2270 putModRm(ModRmMemoryDisp8
, reg
, base
);
2271 m_buffer
.putByteUnchecked(offset
);
2273 putModRm(ModRmMemoryDisp32
, reg
, base
);
2274 m_buffer
.putIntUnchecked(offset
);
2279 void memoryModRM_disp8(int reg
, RegisterID base
, int offset
)
2281 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2282 ASSERT(CAN_SIGN_EXTEND_8_32(offset
));
2284 if ((base
== hasSib
) || (base
== hasSib2
)) {
2286 if (base
== hasSib
) {
2288 putModRmSib(ModRmMemoryDisp8
, reg
, base
, noIndex
, 0);
2289 m_buffer
.putByteUnchecked(offset
);
2291 putModRm(ModRmMemoryDisp8
, reg
, base
);
2292 m_buffer
.putByteUnchecked(offset
);
2296 void memoryModRM_disp32(int reg
, RegisterID base
, int offset
)
2298 // A base of esp or r12 would be interpreted as a sib, so force a sib with no index & put the base in there.
2300 if ((base
== hasSib
) || (base
== hasSib2
)) {
2302 if (base
== hasSib
) {
2304 putModRmSib(ModRmMemoryDisp32
, reg
, base
, noIndex
, 0);
2305 m_buffer
.putIntUnchecked(offset
);
2307 putModRm(ModRmMemoryDisp32
, reg
, base
);
2308 m_buffer
.putIntUnchecked(offset
);
2312 void memoryModRM(int reg
, RegisterID base
, RegisterID index
, int scale
, int offset
)
2314 ASSERT(index
!= noIndex
);
2317 if (!offset
&& (base
!= noBase
) && (base
!= noBase2
))
2319 if (!offset
&& (base
!= noBase
))
2321 putModRmSib(ModRmMemoryNoDisp
, reg
, base
, index
, scale
);
2322 else if (CAN_SIGN_EXTEND_8_32(offset
)) {
2323 putModRmSib(ModRmMemoryDisp8
, reg
, base
, index
, scale
);
2324 m_buffer
.putByteUnchecked(offset
);
2326 putModRmSib(ModRmMemoryDisp32
, reg
, base
, index
, scale
);
2327 m_buffer
.putIntUnchecked(offset
);
2332 void memoryModRM(int reg
, const void* address
)
2334 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
2335 putModRm(ModRmMemoryNoDisp
, reg
, noBase
);
2336 m_buffer
.putIntUnchecked(reinterpret_cast<int32_t>(address
));
2340 AssemblerBuffer m_buffer
;
2346 #endif // ENABLE(ASSEMBLER) && CPU(X86)
2348 #endif // X86Assembler_h