diff options
Diffstat (limited to 'src/shader_recompiler/frontend')
6 files changed, 672 insertions, 56 deletions
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.cpp b/src/shader_recompiler/frontend/ir/microinstruction.cpp index 97e2bf6af..631446cf7 100644 --- a/src/shader_recompiler/frontend/ir/microinstruction.cpp +++ b/src/shader_recompiler/frontend/ir/microinstruction.cpp @@ -118,6 +118,7 @@ bool Inst::MayHaveSideEffects() const noexcept { case Opcode::SharedAtomicXor32: case Opcode::SharedAtomicExchange32: case Opcode::SharedAtomicExchange64: + case Opcode::SharedAtomicExchange32x2: case Opcode::GlobalAtomicIAdd32: case Opcode::GlobalAtomicSMin32: case Opcode::GlobalAtomicUMin32: @@ -138,6 +139,15 @@ bool Inst::MayHaveSideEffects() const noexcept { case Opcode::GlobalAtomicOr64: case Opcode::GlobalAtomicXor64: case Opcode::GlobalAtomicExchange64: + case Opcode::GlobalAtomicIAdd32x2: + case Opcode::GlobalAtomicSMin32x2: + case Opcode::GlobalAtomicUMin32x2: + case Opcode::GlobalAtomicSMax32x2: + case Opcode::GlobalAtomicUMax32x2: + case Opcode::GlobalAtomicAnd32x2: + case Opcode::GlobalAtomicOr32x2: + case Opcode::GlobalAtomicXor32x2: + case Opcode::GlobalAtomicExchange32x2: case Opcode::GlobalAtomicAddF32: case Opcode::GlobalAtomicAddF16x2: case Opcode::GlobalAtomicAddF32x2: @@ -165,6 +175,15 @@ bool Inst::MayHaveSideEffects() const noexcept { case Opcode::StorageAtomicOr64: case Opcode::StorageAtomicXor64: case Opcode::StorageAtomicExchange64: + case Opcode::StorageAtomicIAdd32x2: + case Opcode::StorageAtomicSMin32x2: + case Opcode::StorageAtomicUMin32x2: + case Opcode::StorageAtomicSMax32x2: + case Opcode::StorageAtomicUMax32x2: + case Opcode::StorageAtomicAnd32x2: + case Opcode::StorageAtomicOr32x2: + case Opcode::StorageAtomicXor32x2: + case Opcode::StorageAtomicExchange32x2: case Opcode::StorageAtomicAddF32: case Opcode::StorageAtomicAddF16x2: case Opcode::StorageAtomicAddF32x2: diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc index b94ce7406..efb6bfac3 100644 --- a/src/shader_recompiler/frontend/ir/opcodes.inc +++ b/src/shader_recompiler/frontend/ir/opcodes.inc @@ -341,6 +341,7 @@ OPCODE(SharedAtomicOr32, U32, U32, OPCODE(SharedAtomicXor32, U32, U32, U32, ) OPCODE(SharedAtomicExchange32, U32, U32, U32, ) OPCODE(SharedAtomicExchange64, U64, U32, U64, ) +OPCODE(SharedAtomicExchange32x2, U32x2, U32, U32x2, ) OPCODE(GlobalAtomicIAdd32, U32, U64, U32, ) OPCODE(GlobalAtomicSMin32, U32, U64, U32, ) @@ -362,6 +363,15 @@ OPCODE(GlobalAtomicAnd64, U64, U64, OPCODE(GlobalAtomicOr64, U64, U64, U64, ) OPCODE(GlobalAtomicXor64, U64, U64, U64, ) OPCODE(GlobalAtomicExchange64, U64, U64, U64, ) +OPCODE(GlobalAtomicIAdd32x2, U32x2, U32x2, U32x2, ) +OPCODE(GlobalAtomicSMin32x2, U32x2, U32x2, U32x2, ) +OPCODE(GlobalAtomicUMin32x2, U32x2, U32x2, U32x2, ) +OPCODE(GlobalAtomicSMax32x2, U32x2, U32x2, U32x2, ) +OPCODE(GlobalAtomicUMax32x2, U32x2, U32x2, U32x2, ) +OPCODE(GlobalAtomicAnd32x2, U32x2, U32x2, U32x2, ) +OPCODE(GlobalAtomicOr32x2, U32x2, U32x2, U32x2, ) +OPCODE(GlobalAtomicXor32x2, U32x2, U32x2, U32x2, ) +OPCODE(GlobalAtomicExchange32x2, U32x2, U32x2, U32x2, ) OPCODE(GlobalAtomicAddF32, F32, U64, F32, ) OPCODE(GlobalAtomicAddF16x2, U32, U64, F16x2, ) OPCODE(GlobalAtomicAddF32x2, U32, U64, F32x2, ) @@ -390,6 +400,15 @@ OPCODE(StorageAtomicAnd64, U64, U32, OPCODE(StorageAtomicOr64, U64, U32, U32, U64, ) OPCODE(StorageAtomicXor64, U64, U32, U32, U64, ) OPCODE(StorageAtomicExchange64, U64, U32, U32, U64, ) +OPCODE(StorageAtomicIAdd32x2, U32x2, U32, U32, U32x2, ) +OPCODE(StorageAtomicSMin32x2, U32x2, U32, U32, U32x2, ) +OPCODE(StorageAtomicUMin32x2, U32x2, U32, U32, U32x2, ) +OPCODE(StorageAtomicSMax32x2, U32x2, U32, U32, U32x2, ) +OPCODE(StorageAtomicUMax32x2, U32x2, U32, U32, U32x2, ) +OPCODE(StorageAtomicAnd32x2, U32x2, U32, U32, U32x2, ) +OPCODE(StorageAtomicOr32x2, U32x2, U32, U32, U32x2, ) +OPCODE(StorageAtomicXor32x2, U32x2, U32, U32, U32x2, ) +OPCODE(StorageAtomicExchange32x2, U32x2, U32, U32, U32x2, ) OPCODE(StorageAtomicAddF32, F32, U32, U32, F32, ) OPCODE(StorageAtomicAddF16x2, U32, U32, U32, F16x2, ) OPCODE(StorageAtomicAddF32x2, U32, U32, U32, F32x2, ) diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp index 2300088e3..8007a4d46 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/load_constant.cpp @@ -11,10 +11,20 @@ namespace Shader::Maxwell { using namespace LDC; namespace { std::pair<IR::U32, IR::U32> Slot(IR::IREmitter& ir, Mode mode, const IR::U32& imm_index, - const IR::U32& reg, const IR::U32& imm) { + const IR::U32& reg, const IR::U32& imm_offset) { switch (mode) { case Mode::Default: - return {imm_index, ir.IAdd(reg, imm)}; + return {imm_index, ir.IAdd(reg, imm_offset)}; + case Mode::IS: { + // Segmented addressing mode + // Ra+imm_offset points into a flat mapping of const buffer + // address space + const IR::U32 address{ir.IAdd(reg, imm_offset)}; + const IR::U32 index{ir.BitFieldExtract(address, ir.Imm32(16), ir.Imm32(16))}; + const IR::U32 offset{ir.BitFieldExtract(address, ir.Imm32(0), ir.Imm32(16))}; + + return {ir.IAdd(index, imm_index), offset}; + } default: break; } 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 e0fe47912..f3c7ceb57 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 000000000..8f547c266 --- /dev/null +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation_three_input_lut3.py @@ -0,0 +1,92 @@ +# Copyright © 2022 degasus <markus@selfnet.de> +# 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])) diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp index 248ad3ced..b22725584 100644 --- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp @@ -212,11 +212,11 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo } Optimization::SsaRewritePass(program); + Optimization::ConstantPropagationPass(program); + Optimization::GlobalMemoryToStorageBufferPass(program); Optimization::TexturePass(env, program); - Optimization::ConstantPropagationPass(program); - if (Settings::values.resolution_info.active) { Optimization::RescalingPass(program); } |