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(MASM) && PLATFORM(X86)
31 #include <wtf/Assertions.h>
32 #include <wtf/AlwaysInline.h>
43 JITCodeBuffer(int size)
44 : m_buffer(static_cast<char*>(fastMalloc(size)))
55 void ensureSpace(int space)
57 if (m_index > m_size - space)
61 void putByteUnchecked(int value)
63 m_buffer[m_index] = value;
67 void putByte(int value)
69 if (m_index > m_size - 4)
71 putByteUnchecked(value);
74 void putShortUnchecked(int value)
76 *(short*)(&m_buffer[m_index]) = value;
80 void putShort(int value)
82 if (m_index > m_size - 4)
84 putShortUnchecked(value);
87 void putIntUnchecked(int value)
89 *reinterpret_cast<int*>(&m_buffer[m_index]) = value;
93 void putInt(int value)
95 if (m_index > m_size - 4)
97 putIntUnchecked(value);
102 return m_buffer + m_index;
115 JITCodeBuffer* reset()
126 void* result = fastMalloc(m_index);
131 return memcpy(result, m_buffer, m_index);
137 m_size += m_size / 2;
138 m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_size));
146 #define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm))
147 #define SIB(type, reg, rm) MODRM(type, reg, rm)
148 #define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value))
180 typedef X86::RegisterID RegisterID;
181 typedef X86::XMMRegisterID XMMRegisterID;
187 OP_2BYTE_ESCAPE = 0x0F,
191 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
197 PRE_OPERAND_SIZE = 0x66,
199 OP_IMUL_GvEvIz = 0x69,
200 OP_GROUP1_EvIz = 0x81,
201 OP_GROUP1_EvIb = 0x83,
206 OP_GROUP1A_Ev = 0x8F,
210 OP_GROUP2_EvIb = 0xC1,
212 OP_GROUP11_EvIz = 0xC7,
214 OP_GROUP2_Ev1 = 0xD1,
215 OP_GROUP2_EvCL = 0xD3,
216 OP_CALL_rel32 = 0xE8,
220 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
223 OP2_MOVSD_VsdWsd = 0x10,
224 OP2_MOVSD_WsdVsd = 0x11,
225 OP2_CVTSI2SD_VsdEd = 0x2A,
226 OP2_CVTTSD2SI_GdWsd = 0x2C,
227 OP2_UCOMISD_VsdWsd = 0x2E,
228 OP2_ADDSD_VsdWsd = 0x58,
229 OP2_MULSD_VsdWsd = 0x59,
230 OP2_SUBSD_VsdWsd = 0x5C,
231 OP2_MOVD_EdVd = 0x7E,
234 OP2_JAE_rel32 = 0x83,
236 OP2_JNE_rel32 = 0x85,
237 OP2_JBE_rel32 = 0x86,
242 OP2_JGE_rel32 = 0x8D,
243 OP2_JLE_rel32 = 0x8E,
245 OP2_IMUL_GvEv = 0xAF,
246 OP2_MOVZX_GvEb = 0xB6,
247 OP2_MOVZX_GvEw = 0xB7,
248 OP2_PEXTRW_GdUdIb = 0xC5,
272 static const int MAX_INSTRUCTION_SIZE = 16;
274 X86Assembler(JITCodeBuffer* m_buffer)
282 m_buffer->putByte(OP_INT3);
285 void pushl_r(RegisterID reg)
287 m_buffer->putByte(OP_PUSH_EAX + reg);
290 void pushl_m(int offset, RegisterID base)
292 m_buffer->putByte(OP_GROUP5_Ev);
293 emitModRm_opm(GROUP5_OP_PUSH, base, offset);
296 void popl_r(RegisterID reg)
298 m_buffer->putByte(OP_POP_EAX + reg);
301 void popl_m(int offset, RegisterID base)
303 m_buffer->putByte(OP_GROUP1A_Ev);
304 emitModRm_opm(GROUP1A_OP_POP, base, offset);
307 void movl_rr(RegisterID src, RegisterID dst)
309 m_buffer->putByte(OP_MOV_EvGv);
310 emitModRm_rr(src, dst);
313 void addl_rr(RegisterID src, RegisterID dst)
315 m_buffer->putByte(OP_ADD_EvGv);
316 emitModRm_rr(src, dst);
319 void addl_i8r(int imm, RegisterID dst)
321 m_buffer->putByte(OP_GROUP1_EvIb);
322 emitModRm_opr(GROUP1_OP_ADD, dst);
323 m_buffer->putByte(imm);
326 void addl_i8m(int imm, void* addr)
328 m_buffer->putByte(OP_GROUP1_EvIb);
329 emitModRm_opm(GROUP1_OP_ADD, addr);
330 m_buffer->putByte(imm);
333 void addl_i32r(int imm, RegisterID dst)
335 m_buffer->putByte(OP_GROUP1_EvIz);
336 emitModRm_opr(GROUP1_OP_ADD, dst);
337 m_buffer->putInt(imm);
340 void addl_mr(int offset, RegisterID base, RegisterID dst)
342 m_buffer->putByte(OP_ADD_GvEv);
343 emitModRm_rm(dst, base, offset);
346 void andl_rr(RegisterID src, RegisterID dst)
348 m_buffer->putByte(OP_AND_EvGv);
349 emitModRm_rr(src, dst);
352 void andl_i32r(int imm, RegisterID dst)
354 m_buffer->putByte(OP_GROUP1_EvIz);
355 emitModRm_opr(GROUP1_OP_AND, dst);
356 m_buffer->putInt(imm);
359 void cmpl_i8r(int imm, RegisterID dst)
361 m_buffer->putByte(OP_GROUP1_EvIb);
362 emitModRm_opr(GROUP1_OP_CMP, dst);
363 m_buffer->putByte(imm);
366 void cmpl_rr(RegisterID src, RegisterID dst)
368 m_buffer->putByte(OP_CMP_EvGv);
369 emitModRm_rr(src, dst);
372 void cmpl_rm(RegisterID src, int offset, RegisterID base)
374 m_buffer->putByte(OP_CMP_EvGv);
375 emitModRm_rm(src, base, offset);
378 void cmpl_mr(int offset, RegisterID base, RegisterID dst)
380 m_buffer->putByte(OP_CMP_GvEv);
381 emitModRm_rm(dst, base, offset);
384 void cmpl_i32r(int imm, RegisterID dst)
386 m_buffer->putByte(OP_GROUP1_EvIz);
387 emitModRm_opr(GROUP1_OP_CMP, dst);
388 m_buffer->putInt(imm);
391 void cmpl_i32m(int imm, RegisterID dst)
393 m_buffer->putByte(OP_GROUP1_EvIz);
394 emitModRm_opm(GROUP1_OP_CMP, dst);
395 m_buffer->putInt(imm);
398 void cmpl_i32m(int imm, int offset, RegisterID dst)
400 m_buffer->putByte(OP_GROUP1_EvIz);
401 emitModRm_opm(GROUP1_OP_CMP, dst, offset);
402 m_buffer->putInt(imm);
405 void cmpl_i32m(int imm, void* addr)
407 m_buffer->putByte(OP_GROUP1_EvIz);
408 emitModRm_opm(GROUP1_OP_CMP, addr);
409 m_buffer->putInt(imm);
412 void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
414 m_buffer->putByte(OP_GROUP1_EvIb);
415 emitModRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset);
416 m_buffer->putByte(imm);
419 void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
421 m_buffer->putByte(PRE_OPERAND_SIZE);
422 m_buffer->putByte(OP_CMP_EvGv);
423 emitModRm_rmsib(src, base, index, scale);
426 void sete_r(RegisterID dst)
428 m_buffer->putByte(OP_2BYTE_ESCAPE);
429 m_buffer->putByte(OP_SETE);
430 m_buffer->putByte(MODRM(3, 0, dst));
433 void setz_r(RegisterID dst)
438 void setne_r(RegisterID dst)
440 m_buffer->putByte(OP_2BYTE_ESCAPE);
441 m_buffer->putByte(OP_SETNE);
442 m_buffer->putByte(MODRM(3, 0, dst));
445 void setnz_r(RegisterID dst)
450 void orl_rr(RegisterID src, RegisterID dst)
452 m_buffer->putByte(OP_OR_EvGv);
453 emitModRm_rr(src, dst);
456 void orl_mr(int offset, RegisterID base, RegisterID dst)
458 m_buffer->putByte(OP_OR_GvEv);
459 emitModRm_rm(dst, base, offset);
462 void orl_i32r(int imm, RegisterID dst)
464 m_buffer->putByte(OP_GROUP1_EvIb);
465 emitModRm_opr(GROUP1_OP_OR, dst);
466 m_buffer->putByte(imm);
469 void subl_rr(RegisterID src, RegisterID dst)
471 m_buffer->putByte(OP_SUB_EvGv);
472 emitModRm_rr(src, dst);
475 void subl_i8r(int imm, RegisterID dst)
477 m_buffer->putByte(OP_GROUP1_EvIb);
478 emitModRm_opr(GROUP1_OP_SUB, dst);
479 m_buffer->putByte(imm);
482 void subl_i8m(int imm, void* addr)
484 m_buffer->putByte(OP_GROUP1_EvIb);
485 emitModRm_opm(GROUP1_OP_SUB, addr);
486 m_buffer->putByte(imm);
489 void subl_i32r(int imm, RegisterID dst)
491 m_buffer->putByte(OP_GROUP1_EvIz);
492 emitModRm_opr(GROUP1_OP_SUB, dst);
493 m_buffer->putInt(imm);
496 void subl_mr(int offset, RegisterID base, RegisterID dst)
498 m_buffer->putByte(OP_SUB_GvEv);
499 emitModRm_rm(dst, base, offset);
502 void testl_i32r(int imm, RegisterID dst)
504 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
505 m_buffer->putByteUnchecked(OP_GROUP3_EvIz);
506 emitModRm_opr_Unchecked(GROUP3_OP_TEST, dst);
507 m_buffer->putIntUnchecked(imm);
510 void testl_i32m(int imm, RegisterID dst)
512 m_buffer->putByte(OP_GROUP3_EvIz);
513 emitModRm_opm(GROUP3_OP_TEST, dst);
514 m_buffer->putInt(imm);
517 void testl_i32m(int imm, int offset, RegisterID dst)
519 m_buffer->putByte(OP_GROUP3_EvIz);
520 emitModRm_opm(GROUP3_OP_TEST, dst, offset);
521 m_buffer->putInt(imm);
524 void testl_rr(RegisterID src, RegisterID dst)
526 m_buffer->putByte(OP_TEST_EvGv);
527 emitModRm_rr(src, dst);
530 void xorl_i8r(int imm, RegisterID dst)
532 m_buffer->putByte(OP_GROUP1_EvIb);
533 emitModRm_opr(GROUP1_OP_XOR, dst);
534 m_buffer->putByte(imm);
537 void xorl_rr(RegisterID src, RegisterID dst)
539 m_buffer->putByte(OP_XOR_EvGv);
540 emitModRm_rr(src, dst);
543 void sarl_i8r(int imm, RegisterID dst)
546 m_buffer->putByte(OP_GROUP2_Ev1);
547 emitModRm_opr(GROUP2_OP_SAR, dst);
549 m_buffer->putByte(OP_GROUP2_EvIb);
550 emitModRm_opr(GROUP2_OP_SAR, dst);
551 m_buffer->putByte(imm);
555 void sarl_CLr(RegisterID dst)
557 m_buffer->putByte(OP_GROUP2_EvCL);
558 emitModRm_opr(GROUP2_OP_SAR, dst);
561 void shl_i8r(int imm, RegisterID dst)
564 m_buffer->putByte(OP_GROUP2_Ev1);
565 emitModRm_opr(GROUP2_OP_SHL, dst);
567 m_buffer->putByte(OP_GROUP2_EvIb);
568 emitModRm_opr(GROUP2_OP_SHL, dst);
569 m_buffer->putByte(imm);
573 void shll_CLr(RegisterID dst)
575 m_buffer->putByte(OP_GROUP2_EvCL);
576 emitModRm_opr(GROUP2_OP_SHL, dst);
579 void imull_rr(RegisterID src, RegisterID dst)
581 m_buffer->putByte(OP_2BYTE_ESCAPE);
582 m_buffer->putByte(OP2_IMUL_GvEv);
583 emitModRm_rr(dst, src);
586 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
588 m_buffer->putByte(OP_IMUL_GvEvIz);
589 emitModRm_rr(dst, src);
590 m_buffer->putInt(value);
593 void idivl_r(RegisterID dst)
595 m_buffer->putByte(OP_GROUP3_Ev);
596 emitModRm_opr(GROUP3_OP_IDIV, dst);
601 m_buffer->putByte(OP_CDQ);
604 void movl_mr(RegisterID base, RegisterID dst)
606 m_buffer->putByte(OP_MOV_GvEv);
607 emitModRm_rm(dst, base);
610 void movl_mr(int offset, RegisterID base, RegisterID dst)
612 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
613 m_buffer->putByteUnchecked(OP_MOV_GvEv);
614 emitModRm_rm_Unchecked(dst, base, offset);
617 void movl_mr(void* addr, RegisterID dst)
619 m_buffer->putByte(OP_MOV_GvEv);
620 emitModRm_rm(dst, addr);
623 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
625 m_buffer->putByte(OP_MOV_GvEv);
626 emitModRm_rmsib(dst, base, index, scale, offset);
629 void movzbl_rr(RegisterID src, RegisterID dst)
631 m_buffer->putByte(OP_2BYTE_ESCAPE);
632 m_buffer->putByte(OP2_MOVZX_GvEb);
633 emitModRm_rr(dst, src);
636 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
638 m_buffer->putByte(OP_2BYTE_ESCAPE);
639 m_buffer->putByte(OP2_MOVZX_GvEw);
640 emitModRm_rm(dst, base, offset);
643 void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
645 m_buffer->putByte(OP_2BYTE_ESCAPE);
646 m_buffer->putByte(OP2_MOVZX_GvEw);
647 emitModRm_rmsib(dst, base, index, scale);
650 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
652 m_buffer->putByte(OP_2BYTE_ESCAPE);
653 m_buffer->putByte(OP2_MOVZX_GvEw);
654 emitModRm_rmsib(dst, base, index, scale, offset);
657 void movl_rm(RegisterID src, RegisterID base)
659 m_buffer->putByte(OP_MOV_EvGv);
660 emitModRm_rm(src, base);
663 void movl_rm(RegisterID src, int offset, RegisterID base)
665 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
666 m_buffer->putByteUnchecked(OP_MOV_EvGv);
667 emitModRm_rm_Unchecked(src, base, offset);
670 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
672 m_buffer->putByte(OP_MOV_EvGv);
673 emitModRm_rmsib(src, base, index, scale, offset);
676 void movl_i32r(int imm, RegisterID dst)
678 m_buffer->putByte(OP_GROUP11_EvIz);
679 emitModRm_opr(GROUP11_MOV, dst);
680 m_buffer->putInt(imm);
683 void movl_i32m(int imm, int offset, RegisterID base)
685 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
686 m_buffer->putByteUnchecked(OP_GROUP11_EvIz);
687 emitModRm_opm_Unchecked(GROUP11_MOV, base, offset);
688 m_buffer->putIntUnchecked(imm);
691 void movl_i32m(int imm, void* addr)
693 m_buffer->putByte(OP_GROUP11_EvIz);
694 emitModRm_opm(GROUP11_MOV, addr);
695 m_buffer->putInt(imm);
698 void leal_mr(int offset, RegisterID base, RegisterID dst)
700 m_buffer->putByte(OP_LEA);
701 emitModRm_rm(dst, base, offset);
704 void leal_mr(int offset, RegisterID index, int scale, RegisterID dst)
706 m_buffer->putByte(OP_LEA);
707 emitModRm_rmsib(dst, X86::noBase, index, scale, offset);
712 m_buffer->putByte(OP_RET);
715 void jmp_r(RegisterID dst)
717 m_buffer->putByte(OP_GROUP5_Ev);
718 emitModRm_opr(GROUP5_OP_JMPN, dst);
721 void jmp_m(int offset, RegisterID base)
723 m_buffer->putByte(OP_GROUP5_Ev);
724 emitModRm_opm(GROUP5_OP_JMPN, base, offset);
727 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
729 m_buffer->putByte(PRE_SSE_F2);
730 m_buffer->putByte(OP_2BYTE_ESCAPE);
731 m_buffer->putByte(OP2_MOVSD_VsdWsd);
732 emitModRm_rm((RegisterID)dst, base, offset);
735 void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
737 m_buffer->putByte(PRE_SSE_F2);
738 m_buffer->putByte(OP_2BYTE_ESCAPE);
739 m_buffer->putByte(OP2_MOVSD_WsdVsd);
740 emitModRm_rm((RegisterID)src, base, offset);
743 void movd_rr(XMMRegisterID src, RegisterID dst)
745 m_buffer->putByte(PRE_SSE_66);
746 m_buffer->putByte(OP_2BYTE_ESCAPE);
747 m_buffer->putByte(OP2_MOVD_EdVd);
748 emitModRm_rr((RegisterID)src, dst);
751 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
753 m_buffer->putByte(PRE_SSE_F2);
754 m_buffer->putByte(OP_2BYTE_ESCAPE);
755 m_buffer->putByte(OP2_CVTSI2SD_VsdEd);
756 emitModRm_rr((RegisterID)dst, src);
759 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
761 m_buffer->putByte(PRE_SSE_F2);
762 m_buffer->putByte(OP_2BYTE_ESCAPE);
763 m_buffer->putByte(OP2_CVTTSD2SI_GdWsd);
764 emitModRm_rr(dst, (RegisterID)src);
767 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
769 m_buffer->putByte(PRE_SSE_F2);
770 m_buffer->putByte(OP_2BYTE_ESCAPE);
771 m_buffer->putByte(OP2_ADDSD_VsdWsd);
772 emitModRm_rm((RegisterID)dst, base, offset);
775 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
777 m_buffer->putByte(PRE_SSE_F2);
778 m_buffer->putByte(OP_2BYTE_ESCAPE);
779 m_buffer->putByte(OP2_SUBSD_VsdWsd);
780 emitModRm_rm((RegisterID)dst, base, offset);
783 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
785 m_buffer->putByte(PRE_SSE_F2);
786 m_buffer->putByte(OP_2BYTE_ESCAPE);
787 m_buffer->putByte(OP2_MULSD_VsdWsd);
788 emitModRm_rm((RegisterID)dst, base, offset);
791 void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
793 m_buffer->putByte(PRE_SSE_F2);
794 m_buffer->putByte(OP_2BYTE_ESCAPE);
795 m_buffer->putByte(OP2_ADDSD_VsdWsd);
796 emitModRm_rr((RegisterID)dst, (RegisterID)src);
799 void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
801 m_buffer->putByte(PRE_SSE_F2);
802 m_buffer->putByte(OP_2BYTE_ESCAPE);
803 m_buffer->putByte(OP2_SUBSD_VsdWsd);
804 emitModRm_rr((RegisterID)dst, (RegisterID)src);
807 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
809 m_buffer->putByte(PRE_SSE_F2);
810 m_buffer->putByte(OP_2BYTE_ESCAPE);
811 m_buffer->putByte(OP2_MULSD_VsdWsd);
812 emitModRm_rr((RegisterID)dst, (RegisterID)src);
815 void ucomis_rr(XMMRegisterID src, XMMRegisterID dst)
817 m_buffer->putByte(PRE_SSE_66);
818 m_buffer->putByte(OP_2BYTE_ESCAPE);
819 m_buffer->putByte(OP2_UCOMISD_VsdWsd);
820 emitModRm_rr((RegisterID)dst, (RegisterID)src);
823 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
825 m_buffer->putByte(PRE_SSE_66);
826 m_buffer->putByte(OP_2BYTE_ESCAPE);
827 m_buffer->putByte(OP2_PEXTRW_GdUdIb);
828 emitModRm_rr(dst, (RegisterID)src);
829 m_buffer->putByte(whichWord);
832 // Opaque label types
835 friend class X86Assembler;
852 friend class X86Assembler;
868 // FIXME: make this point to a global label, linked later.
871 m_buffer->putByte(OP_CALL_rel32);
873 return JmpSrc(m_buffer->getOffset());
876 JmpSrc emitCall(RegisterID dst)
878 m_buffer->putByte(OP_GROUP5_Ev);
879 emitModRm_opr(GROUP5_OP_CALLN, dst);
880 return JmpSrc(m_buffer->getOffset());
885 return JmpDst(m_buffer->getOffset());
888 JmpSrc emitUnlinkedJmp()
890 m_buffer->putByte(OP_JMP_rel32);
892 return JmpSrc(m_buffer->getOffset());
895 JmpSrc emitUnlinkedJne()
897 m_buffer->putByte(OP_2BYTE_ESCAPE);
898 m_buffer->putByte(OP2_JNE_rel32);
900 return JmpSrc(m_buffer->getOffset());
903 JmpSrc emitUnlinkedJnz()
905 return emitUnlinkedJne();
908 JmpSrc emitUnlinkedJe()
910 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
911 m_buffer->putByteUnchecked(OP_2BYTE_ESCAPE);
912 m_buffer->putByteUnchecked(OP2_JE_rel32);
913 m_buffer->putIntUnchecked(0);
914 return JmpSrc(m_buffer->getOffset());
917 JmpSrc emitUnlinkedJl()
919 m_buffer->putByte(OP_2BYTE_ESCAPE);
920 m_buffer->putByte(OP2_JL_rel32);
922 return JmpSrc(m_buffer->getOffset());
925 JmpSrc emitUnlinkedJb()
927 m_buffer->putByte(OP_2BYTE_ESCAPE);
928 m_buffer->putByte(OP2_JB_rel32);
930 return JmpSrc(m_buffer->getOffset());
933 JmpSrc emitUnlinkedJle()
935 m_buffer->putByte(OP_2BYTE_ESCAPE);
936 m_buffer->putByte(OP2_JLE_rel32);
938 return JmpSrc(m_buffer->getOffset());
941 JmpSrc emitUnlinkedJbe()
943 m_buffer->putByte(OP_2BYTE_ESCAPE);
944 m_buffer->putByte(OP2_JBE_rel32);
946 return JmpSrc(m_buffer->getOffset());
949 JmpSrc emitUnlinkedJge()
951 m_buffer->putByte(OP_2BYTE_ESCAPE);
952 m_buffer->putByte(OP2_JGE_rel32);
954 return JmpSrc(m_buffer->getOffset());
957 JmpSrc emitUnlinkedJg()
959 m_buffer->putByte(OP_2BYTE_ESCAPE);
960 m_buffer->putByte(OP2_JG_rel32);
962 return JmpSrc(m_buffer->getOffset());
965 JmpSrc emitUnlinkedJa()
967 m_buffer->putByte(OP_2BYTE_ESCAPE);
968 m_buffer->putByte(OP2_JA_rel32);
970 return JmpSrc(m_buffer->getOffset());
973 JmpSrc emitUnlinkedJae()
975 m_buffer->putByte(OP_2BYTE_ESCAPE);
976 m_buffer->putByte(OP2_JAE_rel32);
978 return JmpSrc(m_buffer->getOffset());
981 JmpSrc emitUnlinkedJo()
983 m_buffer->putByte(OP_2BYTE_ESCAPE);
984 m_buffer->putByte(OP2_JO_rel32);
986 return JmpSrc(m_buffer->getOffset());
989 JmpSrc emitUnlinkedJp()
991 m_buffer->putByte(OP_2BYTE_ESCAPE);
992 m_buffer->putByte(OP2_JP_rel32);
994 return JmpSrc(m_buffer->getOffset());
997 JmpSrc emitUnlinkedJs()
999 m_buffer->putByte(OP_2BYTE_ESCAPE);
1000 m_buffer->putByte(OP2_JS_rel32);
1001 m_buffer->putInt(0);
1002 return JmpSrc(m_buffer->getOffset());
1005 void emitPredictionNotTaken()
1007 m_buffer->putByte(PRE_PREDICT_BRANCH_NOT_TAKEN);
1010 void link(JmpSrc from, JmpDst to)
1012 ASSERT(to.m_offset != -1);
1013 ASSERT(from.m_offset != -1);
1015 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_buffer->start()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
1018 static void linkAbsoluteAddress(void* code, JmpDst useOffset, JmpDst address)
1020 ASSERT(useOffset.m_offset != -1);
1021 ASSERT(address.m_offset != -1);
1023 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + useOffset.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(code) + address.m_offset;
1026 static void link(void* code, JmpSrc from, void* to)
1028 ASSERT(from.m_offset != -1);
1030 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
1033 static void* getRelocatedAddress(void* code, JmpSrc jump)
1035 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
1038 static void* getRelocatedAddress(void* code, JmpDst jump)
1040 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
1043 static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
1045 return dst.m_offset - src.m_offset;
1048 static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
1050 return dst.m_offset - src.m_offset;
1053 static void repatchImmediate(intptr_t where, int32_t value)
1055 reinterpret_cast<int32_t*>(where)[-1] = value;
1058 static void repatchDisplacement(intptr_t where, intptr_t value)
1060 reinterpret_cast<intptr_t*>(where)[-1] = value;
1063 static void repatchBranchOffset(intptr_t where, void* destination)
1065 reinterpret_cast<intptr_t*>(where)[-1] = (reinterpret_cast<intptr_t>(destination) - where);
1070 return m_buffer->copy();
1074 void emitConvertToFastCall()
1076 movl_mr(4, X86::esp, X86::eax);
1077 movl_mr(8, X86::esp, X86::edx);
1078 movl_mr(12, X86::esp, X86::ecx);
1081 void emitConvertToFastCall() {}
1084 #if USE(CTI_ARGUMENT)
1085 void emitRestoreArgumentReference()
1087 #if USE(FAST_CALL_CTI_ARGUMENT)
1088 movl_rr(X86::esp, X86::ecx);
1090 movl_rm(X86::esp, 0, X86::esp);
1094 void emitRestoreArgumentReferenceForTrampoline()
1096 #if USE(FAST_CALL_CTI_ARGUMENT)
1097 movl_rr(X86::esp, X86::ecx);
1098 addl_i32r(4, X86::ecx);
1102 void emitRestoreArgumentReference() {}
1103 void emitRestoreArgumentReferenceForTrampoline() {}
1107 void emitModRm_rr(RegisterID reg, RegisterID rm)
1109 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1110 emitModRm_rr_Unchecked(reg, rm);
1113 void emitModRm_rr_Unchecked(RegisterID reg, RegisterID rm)
1115 m_buffer->putByteUnchecked(MODRM(3, reg, rm));
1118 void emitModRm_rm(RegisterID reg, void* addr)
1120 m_buffer->putByte(MODRM(0, reg, X86::noBase));
1121 m_buffer->putInt((int)addr);
1124 void emitModRm_rm(RegisterID reg, RegisterID base)
1126 if (base == X86::esp) {
1127 m_buffer->putByte(MODRM(0, reg, X86::hasSib));
1128 m_buffer->putByte(SIB(0, X86::noScale, X86::esp));
1130 m_buffer->putByte(MODRM(0, reg, base));
1133 void emitModRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)
1135 if (base == X86::esp) {
1136 if (CAN_SIGN_EXTEND_8_32(offset)) {
1137 m_buffer->putByteUnchecked(MODRM(1, reg, X86::hasSib));
1138 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
1139 m_buffer->putByteUnchecked(offset);
1141 m_buffer->putByteUnchecked(MODRM(2, reg, X86::hasSib));
1142 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
1143 m_buffer->putIntUnchecked(offset);
1146 if (CAN_SIGN_EXTEND_8_32(offset)) {
1147 m_buffer->putByteUnchecked(MODRM(1, reg, base));
1148 m_buffer->putByteUnchecked(offset);
1150 m_buffer->putByteUnchecked(MODRM(2, reg, base));
1151 m_buffer->putIntUnchecked(offset);
1156 void emitModRm_rm(RegisterID reg, RegisterID base, int offset)
1158 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1159 emitModRm_rm_Unchecked(reg, base, offset);
1162 void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale)
1168 m_buffer->putByte(MODRM(0, reg, X86::hasSib));
1169 m_buffer->putByte(SIB(shift, index, base));
1172 void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset)
1178 if (CAN_SIGN_EXTEND_8_32(offset)) {
1179 m_buffer->putByte(MODRM(1, reg, X86::hasSib));
1180 m_buffer->putByte(SIB(shift, index, base));
1181 m_buffer->putByte(offset);
1183 m_buffer->putByte(MODRM(2, reg, X86::hasSib));
1184 m_buffer->putByte(SIB(shift, index, base));
1185 m_buffer->putInt(offset);
1189 void emitModRm_opr(OpcodeID opcode, RegisterID rm)
1191 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1192 emitModRm_opr_Unchecked(opcode, rm);
1195 void emitModRm_opr_Unchecked(OpcodeID opcode, RegisterID rm)
1197 emitModRm_rr_Unchecked(static_cast<RegisterID>(opcode), rm);
1200 void emitModRm_opm(OpcodeID opcode, RegisterID base)
1202 emitModRm_rm(static_cast<RegisterID>(opcode), base);
1205 void emitModRm_opm_Unchecked(OpcodeID opcode, RegisterID base, int offset)
1207 emitModRm_rm_Unchecked(static_cast<RegisterID>(opcode), base, offset);
1210 void emitModRm_opm(OpcodeID opcode, RegisterID base, int offset)
1212 emitModRm_rm(static_cast<RegisterID>(opcode), base, offset);
1215 void emitModRm_opm(OpcodeID opcode, void* addr)
1217 emitModRm_rm(static_cast<RegisterID>(opcode), addr);
1220 void emitModRm_opmsib(OpcodeID opcode, RegisterID base, RegisterID index, int scale, int offset)
1222 emitModRm_rmsib(static_cast<RegisterID>(opcode), base, index, scale, offset);
1225 JITCodeBuffer* m_buffer;
1230 #endif // ENABLE(MASM) && PLATFORM(X86)
1232 #endif // X86Assembler_h