Tab to space

This commit is contained in:
Dani Messerman 2015-05-08 23:49:21 +03:00
parent af8817314a
commit 03527aba71
15 changed files with 265 additions and 265 deletions

View File

@ -27,7 +27,7 @@ ARMFuncs::ResultCarry ARMFuncs::Shift_C(InstructionBlock* instruction, llvm::Val
{ {
auto ir_builder = instruction->IrBuilder(); auto ir_builder = instruction->IrBuilder();
auto amount_zero = ir_builder->CreateICmpEQ(amount, ir_builder->getInt32(0)); auto amount_zero = ir_builder->CreateICmpEQ(amount, ir_builder->getInt32(0));
ResultCarry result_amount_not_zero = {}; ResultCarry result_amount_not_zero = {};
switch (type) switch (type)
{ {
@ -39,8 +39,8 @@ ARMFuncs::ResultCarry ARMFuncs::Shift_C(InstructionBlock* instruction, llvm::Val
default: assert(false, "Invalid shift type"); default: assert(false, "Invalid shift type");
} }
auto result = ir_builder->CreateSelect(amount_zero, value, result_amount_not_zero.result); auto result = ir_builder->CreateSelect(amount_zero, value, result_amount_not_zero.result);
auto carry = ir_builder->CreateSelect(amount_zero, carry_in, result_amount_not_zero.carry); auto carry = ir_builder->CreateSelect(amount_zero, carry_in, result_amount_not_zero.carry);
return{ result, carry }; return{ result, carry };
} }
@ -52,10 +52,10 @@ llvm::Value* ShiftZeroCheck(
{ {
auto ir_builder = instruction->IrBuilder(); auto ir_builder = instruction->IrBuilder();
auto amount_zero = ir_builder->CreateICmpEQ(shift, ir_builder->getInt32(0)); auto amount_zero = ir_builder->CreateICmpEQ(shift, ir_builder->getInt32(0));
auto result_amount_not_zero = non_zero_function(instruction, x, shift); auto result_amount_not_zero = non_zero_function(instruction, x, shift);
return ir_builder->CreateSelect(amount_zero, x, result_amount_not_zero.result); return ir_builder->CreateSelect(amount_zero, x, result_amount_not_zero.result);
} }
ARMFuncs::ResultCarry ARMFuncs::LSL_C(InstructionBlock* instruction, llvm::Value* x, llvm::Value* shift) ARMFuncs::ResultCarry ARMFuncs::LSL_C(InstructionBlock* instruction, llvm::Value* x, llvm::Value* shift)
@ -128,11 +128,11 @@ llvm::Value* ARMFuncs::ARMExpandImm(InstructionBlock* instruction, u32 imm12)
ARMFuncs::ResultCarry ARMFuncs::ARMExpandImm_C(InstructionBlock *instruction, u32 imm12, llvm::Value* carry) ARMFuncs::ResultCarry ARMFuncs::ARMExpandImm_C(InstructionBlock *instruction, u32 imm12, llvm::Value* carry)
{ {
auto ir_builder = instruction->IrBuilder(); auto ir_builder = instruction->IrBuilder();
auto value = ir_builder->getInt32(imm12 & 0xFF); auto value = ir_builder->getInt32(imm12 & 0xFF);
auto shift = ir_builder->getInt32(2 * (imm12 >> 8)); auto shift = ir_builder->getInt32(2 * (imm12 >> 8));
return Shift_C(instruction, value, SRType::ROR, shift, carry); return Shift_C(instruction, value, SRType::ROR, shift, carry);
} }
// AddWithCarry from armsupp.cpp // AddWithCarry from armsupp.cpp

View File

@ -45,7 +45,7 @@ public:
static ResultCarry RRX_C(InstructionBlock *instruction, llvm::Value *x, llvm::Value *carry_in); static ResultCarry RRX_C(InstructionBlock *instruction, llvm::Value *x, llvm::Value *carry_in);
static llvm::Value *ARMExpandImm(InstructionBlock *instruction, u32 imm12); static llvm::Value *ARMExpandImm(InstructionBlock *instruction, u32 imm12);
static ResultCarry ARMExpandImm_C(InstructionBlock *instruction, u32 imm12, llvm::Value *carry); static ResultCarry ARMExpandImm_C(InstructionBlock *instruction, u32 imm12, llvm::Value *carry);
static ResultCarryOverflow AddWithCarry(InstructionBlock *instruction, llvm::Value *x, llvm::Value *y, llvm::Value *carry_in); static ResultCarryOverflow AddWithCarry(InstructionBlock *instruction, llvm::Value *x, llvm::Value *y, llvm::Value *carry_in);
}; };

View File

@ -8,8 +8,8 @@ using namespace llvm;
BlockColors::BlockColors(ModuleGen* module) : module(module) BlockColors::BlockColors(ModuleGen* module) : module(module)
{ {
auto ir_builder = module->IrBuilder(); auto ir_builder = module->IrBuilder();
function_type = FunctionType::get(ir_builder->getVoidTy(), ir_builder->getInt32Ty(), false); function_type = FunctionType::get(ir_builder->getVoidTy(), ir_builder->getInt32Ty(), false);
} }
BlockColors::~BlockColors() BlockColors::~BlockColors()
@ -18,69 +18,69 @@ BlockColors::~BlockColors()
void BlockColors::AddBlock(InstructionBlock* block) void BlockColors::AddBlock(InstructionBlock* block)
{ {
if (block->HasColor()) return; if (block->HasColor()) return;
std::stack<InstructionBlock *> current_color_stack; std::stack<InstructionBlock *> current_color_stack;
current_color_stack.push(block); current_color_stack.push(block);
auto color = colors.size(); auto color = colors.size();
colors.push_back({ color }); colors.push_back({ color });
while (current_color_stack.size()) while (current_color_stack.size())
{ {
auto item = current_color_stack.top(); auto item = current_color_stack.top();
current_color_stack.pop(); current_color_stack.pop();
item->SetColor(color); item->SetColor(color);
colors[color].instructions.push_back(item); colors[color].instructions.push_back(item);
for (auto next : item->GetNexts()) for (auto next : item->GetNexts())
{ {
if (next->HasColor()) assert(next->GetColor() == color); if (next->HasColor()) assert(next->GetColor() == color);
else current_color_stack.push(next); else current_color_stack.push(next);
} }
for (auto prev : item->GetPrevs()) for (auto prev : item->GetPrevs())
{ {
if (prev->HasColor()) assert(prev->GetColor() == color); if (prev->HasColor()) assert(prev->GetColor() == color);
else current_color_stack.push(prev); else current_color_stack.push(prev);
} }
} }
} }
void BlockColors::GenerateFunctions() void BlockColors::GenerateFunctions()
{ {
auto ir_builder = module->IrBuilder(); auto ir_builder = module->IrBuilder();
LOG_INFO(BinaryTranslator, "%x block colors", colors.size()); LOG_INFO(BinaryTranslator, "%x block colors", colors.size());
for (auto &color : colors) for (auto &color : colors)
{ {
auto function = Function::Create(function_type, GlobalValue::PrivateLinkage, auto function = Function::Create(function_type, GlobalValue::PrivateLinkage,
"ColorFunction", module->Module()); "ColorFunction", module->Module());
color.function = function; color.function = function;
auto index = &function->getArgumentList().front(); auto index = &function->getArgumentList().front();
auto entry_basic_block = BasicBlock::Create(getGlobalContext(), "Entry", function); auto entry_basic_block = BasicBlock::Create(getGlobalContext(), "Entry", function);
auto default_case_basic_block = BasicBlock::Create(getGlobalContext(), "Default", function); auto default_case_basic_block = BasicBlock::Create(getGlobalContext(), "Default", function);
ir_builder->SetInsertPoint(default_case_basic_block); ir_builder->SetInsertPoint(default_case_basic_block);
ir_builder->CreateUnreachable(); ir_builder->CreateUnreachable();
ir_builder->SetInsertPoint(entry_basic_block); ir_builder->SetInsertPoint(entry_basic_block);
auto switch_instruction = ir_builder->CreateSwitch(index, default_case_basic_block, color.instructions.size()); auto switch_instruction = ir_builder->CreateSwitch(index, default_case_basic_block, color.instructions.size());
for (size_t i = 0; i < color.instructions.size(); ++i) for (size_t i = 0; i < color.instructions.size(); ++i)
{ {
switch_instruction->addCase(ir_builder->getInt32(i), color.instructions[i]->GetEntryBasicBlock()); switch_instruction->addCase(ir_builder->getInt32(i), color.instructions[i]->GetEntryBasicBlock());
AddBasicBlocksToFunction(function, color.instructions[i]->GetEntryBasicBlock()); AddBasicBlocksToFunction(function, color.instructions[i]->GetEntryBasicBlock());
} }
} }
} }
void BlockColors::AddBasicBlocksToFunction(Function* function, BasicBlock* basic_block) void BlockColors::AddBasicBlocksToFunction(Function* function, BasicBlock* basic_block)
{ {
if (basic_block->getParent()) if (basic_block->getParent())
{ {
assert(basic_block->getParent() == function); assert(basic_block->getParent() == function);
return; return;
} }
std::stack<BasicBlock *> basic_blocks; std::stack<BasicBlock *> basic_blocks;
basic_blocks.push(basic_block); basic_blocks.push(basic_block);

View File

@ -2,9 +2,9 @@
namespace llvm namespace llvm
{ {
class BasicBlock; class BasicBlock;
class Function; class Function;
class FunctionType; class FunctionType;
} }
class InstructionBlock; class InstructionBlock;
class ModuleGen; class ModuleGen;
@ -19,32 +19,32 @@ And to generate a function for each color
class BlockColors class BlockColors
{ {
public: public:
BlockColors(ModuleGen *module); BlockColors(ModuleGen *module);
~BlockColors(); ~BlockColors();
void AddBlock(InstructionBlock *block); void AddBlock(InstructionBlock *block);
// Generates a function for each color // Generates a function for each color
void GenerateFunctions(); void GenerateFunctions();
llvm::FunctionType *GetFunctionType() { return function_type; } llvm::FunctionType *GetFunctionType() { return function_type; }
size_t GetColorCount() const { return colors.size(); } size_t GetColorCount() const { return colors.size(); }
size_t GetColorInstructionCount(size_t color) const { return colors[color].instructions.size(); } size_t GetColorInstructionCount(size_t color) const { return colors[color].instructions.size(); }
InstructionBlock *GetColorInstruction(size_t color, size_t index) { return colors[color].instructions[index]; } InstructionBlock *GetColorInstruction(size_t color, size_t index) { return colors[color].instructions[index]; }
llvm::Function *GetColorFunction(size_t color) { return colors[color].function; } llvm::Function *GetColorFunction(size_t color) { return colors[color].function; }
private: private:
ModuleGen *module; ModuleGen *module;
// void ColorFunction(int i) // void ColorFunction(int i)
// Runs the code for color->instructions[i] // Runs the code for color->instructions[i]
llvm::FunctionType *function_type; llvm::FunctionType *function_type;
void AddBasicBlocksToFunction(llvm::Function *function, llvm::BasicBlock *basic_block); void AddBasicBlocksToFunction(llvm::Function *function, llvm::BasicBlock *basic_block);
struct Color struct Color
{ {
size_t color; size_t color;
std::vector<InstructionBlock *> instructions; std::vector<InstructionBlock *> instructions;
llvm::Function *function; llvm::Function *function;
}; };
std::vector<Color> colors; std::vector<Color> colors;
}; };

View File

@ -1,41 +1,41 @@
set(SRCS set(SRCS
main.cpp main.cpp
CodeGen.cpp CodeGen.cpp
ModuleGen.cpp ModuleGen.cpp
Disassembler.cpp Disassembler.cpp
InstructionBlock.cpp InstructionBlock.cpp
MachineState.cpp MachineState.cpp
TBAA.cpp TBAA.cpp
ARMFuncs.cpp ARMFuncs.cpp
BlockColors.cpp BlockColors.cpp
Instructions/Instruction.cpp Instructions/Instruction.cpp
Instructions/MovShift.cpp Instructions/MovShift.cpp
Instructions/Branch.cpp Instructions/Branch.cpp
Instructions/Arithmetic.cpp Instructions/Arithmetic.cpp
Instructions/Ldr.cpp Instructions/Ldr.cpp
Instructions/Str.cpp Instructions/Str.cpp
) )
set(HEADERS set(HEADERS
CodeGen.h CodeGen.h
ModuleGen.h ModuleGen.h
Disassembler.h Disassembler.h
InstructionBlock.h InstructionBlock.h
MachineState.h MachineState.h
TBAA.h TBAA.h
BinarySearch.h BinarySearch.h
ARMFuncs.h ARMFuncs.h
BlockColors.h BlockColors.h
Instructions/Types.h Instructions/Types.h
Instructions/Instruction.h Instructions/Instruction.h
Instructions/MovShift.h Instructions/MovShift.h
Instructions/Branch.h Instructions/Branch.h
Instructions/Arithmetic.h Instructions/Arithmetic.h
Instructions/Ldr.h Instructions/Ldr.h
Instructions/Str.h Instructions/Str.h
) )
create_directory_groups(${SRCS} ${HEADERS}) create_directory_groups(${SRCS} ${HEADERS})
include_directories(.) include_directories(.)

View File

@ -19,8 +19,8 @@
using namespace llvm; using namespace llvm;
CodeGen::CodeGen(const char* output_object_filename, const char* output_debug_filename, bool verify) CodeGen::CodeGen(const char* output_object_filename, const char* output_debug_filename, bool verify)
: output_object_filename(output_object_filename), : output_object_filename(output_object_filename),
output_debug_filename(output_debug_filename), output_debug_filename(output_debug_filename),
verify(verify) verify(verify)
{ {
} }
@ -31,11 +31,11 @@ CodeGen::~CodeGen()
void CodeGen::Run() void CodeGen::Run()
{ {
if (!Loader::ROMCodeStart) if (!Loader::ROMCodeStart)
{ {
LOG_CRITICAL(BinaryTranslator, "No information from the loader about ROM file."); LOG_CRITICAL(BinaryTranslator, "No information from the loader about ROM file.");
return; return;
} }
InitializeLLVM(); InitializeLLVM();
GenerateModule(); GenerateModule();

View File

@ -15,8 +15,8 @@ class ModuleGen;
class CodeGen class CodeGen
{ {
public: public:
CodeGen(const char *output_object_filename, const char *output_debug_filename, bool verify); CodeGen(const char *output_object_filename, const char *output_debug_filename, bool verify);
~CodeGen(); ~CodeGen();
void Run(); void Run();
void InitializeLLVM(); void InitializeLLVM();
@ -25,8 +25,8 @@ public:
bool Verify(); bool Verify();
void OptimizeAndGenerate(); void OptimizeAndGenerate();
private: private:
const char *output_object_filename; const char *output_object_filename;
const char *output_debug_filename; const char *output_debug_filename;
bool verify; bool verify;
std::unique_ptr<ModuleGen> moduleGenerator; std::unique_ptr<ModuleGen> moduleGenerator;

View File

@ -50,8 +50,8 @@ llvm::BasicBlock *InstructionBlock::CreateBasicBlock(const char *name)
void InstructionBlock::Link(InstructionBlock* prev, InstructionBlock* next) void InstructionBlock::Link(InstructionBlock* prev, InstructionBlock* next)
{ {
prev->nexts.push_back(next); prev->nexts.push_back(next);
next->prevs.push_back(prev); next->prevs.push_back(prev);
} }
u32 InstructionBlock::Address() const u32 InstructionBlock::Address() const

View File

@ -50,9 +50,9 @@ public:
*/ */
llvm::BasicBlock *CreateBasicBlock(const char *name); llvm::BasicBlock *CreateBasicBlock(const char *name);
/* /*
* Links two instructions, adding to prev and next lists * Links two instructions, adding to prev and next lists
*/ */
static void Link(InstructionBlock *prev, InstructionBlock *next); static void Link(InstructionBlock *prev, InstructionBlock *next);
u32 Address() const; u32 Address() const;
ModuleGen *Module() { return module; } ModuleGen *Module() { return module; }
@ -60,11 +60,11 @@ public:
llvm::BasicBlock *GetEntryBasicBlock() { return entry_basic_block; } llvm::BasicBlock *GetEntryBasicBlock() { return entry_basic_block; }
bool HasColor() const { return has_color; } bool HasColor() const { return has_color; }
void SetColor(size_t color) { this->color = color; has_color = true; } void SetColor(size_t color) { this->color = color; has_color = true; }
size_t GetColor() const { return color; } size_t GetColor() const { return color; }
std::list<InstructionBlock *> GetNexts() const { return nexts; } std::list<InstructionBlock *> GetNexts() const { return nexts; }
std::list<InstructionBlock *> GetPrevs() const { return prevs; } std::list<InstructionBlock *> GetPrevs() const { return prevs; }
private: private:
// Textual representation of the address // Textual representation of the address
@ -77,9 +77,9 @@ private:
// The block at the entry to instruction // The block at the entry to instruction
llvm::BasicBlock *entry_basic_block; llvm::BasicBlock *entry_basic_block;
bool has_color = false; bool has_color = false;
size_t color; size_t color;
std::list<InstructionBlock *> nexts; std::list<InstructionBlock *> nexts;
std::list<InstructionBlock *> prevs; std::list<InstructionBlock *> prevs;
}; };

View File

@ -56,7 +56,7 @@ void Instruction::GenerateCode(InstructionBlock *instruction_block)
// If not, jump to the next instruction // If not, jump to the next instruction
if (!ir_builder->GetInsertBlock()->getTerminator()) if (!ir_builder->GetInsertBlock()->getTerminator())
{ {
instruction_block->Module()->BranchWritePCConst(instruction_block, Address() + 4); instruction_block->Module()->BranchWritePCConst(instruction_block, Address() + 4);
} }
} }

View File

@ -17,20 +17,20 @@ bool MovShift::Decode()
if (rd == Register::PC && s) return false; // SEE SUBS PC, LR and related instructions; if (rd == Register::PC && s) return false; // SEE SUBS PC, LR and related instructions;
return true; return true;
} }
if (ReadFields({ CondDef(), FieldDef<7>(0x1d), FieldDef<1>(&s), FieldDef<4>(0), if (ReadFields({ CondDef(), FieldDef<7>(0x1d), FieldDef<1>(&s), FieldDef<4>(0),
FieldDef<4>(&rd), FieldDef<12>(&imm12) })) FieldDef<4>(&rd), FieldDef<12>(&imm12) }))
{ {
form = Form::ImmediateA1; form = Form::ImmediateA1;
return true; return true;
} }
if (ReadFields({ CondDef(), FieldDef<8>(0x30), FieldDef<4>(&imm4), if (ReadFields({ CondDef(), FieldDef<8>(0x30), FieldDef<4>(&imm4),
FieldDef<4>(&rd), FieldDef<12>(&imm12) })) FieldDef<4>(&rd), FieldDef<12>(&imm12) }))
{ {
s = false; s = false;
form = Form::ImmediateA2; form = Form::ImmediateA2;
if (rd == Register::PC) return false; // UNPREDICTIBLE if (rd == Register::PC) return false; // UNPREDICTIBLE
return true; return true;
} }
return false; return false;
} }
@ -39,50 +39,50 @@ void MovShift::GenerateInstructionCode(InstructionBlock* instruction_block)
auto ir_builder = instruction_block->IrBuilder(); auto ir_builder = instruction_block->IrBuilder();
auto carry_in = instruction_block->Read(Register::C); auto carry_in = instruction_block->Read(Register::C);
ARMFuncs::ResultCarry result = {}; ARMFuncs::ResultCarry result = {};
switch (form) switch (form)
{ {
case Form::Register: case Form::Register:
result = { instruction_block->Read(rm), carry_in }; result = { instruction_block->Read(rm), carry_in };
switch (op2) switch (op2)
{ {
case Op2Type::MoveAndLSL: case Op2Type::MoveAndLSL:
if (imm5 != 0) if (imm5 != 0)
{ {
result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::LSL, result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::LSL,
ARMFuncs::DecodeImmShift(instruction_block, 0, imm5).amount, result.carry); ARMFuncs::DecodeImmShift(instruction_block, 0, imm5).amount, result.carry);
} }
break; break;
case Op2Type::LSR: case Op2Type::LSR:
result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::LSR, result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::LSR,
ARMFuncs::DecodeImmShift(instruction_block, 1, imm5).amount, result.carry); ARMFuncs::DecodeImmShift(instruction_block, 1, imm5).amount, result.carry);
break; break;
case Op2Type::ASR: case Op2Type::ASR:
result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::ASR, result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::ASR,
ARMFuncs::DecodeImmShift(instruction_block, 2, imm5).amount, result.carry); ARMFuncs::DecodeImmShift(instruction_block, 2, imm5).amount, result.carry);
break; break;
case Op2Type::RRXAndROR: case Op2Type::RRXAndROR:
if (imm5 == 0) if (imm5 == 0)
{ {
result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::RRX, result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::RRX,
ir_builder->getInt32(1), result.carry); ir_builder->getInt32(1), result.carry);
} }
else else
{ {
result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::ROR, result = ARMFuncs::Shift_C(instruction_block, result.result, ARMFuncs::SRType::ROR,
ARMFuncs::DecodeImmShift(instruction_block, 3, imm5).amount, result.carry); ARMFuncs::DecodeImmShift(instruction_block, 3, imm5).amount, result.carry);
} }
break; break;
} }
break; break;
case Form::ImmediateA1: case Form::ImmediateA1:
result = ARMFuncs::ARMExpandImm_C(instruction_block, imm12, carry_in); result = ARMFuncs::ARMExpandImm_C(instruction_block, imm12, carry_in);
break; break;
case Form::ImmediateA2: case Form::ImmediateA2:
result.result = ir_builder->getInt32((imm4 << 12) | imm12); result.result = ir_builder->getInt32((imm4 << 12) | imm12);
break; break;
} }
instruction_block->Write(rd, result.result); instruction_block->Write(rd, result.result);

