mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 11:31:04 +00:00
Added block linking
Each time an instruction finishes it jumps to the next one instead of going back to the switch block
This commit is contained in:
parent
3864675b6d
commit
d7367172e8
@ -25,11 +25,18 @@ void InstructionBlock::GenerateEntryBlock()
|
||||
|
||||
void InstructionBlock::GenerateCode()
|
||||
{
|
||||
Module()->IrBuilder()->SetInsertPoint(entry_basic_block);
|
||||
auto ir_builder = Module()->IrBuilder();
|
||||
ir_builder->SetInsertPoint(entry_basic_block);
|
||||
|
||||
instruction->GenerateCode(this);
|
||||
|
||||
exit_basic_block = Module()->IrBuilder()->GetInsertBlock();
|
||||
auto basic_block = ir_builder->GetInsertBlock();
|
||||
// If the basic block is terminated there has been a jump
|
||||
// If not, jump to the next instruction
|
||||
if (!basic_block->getTerminator())
|
||||
{
|
||||
Module()->WritePCConst(Address() + 4);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Value *InstructionBlock::Read(Register reg)
|
||||
|
@ -47,7 +47,6 @@ public:
|
||||
ModuleGen *Module() { return module; }
|
||||
|
||||
llvm::BasicBlock *GetEntryBasicBlock() { return entry_basic_block; }
|
||||
llvm::BasicBlock *GetExitBasicBlock() { return exit_basic_block; }
|
||||
private:
|
||||
// Textual representation of the address
|
||||
// Used to generate names
|
||||
@ -58,7 +57,4 @@ private:
|
||||
|
||||
// The block at the entry to instruction
|
||||
llvm::BasicBlock *entry_basic_block;
|
||||
|
||||
// The block at the exit from the instruction
|
||||
llvm::BasicBlock *exit_basic_block;
|
||||
};
|
@ -1,6 +1,7 @@
|
||||
#include "DataProcessing.h"
|
||||
#include "Disassembler.h"
|
||||
#include "InstructionBlock.h"
|
||||
#include "ModuleGen.h"
|
||||
|
||||
static RegisterInstruction<DataProcessing> register_instruction;
|
||||
|
||||
@ -32,4 +33,9 @@ void DataProcessing::GenerateCode(InstructionBlock* instruction_block)
|
||||
|
||||
auto value = instruction_block->Read(rm);
|
||||
instruction_block->Write(rd, value);
|
||||
|
||||
if (rd == Register::PC)
|
||||
{
|
||||
instruction_block->Module()->ReadPC();
|
||||
}
|
||||
}
|
@ -35,12 +35,32 @@ void ModuleGen::Run()
|
||||
GenerateGetBlockAddressFunction();
|
||||
|
||||
GenerateInstructionsCode();
|
||||
GenerateInstructionsTermination();
|
||||
AddInstructionsToRunFunction();
|
||||
|
||||
GenerateBlockAddressArray();
|
||||
}
|
||||
|
||||
void ModuleGen::ReadPC()
|
||||
{
|
||||
ir_builder->CreateBr(run_function_re_entry);
|
||||
}
|
||||
|
||||
void ModuleGen::WritePCConst(u32 pc)
|
||||
{
|
||||
auto i = instruction_blocks_by_pc.find(pc);
|
||||
if (i != instruction_blocks_by_pc.end())
|
||||
{
|
||||
// Found instruction, jump to it
|
||||
ir_builder->CreateBr(i->second->GetEntryBasicBlock());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Didn't find instruction, write PC and exit
|
||||
machine->WriteRegiser(Register::PC, ir_builder->getInt32(pc));
|
||||
ir_builder->CreateRetVoid();
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleGen::GenerateGlobals()
|
||||
{
|
||||
machine->GenerateGlobals();
|
||||
@ -200,17 +220,6 @@ void ModuleGen::GenerateInstructionsCode()
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleGen::GenerateInstructionsTermination()
|
||||
{
|
||||
// Return to the switch
|
||||
for (auto &block : instruction_blocks)
|
||||
{
|
||||
ir_builder->SetInsertPoint(block->GetExitBasicBlock());
|
||||
Machine()->WriteRegiser(Register::PC, ir_builder->getInt32(block->Address() + 4));
|
||||
ir_builder->CreateBr(run_function_re_entry);
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleGen::AddInstructionsToRunFunction()
|
||||
{
|
||||
std::stack<BasicBlock *> basic_blocks_stack;
|
||||
@ -223,6 +232,7 @@ void ModuleGen::AddInstructionsToRunFunction()
|
||||
{
|
||||
auto basic_block = basic_blocks_stack.top();
|
||||
basic_blocks_stack.pop();
|
||||
if (basic_block->getParent()) continue; // Already added to run
|
||||
basic_block->insertInto(run_function);
|
||||
auto terminator = basic_block->getTerminator();
|
||||
for (auto i = 0; i < terminator->getNumSuccessors(); ++i)
|
||||
|
@ -20,6 +20,11 @@ public:
|
||||
|
||||
void Run();
|
||||
|
||||
// Generate code to read pc and run all following instructions, used in cases of indirect branch
|
||||
void ReadPC();
|
||||
// Generate code to write to pc and run all following instructions, used in cases of direct branch
|
||||
void WritePCConst(u32 pc);
|
||||
|
||||
llvm::IRBuilder<> *IrBuilder() { return ir_builder.get(); }
|
||||
llvm::Module *Module() { return module; }
|
||||
MachineState *Machine() { return machine.get(); }
|
||||
@ -37,8 +42,6 @@ private:
|
||||
void GenerateInstructionsEntry();
|
||||
// Generates the code of each instruction
|
||||
void GenerateInstructionsCode();
|
||||
// Terminates each block
|
||||
void GenerateInstructionsTermination();
|
||||
// Adds all the basic blocks of an instruction to the run function
|
||||
void AddInstructionsToRunFunction();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user