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

gl_shader_decompiler: Implement POPC (#1203)

* Implement POPC

* implement invert
Laku 8 лет назад
Родитель
Сommit
915ab81ec2

+ 10 - 0
src/video_core/engines/shader_bytecode.h

@@ -344,6 +344,10 @@ union Instruction {
         BitField<49, 1, u64> negate_a;
         BitField<49, 1, u64> negate_a;
     } alu_integer;
     } alu_integer;
 
 
+    union {
+        BitField<40, 1, u64> invert;
+    } popc;
+
     union {
     union {
         BitField<39, 3, u64> pred;
         BitField<39, 3, u64> pred;
         BitField<42, 1, u64> neg_pred;
         BitField<42, 1, u64> neg_pred;
@@ -671,6 +675,9 @@ public:
         ISCADD_C, // Scale and Add
         ISCADD_C, // Scale and Add
         ISCADD_R,
         ISCADD_R,
         ISCADD_IMM,
         ISCADD_IMM,
+        POPC_C,
+        POPC_R,
+        POPC_IMM,
         SEL_C,
         SEL_C,
         SEL_R,
         SEL_R,
         SEL_IMM,
         SEL_IMM,
@@ -892,6 +899,9 @@ private:
             INST("0100110000011---", Id::ISCADD_C, Type::ArithmeticInteger, "ISCADD_C"),
             INST("0100110000011---", Id::ISCADD_C, Type::ArithmeticInteger, "ISCADD_C"),
             INST("0101110000011---", Id::ISCADD_R, Type::ArithmeticInteger, "ISCADD_R"),
             INST("0101110000011---", Id::ISCADD_R, Type::ArithmeticInteger, "ISCADD_R"),
             INST("0011100-00011---", Id::ISCADD_IMM, Type::ArithmeticInteger, "ISCADD_IMM"),
             INST("0011100-00011---", Id::ISCADD_IMM, Type::ArithmeticInteger, "ISCADD_IMM"),
+            INST("0100110000001---", Id::POPC_C, Type::ArithmeticInteger, "POPC_C"),
+            INST("0101110000001---", Id::POPC_R, Type::ArithmeticInteger, "POPC_R"),
+            INST("0011100-00001---", Id::POPC_IMM, Type::ArithmeticInteger, "POPC_IMM"),
             INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"),
             INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"),
             INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"),
             INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"),
             INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"),
             INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"),

+ 9 - 0
src/video_core/renderer_opengl/gl_shader_decompiler.cpp

@@ -1363,6 +1363,15 @@ private:
                                           "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1);
                                           "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1);
                 break;
                 break;
             }
             }
+            case OpCode::Id::POPC_C:
+            case OpCode::Id::POPC_R:
+            case OpCode::Id::POPC_IMM: {
+                if (instr.popc.invert) {
+                    op_b = "~(" + op_b + ')';
+                }
+                regs.SetRegisterToInteger(instr.gpr0, true, 0, "bitCount(" + op_b + ')', 1, 1);
+                break;
+            }
             case OpCode::Id::SEL_C:
             case OpCode::Id::SEL_C:
             case OpCode::Id::SEL_R:
             case OpCode::Id::SEL_R:
             case OpCode::Id::SEL_IMM: {
             case OpCode::Id::SEL_IMM: {