View File

@ -28,6 +28,6 @@ private:
Register rm; Register rm;
u32 imm12; u32 imm12;
u32 imm5; u32 imm5;
u32 imm4; u32 imm4;
Op2Type op2; Op2Type op2;
}; };

View File

@ -21,7 +21,7 @@ ModuleGen::ModuleGen(llvm::Module* module, bool verify)
ir_builder = make_unique<IRBuilder<>>(getGlobalContext()); ir_builder = make_unique<IRBuilder<>>(getGlobalContext());
machine = make_unique<MachineState>(this); machine = make_unique<MachineState>(this);
tbaa = make_unique<TBAA>(); tbaa = make_unique<TBAA>();
block_colors = make_unique<BlockColors>(this); block_colors = make_unique<BlockColors>(this);
} }
ModuleGen::~ModuleGen() ModuleGen::~ModuleGen()
@ -42,7 +42,7 @@ void ModuleGen::Run()
GenerateInstructionsCode(); GenerateInstructionsCode();
ColorBlocks(); ColorBlocks();
GenerateBlockAddressArray(); GenerateBlockAddressArray();
} }
@ -99,11 +99,11 @@ void ModuleGen::GenerateGlobals()
{ {
machine->GenerateGlobals(); machine->GenerateGlobals();
auto function_pointer = PointerType::get(block_colors->GetFunctionType(), 0); auto function_pointer = PointerType::get(block_colors->GetFunctionType(), 0);
block_address_type = StructType::get(function_pointer, ir_builder->getInt32Ty(), nullptr); block_address_type = StructType::get(function_pointer, ir_builder->getInt32Ty(), nullptr);
block_address_not_present = ConstantStruct::get(block_address_type, ConstantPointerNull::get(function_pointer), ir_builder->getInt32(0), nullptr); block_address_not_present = ConstantStruct::get(block_address_type, ConstantPointerNull::get(function_pointer), ir_builder->getInt32(0), nullptr);
auto get_block_address_function_type = FunctionType::get(block_address_type, ir_builder->getInt32Ty(), false); auto get_block_address_function_type = FunctionType::get(block_address_type, ir_builder->getInt32Ty(), false);
get_block_address_function = Function::Create(get_block_address_function_type, GlobalValue::PrivateLinkage, "GetBlockAddress", module); get_block_address_function = Function::Create(get_block_address_function_type, GlobalValue::PrivateLinkage, "GetBlockAddress", module);
auto can_run_function_type = FunctionType::get(ir_builder->getInt1Ty(), false); auto can_run_function_type = FunctionType::get(ir_builder->getInt1Ty(), false);
@ -115,7 +115,7 @@ void ModuleGen::GenerateGlobals()
block_address_array_base = Loader::ROMCodeStart / 4; block_address_array_base = Loader::ROMCodeStart / 4;
block_address_array_size = Loader::ROMCodeSize / 4; block_address_array_size = Loader::ROMCodeSize / 4;
block_address_array_type = ArrayType::get(block_address_type, block_address_array_size); block_address_array_type = ArrayType::get(block_address_type, block_address_array_size);
block_address_array = new GlobalVariable(*module, block_address_array_type, true, GlobalValue::ExternalLinkage, nullptr, "BlockAddressArray"); block_address_array = new GlobalVariable(*module, block_address_array_type, true, GlobalValue::ExternalLinkage, nullptr, "BlockAddressArray");
// bool Verify - contains the value of verify for citra usage // bool Verify - contains the value of verify for citra usage
@ -132,27 +132,27 @@ void ModuleGen::GenerateBlockAddressArray()
std::fill( std::fill(
local_block_address_array_values.get(), local_block_address_array_values.get(),
local_block_address_array_values.get() + block_address_array_size, local_block_address_array_values.get() + block_address_array_size,
block_address_not_present); block_address_not_present);
/*for (auto i = 0; i < instruction_blocks.size(); ++i) /*for (auto i = 0; i < instruction_blocks.size(); ++i)
{ {
auto &block = instruction_blocks[i]; auto &block = instruction_blocks[i];
auto entry_basic_block = block->GetEntryBasicBlock(); auto entry_basic_block = block->GetEntryBasicBlock();
auto index = block->Address() / 4 - block_address_array_base; auto index = block->Address() / 4 - block_address_array_base;
auto color_index = 0; auto color_index = 0;
local_block_address_array_values[index] = BConst local_block_address_array_values[index] = BConst
}*/ }*/
for (auto color = 0; color < block_colors->GetColorCount(); ++color) for (auto color = 0; color < block_colors->GetColorCount(); ++color)
{ {
auto function = block_colors->GetColorFunction(color); auto function = block_colors->GetColorFunction(color);
for (auto i = 0; i < block_colors->GetColorInstructionCount(color); ++i) for (auto i = 0; i < block_colors->GetColorInstructionCount(color); ++i)
{ {
auto block = block_colors->GetColorInstruction(color, i); auto block = block_colors->GetColorInstruction(color, i);
auto index = block->Address() / 4 - block_address_array_base; auto index = block->Address() / 4 - block_address_array_base;
auto value = ConstantStruct::get(block_address_type, function, ir_builder->getInt32(i), nullptr); auto value = ConstantStruct::get(block_address_type, function, ir_builder->getInt32(i), nullptr);
local_block_address_array_values[index] = value; local_block_address_array_values[index] = value;
} }
} }
auto local_block_address_array_values_ref = ArrayRef<Constant*>(local_block_address_array_values.get(), block_address_array_size); auto local_block_address_array_values_ref = ArrayRef<Constant*>(local_block_address_array_values.get(), block_address_array_size);
auto local_blocks_address_array = ConstantArray::get(block_address_array_type, local_block_address_array_values_ref); auto local_blocks_address_array = ConstantArray::get(block_address_array_type, local_block_address_array_values_ref);
@ -205,9 +205,9 @@ void ModuleGen::GenerateCanRunFunction()
ir_builder->SetInsertPoint(basic_block); ir_builder->SetInsertPoint(basic_block);
auto block_address = ir_builder->CreateCall(get_block_address_function, machine->ReadRegiser(Register::PC, true)); auto block_address = ir_builder->CreateCall(get_block_address_function, machine->ReadRegiser(Register::PC, true));
auto function = ir_builder->CreateExtractValue(block_address, 0); auto function = ir_builder->CreateExtractValue(block_address, 0);
ir_builder->CreateRet(ir_builder->CreateICmpNE(function, ir_builder->CreateRet(ir_builder->CreateICmpNE(function,
ConstantPointerNull::get(cast<PointerType>(function->getType())))); ConstantPointerNull::get(cast<PointerType>(function->getType()))));
} }
void ModuleGen::GenerateRunFunction() void ModuleGen::GenerateRunFunction()
@ -231,18 +231,18 @@ void ModuleGen::GenerateRunFunction()
auto block_present_basic_block = BasicBlock::Create(getGlobalContext(), "BlockPresent", run_function); auto block_present_basic_block = BasicBlock::Create(getGlobalContext(), "BlockPresent", run_function);
auto block_not_present_basic_block = BasicBlock::Create(getGlobalContext(), "BlockNotPresent", run_function); auto block_not_present_basic_block = BasicBlock::Create(getGlobalContext(), "BlockNotPresent", run_function);
ir_builder->SetInsertPoint(run_function_entry); ir_builder->SetInsertPoint(run_function_entry);
auto block_address = ir_builder->CreateCall(get_block_address_function, Machine()->ReadRegiser(Register::PC, true)); auto block_address = ir_builder->CreateCall(get_block_address_function, Machine()->ReadRegiser(Register::PC, true));
auto function = ir_builder->CreateExtractValue(block_address, 0); auto function = ir_builder->CreateExtractValue(block_address, 0);
auto block_present_pred = ir_builder->CreateICmpNE(function, auto block_present_pred = ir_builder->CreateICmpNE(function,
ConstantPointerNull::get(cast<PointerType>(function->getType()))); ConstantPointerNull::get(cast<PointerType>(function->getType())));
ir_builder->CreateCondBr(block_present_pred, block_present_basic_block, block_not_present_basic_block); ir_builder->CreateCondBr(block_present_pred, block_present_basic_block, block_not_present_basic_block);
ir_builder->SetInsertPoint(block_present_basic_block); ir_builder->SetInsertPoint(block_present_basic_block);
auto index = ir_builder->CreateExtractValue(block_address, 1); auto index = ir_builder->CreateExtractValue(block_address, 1);
auto call = ir_builder->CreateCall(function, index); auto call = ir_builder->CreateCall(function, index);
call->setTailCall(); call->setTailCall();
ir_builder->CreateRetVoid(); ir_builder->CreateRetVoid();
ir_builder->SetInsertPoint(block_not_present_basic_block); ir_builder->SetInsertPoint(block_not_present_basic_block);
ir_builder->CreateRetVoid(); ir_builder->CreateRetVoid();
@ -286,9 +286,9 @@ void ModuleGen::GenerateInstructionsCode()
void ModuleGen::ColorBlocks() void ModuleGen::ColorBlocks()
{ {
for (auto &instruction : instruction_blocks) for (auto &instruction : instruction_blocks)
{ {
block_colors->AddBlock(instruction.get()); block_colors->AddBlock(instruction.get());
} }
block_colors->GenerateFunctions(); block_colors->GenerateFunctions();
} }

