GPU: Implement the ISCADD shader instructions.
This commit is contained in:
		| @@ -232,6 +232,22 @@ union Instruction { | |||||||
|         } |         } | ||||||
|     } alu; |     } 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 { |     union { | ||||||
|         BitField<48, 1, u64> negate_b; |         BitField<48, 1, u64> negate_b; | ||||||
|         BitField<49, 1, u64> negate_c; |         BitField<49, 1, u64> negate_c; | ||||||
|   | |||||||
| @@ -884,6 +884,30 @@ private: | |||||||
|             } |             } | ||||||
|             break; |             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: { |         case OpCode::Type::Ffma: { | ||||||
|             std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); |             std::string op_a = regs.GetRegisterAsFloat(instr.gpr8); | ||||||
|             std::string op_b = instr.ffma.negate_b ? "-" : ""; |             std::string op_b = instr.ffma.negate_b ? "-" : ""; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user