diff --git a/pcsx2/x86/ix86/ix86.h b/pcsx2/x86/ix86/ix86.h index 3151de883f..939ff21e48 100644 --- a/pcsx2/x86/ix86/ix86.h +++ b/pcsx2/x86/ix86/ix86.h @@ -46,9 +46,16 @@ extern __threadlocal u8 *x86Ptr; extern __threadlocal u8 *j8Ptr[32]; extern __threadlocal u32 *j32Ptr[32]; +template< typename T > +static emitterT void x86write( T val ) +{ + *(T*)x86Ptr = val; + x86Ptr += sizeof(T); +} + static emitterT void write8( u8 val ) { - *x86Ptr = (u8)val; + *x86Ptr = val; x86Ptr++; } @@ -271,9 +278,9 @@ extern void ADD32MtoR( x86IntRegType to, uptr from ); // add r16 to r16 extern void ADD16RtoR( x86IntRegType to , x86IntRegType from ); // add imm16 to r16 -extern void ADD16ItoR( x86IntRegType to, s16 from ); +extern void ADD16ItoR( x86IntRegType to, u16 imm ); // add imm16 to m16 -extern void ADD16ItoM( uptr to, s16 from ); +extern void ADD16ItoM( uptr to, u16 imm ); // add r16 to m16 extern void ADD16RtoM( uptr to, x86IntRegType from ); // add m16 to r16 @@ -313,7 +320,7 @@ extern void SUB32MtoR( x86IntRegType to, uptr from ) ; // sub r32 to m32 extern void SUB32RtoM( uptr to, x86IntRegType from ); // sub r16 to r16 -extern void SUB16RtoR( x86IntRegType to, u16 from ); +extern void SUB16RtoR( x86IntRegType to, x86IntRegType from ); // sub imm16 to r16 extern void SUB16ItoR( x86IntRegType to, u16 from ); // sub imm16 to m16 @@ -643,12 +650,6 @@ extern void CMP32ItoM( uptr to, u32 from ); extern void CMP32RtoR( x86IntRegType to, x86IntRegType from ); // cmp m32 to r32 extern void CMP32MtoR( x86IntRegType to, uptr from ); -// cmp imm32 to [r32] -extern void CMP32I8toRm( x86IntRegType to, u8 from); -// cmp imm32 to [r32+off] -extern void CMP32I8toRm8( x86IntRegType to, u8 from, u8 off); -// cmp imm8 to [r32] -extern void CMP32I8toM( uptr to, u8 from); // cmp imm16 to r16 extern void CMP16ItoR( x86IntRegType to, u16 from ); diff --git a/pcsx2/x86/ix86/ix86_group1.cpp b/pcsx2/x86/ix86/ix86_group1.cpp index 1af689e82c..190550e1eb 100644 --- a/pcsx2/x86/ix86/ix86_group1.cpp +++ b/pcsx2/x86/ix86/ix86_group1.cpp @@ -46,13 +46,27 @@ enum Group1InstructionType }; -emitterT void Group1_32( Group1InstructionType inst, x86Register to, x86Register from ) +static emitterT void Group1( Group1InstructionType inst, x86Register to, x86Register from ) { write8( 0x01 | (inst<<3) ); ModRM( 3, from.Id, to.Id ); } -emitterT void Group1_32( Group1InstructionType inst, x86Register to, u32 imm ) +static emitterT void Group1( Group1InstructionType inst, const ModSib& sibdest, x86Register from ) +{ + write8( 0x01 | (inst<<3) ); + EmitSibMagic( from, sibdest ); +} + +/* add m32 to r32 */ +static emitterT void Group1( Group1InstructionType inst, x86Register to, const ModSib& sibsrc ) +{ + write8( 0x03 | (inst<<3) ); + EmitSibMagic( to, sibsrc ); +} + +template< typename T > +static emitterT void Group1_Imm( Group1InstructionType inst, x86Register to, T imm ) { if( is_s8( imm ) ) { @@ -69,11 +83,12 @@ emitterT void Group1_32( Group1InstructionType inst, x86Register to, u32 imm ) write8( 0x81 ); ModRM( 3, inst, to.Id ); } - write32( imm ); + x86write( imm ); } } -emitterT void Group1_32( Group1InstructionType inst, const ModSib& sibdest, u32 imm ) +template< typename T > +static emitterT void Group1_Imm( Group1InstructionType inst, const ModSib& sibdest, T imm ) { write8( is_s8( imm ) ? 0x83 : 0x81 ); @@ -82,23 +97,10 @@ emitterT void Group1_32( Group1InstructionType inst, const ModSib& sibdest, u32 if( is_s8( imm ) ) write8( (s8)imm ); else - write32( imm ); + x86write( imm ); } -emitterT void Group1_32( Group1InstructionType inst, const ModSib& sibdest, x86Register from ) -{ - write8( 0x01 | (inst<<3) ); - EmitSibMagic( from, sibdest ); -} - -/* add m32 to r32 */ -emitterT void Group1_32( Group1InstructionType inst, x86Register to, const ModSib& sibsrc ) -{ - write8( 0x03 | (inst<<3) ); - EmitSibMagic( to, sibsrc ); -} - -emitterT void Group1_8( Group1InstructionType inst, x86Register to, s8 imm ) +static emitterT void Group1_8( Group1InstructionType inst, x86Register to, s8 imm ) { if( to == eax ) { @@ -113,28 +115,30 @@ emitterT void Group1_8( Group1InstructionType inst, x86Register to, s8 imm ) } } +// 16 bit instruction prefix! +static __forceinline void prefix16() { write8(0x66); } +static __forceinline x86Register cvt2reg( x86Register16 src ) { return x86Register( src.Id ); } + ////////////////////////////////////////////////////////////////////////////////////////// // #define DEFINE_GROUP1_OPCODE( lwr, cod ) \ - emitterT void lwr##32( x86Register to, x86Register from ) { Group1_32( G1Type_##cod, to, from ); } \ - emitterT void lwr##32( x86Register to, u32 imm ) { Group1_32( G1Type_##cod, to, imm ); } \ - emitterT void lwr##32( x86Register to, void* from ) { Group1_32( G1Type_##cod, to, ptr[from] ); } \ - emitterT void lwr##32( void* to, x86Register from ) { Group1_32( G1Type_##cod, ptr[to], from ); } \ - emitterT void lwr##32( void* to, u32 imm ) { Group1_32( G1Type_##cod, ptr[to], imm ); } \ - emitterT void lwr##32( x86Register to, const x86ModRm& from ) { Group1_32( G1Type_##cod, to, ptr[from] ); } \ - emitterT void lwr##32( const x86ModRm& to, x86Register from ) { Group1_32( G1Type_##cod, ptr[to], from ); } \ - emitterT void lwr##32( const x86ModRm& to, u32 imm ) { Group1_32( G1Type_##cod, ptr[to], imm ); } - -/* - emitterT void lwr##16( x86Register16 to, x86Register16 from ) { Group1_32( G1Type_##cod, to, from ); } \ - emitterT void lwr##16( x86Register16 to, u16 imm ) { Group1_32( G1Type_##cod, to, imm ); } \ - emitterT void lwr##16( x86Register16 to, void* from ) { Group1_32( G1Type_##cod, to, ptr[from] ); } \ - emitterT void lwr##16( void* to, x86Register16 from ) { Group1_32( G1Type_##cod, ptr[to], from ); } \ - emitterT void lwr##16( void* to, u16 imm ) { Group1_32( G1Type_##cod, ptr[to], imm ); } \ - emitterT void lwr##16( x86Register16 to, const x86ModRm& from ){ Group1_32( G1Type_##cod, to, ptr[from] ); } \ - emitterT void lwr##16( const x86ModRm& to, x86Register16 from ){ Group1_32( G1Type_##cod, ptr[to], from ); } \ - emitterT void lwr##16( const x86ModRm& to, u32 imm ) { Group1_32( G1Type_##cod, ptr[to], imm ); } -*/ + emitterT void lwr##32( x86Register to, x86Register from ) { Group1( G1Type_##cod, to, from ); } \ + emitterT void lwr##32( x86Register to, void* from ) { Group1( G1Type_##cod, to, ptr[from] ); } \ + emitterT void lwr##32( void* to, x86Register from ) { Group1( G1Type_##cod, ptr[to], from ); } \ + emitterT void lwr##32( x86Register to, const x86ModRm& from ) { Group1( G1Type_##cod, to, ptr[from] ); } \ + emitterT void lwr##32( const x86ModRm& to, x86Register from ) { Group1( G1Type_##cod, ptr[to], from ); } \ + emitterT void lwr##32( x86Register to, u32 imm ) { Group1_Imm( G1Type_##cod, to, imm ); } \ + emitterT void lwr##32( void* to, u32 imm ) { Group1_Imm( G1Type_##cod, ptr[to], imm ); } \ + emitterT void lwr##32( const x86ModRm& to, u32 imm ) { Group1_Imm( G1Type_##cod, ptr[to], imm ); } \ + \ + emitterT void lwr##16( x86Register16 to, x86Register16 from ) { prefix16(); Group1( G1Type_##cod, cvt2reg(to), cvt2reg(from) ); } \ + emitterT void lwr##16( x86Register16 to, void* from ) { prefix16(); Group1( G1Type_##cod, cvt2reg(to), ptr[from] ); } \ + emitterT void lwr##16( void* to, x86Register16 from ) { prefix16(); Group1( G1Type_##cod, ptr[to], cvt2reg(from) ); } \ + emitterT void lwr##16( x86Register16 to, const x86ModRm& from ){ prefix16(); Group1( G1Type_##cod, cvt2reg(to), ptr[from] ); } \ + emitterT void lwr##16( const x86ModRm& to, x86Register16 from ){ prefix16(); Group1( G1Type_##cod, ptr[to], cvt2reg(from) ); } \ + emitterT void lwr##16( x86Register16 to, u16 imm ) { prefix16(); Group1_Imm( G1Type_##cod, cvt2reg(to), imm ); } \ + emitterT void lwr##16( void* to, u16 imm ) { prefix16(); Group1_Imm( G1Type_##cod, ptr[to], imm ); } \ + emitterT void lwr##16( const x86ModRm& to, u16 imm ) { prefix16(); Group1_Imm( G1Type_##cod, ptr[to], imm ); } DEFINE_GROUP1_OPCODE( add, ADD ); DEFINE_GROUP1_OPCODE( cmp, CMP ); @@ -153,6 +157,10 @@ static __forceinline x86Emitter::x86Register _reghlp( x86IntRegType src ) return x86Emitter::x86Register( src ); } +static __forceinline x86Emitter::x86Register16 _reghlp16( x86IntRegType src ) +{ + return x86Emitter::x86Register16( src ); +} static __forceinline x86Emitter::x86ModRm _mrmhlp( x86IntRegType src ) { @@ -164,12 +172,21 @@ static __forceinline x86Emitter::x86ModRm _mrmhlp( x86IntRegType src ) #define DEFINE_GROUP1_OPCODE_LEGACY( lwr, cod ) \ emitterT void cod##32RtoR( x86IntRegType to, x86IntRegType from ) { x86Emitter::lwr##32( _reghlp(to), _reghlp(from) ); } \ emitterT void cod##32ItoR( x86IntRegType to, u32 imm ) { x86Emitter::lwr##32( _reghlp(to), imm ); } \ - emitterT void cod##32MtoR( x86IntRegType to, uptr from ) { x86Emitter::lwr##32( _reghlp(to), (void*)from ); } \ - emitterT void cod##32RtoM( uptr to, x86IntRegType from ) { x86Emitter::lwr##32( (void*)to, _reghlp(from) ); } \ + emitterT void cod##32MtoR( x86IntRegType to, uptr from ) { x86Emitter::lwr##32( _reghlp(to), (void*)from ); } \ + emitterT void cod##32RtoM( uptr to, x86IntRegType from ) { x86Emitter::lwr##32( (void*)to, _reghlp(from) ); } \ emitterT void cod##32ItoM( uptr to, u32 imm ) { x86Emitter::lwr##32( (void*)to, imm ); } \ - emitterT void cod##32ItoRm( x86IntRegType to, u32 imm, int offset ){ x86Emitter::lwr##32( _mrmhlp(to) + offset, imm ); } \ + emitterT void cod##32ItoRm( x86IntRegType to, u32 imm, int offset ) { x86Emitter::lwr##32( _mrmhlp(to) + offset, imm ); } \ emitterT void cod##32RmtoR( x86IntRegType to, x86IntRegType from, int offset ) { x86Emitter::lwr##32( _reghlp(to), _mrmhlp(from) + offset ); } \ - emitterT void cod##32RtoRm( x86IntRegType to, x86IntRegType from, int offset ) { x86Emitter::lwr##32( _mrmhlp(to) + offset, _reghlp(from) ); } + emitterT void cod##32RtoRm( x86IntRegType to, x86IntRegType from, int offset ) { x86Emitter::lwr##32( _mrmhlp(to) + offset, _reghlp(from) ); } \ + \ + emitterT void cod##16RtoR( x86IntRegType to, x86IntRegType from ) { x86Emitter::lwr##16( _reghlp16(to), _reghlp16(from) ); } \ + emitterT void cod##16ItoR( x86IntRegType to, u16 imm ) { x86Emitter::lwr##16( _reghlp16(to), imm ); } \ + emitterT void cod##16MtoR( x86IntRegType to, uptr from ) { x86Emitter::lwr##16( _reghlp16(to), (void*)from ); } \ + emitterT void cod##16RtoM( uptr to, x86IntRegType from ) { x86Emitter::lwr##16( (void*)to, _reghlp16(from) ); } \ + emitterT void cod##16ItoM( uptr to, u16 imm ) { x86Emitter::lwr##16( (void*)to, imm ); } \ + emitterT void cod##16ItoRm( x86IntRegType to, u16 imm, int offset ) { x86Emitter::lwr##16( _mrmhlp(to) + offset, imm ); } \ + emitterT void cod##16RmtoR( x86IntRegType to, x86IntRegType from, int offset ) { x86Emitter::lwr##16( _reghlp16(to), _mrmhlp(from) + offset ); } \ + emitterT void cod##16RtoRm( x86IntRegType to, x86IntRegType from, int offset ) { x86Emitter::lwr##16( _mrmhlp(to) + offset, _reghlp16(from) ); } DEFINE_GROUP1_OPCODE_LEGACY( add, ADD ); DEFINE_GROUP1_OPCODE_LEGACY( cmp, CMP ); @@ -180,6 +197,8 @@ DEFINE_GROUP1_OPCODE_LEGACY( and, AND ); DEFINE_GROUP1_OPCODE_LEGACY( sub, SUB ); DEFINE_GROUP1_OPCODE_LEGACY( xor, XOR ); +// Special forms needed by the legacy emitter syntax: + emitterT void AND32I8toR( x86IntRegType to, s8 from ) { x86Emitter::and32( _reghlp(to), from ); diff --git a/pcsx2/x86/ix86/ix86_legacy.cpp b/pcsx2/x86/ix86/ix86_legacy.cpp index 8a99058c02..3f4134836c 100644 --- a/pcsx2/x86/ix86/ix86_legacy.cpp +++ b/pcsx2/x86/ix86/ix86_legacy.cpp @@ -802,80 +802,6 @@ emitterT void CMOVLE32MtoR( x86IntRegType to, uptr from ) // arithmetic instructions / //////////////////////////////////// -// add r16 to r16 -emitterT void ADD16RtoR( x86IntRegType to , x86IntRegType from ) -{ - write8(0x66); - RexRB(0,to,from); - write8( 0x03 ); - ModRM( 3, to, from ); -} - -/* add imm16 to r16 */ -emitterT void ADD16ItoR( x86IntRegType to, s16 imm ) -{ - write8( 0x66 ); - RexB(0,to); - - if (to == EAX) - { - write8( 0x05 ); - write16( imm ); - } - else if(is_s8(imm)) - { - write8( 0x83 ); - ModRM( 3, 0, to ); - write8((u8)imm ); - } - else - { - write8( 0x81 ); - ModRM( 3, 0, to ); - write16( imm ); - } -} - -/* add imm16 to m16 */ -emitterT void ADD16ItoM( uptr to, s16 imm ) -{ - write8( 0x66 ); - if(is_s8(imm)) - { - write8( 0x83 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 6) ); - write8((u8)imm ); - } - else - { - write8( 0x81 ); - ModRM( 0, 0, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( imm ); - } -} - -/* add r16 to m16 */ -emitterT void ADD16RtoM(uptr to, x86IntRegType from ) -{ - write8( 0x66 ); - RexR(0,from); - write8( 0x01 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* add m16 to r16 */ -emitterT void ADD16MtoR( x86IntRegType to, uptr from ) -{ - write8( 0x66 ); - RexR(0,to); - write8( 0x03 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - // add m8 to r8 emitterT void ADD8MtoR( x86IntRegType to, uptr from ) { @@ -915,49 +841,6 @@ emitterT void INC16M( u32 to ) write32( MEMADDR(to, 4) ); } - - -// sub r16 to r16 -emitterT void SUB16RtoR( x86IntRegType to, u16 from ) -{ - write8(0x66); - RexRB(0,to,from); - write8( 0x2b ); - ModRM( 3, to, from ); -} - -/* sub imm16 to r16 */ -emitterT void SUB16ItoR( x86IntRegType to, u16 from ) { - write8( 0x66 ); - RexB(0,to); - if ( to == EAX ) { - write8( 0x2D ); - } - else { - write8( 0x81 ); - ModRM( 3, 5, to ); - } - write16( from ); -} - -/* sub imm16 to m16 */ -emitterT void SUB16ItoM( uptr to, u16 from ) { - write8( 0x66 ); - write8( 0x81 ); - ModRM( 0, 5, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); -} - -/* sub m16 to r16 */ -emitterT void SUB16MtoR( x86IntRegType to, uptr from ) { - write8( 0x66 ); - RexR(0,to); - write8( 0x2B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - /* dec r32 */ emitterT void DEC32R( x86IntRegType to ) { @@ -1331,60 +1214,6 @@ emitterT void SHRD32ItoR( x86IntRegType to, x86IntRegType from, u8 shift ) // logical instructions / //////////////////////////////////// -// or r16 to r16 -emitterT void OR16RtoR( x86IntRegType to, x86IntRegType from ) -{ - write8(0x66); - RexRB(0,from,to); - write8( 0x09 ); - ModRM( 3, from, to ); -} - -// or imm16 to r16 -emitterT void OR16ItoR( x86IntRegType to, u16 from ) -{ - write8(0x66); - RexB(0,to); - if ( to == EAX ) { - write8( 0x0D ); - } - else { - write8( 0x81 ); - ModRM( 3, 1, to ); - } - write16( from ); -} - -// or imm16 to m316 -emitterT void OR16ItoM( uptr to, u16 from ) -{ - write8(0x66); - write8( 0x81 ); - ModRM( 0, 1, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); -} - -/* or m16 to r16 */ -emitterT void OR16MtoR( x86IntRegType to, uptr from ) -{ - write8(0x66); - RexR(0,to); - write8( 0x0B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - -// or r16 to m16 -emitterT void OR16RtoM( uptr to, x86IntRegType from ) -{ - write8(0x66); - RexR(0,from); - write8( 0x09 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - // or r8 to r8 emitterT void OR8RtoR( x86IntRegType to, x86IntRegType from ) { @@ -1420,77 +1249,6 @@ emitterT void OR8MtoR( x86IntRegType to, uptr from ) write32( MEMADDR(from, 4) ); } -// and r16 to r16 -emitterT void AND16RtoR( x86IntRegType to, x86IntRegType from ) -{ - write8(0x66); - RexRB(0,to,from); - write8( 0x23 ); - ModRM( 3, to, from ); -} - -/* and imm16 to r16 */ -emitterT void AND16ItoR( x86IntRegType to, u16 from ) -{ - write8(0x66); - RexB(0,to); - - if ( to == EAX ) { - write8( 0x25 ); - write16( from ); - } - else if ( from < 0x80 ) { - write8( 0x83 ); - ModRM( 3, 0x4, to ); - write8((u8)from ); - } - else { - write8( 0x81 ); - ModRM( 3, 0x4, to ); - write16( from ); - } -} - -/* and imm16 to m16 */ -emitterT void AND16ItoM( uptr to, u16 from ) -{ - write8(0x66); - if ( from < 0x80 ) { - write8( 0x83 ); - ModRM( 0, 0x4, DISP32 ); - write32( MEMADDR(to, 6) ); - write8((u8)from ); - } - else - { - write8( 0x81 ); - ModRM( 0, 0x4, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); - - } -} - -/* and r16 to m16 */ -emitterT void AND16RtoM( uptr to, x86IntRegType from ) -{ - write8( 0x66 ); - RexR(0,from); - write8( 0x21 ); - ModRM( 0, from, DISP32 ); - write32( MEMADDR(to, 4) ); -} - -/* and m16 to r16 */ -emitterT void AND16MtoR( x86IntRegType to, uptr from ) -{ - write8( 0x66 ); - RexR(0,to); - write8( 0x23 ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4)); -} - /* and imm8 to r8 */ emitterT void AND8ItoR( x86IntRegType to, u8 from ) { @@ -1906,93 +1664,6 @@ emitterT void CALL32M( u32 to ) // misc instructions / //////////////////////////////////// -// cmp imm8 to [r32] (byte ptr) -emitterT void CMP8I8toRm( x86IntRegType to, s8 from, s8 off=0 ) -{ - RexB(0,to); - write8( 0x80 ); - ModRM( (off != 0), 7, to ); - if( off != 0 ) write8(off); - write8(from); -} - -// cmp imm8 to [r32] -emitterT void CMP32I8toRm( x86IntRegType to, u8 from, s8 off=0 ) -{ - RexB(0,to); - write8( 0x83 ); - ModRM( (off!=0), 7, to ); - if( off != 0 ) write8(off); - write8(from); -} - -// cmp imm32 to [r32] -emitterT void CMP32ItoRm( x86IntRegType to, u32 from, s8 off=0 ) -{ - // fixme : This should use the imm8 form if 'from' is between 127 and -128. - - RexB(0,to); - write8( 0x81 ); - ModRM( (off != 0), 7, to ); - if( off != 0 ) write8(off); - write32(from); -} - -// cmp imm8 to [mem] (dword ptr) -emitterT void CMP32I8toM( uptr to, u8 from ) -{ - write8( 0x83 ); - ModRM( 0, 7, DISP32 ); - write32( MEMADDR(to, 5) ); - write8( from ); -} - -/* cmp imm16 to r16 */ -emitterT void CMP16ItoR( x86IntRegType to, u16 from ) -{ - write8( 0x66 ); - RexB(0,to); - if ( to == EAX ) - { - write8( 0x3D ); - } - else - { - write8( 0x81 ); - ModRM( 3, 7, to ); - } - write16( from ); -} - -/* cmp imm16 to m16 */ -emitterT void CMP16ItoM( uptr to, u16 from ) -{ - write8( 0x66 ); - write8( 0x81 ); - ModRM( 0, 7, DISP32 ); - write32( MEMADDR(to, 6) ); - write16( from ); -} - -/* cmp r16 to r16 */ -emitterT void CMP16RtoR( x86IntRegType to, x86IntRegType from ) -{ - write8( 0x66 ); - RexRB(0,from,to); - write8( 0x39 ); - ModRM( 3, from, to ); -} - -/* cmp m16 to r16 */ -emitterT void CMP16MtoR( x86IntRegType to, uptr from ) -{ - write8( 0x66 ); - RexR(0,to); - write8( 0x3B ); - ModRM( 0, to, DISP32 ); - write32( MEMADDR(from, 4) ); -} - // cmp imm8 to r8 emitterT void CMP8ItoR( x86IntRegType to, u8 from ) { @@ -2018,6 +1689,16 @@ emitterT void CMP8MtoR( x86IntRegType to, uptr from ) write32( MEMADDR(from, 4) ); } +// cmp imm8 to [r32] (byte ptr) +emitterT void CMP8I8toRm( x86IntRegType to, s8 from, s8 off=0 ) +{ + RexB(0,to); + write8( 0x80 ); + ModRM( (off != 0), 7, to ); + if( off != 0 ) write8(off); + write8(from); +} + /* test imm32 to r32 */ emitterT void TEST32ItoR( x86IntRegType to, u32 from ) { diff --git a/pcsx2/x86/ix86/ix86_types.h b/pcsx2/x86/ix86/ix86_types.h index be0e0d3ec1..589badb78a 100644 --- a/pcsx2/x86/ix86/ix86_types.h +++ b/pcsx2/x86/ix86/ix86_types.h @@ -151,7 +151,9 @@ struct CPUINFO{ extern CPUINFO cpuinfo; //------------------------------------------------------------------ -static __forceinline bool is_s8( u32 imm ) { return (s8)imm == (s32)imm; } +// templated version of is_s8 is required, so that u16's get correct sign extension treatment. +template< typename T > +static __forceinline bool is_s8( T imm ) { return (s8)imm == (s32)imm; } namespace x86Emitter {