/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2013 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #ifndef XENIA_CPU_X64_X64_EMITTER_H_ #define XENIA_CPU_X64_X64_EMITTER_H_ #include #include #include #include namespace xe { namespace cpu { namespace x64 { // Typedef for all generated functions. typedef void (*x64_function_t)(xe_ppc_state_t* ppc_state, uint64_t lr); class X64Emitter { public: X64Emitter(xe_memory_ref memory); ~X64Emitter(); void Lock(); void Unlock(); int PrepareFunction(sdb::FunctionSymbol* symbol); int MakeFunction(sdb::FunctionSymbol* symbol); AsmJit::X86Compiler& compiler(); sdb::FunctionSymbol* symbol(); sdb::FunctionBlock* fn_block(); // int branch_to_block(uint32_t address); // int branch_to_block_if(uint32_t address, jit_value_t value); // int branch_to_block_if_not(uint32_t address, jit_value_t value); // int branch_to_return(); // int branch_to_return_if(jit_value_t value); // int branch_to_return_if_not(jit_value_t value); // int call_function(sdb::FunctionSymbol* target_symbol, jit_value_t lr, // bool tail); void TraceKernelCall(); void TraceUserCall(); void TraceInstruction(ppc::InstrData& i); void TraceInvalidInstruction(ppc::InstrData& i); void TraceBranch(uint32_t cia); // int GenerateIndirectionBranch(uint32_t cia, jit_value_t target, // bool lk, bool likely_local); void FillRegisters(); void SpillRegisters(); AsmJit::GpVar& xer_value(); void update_xer_value(AsmJit::GpVar& value); void update_xer_with_overflow(AsmJit::GpVar& value); void update_xer_with_carry(AsmJit::GpVar& value); void update_xer_with_overflow_and_carry(AsmJit::GpVar& value); AsmJit::GpVar& lr_value(); void update_lr_value(AsmJit::GpVar& value); AsmJit::GpVar& ctr_value(); void update_ctr_value(AsmJit::GpVar& value); AsmJit::GpVar& cr_value(uint32_t n); void update_cr_value(uint32_t n, AsmJit::GpVar& value); void update_cr_with_cond(uint32_t n, AsmJit::GpVar& lhs, AsmJit::GpVar& rhs, bool is_signed); AsmJit::GpVar& gpr_value(uint32_t n); void update_gpr_value(uint32_t n, AsmJit::GpVar& value); AsmJit::GpVar& fpr_value(uint32_t n); void update_fpr_value(uint32_t n, AsmJit::GpVar& value); AsmJit::GpVar& TouchMemoryAddress(uint32_t cia, AsmJit::GpVar& addr); AsmJit::GpVar& ReadMemory( uint32_t cia, AsmJit::GpVar& addr, uint32_t size, bool acquire = false); void WriteMemory( uint32_t cia, AsmJit::GpVar& addr, uint32_t size, AsmJit::GpVar& value, bool release = false); // jit_value_t get_int32(int32_t value); // jit_value_t get_uint32(uint32_t value); // jit_value_t get_int64(int64_t value); // jit_value_t get_uint64(uint64_t value); AsmJit::GpVar sign_extend(AsmJit::GpVar& value, int size); AsmJit::GpVar zero_extend(AsmJit::GpVar& value, int size); AsmJit::GpVar trunc(AsmJit::GpVar& value, int size); private: static void* OnDemandCompileTrampoline( X64Emitter* emitter, sdb::FunctionSymbol* symbol); void* OnDemandCompile(sdb::FunctionSymbol* symbol); int MakeUserFunction(); int MakePresentImportFunction(); int MakeMissingImportFunction(); void GenerateSharedBlocks(); int PrepareBasicBlock(sdb::FunctionBlock* block); void GenerateBasicBlock(sdb::FunctionBlock* block); void SetupLocals(); xe_memory_ref memory_; GlobalExports global_exports_; xe_mutex_t* lock_; AsmJit::Logger* logger_; AsmJit::X86Assembler assembler_; AsmJit::X86Compiler compiler_; sdb::FunctionSymbol* symbol_; sdb::FunctionBlock* fn_block_; AsmJit::Label return_block_; // jit_label_t internal_indirection_block_; // jit_label_t external_indirection_block_; std::map bbs_; ppc::InstrAccessBits access_bits_; struct { AsmJit::GpVar indirection_target; AsmJit::GpVar indirection_cia; AsmJit::GpVar xer; AsmJit::GpVar lr; AsmJit::GpVar ctr; AsmJit::GpVar cr[8]; AsmJit::GpVar gpr[32]; AsmJit::GpVar fpr[32]; } locals_; }; } // namespace x64 } // namespace cpu } // namespace xe #endif // XENIA_CPU_X64_X64_EMITTER_H_