glasm: Review all GLASM insts to be aware of register aliasing
This commit is contained in:
		| @@ -41,10 +41,23 @@ template <typename ObjectType> | ||||
| void CompositeInsert(EmitContext& ctx, IR::Inst& inst, Register composite, ObjectType object, | ||||
|                      u32 index, char type) { | ||||
|     const Register ret{ctx.reg_alloc.Define(inst)}; | ||||
|     if (ret != composite) { | ||||
|         ctx.Add("MOV.{} {},{};", type, ret, composite); | ||||
|     const char swizzle{"xyzw"[index]}; | ||||
|     if (ret != composite && ret == object) { | ||||
|         // The object is aliased with the return value, so we have to use a temporary to insert | ||||
|         ctx.Add("MOV.{} RC,{};" | ||||
|                 "MOV.{} RC.{},{};" | ||||
|                 "MOV.{} {},RC;", | ||||
|                 type, composite, type, swizzle, object, type, ret); | ||||
|     } else if (ret != composite) { | ||||
|         // The input composite is not aliased with the return value so we have to copy it before | ||||
|         // hand. But the insert object is not aliased with the return value, so we don't have to | ||||
|         // worry about that | ||||
|         ctx.Add("MOV.{} {},{};MOV.{},{}.{},{};", type, ret, composite, type, ret, swizzle, object); | ||||
|     } else { | ||||
|         // The return value is alised so we can just insert the object, it doesn't matter if it's | ||||
|         // aliased | ||||
|         ctx.Add("MOV.{} {}.{},{};", type, ret, swizzle, object); | ||||
|     } | ||||
|     ctx.Add("MOV.{} {}.{},{};", type, ret, "xyzw"[index], object); | ||||
| } | ||||
| } // Anonymous namespace | ||||
|  | ||||
|   | ||||
| @@ -38,9 +38,9 @@ template <typename InputType> | ||||
| void Clamp(EmitContext& ctx, Register ret, InputType value, InputType min_value, | ||||
|            InputType max_value, std::string_view type) { | ||||
|     // Call MAX first to properly clamp nan to min_value instead | ||||
|     ctx.Add("MAX.{} {}.x,{},{};" | ||||
|             "MIN.{} {}.x,{}.x,{};", | ||||
|             type, ret, min_value, value, type, ret, ret, max_value); | ||||
|     ctx.Add("MAX.{} RC.x,{},{};" | ||||
|             "MIN.{} {}.x,RC.x,{};", | ||||
|             type, min_value, value, type, ret, max_value); | ||||
| } | ||||
| } // Anonymous namespace | ||||
|  | ||||
| @@ -159,7 +159,7 @@ void EmitFPRecipSqrt64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Regis | ||||
|  | ||||
| void EmitFPSqrt(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) { | ||||
|     const Register ret{ctx.reg_alloc.Define(inst)}; | ||||
|     ctx.Add("RSQ {}.x,{};RCP {}.x,{}.x;", ret, value, ret, ret); | ||||
|     ctx.Add("RSQ RC.x,{};RCP {}.x,RC.x;", value, ret); | ||||
| } | ||||
|  | ||||
| void EmitFPSaturate16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) { | ||||
|   | ||||
| @@ -87,20 +87,38 @@ void EmitBitwiseXor32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b | ||||
|  | ||||
| void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 insert, | ||||
|                         ScalarS32 offset, ScalarS32 count) { | ||||
|     ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset); | ||||
|     ctx.Add("BFI.S {},RC,{},{};", inst, insert, base); | ||||
|     const Register ret{ctx.reg_alloc.Define(inst)}; | ||||
|     if (count.type != Type::Register && offset.type != Type::Register) { | ||||
|         ctx.Add("BFI.S {},{{{},{},0,0}},{},{};", ret, count, offset, insert, base); | ||||
|     } else { | ||||
|         ctx.Add("MOV.S RC.x,{};MOV.U RC.y,{};" | ||||
|                 "BFI.S {},RC,{},{};", | ||||
|                 count, offset, ret, insert, base); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitBitFieldSExtract(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 offset, | ||||
|                           ScalarS32 count) { | ||||
|     ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset); | ||||
|     ctx.Add("BFE.S {},RC,{};", inst, base); | ||||
|     const Register ret{ctx.reg_alloc.Define(inst)}; | ||||
|     if (count.type != Type::Register && offset.type != Type::Register) { | ||||
|         ctx.Add("BFE.S {},{{{},{},0,0}},{};", ret, count, offset, base); | ||||
|     } else { | ||||
|         ctx.Add("MOV.S RC.x,{};MOV.U RC.y,{};" | ||||
|                 "BFE.S {},RC,{};", | ||||
|                 count, offset, ret, base); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitBitFieldUExtract(EmitContext& ctx, IR::Inst& inst, ScalarU32 base, ScalarU32 offset, | ||||
|                           ScalarU32 count) { | ||||
|     ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};", count, offset); | ||||
|     ctx.Add("BFE.U {},RC,{};", inst, base); | ||||
|     const Register ret{ctx.reg_alloc.Define(inst)}; | ||||
|     if (count.type != Type::Register && offset.type != Type::Register) { | ||||
|         ctx.Add("BFE.U {},{{{},{},0,0}},{};", ret, count, offset, base); | ||||
|     } else { | ||||
|         ctx.Add("MOV.U RC.x,{};MOV.U RC.y,{};" | ||||
|                 "BFE.U {},RC,{};", | ||||
|                 count, offset, ret, base); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void EmitBitReverse32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) { | ||||
| @@ -141,16 +159,16 @@ void EmitUMax32(EmitContext& ctx, IR::Inst& inst, ScalarU32 a, ScalarU32 b) { | ||||
|  | ||||
| void EmitSClamp32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value, ScalarS32 min, ScalarS32 max) { | ||||
|     const Register ret{ctx.reg_alloc.Define(inst)}; | ||||
|     ctx.Add("MIN.S {}.x,{},{};" | ||||
|             "MAX.S {}.x,{},{};", | ||||
|             ret, max, value, ret, ret, min); | ||||
|     ctx.Add("MIN.S RC.x,{},{};" | ||||
|             "MAX.S {}.x,RC.x,{};", | ||||
|             max, value, ret, min); | ||||
| } | ||||
|  | ||||
| void EmitUClamp32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 min, ScalarU32 max) { | ||||
|     const Register ret{ctx.reg_alloc.Define(inst)}; | ||||
|     ctx.Add("MIN.U {}.x,{},{};" | ||||
|             "MAX.U {}.x,{},{};", | ||||
|             ret, max, value, ret, ret, min); | ||||
|     ctx.Add("MIN.U RC.x,{},{};" | ||||
|             "MAX.U {}.x,RC.x,{};", | ||||
|             max, value, ret, min); | ||||
| } | ||||
|  | ||||
| void EmitSLessThan(EmitContext& ctx, IR::Inst& inst, ScalarS32 lhs, ScalarS32 rhs) { | ||||
|   | ||||
| @@ -43,7 +43,7 @@ void EmitSelectU64(EmitContext& ctx, IR::Inst& inst, ScalarS32 cond, Register tr | ||||
|                 cond, ret, true_value); | ||||
|     } else { | ||||
|         ctx.Add("MOV.S.CC RC.x,{};" | ||||
|                 "MOV.U64 {}.x(EQ.x),{};" | ||||
|                 "MOV.U64 {}.x,{};" | ||||
|                 "MOV.U64 {}.x(NE.x),{};", | ||||
|                 cond, ret, false_value, ret, true_value); | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user