Exemple #1
0
void xImpl_Test::operator()( const xIndirect32orLess& dest, int imm ) const
{
	dest.prefix16();
	xWrite8( dest.Is8BitOp() ? 0xf6 : 0xf7 );
	EmitSibMagic( 0, dest );
	dest.xWriteImm( imm );
}
Exemple #2
0
void xImpl_Group2::operator()(const xRegisterInt& to, u8 imm ) const
{
	if( imm == 0 ) return;

	to.prefix16();
	if( imm == 1 )
	{
		// special encoding of 1's
		xWrite8( to.Is8BitOp() ? 0xd0 : 0xd1 );
		EmitSibMagic( InstType, to );
	}
	else
	{
		xWrite8( to.Is8BitOp() ? 0xc0 : 0xc1 );
		EmitSibMagic( InstType, to );
		xWrite8( imm );
	}
}
Exemple #3
0
void xImpl_Group2::operator()( const xIndirect32orLess& sibdest, u8 imm ) const
{
	if( imm == 0 ) return;

	sibdest.prefix16();
	if( imm == 1 )
	{
		// special encoding of 1's
		xWrite8( sibdest.Is8BitOp() ? 0xd0 : 0xd1 );
		EmitSibMagic( InstType, sibdest );
	}
	else
	{
		xWrite8( sibdest.Is8BitOp() ? 0xc0 : 0xc1 );
		EmitSibMagic( InstType, sibdest );
		xWrite8( imm );
	}
}
Exemple #4
0
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 );
	}
}
Exemple #5
0
//////////////////////////////////////////////////////////////////////////////////////////
// Conditionally generates Sib encoding information!
//
// regfield - register field to be written to the ModRm.  This is either a register specifier
//   or an opcode extension.  In either case, the instruction determines the value for us.
//
void EmitSibMagic(uint regfield, const xIndirectVoid &info)
{
    // 3 bits also on x86_64 (so max is 8)
    // We might need to mask it on x86_64
    pxAssertDev(regfield < 8, "Invalid x86 register identifier.");
    int displacement_size = (info.Displacement == 0) ? 0 :
                                                       ((info.IsByteSizeDisp()) ? 1 : 2);

    pxAssert(!info.Base.IsEmpty() || !info.Index.IsEmpty() || displacement_size == 2);

    if (!NeedsSibMagic(info)) {
        // Use ModRm-only encoding, with the rm field holding an index/base register, if
        // one has been specified.  If neither register is specified then use Disp32 form,
        // which is encoded as "EBP w/o displacement" (which is why EBP must always be
        // encoded *with* a displacement of 0, if it would otherwise not have one).

        if (info.Index.IsEmpty()) {
            EmitSibMagic(regfield, (void *)info.Displacement);
            return;
        } else {
            if (info.Index == ebp && displacement_size == 0)
                displacement_size = 1; // forces [ebp] to be encoded as [ebp+0]!

            ModRM(displacement_size, regfield, info.Index.Id);
        }
    } else {
        // In order to encode "just" index*scale (and no base), we have to encode
        // it as a special [index*scale + displacement] form, which is done by
        // specifying EBP as the base register and setting the displacement field
        // to zero. (same as ModRm w/o SIB form above, basically, except the
        // ModRm_UseDisp flag is specified in the SIB instead of the ModRM field).

        if (info.Base.IsEmpty()) {
            ModRM(0, regfield, ModRm_UseSib);
            SibSB(info.Scale, info.Index.Id, ModRm_UseDisp32);
            xWrite<s32>(info.Displacement);
            return;
        } else {
            if (info.Base == ebp && displacement_size == 0)
                displacement_size = 1; // forces [ebp] to be encoded as [ebp+0]!

            ModRM(displacement_size, regfield, ModRm_UseSib);
            SibSB(info.Scale, info.Index.Id, info.Base.Id);
        }
    }

    if (displacement_size != 0) {
        if (displacement_size == 1)
            xWrite<s8>(info.Displacement);
        else
            xWrite<s32>(info.Displacement);
    }
}
Exemple #6
0
void xImpl_IncDec::operator()( const xRegisterInt& to ) const
{
	if( to.Is8BitOp() )
	{
		xWrite8( 0xfe );
		EmitSibMagic( isDec ? 1 : 0, to );
	}
	else
	{
		to.prefix16();
		xWrite8( (isDec ? 0x48 : 0x40) | to.Id );
	}
}
Exemple #7
0
void xImpl_Test::operator()( const xRegisterInt& to, int imm ) const
{
	to.prefix16();

	if( to.IsAccumulator() )
		xWrite8( to.Is8BitOp() ? 0xa8 : 0xa9 );
	else
	{
		xWrite8( to.Is8BitOp() ? 0xf6 : 0xf7 );
		EmitSibMagic( 0, to );
	}
	to.xWriteImm( imm );
}
Exemple #8
0
static void _g1_EmitOp( G1Type InstType, const xIndirectVoid& sibdest, const xRegisterInt& from )
{
	from.prefix16();
	xWrite8( (from.Is8BitOp() ? 0 : 1) | (InstType<<3) );
	EmitSibMagic( from, sibdest );
}
Exemple #9
0
static void _g3_EmitOp( G3Type InstType, const xIndirect32orLess& from )
{
	from.prefix16();
	xWrite8( from.Is8BitOp() ? 0xf6 : 0xf7 );
	EmitSibMagic( InstType, from );
}
Exemple #10
0
static void _g3_EmitOp( G3Type InstType, const xRegisterInt& from )
{
	from.prefix16();
	xWrite8(from.Is8BitOp() ? 0xf6 : 0xf7 );
	EmitSibMagic( InstType, from );
}
Exemple #11
0
__emitinline void xOpWrite0F( u8 prefix, u16 opcode, int instId, const void* data )
{
	SimdPrefix( prefix, opcode );
	EmitSibMagic( instId, data );
}
Exemple #12
0
void xImpl_Group2::operator()( const xIndirect32orLess& sibdest, const xRegisterCL& /* from */ ) const
{
	sibdest.prefix16();
	xWrite8( sibdest.Is8BitOp() ? 0xd2 : 0xd3 );
	EmitSibMagic( InstType, sibdest );
}
Exemple #13
0
void EmitSibMagic( const xRegisterBase& reg1, const void* src )
{
	EmitSibMagic( reg1.Id, src );
}
Exemple #14
0
void xImpl_Test::operator()( const xRegister32& to, const xRegister32& from ) const
{
	xWrite8( 0x85 );
	EmitSibMagic( from, to );
}
Exemple #15
0
__emitinline void xPUSH( const xIndirectVoid& from )
{
	xWrite8( 0xff );
	EmitSibMagic( 6, from );
}
Exemple #16
0
//////////////////////////////////////////////////////////////////////////////////////////
// emitter helpers for xmm instruction with prefixes, most of which are using
// the basic opcode format (items inside braces denote optional or conditional
// emission):
//
//   [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB]
//
// Prefixes are typically 0x66, 0xf2, or 0xf3.  OpcodePrefixes are either 0x38 or
// 0x3a [and other value will result in assertion failue].
//
__emitinline void xOpWrite0F( u8 prefix, u16 opcode, int instId, const xIndirectVoid& sib )
{
	SimdPrefix( prefix, opcode );
	EmitSibMagic( instId, sib );
}
Exemple #17
0
void xImpl_IncDec::operator()( const xIndirect32orLess& to ) const
{
	to.prefix16();
	xWrite8( to.Is8BitOp() ? 0xfe : 0xff );
	EmitSibMagic( isDec ? 1 : 0, to );
}
Exemple #18
0
void EmitSibMagic( const xRegisterBase& reg1, const xIndirectVoid& sib )
{
	EmitSibMagic( reg1.Id, sib );
}
Exemple #19
0
static void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xIndirectVoid& sibsrc )
{
	to.prefix16();
	xWrite8( (to.Is8BitOp() ? 2 : 3) | (InstType<<3) );
	EmitSibMagic( to, sibsrc );
}
Exemple #20
0
void xImpl_Group2::operator()( const xRegisterInt& to, const xRegisterCL& /* from */ ) const
{
	to.prefix16();
	xWrite8( to.Is8BitOp() ? 0xd2 : 0xd3 );
	EmitSibMagic( InstType, to );
}
Exemple #21
0
__emitinline void xPOP( const xIndirectVoid& from )
{
	xWrite8( 0x8f );
	EmitSibMagic( 0, from );
}
Exemple #22
0
void xImpl_Test::operator()( const xRegister16& to, const xRegister16& from ) const
{
	to.prefix16();
	xWrite8( 0x85 );
	EmitSibMagic( from, to );
}