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 *(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))
169 typedef X86::RegisterID RegisterID;
175 OP_2BYTE_ESCAPE = 0x0F,
179 PRE_PREDICT_BRANCH_NOT_TAKEN = 0x2E,
184 PRE_OPERAND_SIZE = 0x66,
185 OP_IMUL_GvEvIz = 0x69,
186 OP_GROUP1_EvIz = 0x81,
187 OP_GROUP1_EvIb = 0x83,
192 OP_GROUP1A_Ev = 0x8F,
195 OP_GROUP2_EvIb = 0xC1,
197 OP_GROUP11_EvIz = 0xC7,
199 OP_GROUP2_Ev1 = 0xD1,
200 OP_GROUP2_EvCL = 0xD3,
201 OP_CALL_rel32 = 0xE8,
204 OP_GROUP3_EvIz = 0xF7, // OP_GROUP3_Ev has an immediate, when instruction is a test.
209 OP2_JAE_rel32 = 0x83,
211 OP2_JNE_rel32 = 0x85,
212 OP2_JBE_rel32 = 0x86,
215 OP2_JGE_rel32 = 0x8D,
216 OP2_JLE_rel32 = 0x8E,
217 OP2_IMUL_GvEv = 0xAF,
218 OP2_MOVZX_GvEb = 0xB6,
219 OP2_MOVZX_GvEw = 0xB7,
243 static const int MAX_INSTRUCTION_SIZE = 16;
245 X86Assembler(JITCodeBuffer* m_buffer)
253 m_buffer->putByte(OP_INT3);
256 void pushl_r(RegisterID reg)
258 m_buffer->putByte(OP_PUSH_EAX + reg);
261 void pushl_m(int offset, RegisterID base)
263 m_buffer->putByte(OP_GROUP5_Ev);
264 emitModRm_opm(GROUP5_OP_PUSH, base, offset);
267 void popl_r(RegisterID reg)
269 m_buffer->putByte(OP_POP_EAX + reg);
272 void popl_m(int offset, RegisterID base)
274 m_buffer->putByte(OP_GROUP1A_Ev);
275 emitModRm_opm(GROUP1A_OP_POP, base, offset);
278 void movl_rr(RegisterID src, RegisterID dst)
280 m_buffer->putByte(OP_MOV_EvGv);
281 emitModRm_rr(src, dst);
284 void addl_rr(RegisterID src, RegisterID dst)
286 m_buffer->putByte(OP_ADD_EvGv);
287 emitModRm_rr(src, dst);
290 void addl_i8r(int imm, RegisterID dst)
292 m_buffer->putByte(OP_GROUP1_EvIb);
293 emitModRm_opr(GROUP1_OP_ADD, dst);
294 m_buffer->putByte(imm);
297 void addl_i8m(int imm, void* addr)
299 m_buffer->putByte(OP_GROUP1_EvIb);
300 emitModRm_opm(GROUP1_OP_ADD, addr);
301 m_buffer->putByte(imm);
304 void addl_i32r(int imm, RegisterID dst)
306 m_buffer->putByte(OP_GROUP1_EvIz);
307 emitModRm_opr(GROUP1_OP_ADD, dst);
308 m_buffer->putInt(imm);
311 void addl_mr(int offset, RegisterID base, RegisterID dst)
313 m_buffer->putByte(OP_ADD_GvEv);
314 emitModRm_rm(dst, base, offset);
317 void andl_rr(RegisterID src, RegisterID dst)
319 m_buffer->putByte(OP_AND_EvGv);
320 emitModRm_rr(src, dst);
323 void andl_i32r(int imm, RegisterID dst)
325 m_buffer->putByte(OP_GROUP1_EvIz);
326 emitModRm_opr(GROUP1_OP_AND, dst);
327 m_buffer->putInt(imm);
330 void cmpl_i8r(int imm, RegisterID dst)
332 m_buffer->putByte(OP_GROUP1_EvIb);
333 emitModRm_opr(GROUP1_OP_CMP, dst);
334 m_buffer->putByte(imm);
337 void cmpl_rr(RegisterID src, RegisterID dst)
339 m_buffer->putByte(OP_CMP_EvGv);
340 emitModRm_rr(src, dst);
343 void cmpl_rm(RegisterID src, int offset, RegisterID base)
345 m_buffer->putByte(OP_CMP_EvGv);
346 emitModRm_rm(src, base, offset);
349 void cmpl_i32r(int imm, RegisterID dst)
351 m_buffer->putByte(OP_GROUP1_EvIz);
352 emitModRm_opr(GROUP1_OP_CMP, dst);
353 m_buffer->putInt(imm);
356 void cmpl_i32m(int imm, RegisterID dst)
358 m_buffer->putByte(OP_GROUP1_EvIz);
359 emitModRm_opm(GROUP1_OP_CMP, dst);
360 m_buffer->putInt(imm);
363 void cmpl_i32m(int imm, int offset, RegisterID dst)
365 m_buffer->putByte(OP_GROUP1_EvIz);
366 emitModRm_opm(GROUP1_OP_CMP, dst, offset);
367 m_buffer->putInt(imm);
370 void cmpl_i32m(int imm, void* addr)
372 m_buffer->putByte(OP_GROUP1_EvIz);
373 emitModRm_opm(GROUP1_OP_CMP, addr);
374 m_buffer->putInt(imm);
377 void cmpl_i8m(int imm, int offset, RegisterID base, RegisterID index, int scale)
379 m_buffer->putByte(OP_GROUP1_EvIb);
380 emitModRm_opmsib(GROUP1_OP_CMP, base, index, scale, offset);
381 m_buffer->putByte(imm);
384 void cmpw_rm(RegisterID src, RegisterID base, RegisterID index, int scale)
386 m_buffer->putByte(PRE_OPERAND_SIZE);
387 m_buffer->putByte(OP_CMP_EvGv);
388 emitModRm_rmsib(src, base, index, scale);
391 void sete_r(RegisterID dst)
393 m_buffer->putByte(OP_2BYTE_ESCAPE);
394 m_buffer->putByte(OP_SETE);
395 m_buffer->putByte(MODRM(3, 0, dst));
398 void setz_r(RegisterID dst)
403 void orl_rr(RegisterID src, RegisterID dst)
405 m_buffer->putByte(OP_OR_EvGv);
406 emitModRm_rr(src, dst);
409 void orl_i32r(int imm, RegisterID dst)
411 m_buffer->putByte(OP_GROUP1_EvIb);
412 emitModRm_opr(GROUP1_OP_OR, dst);
413 m_buffer->putByte(imm);
416 void subl_rr(RegisterID src, RegisterID dst)
418 m_buffer->putByte(OP_SUB_EvGv);
419 emitModRm_rr(src, dst);
422 void subl_i8r(int imm, RegisterID dst)
424 m_buffer->putByte(OP_GROUP1_EvIb);
425 emitModRm_opr(GROUP1_OP_SUB, dst);
426 m_buffer->putByte(imm);
429 void subl_i8m(int imm, void* addr)
431 m_buffer->putByte(OP_GROUP1_EvIb);
432 emitModRm_opm(GROUP1_OP_SUB, addr);
433 m_buffer->putByte(imm);
436 void subl_i32r(int imm, RegisterID dst)
438 m_buffer->putByte(OP_GROUP1_EvIz);
439 emitModRm_opr(GROUP1_OP_SUB, dst);
440 m_buffer->putInt(imm);
443 void subl_mr(int offset, RegisterID base, RegisterID dst)
445 m_buffer->putByte(OP_SUB_GvEv);
446 emitModRm_rm(dst, base, offset);
449 void testl_i32r(int imm, RegisterID dst)
451 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
452 m_buffer->putByteUnchecked(OP_GROUP3_EvIz);
453 emitModRm_opr_Unchecked(GROUP3_OP_TEST, dst);
454 m_buffer->putIntUnchecked(imm);
457 void testl_rr(RegisterID src, RegisterID dst)
459 m_buffer->putByte(OP_TEST_EvGv);
460 emitModRm_rr(src, dst);
463 void xorl_i8r(int imm, RegisterID dst)
465 m_buffer->putByte(OP_GROUP1_EvIb);
466 emitModRm_opr(GROUP1_OP_XOR, dst);
467 m_buffer->putByte(imm);
470 void xorl_rr(RegisterID src, RegisterID dst)
472 m_buffer->putByte(OP_XOR_EvGv);
473 emitModRm_rr(src, dst);
476 void sarl_i8r(int imm, RegisterID dst)
479 m_buffer->putByte(OP_GROUP2_Ev1);
480 emitModRm_opr(GROUP2_OP_SAR, dst);
482 m_buffer->putByte(OP_GROUP2_EvIb);
483 emitModRm_opr(GROUP2_OP_SAR, dst);
484 m_buffer->putByte(imm);
488 void sarl_CLr(RegisterID dst)
490 m_buffer->putByte(OP_GROUP2_EvCL);
491 emitModRm_opr(GROUP2_OP_SAR, dst);
494 void shl_i8r(int imm, RegisterID dst)
497 m_buffer->putByte(OP_GROUP2_Ev1);
498 emitModRm_opr(GROUP2_OP_SHL, dst);
500 m_buffer->putByte(OP_GROUP2_EvIb);
501 emitModRm_opr(GROUP2_OP_SHL, dst);
502 m_buffer->putByte(imm);
506 void shll_CLr(RegisterID dst)
508 m_buffer->putByte(OP_GROUP2_EvCL);
509 emitModRm_opr(GROUP2_OP_SHL, dst);
512 void imull_rr(RegisterID src, RegisterID dst)
514 m_buffer->putByte(OP_2BYTE_ESCAPE);
515 m_buffer->putByte(OP2_IMUL_GvEv);
516 emitModRm_rr(dst, src);
519 void imull_i32r(RegisterID src, int32_t value, RegisterID dst)
521 m_buffer->putByte(OP_IMUL_GvEvIz);
522 emitModRm_rr(dst, src);
523 m_buffer->putInt(value);
526 void idivl_r(RegisterID dst)
528 m_buffer->putByte(OP_GROUP3_Ev);
529 emitModRm_opr(GROUP3_OP_IDIV, dst);
534 m_buffer->putByte(OP_CDQ);
537 void movl_mr(RegisterID base, RegisterID dst)
539 m_buffer->putByte(OP_MOV_GvEv);
540 emitModRm_rm(dst, base);
543 void movl_mr(int offset, RegisterID base, RegisterID dst)
545 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
546 m_buffer->putByteUnchecked(OP_MOV_GvEv);
547 emitModRm_rm_Unchecked(dst, base, offset);
550 void movl_mr(void* addr, RegisterID dst)
552 m_buffer->putByte(OP_MOV_GvEv);
553 emitModRm_rm(dst, addr);
556 void movl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
558 m_buffer->putByte(OP_MOV_GvEv);
559 emitModRm_rmsib(dst, base, index, scale, offset);
562 void movzbl_rr(RegisterID src, RegisterID dst)
564 m_buffer->putByte(OP_2BYTE_ESCAPE);
565 m_buffer->putByte(OP2_MOVZX_GvEb);
566 emitModRm_rr(dst, src);
569 void movzwl_mr(int offset, RegisterID base, RegisterID dst)
571 m_buffer->putByte(OP_2BYTE_ESCAPE);
572 m_buffer->putByte(OP2_MOVZX_GvEw);
573 emitModRm_rm(dst, base, offset);
576 void movzwl_mr(RegisterID base, RegisterID index, int scale, RegisterID dst)
578 m_buffer->putByte(OP_2BYTE_ESCAPE);
579 m_buffer->putByte(OP2_MOVZX_GvEw);
580 emitModRm_rmsib(dst, base, index, scale);
583 void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst)
585 m_buffer->putByte(OP_2BYTE_ESCAPE);
586 m_buffer->putByte(OP2_MOVZX_GvEw);
587 emitModRm_rmsib(dst, base, index, scale, offset);
590 void movl_rm(RegisterID src, RegisterID base)
592 m_buffer->putByte(OP_MOV_EvGv);
593 emitModRm_rm(src, base);
596 void movl_rm(RegisterID src, int offset, RegisterID base)
598 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
599 m_buffer->putByteUnchecked(OP_MOV_EvGv);
600 emitModRm_rm_Unchecked(src, base, offset);
603 void movl_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale)
605 m_buffer->putByte(OP_MOV_EvGv);
606 emitModRm_rmsib(src, base, index, scale, offset);
609 void movl_i32r(int imm, RegisterID dst)
611 m_buffer->putByte(OP_GROUP11_EvIz);
612 emitModRm_opr(GROUP11_MOV, dst);
613 m_buffer->putInt(imm);
616 void movl_i32m(int imm, int offset, RegisterID base)
618 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
619 m_buffer->putByteUnchecked(OP_GROUP11_EvIz);
620 emitModRm_opm_Unchecked(GROUP11_MOV, base, offset);
621 m_buffer->putIntUnchecked(imm);
624 void movl_i32m(int imm, void* addr)
626 m_buffer->putByte(OP_GROUP11_EvIz);
627 emitModRm_opm(GROUP11_MOV, addr);
628 m_buffer->putInt(imm);
631 void leal_mr(int offset, RegisterID base, RegisterID dst)
633 m_buffer->putByte(OP_LEA);
634 emitModRm_rm(dst, base, offset);
639 m_buffer->putByte(OP_RET);
642 void jmp_r(RegisterID dst)
644 m_buffer->putByte(OP_GROUP5_Ev);
645 emitModRm_opr(GROUP5_OP_JMPN, dst);
648 void jmp_m(int offset, RegisterID base)
650 m_buffer->putByte(OP_GROUP5_Ev);
651 emitModRm_opm(GROUP5_OP_JMPN, base, offset);
654 void call_r(RegisterID dst)
656 m_buffer->putByte(OP_GROUP5_Ev);
657 emitModRm_opr(GROUP5_OP_CALLN, dst);
660 // Opaque label types
663 friend class X86Assembler;
680 friend class X86Assembler;
696 // FIXME: make this point to a global label, linked later.
699 m_buffer->putByte(OP_CALL_rel32);
701 return JmpSrc(m_buffer->getOffset());
706 return JmpDst(m_buffer->getOffset());
709 JmpSrc emitUnlinkedJmp()
711 m_buffer->putByte(OP_JMP_rel32);
713 return JmpSrc(m_buffer->getOffset());
716 JmpSrc emitUnlinkedJne()
718 m_buffer->putByte(OP_2BYTE_ESCAPE);
719 m_buffer->putByte(OP2_JNE_rel32);
721 return JmpSrc(m_buffer->getOffset());
724 JmpSrc emitUnlinkedJnz()
726 return emitUnlinkedJne();
729 JmpSrc emitUnlinkedJe()
731 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
732 m_buffer->putByteUnchecked(OP_2BYTE_ESCAPE);
733 m_buffer->putByteUnchecked(OP2_JE_rel32);
734 m_buffer->putIntUnchecked(0);
735 return JmpSrc(m_buffer->getOffset());
738 JmpSrc emitUnlinkedJl()
740 m_buffer->putByte(OP_2BYTE_ESCAPE);
741 m_buffer->putByte(OP2_JL_rel32);
743 return JmpSrc(m_buffer->getOffset());
746 JmpSrc emitUnlinkedJb()
748 m_buffer->putByte(OP_2BYTE_ESCAPE);
749 m_buffer->putByte(OP2_JB_rel32);
751 return JmpSrc(m_buffer->getOffset());
754 JmpSrc emitUnlinkedJle()
756 m_buffer->putByte(OP_2BYTE_ESCAPE);
757 m_buffer->putByte(OP2_JLE_rel32);
759 return JmpSrc(m_buffer->getOffset());
762 JmpSrc emitUnlinkedJbe()
764 m_buffer->putByte(OP_2BYTE_ESCAPE);
765 m_buffer->putByte(OP2_JBE_rel32);
767 return JmpSrc(m_buffer->getOffset());
770 JmpSrc emitUnlinkedJge()
772 m_buffer->putByte(OP_2BYTE_ESCAPE);
773 m_buffer->putByte(OP2_JGE_rel32);
775 return JmpSrc(m_buffer->getOffset());
778 JmpSrc emitUnlinkedJa()
780 m_buffer->putByte(OP_2BYTE_ESCAPE);
781 m_buffer->putByte(OP2_JA_rel32);
783 return JmpSrc(m_buffer->getOffset());
786 JmpSrc emitUnlinkedJae()
788 m_buffer->putByte(OP_2BYTE_ESCAPE);
789 m_buffer->putByte(OP2_JAE_rel32);
791 return JmpSrc(m_buffer->getOffset());
794 JmpSrc emitUnlinkedJo()
796 m_buffer->putByte(OP_2BYTE_ESCAPE);
797 m_buffer->putByte(OP2_JO_rel32);
799 return JmpSrc(m_buffer->getOffset());
802 void emitPredictionNotTaken()
804 m_buffer->putByte(PRE_PREDICT_BRANCH_NOT_TAKEN);
807 void link(JmpSrc from, JmpDst to)
809 ASSERT(to.m_offset != -1);
810 ASSERT(from.m_offset != -1);
812 ((int*)(((ptrdiff_t)(m_buffer->start())) + from.m_offset))[-1] = to.m_offset - from.m_offset;
815 static void linkAbsoluteAddress(void* code, JmpDst useOffset, JmpDst address)
817 ASSERT(useOffset.m_offset != -1);
818 ASSERT(address.m_offset != -1);
820 ((int*)(((ptrdiff_t)code) + useOffset.m_offset))[-1] = ((ptrdiff_t)code) + address.m_offset;
823 static void link(void* code, JmpSrc from, void* to)
825 ASSERT(from.m_offset != -1);
827 ((int*)((ptrdiff_t)code + from.m_offset))[-1] = (ptrdiff_t)to - ((ptrdiff_t)code + from.m_offset);
830 static void* getRelocatedAddress(void* code, JmpSrc jump)
832 return reinterpret_cast<void*>((ptrdiff_t)code + jump.m_offset);
835 static void* getRelocatedAddress(void* code, JmpDst jump)
837 return reinterpret_cast<void*>((ptrdiff_t)code + jump.m_offset);
840 static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst)
842 return dst.m_offset - src.m_offset;
845 static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst)
847 return dst.m_offset - src.m_offset;
850 static void repatchImmediate(intptr_t where, int32_t value)
852 reinterpret_cast<int32_t*>(where)[-1] = value;
855 static void repatchDisplacement(intptr_t where, intptr_t value)
857 reinterpret_cast<intptr_t*>(where)[-1] = value;
860 static void repatchBranchOffset(intptr_t where, void* destination)
862 reinterpret_cast<intptr_t*>(where)[-1] = (reinterpret_cast<intptr_t>(destination) - where);
867 return m_buffer->copy();
871 void emitConvertToFastCall()
873 movl_mr(4, X86::esp, X86::eax);
874 movl_mr(8, X86::esp, X86::edx);
875 movl_mr(12, X86::esp, X86::ecx);
878 void emitRestoreArgumentReference()
880 movl_rm(X86::esp, 0, X86::esp);
883 void emitConvertToFastCall() {};
884 void emitRestoreArgumentReference() {};
888 void emitModRm_rr(RegisterID reg, RegisterID rm)
890 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
891 emitModRm_rr_Unchecked(reg, rm);
894 void emitModRm_rr_Unchecked(RegisterID reg, RegisterID rm)
896 m_buffer->putByteUnchecked(MODRM(3, reg, rm));
899 void emitModRm_rm(RegisterID reg, void* addr)
901 m_buffer->putByte(MODRM(0, reg, X86::noBase));
902 m_buffer->putInt((int)addr);
905 void emitModRm_rm(RegisterID reg, RegisterID base)
907 if (base == X86::esp) {
908 m_buffer->putByte(MODRM(0, reg, X86::hasSib));
909 m_buffer->putByte(SIB(0, X86::noScale, X86::esp));
911 m_buffer->putByte(MODRM(0, reg, base));
914 void emitModRm_rm_Unchecked(RegisterID reg, RegisterID base, int offset)
916 if (base == X86::esp) {
917 if (CAN_SIGN_EXTEND_8_32(offset)) {
918 m_buffer->putByteUnchecked(MODRM(1, reg, X86::hasSib));
919 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
920 m_buffer->putByteUnchecked(offset);
922 m_buffer->putByteUnchecked(MODRM(2, reg, X86::hasSib));
923 m_buffer->putByteUnchecked(SIB(0, X86::noScale, X86::esp));
924 m_buffer->putIntUnchecked(offset);
927 if (CAN_SIGN_EXTEND_8_32(offset)) {
928 m_buffer->putByteUnchecked(MODRM(1, reg, base));
929 m_buffer->putByteUnchecked(offset);
931 m_buffer->putByteUnchecked(MODRM(2, reg, base));
932 m_buffer->putIntUnchecked(offset);
937 void emitModRm_rm(RegisterID reg, RegisterID base, int offset)
939 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
940 emitModRm_rm_Unchecked(reg, base, offset);
943 void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale)
949 m_buffer->putByte(MODRM(0, reg, X86::hasSib));
950 m_buffer->putByte(SIB(shift, index, base));
953 void emitModRm_rmsib(RegisterID reg, RegisterID base, RegisterID index, int scale, int offset)
959 if (CAN_SIGN_EXTEND_8_32(offset)) {
960 m_buffer->putByte(MODRM(1, reg, X86::hasSib));
961 m_buffer->putByte(SIB(shift, index, base));
962 m_buffer->putByte(offset);
964 m_buffer->putByte(MODRM(2, reg, X86::hasSib));
965 m_buffer->putByte(SIB(shift, index, base));
966 m_buffer->putInt(offset);
970 void emitModRm_opr(OpcodeID opcode, RegisterID rm)
972 m_buffer->ensureSpace(MAX_INSTRUCTION_SIZE);
973 emitModRm_opr_Unchecked(opcode, rm);
976 void emitModRm_opr_Unchecked(OpcodeID opcode, RegisterID rm)
978 emitModRm_rr_Unchecked(static_cast<RegisterID>(opcode), rm);
981 void emitModRm_opm(OpcodeID opcode, RegisterID base)
983 emitModRm_rm(static_cast<RegisterID>(opcode), base);
986 void emitModRm_opm_Unchecked(OpcodeID opcode, RegisterID base, int offset)
988 emitModRm_rm_Unchecked(static_cast<RegisterID>(opcode), base, offset);
991 void emitModRm_opm(OpcodeID opcode, RegisterID base, int offset)
993 emitModRm_rm(static_cast<RegisterID>(opcode), base, offset);
996 void emitModRm_opm(OpcodeID opcode, void* addr)
998 emitModRm_rm(static_cast<RegisterID>(opcode), addr);
1001 void emitModRm_opmsib(OpcodeID opcode, RegisterID base, RegisterID index, int scale, int offset)
1003 emitModRm_rmsib(static_cast<RegisterID>(opcode), base, index, scale, offset);
1006 JITCodeBuffer* m_buffer;
1011 #endif // ENABLE(MASM) && PLATFORM(X86)
1013 #endif // X86Assembler_h