Added bl, blx

17% of the instructions in 3dscraft
This commit is contained in:
Dani Messerman 2015-05-01 00:41:58 +03:00
parent 4daf99fa44
commit 7882bb2c4c
8 changed files with 88 additions and 8 deletions

View File

@ -9,6 +9,7 @@ set(SRCS
Instructions/Instruction.cpp Instructions/Instruction.cpp
Instructions/DataProcessing.cpp Instructions/DataProcessing.cpp
Instructions/Branch.cpp
) )
set(HEADERS set(HEADERS
CodeGen.h CodeGen.h
@ -21,6 +22,7 @@ set(HEADERS
Instructions/Types.h Instructions/Types.h
Instructions/Instruction.h Instructions/Instruction.h
Instructions/DataProcessing.h Instructions/DataProcessing.h
Instructions/Branch.h
) )
create_directory_groups(${SRCS} ${HEADERS}) create_directory_groups(${SRCS} ${HEADERS})

View File

@ -35,7 +35,7 @@ void InstructionBlock::GenerateCode()
// If not, jump to the next instruction // If not, jump to the next instruction
if (!basic_block->getTerminator()) if (!basic_block->getTerminator())
{ {
Module()->WritePCConst(Address() + 4); Module()->BranchWritePCConst(Address() + 4);
} }
} }
@ -49,7 +49,7 @@ llvm::Value *InstructionBlock::Write(Register reg, llvm::Value *value)
return module->Machine()->WriteRegiser(reg, value); return module->Machine()->WriteRegiser(reg, value);
} }
size_t InstructionBlock::Address() u32 InstructionBlock::Address()
{ {
return instruction->Address(); return instruction->Address();
} }

View File

@ -1,5 +1,6 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <common/common_types.h>
namespace llvm namespace llvm
{ {
@ -43,7 +44,7 @@ public:
*/ */
llvm::Value *Write(Register reg, llvm::Value *value); llvm::Value *Write(Register reg, llvm::Value *value);
size_t Address(); u32 Address();
ModuleGen *Module() { return module; } ModuleGen *Module() { return module; }
llvm::BasicBlock *GetEntryBasicBlock() { return entry_basic_block; } llvm::BasicBlock *GetEntryBasicBlock() { return entry_basic_block; }

View File

@ -0,0 +1,51 @@
#include "Branch.h"
#include "Disassembler.h"
#include "InstructionBlock.h"
#include "ModuleGen.h"
static RegisterInstruction<Branch> register_instruction;
bool Branch::Decode()
{
// B imm, BL imm
if (ReadFields({ FieldDef<4>(&cond), FieldDef<3>(5), FieldDef<1>(&link), FieldDef<24>(&imm24) }))
{
if (cond != Condition::AL) return false;
form = Form::Immediate;
return true;
}
// BLX reg
if (ReadFields({ FieldDef<4>(&cond), FieldDef<24>(0x12fff3), FieldDef<4>(&rm)}))
{
if (cond != Condition::AL) return false;
if (rm == Register::PC) return false;
link = true;
form = Form::Register;
return true;
}
return false;
}
void Branch::GenerateCode(InstructionBlock* instruction_block)
{
auto ir_builder = instruction_block->Module()->IrBuilder();
if (link)
{
instruction_block->Write(Register::LR, ir_builder->getInt32(instruction_block->Address() + 4));
}
if (form == Form::Immediate)
{
auto pc = static_cast<s32>(imm24 << 2);
pc = pc << 6 >> 6; // Sign extend
pc += instruction_block->Address() + 8;
instruction_block->Module()->BranchWritePCConst(pc);
}
else
{
auto pc = instruction_block->Read(rm);
instruction_block->Write(Register::PC, pc);
instruction_block->Module()->BranchReadPC();
}
}

View File

@ -0,0 +1,26 @@
#include "Instruction.h"
#include "Types.h"
/*
* Data processing instructions
* ARMv7-A 5.2.1 (register), 5.2.2 (register-shifted register, 5.2.3 (immediate)
*/
class Branch : public Instruction
{
public:
enum class Form
{
Immediate, Register
};
public:
virtual bool Decode() override;
void GenerateCode(InstructionBlock* instruction_block) override;
private:
Form form;
Condition cond;
bool link;
u32 imm24;
Register rm;
};

View File

@ -37,6 +37,6 @@ void DataProcessing::GenerateCode(InstructionBlock* instruction_block)
if (rd == Register::PC) if (rd == Register::PC)
{ {
instruction_block->Module()->ReadPC(); instruction_block->Module()->BranchReadPC();
} }
} }

View File

@ -42,12 +42,12 @@ void ModuleGen::Run()
GenerateBlockAddressArray(); GenerateBlockAddressArray();
} }
void ModuleGen::ReadPC() void ModuleGen::BranchReadPC()
{ {
ir_builder->CreateBr(run_function_re_entry); ir_builder->CreateBr(run_function_re_entry);
} }
void ModuleGen::WritePCConst(u32 pc) void ModuleGen::BranchWritePCConst(u32 pc)
{ {
auto i = instruction_blocks_by_pc.find(pc); auto i = instruction_blocks_by_pc.find(pc);
if (i != instruction_blocks_by_pc.end()) if (i != instruction_blocks_by_pc.end())

View File

@ -22,9 +22,9 @@ public:
void Run(); void Run();
// Generate code to read pc and run all following instructions, used in cases of indirect branch // Generate code to read pc and run all following instructions, used in cases of indirect branch
void ReadPC(); void BranchReadPC();
// Generate code to write to pc and run all following instructions, used in cases of direct branch // Generate code to write to pc and run all following instructions, used in cases of direct branch
void WritePCConst(u32 pc); void BranchWritePCConst(u32 pc);
llvm::IRBuilder<> *IrBuilder() { return ir_builder.get(); } llvm::IRBuilder<> *IrBuilder() { return ir_builder.get(); }
llvm::Module *Module() { return module; } llvm::Module *Module() { return module; }