GPU: Implement the ISCADD shader instructions.
This commit is contained in:
		| @@ -232,6 +232,22 @@ union Instruction { | ||||
|         } | ||||
|     } alu; | ||||
|  | ||||
|     union { | ||||
|         BitField<39, 5, u64> shift_amount; | ||||
|         BitField<20, 19, u64> immediate_low; | ||||
|         BitField<56, 1, u64> immediate_high; | ||||
|         BitField<48, 1, u64> negate_b; | ||||
|         BitField<49, 1, u64> negate_a; | ||||
|  | ||||
|         s32 GetImmediate() const { | ||||
|             u32 immediate = static_cast<u32>(immediate_low | (immediate_high << 19)); | ||||
|             // Sign extend the 20-bit value. | ||||
|             u32 mask = 1U << (20 - 1); | ||||
|             return static_cast<s32>((immediate ^ mask) - mask); | ||||
|         } | ||||
|  | ||||
|     } iscadd; | ||||
|  | ||||
|     union { | ||||
|         BitField<48, 1, u64> negate_b; | ||||
|         BitField<49, 1, u64> negate_c; | ||||
|   | ||||
| @@ -884,6 +884,30 @@ private: | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         case OpCode::Type::ScaledAdd: { | ||||
|             std::string op_a = regs.GetRegisterAsInteger(instr.gpr8); | ||||
|  | ||||
|             if (instr.iscadd.negate_a) | ||||
|                 op_a = '-' + op_a; | ||||
|  | ||||
|             std::string op_b = instr.iscadd.negate_b ? "-" : ""; | ||||
|  | ||||
|             if (instr.is_b_imm) { | ||||
|                 op_b += '(' + std::to_string(instr.iscadd.GetImmediate()) + ')'; | ||||
|             } else { | ||||
|                 if (instr.is_b_gpr) { | ||||
|                     op_b += regs.GetRegisterAsInteger(instr.gpr20); | ||||
|                 } else { | ||||
|                     op_b += regs.GetUniform(instr.uniform, instr.gpr0); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             std::string shift = std::to_string(instr.iscadd.shift_amount.Value()); | ||||
|  | ||||
|             regs.SetRegisterToInteger(instr.gpr0, true, 0, | ||||
|                                       "((" + op_a + " << " + shift + ") + " + op_b + ')', 1, 1); | ||||
|             break; | ||||
|         } | ||||
|         case OpCode::Type::Ffma: { | ||||
|             std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | ||||
|             std::string op_b = instr.ffma.negate_b ? "-" : ""; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user