Просмотр исходного кода

opengl: Implement LOP.CC

Used by MH:Rise
ameerj 5 лет назад
Родитель
Сommit
8289eb108f

+ 27 - 3
src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp

@@ -7,6 +7,30 @@
 #include "shader_recompiler/frontend/ir/value.h"
 
 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) {
     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) {
-    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) {
-    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) {
-    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,

+ 11 - 3
src/shader_recompiler/backend/glsl/emit_glsl_integer.cpp

@@ -27,6 +27,14 @@ void SetSignFlag(EmitContext& ctx, IR::Inst& inst, std::string_view result) {
     ctx.AddU1("{}=int({})<0;", *sign, result);
     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
 
 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) {
-    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) {
-    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) {
-    ctx.AddU32("{}={}^{};", inst, a, b);
+    BitwiseLogicalOp(ctx, inst, a, b, '^');
 }
 
 void EmitBitFieldInsert(EmitContext& ctx, IR::Inst& inst, std::string_view base,