1 #ifndef RSP_HPP__ 2 #define RSP_HPP__ 3 4 #include <memory> 5 #include <stdint.h> 6 #include <string.h> 7 #include <string> 8 #include <unordered_map> 9 10 #include "debug_jit.hpp" 11 #include "llvm_jit.hpp" 12 #include "rsp_op.hpp" 13 #include "state.hpp" 14 15 namespace RSP 16 { 17 #ifdef DEBUG_JIT 18 using Block = JIT::DebugBlock; 19 #else 20 using Block = JIT::Block; 21 #endif 22 using Func = JIT::Func; 23 24 25 class alignas(64) CPU 26 { 27 public: 28 CPU(); 29 ~CPU(); 30 31 CPU(CPU &&) = delete; 32 void operator=(CPU &&) = delete; 33 set_dmem(uint32_t * dmem)34 void set_dmem(uint32_t *dmem) 35 { 36 state.dmem = dmem; 37 } 38 set_imem(uint32_t * imem)39 void set_imem(uint32_t *imem) 40 { 41 state.imem = imem; 42 } 43 set_rdram(uint32_t * rdram)44 void set_rdram(uint32_t *rdram) 45 { 46 state.rdram = rdram; 47 } 48 49 void invalidate_imem(); 50 get_state()51 CPUState &get_state() 52 { 53 return state; 54 } 55 56 ReturnMode run(); 57 58 void enter(uint32_t pc); 59 void call(uint32_t target, uint32_t ret); 60 int ret(uint32_t pc); 61 void exit(ReturnMode mode); 62 63 void print_registers(); 64 65 private: 66 CPUState state; 67 Func blocks[IMEM_WORDS] = {}; 68 std::unordered_map<std::string, uint64_t> symbol_table; 69 #ifndef DEBUG_JIT 70 JIT::LLVMEngine jit_engine; 71 #endif 72 std::unordered_map<uint64_t, std::unique_ptr<Block>> cached_blocks[IMEM_WORDS]; 73 74 void invalidate_code(); 75 uint64_t hash_imem(unsigned pc, unsigned count) const; 76 Func jit_region(uint64_t hash, unsigned pc, unsigned count); 77 78 std::string full_code; 79 std::string body; 80 81 void init_symbol_table(); 82 83 alignas(64) uint32_t cached_imem[IMEM_WORDS] = {}; 84 85 // Platform specific. 86 #ifdef __GNUC__ 87 intptr_t env[64]; 88 // We're reading this after setjmp returns so need to make sure the read happens when we expect it to. 89 volatile ReturnMode return_mode; 90 #else 91 #error "Need __builtin_setjmp/longjmp support alternative for other compilers ..." 92 #endif 93 94 #define CALL_STACK_SIZE 32 95 uint32_t call_stack[CALL_STACK_SIZE] = {}; 96 unsigned call_stack_ptr = 0; 97 98 unsigned analyze_static_end(unsigned pc, unsigned end); 99 }; 100 } // namespace RSP 101 102 #endif 103