summaryrefslogblamecommitdiffstats
path: root/src/shader_recompiler/frontend/maxwell/translate/translate.cpp
blob: 6d684482698dc6f3d6b0d92297e6c1d0e4128e09 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12

                                                               









                                                                   
                      
                                                                       
                                        
                                                                                               
                                    
                                                                                            
                                
            
                            


     

                                                                                          


                                           
                                                                  
                                                         


                                              





                                                                                                    





                                                                           
         
     


                              
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#include "shader_recompiler/environment.h"
#include "shader_recompiler/frontend/ir/basic_block.h"
#include "shader_recompiler/frontend/maxwell/decode.h"
#include "shader_recompiler/frontend/maxwell/location.h"
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
#include "shader_recompiler/frontend/maxwell/translate/translate.h"

namespace Shader::Maxwell {

template <auto method>
static void Invoke(TranslatorVisitor& visitor, Location pc, u64 insn) {
    using MethodType = decltype(method);
    if constexpr (std::is_invocable_r_v<void, MethodType, TranslatorVisitor&, Location, u64>) {
        (visitor.*method)(pc, insn);
    } else if constexpr (std::is_invocable_r_v<void, MethodType, TranslatorVisitor&, u64>) {
        (visitor.*method)(insn);
    } else {
        (visitor.*method)();
    }
}

void Translate(Environment& env, IR::Block* block, u32 location_begin, u32 location_end) {
    if (location_begin == location_end) {
        return;
    }
    TranslatorVisitor visitor{env, *block};
    for (Location pc = location_begin; pc != location_end; ++pc) {
        const u64 insn{env.ReadInstruction(pc.Offset())};
        try {
            const Opcode opcode{Decode(insn)};
            switch (opcode) {
#define INST(name, cute, mask)                                                                     \
    case Opcode::name:                                                                             \
        Invoke<&TranslatorVisitor::name>(visitor, pc, insn);                                       \
        break;
#include "shader_recompiler/frontend/maxwell/maxwell.inc"
#undef OPCODE
            default:
                throw LogicError("Invalid opcode {}", opcode);
            }
        } catch (Exception& exception) {
            exception.Prepend(fmt::format("Translate {}: ", Decode(insn)));
            throw;
        }
    }
}

} // namespace Shader::Maxwell