示例#1
0
int ASM_Move_32(InstructionInfoStruct *CurInstruction)
{
	//output the bytes for a mov based on required setup
	switch(CurInstruction->Flags & FLAG_X86MASK)
	{
		case (FLAG_INX86REG | FLAG_OUTX86REG):
			*(u16 *)(DynaRecMemPtr) = (ModRM(0x03, CurInstruction->InReg, CurInstruction->OutReg) << 8) | 0x89;
			RegAssignment[CurInstruction->OutReg].Modified = 1;
			return 2;

		case (FLAG_VALUE | FLAG_OUTX86REG):
			*(u16 *)(DynaRecMemPtr) = (ModRM(0x03, 0, CurInstruction->OutReg) << 8) | 0xC7;
			*(u32 *)(DynaRecMemPtr+2) = CurInstruction->InMemPos;
			RegAssignment[CurInstruction->OutReg].Modified = 1;
			return 6;

		case (FLAG_INX86REG | FLAG_MEMORYOUT):
			*(u16 *)(DynaRecMemPtr) = (ModRM(0x00, CurInstruction->InReg, 0x05) << 8) | 0x89;
			*(u32 *)(DynaRecMemPtr+2) = (unsigned int)(CurInstruction->OutMemPos);
			return 6;

		case (FLAG_OUTX86REG | FLAG_MEMORYIN):
			*(u16 *)(DynaRecMemPtr) = (ModRM(0x00, CurInstruction->OutReg, 0x05) << 8) | 0x8B;
			*(u32 *)(DynaRecMemPtr+2) = (unsigned int)(CurInstruction->InMemPos);
			RegAssignment[CurInstruction->OutReg].Modified = 1;
			return 6;

		default:
			return 0;
	};
}
示例#2
0
int ASM_MoveZX_32(InstructionInfoStruct *CurInstruction)
{
	int Ret;

	//output the bytes for a mov based on required setup
	switch(CurInstruction->Flags & FLAG_X86MASK)
	{
		case (FLAG_INX86REG | FLAG_OUTX86REG):
			*(u16 *)(DynaRecMemPtr) = 0xb70f;
			*(u8 *)(DynaRecMemPtr+2) = ModRM(0x03, CurInstruction->OutReg, CurInstruction->InReg);
			RegAssignment[CurInstruction->OutReg].Modified = 1;
			return 3;

		case (FLAG_VALUE | FLAG_OUTX86REG):
			//write the value to a register
			Ret = ASM_Move(CurInstruction);

			//now movzx the register to itself
			*(u16 *)(DynaRecMemPtr+Ret) = 0xb70f;
			*(u8 *)(DynaRecMemPtr+2+Ret) = ModRM(0x03, CurInstruction->OutReg, CurInstruction->OutReg);
			RegAssignment[CurInstruction->OutReg].Modified = 1;
			return Ret+3;
		default:
			return 0;
	};
}
示例#3
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);
    }
}
示例#4
0
int ASM_MoveB_ToRegMemPtr(InstructionInfoStruct *CurInstruction)
{
	switch(CurInstruction->Flags & FLAG_X86MASK)
	{
		case (FLAG_INX86REG | FLAG_OUTX86REG):
			*(u16 *)(DynaRecMemPtr) = (ModRM(0x00, CurInstruction->InReg, CurInstruction->OutReg) << 8) | 0x88;
			return 2;

		case (FLAG_VALUE | FLAG_OUTX86REG):
			*(u16 *)(DynaRecMemPtr) = (ModRM(0x00, 0, CurInstruction->OutReg) << 8) | 0xC6;
			*(u8 *)(DynaRecMemPtr+2) = CurInstruction->InVal & 0xFF;
			return 3;

		default:
			return 0;
	};
}
示例#5
0
int ASM_Move_ToRegMemPtr(InstructionInfoStruct *CurInstruction)
{
	switch(CurInstruction->Flags & FLAG_X86MASK)
	{
		case (FLAG_INX86REG | FLAG_OUTX86REG):
			*(u8 *)DynaRecMemPtr = 0x66;
			*(u16 *)(DynaRecMemPtr+1) = (ModRM(0x00, CurInstruction->InReg, CurInstruction->OutReg) << 8) | 0x89;
			return 3;

		case (FLAG_VALUE | FLAG_OUTX86REG):
			*(u8 *)DynaRecMemPtr = 0x66;
			*(u16 *)(DynaRecMemPtr+1) = (ModRM(0x00, 0, CurInstruction->OutReg) << 8) | 0xC7;
			*(u16 *)(DynaRecMemPtr+3) = CurInstruction->InVal;
			return 5;

		default:
			return 0;
	};
}
示例#6
0
void EmitSibMagic( uint regfield, const void* address )
{
	ModRM( 0, regfield, ModRm_UseDisp32 );

	// SIB encoding only supports 32bit offsets, even on x86_64
	// We must make sure that the displacement is within the 32bit range
	// Else we will fail out in a spectacular fashion
	sptr displacement = (sptr)address;
	pxAssertDev(displacement >= -0x80000000LL && displacement < 0x80000000LL, "SIB target is too far away, needs an indirect register");

	xWrite<s32>( (s32)displacement );
}
示例#7
0
int ASM_MoveZX_FromRegMemPtr(InstructionInfoStruct *CurInstruction)
{
	switch(CurInstruction->Flags & FLAG_X86MASK)
	{
		case (FLAG_INX86REG | FLAG_OUTX86REG):
			*(u16 *)(DynaRecMemPtr) = 0xb60f;
			*(u8 *)(DynaRecMemPtr+2) = ModRM(0x00, CurInstruction->OutReg, CurInstruction->InReg);
			RegAssignment[CurInstruction->OutReg].Modified = 1;
			return 3;

		default:
			return 0;
	};
}
示例#8
0
/* fistp m32 from fpu reg stack */
void FISTP32( u32 from ) 
{
	write8( 0xDB );
	ModRM( 0, 0x3, DISP32 );
	write32( MEMADDR(from, 4) ); 
}
示例#9
0
文件: fpu.cpp 项目: Aced14/pcsx2
/* fstp m32 from fpu reg stack */
emitterT void FSTP32( u32 to )
{
	xWrite8( 0xD9 );
	ModRM( 0, 0x3, DISP32 );
	xWrite32( MEMADDR(to, 4) );
}
示例#10
0
/* fnstcw fpu control word to m16 */
void FNSTCW( u32 to ) 
{
	write8( 0xD9 );
	ModRM( 0, 0x7, DISP32 );
	write32( MEMADDR(to, 4) ); 
}
示例#11
0
文件: fpu.cpp 项目: Aced14/pcsx2
/* fld m32 to fpu reg stack */
emitterT void FLD32( u32 from )
{
	xWrite8( 0xD9 );
	ModRM( 0, 0x0, DISP32 );
	xWrite32( MEMADDR(from, 4) );
}
示例#12
0
	/*
		0: Opcode
		1: Register Target
		2: Short/Long
		3: mem-reg, reg/reg, mem-reg/mem-reg
		4~5: mod rm info
	*/
	BYTE option[6];
}	INSTRUCTIONS;

