mirror of
https://github.com/hedge-dev/XenonRecomp.git
synced 2025-06-06 01:02:08 +00:00
Vector comparison instructions.
This commit is contained in:
parent
34d44c3c0a
commit
7d7ab43bbc
@ -1241,6 +1241,7 @@ int main()
|
|||||||
// no op
|
// no op
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// TODO: vector instructions require denormal flushing checks
|
||||||
case PPC_INST_VADDFP:
|
case PPC_INST_VADDFP:
|
||||||
case PPC_INST_VADDFP128:
|
case PPC_INST_VADDFP128:
|
||||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_add_ps(_mm_load_ps(ctx.v{}.f32), _mm_load_ps(ctx.v{}.f32)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
println("\t_mm_store_ps(ctx.v{}.f32, _mm_add_ps(_mm_load_ps(ctx.v{}.f32), _mm_load_ps(ctx.v{}.f32)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
@ -1291,17 +1292,20 @@ int main()
|
|||||||
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_avg_epu8(_mm_load_si128((__m128i*)ctx.v{}.u8), _mm_load_si128((__m128i*)ctx.v{}.u8)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_avg_epu8(_mm_load_si128((__m128i*)ctx.v{}.u8), _mm_load_si128((__m128i*)ctx.v{}.u8)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PPC_INST_VCTSXS:
|
||||||
case PPC_INST_VCFPSXWS128:
|
case PPC_INST_VCFPSXWS128:
|
||||||
|
// TODO: saturate
|
||||||
|
println("\t_mm_store_si128((__m128i*)ctx.v{}.s32, _mm_cvttps_epi32(_mm_mul_ps(_mm_load_ps(ctx.v{}.f32), _mm_set1_ps(exp2f({})))));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCFSX:
|
case PPC_INST_VCFSX:
|
||||||
// NOTE: ignoring the immediate since it's always 0 in the game code
|
case PPC_INST_VCSXWFP128:
|
||||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_cvtepi32_ps(_mm_load_si128((__m128i*)ctx.v{}.u32)));", insn.operands[0], insn.operands[1]);
|
println("\t_mm_store_ps(ctx.v{}.f32, _mm_mul_ps(_mm_cvtepi32_ps(_mm_load_si128((__m128i*)ctx.v{}.u32)), _mm_set1_ps(ldexpf(1.0f, {}))));", insn.operands[0], insn.operands[1], -int32_t(insn.operands[2]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCFUX:
|
case PPC_INST_VCFUX:
|
||||||
// NOTE: ignoring the immediate since it's always 0 in the game code
|
case PPC_INST_VCUXWFP128:
|
||||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_cvtepu32_ps(_mm_load_si128((__m128i*)ctx.v{}.u32)));", insn.operands[0], insn.operands[1]);
|
println("\t_mm_store_ps(ctx.v{}.f32, _mm_mul_ps(_mm_cvtepu32_ps(_mm_load_si128((__m128i*)ctx.v{}.u32)), _mm_set1_ps(ldexpf(1.0f, {}))));", insn.operands[0], insn.operands[1], -int32_t(insn.operands[2]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCMPBFP128:
|
case PPC_INST_VCMPBFP128:
|
||||||
@ -1313,27 +1317,38 @@ int main()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCMPEQUB:
|
case PPC_INST_VCMPEQUB:
|
||||||
|
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_cmpeq_epi8(_mm_load_si128((__m128i*)ctx.v{}.u8), _mm_load_si128((__m128i*)ctx.v{}.u8)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
|
if (insn.opcode->opcode & 0x1)
|
||||||
|
println("\tctx.cr6.setFromMask(_mm_load_si128((__m128i*)ctx.v{}.u8), 0xFFFF);", insn.operands[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCMPEQUW:
|
case PPC_INST_VCMPEQUW:
|
||||||
case PPC_INST_VCMPEQUW128:
|
case PPC_INST_VCMPEQUW128:
|
||||||
|
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_cmpeq_epi32(_mm_load_si128((__m128i*)ctx.v{}.u32), _mm_load_si128((__m128i*)ctx.v{}.u32)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
|
if ((insn.opcode->id == PPC_INST_VCMPEQUW && (insn.opcode->opcode & 0x1)) || (insn.opcode->id == PPC_INST_VCMPEQUW128 && (insn.opcode->opcode & 0x40)))
|
||||||
|
println("\tctx.cr6.setFromMask(_mm_load_ps(ctx.v{}.f32), 0xF);", insn.operands[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCMPGEFP:
|
case PPC_INST_VCMPGEFP:
|
||||||
case PPC_INST_VCMPGEFP128:
|
case PPC_INST_VCMPGEFP128:
|
||||||
// TODO: . variant
|
|
||||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_cmpge_ps(_mm_load_ps(ctx.v{}.f32), _mm_load_ps(ctx.v{}.f32)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
println("\t_mm_store_ps(ctx.v{}.f32, _mm_cmpge_ps(_mm_load_ps(ctx.v{}.f32), _mm_load_ps(ctx.v{}.f32)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
|
if (insn.opcode->id == PPC_INST_VCMPGEFP128 && (insn.opcode->opcode & 0x40))
|
||||||
|
println("\tctx.cr6.setFromMask(_mm_load_ps(ctx.v{}.f32), 0xF);", insn.operands[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCMPGTFP:
|
case PPC_INST_VCMPGTFP:
|
||||||
case PPC_INST_VCMPGTFP128:
|
case PPC_INST_VCMPGTFP128:
|
||||||
// TODO: . variant
|
|
||||||
println("\t_mm_store_ps(ctx.v{}.f32, _mm_cmpgt_ps(_mm_load_ps(ctx.v{}.f32), _mm_load_ps(ctx.v{}.f32)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
println("\t_mm_store_ps(ctx.v{}.f32, _mm_cmpgt_ps(_mm_load_ps(ctx.v{}.f32), _mm_load_ps(ctx.v{}.f32)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
|
if (insn.opcode->id == PPC_INST_VCMPGTFP128 && (insn.opcode->opcode & 0x40))
|
||||||
|
println("\tctx.cr6.setFromMask(_mm_load_ps(ctx.v{}.f32), 0xF);", insn.operands[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCMPGTUB:
|
case PPC_INST_VCMPGTUB:
|
||||||
|
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_cmpgt_epu8(_mm_load_si128((__m128i*)ctx.v{}.u8), _mm_load_si128((__m128i*)ctx.v{}.u8)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
case PPC_INST_VCMPGTUH:
|
case PPC_INST_VCMPGTUH:
|
||||||
case PPC_INST_VCSXWFP128:
|
println("\t_mm_store_si128((__m128i*)ctx.v{}.u8, _mm_cmpgt_epu16(_mm_load_si128((__m128i*)ctx.v{}.u16), _mm_load_si128((__m128i*)ctx.v{}.u16)));", insn.operands[0], insn.operands[1], insn.operands[2]);
|
||||||
case PPC_INST_VCTSXS:
|
|
||||||
case PPC_INST_VCUXWFP128:
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PPC_INST_VEXPTEFP128:
|
case PPC_INST_VEXPTEFP128:
|
||||||
|
@ -81,6 +81,24 @@ struct PPCCRRegister
|
|||||||
eq = left == right;
|
eq = left == right;
|
||||||
un = isnan(left) || isnan(right);
|
un = isnan(left) || isnan(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setFromMask(__m128 mask, int imm)
|
||||||
|
{
|
||||||
|
int m = _mm_movemask_ps(mask);
|
||||||
|
lt = m == imm; // all equal
|
||||||
|
gt = 0;
|
||||||
|
eq = m == 0; // none equal
|
||||||
|
so = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFromMask(__m128i mask, int imm)
|
||||||
|
{
|
||||||
|
int m = _mm_movemask_epi8(mask);
|
||||||
|
lt = m == imm; // all equal
|
||||||
|
gt = 0;
|
||||||
|
eq = m == 0; // none equal
|
||||||
|
so = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(0x10) PPCVRegister
|
struct alignas(0x10) PPCVRegister
|
||||||
@ -455,3 +473,16 @@ inline __m128i _mm_perm_epi8(__m128i a, __m128i b, __m128i c)
|
|||||||
__m128i e = _mm_sub_epi8(d, _mm_and_si128(c, d));
|
__m128i e = _mm_sub_epi8(d, _mm_and_si128(c, d));
|
||||||
return _mm_blendv_epi8(_mm_shuffle_epi8(a, e), _mm_shuffle_epi8(b, e), _mm_slli_epi32(c, 3));
|
return _mm_blendv_epi8(_mm_shuffle_epi8(a, e), _mm_shuffle_epi8(b, e), _mm_slli_epi32(c, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline __m128i _mm_cmpgt_epu8(__m128i a, __m128i b)
|
||||||
|
{
|
||||||
|
__m128i c = _mm_set1_epi8(0x80);
|
||||||
|
return _mm_cmpgt_epi8(_mm_xor_si128(a, c), _mm_xor_si128(b, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline __m128i _mm_cmpgt_epu16(__m128i a, __m128i b)
|
||||||
|
{
|
||||||
|
__m128i c = _mm_set1_epi16(0x8000);
|
||||||
|
return _mm_cmpgt_epi16(_mm_xor_si128(a, c), _mm_xor_si128(b, c));
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user