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>
33 #include <wtf/FastMalloc.h>
45 JITCodeBuffer(int size)
46 : m_buffer(static_cast<char*>(fastMalloc(size)))
57 void ensureSpace(int space)
59 if (m_index > m_size - space)
63 void putByteUnchecked(int value)
65 m_buffer[m_index] = value;
69 void putByte(int value)
71 if (m_index > m_size - 4)
73 putByteUnchecked(value);
76 void putShortUnchecked(int value)
78 *(short*)(&m_buffer[m_index]) = value;
82 void putShort(int value)
84 if (m_index > m_size - 4)
86 putShortUnchecked(value);
89 void putIntUnchecked(int value)
91 *reinterpret_cast<int*>(&m_buffer[m_index]) = value;
95 void putInt(int value)
97 if (m_index > m_size - 4)
99 putIntUnchecked(value);
104 return m_buffer + m_index;
117 JITCodeBuffer* reset()
128 void* result = WTF::fastMallocExecutable(m_index);
133 return memcpy(result, m_buffer, m_index);
139 m_size += m_size / 2;
140 m_buffer = static_cast<char*>(fastRealloc(m_buffer, m_size));
148 #define MODRM(type, reg, rm) ((type << 6) | (reg << 3) | (rm))
149 #define SIB(type, reg, rm) MODRM(type, reg, rm)
150 #define CAN_SIGN_EXTEND_8_32(value) (value == ((int)(signed char)value))
182 typedef X86::RegisterID RegisterID;
183 typedef X86::XMMRegisterID XMMRegisterID;
189 OP_2BYTE_ESCAPE = 0x0F,
193 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
199 PRE_OPERAND_SIZE = 0x66,
202 OP_IMUL_GvEvIz = 0x69,
203 OP_GROUP1_EvIz = 0x81,
204 OP_GROUP1_EvIb = 0x83,
209 OP_GROUP1A_Ev = 0x8F,
213 OP_GROUP2_EvIb = 0xC1,
215 OP_GROUP11_EvIz = 0xC7,
217 OP_GROUP2_Ev1 = 0xD1,
218 OP_GROUP2_EvCL = 0xD3,
219 OP_CALL_rel32 = 0xE8,
223 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
226 OP2_MOVSD_VsdWsd = 0x10,
227 OP2_MOVSD_WsdVsd = 0x11,
228 OP2_CVTSI2SD_VsdEd = 0x2A,
229 OP2_CVTTSD2SI_GdWsd = 0x2C,
230 OP2_UCOMISD_VsdWsd = 0x2E,
231 OP2_ADDSD_VsdWsd = 0x58,
232 OP2_MULSD_VsdWsd = 0x59,
233 OP2_SUBSD_VsdWsd = 0x5C,
234 OP2_MOVD_EdVd = 0x7E,
237 OP2_JAE_rel32 = 0x83,
239 OP2_JNE_rel32 = 0x85,
240 OP2_JBE_rel32 = 0x86,
245 OP2_JGE_rel32 = 0x8D,
246 OP2_JLE_rel32 = 0x8E,
248 OP2_IMUL_GvEv = 0xAF,
249 OP2_MOVZX_GvEb = 0xB6,
250 OP2_MOVZX_GvEw = 0xB7,
251 OP2_PEXTRW_GdUdIb = 0xC5,
275 static const int MAX_INSTRUCTION_SIZE = 16;
277 X86Assembler(JITCodeBuffer* m_buffer)
285 m_buffer->putByte(OP_INT3);
288 void pushl_r(RegisterID reg)
290 m_buffer->putByte(OP_PUSH_EAX + reg);
293 void pushl_m(int offset, RegisterID base)
295 m_buffer->putByte(OP_GROUP5_Ev);
296 emitModRm_opm(GROUP5_OP_PUSH, base, offset);
299 void pushl_i32(int imm)
301 m_buffer->putByte(OP_PUSH_Iz);
302 m_buffer->putInt(imm);
305 void popl_r(RegisterID reg)
307 m_buffer->putByte(OP_POP_EAX + reg);
310 void popl_m(int offset, RegisterID base)
312 m_buffer->putByte(OP_GROUP1A_Ev);
313 emitModRm_opm(GROUP1A_OP_POP, base, offset);
316 void movl_rr(RegisterID src, RegisterID dst)
318 m_buffer->putByte(OP_MOV_EvGv);
319 emitModRm_rr(src, dst);
322 void addl_rr(RegisterID src, RegisterID dst)
324 m_buffer->putByte(OP_ADD_EvGv);
325 emitModRm_rr(src, dst);
328 void addl_i8r(int imm, RegisterID dst)
330 m_buffer->putByte(OP_GROUP1_EvIb);
331 emitModRm_opr(GROUP1_OP_ADD, dst);
332 m_buffer->putByte(imm);
335 void addl_i8m(int imm, void* addr)
337 m_buffer->putByte(OP_GROUP1_EvIb);
338 emitModRm_opm(GROUP1_OP_ADD, addr);
339 m_buffer->putByte(imm);
342 void addl_i32r(int imm, RegisterID dst)
344 m_buffer->putByte(OP_GROUP1_EvIz);
345 emitModRm_opr(GROUP1_OP_ADD, dst);
346 m_buffer->putInt(imm);
349 void addl_mr(int offset, RegisterID base, RegisterID dst)
351 m_buffer->putByte(OP_ADD_GvEv);
352 emitModRm_rm(dst, base, offset);
355 void andl_rr(RegisterID src, RegisterID dst)
357 m_buffer->putByte(OP_AND_EvGv);
358 emitModRm_rr(src, dst);
361 void andl_i32r(int imm, RegisterID dst)
363 m_buffer->putByte(OP_GROUP1_EvIz);
364 emitModRm_opr(GROUP1_OP_AND, dst);
365 m_buffer->putInt(imm);
368 void cmpl_i8r(int imm, RegisterID dst)
370 m_buffer->putByte(OP_GROUP1_EvIb);
371 emitModRm_opr(GROUP1_OP_CMP, dst);
372 m_buffer->putByte(imm);
375 void cmpl_rr(RegisterID src, RegisterID dst)
377 m_buffer->putByte(OP_CMP_EvGv);
378 emitModRm_rr(src, dst);
381 void cmpl_rm(RegisterID src, int offset, RegisterID base)
383 m_buffer->putByte(OP_CMP_EvGv);
384 emitModRm_rm(src, base, offset);
387 void cmpl_mr(int offset, RegisterID base, RegisterID dst)
389 m_buffer->putByte(OP_CMP_GvEv);
390 emitModRm_rm(dst, base, offset);
393 void cmpl_i32r(int imm, RegisterID dst)
395 m_buffer->putByte(OP_GROUP1_EvIz);
396 emitModRm_opr(GROUP1_OP_CMP, dst);
397 m_buffer->putInt(imm);
400 void cmpl_i32m(int imm, RegisterID dst)
402 m_buffer->putByte(OP_GROUP1_EvIz);
403 emitModRm_opm(GROUP1_OP_CMP, dst);
404 m_buffer->putInt(imm);
407 void cmpl_i32m(int imm, int offset, RegisterID dst)
409 m_buffer->putByte(OP_GROUP1_EvIz);
410 emitModRm_opm(GROUP1_OP_CMP, dst, offset);
411 m_buffer->putInt(imm);
414 void cmpl_i32m(int imm, void* addr)
416 m_buffer->putByte(OP_GROUP1_EvIz);
417 emitModRm_opm(GROUP1_OP_CMP, addr);
418 m_buffer->putInt(imm);
421 void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
423 m_buffer->putByte(OP_GROUP1_EvIb);
424 emitModRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset);
425 m_buffer->putByte(imm);
428 void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
430 m_buffer->putByte(PRE_OPERAND_SIZE);
431 m_buffer->putByte(OP_CMP_EvGv);
432 emitModRm_rmsib(src, base, index, scale);
435 void sete_r(RegisterID dst)
437 m_buffer->putByte(OP_2BYTE_ESCAPE);
438 m_buffer->putByte(OP_SETE);
439 m_buffer->putByte(MODRM(3, 0, dst));
442 void setz_r(RegisterID dst)
447 void setne_r(RegisterID dst)
449 m_buffer->putByte(OP_2BYTE_ESCAPE);
450 m_buffer->putByte(OP_SETNE);
451 m_buffer->putByte(MODRM(3, 0, dst));
454 void setnz_r(RegisterID dst)
459 void orl_rr(RegisterID src, RegisterID dst)
461 m_buffer->putByte(OP_OR_EvGv);
462 emitModRm_rr(src, dst);
465 void orl_mr(int offset, RegisterID base, RegisterID dst)
467 m_buffer->putByte(OP_OR_GvEv);
468 emitModRm_rm(dst, base, offset);
471 void orl_i32r(int imm, RegisterID dst)
473 m_buffer->putByte(OP_GROUP1_EvIb);
474 emitModRm_opr(GROUP1_OP_OR, dst);
475 m_buffer->putByte(imm);
478 void subl_rr(RegisterID src, RegisterID dst)
480 m_buffer->putByte(OP_SUB_EvGv);
481 emitModRm_rr(src, dst);
484 void subl_i8r(int imm, RegisterID dst)
486 m_buffer->putByte(OP_GROUP1_EvIb);
487 emitModRm_opr(GROUP1_OP_SUB, dst);
488 m_buffer->putByte(imm);
491 void subl_i8m(int imm, void* addr)
493 m_buffer->putByte(OP_GROUP1_EvIb);
494 emitModRm_opm(GROUP1_OP_SUB, addr);
495 m_buffer->putByte(imm);
498 void subl_i32r(int imm, RegisterID dst)
500 m_buffer->putByte(OP_GROUP1_EvIz);
501 emitModRm_opr(GROUP1_OP_SUB, dst);
502 m_buffer->putInt(imm);
505 void subl_mr(int offset, RegisterID base, RegisterID dst)
507 m_buffer->putByte(OP_SUB_GvEv);
508 emitModRm_rm(dst, base, offset);
511 void testl_i32r(int imm, RegisterID dst)
513 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
514 m_buffer->putByteUnchecked(OP_GROUP3_EvIz);
515 emitModRm_opr_Unchecked(GROUP3_OP_TEST, dst);
516 m_buffer->putIntUnchecked(imm);
519 void testl_i32m(int imm, RegisterID dst)
521 m_buffer->putByte(OP_GROUP3_EvIz);
522 emitModRm_opm(GROUP3_OP_TEST, dst);
523 m_buffer->putInt(imm);
526 void testl_i32m(int imm, int offset, RegisterID dst)
528 m_buffer->putByte(OP_GROUP3_EvIz);
529 emitModRm_opm(GROUP3_OP_TEST, dst, offset);
530 m_buffer->putInt(imm);
533 void testl_rr(RegisterID src, RegisterID dst)
535 m_buffer->putByte(OP_TEST_EvGv);
536 emitModRm_rr(src, dst);
539 void xorl_i8r(int imm, RegisterID dst)
541 m_buffer->putByte(OP_GROUP1_EvIb);
542 emitModRm_opr(GROUP1_OP_XOR, dst);
543 m_buffer->putByte(imm);
546 void xorl_rr(RegisterID src, RegisterID dst)
548 m_buffer->putByte(OP_XOR_EvGv);
549 emitModRm_rr(src, dst);
552 void sarl_i8r(int imm, RegisterID dst)
555 m_buffer->putByte(OP_GROUP2_Ev1);
556 emitModRm_opr(GROUP2_OP_SAR, dst);
558 m_buffer->putByte(OP_GROUP2_EvIb);
559 emitModRm_opr(GROUP2_OP_SAR, dst);
560 m_buffer->putByte(imm);
564 void sarl_CLr(RegisterID dst)
566 m_buffer->putByte(OP_GROUP2_EvCL);
567 emitModRm_opr(GROUP2_OP_SAR, dst);
570 void shl_i8r(int imm, RegisterID dst)
573 m_buffer->putByte(OP_GROUP2_Ev1);
574 emitModRm_opr(GROUP2_OP_SHL, dst);
576 m_buffer->putByte(OP_GROUP2_EvIb);
577 emitModRm_opr(GROUP2_OP_SHL, dst);
578 m_buffer->putByte(imm);
582 void shll_CLr(RegisterID dst)
584 m_buffer->putByte(OP_GROUP2_EvCL);
585 emitModRm_opr(GROUP2_OP_SHL, dst);
588 void imull_rr(RegisterID src, RegisterID dst)
590 m_buffer->putByte(OP_2BYTE_ESCAPE);
591 m_buffer->putByte(OP2_IMUL_GvEv);
592 emitModRm_rr(dst, src);
595 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
597 m_buffer->putByte(OP_IMUL_GvEvIz);
598 emitModRm_rr(dst, src);
599 m_buffer->putInt(value);
602 void idivl_r(RegisterID dst)
604 m_buffer->putByte(OP_GROUP3_Ev);
605 emitModRm_opr(GROUP3_OP_IDIV, dst);
610 m_buffer->putByte(OP_CDQ);
613 void movl_mr(RegisterID base, RegisterID dst)
615 m_buffer->putByte(OP_MOV_GvEv);
616 emitModRm_rm(dst, base);
619 void movl_mr(int offset, RegisterID base, RegisterID dst)
621 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
622 m_buffer->putByteUnchecked(OP_MOV_GvEv);
623 emitModRm_rm_Unchecked(dst, base, offset);
626 void movl_mr(void* addr, RegisterID dst)
628 m_buffer->putByte(OP_MOV_GvEv);
629 emitModRm_rm(dst, addr);
632 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
634 m_buffer->putByte(OP_MOV_GvEv);
635 emitModRm_rmsib(dst, base, index, scale, offset);
638 void movzbl_rr(RegisterID src, RegisterID dst)
640 m_buffer->putByte(OP_2BYTE_ESCAPE);
641 m_buffer->putByte(OP2_MOVZX_GvEb);
642 emitModRm_rr(dst, src);
645 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
647 m_buffer->putByte(OP_2BYTE_ESCAPE);
648 m_buffer->putByte(OP2_MOVZX_GvEw);
649 emitModRm_rm(dst, base, offset);
652 void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
654 m_buffer->putByte(OP_2BYTE_ESCAPE);
655 m_buffer->putByte(OP2_MOVZX_GvEw);
656 emitModRm_rmsib(dst, base, index, scale);
659 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
661 m_buffer->putByte(OP_2BYTE_ESCAPE);
662 m_buffer->putByte(OP2_MOVZX_GvEw);
663 emitModRm_rmsib(dst, base, index, scale, offset);
666 void movl_rm(RegisterID src, RegisterID base)
668 m_buffer->putByte(OP_MOV_EvGv);
669 emitModRm_rm(src, base);
672 void movl_rm(RegisterID src, int offset, RegisterID base)
674 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
675 m_buffer->putByteUnchecked(OP_MOV_EvGv);
676 emitModRm_rm_Unchecked(src, base, offset);
679 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
681 m_buffer->putByte(OP_MOV_EvGv);
682 emitModRm_rmsib(src, base, index, scale, offset);
685 void movl_i32r(int imm, RegisterID dst)
687 m_buffer->putByte(OP_GROUP11_EvIz);
688 emitModRm_opr(GROUP11_MOV, dst);
689 m_buffer->putInt(imm);
692 void movl_i32m(int imm, int offset, RegisterID base)
694 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
695 m_buffer->putByteUnchecked(OP_GROUP11_EvIz);
696 emitModRm_opm_Unchecked(GROUP11_MOV, base, offset);
697 m_buffer->putIntUnchecked(imm);
700 void movl_i32m(int imm, void* addr)
702 m_buffer->putByte(OP_GROUP11_EvIz);
703 emitModRm_opm(GROUP11_MOV, addr);
704 m_buffer->putInt(imm);
707 void leal_mr(int offset, RegisterID base, RegisterID dst)
709 m_buffer->putByte(OP_LEA);
710 emitModRm_rm(dst, base, offset);
713 void leal_mr(int offset, RegisterID index, int scale, RegisterID dst)
715 m_buffer->putByte(OP_LEA);
716 emitModRm_rmsib(dst, X86::noBase, index, scale, offset);
721 m_buffer->putByte(OP_RET);
724 void jmp_r(RegisterID dst)
726 m_buffer->putByte(OP_GROUP5_Ev);
727 emitModRm_opr(GROUP5_OP_JMPN, dst);
730 void jmp_m(int offset, RegisterID base)
732 m_buffer->putByte(OP_GROUP5_Ev);
733 emitModRm_opm(GROUP5_OP_JMPN, base, offset);
736 void movsd_mr(int offset, RegisterID base, XMMRegisterID dst)
738 m_buffer->putByte(PRE_SSE_F2);
739 m_buffer->putByte(OP_2BYTE_ESCAPE);
740 m_buffer->putByte(OP2_MOVSD_VsdWsd);
741 emitModRm_rm((RegisterID)dst, base, offset);
744 void movsd_rm(XMMRegisterID src, int offset, RegisterID base)
746 m_buffer->putByte(PRE_SSE_F2);
747 m_buffer->putByte(OP_2BYTE_ESCAPE);
748 m_buffer->putByte(OP2_MOVSD_WsdVsd);
749 emitModRm_rm((RegisterID)src, base, offset);
752 void movd_rr(XMMRegisterID src, RegisterID dst)
754 m_buffer->putByte(PRE_SSE_66);
755 m_buffer->putByte(OP_2BYTE_ESCAPE);
756 m_buffer->putByte(OP2_MOVD_EdVd);
757 emitModRm_rr((RegisterID)src, dst);
760 void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst)
762 m_buffer->putByte(PRE_SSE_F2);
763 m_buffer->putByte(OP_2BYTE_ESCAPE);
764 m_buffer->putByte(OP2_CVTSI2SD_VsdEd);
765 emitModRm_rr((RegisterID)dst, src);
768 void cvttsd2si_rr(XMMRegisterID src, RegisterID dst)
770 m_buffer->putByte(PRE_SSE_F2);
771 m_buffer->putByte(OP_2BYTE_ESCAPE);
772 m_buffer->putByte(OP2_CVTTSD2SI_GdWsd);
773 emitModRm_rr(dst, (RegisterID)src);
776 void addsd_mr(int offset, RegisterID base, XMMRegisterID dst)
778 m_buffer->putByte(PRE_SSE_F2);
779 m_buffer->putByte(OP_2BYTE_ESCAPE);
780 m_buffer->putByte(OP2_ADDSD_VsdWsd);
781 emitModRm_rm((RegisterID)dst, base, offset);
784 void subsd_mr(int offset, RegisterID base, XMMRegisterID dst)
786 m_buffer->putByte(PRE_SSE_F2);
787 m_buffer->putByte(OP_2BYTE_ESCAPE);
788 m_buffer->putByte(OP2_SUBSD_VsdWsd);
789 emitModRm_rm((RegisterID)dst, base, offset);
792 void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst)
794 m_buffer->putByte(PRE_SSE_F2);
795 m_buffer->putByte(OP_2BYTE_ESCAPE);
796 m_buffer->putByte(OP2_MULSD_VsdWsd);
797 emitModRm_rm((RegisterID)dst, base, offset);
800 void addsd_rr(XMMRegisterID src, XMMRegisterID dst)
802 m_buffer->putByte(PRE_SSE_F2);
803 m_buffer->putByte(OP_2BYTE_ESCAPE);
804 m_buffer->putByte(OP2_ADDSD_VsdWsd);
805 emitModRm_rr((RegisterID)dst, (RegisterID)src);
808 void subsd_rr(XMMRegisterID src, XMMRegisterID dst)
810 m_buffer->putByte(PRE_SSE_F2);
811 m_buffer->putByte(OP_2BYTE_ESCAPE);
812 m_buffer->putByte(OP2_SUBSD_VsdWsd);
813 emitModRm_rr((RegisterID)dst, (RegisterID)src);
816 void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)
818 m_buffer->putByte(PRE_SSE_F2);
819 m_buffer->putByte(OP_2BYTE_ESCAPE);
820 m_buffer->putByte(OP2_MULSD_VsdWsd);
821 emitModRm_rr((RegisterID)dst, (RegisterID)src);
824 void ucomis_rr(XMMRegisterID src, XMMRegisterID dst)
826 m_buffer->putByte(PRE_SSE_66);
827 m_buffer->putByte(OP_2BYTE_ESCAPE);
828 m_buffer->putByte(OP2_UCOMISD_VsdWsd);
829 emitModRm_rr((RegisterID)dst, (RegisterID)src);
832 void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst)
834 m_buffer->putByte(PRE_SSE_66);
835 m_buffer->putByte(OP_2BYTE_ESCAPE);
836 m_buffer->putByte(OP2_PEXTRW_GdUdIb);
837 emitModRm_rr(dst, (RegisterID)src);
838 m_buffer->putByte(whichWord);
841 // Opaque label types
844 friend class X86Assembler;
861 friend class X86Assembler;
877 // FIXME: make this point to a global label, linked later.
880 m_buffer->putByte(OP_CALL_rel32);
882 return JmpSrc(m_buffer->getOffset());
885 JmpSrc emitCall(RegisterID dst)
887 m_buffer->putByte(OP_GROUP5_Ev);
888 emitModRm_opr(GROUP5_OP_CALLN, dst);
889 return JmpSrc(m_buffer->getOffset());
894 return JmpDst(m_buffer->getOffset());
897 JmpSrc emitUnlinkedJmp()
899 m_buffer->putByte(OP_JMP_rel32);
901 return JmpSrc(m_buffer->getOffset());
904 JmpSrc emitUnlinkedJne()
906 m_buffer->putByte(OP_2BYTE_ESCAPE);
907 m_buffer->putByte(OP2_JNE_rel32);
909 return JmpSrc(m_buffer->getOffset());
912 JmpSrc emitUnlinkedJnz()
914 return emitUnlinkedJne();
917 JmpSrc emitUnlinkedJe()
919 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
920 m_buffer->putByteUnchecked(OP_2BYTE_ESCAPE);
921 m_buffer->putByteUnchecked(OP2_JE_rel32);
922 m_buffer->putIntUnchecked(0);
923 return JmpSrc(m_buffer->getOffset());
926 JmpSrc emitUnlinkedJl()
928 m_buffer->putByte(OP_2BYTE_ESCAPE);
929 m_buffer->putByte(OP2_JL_rel32);
931 return JmpSrc(m_buffer->getOffset());
934 JmpSrc emitUnlinkedJb()
936 m_buffer->putByte(OP_2BYTE_ESCAPE);
937 m_buffer->putByte(OP2_JB_rel32);
939 return JmpSrc(m_buffer->getOffset());
942 JmpSrc emitUnlinkedJle()
944 m_buffer->putByte(OP_2BYTE_ESCAPE);
945 m_buffer->putByte(OP2_JLE_rel32);
947 return JmpSrc(m_buffer->getOffset());
950 JmpSrc emitUnlinkedJbe()
952 m_buffer->putByte(OP_2BYTE_ESCAPE);
953 m_buffer->putByte(OP2_JBE_rel32);
955 return JmpSrc(m_buffer->getOffset());
958 JmpSrc emitUnlinkedJge()
960 m_buffer->putByte(OP_2BYTE_ESCAPE);
961 m_buffer->putByte(OP2_JGE_rel32);
963 return JmpSrc(m_buffer->getOffset());
966 JmpSrc emitUnlinkedJg()
968 m_buffer->putByte(OP_2BYTE_ESCAPE);
969 m_buffer->putByte(OP2_JG_rel32);
971 return JmpSrc(m_buffer->getOffset());
974 JmpSrc emitUnlinkedJa()
976 m_buffer->putByte(OP_2BYTE_ESCAPE);
977 m_buffer->putByte(OP2_JA_rel32);
979 return JmpSrc(m_buffer->getOffset());
982 JmpSrc emitUnlinkedJae()
984 m_buffer->putByte(OP_2BYTE_ESCAPE);
985 m_buffer->putByte(OP2_JAE_rel32);
987 return JmpSrc(m_buffer->getOffset());
990 JmpSrc emitUnlinkedJo()
992 m_buffer->putByte(OP_2BYTE_ESCAPE);
993 m_buffer->putByte(OP2_JO_rel32);
995 return JmpSrc(m_buffer->getOffset());
998 JmpSrc emitUnlinkedJp()
1000 m_buffer->putByte(OP_2BYTE_ESCAPE);
1001 m_buffer->putByte(OP2_JP_rel32);
1002 m_buffer->putInt(0);
1003 return JmpSrc(m_buffer->getOffset());
1006 JmpSrc emitUnlinkedJs()
1008 m_buffer->putByte(OP_2BYTE_ESCAPE);
1009 m_buffer->putByte(OP2_JS_rel32);
1010 m_buffer->putInt(0);
1011 return JmpSrc(m_buffer->getOffset());
1014 void emitPredictionNotTaken()
1016 m_buffer->putByte(PRE_PREDICT_BRANCH_NOT_TAKEN);
1019 void link(JmpSrc from, JmpDst to)
1021 ASSERT(to.m_offset != -1);
1022 ASSERT(from.m_offset != -1);
1024 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_buffer->start()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
1027 static void linkAbsoluteAddress(void* code, JmpDst useOffset, JmpDst address)
1029 ASSERT(useOffset.m_offset != -1);
1030 ASSERT(address.m_offset != -1);
1032 reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + useOffset.m_offset)[-1] = reinterpret_cast<ptrdiff_t>(code) + address.m_offset;
1035 static void link(void* code, JmpSrc from, void* to)
1037 ASSERT(from.m_offset != -1);
1039 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);
1042 static void* getRelocatedAddress(void* code, JmpSrc jump)
1044 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
1047 static void* getRelocatedAddress(void* code, JmpDst jump)
1049 return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset);
1052 static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
1054 return dst.m_offset - src.m_offset;
1057 static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
1059 return dst.m_offset - src.m_offset;
1062 static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst)
1064 return dst.m_offset - src.m_offset;
1067 static void repatchImmediate(intptr_t where, int32_t value)
1069 reinterpret_cast<int32_t*>(where)[-1] = value;
1072 static void repatchDisplacement(intptr_t where, intptr_t value)
1074 reinterpret_cast<intptr_t*>(where)[-1] = value;
1077 static void repatchBranchOffset(intptr_t where, void* destination)
1079 reinterpret_cast<intptr_t*>(where)[-1] = (reinterpret_cast<intptr_t>(destination) - where);
1084 return m_buffer->copy();
1088 void emitConvertToFastCall()
1090 movl_mr(4, X86::esp, X86::eax);
1091 movl_mr(8, X86::esp, X86::edx);
1092 movl_mr(12, X86::esp, X86::ecx);
1095 void emitConvertToFastCall() {}
1098 #if USE(CTI_ARGUMENT)
1099 void emitRestoreArgumentReference()
1101 #if USE(FAST_CALL_CTI_ARGUMENT)
1102 movl_rr(X86::esp, X86::ecx);
1104 movl_rm(X86::esp, 0, X86::esp);
1108 void emitRestoreArgumentReferenceForTrampoline()
1110 #if USE(FAST_CALL_CTI_ARGUMENT)
1111 movl_rr(X86::esp, X86::ecx);
1112 addl_i32r(4, X86::ecx);
1116 void emitRestoreArgumentReference() {}
1117 void emitRestoreArgumentReferenceForTrampoline() {}
1121 void emitModRm_rr(RegisterID reg, RegisterID rm)
1123 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1124 emitModRm_rr_Unchecked(reg, rm);
1127 void emitModRm_rr_Unchecked(RegisterID reg, RegisterID rm)
1129 m_buffer->putByteUnchecked(MODRM(3, reg, rm));
1132 void emitModRm_rm(RegisterID reg, void* addr)
1134 m_buffer->putByte(MODRM(0, reg, X86::noBase));
1135 m_buffer->putInt((int)addr);
1138 void emitModRm_rm(RegisterID reg, RegisterID base)
1140 if (base == X86::esp) {
1141 m_buffer->putByte(MODRM(0, reg, X86::hasSib));
1142 m_buffer->putByte(SIB(0, X86::noScale, X86::esp));
1144 m_buffer->putByte(MODRM(0, reg, base));
1147 void emitModRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)
1149 if (base == X86::esp) {
1150 if (CAN_SIGN_EXTEND_8_32(offset)) {
1151 m_buffer->putByteUnchecked(MODRM(1, reg, X86::hasSib));
1152 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
1153 m_buffer->putByteUnchecked(offset);
1155 m_buffer->putByteUnchecked(MODRM(2, reg, X86::hasSib));
1156 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
1157 m_buffer->putIntUnchecked(offset);
1160 if (CAN_SIGN_EXTEND_8_32(offset)) {
1161 m_buffer->putByteUnchecked(MODRM(1, reg, base));
1162 m_buffer->putByteUnchecked(offset);
1164 m_buffer->putByteUnchecked(MODRM(2, reg, base));
1165 m_buffer->putIntUnchecked(offset);
1170 void emitModRm_rm(RegisterID reg, RegisterID base, int offset)
1172 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1173 emitModRm_rm_Unchecked(reg, base, offset);
1176 void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale)
1182 m_buffer->putByte(MODRM(0, reg, X86::hasSib));
1183 m_buffer->putByte(SIB(shift, index, base));
1186 void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset)
1192 if (CAN_SIGN_EXTEND_8_32(offset)) {
1193 m_buffer->putByte(MODRM(1, reg, X86::hasSib));
1194 m_buffer->putByte(SIB(shift, index, base));
1195 m_buffer->putByte(offset);
1197 m_buffer->putByte(MODRM(2, reg, X86::hasSib));
1198 m_buffer->putByte(SIB(shift, index, base));
1199 m_buffer->putInt(offset);
1203 void emitModRm_opr(OpcodeID opcode, RegisterID rm)
1205 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
1206 emitModRm_opr_Unchecked(opcode, rm);
1209 void emitModRm_opr_Unchecked(OpcodeID opcode, RegisterID rm)
1211 emitModRm_rr_Unchecked(static_cast<RegisterID>(opcode), rm);
1214 void emitModRm_opm(OpcodeID opcode, RegisterID base)
1216 emitModRm_rm(static_cast<RegisterID>(opcode), base);
1219 void emitModRm_opm_Unchecked(OpcodeID opcode, RegisterID base, int offset)
1221 emitModRm_rm_Unchecked(static_cast<RegisterID>(opcode), base, offset);
1224 void emitModRm_opm(OpcodeID opcode, RegisterID base, int offset)
1226 emitModRm_rm(static_cast<RegisterID>(opcode), base, offset);
1229 void emitModRm_opm(OpcodeID opcode, void* addr)
1231 emitModRm_rm(static_cast<RegisterID>(opcode), addr);
1234 void emitModRm_opmsib(OpcodeID opcode, RegisterID base, RegisterID index, int scale, int offset)
1236 emitModRm_rmsib(static_cast<RegisterID>(opcode), base, index, scale, offset);
1239 JITCodeBuffer* m_buffer;
1244 #endif // ENABLE(MASM) && PLATFORM(X86)
1246 #endif // X86Assembler_h