[GPU] Store ALU result after both vector and scalar instructions

This commit is contained in:
Triang3l
2019-04-20 20:25:27 +03:00
parent cd1aadef74
commit 66a9c9d812
10 changed files with 421 additions and 403 deletions

View File

@@ -459,51 +459,62 @@ struct ParsedAluInstruction {
// Index into the ucode dword source.
uint32_t dword_index = 0;
enum class Type {
kNop,
kVector,
kScalar,
};
// Type of the instruction.
Type type = Type::kNop;
bool is_nop() const { return type == Type::kNop; }
bool is_vector_type() const { return type == Type::kVector; }
bool is_scalar_type() const { return type == Type::kScalar; }
// Opcode for the instruction if it is a vector type.
ucode::AluVectorOpcode vector_opcode = ucode::AluVectorOpcode::kAdd;
// Opcode for the instruction if it is a scalar type.
ucode::AluScalarOpcode scalar_opcode = ucode::AluScalarOpcode::kAdds;
// Friendly name of the instruction.
const char* opcode_name = nullptr;
// True if the vector part of the instruction needs to be executed and data
// about it in this structure is valid.
bool has_vector_op = false;
// True if the scalar part of the instruction needs to be executed and data
// about it in this structure is valid.
bool has_scalar_op = false;
bool is_nop() const { return !has_vector_op && !has_scalar_op; }
// Opcode for the vector part of the instruction.
ucode::AluVectorOpcode vector_opcode = ucode::AluVectorOpcode::kAdd;
// Opcode for the scalar part of the instruction.
ucode::AluScalarOpcode scalar_opcode = ucode::AluScalarOpcode::kAdds;
// Friendly name of the vector instruction.
const char* vector_opcode_name = nullptr;
// Friendly name of the scalar instruction.
const char* scalar_opcode_name = nullptr;
// True if the instruction is paired with another instruction.
bool is_paired = false;
// True if the instruction is predicated on the specified
// predicate_condition.
bool is_predicated = false;
// Expected predication condition value if predicated.
bool predicate_condition = false;
// Describes how the instruction result is stored.
InstructionResult result;
// Describes how the vector operation result is stored.
InstructionResult vector_result;
// Describes how the scalar operation result is stored.
InstructionResult scalar_result;
// Both operations must be executed before any result is stored if vector and
// scalar operations are paired. There are cases of vector result being used
// as scalar operand or vice versa (the halo on Avalanche in Halo 3, for
// example), in this case there must be no dependency between the two
// operations.
// Number of source operands.
size_t operand_count = 0;
// Describes each source operand.
InstructionOperand operands[3];
// Number of source operands of the vector operation.
size_t vector_operand_count = 0;
// Describes each source operand of the vector operation.
InstructionOperand vector_operands[3];
// Number of source operands of the scalar operation.
size_t scalar_operand_count = 0;
// Describes each source operand of the scalar operation.
InstructionOperand scalar_operands[2];
// If this is a valid eA write (MAD with a stream constant), returns the index
// of the stream float constant, otherwise returns UINT32_MAX.
uint32_t GetMemExportStreamConstant() const {
if (result.storage_target == InstructionStorageTarget::kExportAddress &&
is_vector_type() && vector_opcode == ucode::AluVectorOpcode::kMad &&
result.has_all_writes() &&
operands[2].storage_source ==
if (has_vector_op &&
vector_result.storage_target ==
InstructionStorageTarget::kExportAddress &&
vector_opcode == ucode::AluVectorOpcode::kMad &&
vector_result.has_all_writes() &&
vector_operands[2].storage_source ==
InstructionStorageSource::kConstantFloat &&
operands[2].storage_addressing_mode ==
vector_operands[2].storage_addressing_mode ==
InstructionStorageAddressingMode::kStatic &&
operands[2].is_standard_swizzle()) {
return operands[2].storage_index;
vector_operands[2].is_standard_swizzle()) {
return vector_operands[2].storage_index;
}
return UINT32_MAX;
}