mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-04-21 03:54:45 +00:00
Implement MinTri, MaxTri, MedTri
This commit is contained in:
parent
df2faa915b
commit
20c4e07049
9 changed files with 383 additions and 0 deletions
|
@ -146,6 +146,34 @@ void EmitFPMin64(EmitContext& ctx, const Operands& dest, const Operands& op1, co
|
|||
MovDouble(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitFPMinTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm();
|
||||
MovFloat(ctx, tmp, op1[0]);
|
||||
ctx.Code().minss(tmp, op2[0].Op());
|
||||
ctx.Code().minss(tmp, op3[0].Op());
|
||||
MovFloat(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitFPMaxTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm();
|
||||
MovFloat(ctx, tmp, op1[0]);
|
||||
ctx.Code().maxss(tmp, op2[0].Op());
|
||||
ctx.Code().maxss(tmp, op3[0].Op());
|
||||
MovFloat(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitFPMedTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Xmm tmp = dest[0].IsMem() ? ctx.TempXmmReg() : dest[0].Xmm();
|
||||
Xmm tmp2 = ctx.TempXmmReg();
|
||||
MovFloat(ctx, tmp2, op1[0]);
|
||||
ctx.Code().maxss(tmp2, op2[0].Op());
|
||||
ctx.Code().minss(tmp2, op3[0].Op());
|
||||
MovFloat(ctx, tmp, op1[0]);
|
||||
ctx.Code().minss(tmp, op2[0].Op());
|
||||
ctx.Code().maxss(tmp, tmp2);
|
||||
MovFloat(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitFPMul16(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) {
|
||||
Xmm tmp1 = ctx.TempXmmReg();
|
||||
Xmm tmp2 = ctx.TempXmmReg();
|
||||
|
|
|
@ -237,6 +237,9 @@ void EmitFPMax32(EmitContext& ctx, const Operands& dest, const Operands& op1, co
|
|||
void EmitFPMax64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||
void EmitFPMin32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, bool is_legacy = false);
|
||||
void EmitFPMin64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||
void EmitFPMinTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitFPMaxTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitFPMedTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitFPMul16(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||
void EmitFPMul32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||
void EmitFPMul64(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||
|
@ -362,6 +365,12 @@ void EmitSMin32(EmitContext& ctx, const Operands& dest, const Operands& op1, con
|
|||
void EmitUMin32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||
void EmitSMax32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||
void EmitUMax32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2);
|
||||
void EmitSMinTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitUMinTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitSMaxTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitUMaxTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitSMedTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitUMedTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3);
|
||||
void EmitSClamp32(EmitContext& ctx, const Operands& dest, const Operands& op, const Operands& min, const Operands& max);
|
||||
void EmitUClamp32(EmitContext& ctx, const Operands& dest, const Operands& op, const Operands& min, const Operands& max);
|
||||
void EmitSLessThan32(EmitContext& ctx, const Operands& dest, const Operands& lhs, const Operands& rhs);
|
||||
|
|
|
@ -377,6 +377,78 @@ void EmitUMax32(EmitContext& ctx, const Operands& dest, const Operands& op1, con
|
|||
MovGP(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitSMinTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg();
|
||||
MovGP(ctx, tmp, op1[0]);
|
||||
ctx.Code().cmp(tmp, op2[0].Op());
|
||||
ctx.Code().cmovg(tmp, op2[0].Op());
|
||||
ctx.Code().cmp(tmp, op3[0].Op());
|
||||
ctx.Code().cmovg(tmp, op3[0].Op());
|
||||
MovGP(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitUMinTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg();
|
||||
MovGP(ctx, tmp, op1[0]);
|
||||
ctx.Code().cmp(tmp, op2[0].Op());
|
||||
ctx.Code().cmova(tmp, op2[0].Op());
|
||||
ctx.Code().cmp(tmp, op3[0].Op());
|
||||
ctx.Code().cmova(tmp, op3[0].Op());
|
||||
MovGP(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitSMaxTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg();
|
||||
MovGP(ctx, tmp, op1[0]);
|
||||
ctx.Code().cmp(tmp, op2[0].Op());
|
||||
ctx.Code().cmovl(tmp, op2[0].Op());
|
||||
ctx.Code().cmp(tmp, op3[0].Op());
|
||||
ctx.Code().cmovl(tmp, op3[0].Op());
|
||||
MovGP(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitUMaxTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg();
|
||||
MovGP(ctx, tmp, op1[0]);
|
||||
ctx.Code().cmp(tmp, op2[0].Op());
|
||||
ctx.Code().cmovb(tmp, op2[0].Op());
|
||||
ctx.Code().cmp(tmp, op3[0].Op());
|
||||
ctx.Code().cmovb(tmp, op3[0].Op());
|
||||
MovGP(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitSMedTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg();
|
||||
Reg tmp2 = ctx.TempGPReg().cvt32();
|
||||
MovGP(ctx, tmp2, op1[0]);
|
||||
ctx.Code().cmp(tmp2, op2[0].Op());
|
||||
ctx.Code().cmovl(tmp2, op2[0].Op());
|
||||
ctx.Code().cmp(tmp2, op3[0].Op());
|
||||
ctx.Code().cmovg(tmp2, op3[0].Op());
|
||||
MovGP(ctx, tmp, op1[0]);
|
||||
ctx.Code().cmp(tmp, op2[0].Op());
|
||||
ctx.Code().cmovg(tmp, op2[0].Op());
|
||||
ctx.Code().cmp(tmp, tmp);
|
||||
ctx.Code().cmovl(tmp, tmp2);
|
||||
MovGP(ctx, dest[0], tmp);
|
||||
}
|
||||
|
||||
void EmitUMedTri32(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2, const Operands& op3) {
|
||||
Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg();
|
||||
Reg tmp2 = ctx.TempGPReg().cvt32();
|
||||
MovGP(ctx, tmp, op1[0]);
|
||||
ctx.Code().cmp(tmp, op2[0].Op());
|
||||
ctx.Code().cmova(tmp, op2[0].Op());
|
||||
ctx.Code().cmp(tmp, op3[0].Op());
|
||||
ctx.Code().cmovb(tmp, op3[0].Op());
|
||||
MovGP(ctx, tmp2, op1[0]);
|
||||
ctx.Code().cmp(tmp2, op2[0].Op());
|
||||
ctx.Code().cmovb(tmp2, op2[0].Op());
|
||||
ctx.Code().cmp(tmp2, tmp);
|
||||
ctx.Code().cmova(tmp2, tmp);
|
||||
MovGP(ctx, dest[0], tmp2);
|
||||
}
|
||||
|
||||
void EmitSClamp32(EmitContext& ctx, const Operands& dest, const Operands& value, const Operands& min, const Operands& max) {
|
||||
Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg();
|
||||
MovGP(ctx, tmp, value[0]);
|
||||
|
|
|
@ -85,6 +85,27 @@ void DoFPMin64(ImmValueList& inst_values, const ImmValueList& args0, const ImmVa
|
|||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
|
||||
}
|
||||
|
||||
void DoFPMaxTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MaxTri<Type::F32, true>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1,
|
||||
args2);
|
||||
}
|
||||
|
||||
void DoFPMinTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MinTri<Type::F32, true>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1,
|
||||
args2);
|
||||
}
|
||||
|
||||
void DoFPMedTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MedTri<Type::F32, true>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1,
|
||||
args2);
|
||||
}
|
||||
|
||||
void DoFPMul32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
|
||||
Common::CartesianInvoke(ImmValue::Mul<Type::F32, true>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
|
||||
|
|
|
@ -22,6 +22,12 @@ void DoFPMax64(ImmValueList& inst_values, const ImmValueList& args0, const ImmVa
|
|||
void DoFPMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args_legacy);
|
||||
void DoFPMin64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||
void DoFPMinTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2);
|
||||
void DoFPMaxTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2);
|
||||
void DoFPMedTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2);
|
||||
void DoFPMul32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||
void DoFPMul64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||
void DoFPDiv32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||
|
|
|
@ -219,6 +219,42 @@ void DoUMax32(ImmValueList& inst_values, const ImmValueList& args0, const ImmVal
|
|||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
|
||||
}
|
||||
|
||||
void DoSMinTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MinTri<Type::U32, true>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1, args2);
|
||||
}
|
||||
|
||||
void DoUMinTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MinTri<Type::U32, false>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1, args2);
|
||||
}
|
||||
|
||||
void DoSMaxTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MaxTri<Type::U32, true>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1, args2);
|
||||
}
|
||||
|
||||
void DoUMaxTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MaxTri<Type::U32, false>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1, args2);
|
||||
}
|
||||
|
||||
void DoSMedTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MedTri<Type::U32, true>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1, args2);
|
||||
}
|
||||
|
||||
void DoUMedTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||
const ImmValueList& args2) {
|
||||
Common::CartesianInvoke(ImmValue::MedTri<Type::U32, false>,
|
||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1, args2);
|
||||
}
|
||||
|
||||
void DoSClamp32(ImmValueList& inst_values, const ImmValueList& value, const ImmValueList& min,
|
||||
const ImmValueList& max) {
|
||||
Common::CartesianInvoke(ImmValue::Clamp<Type::U32, true>,
|
||||
|
|
|
@ -62,6 +62,12 @@ void DoSMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmVal
|
|||
void DoUMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||
void DoSMax32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||
void DoUMax32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||
void DoSMinTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1, const ImmValueList& args2);
|
||||
void DoUMinTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1, const ImmValueList& args2);
|
||||
void DoSMaxTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1, const ImmValueList& args2);
|
||||
void DoUMaxTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1, const ImmValueList& args2);
|
||||
void DoSMedTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1, const ImmValueList& args2);
|
||||
void DoUMedTri32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1, const ImmValueList& args2);
|
||||
void DoSClamp32(ImmValueList& inst_values, const ImmValueList& value, const ImmValueList& min,
|
||||
const ImmValueList& max);
|
||||
void DoUClamp32(ImmValueList& inst_values, const ImmValueList& value, const ImmValueList& min,
|
||||
|
|
|
@ -1127,6 +1127,202 @@ ImmValue ImmValue::Max<Type::F64, true>(const ImmValue& a, const ImmValue& b) no
|
|||
return ImmValue(std::max(a.imm_values[0].imm_f64, b.imm_values[0].imm_f64));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::U8, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_u8, b.imm_values[0].imm_u8),
|
||||
c.imm_values[0].imm_u8));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::U8, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_s8, b.imm_values[0].imm_s8),
|
||||
c.imm_values[0].imm_s8));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::U16, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_u16, b.imm_values[0].imm_u16),
|
||||
c.imm_values[0].imm_u16));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::U16, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_s16, b.imm_values[0].imm_s16),
|
||||
c.imm_values[0].imm_s16));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::U32, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_u32, b.imm_values[0].imm_u32),
|
||||
c.imm_values[0].imm_u32));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::U32, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_s32, b.imm_values[0].imm_s32),
|
||||
c.imm_values[0].imm_s32));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::U64, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_u64, b.imm_values[0].imm_u64),
|
||||
c.imm_values[0].imm_u64));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::U64, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_u64, b.imm_values[0].imm_u64),
|
||||
c.imm_values[0].imm_u64));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::F32, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_f32, b.imm_values[0].imm_f32),
|
||||
c.imm_values[0].imm_f32));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MinTri<Type::F64, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::min(std::min(a.imm_values[0].imm_f64, b.imm_values[0].imm_f64),
|
||||
c.imm_values[0].imm_f64));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::U8, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_u8, b.imm_values[0].imm_u8),
|
||||
c.imm_values[0].imm_u8));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::U8, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_s8, b.imm_values[0].imm_s8),
|
||||
c.imm_values[0].imm_s8));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::U16, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_u16, b.imm_values[0].imm_u16),
|
||||
c.imm_values[0].imm_u16));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::U16, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_s16, b.imm_values[0].imm_s16),
|
||||
c.imm_values[0].imm_s16));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::U32, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_u32, b.imm_values[0].imm_u32),
|
||||
c.imm_values[0].imm_u32));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::U32, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_s32, b.imm_values[0].imm_s32),
|
||||
c.imm_values[0].imm_s32));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::U64, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_u64, b.imm_values[0].imm_u64),
|
||||
c.imm_values[0].imm_u64));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::U64, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_s64, b.imm_values[0].imm_s64),
|
||||
c.imm_values[0].imm_s64));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::F32, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_f32, b.imm_values[0].imm_f32),
|
||||
c.imm_values[0].imm_f32));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MaxTri<Type::F64, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_f64, b.imm_values[0].imm_f64),
|
||||
c.imm_values[0].imm_f64));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::U8, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
u8 mmx = std::min(std::max(a.imm_values[0].imm_u8, b.imm_values[0].imm_u8),
|
||||
c.imm_values[0].imm_u8);
|
||||
return ImmValue(std::max(std::min(a.imm_values[0].imm_u8, b.imm_values[0].imm_u8),
|
||||
mmx));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::U8, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
s8 mmx = std::min(std::max(a.imm_values[0].imm_s8, b.imm_values[0].imm_s8),
|
||||
c.imm_values[0].imm_s8);
|
||||
return ImmValue(std::max(std::min(a.imm_values[0].imm_s8, b.imm_values[0].imm_s8),
|
||||
mmx));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::U16, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
u16 mmx = std::min(std::max(a.imm_values[0].imm_u16, b.imm_values[0].imm_u16),
|
||||
c.imm_values[0].imm_u16);
|
||||
return ImmValue(std::max(std::min(a.imm_values[0].imm_u16, b.imm_values[0].imm_u16),
|
||||
mmx));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::U16, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
s16 mmx = std::min(std::max(a.imm_values[0].imm_s16, b.imm_values[0].imm_s16),
|
||||
c.imm_values[0].imm_s16);
|
||||
return ImmValue(std::max(std::min(a.imm_values[0].imm_s16, b.imm_values[0].imm_s16),
|
||||
mmx));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::U32, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
u32 mmx = std::min(std::max(a.imm_values[0].imm_u32, b.imm_values[0].imm_u32),
|
||||
c.imm_values[0].imm_u32);
|
||||
return ImmValue(std::max(std::min(a.imm_values[0].imm_u32, b.imm_values[0].imm_u32),
|
||||
mmx));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::U32, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
s32 mmx = std::min(std::max(a.imm_values[0].imm_s32, b.imm_values[0].imm_s32),
|
||||
c.imm_values[0].imm_s32);
|
||||
return ImmValue(std::max(std::min(a.imm_values[0].imm_s32, b.imm_values[0].imm_s32),
|
||||
mmx));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::U64, false>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
u64 mmx = std::min(std::max(a.imm_values[0].imm_u64, b.imm_values[0].imm_u64),
|
||||
c.imm_values[0].imm_u64);
|
||||
return ImmValue(std::max(std::min(a.imm_values[0].imm_u64, b.imm_values[0].imm_u64),
|
||||
mmx));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::U64, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
s64 mmx = std::min(std::max(a.imm_values[0].imm_s64, b.imm_values[0].imm_s64),
|
||||
c.imm_values[0].imm_s64);
|
||||
return ImmValue(std::max(std::min(a.imm_values[0].imm_s64, b.imm_values[0].imm_s64),
|
||||
mmx));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::F32, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_f32, b.imm_values[0].imm_f32),
|
||||
c.imm_values[0].imm_f32));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::MedTri<Type::F64, true>(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept {
|
||||
return ImmValue(std::max(std::max(a.imm_values[0].imm_f64, b.imm_values[0].imm_f64),
|
||||
c.imm_values[0].imm_f64));
|
||||
}
|
||||
|
||||
template <>
|
||||
ImmValue ImmValue::Clamp<Type::U8, false>(const ImmValue& in, const ImmValue& min,
|
||||
const ImmValue& max) noexcept {
|
||||
|
|
|
@ -166,6 +166,15 @@ public:
|
|||
template <IR::Type Type, bool IsSigned>
|
||||
[[nodiscard]] static ImmValue Max(const ImmValue& a, const ImmValue& b) noexcept;
|
||||
|
||||
template <IR::Type Type, bool IsSigned>
|
||||
[[nodiscard]] static ImmValue MinTri(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept;
|
||||
|
||||
template <IR::Type Type, bool IsSigned>
|
||||
[[nodiscard]] static ImmValue MaxTri(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept;
|
||||
|
||||
template <IR::Type Type, bool IsSigned>
|
||||
[[nodiscard]] static ImmValue MedTri(const ImmValue& a, const ImmValue& b, const ImmValue& c) noexcept;
|
||||
|
||||
template <IR::Type Type, bool IsSigned>
|
||||
[[nodiscard]] static ImmValue Clamp(const ImmValue& in, const ImmValue& min,
|
||||
const ImmValue& max) noexcept;
|
||||
|
|
Loading…
Add table
Reference in a new issue