mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-02 07:22:24 +00:00
Implement MinTri, MaxTri, MedTri
This commit is contained in:
parent
df2faa915b
commit
20c4e07049
@ -146,6 +146,34 @@ void EmitFPMin64(EmitContext& ctx, const Operands& dest, const Operands& op1, co
|
|||||||
MovDouble(ctx, dest[0], tmp);
|
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) {
|
void EmitFPMul16(EmitContext& ctx, const Operands& dest, const Operands& op1, const Operands& op2) {
|
||||||
Xmm tmp1 = ctx.TempXmmReg();
|
Xmm tmp1 = ctx.TempXmmReg();
|
||||||
Xmm tmp2 = 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 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 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 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 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 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);
|
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 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 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 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 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 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);
|
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);
|
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) {
|
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();
|
Reg tmp = dest[0].IsMem() ? ctx.TempGPReg().cvt32() : dest[0].Reg();
|
||||||
MovGP(ctx, tmp, value[0]);
|
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);
|
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) {
|
void DoFPMul32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1) {
|
||||||
Common::CartesianInvoke(ImmValue::Mul<Type::F32, true>,
|
Common::CartesianInvoke(ImmValue::Mul<Type::F32, true>,
|
||||||
std::insert_iterator(inst_values, inst_values.begin()), args0, args1);
|
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,
|
void DoFPMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1,
|
||||||
const ImmValueList& args_legacy);
|
const ImmValueList& args_legacy);
|
||||||
void DoFPMin64(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
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 DoFPMul32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||||
void DoFPMul64(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);
|
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);
|
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,
|
void DoSClamp32(ImmValueList& inst_values, const ImmValueList& value, const ImmValueList& min,
|
||||||
const ImmValueList& max) {
|
const ImmValueList& max) {
|
||||||
Common::CartesianInvoke(ImmValue::Clamp<Type::U32, true>,
|
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 DoUMin32(ImmValueList& inst_values, const ImmValueList& args0, const ImmValueList& args1);
|
||||||
void DoSMax32(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 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,
|
void DoSClamp32(ImmValueList& inst_values, const ImmValueList& value, const ImmValueList& min,
|
||||||
const ImmValueList& max);
|
const ImmValueList& max);
|
||||||
void DoUClamp32(ImmValueList& inst_values, const ImmValueList& value, const ImmValueList& min,
|
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));
|
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 <>
|
template <>
|
||||||
ImmValue ImmValue::Clamp<Type::U8, false>(const ImmValue& in, const ImmValue& min,
|
ImmValue ImmValue::Clamp<Type::U8, false>(const ImmValue& in, const ImmValue& min,
|
||||||
const ImmValue& max) noexcept {
|
const ImmValue& max) noexcept {
|
||||||
|
@ -166,6 +166,15 @@ public:
|
|||||||
template <IR::Type Type, bool IsSigned>
|
template <IR::Type Type, bool IsSigned>
|
||||||
[[nodiscard]] static ImmValue Max(const ImmValue& a, const ImmValue& b) noexcept;
|
[[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>
|
template <IR::Type Type, bool IsSigned>
|
||||||
[[nodiscard]] static ImmValue Clamp(const ImmValue& in, const ImmValue& min,
|
[[nodiscard]] static ImmValue Clamp(const ImmValue& in, const ImmValue& min,
|
||||||
const ImmValue& max) noexcept;
|
const ImmValue& max) noexcept;
|
||||||
|
Loading…
Reference in New Issue
Block a user