__emitinline void xAdvancePtr( uint bytes ) { if( IsDevBuild ) { // common debugger courtesy: advance with INT3 as filler. for( uint i=0; i<bytes; i++ ) xWrite8( 0xcc ); } else x86Ptr += bytes; }
static void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, int imm ) { to.prefix16(); if( !to.Is8BitOp() && is_s8( imm ) ) { xWrite8( 0x83 ); EmitSibMagic( InstType, to ); xWrite<s8>( imm ); } else { if( to.IsAccumulator() ) xWrite8( (to.Is8BitOp() ? 4 : 5) | (InstType<<3) ); else { xWrite8( to.Is8BitOp() ? 0x80 : 0x81 ); EmitSibMagic( InstType, to ); } to.xWriteImm( imm ); } }
xForwardJumpBase::xForwardJumpBase(uint opsize, JccComparisonType cctype) { pxAssert(opsize == 1 || opsize == 4); pxAssertDev(cctype != Jcc_Unknown, "Invalid ForwardJump conditional type."); BasePtr = (s8 *)xGetPtr() + ((opsize == 1) ? 2 : // j8's are always 2 bytes. ((cctype == Jcc_Unconditional) ? 5 : 6)); // j32's are either 5 or 6 bytes if (opsize == 1) xWrite8((cctype == Jcc_Unconditional) ? 0xeb : (0x70 | cctype)); else { if (cctype == Jcc_Unconditional) xWrite8(0xe9); else { xWrite8(0x0f); xWrite8(0x80 | cctype); } } xAdvancePtr(opsize); }
void xImpl_IncDec::operator()(const xRegisterInt &to) const { if (to.Is8BitOp()) { u8 regfield = isDec ? 1 : 0; xOpWrite(to.GetPrefix16(), 0xfe, regfield, to); } else { #ifdef __x86_64__ pxAssertMsg(0, "Single Byte INC/DEC aren't valid in 64 bits." "You need to use the ModR/M form (FF/0 FF/1 opcodes)"); #endif to.prefix16(); xWrite8((isDec ? 0x48 : 0x40) | to.Id); } }
static void _imul_ImmStyle( const xRegisterInt& param1, const SrcType& param2, int imm ) { // for iMul OpSize is allowed to be 16 or 32 bit only. const uint OpSize = param1.GetOperandSize(); pxAssert( OpSize == param2.GetOperandSize() ); pxAssert( OpSize > 1 ); xOpWrite0F( (OpSize == 2) ? 0x66 : 0, is_s8( imm ) ? 0x6b : 0x69, param1, param2 ); if( is_s8( imm ) ) xWrite8( (u8)imm ); else param1.xWriteImm( imm ); }
__fi void xCLC() { xWrite8( 0xF8 ); }
__fi void xSTC() { xWrite8( 0xF9 ); }
__emitinline void xPOP( const xIndirectVoid& from ) { xWrite8( 0x8f ); EmitSibMagic( 0, from ); }
static void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xIndirectVoid& sibsrc ) { to.prefix16(); xWrite8( (to.Is8BitOp() ? 2 : 3) | (InstType<<3) ); EmitSibMagic( to, sibsrc ); }
void xImpl_Group2::operator()( const xRegisterInt& to, const xRegisterCL& /* from */ ) const { to.prefix16(); xWrite8( to.Is8BitOp() ? 0xd2 : 0xd3 ); EmitSibMagic( InstType, to ); }
static void _g3_EmitOp( G3Type InstType, const xRegisterInt& from ) { from.prefix16(); xWrite8(from.Is8BitOp() ? 0xf6 : 0xf7 ); EmitSibMagic( InstType, from ); }
// pops the EFLAGS register from the stack __fi void xPOPFD() { xWrite8( 0x9D ); }
__fi void xLEAVE() { xWrite8( 0xC9 ); }
__fi void xPUSH( xRegister32 from ) { xWrite8( 0x50 | from.Id ); }
// pushes the EFLAGS register onto the stack __fi void xPUSHFD() { xWrite8( 0x9C ); }
__fi void xPUSH( u32 imm ) { xWrite8( 0x68 ); xWrite32( imm ); }
__fi void xPOP( xRegister32 from ) { xWrite8( 0x58 | from.Id ); }
__emitinline void xPUSH( const xIndirectVoid& from ) { xWrite8( 0xff ); EmitSibMagic( 6, from ); }
// NOP 1-byte __fi void xNOP() { xWrite8(0x90); }
__fi void xRET() { xWrite8( 0xC3 ); }
// ------------------------------------------------------------------------ // Emits a 32 bit jump, and returns a pointer to the 8 bit displacement. // (displacements should be assigned relative to the end of the jump instruction, // or in other words *(retval+1) ) __emitinline s8* xJcc8( JccComparisonType comparison, s8 displacement ) { xWrite8( (comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison) ); xWrite<s8>( displacement ); return (s8*)xGetPtr() - 1; }
__fi void xCDQ() { xWrite8( 0x99 ); }
void xImpl_Group2::operator()( const xIndirect32orLess& sibdest, const xRegisterCL& /* from */ ) const { sibdest.prefix16(); xWrite8( sibdest.Is8BitOp() ? 0xd2 : 0xd3 ); EmitSibMagic( InstType, sibdest ); }
void xImpl_Test::operator()( const xRegister32& to, const xRegister32& from ) const { xWrite8( 0x85 ); EmitSibMagic( from, to ); }
static void _g3_EmitOp( G3Type InstType, const xIndirect32orLess& from ) { from.prefix16(); xWrite8( from.Is8BitOp() ? 0xf6 : 0xf7 ); EmitSibMagic( InstType, from ); }
__fi void xLAHF() { xWrite8( 0x9f ); }
static void _g1_EmitOp( G1Type InstType, const xIndirectVoid& sibdest, const xRegisterInt& from ) { from.prefix16(); xWrite8( (from.Is8BitOp() ? 0 : 1) | (InstType<<3) ); EmitSibMagic( from, sibdest ); }
__fi void xSAHF() { xWrite8( 0x9e ); }
__fi void xCWDE() { xWrite8( 0x98 ); }
void xImpl_IncDec::operator()( const xIndirect32orLess& to ) const { to.prefix16(); xWrite8( to.Is8BitOp() ? 0xfe : 0xff ); EmitSibMagic( isDec ? 1 : 0, to ); }