mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
SPU: some instructions updated
This commit is contained in:
parent
e477a0b8fc
commit
a86317ce5a
3 changed files with 47 additions and 18 deletions
|
@ -408,7 +408,7 @@ void spu_interpreter::FREST(SPUThread& CPU, spu_opcode_t op)
|
||||||
|
|
||||||
void spu_interpreter::FRSQEST(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));
|
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)
|
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)
|
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)
|
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);
|
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)
|
void spu_interpreter::MPY(SPUThread& CPU, spu_opcode_t op)
|
||||||
{
|
{
|
||||||
return DEFAULT(CPU, 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));
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
void spu_interpreter::HLGTI(SPUThread& CPU, spu_opcode_t op)
|
||||||
|
|
|
@ -8,10 +8,10 @@ union spu_opcode_t
|
||||||
|
|
||||||
struct
|
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 ra : 7; // 18..24
|
||||||
u32 rb : 7; // 11..17
|
u32 rb : 7; // 11..17
|
||||||
u32 rc : 7; // 4..10
|
u32 rc : 7; // 4..10, it's actually RT in 4-op instructions
|
||||||
};
|
};
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|
@ -77,8 +77,8 @@ union spu_opcode_t
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
u32 : 18; // 14..31
|
u32 : 18; // 14..31
|
||||||
u32 e : 1; // 13
|
u32 e : 1; // 13, "enable interrupts" bit
|
||||||
u32 d : 1; // 12
|
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];
|
return funcs[opcode >> 21];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_spu_inter_func_list;
|
const g_spu_inter_func_list;
|
||||||
|
|
||||||
SPUThread& GetCurrentSPUThread()
|
SPUThread& GetCurrentSPUThread()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue