opengl: Implement LOP.CC
Used by MH:Rise
This commit is contained in:
		| @@ -7,6 +7,30 @@ | |||||||
| #include "shader_recompiler/frontend/ir/value.h" | #include "shader_recompiler/frontend/ir/value.h" | ||||||
|  |  | ||||||
| namespace Shader::Backend::GLASM { | namespace Shader::Backend::GLASM { | ||||||
|  | namespace { | ||||||
|  | void BitwiseLogicalOp(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b, | ||||||
|  |                       std::string_view lop) { | ||||||
|  |     const auto zero = inst.GetAssociatedPseudoOperation(IR::Opcode::GetZeroFromOp); | ||||||
|  |     const auto sign = inst.GetAssociatedPseudoOperation(IR::Opcode::GetSignFromOp); | ||||||
|  |     if (zero) { | ||||||
|  |         zero->Invalidate(); | ||||||
|  |     } | ||||||
|  |     if (sign) { | ||||||
|  |         sign->Invalidate(); | ||||||
|  |     } | ||||||
|  |     if (zero || sign) { | ||||||
|  |         ctx.reg_alloc.InvalidateConditionCodes(); | ||||||
|  |     } | ||||||
|  |     const auto ret{ctx.reg_alloc.Define(inst)}; | ||||||
|  |     ctx.Add("{}.S {}.x,{},{};", lop, ret, a, b); | ||||||
|  |     if (zero) { | ||||||
|  |         ctx.Add("SEQ.S {},{},0;", *zero, ret); | ||||||
|  |     } | ||||||
|  |     if (sign) { | ||||||
|  |         ctx.Add("SLT.S {},{},0;", *sign, ret); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | } // Anonymous namespace | ||||||
|  |  | ||||||
| void EmitIAdd32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | void EmitIAdd32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||||||
|     const std::array flags{ |     const std::array flags{ | ||||||
| @@ -110,15 +134,15 @@ void EmitShiftRightArithmetic64(EmitContext& ctx, IR::Inst& inst, ScalarRegister | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBitwiseAnd32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | void EmitBitwiseAnd32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||||||
|     ctx.Add("AND.S {}.x,{},{};", inst, a, b); |     BitwiseLogicalOp(ctx, inst, a, b, "AND"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBitwiseOr32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | void EmitBitwiseOr32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||||||
|     ctx.Add("OR.S {}.x,{},{};", inst, a, b); |     BitwiseLogicalOp(ctx, inst, a, b, "OR"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBitwiseXor32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | void EmitBitwiseXor32(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b) { | ||||||
|     ctx.Add("XOR.S {}.x,{},{};", inst, a, b); |     BitwiseLogicalOp(ctx, inst, a, b, "XOR"); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 insert, | void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, ScalarS32 base, ScalarS32 insert, | ||||||
|   | |||||||
| @@ -27,6 +27,14 @@ void SetSignFlag(EmitContext& ctx, IR::Inst& inst, std::string_view result) { | |||||||
|     ctx.AddU1("{}=int({})<0;", *sign, result); |     ctx.AddU1("{}=int({})<0;", *sign, result); | ||||||
|     sign->Invalidate(); |     sign->Invalidate(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void BitwiseLogicalOp(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, | ||||||
|  |                       char lop) { | ||||||
|  |     const auto result{ctx.var_alloc.Define(inst, GlslVarType::U32)}; | ||||||
|  |     ctx.Add("{}={}{}{};", result, a, lop, b); | ||||||
|  |     SetZeroFlag(ctx, inst, result); | ||||||
|  |     SetSignFlag(ctx, inst, result); | ||||||
|  | } | ||||||
| } // Anonymous namespace | } // Anonymous namespace | ||||||
|  |  | ||||||
| void EmitIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | void EmitIAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | ||||||
| @@ -113,15 +121,15 @@ void EmitShiftRightArithmetic64(EmitContext& ctx, IR::Inst& inst, std::string_vi | |||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBitwiseAnd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | void EmitBitwiseAnd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | ||||||
|     ctx.AddU32("{}={}&{};", inst, a, b); |     BitwiseLogicalOp(ctx, inst, a, b, '&'); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBitwiseOr32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | void EmitBitwiseOr32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | ||||||
|     ctx.AddU32("{}={}|{};", inst, a, b); |     BitwiseLogicalOp(ctx, inst, a, b, '|'); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBitwiseXor32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | void EmitBitwiseXor32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | ||||||
|     ctx.AddU32("{}={}^{};", inst, a, b); |     BitwiseLogicalOp(ctx, inst, a, b, '^'); | ||||||
| } | } | ||||||
|  |  | ||||||
| void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, std::string_view base, | void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, std::string_view base, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user