View File

@ -50,10 +50,10 @@ private:
// Generates the entry basic blocks for each instruction // Generates the entry basic blocks for each instruction
void GenerateInstructionsEntry(); void GenerateInstructionsEntry();
// Generates the code of each instruction // Generates the code of each instruction
void GenerateInstructionsCode(); void GenerateInstructionsCode();
// Must be run after the instruction code is generated since it depends on the // Must be run after the instruction code is generated since it depends on the
// inter block jumps // inter block jumps
void ColorBlocks(); void ColorBlocks();
llvm::Module *module; llvm::Module *module;
bool verify; bool verify;
@ -64,16 +64,16 @@ private:
std::unique_ptr<llvm::IRBuilder<>> ir_builder; std::unique_ptr<llvm::IRBuilder<>> ir_builder;
size_t block_address_array_base; size_t block_address_array_base;
size_t block_address_array_size; size_t block_address_array_size;
/* /*
* struct BlockAddress * struct BlockAddress
* { * {
* void (*function)(u32 index); * void (*function)(u32 index);
* u32 index; * u32 index;
* } * }
*/ */
llvm::StructType *block_address_type; llvm::StructType *block_address_type;
llvm::Constant *block_address_not_present; llvm::Constant *block_address_not_present;
/* /*
* i8 **BlockAddressArray; * i8 **BlockAddressArray;
* The array at [i/4 - block_address_array_base] contains the block address for the instruction at i * The array at [i/4 - block_address_array_base] contains the block address for the instruction at i
@ -109,5 +109,5 @@ private:
std::vector<std::unique_ptr<InstructionBlock>> instruction_blocks; std::vector<std::unique_ptr<InstructionBlock>> instruction_blocks;
std::unordered_map<u32, InstructionBlock *> instruction_blocks_by_pc; std::unordered_map<u32, InstructionBlock *> instruction_blocks_by_pc;
std::unique_ptr<BlockColors> block_colors; std::unique_ptr<BlockColors> block_colors;
}; };

View File

@ -28,30 +28,30 @@ int main(int argc, const char *const *argv)
} }
cl::ParseCommandLineOptions(argc, argv); cl::ParseCommandLineOptions(argc, argv);
std::shared_ptr<Log::Logger> logger = Log::InitGlobalLogger(); std::shared_ptr<Log::Logger> logger = Log::InitGlobalLogger();
Log::Filter log_filter(Log::Level::Debug); Log::Filter log_filter(Log::Level::Debug);
Log::SetFilter(&log_filter); Log::SetFilter(&log_filter);
std::thread logging_thread(Log::TextLoggingLoop, logger); std::thread logging_thread(Log::TextLoggingLoop, logger);
SCOPE_EXIT({ SCOPE_EXIT({
logger->Close(); logger->Close();
logging_thread.join(); logging_thread.join();
}); });
auto input_rom = InputFilename.c_str(); auto input_rom = InputFilename.c_str();
auto output_object = OutputFilename.c_str(); auto output_object = OutputFilename.c_str();
auto output_debug = DebugFilename.getNumOccurrences() ? DebugFilename.c_str() : nullptr; auto output_debug = DebugFilename.getNumOccurrences() ? DebugFilename.c_str() : nullptr;
bool verify = Verify; bool verify = Verify;
Core::Init(); Core::Init();
Memory::Init(); Memory::Init();
auto load_result = Loader::LoadFile(input_rom); auto load_result = Loader::LoadFile(input_rom);
if (Loader::ResultStatus::Success != load_result) if (Loader::ResultStatus::Success != load_result)
{ {
LOG_CRITICAL(BinaryTranslator, "Failed to load ROM (Error %i)!", load_result); LOG_CRITICAL(BinaryTranslator, "Failed to load ROM (Error %i)!", load_result);
return -1; return -1;
} }
CodeGen code_generator(output_object, output_debug, verify); CodeGen code_generator(output_object, output_debug, verify);
code_generator.Run(); code_generator.Run();
} }