2013-01-20 17:48:39 +00:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
* 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. *
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
|
|
|
|
2013-01-21 18:58:52 +00:00
|
|
|
#ifndef XENIA_CPU_CODEGEN_FUNCTION_GENERATOR_H_
|
|
|
|
#define XENIA_CPU_CODEGEN_FUNCTION_GENERATOR_H_
|
2013-01-20 17:48:39 +00:00
|
|
|
|
2013-01-21 18:58:52 +00:00
|
|
|
#include <llvm/IR/Attributes.h>
|
|
|
|
#include <llvm/IR/DataLayout.h>
|
|
|
|
#include <llvm/IR/DerivedTypes.h>
|
|
|
|
#include <llvm/IR/IRBuilder.h>
|
|
|
|
#include <llvm/IR/LLVMContext.h>
|
|
|
|
#include <llvm/IR/Module.h>
|
2013-01-20 17:48:39 +00:00
|
|
|
|
|
|
|
#include <xenia/cpu/sdb.h>
|
2013-01-21 18:58:52 +00:00
|
|
|
#include <xenia/cpu/ppc/instr.h>
|
2013-01-20 17:48:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace xe {
|
|
|
|
namespace cpu {
|
2013-01-21 18:58:52 +00:00
|
|
|
namespace codegen {
|
2013-01-20 17:48:39 +00:00
|
|
|
|
|
|
|
|
2013-01-21 18:58:52 +00:00
|
|
|
class FunctionGenerator {
|
2013-01-20 17:48:39 +00:00
|
|
|
public:
|
2013-01-22 08:22:27 +00:00
|
|
|
FunctionGenerator(
|
|
|
|
xe_memory_ref memory, sdb::SymbolDatabase* sdb, sdb::FunctionSymbol* fn,
|
|
|
|
llvm::LLVMContext* context, llvm::Module* gen_module,
|
|
|
|
llvm::Function* gen_fn);
|
2013-01-21 18:58:52 +00:00
|
|
|
~FunctionGenerator();
|
2013-01-20 17:48:39 +00:00
|
|
|
|
2013-01-22 08:22:27 +00:00
|
|
|
sdb::SymbolDatabase* sdb();
|
2013-01-20 17:48:39 +00:00
|
|
|
sdb::FunctionSymbol* fn();
|
|
|
|
llvm::LLVMContext* context();
|
|
|
|
llvm::Module* gen_module();
|
|
|
|
llvm::Function* gen_fn();
|
2013-01-22 08:22:27 +00:00
|
|
|
sdb::FunctionBlock* fn_block();
|
2013-01-20 17:48:39 +00:00
|
|
|
|
2013-01-26 09:25:31 +00:00
|
|
|
void PushInsertPoint();
|
|
|
|
void PopInsertPoint();
|
|
|
|
|
2013-01-20 17:48:39 +00:00
|
|
|
void GenerateBasicBlocks();
|
|
|
|
llvm::BasicBlock* GetBasicBlock(uint32_t address);
|
2013-01-22 08:22:27 +00:00
|
|
|
llvm::BasicBlock* GetNextBasicBlock();
|
2013-01-25 08:32:42 +00:00
|
|
|
llvm::BasicBlock* GetReturnBasicBlock();
|
2013-01-20 17:48:39 +00:00
|
|
|
|
2013-01-22 08:22:27 +00:00
|
|
|
llvm::Function* GetFunction(sdb::FunctionSymbol* fn);
|
|
|
|
|
2013-01-25 08:32:42 +00:00
|
|
|
int GenerateIndirectionBranch(uint32_t cia, llvm::Value* target,
|
|
|
|
bool lk, bool likely_local);
|
|
|
|
|
2013-01-22 08:22:27 +00:00
|
|
|
llvm::Value* LoadStateValue(uint32_t offset, llvm::Type* type,
|
|
|
|
const char* name = "");
|
|
|
|
void StoreStateValue(uint32_t offset, llvm::Type* type, llvm::Value* value);
|
2013-01-20 17:48:39 +00:00
|
|
|
|
|
|
|
llvm::Value* cia_value();
|
|
|
|
|
2013-01-26 09:25:31 +00:00
|
|
|
llvm::Value* SetupLocal(llvm::Type* type, const char* name);
|
2013-01-25 08:32:42 +00:00
|
|
|
void FillRegisters();
|
|
|
|
void SpillRegisters();
|
2013-01-21 18:58:52 +00:00
|
|
|
|
|
|
|
llvm::Value* xer_value();
|
|
|
|
void update_xer_value(llvm::Value* value);
|
2013-01-27 05:51:31 +00:00
|
|
|
void update_xer_with_overflow(llvm::Value* value);
|
|
|
|
void update_xer_with_carry(llvm::Value* value);
|
|
|
|
void update_xer_with_overflow_and_carry(llvm::Value* value);
|
|
|
|
|
2013-01-21 18:58:52 +00:00
|
|
|
llvm::Value* lr_value();
|
|
|
|
void update_lr_value(llvm::Value* value);
|
2013-01-27 05:51:31 +00:00
|
|
|
|
2013-01-21 18:58:52 +00:00
|
|
|
llvm::Value* ctr_value();
|
|
|
|
void update_ctr_value(llvm::Value* value);
|
|
|
|
|
2013-01-26 09:25:31 +00:00
|
|
|
llvm::Value* cr_value(uint32_t n);
|
|
|
|
void update_cr_value(uint32_t n, llvm::Value* value);
|
2013-01-27 05:51:31 +00:00
|
|
|
void update_cr_with_cond(uint32_t n, llvm::Value* lhs, llvm::Value* rhs,
|
|
|
|
bool is_signed);
|
2013-01-20 17:48:39 +00:00
|
|
|
|
|
|
|
llvm::Value* gpr_value(uint32_t n);
|
|
|
|
void update_gpr_value(uint32_t n, llvm::Value* value);
|
|
|
|
|
2013-01-22 08:22:27 +00:00
|
|
|
llvm::Value* GetMembase();
|
2013-01-20 17:48:39 +00:00
|
|
|
llvm::Value* memory_addr(uint32_t addr);
|
2013-01-22 08:22:27 +00:00
|
|
|
llvm::Value* ReadMemory(llvm::Value* addr, uint32_t size, bool extend);
|
|
|
|
void WriteMemory(llvm::Value* addr, uint32_t size, llvm::Value* value);
|
2013-01-20 17:48:39 +00:00
|
|
|
|
|
|
|
private:
|
2013-01-25 08:32:42 +00:00
|
|
|
void GenerateSharedBlocks();
|
2013-01-21 09:11:57 +00:00
|
|
|
void GenerateBasicBlock(sdb::FunctionBlock* block, llvm::BasicBlock* bb);
|
|
|
|
|
2013-01-26 09:25:31 +00:00
|
|
|
void setup_xer();
|
|
|
|
void setup_lr();
|
|
|
|
void setup_ctr();
|
|
|
|
void setup_cr(uint32_t n);
|
|
|
|
void setup_gpr(uint32_t n);
|
|
|
|
|
2013-01-22 08:22:27 +00:00
|
|
|
xe_memory_ref memory_;
|
|
|
|
sdb::SymbolDatabase* sdb_;
|
|
|
|
sdb::FunctionSymbol* fn_;
|
|
|
|
llvm::LLVMContext* context_;
|
|
|
|
llvm::Module* gen_module_;
|
|
|
|
llvm::Function* gen_fn_;
|
|
|
|
sdb::FunctionBlock* fn_block_;
|
2013-01-25 08:32:42 +00:00
|
|
|
llvm::BasicBlock* return_block_;
|
|
|
|
llvm::BasicBlock* internal_indirection_block_;
|
|
|
|
llvm::BasicBlock* external_indirection_block_;
|
2013-01-22 08:22:27 +00:00
|
|
|
llvm::BasicBlock* bb_;
|
2013-01-21 18:58:52 +00:00
|
|
|
llvm::IRBuilder<>* builder_;
|
2013-01-20 17:48:39 +00:00
|
|
|
|
2013-01-26 09:25:31 +00:00
|
|
|
std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock::iterator> >
|
|
|
|
insert_points_;
|
|
|
|
|
2013-01-21 09:11:57 +00:00
|
|
|
std::map<uint32_t, llvm::BasicBlock*> bbs_;
|
|
|
|
|
2013-01-20 17:48:39 +00:00
|
|
|
// Address of the instruction being generated.
|
|
|
|
uint32_t cia_;
|
2013-01-21 18:58:52 +00:00
|
|
|
|
|
|
|
struct {
|
2013-01-25 08:32:42 +00:00
|
|
|
llvm::Value* indirection_target;
|
|
|
|
llvm::Value* indirection_cia;
|
|
|
|
|
2013-01-21 18:58:52 +00:00
|
|
|
llvm::Value* xer;
|
|
|
|
llvm::Value* lr;
|
|
|
|
llvm::Value* ctr;
|
2013-01-26 09:25:31 +00:00
|
|
|
llvm::Value* cr[8];
|
2013-01-21 18:58:52 +00:00
|
|
|
llvm::Value* gpr[32];
|
2013-01-25 08:32:42 +00:00
|
|
|
} locals_;
|
2013-01-20 17:48:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-01-21 18:58:52 +00:00
|
|
|
} // namespace codegen
|
2013-01-20 17:48:39 +00:00
|
|
|
} // namespace cpu
|
|
|
|
} // namespace xe
|
|
|
|
|
|
|
|
|
2013-01-21 18:58:52 +00:00
|
|
|
#endif // XENIA_CPU_CODEGEN_FUNCTION_GENERATOR_H_
|