From b6d9cc824e9573623a460c5ffd0664bbe5429956 Mon Sep 17 00:00:00 2001 From: merry Date: Tue, 8 Mar 2022 13:25:04 +0000 Subject: [PATCH] TruthTable --- .../Instructions/Lop3Expression.cs | 106 +++++++++--------- 1 file changed, 55 insertions(+), 51 deletions(-) diff --git a/Ryujinx.Graphics.Shader/Instructions/Lop3Expression.cs b/Ryujinx.Graphics.Shader/Instructions/Lop3Expression.cs index aa47feca0..e7fd934bc 100644 --- a/Ryujinx.Graphics.Shader/Instructions/Lop3Expression.cs +++ b/Ryujinx.Graphics.Shader/Instructions/Lop3Expression.cs @@ -7,6 +7,26 @@ namespace Ryujinx.Graphics.Shader.Instructions { static class Lop3Expression { + private enum TruthTable : byte + { + False = 0x00, // false + True = 0xff, // true + In = 0xf0, // a + And2 = 0xc0, // a & b + Xor2 = 0x3c, // a ^ b + And3 = 0x80, // a & b & c + XorAnd = 0x60, // a & (b ^ c) + OrAnd = 0xe0, // a & (b | c) + Onehot = 0x16, // (a & !b & !c) | (!a & b & !c) | (!a & !b & c) - Only one value is true. + Majority = 0xe8, // Popcount(a, b, c) >= 2 + Gamble = 0x81, // (a & b & c) | (!a & !b & !c) - All on or all off + InverseGamble = 0x7e, // Inverse of Gamble + Dot = 0x1a, // a ^ (c | (a & b)) + Mux = 0xca, // a ? b : c + AndXor = 0x78, // a ^ (b & c) + Xor3 = 0x96, // a ^ b ^ c + } + public static Operand GetFromTruthTable(EmitterContext context, Operand srcA, Operand srcB, Operand srcC, int imm) { Operand notSrcA = context.BitwiseNot(srcA); @@ -15,7 +35,7 @@ namespace Ryujinx.Graphics.Shader.Instructions for (int i = 0; i < 0x40; i++) { - int currImm = imm; + TruthTable currImm = (TruthTable)imm; Operand x = srcA; Operand y = srcB; @@ -24,37 +44,37 @@ namespace Ryujinx.Graphics.Shader.Instructions if ((i & 0x01) != 0) { x = notSrcA; - currImm = PermuteByte(currImm, 3, 2, 1, 0, 7, 6, 5, 4); + currImm = PermuteTable(currImm, 3, 2, 1, 0, 7, 6, 5, 4); } if ((i & 0x02) != 0) { y = notSrcB; - currImm = PermuteByte(currImm, 5, 4, 7, 6, 1, 0, 3, 2); + currImm = PermuteTable(currImm, 5, 4, 7, 6, 1, 0, 3, 2); } if ((i & 0x04) != 0) { z = notSrcC; - currImm = PermuteByte(currImm, 6, 7, 4, 5, 2, 3, 0, 1); + currImm = PermuteTable(currImm, 6, 7, 4, 5, 2, 3, 0, 1); } if ((i & 0x08) != 0) { (x, y) = (y, x); - currImm = PermuteByte(currImm, 7, 6, 3, 2, 5, 4, 1, 0); + currImm = PermuteTable(currImm, 7, 6, 3, 2, 5, 4, 1, 0); } if ((i & 0x10) != 0) { (x, z) = (z, x); - currImm = PermuteByte(currImm, 7, 3, 5, 1, 6, 2, 4, 0); + currImm = PermuteTable(currImm, 7, 3, 5, 1, 6, 2, 4, 0); } if ((i & 0x20) != 0) { (y, z) = (z, y); - currImm = PermuteByte(currImm, 7, 5, 6, 4, 3, 1, 2, 0); + currImm = PermuteTable(currImm, 7, 5, 6, 4, 3, 1, 2, 0); } Operand result = GetExpr(currImm, context, x, y, z); @@ -63,7 +83,7 @@ namespace Ryujinx.Graphics.Shader.Instructions return result; } - Operand notResult = GetExpr((~currImm) & 0xff, context, x, y, z); + Operand notResult = GetExpr((TruthTable)((~(int)currImm) & 0xff), context, x, y, z); if (notResult != null) { return context.BitwiseNot(notResult); @@ -73,59 +93,43 @@ namespace Ryujinx.Graphics.Shader.Instructions return null; } - private static Operand GetExpr(int imm, EmitterContext context, Operand x, Operand y, Operand z) + private static Operand GetExpr(TruthTable imm, EmitterContext context, Operand x, Operand y, Operand z) { return imm switch { - // False - 0x00 => Const(IrConsts.False), - // True - 0xff => Const(IrConsts.True), - // In - 0xf0 => x, - // And2 - 0xc0 => context.BitwiseAnd(x, y), - // Xor2 - 0x3c => context.BitwiseExclusiveOr(x, y), - // And3 - 0x80 => context.BitwiseAnd(x, context.BitwiseAnd(y, z)), - // XorAnd - 0x60 => context.BitwiseAnd(x, context.BitwiseExclusiveOr(y, z)), - // OrAnd - 0xe0 => context.BitwiseAnd(x, context.BitwiseOr(y, z)), - // Onehot - 0x16 => context.BitwiseExclusiveOr(context.BitwiseOr(x, y), context.BitwiseOr(z, context.BitwiseAnd(x, y))), - // Majority - 0xe8 => context.BitwiseAnd(context.BitwiseOr(x, y), context.BitwiseOr(z, context.BitwiseAnd(x, y))), - // Inverse Gamble - 0x7e => context.BitwiseOr(context.BitwiseExclusiveOr(x, y), context.BitwiseExclusiveOr(x, z)), - // Dot - 0x1a => context.BitwiseAnd(context.BitwiseExclusiveOr(x, z), context.BitwiseOr(context.BitwiseNot(y), z)), - // Mux - 0xca => context.BitwiseOr(context.BitwiseAnd(x, y), context.BitwiseAnd(context.BitwiseNot(x), z)), - // AndXor - 0x78 => context.BitwiseExclusiveOr(x, context.BitwiseAnd(y, z)), - // Xor3 - 0x96 => context.BitwiseExclusiveOr(x, context.BitwiseExclusiveOr(y, z)), - // Not one of the base cases - _ => null + TruthTable.False => Const(IrConsts.False), + TruthTable.True => Const(IrConsts.True), + TruthTable.In => x, + TruthTable.And2 => context.BitwiseAnd(x, y), + TruthTable.Xor2 => context.BitwiseExclusiveOr(x, y), + TruthTable.And3 => context.BitwiseAnd(x, context.BitwiseAnd(y, z)), + TruthTable.XorAnd => context.BitwiseAnd(x, context.BitwiseExclusiveOr(y, z)), + TruthTable.OrAnd => context.BitwiseAnd(x, context.BitwiseOr(y, z)), + TruthTable.Onehot => context.BitwiseExclusiveOr(context.BitwiseOr(x, y), context.BitwiseOr(z, context.BitwiseAnd(x, y))), + TruthTable.Majority => context.BitwiseAnd(context.BitwiseOr(x, y), context.BitwiseOr(z, context.BitwiseAnd(x, y))), + TruthTable.InverseGamble => context.BitwiseOr(context.BitwiseExclusiveOr(x, y), context.BitwiseExclusiveOr(x, z)), + TruthTable.Dot => context.BitwiseAnd(context.BitwiseExclusiveOr(x, z), context.BitwiseOr(context.BitwiseNot(y), z)), + TruthTable.Mux => context.BitwiseOr(context.BitwiseAnd(x, y), context.BitwiseAnd(context.BitwiseNot(x), z)), + TruthTable.AndXor => context.BitwiseExclusiveOr(x, context.BitwiseAnd(y, z)), + TruthTable.Xor3 => context.BitwiseExclusiveOr(x, context.BitwiseExclusiveOr(y, z)), + _ => null }; } - private static int PermuteByte(int imm, int bit7, int bit6, int bit5, int bit4, int bit3, int bit2, int bit1, int bit0) + private static TruthTable PermuteTable(TruthTable imm, int bit7, int bit6, int bit5, int bit4, int bit3, int bit2, int bit1, int bit0) { int result = 0; - result |= ((imm >> 0) & 1) << bit0; - result |= ((imm >> 1) & 1) << bit1; - result |= ((imm >> 2) & 1) << bit2; - result |= ((imm >> 3) & 1) << bit3; - result |= ((imm >> 4) & 1) << bit4; - result |= ((imm >> 5) & 1) << bit5; - result |= ((imm >> 6) & 1) << bit6; - result |= ((imm >> 7) & 1) << bit7; + result |= (((int)imm >> 0) & 1) << bit0; + result |= (((int)imm >> 1) & 1) << bit1; + result |= (((int)imm >> 2) & 1) << bit2; + result |= (((int)imm >> 3) & 1) << bit3; + result |= (((int)imm >> 4) & 1) << bit4; + result |= (((int)imm >> 5) & 1) << bit5; + result |= (((int)imm >> 6) & 1) << bit6; + result |= (((int)imm >> 7) & 1) << bit7; - return result; + return (TruthTable)result; } } } \ No newline at end of file