| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | // Copyright 2018 yuzu Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "common/assert.h"
 | 
					
						
							|  |  |  | #include "common/common_types.h"
 | 
					
						
							|  |  |  | #include "video_core/engines/shader_bytecode.h"
 | 
					
						
							|  |  |  | #include "video_core/shader/shader_ir.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace VideoCommon::Shader { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | using Tegra::Shader::Instruction; | 
					
						
							|  |  |  | using Tegra::Shader::OpCode; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-30 02:09:40 -03:00
										 |  |  | u32 ShaderIR::DecodeBfe(NodeBlock& bb, u32 pc) { | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  |     const Instruction instr = {program_code[pc]}; | 
					
						
							|  |  |  |     const auto opcode = OpCode::Decode(instr); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-16 18:19:17 -03:00
										 |  |  |     UNIMPLEMENTED_IF(instr.bfe.negate_b); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Node op_a = GetRegister(instr.gpr8); | 
					
						
							|  |  |  |     op_a = GetOperandAbsNegInteger(op_a, false, instr.bfe.negate_a, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (opcode->get().GetId()) { | 
					
						
							|  |  |  |     case OpCode::Id::BFE_IMM: { | 
					
						
							|  |  |  |         UNIMPLEMENTED_IF_MSG(instr.generates_cc, | 
					
						
							|  |  |  |                              "Condition codes generation in BFE is not implemented"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const Node inner_shift_imm = Immediate(static_cast<u32>(instr.bfe.GetLeftShiftValue())); | 
					
						
							|  |  |  |         const Node outer_shift_imm = | 
					
						
							|  |  |  |             Immediate(static_cast<u32>(instr.bfe.GetLeftShiftValue() + instr.bfe.shift_position)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const Node inner_shift = | 
					
						
							|  |  |  |             Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, op_a, inner_shift_imm); | 
					
						
							|  |  |  |         const Node outer_shift = | 
					
						
							|  |  |  |             Operation(OperationCode::ILogicalShiftRight, NO_PRECISE, inner_shift, outer_shift_imm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-27 16:50:36 -03:00
										 |  |  |         SetInternalFlagsFromInteger(bb, outer_shift, instr.generates_cc); | 
					
						
							| 
									
										
										
										
											2018-12-16 18:19:17 -03:00
										 |  |  |         SetRegister(bb, instr.gpr0, outer_shift); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         UNIMPLEMENTED_MSG("Unhandled BFE instruction: {}", opcode->get().GetName()); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-20 19:09:21 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return pc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } // namespace VideoCommon::Shader
 |