teak-llvm/llvm/lib/Target/Teak/TeakOptimizeMovImmPass.cpp
Gericom 3da44a85b7 Many bug fixes and improvements
Fixed invalid mpy instruction being generated
Fixed byte order of 32 bit values when emitted to the elf file
Support for addv/subv to modify 16 bit registers directly
Support for move 8bit immediate
Support for tst0 instruction
Support for directly adding p0 to an ab register after mpy
Support for 8 bit immediate multiply
Support for modr instruction
Support for post increase/decrement for loads and stores
Use copy instruction for a to a register moves
2020-07-28 16:42:11 +02:00

93 lines
2.9 KiB
C++

#include "Teak.h"
#include "TeakInstrInfo.h"
#include "TeakMachineFunctionInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
using namespace llvm;
namespace
{
class TeakOptimizeMovImmPass : public MachineFunctionPass
{
public:
static char sId;
TeakOptimizeMovImmPass() : MachineFunctionPass(sId) { }
bool runOnMachineFunction(MachineFunction& mf) override;
MachineFunctionProperties getRequiredProperties() const override
{
return MachineFunctionProperties()
.set(MachineFunctionProperties::Property::NoVRegs);
}
StringRef getPassName() const override { return "optimise teak move immediate pass"; }
};
char TeakOptimizeMovImmPass::sId = 0;
}
bool TeakOptimizeMovImmPass::runOnMachineFunction(MachineFunction& mf)
{
if (skipFunction(mf.getFunction()))
return false;
const TargetInstrInfo* tii = mf.getSubtarget().getInstrInfo();
std::vector<MachineInstr*> movImms;
for (auto& mbb : mf)
{
for (auto& mi : mbb)
{
if (mi.getOpcode() == Teak::MOV_imm16_regnob16 ||
mi.getOpcode() == Teak::MOV_imm16_ab ||
mi.getOpcode() == Teak::MOV_imm16_abh)
{
movImms.push_back(&mi);
}
}
}
bool changed = false;
for (auto mi : movImms)
{
if (!mi->getOperand(1).isImm())
continue;
unsigned dstReg = mi->getOperand(0).getReg();
if (mi->getOpcode() == Teak::MOV_imm16_ab)
dstReg = teakGetAbLReg(dstReg);
else if (mi->getOpcode() == Teak::MOV_imm16_abh)
dstReg = teakGetAbHReg(dstReg);
int64_t imm = mi->getOperand(1).getImm();
if ((dstReg == Teak::R0 || dstReg == Teak::R1 ||
dstReg == Teak::R2 || dstReg == Teak::R3 ||
dstReg == Teak::R4 || dstReg == Teak::R5 ||
dstReg == Teak::R7 || dstReg == Teak::Y0 ||
dstReg == Teak::SV || dstReg == Teak::A0H ||
dstReg == Teak::A1H || dstReg == Teak::EXT0 ||
dstReg == Teak::EXT1 || dstReg == Teak::EXT2 ||
dstReg == Teak::EXT3) && imm >= -128 && imm <= 127)
{
BuildMI(*mi->getParent(), *mi, mi->getDebugLoc(), tii->get(Teak::MOV_imm8s), dstReg)
.addImm(imm);
mi->eraseFromParent();
changed = true;
}
else if ((dstReg == Teak::A0L || dstReg == Teak::A1L) && imm >= 0 && imm <= 255)
{
BuildMI(*mi->getParent(), *mi, mi->getDebugLoc(), tii->get(Teak::MOV_imm8u), dstReg)
.addImm(imm);
mi->eraseFromParent();
changed = true;
}
}
return changed;
}
FunctionPass* llvm::createTeakOptimizeMovImmPass()
{
return new TeakOptimizeMovImmPass();
}