diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp index e0fe47912b..f3c7ceb57f 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input.cpp @@ -13,59 +13,535 @@ namespace { // Emulate GPU's LOP3.LUT (three-input logic op with 8-bit truth table) IR::U32 ApplyLUT(IR::IREmitter& ir, const IR::U32& a, const IR::U32& b, const IR::U32& c, u64 ttbl) { - IR::U32 r{ir.Imm32(0)}; - const IR::U32 not_a{ir.BitwiseNot(a)}; - const IR::U32 not_b{ir.BitwiseNot(b)}; - const IR::U32 not_c{ir.BitwiseNot(c)}; - if (ttbl & 0x01) { - // r |= ~a & ~b & ~c; - const auto lhs{ir.BitwiseAnd(not_a, not_b)}; - const auto rhs{ir.BitwiseAnd(lhs, not_c)}; - r = ir.BitwiseOr(r, rhs); + switch (ttbl) { + // generated code, do not edit manually + case 0: + return ir.Imm32(0); + case 1: + return ir.BitwiseNot(ir.BitwiseOr(a, ir.BitwiseOr(b, c))); + case 2: + return ir.BitwiseAnd(c, ir.BitwiseNot(ir.BitwiseOr(a, b))); + case 3: + return ir.BitwiseNot(ir.BitwiseOr(a, b)); + case 4: + return ir.BitwiseAnd(b, ir.BitwiseNot(ir.BitwiseOr(a, c))); + case 5: + return ir.BitwiseNot(ir.BitwiseOr(a, c)); + case 6: + return ir.BitwiseAnd(ir.BitwiseNot(a), ir.BitwiseXor(b, c)); + case 7: + return ir.BitwiseNot(ir.BitwiseOr(a, ir.BitwiseAnd(b, c))); + case 8: + return ir.BitwiseAnd(ir.BitwiseAnd(b, c), ir.BitwiseNot(a)); + case 9: + return ir.BitwiseNot(ir.BitwiseOr(a, ir.BitwiseXor(b, c))); + case 10: + return ir.BitwiseAnd(c, ir.BitwiseNot(a)); + case 11: + return ir.BitwiseAnd(ir.BitwiseNot(a), ir.BitwiseOr(c, ir.BitwiseNot(b))); + case 12: + return ir.BitwiseAnd(b, ir.BitwiseNot(a)); + case 13: + return ir.BitwiseAnd(ir.BitwiseNot(a), ir.BitwiseOr(b, ir.BitwiseNot(c))); + case 14: + return ir.BitwiseAnd(ir.BitwiseNot(a), ir.BitwiseOr(b, c)); + case 15: + return ir.BitwiseNot(a); + case 16: + return ir.BitwiseAnd(a, ir.BitwiseNot(ir.BitwiseOr(b, c))); + case 17: + return ir.BitwiseNot(ir.BitwiseOr(b, c)); + case 18: + return ir.BitwiseAnd(ir.BitwiseNot(b), ir.BitwiseXor(a, c)); + case 19: + return ir.BitwiseNot(ir.BitwiseOr(b, ir.BitwiseAnd(a, c))); + case 20: + return ir.BitwiseAnd(ir.BitwiseNot(c), ir.BitwiseXor(a, b)); + case 21: + return ir.BitwiseNot(ir.BitwiseOr(c, ir.BitwiseAnd(a, b))); + case 22: + return ir.BitwiseXor(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseAnd(a, b))); + case 23: + return ir.BitwiseXor(ir.BitwiseAnd(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c)), + ir.BitwiseNot(a)); + case 24: + return ir.BitwiseAnd(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c)); + case 25: + return ir.BitwiseNot(ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(b, c))); + case 26: + return ir.BitwiseAnd(ir.BitwiseOr(c, ir.BitwiseNot(b)), ir.BitwiseXor(a, c)); + case 27: + return ir.BitwiseXor(ir.BitwiseOr(a, ir.BitwiseNot(c)), ir.BitwiseOr(b, c)); + case 28: + return ir.BitwiseAnd(ir.BitwiseOr(b, ir.BitwiseNot(c)), ir.BitwiseXor(a, b)); + case 29: + return ir.BitwiseXor(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseOr(b, c)); + case 30: + return ir.BitwiseXor(a, ir.BitwiseOr(b, c)); + case 31: + return ir.BitwiseNot(ir.BitwiseAnd(a, ir.BitwiseOr(b, c))); + case 32: + return ir.BitwiseAnd(ir.BitwiseAnd(a, c), ir.BitwiseNot(b)); + case 33: + return ir.BitwiseNot(ir.BitwiseOr(b, ir.BitwiseXor(a, c))); + case 34: + return ir.BitwiseAnd(c, ir.BitwiseNot(b)); + case 35: + return ir.BitwiseAnd(ir.BitwiseNot(b), ir.BitwiseOr(c, ir.BitwiseNot(a))); + case 36: + return ir.BitwiseAnd(ir.BitwiseXor(a, b), ir.BitwiseXor(b, c)); + case 37: + return ir.BitwiseNot(ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(a, c))); + case 38: + return ir.BitwiseAnd(ir.BitwiseOr(c, ir.BitwiseNot(a)), ir.BitwiseXor(b, c)); + case 39: + return ir.BitwiseXor(ir.BitwiseOr(a, c), ir.BitwiseOr(b, ir.BitwiseNot(c))); + case 40: + return ir.BitwiseAnd(c, ir.BitwiseXor(a, b)); + case 41: + return ir.BitwiseXor(ir.BitwiseOr(a, b), + ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseNot(c))); + case 42: + return ir.BitwiseAnd(c, ir.BitwiseNot(ir.BitwiseAnd(a, b))); + case 43: + return ir.BitwiseXor(ir.BitwiseOr(a, ir.BitwiseNot(c)), + ir.BitwiseOr(b, ir.BitwiseXor(a, c))); + case 44: + return ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, b)); + case 45: + return ir.BitwiseXor(a, ir.BitwiseOr(b, ir.BitwiseNot(c))); + case 46: + return ir.BitwiseXor(ir.BitwiseAnd(a, b), ir.BitwiseOr(b, c)); + case 47: + return ir.BitwiseOr(ir.BitwiseAnd(c, ir.BitwiseNot(b)), ir.BitwiseNot(a)); + case 48: + return ir.BitwiseAnd(a, ir.BitwiseNot(b)); + case 49: + return ir.BitwiseAnd(ir.BitwiseNot(b), ir.BitwiseOr(a, ir.BitwiseNot(c))); + case 50: + return ir.BitwiseAnd(ir.BitwiseNot(b), ir.BitwiseOr(a, c)); + case 51: + return ir.BitwiseNot(b); + case 52: + return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(c)), ir.BitwiseXor(a, b)); + case 53: + return ir.BitwiseXor(ir.BitwiseOr(a, c), ir.BitwiseOr(b, ir.BitwiseNot(a))); + case 54: + return ir.BitwiseXor(b, ir.BitwiseOr(a, c)); + case 55: + return ir.BitwiseNot(ir.BitwiseAnd(b, ir.BitwiseOr(a, c))); + case 56: + return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(a, b)); + case 57: + return ir.BitwiseXor(b, ir.BitwiseOr(a, ir.BitwiseNot(c))); + case 58: + return ir.BitwiseXor(ir.BitwiseAnd(a, b), ir.BitwiseOr(a, c)); + case 59: + return ir.BitwiseOr(ir.BitwiseAnd(c, ir.BitwiseNot(a)), ir.BitwiseNot(b)); + case 60: + return ir.BitwiseXor(a, b); + case 61: + return ir.BitwiseOr(ir.BitwiseNot(ir.BitwiseOr(a, c)), ir.BitwiseXor(a, b)); + case 62: + return ir.BitwiseOr(ir.BitwiseAnd(c, ir.BitwiseNot(a)), ir.BitwiseXor(a, b)); + case 63: + return ir.BitwiseNot(ir.BitwiseAnd(a, b)); + case 64: + return ir.BitwiseAnd(ir.BitwiseAnd(a, b), ir.BitwiseNot(c)); + case 65: + return ir.BitwiseNot(ir.BitwiseOr(c, ir.BitwiseXor(a, b))); + case 66: + return ir.BitwiseAnd(ir.BitwiseXor(a, c), ir.BitwiseXor(b, c)); + case 67: + return ir.BitwiseNot(ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(a, b))); + case 68: + return ir.BitwiseAnd(b, ir.BitwiseNot(c)); + case 69: + return ir.BitwiseAnd(ir.BitwiseNot(c), ir.BitwiseOr(b, ir.BitwiseNot(a))); + case 70: + return ir.BitwiseAnd(ir.BitwiseOr(b, ir.BitwiseNot(a)), ir.BitwiseXor(b, c)); + case 71: + return ir.BitwiseXor(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseNot(b))); + case 72: + return ir.BitwiseAnd(b, ir.BitwiseXor(a, c)); + case 73: + return ir.BitwiseXor(ir.BitwiseOr(a, c), + ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseNot(b))); + case 74: + return ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, c)); + case 75: + return ir.BitwiseXor(a, ir.BitwiseOr(c, ir.BitwiseNot(b))); + case 76: + return ir.BitwiseAnd(b, ir.BitwiseNot(ir.BitwiseAnd(a, c))); + case 77: + return ir.BitwiseXor(ir.BitwiseOr(a, ir.BitwiseNot(b)), + ir.BitwiseOr(c, ir.BitwiseXor(a, b))); + case 78: + return ir.BitwiseXor(ir.BitwiseAnd(a, c), ir.BitwiseOr(b, c)); + case 79: + return ir.BitwiseOr(ir.BitwiseAnd(b, ir.BitwiseNot(c)), ir.BitwiseNot(a)); + case 80: + return ir.BitwiseAnd(a, ir.BitwiseNot(c)); + case 81: + return ir.BitwiseAnd(ir.BitwiseNot(c), ir.BitwiseOr(a, ir.BitwiseNot(b))); + case 82: + return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseXor(a, c)); + case 83: + return ir.BitwiseXor(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseNot(a))); + case 84: + return ir.BitwiseAnd(ir.BitwiseNot(c), ir.BitwiseOr(a, b)); + case 85: + return ir.BitwiseNot(c); + case 86: + return ir.BitwiseXor(c, ir.BitwiseOr(a, b)); + case 87: + return ir.BitwiseNot(ir.BitwiseAnd(c, ir.BitwiseOr(a, b))); + case 88: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(a, c)); + case 89: + return ir.BitwiseXor(c, ir.BitwiseOr(a, ir.BitwiseNot(b))); + case 90: + return ir.BitwiseXor(a, c); + case 91: + return ir.BitwiseOr(ir.BitwiseNot(ir.BitwiseOr(a, b)), ir.BitwiseXor(a, c)); + case 92: + return ir.BitwiseXor(ir.BitwiseAnd(a, c), ir.BitwiseOr(a, b)); + case 93: + return ir.BitwiseOr(ir.BitwiseAnd(b, ir.BitwiseNot(a)), ir.BitwiseNot(c)); + case 94: + return ir.BitwiseOr(ir.BitwiseAnd(b, ir.BitwiseNot(a)), ir.BitwiseXor(a, c)); + case 95: + return ir.BitwiseNot(ir.BitwiseAnd(a, c)); + case 96: + return ir.BitwiseAnd(a, ir.BitwiseXor(b, c)); + case 97: + return ir.BitwiseXor(ir.BitwiseOr(b, c), + ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseNot(a))); + case 98: + return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(b, c)); + case 99: + return ir.BitwiseXor(b, ir.BitwiseOr(c, ir.BitwiseNot(a))); + case 100: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(b, c)); + case 101: + return ir.BitwiseXor(c, ir.BitwiseOr(b, ir.BitwiseNot(a))); + case 102: + return ir.BitwiseXor(b, c); + case 103: + return ir.BitwiseOr(ir.BitwiseNot(ir.BitwiseOr(a, b)), ir.BitwiseXor(b, c)); + case 104: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(c, ir.BitwiseAnd(a, b))); + case 105: + return ir.BitwiseXor(ir.BitwiseNot(a), ir.BitwiseXor(b, c)); + case 106: + return ir.BitwiseXor(c, ir.BitwiseAnd(a, b)); + case 107: + return ir.BitwiseXor(ir.BitwiseAnd(c, ir.BitwiseOr(a, b)), + ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 108: + return ir.BitwiseXor(b, ir.BitwiseAnd(a, c)); + case 109: + return ir.BitwiseXor(ir.BitwiseAnd(b, ir.BitwiseOr(a, c)), + ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 110: + return ir.BitwiseOr(ir.BitwiseAnd(b, ir.BitwiseNot(a)), ir.BitwiseXor(b, c)); + case 111: + return ir.BitwiseOr(ir.BitwiseNot(a), ir.BitwiseXor(b, c)); + case 112: + return ir.BitwiseAnd(a, ir.BitwiseNot(ir.BitwiseAnd(b, c))); + case 113: + return ir.BitwiseXor(ir.BitwiseOr(b, ir.BitwiseNot(a)), + ir.BitwiseOr(c, ir.BitwiseXor(a, b))); + case 114: + return ir.BitwiseXor(ir.BitwiseAnd(b, c), ir.BitwiseOr(a, c)); + case 115: + return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(c)), ir.BitwiseNot(b)); + case 116: + return ir.BitwiseXor(ir.BitwiseAnd(b, c), ir.BitwiseOr(a, b)); + case 117: + return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(b)), ir.BitwiseNot(c)); + case 118: + return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(b)), ir.BitwiseXor(b, c)); + case 119: + return ir.BitwiseNot(ir.BitwiseAnd(b, c)); + case 120: + return ir.BitwiseXor(a, ir.BitwiseAnd(b, c)); + case 121: + return ir.BitwiseXor(ir.BitwiseAnd(a, ir.BitwiseOr(b, c)), + ir.BitwiseXor(b, ir.BitwiseNot(c))); + case 122: + return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(b)), ir.BitwiseXor(a, c)); + case 123: + return ir.BitwiseOr(ir.BitwiseNot(b), ir.BitwiseXor(a, c)); + case 124: + return ir.BitwiseOr(ir.BitwiseAnd(a, ir.BitwiseNot(c)), ir.BitwiseXor(a, b)); + case 125: + return ir.BitwiseOr(ir.BitwiseNot(c), ir.BitwiseXor(a, b)); + case 126: + return ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c)); + case 127: + return ir.BitwiseNot(ir.BitwiseAnd(a, ir.BitwiseAnd(b, c))); + case 128: + return ir.BitwiseAnd(a, ir.BitwiseAnd(b, c)); + case 129: + return ir.BitwiseNot(ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c))); + case 130: + return ir.BitwiseAnd(c, ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 131: + return ir.BitwiseAnd(ir.BitwiseOr(c, ir.BitwiseNot(a)), ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 132: + return ir.BitwiseAnd(b, ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 133: + return ir.BitwiseAnd(ir.BitwiseOr(b, ir.BitwiseNot(a)), ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 134: + return ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, ir.BitwiseXor(b, c))); + case 135: + return ir.BitwiseXor(ir.BitwiseAnd(b, c), ir.BitwiseNot(a)); + case 136: + return ir.BitwiseAnd(b, c); + case 137: + return ir.BitwiseAnd(ir.BitwiseOr(b, ir.BitwiseNot(a)), ir.BitwiseXor(b, ir.BitwiseNot(c))); + case 138: + return ir.BitwiseAnd(c, ir.BitwiseOr(b, ir.BitwiseNot(a))); + case 139: + return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseNot(ir.BitwiseOr(a, b))); + case 140: + return ir.BitwiseAnd(b, ir.BitwiseOr(c, ir.BitwiseNot(a))); + case 141: + return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseNot(ir.BitwiseOr(a, c))); + case 142: + return ir.BitwiseXor(a, ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c))); + case 143: + return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseNot(a)); + case 144: + return ir.BitwiseAnd(a, ir.BitwiseXor(b, ir.BitwiseNot(c))); + case 145: + return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseXor(b, ir.BitwiseNot(c))); + case 146: + return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(a, ir.BitwiseXor(b, c))); + case 147: + return ir.BitwiseXor(ir.BitwiseAnd(a, c), ir.BitwiseNot(b)); + case 148: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(a, ir.BitwiseXor(b, c))); + case 149: + return ir.BitwiseXor(ir.BitwiseAnd(a, b), ir.BitwiseNot(c)); + case 150: + return ir.BitwiseXor(a, ir.BitwiseXor(b, c)); + case 151: + return ir.BitwiseOr(ir.BitwiseNot(ir.BitwiseOr(a, b)), + ir.BitwiseXor(a, ir.BitwiseXor(b, c))); + case 152: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(b, ir.BitwiseNot(c))); + case 153: + return ir.BitwiseXor(b, ir.BitwiseNot(c)); + case 154: + return ir.BitwiseXor(c, ir.BitwiseAnd(a, ir.BitwiseNot(b))); + case 155: + return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(b, c))); + case 156: + return ir.BitwiseXor(b, ir.BitwiseAnd(a, ir.BitwiseNot(c))); + case 157: + return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(b, c))); + case 158: + return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseXor(a, ir.BitwiseOr(b, c))); + case 159: + return ir.BitwiseNot(ir.BitwiseAnd(a, ir.BitwiseXor(b, c))); + case 160: + return ir.BitwiseAnd(a, c); + case 161: + return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 162: + return ir.BitwiseAnd(c, ir.BitwiseOr(a, ir.BitwiseNot(b))); + case 163: + return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseNot(ir.BitwiseOr(a, b))); + case 164: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 165: + return ir.BitwiseXor(a, ir.BitwiseNot(c)); + case 166: + return ir.BitwiseXor(c, ir.BitwiseAnd(b, ir.BitwiseNot(a))); + case 167: + return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseXor(a, c))); + case 168: + return ir.BitwiseAnd(c, ir.BitwiseOr(a, b)); + case 169: + return ir.BitwiseXor(ir.BitwiseNot(c), ir.BitwiseOr(a, b)); + case 170: + return c; + case 171: + return ir.BitwiseOr(c, ir.BitwiseNot(ir.BitwiseOr(a, b))); + case 172: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseNot(a))); + case 173: + return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 174: + return ir.BitwiseOr(c, ir.BitwiseAnd(b, ir.BitwiseNot(a))); + case 175: + return ir.BitwiseOr(c, ir.BitwiseNot(a)); + case 176: + return ir.BitwiseAnd(a, ir.BitwiseOr(c, ir.BitwiseNot(b))); + case 177: + return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseNot(ir.BitwiseOr(b, c))); + case 178: + return ir.BitwiseXor(b, ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c))); + case 179: + return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseNot(b)); + case 180: + return ir.BitwiseXor(a, ir.BitwiseAnd(b, ir.BitwiseNot(c))); + case 181: + return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, c))); + case 182: + return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(b, ir.BitwiseOr(a, c))); + case 183: + return ir.BitwiseNot(ir.BitwiseAnd(b, ir.BitwiseXor(a, c))); + case 184: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseNot(b))); + case 185: + return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(b, ir.BitwiseNot(c))); + case 186: + return ir.BitwiseOr(c, ir.BitwiseAnd(a, ir.BitwiseNot(b))); + case 187: + return ir.BitwiseOr(c, ir.BitwiseNot(b)); + case 188: + return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(a, b)); + case 189: + return ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 190: + return ir.BitwiseOr(c, ir.BitwiseXor(a, b)); + case 191: + return ir.BitwiseOr(c, ir.BitwiseNot(ir.BitwiseAnd(a, b))); + case 192: + return ir.BitwiseAnd(a, b); + case 193: + return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(c)), ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 194: + return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 195: + return ir.BitwiseXor(a, ir.BitwiseNot(b)); + case 196: + return ir.BitwiseAnd(b, ir.BitwiseOr(a, ir.BitwiseNot(c))); + case 197: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseNot(ir.BitwiseOr(a, c))); + case 198: + return ir.BitwiseXor(b, ir.BitwiseAnd(c, ir.BitwiseNot(a))); + case 199: + return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseXor(a, b))); + case 200: + return ir.BitwiseAnd(b, ir.BitwiseOr(a, c)); + case 201: + return ir.BitwiseXor(ir.BitwiseNot(b), ir.BitwiseOr(a, c)); + case 202: + return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseOr(b, ir.BitwiseNot(a))); + case 203: + return ir.BitwiseOr(ir.BitwiseAnd(b, c), ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 204: + return b; + case 205: + return ir.BitwiseOr(b, ir.BitwiseNot(ir.BitwiseOr(a, c))); + case 206: + return ir.BitwiseOr(b, ir.BitwiseAnd(c, ir.BitwiseNot(a))); + case 207: + return ir.BitwiseOr(b, ir.BitwiseNot(a)); + case 208: + return ir.BitwiseAnd(a, ir.BitwiseOr(b, ir.BitwiseNot(c))); + case 209: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseNot(ir.BitwiseOr(b, c))); + case 210: + return ir.BitwiseXor(a, ir.BitwiseAnd(c, ir.BitwiseNot(b))); + case 211: + return ir.BitwiseNot(ir.BitwiseAnd(ir.BitwiseOr(b, c), ir.BitwiseXor(a, b))); + case 212: + return ir.BitwiseXor(c, ir.BitwiseOr(ir.BitwiseXor(a, b), ir.BitwiseXor(a, c))); + case 213: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseNot(c)); + case 214: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(c, ir.BitwiseOr(a, b))); + case 215: + return ir.BitwiseNot(ir.BitwiseAnd(c, ir.BitwiseXor(a, b))); + case 216: + return ir.BitwiseAnd(ir.BitwiseOr(a, c), ir.BitwiseOr(b, ir.BitwiseNot(c))); + case 217: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(b, ir.BitwiseNot(c))); + case 218: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(a, c)); + case 219: + return ir.BitwiseOr(ir.BitwiseXor(a, c), ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 220: + return ir.BitwiseOr(b, ir.BitwiseAnd(a, ir.BitwiseNot(c))); + case 221: + return ir.BitwiseOr(b, ir.BitwiseNot(c)); + case 222: + return ir.BitwiseOr(b, ir.BitwiseXor(a, c)); + case 223: + return ir.BitwiseOr(b, ir.BitwiseNot(ir.BitwiseAnd(a, c))); + case 224: + return ir.BitwiseAnd(a, ir.BitwiseOr(b, c)); + case 225: + return ir.BitwiseXor(ir.BitwiseNot(a), ir.BitwiseOr(b, c)); + case 226: + return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(b)), ir.BitwiseOr(b, c)); + case 227: + return ir.BitwiseOr(ir.BitwiseAnd(a, c), ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 228: + return ir.BitwiseAnd(ir.BitwiseOr(a, ir.BitwiseNot(c)), ir.BitwiseOr(b, c)); + case 229: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 230: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), ir.BitwiseXor(b, c)); + case 231: + return ir.BitwiseOr(ir.BitwiseXor(a, ir.BitwiseNot(b)), ir.BitwiseXor(b, c)); + case 232: + return ir.BitwiseAnd(ir.BitwiseOr(a, b), ir.BitwiseOr(c, ir.BitwiseAnd(a, b))); + case 233: + return ir.BitwiseOr(ir.BitwiseAnd(a, b), + ir.BitwiseXor(ir.BitwiseNot(c), ir.BitwiseOr(a, b))); + case 234: + return ir.BitwiseOr(c, ir.BitwiseAnd(a, b)); + case 235: + return ir.BitwiseOr(c, ir.BitwiseXor(a, ir.BitwiseNot(b))); + case 236: + return ir.BitwiseOr(b, ir.BitwiseAnd(a, c)); + case 237: + return ir.BitwiseOr(b, ir.BitwiseXor(a, ir.BitwiseNot(c))); + case 238: + return ir.BitwiseOr(b, c); + case 239: + return ir.BitwiseOr(ir.BitwiseNot(a), ir.BitwiseOr(b, c)); + case 240: + return a; + case 241: + return ir.BitwiseOr(a, ir.BitwiseNot(ir.BitwiseOr(b, c))); + case 242: + return ir.BitwiseOr(a, ir.BitwiseAnd(c, ir.BitwiseNot(b))); + case 243: + return ir.BitwiseOr(a, ir.BitwiseNot(b)); + case 244: + return ir.BitwiseOr(a, ir.BitwiseAnd(b, ir.BitwiseNot(c))); + case 245: + return ir.BitwiseOr(a, ir.BitwiseNot(c)); + case 246: + return ir.BitwiseOr(a, ir.BitwiseXor(b, c)); + case 247: + return ir.BitwiseOr(a, ir.BitwiseNot(ir.BitwiseAnd(b, c))); + case 248: + return ir.BitwiseOr(a, ir.BitwiseAnd(b, c)); + case 249: + return ir.BitwiseOr(a, ir.BitwiseXor(b, ir.BitwiseNot(c))); + case 250: + return ir.BitwiseOr(a, c); + case 251: + return ir.BitwiseOr(ir.BitwiseNot(b), ir.BitwiseOr(a, c)); + case 252: + return ir.BitwiseOr(a, b); + case 253: + return ir.BitwiseOr(ir.BitwiseNot(c), ir.BitwiseOr(a, b)); + case 254: + return ir.BitwiseOr(a, ir.BitwiseOr(b, c)); + case 255: + return ir.Imm32(0xFFFFFFFF); + // end of generated code } - if (ttbl & 0x02) { - // r |= ~a & ~b & c; - const auto lhs{ir.BitwiseAnd(not_a, not_b)}; - const auto rhs{ir.BitwiseAnd(lhs, c)}; - r = ir.BitwiseOr(r, rhs); - } - if (ttbl & 0x04) { - // r |= ~a & b & ~c; - const auto lhs{ir.BitwiseAnd(not_a, b)}; - const auto rhs{ir.BitwiseAnd(lhs, not_c)}; - r = ir.BitwiseOr(r, rhs); - } - if (ttbl & 0x08) { - // r |= ~a & b & c; - const auto lhs{ir.BitwiseAnd(not_a, b)}; - const auto rhs{ir.BitwiseAnd(lhs, c)}; - r = ir.BitwiseOr(r, rhs); - } - if (ttbl & 0x10) { - // r |= a & ~b & ~c; - const auto lhs{ir.BitwiseAnd(a, not_b)}; - const auto rhs{ir.BitwiseAnd(lhs, not_c)}; - r = ir.BitwiseOr(r, rhs); - } - if (ttbl & 0x20) { - // r |= a & ~b & c; - const auto lhs{ir.BitwiseAnd(a, not_b)}; - const auto rhs{ir.BitwiseAnd(lhs, c)}; - r = ir.BitwiseOr(r, rhs); - } - if (ttbl & 0x40) { - // r |= a & b & ~c; - const auto lhs{ir.BitwiseAnd(a, b)}; - const auto rhs{ir.BitwiseAnd(lhs, not_c)}; - r = ir.BitwiseOr(r, rhs); - } - if (ttbl & 0x80) { - // r |= a & b & c; - const auto lhs{ir.BitwiseAnd(a, b)}; - const auto rhs{ir.BitwiseAnd(lhs, c)}; - r = ir.BitwiseOr(r, rhs); - } - return r; + throw NotImplementedException("LOP3 with out of range ttbl"); } IR::U32 LOP3(TranslatorVisitor& v, u64 insn, const IR::U32& op_b, const IR::U32& op_c, u64 lut) { diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input_lut3.py b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input_lut3.py new file mode 100644 index 0000000000..8f547c2662 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input_lut3.py @@ -0,0 +1,92 @@ +# Copyright © 2022 degasus +# This work is free. You can redistribute it and/or modify it under the +# terms of the Do What The Fuck You Want To Public License, Version 2, +# as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. + +from itertools import product + +# The primitive instructions +OPS = { + 'ir.BitwiseAnd({}, {})' : (2, 1, lambda a,b: a&b), + 'ir.BitwiseOr({}, {})' : (2, 1, lambda a,b: a|b), + 'ir.BitwiseXor({}, {})' : (2, 1, lambda a,b: a^b), + 'ir.BitwiseNot({})' : (1, 0.1, lambda a: (~a) & 255), # Only tiny cost, as this can often inlined in other instructions +} + +# Our database of combination of instructions +optimized_calls = {} +def cmp(lhs, rhs): + if lhs is None: # new entry + return True + if lhs[3] > rhs[3]: # costs + return True + if lhs[3] < rhs[3]: # costs + return False + if len(lhs[0]) > len(rhs[0]): # string len + return True + if len(lhs[0]) < len(rhs[0]): # string len + return False + if lhs[0] > rhs[0]: # string sorting + return True + if lhs[0] < rhs[0]: # string sorting + return False + assert lhs == rhs, "redundant instruction, bug in brute force" + return False +def register(imm, instruction, count, latency): + # Use the sum of instruction count and latency as costs to evaluate which combination is best + costs = count + latency + + old = optimized_calls.get(imm, None) + new = (instruction, count, latency, costs) + + # Update if new or better + if cmp(old, new): + optimized_calls[imm] = new + return True + + return False + +# Constants: 0, 1 (for free) +register(0, 'ir.Imm32(0)', 0, 0) +register(255, 'ir.Imm32(0xFFFFFFFF)', 0, 0) + +# Inputs: a, b, c (for free) +ta = 0xF0 +tb = 0xCC +tc = 0xAA +inputs = { + ta : 'a', + tb : 'b', + tc : 'c', +} +for imm, instruction in inputs.items(): + register(imm, instruction, 0, 0) + register((~imm) & 255, 'ir.BitwiseNot({})'.format(instruction), 0.099, 0.099) # slightly cheaper NEG on inputs + +# Try to combine two values from the db with an instruction. +# If it is better than the old method, update it. +while True: + registered = 0 + calls_copy = optimized_calls.copy() + for OP, (argc, cost, f) in OPS.items(): + for args in product(calls_copy.items(), repeat=argc): + # unpack(transponse) the arrays + imm = [arg[0] for arg in args] + value = [arg[1][0] for arg in args] + count = [arg[1][1] for arg in args] + latency = [arg[1][2] for arg in args] + + registered += register( + f(*imm), + OP.format(*value), + sum(count) + cost, + max(latency) + cost) + if registered == 0: + # No update at all? So terminate + break + +# Hacky output. Please improve me to output valid C++ instead. +s = """ case {imm}: + return {op};""" +for imm in range(256): + print(s.format(imm=imm, op=optimized_calls[imm][0]))