Implement MinTri, MaxTri, MedTri

This commit is contained in:
Lander Gallastegi 2025-04-08 13:14:30 +02:00
parent df2faa915b
commit 20c4e07049
9 changed files with 383 additions and 0 deletions

View file

@ -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();

View file

@ -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);

View file

@ -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]);

View file

@ -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);

View file

@ -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);

View file

@ -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>,

View file

@ -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,

View file

@ -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 {

View file

@ -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;