forked from eden-emu/eden
		
	Merge pull request #7989 from degasus/maxwell_LUT3
shader_recompiler/LOP3: Use brute force python results within switch/case.
This commit is contained in:
		
						commit
						35309f27ed
					
				
					 2 changed files with 620 additions and 52 deletions
				
			
		|  | @ -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) { | ||||
|  |  | |||
|  | @ -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])) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Fernando S
						Fernando S