shader_ir: Implement BRX & BRA.CC
This commit is contained in:
		 Fernando Sahmkow
					Fernando Sahmkow
				
			
				
					committed by
					
						 FernandoS27
						FernandoS27
					
				
			
			
				
	
			
			
			 FernandoS27
						FernandoS27
					
				
			
						parent
						
							c218ae4b02
						
					
				
				
					commit
					8a6fc529a9
				
			| @@ -284,6 +284,9 @@ ParseResult ParseCode(CFGRebuildState& state, u32 address, ParseInfo& parse_info | ||||
|             state.pbk_labels.emplace(offset, target); | ||||
|             break; | ||||
|         } | ||||
|         case OpCode::Id::BRX: { | ||||
|             return ParseResult::AbnormalFlow; | ||||
|         } | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -149,6 +149,7 @@ enum class OperationCode { | ||||
|     ImageStore, /// (MetaImage, float[N] coords) -> void | ||||
|  | ||||
|     Branch,        /// (uint branch_target) -> void | ||||
|     BranchIndirect,/// (uint branch_target) -> void | ||||
|     PushFlowStack, /// (uint branch_target) -> void | ||||
|     PopFlowStack,  /// () -> void | ||||
|     Exit,          /// () -> void | ||||
|   | ||||
		Reference in New Issue
	
	Block a user