@ -17,15 +17,14 @@ using Tegra::Shader::Instruction;
using Tegra : : Shader : : OpCode ;
namespace {
constexpr u64 NUM_PROGRAMMABLE_PREDICATES = 7 ;
}
constexpr u64 NUM_CONDITION_CODES = 4 ;
constexpr u64 NUM_PREDICATES = 7 ;
} // namespace
u32 ShaderIR : : DecodeRegisterSetPredicate ( NodeBlock & bb , u32 pc ) {
const Instruction instr = { program_code [ pc ] } ;
const auto opcode = OpCode : : Decode ( instr ) ;
UNIMPLEMENTED_IF ( instr . p2r_r2p . mode ! = Tegra : : Shader : : R2pMode : : Pr ) ;
Node apply_mask = [ this , opcode , instr ] {
switch ( opcode - > get ( ) . GetId ( ) ) {
case OpCode : : Id : : R2P_IMM :
@ -39,12 +38,18 @@ u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) {
const u32 offset = static_cast < u32 > ( instr . p2r_r2p . byte ) * 8 ;
const bool cc = instr . p2r_r2p . mode = = Tegra : : Shader : : R2pMode : : Cc ;
const u64 num_entries = cc ? NUM_CONDITION_CODES : NUM_PREDICATES ;
const auto get_entry = [ this , cc ] ( u64 entry ) {
return cc ? GetInternalFlag ( static_cast < InternalFlag > ( entry ) ) : GetPredicate ( entry ) ;
} ;
switch ( opcode - > get ( ) . GetId ( ) ) {
case OpCode : : Id : : R2P_IMM : {
Node mask = GetRegister ( instr . gpr8 ) ;
for ( u64 pred = 0 ; pred < NUM_PROGRAMMABLE_PREDICATES ; + + pred ) {
const u32 shift = static_cast < u32 > ( pred ) ;
for ( u64 entry = 0 ; entry < num_entries ; + + entry ) {
const u32 shift = static_cast < u32 > ( entry ) ;
Node apply = BitfieldExtract ( apply_mask , shift , 1 ) ;
Node condition = Operation ( OperationCode : : LogicalUNotEqual , apply , Immediate ( 0 ) ) ;
@ -52,15 +57,15 @@ u32 ShaderIR::DecodeRegisterSetPredicate(NodeBlock& bb, u32 pc) {
Node compare = BitfieldExtract ( mask , offset + shift , 1 ) ;
Node value = Operation ( OperationCode : : LogicalUNotEqual , move ( compare ) , Immediate ( 0 ) ) ;
Node code = Operation ( OperationCode : : LogicalAssign , GetPredicate( pred ) , move ( value ) ) ;
Node code = Operation ( OperationCode : : LogicalAssign , get_entry( entry ) , move ( value ) ) ;
bb . push_back ( Conditional ( condition , { move ( code ) } ) ) ;
}
break ;
}
case OpCode : : Id : : P2R_IMM : {
Node value = Immediate ( 0 ) ;
for ( u64 pred = 0 ; pred < NUM_PROGRAMMABLE_PREDICATES ; + + pred ) {
Node bit = Operation ( OperationCode : : Select , GetPredicate( pred ) , Immediate ( 1U < < pred ) ,
for ( u64 entry = 0 ; entry < num_entries ; + + entry ) {
Node bit = Operation ( OperationCode : : Select , get_entry( entry ) , Immediate ( 1U < < entry ) ,
Immediate ( 0 ) ) ;
value = Operation ( OperationCode : : UBitwiseOr , move ( value ) , move ( bit ) ) ;
}