static const INSTRUCTIONS inst_info[] = {
	{"ERR",	PREFIX::_PF_ERR},

	// Priority: Short > EAX > Long
	{"ADD", PREFIX::_PF_ATH, 0x83, 0, 0, (BYTE)PREFIX::_PF_RM, ModRM(3,(int)ExtensionGroup1::add,0)},
	{"ADD", PREFIX::_PF_ATH, 0x05, AX|EXX, 0, (BYTE)PREFIX::_PF_RM},
	{"ADD", PREFIX::_PF_ATH, 0x81, 0, 1, (BYTE)PREFIX::_PF_RM, ModRM(3,(int)ExtensionGroup1::add,0)},
	{"ADD", PREFIX::_PF_ATH, 0x03, 0, 0, (BYTE)PREFIX::_PF_MR},

	{"AND", PREFIX::_PF_LOC, 0x83, 0, 0, (BYTE)PREFIX::_PF_RM, ModRM(3,(int)ExtensionGroup1::and,0)},
	{"AND", PREFIX::_PF_LOC, 0x25, AX|EXX, 0, (BYTE)PREFIX::_PF_RM},
	{"AND", PREFIX::_PF_LOC, 0x81, 0, 1, (BYTE)PREFIX::_PF_RM, ModRM(3,(int)ExtensionGroup1::and,0)},
	{"AND", PREFIX::_PF_LOC, 0x23, 0, 0, (BYTE)PREFIX::_PF_MR},
	
	{ "OR", PREFIX::_PF_LOC, 0x83, 0, 0, (BYTE)PREFIX::_PF_RM, ModRM(3,(int)ExtensionGroup1::or,0)},
	{ "OR", PREFIX::_PF_LOC, 0x0d, AX|EXX, 0, (BYTE)PREFIX::_PF_RM},
	{ "OR", PREFIX::_PF_LOC, 0x81, 0, 1, (BYTE)PREFIX::_PF_RM, ModRM(3,(int)ExtensionGroup1::or,0)},
	{ "OR", PREFIX::_PF_LOC, 0x0b, 0, 0, (BYTE)PREFIX::_PF_MR},
	
	{"SUB", PREFIX::_PF_ATH, 0x83, 0, 0, 0, ModRM(3,(int)ExtensionGroup1::sub,0)},
示例#13
0
/* fcomp m32 to fpu reg stack */
void FCOMP32( u32 from )
{
	write8( 0xD8 );
	ModRM( 0, 0x3, DISP32 );
	write32( MEMADDR(from, 4) ); 
}
示例#14
0
/* fdiv m32 to fpu reg stack */
void FDIV32( u32 from ) 
{
	write8( 0xD8 );
	ModRM( 0, 0x6, DISP32 );
	write32( MEMADDR(from, 4) ); 
}
示例#15
0
/* fmul m32 to fpu reg stack */
void FMUL32( u32 from )
{
	write8( 0xD8 );
	ModRM( 0, 0x1, DISP32 );
	write32( MEMADDR(from, 4) ); 
}
示例#16
0
/* fsub m32 to fpu reg stack */
void FSUB32( u32 from ) 
{
	write8( 0xD8 );
	ModRM( 0, 0x4, DISP32 );
	write32( MEMADDR(from, 4) ); 
}
示例#17
0
文件: fpu.cpp 项目: Aced14/pcsx2
/* fmul m32 to fpu reg stack */
emitterT void FMUL32( u32 from )
{
	xWrite8( 0xD8 );
	ModRM( 0, 0x1, DISP32 );
	xWrite32( MEMADDR(from, 4) );
}
示例#18
0
// ------------------------------------------------------------------------
// Internal implementation of EmitSibMagic which has been custom tailored
// to optimize special forms of the Lea instructions accordingly, such
// as when a LEA can be replaced with a "MOV reg,imm" or "MOV reg,reg".
//
// preserve_flags - set to ture to disable use of SHL on [Index*Base] forms
// of LEA, which alters flags states.
//
static void EmitLeaMagic( const xRegisterInt& to, const xIndirectVoid& src, bool preserve_flags )
{
	int displacement_size = (src.Displacement == 0) ? 0 :
		( ( src.IsByteSizeDisp() ) ? 1 : 2 );

	// See EmitSibMagic for commenting on SIB encoding.

	if( !NeedsSibMagic( src ) )
	{
		// LEA Land: means we have either 1-register encoding or just an offset.
		// offset is encodable as an immediate MOV, and a register is encodable
		// as a register MOV.

		if( src.Index.IsEmpty() )
		{
			xMOV( to, src.Displacement );
			return;
		}
		else if( displacement_size == 0 )
		{
			_xMovRtoR( to, src.Index );
			return;
		}
		else
		{
			if( !preserve_flags )
			{
				// encode as MOV and ADD combo.  Make sure to use the immediate on the
				// ADD since it can encode as an 8-bit sign-extended value.

				_xMovRtoR( to, src.Index );
				xADD( to, src.Displacement );
				return;
			}
			else
			{
				// note: no need to do ebp+0 check since we encode all 0 displacements as
				// register assignments above (via MOV)

				xWrite8( 0x8d );
				ModRM( displacement_size, to.Id, src.Index.Id );
			}
		}
	}
	else
	{
		if( src.Base.IsEmpty() )
		{
			if( !preserve_flags && (displacement_size == 0) )
			{
				// Encode [Index*Scale] as a combination of Mov and Shl.
				// This is more efficient because of the bloated LEA format which requires
				// a 32 bit displacement, and the compact nature of the alternative.
				//
				// (this does not apply to older model P4s with the broken barrel shifter,
				//  but we currently aren't optimizing for that target anyway).

				_xMovRtoR( to, src.Index );
				xSHL( to, src.Scale );
				return;
			}
			xWrite8( 0x8d );
			ModRM( 0, to.Id, ModRm_UseSib );
			SibSB( src.Scale, src.Index.Id, ModRm_UseDisp32 );
			xWrite32( src.Displacement );
			return;
		}
		else
		{
			if( src.Scale == 0 )
			{
				if( !preserve_flags )
				{
					if( src.Index == esp )
					{
						// ESP is not encodable as an index (ix86 ignores it), thus:
						_xMovRtoR( to, src.Base );	// will do the trick!
						if( src.Displacement ) xADD( to, src.Displacement );
						return;
					}
					else if( src.Displacement == 0 )
					{
						_xMovRtoR( to, src.Base );
						_g1_EmitOp( G1Type_ADD, to, src.Index );
						return;
					}
				}
				else if( (src.Index == esp) && (src.Displacement == 0) )
				{
					// special case handling of ESP as Index, which is replaceable with
					// a single MOV even when preserve_flags is set! :D

					_xMovRtoR( to, src.Base );
					return;
				}
			}

			if( src.Base == ebp && displacement_size == 0 )
				displacement_size = 1;		// forces [ebp] to be encoded as [ebp+0]!

			xWrite8( 0x8d );
			ModRM( displacement_size, to.Id, ModRm_UseSib );
			SibSB( src.Scale, src.Index.Id, src.Base.Id );
		}
	}

	if( displacement_size != 0 )
	{
		if( displacement_size == 1 )
			xWrite<s8>( src.Displacement );
		else
			xWrite<s32>( src.Displacement );
	}
}
示例#19
0
/* fstp m32 from fpu reg stack */
void FSTP32( u32 to )
{
	write8( 0xD9 );
	ModRM( 0, 0x3, DISP32 );
	write32( MEMADDR(to, 4) ); 
}
示例#20
0
#include "x86.hpp"

std::vector<x86_insn_mnemonic>  x86_format_table = {
  {"mov", { {0x88, DFDX_OPC_MOV, true,ModRM(), 0},
            {0x89, DFDX_OPC_MOV, false, ModRM(), 0},
            {0x8a, DFDX_OPC_MOV, true, ModRM(), 1},
            {0x8b, DFDX_OPC_MOV, false, ModRM(), 1},
    },
  },

  {"add", { {0x04, DFDX_OPC_ADD, false, Imm8(), 1},
            {0x05, DFDX_OPC_ADD, false, Imm(), 1},
            {0x80, DFDX_OPC_ADD, true, ModRM_Imm(), 0},
            {0x81, DFDX_OPC_ADD, false, ModRM_Imm(), 0},
            {0x83, DFDX_OPC_ADD, false, ModRM_Op_Imm8(0), 0},
            {0x00, DFDX_OPC_ADD, true, ModRM(), 0},
            {0x01, DFDX_OPC_ADD, false, ModRM(), 0},
            {0x02, DFDX_OPC_ADD, true, ModRM(), 1},
            {0x03, DFDX_OPC_ADD, false, ModRM(), 1},
    },
  },

  {"sub", { {0x2c, DFDX_OPC_SUB, false, Imm8(), 1},
            {0x2d, DFDX_OPC_SUB, false, Imm(), 1},
            {0x80, DFDX_OPC_SUB, true, ModRM_Op_Imm8(5), 0},
            {0x81, DFDX_OPC_SUB, false, ModRM_Op_Imm(5), 0},
            {0x83, DFDX_OPC_SUB, false, ModRM_Op_Imm8(5), 0},
            {0x28, DFDX_OPC_SUB, true, ModRM(), 0},
            {0x29, DFDX_OPC_SUB, false, ModRM(), 0},
            {0x2a, DFDX_OPC_SUB, true, ModRM(), 1},
            {0x2b, DFDX_OPC_SUB, false, ModRM(), 1},
示例#21
0
/* fldcw fpu control word from m16 */
void FLDCW( u32 from )
{
	write8( 0xD9 );
	ModRM( 0, 0x5, DISP32 );
	write32( MEMADDR(from, 4) ); 
}