mirror of
https://github.com/yuzu-emu/yuzu-android.git
synced 2025-06-12 09:37:56 -05:00
shader_ir: Implement BRX & BRA.CC
This commit is contained in:
committed by
FernandoS27
parent
c218ae4b02
commit
8a6fc529a9
@ -91,11 +91,45 @@ u32 ShaderIR::DecodeOther(NodeBlock& bb, u32 pc) {
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::BRA: {
|
||||
UNIMPLEMENTED_IF_MSG(instr.bra.constant_buffer != 0,
|
||||
"BRA with constant buffers are not implemented");
|
||||
Node branch;
|
||||
if (instr.bra.constant_buffer == 0) {
|
||||
const u32 target = pc + instr.bra.GetBranchTarget();
|
||||
branch = Operation(OperationCode::Branch, Immediate(target));
|
||||
} else {
|
||||
const u32 target = pc + 1;
|
||||
const Node op_a = GetConstBuffer(instr.cbuf36.index, instr.cbuf36.GetOffset());
|
||||
const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight,
|
||||
true, PRECISE, op_a, Immediate(3));
|
||||
const Node operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
|
||||
branch = Operation(OperationCode::BranchIndirect, convert);
|
||||
}
|
||||
|
||||
const u32 target = pc + instr.bra.GetBranchTarget();
|
||||
const Node branch = Operation(OperationCode::Branch, Immediate(target));
|
||||
const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
|
||||
if (cc != Tegra::Shader::ConditionCode::T) {
|
||||
bb.push_back(Conditional(GetConditionCode(cc), {branch}));
|
||||
} else {
|
||||
bb.push_back(branch);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::Id::BRX: {
|
||||
Node operand;
|
||||
if (instr.brx.constant_buffer != 0) {
|
||||
const s32 target = pc + 1;
|
||||
const Node index = GetRegister(instr.gpr8);
|
||||
const Node op_a =
|
||||
GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 0, index);
|
||||
const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight,
|
||||
true, PRECISE, op_a, Immediate(3));
|
||||
operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
|
||||
} else {
|
||||
const s32 target = pc + instr.brx.GetBranchExtend();
|
||||
const Node op_a = GetRegister(instr.gpr8);
|
||||
const Node convert = SignedOperation(OperationCode::IArithmeticShiftRight,
|
||||
true, PRECISE, op_a, Immediate(3));
|
||||
operand = Operation(OperationCode::IAdd, PRECISE, convert, Immediate(target));
|
||||
}
|
||||
const Node branch = Operation(OperationCode::BranchIndirect, operand);
|
||||
|
||||
const Tegra::Shader::ConditionCode cc = instr.flow_condition_code;
|
||||
if (cc != Tegra::Shader::ConditionCode::T) {
|
||||
|
Reference in New Issue
Block a user