mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 11:21:04 +00:00
Added TBAA
This commit is contained in:
parent
d7367172e8
commit
8331f6b3cc
@ -5,6 +5,7 @@ set(SRCS
|
||||
Disassembler.cpp
|
||||
InstructionBlock.cpp
|
||||
MachineState.cpp
|
||||
TBAA.cpp
|
||||
|
||||
Instructions/Instruction.cpp
|
||||
Instructions/DataProcessing.cpp
|
||||
@ -15,6 +16,7 @@ set(HEADERS
|
||||
Disassembler.h
|
||||
InstructionBlock.h
|
||||
MachineState.h
|
||||
TBAA.h
|
||||
|
||||
Instructions/Types.h
|
||||
Instructions/Instruction.h
|
||||
|
@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* A register in a broad sense: R0-R15, and flags
|
||||
*/
|
||||
@ -5,9 +7,12 @@ enum class Register
|
||||
{
|
||||
R0, R1, R2, R3, R4, R5, R6, R7,
|
||||
R8, R9, R10, R11, R12, SP, LR, PC,
|
||||
N, Z, C, V
|
||||
N, Z, C, V,
|
||||
Count
|
||||
};
|
||||
|
||||
static const size_t RegisterCount = static_cast<size_t>(Register::Count);
|
||||
|
||||
enum class Condition
|
||||
{
|
||||
EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, Invalid
|
||||
|
@ -26,13 +26,15 @@ void MachineState::GenerateGlobals()
|
||||
|
||||
Value* MachineState::ReadRegiser(Register reg)
|
||||
{
|
||||
auto load = module->IrBuilder()->CreateLoad(GetRegisterPtr(reg));
|
||||
auto load = module->IrBuilder()->CreateAlignedLoad(GetRegisterPtr(reg), 4);
|
||||
module->GetTBAA()->TagRegister(load, reg);
|
||||
return load;
|
||||
}
|
||||
|
||||
Value* MachineState::WriteRegiser(Register reg, Value *value)
|
||||
{
|
||||
auto store = module->IrBuilder()->CreateAlignedStore(value, GetRegisterPtr(reg), 4);
|
||||
module->GetTBAA()->TagRegister(store, reg);
|
||||
return store;
|
||||
}
|
||||
|
||||
@ -51,5 +53,6 @@ Value *MachineState::GetRegisterPtr(Register reg)
|
||||
index = static_cast<unsigned>(reg)-static_cast<unsigned>(Register::N);
|
||||
}
|
||||
auto base = module->IrBuilder()->CreateAlignedLoad(global, 4);
|
||||
module->GetTBAA()->TagConst(base);
|
||||
return module->IrBuilder()->CreateConstInBoundsGEP1_32(base, index);
|
||||
}
|
@ -17,6 +17,7 @@ ModuleGen::ModuleGen(llvm::Module* module)
|
||||
{
|
||||
ir_builder = make_unique<IRBuilder<>>(getGlobalContext());
|
||||
machine = make_unique<MachineState>(this);
|
||||
tbaa = make_unique<TBAA>();
|
||||
}
|
||||
|
||||
ModuleGen::~ModuleGen()
|
||||
@ -25,6 +26,7 @@ ModuleGen::~ModuleGen()
|
||||
|
||||
void ModuleGen::Run()
|
||||
{
|
||||
tbaa->GenerateTags();
|
||||
GenerateGlobals();
|
||||
|
||||
DecodeInstructions();
|
||||
@ -133,6 +135,7 @@ void ModuleGen::GenerateGetBlockAddressFunction()
|
||||
ir_builder->SetInsertPoint(index_in_bounds_basic_block);
|
||||
Value *gep_values[] = { ir_builder->getInt32(0), index };
|
||||
auto block_address = ir_builder->CreateLoad(ir_builder->CreateInBoundsGEP(block_address_array, gep_values));
|
||||
tbaa->TagConst(block_address);
|
||||
ir_builder->CreateRet(block_address);
|
||||
|
||||
ir_builder->SetInsertPoint(index_out_of_bounds_basic_block);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#include <unordered_map>
|
||||
#include <common/common_types.h>
|
||||
#include "TBAA.h"
|
||||
|
||||
enum class Register;
|
||||
|
||||
@ -28,6 +29,7 @@ public:
|
||||
llvm::IRBuilder<> *IrBuilder() { return ir_builder.get(); }
|
||||
llvm::Module *Module() { return module; }
|
||||
MachineState *Machine() { return machine.get(); }
|
||||
TBAA *GetTBAA() { return tbaa.get(); }
|
||||
|
||||
private:
|
||||
// Generates the declarations of all the globals of the module
|
||||
@ -46,6 +48,7 @@ private:
|
||||
void AddInstructionsToRunFunction();
|
||||
|
||||
std::unique_ptr<MachineState> machine;
|
||||
std::unique_ptr<TBAA> tbaa;
|
||||
|
||||
std::unique_ptr<llvm::IRBuilder<>> ir_builder;
|
||||
llvm::Module *module;
|
||||
|
33
src/binary_translation/TBAA.cpp
Normal file
33
src/binary_translation/TBAA.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "TBAA.h"
|
||||
#include <llvm/IR/MDBuilder.h>
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
#include <llvm/IR/Metadata.h>
|
||||
#include <sstream>
|
||||
#include <llvm/IR/Instruction.h>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void TBAA::GenerateTags()
|
||||
{
|
||||
MDBuilder md_builder(getGlobalContext());
|
||||
|
||||
auto tbaa_root = md_builder.createTBAARoot("Root");
|
||||
|
||||
for (auto i = 0; i < RegisterCount; ++i)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Register_" << i;
|
||||
register_nodes[i] = md_builder.createTBAAScalarTypeNode(ss.str(), tbaa_root);
|
||||
}
|
||||
const_node = md_builder.createTBAAScalarTypeNode("Readonly", tbaa_root);
|
||||
}
|
||||
|
||||
void TBAA::TagRegister(Instruction* instruction, Register reg)
|
||||
{
|
||||
instruction->setMetadata(LLVMContext::MD_tbaa, register_nodes[(int)reg]);
|
||||
}
|
||||
|
||||
void TBAA::TagConst(Instruction* instruction)
|
||||
{
|
||||
instruction->setMetadata(LLVMContext::MD_tbaa, const_node);
|
||||
}
|
28
src/binary_translation/TBAA.h
Normal file
28
src/binary_translation/TBAA.h
Normal file
@ -0,0 +1,28 @@
|
||||
#include "Instructions/Types.h"
|
||||
|
||||
namespace llvm
|
||||
{
|
||||
class Instruction;
|
||||
class MDNode;
|
||||
}
|
||||
|
||||
/*
|
||||
Manages TBAA.
|
||||
A TBAA type is generated for each register and global.
|
||||
It is a bit of an abuse of TBAA but because nothing aliases it is a good way
|
||||
to notify LLVM of it.
|
||||
*/
|
||||
|
||||
class TBAA
|
||||
{
|
||||
public:
|
||||
void GenerateTags();
|
||||
|
||||
void TagRegister(llvm::Instruction *instruction, Register reg);
|
||||
void TagConst(llvm::Instruction *instruction);
|
||||
private:
|
||||
llvm::MDNode *register_nodes[RegisterCount];
|
||||
// Tag for everything that is never written.
|
||||
// Since it is never written, one tag works
|
||||
llvm::MDNode *const_node;
|
||||
};
|
Loading…
Reference in New Issue
Block a user