mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 17:11:23 +00:00
SPU: some instructions updated
This commit is contained in:
parent
e477a0b8fc
commit
a86317ce5a
@ -408,7 +408,7 @@ void spu_interpreter::FREST(SPUThread& CPU, spu_opcode_t op)
|
||||
|
||||
void spu_interpreter::FRSQEST(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
static const auto mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
|
||||
const auto mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
|
||||
CPU.GPR[op.rt].vf = _mm_rsqrt_ps(_mm_and_ps(CPU.GPR[op.ra].vf, mask));
|
||||
}
|
||||
|
||||
@ -631,7 +631,10 @@ void spu_interpreter::XSHW(SPUThread& CPU, spu_opcode_t op)
|
||||
|
||||
void spu_interpreter::CNTB(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
const auto counts = _mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0);
|
||||
const auto mask = _mm_set1_epi8(0xf);
|
||||
const auto a = CPU.GPR[op.ra].vi;
|
||||
CPU.GPR[op.rt].vi = _mm_add_epi8(_mm_shuffle_epi8(counts, _mm_and_si128(a, mask)), _mm_shuffle_epi8(counts, _mm_and_si128(_mm_srli_epi64(a, 4), mask)));
|
||||
}
|
||||
|
||||
void spu_interpreter::XSBH(SPUThread& CPU, spu_opcode_t op)
|
||||
@ -688,7 +691,7 @@ void spu_interpreter::ORC(SPUThread& CPU, spu_opcode_t op)
|
||||
|
||||
void spu_interpreter::FCMGT(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
static const auto mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
|
||||
const auto mask = _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff));
|
||||
CPU.GPR[op.rt].vf = _mm_cmp_ps(_mm_and_ps(CPU.GPR[op.rb].vf, mask), _mm_and_ps(CPU.GPR[op.ra].vf, mask), 1);
|
||||
}
|
||||
|
||||
@ -838,7 +841,7 @@ void spu_interpreter::DFCEQ(SPUThread& CPU, spu_opcode_t op)
|
||||
void spu_interpreter::MPY(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
return DEFAULT(CPU, op);
|
||||
static const auto mask = _mm_set1_epi32(0xffff);
|
||||
const auto mask = _mm_set1_epi32(0xffff);
|
||||
CPU.GPR[op.rt].vi = _mm_madd_epi16(_mm_and_si128(CPU.GPR[op.ra].vi, mask), _mm_and_si128(CPU.GPR[op.rb].vi, mask));
|
||||
}
|
||||
|
||||
@ -900,24 +903,50 @@ void spu_interpreter::HEQ(SPUThread& CPU, spu_opcode_t op)
|
||||
}
|
||||
|
||||
|
||||
class spu_scale_table_t
|
||||
{
|
||||
std::array<__m128, 155 + 174> m_data;
|
||||
|
||||
public:
|
||||
spu_scale_table_t()
|
||||
{
|
||||
for (s32 i = -155; i < 174; i++)
|
||||
{
|
||||
m_data[i + 155] = _mm_set1_ps(static_cast<float>(pow(2, i)));
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline __m128 operator [] (s32 scale) const
|
||||
{
|
||||
return m_data[scale + 155];
|
||||
}
|
||||
}
|
||||
const g_spu_scale_table;
|
||||
|
||||
|
||||
void spu_interpreter::CFLTS(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
const auto scaled = _mm_mul_ps(CPU.GPR[op.ra].vf, g_spu_scale_table[173 - op.i8]);
|
||||
CPU.GPR[op.rt].vi = _mm_xor_si128(_mm_cvttps_epi32(scaled), _mm_castps_si128(_mm_cmpge_ps(scaled, _mm_set1_ps(0x80000000))));
|
||||
}
|
||||
|
||||
void spu_interpreter::CFLTU(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
const auto scaled1 = _mm_max_ps(_mm_mul_ps(CPU.GPR[op.ra].vf, g_spu_scale_table[173 - op.i8]), _mm_set1_ps(0.0f));
|
||||
const auto scaled2 = _mm_and_ps(_mm_sub_ps(scaled1, _mm_set1_ps(0x80000000)), _mm_cmpge_ps(scaled1, _mm_set1_ps(0x80000000)));
|
||||
CPU.GPR[op.rt].vi = _mm_or_si128(_mm_or_si128(_mm_cvttps_epi32(scaled1), _mm_cvttps_epi32(scaled2)), _mm_castps_si128(_mm_cmpge_ps(scaled1, _mm_set1_ps(0x100000000))));
|
||||
}
|
||||
|
||||
void spu_interpreter::CSFLT(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
CPU.GPR[op.rt].vf = _mm_mul_ps(_mm_cvtepi32_ps(CPU.GPR[op.ra].vi), g_spu_scale_table[op.i8 - 155]);
|
||||
}
|
||||
|
||||
void spu_interpreter::CUFLT(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
const auto a = CPU.GPR[op.ra].vi;
|
||||
const auto fix = _mm_and_ps(_mm_castsi128_ps(_mm_srai_epi32(a, 31)), _mm_set1_ps(0x80000000));
|
||||
CPU.GPR[op.rt].vf = _mm_mul_ps(_mm_add_ps(_mm_cvtepi32_ps(_mm_and_si128(a, _mm_set1_epi32(0x7fffffff))), fix), g_spu_scale_table[op.i8 - 155]);
|
||||
}
|
||||
|
||||
|
||||
@ -987,7 +1016,7 @@ void spu_interpreter::BR(SPUThread& CPU, spu_opcode_t op)
|
||||
|
||||
void spu_interpreter::FSMBI(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
CPU.GPR[op.rt].vi = g_imm_table.fsmb_table[op.i16];
|
||||
}
|
||||
|
||||
void spu_interpreter::BRSL(SPUThread& CPU, spu_opcode_t op)
|
||||
@ -1123,17 +1152,17 @@ void spu_interpreter::HGTI(SPUThread& CPU, spu_opcode_t op)
|
||||
|
||||
void spu_interpreter::CLGTI(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
CPU.GPR[op.rt].vi = _mm_cmpgt_epi32(_mm_xor_si128(CPU.GPR[op.ra].vi, _mm_set1_epi32(0x80000000)), _mm_set1_epi32(op.si10 ^ 0x80000000));
|
||||
}
|
||||
|
||||
void spu_interpreter::CLGTHI(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
CPU.GPR[op.rt].vi = _mm_cmpgt_epi16(_mm_xor_si128(CPU.GPR[op.ra].vi, _mm_set1_epi32(0x80008000)), _mm_set1_epi16(op.si10 ^ 0x8000));
|
||||
}
|
||||
|
||||
void spu_interpreter::CLGTBI(SPUThread& CPU, spu_opcode_t op)
|
||||
{
|
||||
DEFAULT(CPU, op);
|
||||
CPU.GPR[op.rt].vi = _mm_cmpgt_epi8(_mm_xor_si128(CPU.GPR[op.ra].vi, _mm_set1_epi32(0x80808080)), _mm_set1_epi8(op.i8 ^ 0x80));
|
||||
}
|
||||
|
||||
void spu_interpreter::HLGTI(SPUThread& CPU, spu_opcode_t op)
|
||||
|
@ -8,10 +8,10 @@ union spu_opcode_t
|
||||
|
||||
struct
|
||||
{
|
||||
u32 rt : 7; // 25..31
|
||||
u32 rt : 7; // 25..31, it's actually RC in 4-op instructions
|
||||
u32 ra : 7; // 18..24
|
||||
u32 rb : 7; // 11..17
|
||||
u32 rc : 7; // 4..10
|
||||
u32 rc : 7; // 4..10, it's actually RT in 4-op instructions
|
||||
};
|
||||
|
||||
struct
|
||||
@ -77,8 +77,8 @@ union spu_opcode_t
|
||||
struct
|
||||
{
|
||||
u32 : 18; // 14..31
|
||||
u32 e : 1; // 13
|
||||
u32 d : 1; // 12
|
||||
u32 e : 1; // 13, "enable interrupts" bit
|
||||
u32 d : 1; // 12, "disable interrupts" bit
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -42,12 +42,12 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline spu_inter_func_t operator [] (u32 opcode)
|
||||
__forceinline spu_inter_func_t operator [] (u32 opcode) const
|
||||
{
|
||||
return funcs[opcode >> 21];
|
||||
}
|
||||
}
|
||||
g_spu_inter_func_list;
|
||||
const g_spu_inter_func_list;
|
||||
|
||||
SPUThread& GetCurrentSPUThread()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user