📄 x86assembler.h
字号:
{ m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, offset); } void movq_rm_disp32(RegisterID src, int offset, RegisterID base) { m_formatter.oneByteOp64_disp32(OP_MOV_EvGv, src, base, offset); } void movq_rm(RegisterID src, int offset, RegisterID base, RegisterID index, int scale) { m_formatter.oneByteOp64(OP_MOV_EvGv, src, base, index, scale, offset); } void movq_mEAX(void* addr) { m_formatter.oneByteOp64(OP_MOV_EAXOv); m_formatter.immediate64(reinterpret_cast<int64_t>(addr)); } void movq_mr(int offset, RegisterID base, RegisterID dst) { m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, offset); } void movq_mr_disp32(int offset, RegisterID base, RegisterID dst) { m_formatter.oneByteOp64_disp32(OP_MOV_GvEv, dst, base, offset); } void movq_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) { m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset); } void movq_i32m(int imm, int offset, RegisterID base) { m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset); m_formatter.immediate32(imm); } void movq_i64r(int64_t imm, RegisterID dst) { m_formatter.oneByteOp64(OP_MOV_EAXIv, dst); m_formatter.immediate64(imm); } void movsxd_rr(RegisterID src, RegisterID dst) { m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src); } #else void movl_mr(void* addr, RegisterID dst) { if (dst == X86::eax) movl_mEAX(addr); else m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr); } void movl_i32m(int imm, void* addr) { m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr); m_formatter.immediate32(imm); }#endif void movzwl_mr(int offset, RegisterID base, RegisterID dst) { m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, offset); } void movzwl_mr(int offset, RegisterID base, RegisterID index, int scale, RegisterID dst) { m_formatter.twoByteOp(OP2_MOVZX_GvEw, dst, base, index, scale, offset); } void movzbl_rr(RegisterID src, RegisterID dst) { // In 64-bit, this may cause an unnecessary REX to be planted (if the dst register // is in the range ESP-EDI, and the src would not have required a REX). Unneeded // REX prefixes are defined to be silently ignored by the processor. m_formatter.twoByteOp8(OP2_MOVZX_GvEb, dst, src); } void leal_mr(int offset, RegisterID base, RegisterID dst) { m_formatter.oneByteOp(OP_LEA, dst, base, offset); } // Flow control: JmpSrc call() { m_formatter.oneByteOp(OP_CALL_rel32); return m_formatter.immediateRel32(); } JmpSrc call(RegisterID dst) { m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_CALLN, dst); return JmpSrc(m_formatter.size()); } JmpSrc jmp() { m_formatter.oneByteOp(OP_JMP_rel32); return m_formatter.immediateRel32(); } // Return a JmpSrc so we have a label to the jump, so we can use this // To make a tail recursive call on x86-64. The MacroAssembler // really shouldn't wrap this as a Jump, since it can't be linked. :-/ JmpSrc jmp_r(RegisterID dst) { m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, dst); return JmpSrc(m_formatter.size()); } void jmp_m(int offset, RegisterID base) { m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, base, offset); } JmpSrc jne() { m_formatter.twoByteOp(jccRel32(ConditionNE)); return m_formatter.immediateRel32(); } JmpSrc jnz() { return jne(); } JmpSrc je() { m_formatter.twoByteOp(jccRel32(ConditionE)); return m_formatter.immediateRel32(); } JmpSrc jl() { m_formatter.twoByteOp(jccRel32(ConditionL)); return m_formatter.immediateRel32(); } JmpSrc jb() { m_formatter.twoByteOp(jccRel32(ConditionB)); return m_formatter.immediateRel32(); } JmpSrc jle() { m_formatter.twoByteOp(jccRel32(ConditionLE)); return m_formatter.immediateRel32(); } JmpSrc jbe() { m_formatter.twoByteOp(jccRel32(ConditionBE)); return m_formatter.immediateRel32(); } JmpSrc jge() { m_formatter.twoByteOp(jccRel32(ConditionGE)); return m_formatter.immediateRel32(); } JmpSrc jg() { m_formatter.twoByteOp(jccRel32(ConditionG)); return m_formatter.immediateRel32(); } JmpSrc ja() { m_formatter.twoByteOp(jccRel32(ConditionA)); return m_formatter.immediateRel32(); } JmpSrc jae() { m_formatter.twoByteOp(jccRel32(ConditionAE)); return m_formatter.immediateRel32(); } JmpSrc jo() { m_formatter.twoByteOp(jccRel32(ConditionO)); return m_formatter.immediateRel32(); } JmpSrc jp() { m_formatter.twoByteOp(jccRel32(ConditionP)); return m_formatter.immediateRel32(); } JmpSrc js() { m_formatter.twoByteOp(jccRel32(ConditionS)); return m_formatter.immediateRel32(); } JmpSrc jCC(Condition cond) { m_formatter.twoByteOp(jccRel32(cond)); return m_formatter.immediateRel32(); } // SSE operations: void addsd_rr(XMMRegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, (RegisterID)src); } void addsd_mr(int offset, RegisterID base, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, base, offset); } void cvtsi2sd_rr(RegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, src); } void cvttsd2si_rr(XMMRegisterID src, RegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_CVTTSD2SI_GdWsd, dst, (RegisterID)src); } void movd_rr(XMMRegisterID src, RegisterID dst) { m_formatter.prefix(PRE_SSE_66); m_formatter.twoByteOp(OP2_MOVD_EdVd, (RegisterID)src, dst); }#if PLATFORM(X86_64) void movq_rr(XMMRegisterID src, RegisterID dst) { m_formatter.prefix(PRE_SSE_66); m_formatter.twoByteOp64(OP2_MOVD_EdVd, (RegisterID)src, dst); } void movq_rr(RegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_66); m_formatter.twoByteOp64(OP2_MOVD_VdEd, (RegisterID)dst, src); }#endif void movsd_rm(XMMRegisterID src, int offset, RegisterID base) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, base, offset); } void movsd_mr(int offset, RegisterID base, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, base, offset); } void mulsd_rr(XMMRegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, (RegisterID)src); } void mulsd_mr(int offset, RegisterID base, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_MULSD_VsdWsd, (RegisterID)dst, base, offset); } void pextrw_irr(int whichWord, XMMRegisterID src, RegisterID dst) { m_formatter.prefix(PRE_SSE_66); m_formatter.twoByteOp(OP2_PEXTRW_GdUdIb, (RegisterID)dst, (RegisterID)src); m_formatter.immediate8(whichWord); } void subsd_rr(XMMRegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, (RegisterID)src); } void subsd_mr(int offset, RegisterID base, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_F2); m_formatter.twoByteOp(OP2_SUBSD_VsdWsd, (RegisterID)dst, base, offset); } void ucomisd_rr(XMMRegisterID src, XMMRegisterID dst) { m_formatter.prefix(PRE_SSE_66); m_formatter.twoByteOp(OP2_UCOMISD_VsdWsd, (RegisterID)dst, (RegisterID)src); } // Misc instructions: void int3() { m_formatter.oneByteOp(OP_INT3); } void ret() { m_formatter.oneByteOp(OP_RET); } void predictNotTaken() { m_formatter.prefix(PRE_PREDICT_BRANCH_NOT_TAKEN); } // Assembler admin methods: JmpDst label() { return JmpDst(m_formatter.size()); } JmpDst align(int alignment) { while (!m_formatter.isAligned(alignment)) m_formatter.oneByteOp(OP_HLT); return label(); } // Linking & patching: void linkJump(JmpSrc from, JmpDst to) { ASSERT(to.m_offset != -1); ASSERT(from.m_offset != -1); reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset; } static void linkJump(void* code, JmpSrc from, void* to) { ASSERT(from.m_offset != -1); ptrdiff_t linkOffset = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset); ASSERT(linkOffset == static_cast<int>(linkOffset)); reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = linkOffset; } static void patchJump(intptr_t where, void* destination) { intptr_t offset = reinterpret_cast<intptr_t>(destination) - where; ASSERT(offset == static_cast<int32_t>(offset)); reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset); } #if PLATFORM(X86_64) // FIXME: transition these functions out of here - the assembler // shouldn't know that that this is mov/call pair using r11. :-/ static void patchMacroAssemblerCall(intptr_t where, void* destination) { patchAddress(reinterpret_cast<void*>(where - REPTACH_OFFSET_CALL_R11), JmpDst(0), destination); }#else static void patchMacroAssemblerCall(intptr_t where, void* destination) { intptr_t offset = reinterpret_cast<intptr_t>(destination) - where; ASSERT(offset == static_cast<int32_t>(offset)); reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset); }#endif void linkCall(JmpSrc from, JmpDst to) { ASSERT(to.m_offset != -1); ASSERT(from.m_offset != -1); reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset; } static void linkCall(void* code, JmpSrc from, void* to) { ASSERT(from.m_offset != -1); ptrdiff_t linkOffset = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset); ASSERT(linkOffset == static_cast<int>(linkOffset)); reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = linkOffset; } static void patchCall(intptr_t where, void* destination) { intptr_t offset = reinterpret_cast<intptr_t>(destination) - where; ASSERT(offset == static_cast<int32_t>(offset)); reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset); } static void patchAddress(void* code, JmpDst position, void* value) { ASSERT(position.m_offset != -1); reinterpret_cast<void**>(reinterpret_cast<ptrdiff_t>(code) + position.m_offset)[-1] = value; } static unsigned getCallReturnOffset(JmpSrc call) { ASSERT(call.m_offset >= 0); return call.m_offset; } static void* getRelocatedAddress(void* code, JmpSrc jump) { return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + jump.m_offset); } static void* getRelocatedAddress(void* code, JmpDst destination) { ASSERT(destination.m_offset != -1); return reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(code) + destination.m_offset); } static int getDifferenceBetweenLabels(JmpDst src, JmpDst dst) { return dst.m_offset - src.m_offset; } static int getDifferenceBetweenLabels(JmpDst src, JmpSrc dst) { return dst.m_offset - src.m_offset; } static int getDifferenceBetweenLabels(JmpSrc src, JmpDst dst) { return dst.m_offset - src.m_offset; } static void patchImmediate(intptr_t where, int32_t value) { reinterpret_cast<int32_t*>(where)[-1] = value; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -