📄 macroassemblerx86common.h
字号:
else m_assembler.movl_i32r(imm.m_value, dest); }#if PLATFORM(X86_64) void move(RegisterID src, RegisterID dest) { // Note: on 64-bit this is is a full register move; perhaps it would be // useful to have separate move32 & movePtr, with move32 zero extending? m_assembler.movq_rr(src, dest); } void move(ImmPtr imm, RegisterID dest) { if (CAN_SIGN_EXTEND_U32_64(imm.asIntptr())) m_assembler.movl_i32r(static_cast<int32_t>(imm.asIntptr()), dest); else m_assembler.movq_i64r(imm.asIntptr(), dest); } void swap(RegisterID reg1, RegisterID reg2) { m_assembler.xchgq_rr(reg1, reg2); } void signExtend32ToPtr(RegisterID src, RegisterID dest) { m_assembler.movsxd_rr(src, dest); } void zeroExtend32ToPtr(RegisterID src, RegisterID dest) { m_assembler.movl_rr(src, dest); }#else void move(RegisterID src, RegisterID dest) { m_assembler.movl_rr(src, dest); } void move(ImmPtr imm, RegisterID dest) { m_assembler.movl_i32r(imm.asIntptr(), dest); } void swap(RegisterID reg1, RegisterID reg2) { m_assembler.xchgl_rr(reg1, reg2); } void signExtend32ToPtr(RegisterID src, RegisterID dest) { if (src != dest) move(src, dest); } void zeroExtend32ToPtr(RegisterID src, RegisterID dest) { if (src != dest) move(src, dest); }#endif // Forwards / external control flow operations: // // This set of jump and conditional branch operations return a Jump // object which may linked at a later point, allow forwards jump, // or jumps that will require external linkage (after the code has been // relocated). // // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge // respecitvely, for unsigned comparisons the names b, a, be, and ae are // used (representing the names 'below' and 'above'). // // Operands to the comparision are provided in the expected order, e.g. // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when // treated as a signed 32bit value, is less than or equal to 5. // // jz and jnz test whether the first operand is equal to zero, and take // an optional second operand of a mask under which to perform the test.public: Jump branch32(Condition cond, RegisterID left, RegisterID right) { m_assembler.cmpl_rr(right, left); return Jump(m_assembler.jCC(cond)); } Jump branch32(Condition cond, RegisterID left, Imm32 right) { if (((cond == Equal) || (cond == NotEqual)) && !right.m_value) m_assembler.testl_rr(left, left); else m_assembler.cmpl_ir(right.m_value, left); return Jump(m_assembler.jCC(cond)); } Jump branch32(Condition cond, RegisterID left, Address right) { m_assembler.cmpl_mr(right.offset, right.base, left); return Jump(m_assembler.jCC(cond)); } Jump branch32(Condition cond, Address left, RegisterID right) { m_assembler.cmpl_rm(right, left.offset, left.base); return Jump(m_assembler.jCC(cond)); } Jump branch32(Condition cond, Address left, Imm32 right) { m_assembler.cmpl_im(right.m_value, left.offset, left.base); return Jump(m_assembler.jCC(cond)); } Jump branch16(Condition cond, BaseIndex left, RegisterID right) { m_assembler.cmpw_rm(right, left.offset, left.base, left.index, left.scale); return Jump(m_assembler.jCC(cond)); } Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask) { ASSERT((cond == Zero) || (cond == NonZero)); m_assembler.testl_rr(reg, mask); return Jump(m_assembler.jCC(cond)); } Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1)) { ASSERT((cond == Zero) || (cond == NonZero)); // if we are only interested in the low seven bits, this can be tested with a testb if (mask.m_value == -1) m_assembler.testl_rr(reg, reg); else if ((mask.m_value & ~0x7f) == 0) m_assembler.testb_i8r(mask.m_value, reg); else m_assembler.testl_i32r(mask.m_value, reg); return Jump(m_assembler.jCC(cond)); } Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1)) { ASSERT((cond == Zero) || (cond == NonZero)); if (mask.m_value == -1) m_assembler.cmpl_im(0, address.offset, address.base); else m_assembler.testl_i32m(mask.m_value, address.offset, address.base); return Jump(m_assembler.jCC(cond)); } Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1)) { ASSERT((cond == Zero) || (cond == NonZero)); if (mask.m_value == -1) m_assembler.cmpl_im(0, address.offset, address.base, address.index, address.scale); else m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale); return Jump(m_assembler.jCC(cond)); } Jump jump() { return Jump(m_assembler.jmp()); } void jump(RegisterID target) { m_assembler.jmp_r(target); } // Address is a memory location containing the address to jump to void jump(Address address) { m_assembler.jmp_m(address.offset, address.base); } // Arithmetic control flow operations: // // This set of conditional branch operations branch based // on the result of an arithmetic operation. The operation // is performed as normal, storing the result. // // * jz operations branch if the result is zero. // * jo operations branch if the (signed) arithmetic // operation caused an overflow to occur. Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); add32(src, dest); return Jump(m_assembler.jCC(cond)); } Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); add32(imm, dest); return Jump(m_assembler.jCC(cond)); } Jump branchMul32(Condition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); mul32(src, dest); return Jump(m_assembler.jCC(cond)); } Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); mul32(imm, src, dest); return Jump(m_assembler.jCC(cond)); } Jump branchSub32(Condition cond, RegisterID src, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); sub32(src, dest); return Jump(m_assembler.jCC(cond)); } Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest) { ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero)); sub32(imm, dest); return Jump(m_assembler.jCC(cond)); } // Miscellaneous operations: void breakpoint() { m_assembler.int3(); } Call nearCall() { return Call(m_assembler.call(), Call::LinkableNear); } Call call(RegisterID target) { return Call(m_assembler.call(target), Call::None); } void ret() { m_assembler.ret(); } void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest) { m_assembler.cmpl_rr(right, left); m_assembler.setCC_r(cond, dest); m_assembler.movzbl_rr(dest, dest); } void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest) { if (((cond == Equal) || (cond == NotEqual)) && !right.m_value) m_assembler.testl_rr(left, left); else m_assembler.cmpl_ir(right.m_value, left); m_assembler.setCC_r(cond, dest); m_assembler.movzbl_rr(dest, dest); } // FIXME: // The mask should be optional... paerhaps the argument order should be // dest-src, operations always have a dest? ... possibly not true, considering // asm ops like test, or pseudo ops like pop(). void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest) { if (mask.m_value == -1) m_assembler.cmpl_im(0, address.offset, address.base); else m_assembler.testl_i32m(mask.m_value, address.offset, address.base); m_assembler.setCC_r(cond, dest); m_assembler.movzbl_rr(dest, dest); }};} // namespace JSC#endif // ENABLE(ASSEMBLER)#endif // MacroAssemblerX86Common_h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -