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
This commit is contained in:
Gericom 2020-07-28 16:42:11 +02:00
parent c0fc95658e
commit 3da44a85b7
20 changed files with 1194 additions and 570 deletions

View File

@ -20,6 +20,7 @@ add_llvm_target(TeakCodeGen
TeakISelDAGToDAG.cpp
TeakAsmPrinter.cpp
TeakMCInstLower.cpp
TeakOptimizeMovImmPass.cpp
)
add_subdirectory(AsmParser)

View File

@ -4,4 +4,5 @@ add_llvm_component_library(LLVMTeakDesc
TeakMCCodeEmitter.cpp
TeakAsmBackend.cpp
TeakELFObjectWriter.cpp
TeakELFStreamer.cpp
)

View File

@ -0,0 +1,41 @@
#include "TeakELFStreamer.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/Support/Casting.h"
using namespace llvm;
TeakELFStreamer::TeakELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter)
: MCELFStreamer(Context, std::move(MAB), std::move(OW), std::move(Emitter))
{
}
void TeakELFStreamer::EmitIntValue(uint64_t Value, unsigned Size)
{
if (Size == 4)
{
char buf[4];
buf[0] = uint8_t((Value >> 16) & 0xFF);
buf[1] = uint8_t((Value >> 24) & 0xFF);
buf[2] = uint8_t(Value & 0xFF);
buf[3] = uint8_t((Value >> 8) & 0xFF);
EmitBytes(StringRef(buf, Size));
return;
}
MCELFStreamer::EmitIntValue(Value, Size);
}
MCELFStreamer* llvm::createTeakELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter, bool RelaxAll)
{
return new TeakELFStreamer(Context, std::move(MAB), std::move(OW), std::move(Emitter));
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "llvm/MC/MCELFStreamer.h"
#include <memory>
namespace llvm
{
class MCAsmBackend;
class MCCodeEmitter;
class MCContext;
class MCSubtargetInfo;
class MCObjectWriter;
class TeakELFStreamer : public MCELFStreamer
{
public:
TeakELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter);
void EmitIntValue(uint64_t Value, unsigned Size) override;
};
MCELFStreamer* createTeakELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter, bool RelaxAll);
}

View File

@ -132,10 +132,10 @@ static unsigned encodeRegisterOp(unsigned reg)
case Teak::B1H: return 0x11;
case Teak::B0L: return 0x12;
case Teak::B1L: return 0x13;
//case Teak::EXT0: return 0x14;
//case Teak::EXT1: return 0x15;
//case Teak::EXT2: return 0x16;
//case Teak::EXT3: return 0x17;
case Teak::EXT0: return 0x14;
case Teak::EXT1: return 0x15;
case Teak::EXT2: return 0x16;
case Teak::EXT3: return 0x17;
case Teak::A0: return 0x18;
case Teak::A1: return 0x19;
case Teak::A0L: return 0x1A;
@ -175,10 +175,10 @@ static unsigned encodeRegisterP0Op(unsigned reg)
case Teak::B1H: return 0x11;
case Teak::B0L: return 0x12;
case Teak::B1L: return 0x13;
//case Teak::EXT0: return 0x14;
//case Teak::EXT1: return 0x15;
//case Teak::EXT2: return 0x16;
//case Teak::EXT3: return 0x17;
case Teak::EXT0: return 0x14;
case Teak::EXT1: return 0x15;
case Teak::EXT2: return 0x16;
case Teak::EXT3: return 0x17;
case Teak::A0: return 0x18;
case Teak::A1: return 0x19;
case Teak::A0L: return 0x1A;
@ -235,6 +235,19 @@ static unsigned encodeAxlOp(unsigned reg)
}
}
static unsigned encodeAxhOp(unsigned reg)
{
switch (reg)
{
case Teak::A0H: return 0;
case Teak::A1H: return 1;
default:
dbgs() << "encodeAxhOp(" << reg << ")\n";
llvm_unreachable("Unsupported register");
break;
}
}
static unsigned encodeBxOp(unsigned reg)
{
switch (reg)
@ -248,6 +261,53 @@ static unsigned encodeBxOp(unsigned reg)
}
}
static unsigned encodeAbeOp(unsigned reg)
{
switch (reg)
{
case Teak::B0E: return 0;
case Teak::B1E: return 1;
case Teak::A0E: return 2;
case Teak::A1E: return 3;
default:
dbgs() << "encodeAbeOp(" << reg << ")\n";
llvm_unreachable("Unsupported register");
break;
}
}
static unsigned encodePxOp(unsigned reg)
{
switch (reg)
{
case Teak::P0: return 0;
case Teak::P1: return 1;
default:
dbgs() << "encodePxOp(" << reg << ")\n";
llvm_unreachable("Unsupported register");
break;
}
}
static unsigned encodeR0123457Y0Op(unsigned reg)
{
switch (reg)
{
case Teak::R0: return 0;
case Teak::R1: return 1;
case Teak::R2: return 2;
case Teak::R3: return 3;
case Teak::R4: return 4;
case Teak::R5: return 5;
case Teak::R7: return 6;
case Teak::Y0: return 7;
default:
dbgs() << "encodeR0123457Y0Op(" << reg << ")\n";
llvm_unreachable("Unsupported register");
break;
}
}
static unsigned encodeRnOp(unsigned reg)
{
switch (reg)
@ -377,6 +437,18 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::ADD_memrn_a:
EmitConstant(0x8680 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
break;
case Teak::ADD_px_ab:
{
unsigned abReg = MI.getOperand(0).getReg();
unsigned pReg = MI.getOperand(1).getReg();
if (pReg == Teak::P0 && TeakMCRegisterClasses[Teak::ARegsRegClassID].contains(abReg))
EmitConstant(0x86A0 | encodeRegisterP0Op(pReg) | (encodeAxOp(abReg) << 8), 2, OS);
else if (pReg == Teak::P1 && TeakMCRegisterClasses[Teak::ARegsRegClassID].contains(abReg))
EmitConstant(0xD782 | encodeAxOp(abReg), 2, OS);
else
EmitConstant(0x5DF8 | (encodePxOp(pReg) << 1) | encodeBxOp(abReg), 2, OS);
break;
}
case Teak::ADDL_memrn_a:
EmitConstant(0x9480 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
break;
@ -558,6 +630,18 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::INC_a:
EmitConstant(0x67D0 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS);
break;
case Teak::MODR_inc1:
EmitConstant(0x0080 | encodeRnOp(MI.getOperand(0).getReg()) | (TeakStepZIDS::AddOne << 3), 2, OS);
break;
case Teak::MODR_dec1:
EmitConstant(0x0080 | encodeRnOp(MI.getOperand(0).getReg()) | (TeakStepZIDS::SubOne << 3), 2, OS);
break;
case Teak::MODR_inc2:
EmitConstant(0x4990 | encodeRnOp(MI.getOperand(0).getReg()), 2, OS);
break;
case Teak::MODR_dec2:
EmitConstant(0x5DA0 | encodeRnOp(MI.getOperand(0).getReg()), 2, OS);
break;
case Teak::MOV_imm16_regnob16:
case Teak::MOV_imm16neg_ab:
case Teak::MOV_imm16_ab:
@ -583,6 +667,35 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
}
break;
}
case Teak::MOV_imm8s:
{
unsigned reg = MI.getOperand(0).getReg();
int64_t imm = MI.getOperand(1).getImm();
if (reg == Teak::A0H || reg == Teak::A1H)
EmitConstant(0x2500 | (encodeAxhOp(reg) << 12) | (imm & 0xFF), 2, OS);
else if (reg == Teak::EXT0)
EmitConstant(0x2900 | (imm & 0xFF), 2, OS);
else if (reg == Teak::EXT1)
EmitConstant(0x2D00 | (imm & 0xFF), 2, OS);
else if (reg == Teak::EXT2)
EmitConstant(0x3900 | (imm & 0xFF), 2, OS);
else if (reg == Teak::EXT3)
EmitConstant(0x3D00 | (imm & 0xFF), 2, OS);
else if (reg == Teak::R0 || reg == Teak::R1 || reg == Teak::R2 ||
reg == Teak::R3 || reg == Teak::R4 || reg == Teak::R5 ||
reg == Teak::R7 || reg == Teak::Y0)
{
EmitConstant(0x2300 | (encodeR0123457Y0Op(reg) << 10) | (imm & 0xFF), 2, OS);
}
else if(reg == Teak::SV)
EmitConstant(0x0500 | (imm & 0xFF), 2, OS);
else
llvm_unreachable("mov imm8s unsupported register");
break;
}
case Teak::MOV_imm8u:
EmitConstant(0x2100 | (encodeAxlOp(MI.getOperand(0).getReg()) << 12) | (MI.getOperand(1).getImm() & 0xFF), 2, OS);
break;
case Teak::MOV_ab_ab:
EmitConstant(0xD290 | (encodeAbOp(MI.getOperand(1).getReg()) << 10) | (encodeAbOp(MI.getOperand(0).getReg()) << 5), 2, OS);
break;
@ -590,11 +703,14 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::MOV_regnobp016_ab:
case Teak::MOV_regnobp016_abl:
case Teak::MOV_p0_ab:
case Teak::MOV_p0_regnob16:
{
unsigned dstReg = MI.getOperand(0).getReg();
if(MI.getOpcode() == Teak::MOV_regnobp016_abl)
dstReg = teakGetAbLReg(dstReg);
if(MI.getOperand(1).getReg() == Teak::P0 && !TeakMCRegisterClasses[Teak::ABRegsRegClassID].contains(dstReg))
llvm_unreachable("Register P0 can only be moved to ABx!");
if(MI.getOperand(1).getReg() == Teak::R6)
{
if(TeakMCRegisterClasses[Teak::BRegsRegClassID].contains(dstReg))
@ -614,12 +730,16 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
break;
}
case Teak::MOV_regnob16_memrn:
case Teak::MOV_regnob16_memrn_postinc:
case Teak::MOV_regnob16_memrn_postdec:
case Teak::MOV_abl_memrn:
{
TeakStepZIDS::Steps step =
MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec ? TeakStepZIDS::SubOne : TeakStepZIDS::Zero;
int opOffset = MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec ? 1 : 0;
TeakStepZIDS::Steps step = TeakStepZIDS::Zero;
if (MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec)
step = TeakStepZIDS::SubOne;
else if (MI.getOpcode() == Teak::MOV_regnob16_memrn_postinc)
step = TeakStepZIDS::AddOne;
int opOffset = step == TeakStepZIDS::Zero ? 0 : 1;
unsigned reg = MI.getOperand(opOffset).getReg();
if(MI.getOpcode() == Teak::MOV_abl_memrn)
reg = teakGetAbLReg(reg);
@ -642,13 +762,17 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
break;
}
case Teak::MOV_memrn_regnob16:
case Teak::MOV_memrn_regnob16_postinc:
case Teak::MOV_memrn_regnob16_postdec:
case Teak::MOV_memrn_ab:
case Teak::MOV_memrn_ab1:
{
unsigned dstReg = MI.getOperand(0).getReg();
TeakStepZIDS::Steps step =
MI.getOpcode() == Teak::MOV_memrn_regnob16_postdec ? TeakStepZIDS::SubOne : TeakStepZIDS::Zero;
TeakStepZIDS::Steps step = TeakStepZIDS::Zero;
if (MI.getOpcode() == Teak::MOV_memrn_regnob16_postdec)
step = TeakStepZIDS::SubOne;
else if (MI.getOpcode() == Teak::MOV_memrn_regnob16_postinc)
step = TeakStepZIDS::AddOne;
if(MI.getOpcode() == Teak::MOV_memrn_ab1)
dstReg = teakGetAbLReg(dstReg);
if(dstReg == Teak::R6)
@ -693,6 +817,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
}
break;
}
case Teak::MPYI_y0_imm8s:
EmitConstant(0x0800 | (MI.getOperand(2).getImm() & 0xFF), 2, OS);
break;
case Teak::MPY_y0_regnob16:
if(MI.getOperand(2).getReg() == Teak::R6)
EmitConstant(0x5EA0, 2, OS);
@ -702,6 +829,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::NEG_a:
EmitConstant(0x6790 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS);
break;
case Teak::NOP:
EmitConstant(0, 2, OS);
break;
case Teak::NOT_a:
EmitConstant(0x6780 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS);
break;
@ -888,6 +1018,17 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
EmitConstant(0x4980 | swapOp, 2, OS);
break;
}
case Teak::TST0_imm16_RegNoBRegs16:
if (MI.getOperand(1).getReg() == Teak::R6)
EmitConstant(0x47BC, 2, OS);
else
EmitConstant(0x89E0 | encodeRegisterOp(MI.getOperand(1).getReg()), 2, OS);
EmitConstant(MI.getOperand(0).getImm() & 0xFFFF, 2, OS);
break;
case Teak::TST0_imm16_memrn:
EmitConstant(0x88E0 | encodeRnOp(MI.getOperand(1).getReg()), 2, OS);
EmitConstant(MI.getOperand(0).getImm() & 0xFFFF, 2, OS);
break;
case Teak::PUSH_regnob16:
{
unsigned reg = MI.getOperand(0).getReg();
@ -902,6 +1043,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::PUSH_ararpsttmod:
EmitConstant(0xD3D0 | encodeArArpSttModOp(MI.getOperand(0).getReg()), 2, OS);
break;
case Teak::PUSH_abe:
EmitConstant(0xD7C8 | (encodeAbeOp(MI.getOperand(0).getReg()) << 1), 2, OS);
break;
case Teak::POP_regnob16:
{
unsigned reg = MI.getOperand(0).getReg();
@ -916,6 +1060,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::POP_ararpsttmod:
EmitConstant(0x80C7 | (encodeArArpSttModOp(MI.getOperand(0).getReg()) << 8), 2, OS);
break;
case Teak::POP_abe:
EmitConstant(0x47B4 | encodeAbeOp(MI.getOperand(0).getReg()), 2, OS);
break;
case Teak::RET:
EmitConstant(0x4580 | MI.getOperand(0).getImm(), 2, OS);
break;

View File

@ -1,25 +1,17 @@
//===-- TeakMCTargetDesc.cpp - Teak Target Descriptions -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides Teak specific target descriptions.
//
//===----------------------------------------------------------------------===//
#include "../TargetInfo/TeakTargetInfo.h"
#include "llvm/MC/MCAsmBackend.h"
#include "TeakMCTargetDesc.h"
#include "InstPrinter/TeakInstPrinter.h"
#include "TeakMCAsmInfo.h"
#include "TeakELFStreamer.h"
//\#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
@ -77,15 +69,22 @@ static MCAsmInfo *createTeakMCAsmInfo(const MCRegisterInfo &MRI,
// return X;
// }
static MCInstPrinter *
createTeakMCInstPrinter(const Triple &TT, unsigned SyntaxVariant,
const MCAsmInfo &MAI, const MCInstrInfo &MII,
const MCRegisterInfo &MRI) {
static MCInstPrinter* createTeakMCInstPrinter(const Triple &TT, unsigned SyntaxVariant,
const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
{
return new TeakInstPrinter(MAI, MII, MRI);
}
static MCStreamer* createTeakMCStreamer(const Triple &T, MCContext &Context,
std::unique_ptr<MCAsmBackend> &&MAB, std::unique_ptr<MCObjectWriter> &&OW,
std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll)
{
return createTeakELFStreamer(Context, std::move(MAB), std::move(OW), std::move(Emitter), RelaxAll);
}
// Force static initialization.
extern "C" void LLVMInitializeTeakTargetMC() {
extern "C" void LLVMInitializeTeakTargetMC()
{
// Register the MC asm info.
RegisterMCAsmInfoFn X(getTheTeakTarget(), createTeakMCAsmInfo);
@ -109,4 +108,6 @@ extern "C" void LLVMInitializeTeakTargetMC() {
// Register the MCCodeEmitter
TargetRegistry::RegisterMCCodeEmitter(getTheTeakTarget(), createTeakMCCodeEmitter);
TargetRegistry::RegisterELFStreamer(getTheTeakTarget(), createTeakMCStreamer);
}

View File

@ -23,7 +23,8 @@ namespace llvm
class TargetMachine;
class TeakTargetMachine;
FunctionPass *createTeakISelDag(TeakTargetMachine &TM, CodeGenOpt::Level OptLevel);
FunctionPass* createTeakISelDag(TeakTargetMachine &TM, CodeGenOpt::Level OptLevel);
FunctionPass* createTeakOptimizeMovImmPass();
namespace TeakCC
{
@ -100,6 +101,31 @@ namespace llvm
}
}
inline static unsigned teakGetAbReg(unsigned reg)
{
switch(reg)
{
case Teak::A0: return Teak::A0;
case Teak::A0L: return Teak::A0;
case Teak::A0H: return Teak::A0;
case Teak::A0E: return Teak::A0;
case Teak::A1: return Teak::A1;
case Teak::A1L: return Teak::A1;
case Teak::A1H: return Teak::A1;
case Teak::A1E: return Teak::A1;
case Teak::B0: return Teak::B0;
case Teak::B0L: return Teak::B0;
case Teak::B0H: return Teak::B0;
case Teak::B0E: return Teak::B0;
case Teak::B1: return Teak::B1;
case Teak::B1L: return Teak::B1;
case Teak::B1H: return Teak::B1;
case Teak::B1E: return Teak::B1;
default:
llvm_unreachable("Invalid reg");
}
}
inline static unsigned teakGetAbLReg(unsigned reg)
{
switch(reg)
@ -133,6 +159,23 @@ namespace llvm
llvm_unreachable("Invalid reg");
}
}
inline static unsigned teakGetAbEReg(unsigned reg)
{
switch(reg)
{
case Teak::A0: return Teak::A0E;
case Teak::A0E: return Teak::A0E;
case Teak::A1: return Teak::A1E;
case Teak::A1E: return Teak::A1E;
case Teak::B0: return Teak::B0E;
case Teak::B0E: return Teak::B0E;
case Teak::B1: return Teak::B1E;
case Teak::B1E: return Teak::B1E;
default:
llvm_unreachable("Invalid reg");
}
}
} // end namespace llvm;
#endif

View File

@ -55,5 +55,5 @@ def CC_Teak : CallingConv<[
//CCIfType<[i32], CCAssignToStack<4, 4>>
]>;
def CSR : CalleeSavedRegs<(add Y0, Y1, R0, R1, R2, R3, R4, R5, R6, R7)>;
def CSR : CalleeSavedRegs<(add Y0, Y1, R0, R1, R2, R3, R4, R5, R6, R7, (sequence "PAGE%u", 0, 39))>;
def CSR_NoRegs : CalleeSavedRegs<(add)>;

View File

@ -113,6 +113,9 @@ void TeakFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB
.addImm(-(StackSize >> 1))
.addReg(Teak::SP)
.setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, dl, TII.get(Teak::NOP))
.setMIFlag(MachineInstr::FrameSetup);
}
void TeakFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
@ -136,6 +139,8 @@ void TeakFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB
BuildMI(MBB, MBBI, dl, TII.get(Teak::MOV_regnobp016_regnob16), Teak::SP)
.addReg(Teak::R7)
.setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, dl, TII.get(Teak::NOP))
.setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, dl, TII.get(Teak::POP_regnob16), Teak::R7)
.setMIFlag(MachineInstr::FrameSetup);
}

View File

@ -73,6 +73,7 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM)
addRegisterClass(MVT::i16, &Teak::ABLRegsRegClass);
//addRegisterClass(MVT::i16, &Teak::ALRegsRegClass);
addRegisterClass(MVT::i16, &Teak::RegNoBRegs16_nohRegClass);
// addRegisterClass(MVT::i16, &Teak::RegNoBRegs16_noh_pageRegClass);
//addRegisterClass(MVT::i16, &Teak::Y0RegsRegClass);
//addRegisterClass(MVT::i32, &Teak::P0RegsRegClass);
//addRegisterClass(MVT::i16, &Teak::ABHRegsRegClass);
@ -99,6 +100,7 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM)
setOperationAction(ISD::ADD, MVT::i16, Custom);
setOperationAction(ISD::SUB, MVT::i16, Custom);
setOperationAction(ISD::MUL, MVT::i16, Custom);
setOperationAction(ISD::AND, MVT::i16, Custom);
setOperationAction(ISD::AND, MVT::i40, Custom);
setOperationAction(ISD::XOR, MVT::i16, Custom);
@ -240,36 +242,35 @@ bool TeakTargetLowering::isNarrowingProfitable(EVT VT1, EVT VT2) const
bool TeakTargetLowering::getPostIndexedAddressParts(SDNode* N, SDNode* Op,
SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const
{
SDLoc DL(N);
const LoadSDNode* ld = dyn_cast<LoadSDNode>(N);
const StoreSDNode* st = dyn_cast<StoreSDNode>(N);
if (!(ld && ld->getMemoryVT() == MVT::i16) && !(st && st->getMemoryVT() == MVT::i16))
return false;
if (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB)
return false;
if (const ConstantSDNode* rhs = dyn_cast<ConstantSDNode>(Op->getOperand(1)))
{
int rhsc = rhs->getSExtValue();
if (Op->getOpcode() == ISD::SUB)
rhsc = -rhsc;
if (rhsc != 1 && rhsc != -1)
return false;
Base = Op->getOperand(0);
Offset = DAG.getConstant(rhsc, DL, MVT::i16);
AM = ISD::POST_INC;
return true;
}
// dbgs() << "getPostIndexedAddressParts\n";
// EVT VT;
// SDLoc DL(N);
// const LoadSDNode* ld = dyn_cast<LoadSDNode>(N);
// if (!ld)
// return false;
// if(ld->getMemoryVT() != MVT::i16)
// return false;
// if (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB)
// return false;
// if (const ConstantSDNode* rhs = dyn_cast<ConstantSDNode>(Op->getOperand(1)))
// {
// int rhsc = rhs->getSExtValue();
// if (Op->getOpcode() == ISD::SUB)
// rhsc = -rhsc;
// if (rhsc != 1 && rhsc != -1)
// return false;
// Base = Op->getOperand(0);
// Offset = DAG.getConstant(rhsc, DL, MVT::i16);
// AM = ISD::POST_INC;
// return true;
// }
// // dbgs() << "getPostIndexedAddressParts\n";
// // EVT VT;
// // SDLoc DL(N);
// // Op->dump();
// // N->dump();
// return false;
// Op->dump();
// N->dump();
return false;
}
bool TeakTargetLowering::allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace,
@ -376,10 +377,10 @@ SDValue TeakTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
SDValue CompareFlag;
if (LHS.getValueType().isInteger())
{
CompareFlag = DAG.getNode(TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS);
Opc = TeakISD::SELECT_ICC;
if (SPCC == ~0U)
SPCC = IntCondCCodeToICC(CC);
CompareFlag = DAG.getNode((SPCC == TeakCC::Eq || SPCC == TeakCC::Neq) ? TeakISD::CMPZICC : TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS);
}
else
llvm_unreachable("!LHS.getValueType().isInteger()");
@ -415,10 +416,10 @@ SDValue TeakTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
SDValue CompareFlag;
if (LHS.getValueType().isInteger())
{
CompareFlag = DAG.getNode(TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS);
if (SPCC == ~0U)
SPCC = IntCondCCodeToICC(CC);
// 32-bit compares use the icc flags, 64-bit uses the xcc flags.
CompareFlag = DAG.getNode((SPCC == TeakCC::Eq || SPCC == TeakCC::Neq) ? TeakISD::CMPZICC : TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS);
Opc = TeakISD::BRICC;
}
else
@ -454,13 +455,9 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
const SDNode *N = Op.getNode();
SDLoc dl(N);
assert(N->getValueType(0) == MVT::i16 && "Unexpected custom legalisation");
//this seems to give problems for some reason
// if(isa<ConstantSDNode>(N->getOperand(1)))
// {
// dbgs() << "constant!\n";
// return Op;
// }
//dbgs() << "Lowering!\n";
if(isa<ConstantSDNode>(N->getOperand(1)))
return DAG.getNode(Op.getOpcode(), dl, MVT::i16, N->getOperand(0), N->getOperand(1));
SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i40, N->getOperand(0));
SDValue NewOp1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i40, N->getOperand(1));
SDValue NewWOp = DAG.getNode(Op.getOpcode(), dl, MVT::i40, NewOp0, NewOp1);
@ -495,6 +492,13 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
SDValue NewWOp = DAG.getNode(nodeType, dl, MVT::i40, NewOp0, NewOp1);
return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, NewWOp);
}
case ISD::MUL:
{
const SDNode *N = Op.getNode();
SDLoc dl(N);
assert(N->getValueType(0) == MVT::i16 && "Unexpected custom legalisation");
return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, DAG.getNode(TeakISD::MPY, dl, MVT::i40, N->getOperand(0), N->getOperand(1)));
}
case ISD::SHL:
{
const SDNode *N = Op.getNode();

View File

@ -36,6 +36,7 @@ enum NodeType {
MOVEi32,
CALL,
CMPICC,
CMPZICC,
BRICC,
SELECT_ICC,
WRAPPER,
@ -43,7 +44,10 @@ enum NodeType {
SHIFT_LOGIC,
AND,
OR,
XOR
XOR,
ADD,
SUB,
MPY
};
}

View File

@ -287,12 +287,42 @@ void TeakInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
{
MachineFunction &MF = *MBB.getParent();
const TeakSubtarget &st = MF.getSubtarget<TeakSubtarget>();
const TargetRegisterInfo *RegInfo = st.getRegisterInfo();
bool keepFlags = MBB.computeRegisterLiveness(RegInfo, Teak::ICC, I) != MachineBasicBlock::LQR_Dead;
dbgs() << "copyPhysReg(" << SrcReg.id() << ", " << DestReg.id() << ")\n";
unsigned op;
// if(Teak::ABLRegsRegClass.contains(DestReg))
// {
// // unsigned fullDst = teakGetAbReg(DestReg.id());
// // unsigned hiDst = teakGetAbHReg(fullDst);
// // //special handling for subreg copies, which cannot be done directly
// // // if(keepFlags)
// // // BuildMI(MBB, I, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
// // // BuildMI(MBB, I, DL, get(Teak::RST_imm16_regnob16), DestReg)
// // // .addImm(0xFFFF)
// // // .addReg(DestReg);
// // // if(keepFlags)
// // // BuildMI(MBB, I, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
// // bool hiAlive = MBB.computeRegisterLiveness(RegInfo, hiDst, I) != MachineBasicBlock::LQR_Dead;
// // dbgs() << "Hi dst alive: " << hiAlive << "\n";
// // if(hiAlive)
// // {
// llvm_unreachable("Invalid low destination register!");
// return;
// // }
// }
// else if(Teak::ABHRegsRegClass.contains(DestReg))
// {
// llvm_unreachable("Invalid high destination register!");
// return;
// }
// if(Teak::ARegsRegClass.contains(SrcReg) && Teak::ARegsRegClass.contains(DestReg) && SrcReg != DestReg)
// op = Teak::COPY_a;
// else
if(Teak::ABRegsRegClass.contains(SrcReg) && Teak::ABRegsRegClass.contains(DestReg))
if(Teak::ARegsRegClass.contains(SrcReg) && Teak::ARegsRegClass.contains(DestReg))
op = Teak::COPY_a;
else if(Teak::ABRegsRegClass.contains(SrcReg) && Teak::ABRegsRegClass.contains(DestReg))
op = Teak::MOV_ab_ab;
else if(Teak::RegNoBRegs16RegClass.contains(SrcReg) && Teak::RegNoBRegs40RegClass.contains(DestReg))
op = Teak::MOV_regnobp016_abl;
@ -305,9 +335,15 @@ void TeakInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
else
assert(0 && "Unimplemented copyPhysReg");
const TargetRegisterInfo *RegInfo = st.getRegisterInfo();
if (MBB.computeRegisterLiveness(RegInfo, Teak::ICC, I) == MachineBasicBlock::LQR_Dead)
if (!keepFlags)
{
if (op == Teak::COPY_a)
BuildMI(MBB, I, DL, get(op), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc))
.addImm(TeakCC::True)
->addRegisterDead(Teak::ICC, RegInfo);
else
BuildMI(MBB, I, DL, get(op), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc))
->addRegisterDead(Teak::ICC, RegInfo);
@ -315,6 +351,11 @@ void TeakInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
else
{
BuildMI(MBB, I, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if (op == Teak::COPY_a)
BuildMI(MBB, I, DL, get(op), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc))
.addImm(TeakCC::True);
else
BuildMI(MBB, I, DL, get(op), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc));
BuildMI(MBB, I, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
@ -457,6 +498,29 @@ bool TeakInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TBB, unsigned TCycles
return true;
}
void TeakInstrInfo::makeRnRegDisplacement(MachineBasicBlock& mbb, MachineInstr& mi, const DebugLoc& dl, Register reg, signed short offset) const
{
if(offset == 0)
return;
if(offset == 1)
BuildMI(mbb, mi, dl, get(Teak::MODR_inc1), reg)
.addReg(reg);
else if(offset == -1)
BuildMI(mbb, mi, dl, get(Teak::MODR_dec1), reg)
.addReg(reg);
else if(offset == 2)
BuildMI(mbb, mi, dl, get(Teak::MODR_inc2), reg)
.addReg(reg);
else if(offset == -2)
BuildMI(mbb, mi, dl, get(Teak::MODR_dec2), reg)
.addReg(reg);
else
BuildMI(mbb, mi, dl, get(Teak::ADDV_imm16_RegNoBRegs16), reg)
.addImm(offset)
.addReg(reg);
}
bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
{
DebugLoc DL = MI.getDebugLoc();
@ -473,20 +537,14 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
case Teak::STORE_REG_TO_STACK_PSEUDO_16:
{
dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_16\n";
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2;
signed short frameOffset = (signed short)MI.getOperand(2).getImm();
if(keepFlags && frameOffset)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn))
.addReg(MI.getOperand(0).getReg(), getKillRegState(MI.getOperand(0).isKill()))
.addReg(MI.getOperand(1).getReg());
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(-frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
if(keepFlags && frameOffset)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
MBB.erase(MI);
@ -497,29 +555,15 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
{
dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_TRUNC16\n";
unsigned srcReg = MI.getOperand(0).getReg();
unsigned loReg;
if(srcReg == Teak::A0)
loReg = Teak::A0L;
else if(srcReg == Teak::A1)
loReg = Teak::A1L;
else if(srcReg == Teak::B0)
loReg = Teak::B0L;
else if(srcReg == Teak::B1)
loReg = Teak::B1L;
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2;
unsigned loReg = teakGetAbLReg(srcReg);
signed short frameOffset = (signed short)MI.getOperand(2).getImm();
if(keepFlags && frameOffset)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn))
.addReg(loReg, getKillRegState(MI.getOperand(0).isKill()))
.addReg(MI.getOperand(1).getReg());
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(-frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
if(keepFlags && frameOffset)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
MBB.erase(MI);
@ -530,35 +574,12 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
{
dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_32\n";
unsigned srcReg = MI.getOperand(0).getReg();
unsigned loReg;
unsigned hiReg;
if(srcReg == Teak::A0)
{
loReg = Teak::A0L;
hiReg = Teak::A0H;
}
else if(srcReg == Teak::A1)
{
loReg = Teak::A1L;
hiReg = Teak::A1H;
}
else if(srcReg == Teak::B0)
{
loReg = Teak::B0L;
hiReg = Teak::B0H;
}
else if(srcReg == Teak::B1)
{
loReg = Teak::B1L;
hiReg = Teak::B1H;
}
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2;
unsigned loReg = teakGetAbLReg(srcReg);
unsigned hiReg = teakGetAbHReg(srcReg);
signed short frameOffset = (signed short)MI.getOperand(2).getImm();
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
if(loReg == Teak::A0L || loReg == Teak::A1L)
{
BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn))
@ -568,10 +589,7 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
.addReg(loReg, getKillRegState(MI.getOperand(0).isKill()))
.addReg(Teak::R7)
.addImm(-1);
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(-frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
}
else
{
@ -581,9 +599,7 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn))
.addReg(loReg, getKillRegState(MI.getOperand(0).isKill()))
.addReg(MI.getOperand(1).getReg());
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(-frameOffset + 1)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset + 1);
}
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
@ -595,7 +611,7 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
{
dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16\n";
unsigned dstReg = MI.getOperand(0).getReg();
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2;
signed short frameOffset = (signed short)MI.getOperand(2).getImm();
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(dstReg == Teak::A0L || dstReg == Teak::A1L)
@ -611,16 +627,10 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
}
else
{
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_regnob16), dstReg)
.addReg(MI.getOperand(1).getReg());
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(-frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
}
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
@ -632,7 +642,7 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
{
dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40\n";
unsigned dstReg = MI.getOperand(0).getReg();
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2;
signed short frameOffset = (signed short)MI.getOperand(2).getImm();
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(dstReg == Teak::A0 || dstReg == Teak::A1)
@ -648,16 +658,10 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
}
else
{
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab), dstReg)
.addReg(MI.getOperand(1).getReg());
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(-frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
}
@ -668,19 +672,13 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40:
{
dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40\n";
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2;
signed short frameOffset = (signed short)MI.getOperand(2).getImm();
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab1), MI.getOperand(0).getReg())
.addReg(MI.getOperand(1).getReg());
if(frameOffset)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg())
.addImm(-frameOffset)
.addReg(MI.getOperand(1).getReg());
makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
MBB.erase(MI);
@ -690,7 +688,7 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
{
dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40\n";
unsigned dstReg = MI.getOperand(0).getReg();
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2;
signed short frameOffset = (signed short)MI.getOperand(2).getImm();
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(dstReg == Teak::A0 || dstReg == Teak::A1)
@ -753,16 +751,49 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
MBB.erase(MI);
return true;
}
case Teak::MPY_y0_regnob16_RegNoBRegs16:
case Teak::MPYI_y0_imm8s_ab:
case Teak::MPYI_y0_imm8s_ab_ADD:
{
BuildMI(MBB, MI, DL, get(Teak::MPY_y0_regnob16), Teak::P0)
BuildMI(MBB, MI, DL, get(Teak::MPYI_y0_imm8s), Teak::P0)
.addReg(MI.getOperand(1).getReg())
.addReg(MI.getOperand(2).getReg());
BuildMI(MBB, MI, DL, get(Teak::MOV_p0_regnob16), MI.getOperand(0).getReg())
.addImm(MI.getOperand(2).getImm());
if (MI.getOpcode() == Teak::MPYI_y0_imm8s_ab_ADD)
BuildMI(MBB, MI, DL, get(Teak::ADD_px_ab), MI.getOperand(0).getReg())
.addReg(Teak::P0)
.addReg(MI.getOperand(0).getReg());
else
BuildMI(MBB, MI, DL, get(Teak::MOV_p0_ab), MI.getOperand(0).getReg())
.addReg(Teak::P0);
MBB.erase(MI);
return true;
}
case Teak::MPY_y0_regnob16_ab:
case Teak::MPY_y0_regnob16_ab_ADD:
{
BuildMI(MBB, MI, DL, get(Teak::MPY_y0_regnob16), Teak::P0)
.addReg(MI.getOperand(1).getReg())
.addReg(MI.getOperand(2).getReg());
if (MI.getOpcode() == Teak::MPY_y0_regnob16_ab_ADD)
BuildMI(MBB, MI, DL, get(Teak::ADD_px_ab), MI.getOperand(0).getReg())
.addReg(Teak::P0)
.addReg(MI.getOperand(0).getReg());
else
BuildMI(MBB, MI, DL, get(Teak::MOV_p0_ab), MI.getOperand(0).getReg())
.addReg(Teak::P0);
MBB.erase(MI);
return true;
}
// case Teak::MPY_y0_regnob16_RegNoBRegs16:
// {
// BuildMI(MBB, MI, DL, get(Teak::MPY_y0_regnob16), Teak::P0)
// .addReg(MI.getOperand(1).getReg())
// .addReg(MI.getOperand(2).getReg());
// BuildMI(MBB, MI, DL, get(Teak::MOV_p0_regnob16), MI.getOperand(0).getReg())
// .addReg(Teak::P0);
// MBB.erase(MI);
// return true;
// }
// case Teak::SHL_PSEUDO_ab_ab_sv:
// {
// BuildMI(MBB, MI, DL, get(Teak::MOV_regnobp016_regnob16), Teak::SV)

View File

@ -26,6 +26,8 @@ class TeakInstrInfo : public TeakGenInstrInfo {
const TeakRegisterInfo RI;
virtual void anchor();
void makeRnRegDisplacement(MachineBasicBlock& mbb, MachineInstr& mi, const DebugLoc& dl, Register reg, signed short offset) const;
public:
TeakInstrInfo();

View File

@ -1,6 +1,11 @@
include "TeakInstrFormats.td"
include "TeakOperators.td"
// An 'and' node with a single use.
// def and_su : PatFrag<(ops node:$lhs, node:$rhs), (TeakAnd node:$lhs, node:$rhs), [{
// return N->hasOneUse();
// }]>;
//def : Pattern<(i32 (load_sym tglobaladdr:$addr)), [(MOVi32 $addr)]>;
// def MOVi32 : InstTeak<(outs BRegs:$dst), (ins i32imm:$src), "",
@ -50,6 +55,13 @@ def Imm8u_16 : Operand<i16>, ImmLeaf<i16, [{
let ParserMatchClass = Imm8u_16AsmOperand;
}
def Imm8s_16AsmOperand: ImmAsmOperand<-128,127> { let Name = "Imm8s_16"; }
def Imm8s_16 : Operand<i16>, ImmLeaf<i16, [{
return Imm >= -128 && Imm <= 127;
}]> {
let ParserMatchClass = Imm8s_16AsmOperand;
}
def Imm0_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; }
def imm0_65535 : Operand<i40>, ImmLeaf<i40, [{
return Imm >= 0 && Imm < 65536;
@ -147,6 +159,34 @@ def load_postdec : PatFrag<(ops node:$base),
let IsNonExtLoad = 1;
}
def store_postinc : PatFrag<(ops node:$val, node:$base),
(st node:$val, node:$base), [{
const StoreSDNode* st = cast<StoreSDNode>(N);
ISD::MemIndexedMode idxMode = st->getAddressingMode();
if (idxMode != ISD::POST_INC && idxMode != ISD::POST_DEC)
return false;
int offs = cast<ConstantSDNode>(st->getOffset())->getSExtValue();
return (idxMode == ISD::POST_INC && offs == 1) || (idxMode == ISD::POST_DEC && offs == -1);
}]>{
let IsStore = 1;
let IsUnindexed = 0;
let IsTruncStore = 0;
}
def store_postdec : PatFrag<(ops node:$val, node:$base),
(st node:$val, node:$base), [{
const StoreSDNode* st = cast<StoreSDNode>(N);
ISD::MemIndexedMode idxMode = st->getAddressingMode();
if (idxMode != ISD::POST_INC && idxMode != ISD::POST_DEC)
return false;
int offs = cast<ConstantSDNode>(st->getOffset())->getSExtValue();
return (idxMode == ISD::POST_INC && offs == -1) || (idxMode == ISD::POST_DEC && offs == 1);
}]>{
let IsStore = 1;
let IsUnindexed = 0;
let IsTruncStore = 0;
}
def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm), (ops (i32 0), (i32 zero_reg))>
{
let PrintMethod = "printCondCode";
@ -168,54 +208,78 @@ def MemR0425 : RegisterOperand<RegR0425>
// "addv $val, [$addr]",
// [(store (add (load GRRegs:$addr), immNeg32768_32767_16:$val), GRRegs:$addr)]>;
def NOP : InstTeak<(outs), (ins), "nop", []>;
let Defs = [ICC] in
{
let isCommutable = 1, mayStore = 1, mayLoad = 1 in
def ADDV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767_16:$val, GRRegs:$addr), "addv $val, [$addr]", [(store (add (i16 (load GRRegs:$addr)), immNeg32768_32767_16:$val), GRRegs:$addr)]>;
let mayLoad = 1 in
def TST0_imm16_memrn : InstTeakImm16<(outs), (ins imm0_65535_16:$val, GRRegs:$addr), "tst0 $val, [$addr]", [(TeakCmpzICC (i40 (sext (TeakAnd (i16 (load GRRegs:$addr)), imm0_65535_16:$val))), 0)]>;
def TST0_imm16_RegNoBRegs16 : InstTeakImm16<(outs), (ins imm0_65535_16:$val, RegNoBRegs16:$a), "tst0 $val, $a", [(TeakCmpzICC (i40 (sext (TeakAnd RegNoBRegs16:$a, imm0_65535_16:$val))), 0)]>;
// let isCommutable = 1, mayStore = 1, mayLoad = 1 in
// def ADDV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, GRRegs:$addr), "addv $val, [$addr]", [(store (i16 (trunc (add (anyext (i16 (load GRRegs:$addr))), immNeg32768_32767:$val))), GRRegs:$addr)]>;
// let mayStore = 1, mayLoad = 1 in
// def SUBV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, GRRegs:$addr), "subv $val, [$addr]", [(store (i16 (trunc (sub (anyext (i16 (load GRRegs:$addr))), immNeg32768_32767:$val))), GRRegs:$addr)]>;
let mayStore = 1, mayLoad = 1 in
{
def ADDV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767_16:$val, GRRegs:$addr), "addv $val, [$addr]", [(store (add (i16 (load GRRegs:$addr)), immNeg32768_32767_16:$val), GRRegs:$addr)]>;
def SUBV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767_16:$val, GRRegs:$addr), "subv $val, [$addr]", [(store (sub (i16 (load GRRegs:$addr)), immNeg32768_32767_16:$val), GRRegs:$addr)]>;
}
let Constraints = "$dst = $a", isCommutable = 1 in
// let isCommutable = 1, mayStore = 1, mayLoad = 1 in
// def ADDV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767_16:$val, GRRegs:$addr), "addv $val, [$addr]", [(store (add (i16 (load GRRegs:$addr)), immNeg32768_32767_16:$val), GRRegs:$addr)]>;
// let mayStore = 1, mayLoad = 1 in
// def SUBV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767_16:$val, GRRegs:$addr), "subv $val, [$addr]", [(store (sub (i16 (load GRRegs:$addr)), immNeg32768_32767_16:$val), GRRegs:$addr)]>;
let Constraints = "$dst = $a" in
{
def MODR_inc1 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr [${a}++]", [(set GRRegs:$dst, (add GRRegs:$a, 1))]>;
def MODR_dec1 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr [${a}--]", [(set GRRegs:$dst, (add GRRegs:$a, -1))]>;
def MODR_inc2 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr ${a}, +2", [(set GRRegs:$dst, (add GRRegs:$a, 2))]>;
def MODR_dec2 : InstTeak<(outs GRRegs:$dst), (ins GRRegs:$a), "modr ${a}, -2", [(set GRRegs:$dst, (add GRRegs:$a, -2))]>;
}
let Constraints = "$dst = $a" in
def ADDV_imm16_RegNoBRegs16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins immNeg32768_32767_16:$val, RegNoBRegs16:$a), "addv $val, $a", [(set RegNoBRegs16:$dst, (add RegNoBRegs16:$a, immNeg32768_32767_16:$val))]>;
// let Constraints = "$dst = $a", isCommutable = 1 in
// def ADDV_imm16_RegNoBRegs16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins immNeg32768_32767:$val, RegNoBRegs16:$a), "addv $val, $a", [(set RegNoBRegs16:$dst, (trunc (add (anyext RegNoBRegs16:$a), immNeg32768_32767:$val)))]>;
let Constraints = "$dst = $a" in
def SUBV_imm16_RegNoBRegs16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins immNeg32768_32767_16:$val, RegNoBRegs16:$a), "subv $val, $a", [(set RegNoBRegs16:$dst, (sub RegNoBRegs16:$a, immNeg32768_32767_16:$val))]>;
let Constraints = "$dst = $a", isCommutable = 1 in
// let Constraints = "$dst = $a" in
// def SUBV_imm16_RegNoBRegs16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins immNeg32768_32767:$val, RegNoBRegs16:$a), "subv $val, $a", [(set RegNoBRegs16:$dst, (trunc (sub (anyext RegNoBRegs16:$a), immNeg32768_32767:$val)))]>;
let Constraints = "$dst = $a" in
{
def INC_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "inc $a, $p", [(set ARegs:$dst, (add ARegs:$a, 1))]>;
let Constraints = "$dst = $a", isCommutable = 1 in
def DEC_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "dec $a, $p", [(set ARegs:$dst, (add ARegs:$a, -1))]>;
let Constraints = "$dst = $a", isCommutable = 1 in
def RND_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "rnd $a, $p", [(set ARegs:$dst, (add ARegs:$a, 0x8000))]>;
let Constraints = "$dst = $a", isCommutable = 1 in
def ADD_imm8u_a : InstTeak<(outs ARegs:$dst), (ins Imm8u:$val, ARegs:$a), "add ${val}u8, $a", [(set ARegs:$dst, (add ARegs:$a, Imm8u:$val))]>;
let Constraints = "$dst = $a", isCommutable = 1 in
def ADD_imm16_a : InstTeakImm16<(outs ARegs:$dst), (ins immNeg32768_32767:$val, ARegs:$a), "add $val, $a", [(set ARegs:$dst, (add ARegs:$a, immNeg32768_32767:$val))]>;
let Constraints = "$dst = $a", isCommutable = 1, mayLoad = 1 in
let mayLoad = 1 in
{
def ADD_memimm16_a : InstTeakImm16<(outs ARegs:$dst), (ins Operand<i16>:$addr, ARegs:$a), "add [$addr], $a", [(set ARegs:$dst, (add ARegs:$a, (sextloadi16 imm:$addr)))]>;
let Constraints = "$dst = $a", isCommutable = 1, mayLoad = 1 in
def ADD_memrn_a : InstTeak<(outs ARegs:$dst), (ins GRRegs:$addr, ARegs:$a), "add [$addr], $a", [(set ARegs:$dst, (add ARegs:$a, (sextloadi16 GRRegs:$addr)))]>;
let Constraints = "$dst = $a", mayLoad = 1 in
def ADDL_memrn_a : InstTeak<(outs ARegs:$dst), (ins GRRegs:$addr, ARegs:$a), "addl [$addr], $a", [(set ARegs:$dst, (add ARegs:$a, (zextloadi16 GRRegs:$addr)))]>;
}
let Constraints = "$dst = $a" in
def ADD_regnobp016_a : InstTeak<(outs ARegs:$dst), (ins RegNoBRegs16:$nob, ARegs:$a), "add $nob, $a", [(set ARegs:$dst, (add ARegs:$a, (sext RegNoBRegs16:$nob)))]>;
let Constraints = "$dst = $a" in
def ADDL_regnob16_a : InstTeak<(outs ARegs:$dst), (ins RegNoBRegs16:$nob, ARegs:$a), "addl $nob, $a", [(set ARegs:$dst, (add ARegs:$a, (zext RegNoBRegs16:$nob)))]>;
let Constraints = "$dst = $a", isCommutable = 1 in
let isCommutable = 1 in
def ADD_ab_ab : InstTeak<(outs ABRegs:$dst), (ins ABRegs:$b, ABRegs:$a), "add $b, $a", [(set ABRegs:$dst, (add ABRegs:$a, ABRegs:$b))]>;
def ADD_px_ab : InstTeak<(outs ABRegs:$dst), (ins PRegs:$b, ABRegs:$a), "add $b, $a", []>;
}
//this does not give the expected result, it is actually
//a = a & (0xFF00 | val)
// let Defs = [ICC], Constraints = "$dst = $a" in
@ -290,11 +354,15 @@ let Defs = [ICC] in
def XOR_imm16_a : InstTeakImm16<(outs ARegs:$dst), (ins imm0_65535:$val, ARegs:$a), "xor $val, $a", [(set ARegs:$dst, (TeakXor ARegs:$a, imm0_65535:$val))]>;
def XOR_regnobp016_a : InstTeak<(outs ARegs:$dst), (ins RegNoBRegs16:$b, ARegs:$a), "xor $b, $a", [(set ARegs:$dst, (TeakXor ARegs:$a, (zext RegNoBRegs16:$b)))]>;
// def XOR_regnobp016_al : InstTeak<(outs ALRegs:$dst), (ins RegNoBRegs16:$b, ALRegs:$a), "xor $b, $a", [(set ALRegs:$dst, (TeakXor ALRegs:$a, RegNoBRegs16:$b))]>;
let isCommutable = 1 in
def XOR_a_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$b, ARegs:$a), "xor $b, $a", [(set ARegs:$dst, (TeakXor ARegs:$a, ARegs:$b))]>;
}
let isCommutable = 1 in
{
def AND_ab_ab_a : InstTeak<(outs ARegs:$dst), (ins ABRegs:$b, ABRegs:$a), "and $b, $a, $dst", [(set ARegs:$dst, (TeakAnd ABRegs:$a, ABRegs:$b))]>;
def OR_ab_ab_a : InstTeak<(outs ARegs:$dst), (ins ABRegs:$b, ABRegs:$a), "or $b, $a, $dst", [(set ARegs:$dst, (TeakOr ABRegs:$a, ABRegs:$b))]>;
}
let isMoveImm = 1 in
{
@ -304,6 +372,8 @@ let Defs = [ICC] in
def MOV_imm16neg_ab : InstTeakImm16<(outs ABRegs:$dst), (ins immNeg32768_32767:$val), "mov $val, $dst", [(set ABRegs:$dst, immNeg32768_32767:$val)]>;
def MOV_imm16_ab : InstTeakImm16<(outs ABRegs:$dst), (ins imm0_65535:$val), "mov $val, ${dst}l", [(set ABRegs:$dst, imm0_65535:$val)]>;
def MOV_imm16_abh : InstTeakImm16<(outs ABRegs:$dst), (ins immUpper16Signed:$val), "mov $val, ${dst}h", [(set ABRegs:$dst, immUpper16Signed:$val)]>;
def MOV_imm8s : InstTeak<(outs MovImm8sRegs:$dst), (ins Imm8s_16:$val), "mov ${val}s8, $dst", []>;
def MOV_imm8u : InstTeak<(outs ALRegs:$dst), (ins Imm8u_16:$val), "mov ${val}u8, $dst", []>;
}
let isMoveReg = 1 in
@ -312,7 +382,7 @@ let Defs = [ICC] in
def COPY_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$src, pred:$p), "copy $dst, $p", []>;
def MOV_ab_ab : InstTeak<(outs ABRegs:$dst), (ins ABRegs:$src), "mov $src, $dst", [/*(set ABRegs:$dst, ABRegs:$src)*/]>;
def MOV_regnobp016_regnob16 : InstTeak<(outs RegNoBRegs16:$dst), (ins RegNoBRegs16:$src), "mov $src, $dst", [/*(set RegNoBRegs16:$dst, RegNoBRegs16:$src)*/]>;
def MOV_p0_regnob16 : InstTeak<(outs RegNoBRegs16:$dst), (ins P0Regs:$src), "mov $src, $dst", [/*(set RegNoBRegs16:$dst, RegNoBRegs16:$src)*/]>;
//def MOV_p0_regnob16 : InstTeak<(outs RegNoBRegs16:$dst), (ins P0Regs:$src), "mov $src, $dst", [/*(set RegNoBRegs16:$dst, RegNoBRegs16:$src)*/]>;
def MOV_regnobp016_ab : InstTeak<(outs ABRegs:$dst), (ins RegNoBRegs16:$src), "mov $src, $dst", [(set ABRegs:$dst, (sext RegNoBRegs16:$src))]>;
def MOV_p0_ab : InstTeak<(outs ABRegs:$dst), (ins P0Regs:$src), "mov $src, $dst", [/*(set ABRegs:$dst, (sext P0Regs:$src))*/]>;
def MOV_regnobp016_abl : InstTeak<(outs ABRegs:$dst), (ins RegNoBRegs16:$src), "mov $src, ${dst}l", [(set ABRegs:$dst, (zext RegNoBRegs16:$src))]>;
@ -323,10 +393,20 @@ let Defs = [ICC] in
def SHFC_arith_ab_ab_sv : InstTeak<(outs ABRegs:$dst), (ins ABRegs:$src, SVReg:$shift, pred:$p), "shfc $src, $dst, $p", [(set ABRegs:$dst, (TeakShiftArith ABRegs:$src, SVReg:$shift))]>;
def SHFC_logic_ab_ab_sv : TeakPseudoInst<(outs ABRegs:$dst), (ins ABRegs:$src, SVReg:$shift, pred:$p), "shfc $src, $dst, $p", [(set ABRegs:$dst, (TeakShiftLogic ABRegs:$src, SVReg:$shift))]>;
let Defs = [ICC, X0, P0] in
{
def MPYI_y0_imm8s : InstTeak<(outs P0Regs:$p), (ins Y0Regs:$y, Imm8s_16:$x), "mpyi $y, $x", []>;
def MPY_y0_regnob16 : InstTeak<(outs P0Regs:$p), (ins Y0Regs:$y, RegNoBRegs16:$x), "mpy $y, $x", []>;
let Defs = [ICC, P0] in
def MPY_y0_regnob16_RegNoBRegs16 : TeakPseudoInst<(outs RegNoBRegs16:$dst), (ins Y0Regs:$y, RegNoBRegs16:$x), "mpy $y, $x", [(set RegNoBRegs16:$dst, (mul RegNoBRegs16:$x, Y0Regs:$y))]>;
let Constraints = "$dst = $ab" in
{
def MPYI_y0_imm8s_ab_ADD : TeakPseudoInst<(outs ABRegs:$dst), (ins Y0Regs:$y, Imm8s_16:$x, ABRegs:$ab), "MPYI_y0_imm8s_ab $y, $x, $ab", [(set ABRegs:$dst, (add ABRegs:$ab, (TeakMpy Y0Regs:$y, Imm8s_16:$x)))]>;
def MPY_y0_regnob16_ab_ADD : TeakPseudoInst<(outs ABRegs:$dst), (ins Y0Regs:$y, RegNoBRegs16:$x, ABRegs:$ab), "MPY_y0_regnob16_ab_ADD $y, $x, $ab", [(set ABRegs:$dst, (add ABRegs:$ab, (TeakMpy RegNoBRegs16:$x, Y0Regs:$y)))]>;
}
def MPYI_y0_imm8s_ab : TeakPseudoInst<(outs ABRegs:$dst), (ins Y0Regs:$y, Imm8s_16:$x), "MPYI_y0_imm8s_ab $y, $x, $dst", [(set ABRegs:$dst, (TeakMpy Y0Regs:$y, Imm8s_16:$x))]>;
def MPY_y0_regnob16_ab : TeakPseudoInst<(outs ABRegs:$dst), (ins Y0Regs:$y, RegNoBRegs16:$x), "MPY_y0_regnob16_ab $y, $x, $dst", [(set ABRegs:$dst, (TeakMpy RegNoBRegs16:$x, Y0Regs:$y))]>;
}
let Constraints = "$asrc = $bdst, $bsrc = $adst" in
def SWAP_ab : InstTeak<(outs BRegs:$adst, ARegs:$bdst), (ins ARegs:$asrc, BRegs:$bsrc), "swap ($asrc, $bsrc)", []>;
@ -384,7 +464,10 @@ let mayStore = 1 in
def MOV_regnob16_memrn : InstTeak<(outs), (ins RegNoBRegs16:$a, GRRegs:$dstAddr), "mov $a, [$dstAddr]", [(store RegNoBRegs16:$a, GRRegs:$dstAddr)]>;
let mayStore = 1, Constraints = "$dstAddr = $dstAddrOut" in
def MOV_regnob16_memrn_postdec : InstTeak<(outs GRRegs:$dstAddrOut), (ins RegNoBRegs16:$a, GRRegs:$dstAddr), "mov $a, [${dstAddr}--]", []>;
def MOV_regnob16_memrn_postinc : InstTeak<(outs GRRegs:$dstAddrOut), (ins RegNoBRegs16:$a, GRRegs:$dstAddr), "mov $a, [${dstAddr}++]", [(set GRRegs:$dstAddrOut, (store_postinc RegNoBRegs16:$a, GRRegs:$dstAddr))]>;
let mayStore = 1, Constraints = "$dstAddr = $dstAddrOut" in
def MOV_regnob16_memrn_postdec : InstTeak<(outs GRRegs:$dstAddrOut), (ins RegNoBRegs16:$a, GRRegs:$dstAddr), "mov $a, [${dstAddr}--]", [(set GRRegs:$dstAddrOut, (store_postdec RegNoBRegs16:$a, GRRegs:$dstAddr))]>;
let mayStore = 1 in
def MOV_abl_memrn : InstTeak<(outs), (ins ABRegs:$a, GRRegs:$dstAddr), "mov ${a}l, [$dstAddr]", [(truncstorei16 ABRegs:$a, GRRegs:$dstAddr)]>;
@ -392,8 +475,8 @@ def MOV_abl_memrn : InstTeak<(outs), (ins ABRegs:$a, GRRegs:$dstAddr), "mov ${a}
let Defs = [ICC], mayLoad = 1 in
def MOV_memrn_regnob16 : InstTeak<(outs RegNoBRegs16_nolh:$dst), (ins GRRegs:$srcAddr), "mov [$srcAddr], $dst", [(set RegNoBRegs16_nolh:$dst, (load GRRegs:$srcAddr))]>;
// let Defs = [ICC], mayLoad = 1, Constraints = "$srcAddr = $srcAddrOut" in
// def MOV_memrn_regnob16_postinc : InstTeak<(outs RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut), (ins GRRegs:$srcAddr), "mov [${srcAddr}++], $dst", [(set RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut, (load_postinc GRRegs:$srcAddr))]>;
let Defs = [ICC], mayLoad = 1, Constraints = "$srcAddr = $srcAddrOut" in
def MOV_memrn_regnob16_postinc : InstTeak<(outs RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut), (ins GRRegs:$srcAddr), "mov [${srcAddr}++], $dst", [(set RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut, (load_postinc GRRegs:$srcAddr))]>;
let Defs = [ICC], mayLoad = 1, Constraints = "$srcAddr = $srcAddrOut" in
def MOV_memrn_regnob16_postdec : InstTeak<(outs RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut), (ins GRRegs:$srcAddr), "mov [${srcAddr}--], $dst", [(set RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut, (load_postdec GRRegs:$srcAddr))]>;
@ -479,12 +562,14 @@ let Defs = [SP], Uses = [SP] in
def PUSH_regnob16 : InstTeak<(outs), (ins RegNoBRegs16:$reg), "push $reg", []>;
//def PUSH_px : InstTeak<(outs), (ins PRegs:$reg), "push $reg", []>;
def PUSH_ararpsttmod : InstTeak<(outs), (ins ArArpSttMod:$reg), "push $reg", []>;
def PUSH_abe : InstTeak<(outs), (ins ABERegs:$reg), "push $reg", []>;
}
let Defs = [SP, ICC], mayLoad = 1 in
{
def POP_regnob16 : InstTeak<(outs RegNoBRegs16_nolh:$reg), (ins), "pop $reg", []>;
//def POP_px : InstTeak<(outs PRegs:$reg), (ins), "pop $reg", []>;
def POP_ararpsttmod : InstTeak<(outs ArArpSttMod:$reg), (ins), "pop $reg", []>;
def POP_abe : InstTeak<(outs ABERegs:$reg), (ins), "pop $reg", []>;
}
}
@ -506,6 +591,16 @@ let isCompare = 1, Defs = [ICC] in
def CMP_ab_ab : InstTeak<(outs), (ins ABRegs:$b, ABRegs:$a), "cmp $b, $a", [(TeakCmpICC ABRegs:$a, ABRegs:$b)]>;
}
def : Pat<(TeakCmpzICC ARegs:$a, Imm8u:$val), (CMP_imm8u_a Imm8u:$val, ARegs:$a)>;
def : Pat<(TeakCmpzICC ARegs:$a, immNeg32768_32767:$val), (CMP_imm16_a immNeg32768_32767:$val, ARegs:$a)>;
def : Pat<(TeakCmpzICC (sext RegNoBRegs16:$a), immNeg32768_32767:$val), (CMPV_imm16_RegNoBRegs16 immNeg32768_32767:$val, RegNoBRegs16:$a)>;
def : Pat<(TeakCmpzICC ARegs:$a, (sextloadi16 imm:$addr)), (CMP_memimm16_a imm:$addr, ARegs:$a)>;
def : Pat<(TeakCmpzICC ARegs:$a, (sextloadi16 GRRegs:$addr)), (CMP_memrn_a GRRegs:$addr, ARegs:$a)>;
def : Pat<(TeakCmpzICC ARegs:$a, (zextloadi16 GRRegs:$addr)), (CMPU_memrn_a GRRegs:$addr, ARegs:$a)>;
def : Pat<(TeakCmpzICC ARegs:$a, (sext RegNoBRegs16:$b)), (CMP_regnobp016_a RegNoBRegs16:$b, ARegs:$a)>;
def : Pat<(TeakCmpzICC ARegs:$a, (zext RegNoBRegs16:$b)), (CMPU_regnob016_a RegNoBRegs16:$b, ARegs:$a)>;
def : Pat<(TeakCmpzICC ABRegs:$a, ABRegs:$b), (CMP_ab_ab ABRegs:$b, ABRegs:$a)>;
let Uses = [ICC], usesCustomInserter = 1 in
{
def SELECT_CC_Int_ICC : TeakPseudoInst<(outs ABRegs:$dst), (ins ABRegs:$T, ABRegs:$F, Operand<i40>:$Cond), "; SELECT_CC_Int_ICC PSEUDO!",
@ -555,6 +650,7 @@ def : Pat<(i40 (TeakOr ARegs:$a, (extloadi16 (TeakWrapper tglobaladdr:$src)))),
def : Pat<(i40 (TeakXor ARegs:$a, (zextloadi16 (TeakWrapper tglobaladdr:$src)))), (XOR_memimm16_a tglobaladdr:$src, ARegs:$a)>;
def : Pat<(i40 (TeakXor ARegs:$a, (extloadi16 (TeakWrapper tglobaladdr:$src)))), (XOR_memimm16_a tglobaladdr:$src, ARegs:$a)>;
def : Pat<(TeakCmpICC ARegs:$a, (i40 (sextloadi16 (TeakWrapper tglobaladdr:$src)))), (CMP_memimm16_a tglobaladdr:$src, ARegs:$a)>;
def : Pat<(TeakCmpzICC ARegs:$a, (i40 (sextloadi16 (TeakWrapper tglobaladdr:$src)))), (CMP_memimm16_a tglobaladdr:$src, ARegs:$a)>;
def : Pat<(store ALRegs:$src, (i16 (TeakWrapper tglobaladdr:$dst))), (MOV_al2_memimm16 ALRegs:$src, tglobaladdr:$dst)>;
def : Pat<(truncstorei16 ARegs:$src, (i16 (TeakWrapper tglobaladdr:$dst))), (MOV_al_memimm16 ARegs:$src, tglobaladdr:$dst)>;
def : Pat<(i40 (sextloadi16 (TeakWrapper tglobaladdr:$src))), (MOV_memimm16_a tglobaladdr:$src)>;

View File

@ -33,6 +33,9 @@ def SDT_TeakCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>;
def SDT_TeakCmpICC : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
def TeakCmpICC : SDNode<"TeakISD::CMPICC", SDT_TeakCmpICC, [SDNPOutGlue]>;
def SDT_TeakCmpzICC : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
def TeakCmpzICC : SDNode<"TeakISD::CMPZICC", SDT_TeakCmpzICC, [SDNPOutGlue]>;
def SDT_TeakSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i40>]>;
def TeakSelectICC : SDNode<"TeakISD::SELECT_ICC", SDT_TeakSelectCC, [SDNPInGlue]>;
@ -79,6 +82,9 @@ def TeakOr : SDNode<"TeakISD::OR", SDT_TeakOr>;
def SDT_TeakXor : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>]>;
def TeakXor : SDNode<"TeakISD::XOR", SDT_TeakXor>;
def SDT_TeakMpy : SDTypeProfile<1, 2, [SDTCisVT<0, i40>, SDTCisVT<1, i16>, SDTCisVT<2, i16>]>;
def TeakMpy : SDNode<"TeakISD::MPY", SDT_TeakMpy>;
// //===----------------------------------------------------------------------===//
// // Operand Definitions.
// //===----------------------------------------------------------------------===//

View File

@ -0,0 +1,93 @@
#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();
}

View File

@ -56,6 +56,10 @@ BitVector TeakRegisterInfo::getReservedRegs(const MachineFunction &MF) const
Reserved.set(Teak::PC);
Reserved.set(Teak::R7);
Reserved.set(Teak::LC);
Reserved.set(Teak::EXT0);
Reserved.set(Teak::EXT1);
Reserved.set(Teak::EXT2);
Reserved.set(Teak::EXT3);
return Reserved;
}
@ -127,6 +131,8 @@ unsigned TeakRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, Ma
return 4;
case Teak::RegNoBRegs16_nohRegClassID:
return 12;
case Teak::RegNoBRegs16_noh_pageRegClassID:
return 12 + 80;
}
}
@ -264,29 +270,36 @@ bool TeakRegisterInfo::shouldCoalesce(MachineInstr *MI, const TargetRegisterClas
dbgs() << "DstSubReg: " << DstSubReg << "\n";
dbgs() << "NewRC: " << NewRC->getID() << "\n";
if (SrcRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
DstRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
NewRC->hasSuperClassEq(&Teak::SVRegRegClass))
return false;
// if (SrcRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
// DstRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
// NewRC->hasSuperClassEq(&Teak::SVRegRegClass))
// return false;
if(DstSubReg == Teak::sub_16bit)
return true;
//if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass))
// if(DstSubReg == Teak::sub_16bit)
// return true;
// //if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass))
// // return true;
// if(SrcRC->hasSuperClassEq(&Teak::ABLRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass))
// return true;
if(SrcRC->hasSuperClassEq(&Teak::ABLRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass))
return true;
if(SrcRC->hasSuperClassEq(&Teak::ABRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass))
return true;
//return true;//false;
if(SrcRC->hasSuperClassEq(&Teak::ARegsRegClass) && DstRC->hasSuperClassEq(&Teak::ARegsRegClass) && NewRC->hasSuperClassEq(&Teak::ARegsRegClass))
return true;
if(SrcRC->hasSuperClassEq(&Teak::ALRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ALRegsRegClass))
return true;
// if(SrcRC->hasSuperClassEq(&Teak::ABRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass))
// return true;
// //return true;//false;
// if(SrcRC->hasSuperClassEq(&Teak::ARegsRegClass) && DstRC->hasSuperClassEq(&Teak::ARegsRegClass) && NewRC->hasSuperClassEq(&Teak::ARegsRegClass))
// return true;
// if(SrcRC->hasSuperClassEq(&Teak::ALRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ALRegsRegClass))
// return true;
if (DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) || NewRC->hasSuperClassEq(&Teak::ALRegsRegClass) ||
DstRC->hasSuperClassEq(&Teak::ARegsRegClass) || NewRC->hasSuperClassEq(&Teak::ARegsRegClass))
return false;
// if (DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) || NewRC->hasSuperClassEq(&Teak::ALRegsRegClass) ||
// DstRC->hasSuperClassEq(&Teak::ARegsRegClass) || NewRC->hasSuperClassEq(&Teak::ARegsRegClass))
// return false;
return true;
}
const TargetRegisterClass* TeakRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass* RC) const
{
//if (RC == &Teak::RegNoBRegs16RegClass)
// return &Teak::RegNoBRegs16_nolhRegClass;
return RC;
}

View File

@ -72,6 +72,8 @@ public:
unsigned DstSubReg,
const TargetRegisterClass *NewRC,
LiveIntervals &LIS) const override;
virtual const TargetRegisterClass* getCrossCopyRegClass(const TargetRegisterClass* RC) const override;
};
} // end namespace llvm

View File

@ -95,15 +95,111 @@ def MOD1 : TeakReg<0, "mod1">;
def MOD2 : TeakReg<0, "mod2">;
def MOD3 : TeakReg<0, "mod3">;
def EXT0 : TeakReg<0, "ext0">;
def EXT1 : TeakReg<0, "ext1">;
def EXT2 : TeakReg<0, "ext2">;
def EXT3 : TeakReg<0, "ext3">;
def ICC : TeakReg<0, "ICC">;//for flag setting ops, maybe rename
// Page registers: 80 fake registers that are actually in memory
// Since memory is as fast as the cpu, there's no performance difference
// between using those fake registers or real registers using the short
// 8 bit page addressing mode, given that an instruction supports this ofc
// The first 40 page registers are preserved over function calls
def PAGE0 : TeakReg<0, "[page:0x0000u8]">;
def PAGE1 : TeakReg<0, "[page:0x0001u8]">;
def PAGE2 : TeakReg<0, "[page:0x0002u8]">;
def PAGE3 : TeakReg<0, "[page:0x0003u8]">;
def PAGE4 : TeakReg<0, "[page:0x0004u8]">;
def PAGE5 : TeakReg<0, "[page:0x0005u8]">;
def PAGE6 : TeakReg<0, "[page:0x0006u8]">;
def PAGE7 : TeakReg<0, "[page:0x0007u8]">;
def PAGE8 : TeakReg<0, "[page:0x0008u8]">;
def PAGE9 : TeakReg<0, "[page:0x0009u8]">;
def PAGE10 : TeakReg<0, "[page:0x000Au8]">;
def PAGE11 : TeakReg<0, "[page:0x000Bu8]">;
def PAGE12 : TeakReg<0, "[page:0x000Cu8]">;
def PAGE13 : TeakReg<0, "[page:0x000Du8]">;
def PAGE14 : TeakReg<0, "[page:0x000Eu8]">;
def PAGE15 : TeakReg<0, "[page:0x000Fu8]">;
def PAGE16 : TeakReg<0, "[page:0x0010u8]">;
def PAGE17 : TeakReg<0, "[page:0x0011u8]">;
def PAGE18 : TeakReg<0, "[page:0x0012u8]">;
def PAGE19 : TeakReg<0, "[page:0x0013u8]">;
def PAGE20 : TeakReg<0, "[page:0x0014u8]">;
def PAGE21 : TeakReg<0, "[page:0x0015u8]">;
def PAGE22 : TeakReg<0, "[page:0x0016u8]">;
def PAGE23 : TeakReg<0, "[page:0x0017u8]">;
def PAGE24 : TeakReg<0, "[page:0x0018u8]">;
def PAGE25 : TeakReg<0, "[page:0x0019u8]">;
def PAGE26 : TeakReg<0, "[page:0x001Au8]">;
def PAGE27 : TeakReg<0, "[page:0x001Bu8]">;
def PAGE28 : TeakReg<0, "[page:0x001Cu8]">;
def PAGE29 : TeakReg<0, "[page:0x001Du8]">;
def PAGE30 : TeakReg<0, "[page:0x001Eu8]">;
def PAGE31 : TeakReg<0, "[page:0x001Fu8]">;
def PAGE32 : TeakReg<0, "[page:0x0020u8]">;
def PAGE33 : TeakReg<0, "[page:0x0021u8]">;
def PAGE34 : TeakReg<0, "[page:0x0022u8]">;
def PAGE35 : TeakReg<0, "[page:0x0023u8]">;
def PAGE36 : TeakReg<0, "[page:0x0024u8]">;
def PAGE37 : TeakReg<0, "[page:0x0025u8]">;
def PAGE38 : TeakReg<0, "[page:0x0026u8]">;
def PAGE39 : TeakReg<0, "[page:0x0027u8]">;
// The second 40 page registers are not preserved
def PAGE40 : TeakReg<0, "[page:0x0028u8]">;
def PAGE41 : TeakReg<0, "[page:0x0029u8]">;
def PAGE42 : TeakReg<0, "[page:0x002Au8]">;
def PAGE43 : TeakReg<0, "[page:0x002Bu8]">;
def PAGE44 : TeakReg<0, "[page:0x002Cu8]">;
def PAGE45 : TeakReg<0, "[page:0x002Du8]">;
def PAGE46 : TeakReg<0, "[page:0x002Eu8]">;
def PAGE47 : TeakReg<0, "[page:0x002Fu8]">;
def PAGE48 : TeakReg<0, "[page:0x0030u8]">;
def PAGE49 : TeakReg<0, "[page:0x0031u8]">;
def PAGE50 : TeakReg<0, "[page:0x0032u8]">;
def PAGE51 : TeakReg<0, "[page:0x0033u8]">;
def PAGE52 : TeakReg<0, "[page:0x0034u8]">;
def PAGE53 : TeakReg<0, "[page:0x0035u8]">;
def PAGE54 : TeakReg<0, "[page:0x0036u8]">;
def PAGE55 : TeakReg<0, "[page:0x0037u8]">;
def PAGE56 : TeakReg<0, "[page:0x0038u8]">;
def PAGE57 : TeakReg<0, "[page:0x0039u8]">;
def PAGE58 : TeakReg<0, "[page:0x003Au8]">;
def PAGE59 : TeakReg<0, "[page:0x003Bu8]">;
def PAGE60 : TeakReg<0, "[page:0x003Cu8]">;
def PAGE61 : TeakReg<0, "[page:0x003Du8]">;
def PAGE62 : TeakReg<0, "[page:0x003Eu8]">;
def PAGE63 : TeakReg<0, "[page:0x003Fu8]">;
def PAGE64 : TeakReg<0, "[page:0x0040u8]">;
def PAGE65 : TeakReg<0, "[page:0x0041u8]">;
def PAGE66 : TeakReg<0, "[page:0x0042u8]">;
def PAGE67 : TeakReg<0, "[page:0x0043u8]">;
def PAGE68 : TeakReg<0, "[page:0x0044u8]">;
def PAGE69 : TeakReg<0, "[page:0x0045u8]">;
def PAGE70 : TeakReg<0, "[page:0x0046u8]">;
def PAGE71 : TeakReg<0, "[page:0x0047u8]">;
def PAGE72 : TeakReg<0, "[page:0x0048u8]">;
def PAGE73 : TeakReg<0, "[page:0x0049u8]">;
def PAGE74 : TeakReg<0, "[page:0x004Au8]">;
def PAGE75 : TeakReg<0, "[page:0x004Bu8]">;
def PAGE76 : TeakReg<0, "[page:0x004Cu8]">;
def PAGE77 : TeakReg<0, "[page:0x004Du8]">;
def PAGE78 : TeakReg<0, "[page:0x004Eu8]">;
def PAGE79 : TeakReg<0, "[page:0x004Fu8]">;
// Register classes.
//
def GRRegs : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>;
def RegNoBRegs40 : RegisterClass<"Teak", [i40], 32, (add A0, A1)>;
def RegNoBRegs16 : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV)>;
def RegNoBRegs16_nolh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, LC, SV)>;
def RegNoBRegs16_noh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, A0L, A1L, B0L, B1L, LC, SV)>;
def RegNoBRegs16 : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV, EXT0, EXT1, EXT2, EXT3)>;
def RegNoBRegs16_nolh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, LC, SV, EXT0, EXT1, EXT2, EXT3)>;
def RegNoBRegs16_noh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, A0L, A1L, B0L, B1L, LC, SV, EXT0, EXT1, EXT2, EXT3)>;
def RegNoBRegs16_page : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV, EXT0, EXT1, EXT2, EXT3, (sequence "PAGE%u", 0, 79))>;
def RegNoBRegs16_noh_page : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, A0L, A1L, B0L, B1L, LC, SV, EXT0, EXT1, EXT2, EXT3, (sequence "PAGE%u", 0, 79))>;
def RegR0425 : RegisterClass<"Teak", [i16], 16, (add R0, R4, R2, R5)>;
//def RegNoBRegsP040 : RegisterClass<"Teak", [i40], 32, (add A0, A1)>;
//def RegNoBRegsP016 : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R7, Y0, /**/ SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV)>;
@ -112,12 +208,13 @@ def BRegs : RegisterClass<"Teak", [i40], 32, (add B0, B1)>;
def B0Reg : RegisterClass<"Teak", [i40], 32, (add B0)>;
def B1Reg : RegisterClass<"Teak", [i40], 32, (add B1)>;
def ABRegs : RegisterClass<"Teak", [i40], 32, (add A0, A1, B0, B1)>;
def ABLRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L, B0L, B1L)>;
def ALRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L)>;
// {
// let CopyCost = -1;
// }
def ABHRegs : RegisterClass<"Teak", [i16], 16, (add A0H, A1H, B0H, B1H)>;
let CopyCost = -1 in
{
def ABLRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L, B0L, B1L)>;
def ALRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L)>;
def ABHRegs : RegisterClass<"Teak", [i16], 16, (add A0H, A1H, B0H, B1H)>;
def ABERegs : RegisterClass<"Teak", [i8], 16, (add A0E, A1E, B0E, B1E)>;
}
def ArArpSttMod : RegisterClass<"Teak", [i16], 16, (add STT0)>;
def FP : RegisterClass<"Teak", [i16], 16, (add R7)>;
def Y0Regs : RegisterClass<"Teak", [i16], 16, (add Y0)>;
@ -129,3 +226,9 @@ def SVReg : RegisterClass<"Teak", [i16], 16, (add SV)>;
//def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>;
def SttModRegs : RegisterClass<"Teak", [i16], 16, (add STT0, STT1, STT2, MOD0, MOD1, MOD2, MOD3)>;
def MovImm8sRegs : RegisterClass<"Teak", [i16], 16, (add A0H, A1H, EXT0, EXT1, EXT2, EXT3, R0, R1, R2, R3, R4, R5, R7, Y0, SV)>;
def PAGERegs : RegisterClass<"Teak", [i16], 16, (add (sequence "PAGE%u", 0, 79))>;
def PAGESavedRegs : RegisterClass<"Teak", [i16], 16, (add (sequence "PAGE%u", 0, 39))>;
def PAGETrashedRegs : RegisterClass<"Teak", [i16], 16, (add (sequence "PAGE%u", 40, 79))>;

View File

@ -70,11 +70,16 @@ public:
};
} // namespace
TargetPassConfig *TeakTargetMachine::createPassConfig(PassManagerBase &PM) {
TargetPassConfig *TeakTargetMachine::createPassConfig(PassManagerBase &PM)
{
return new TeakPassConfig(*this, PM);
}
bool TeakPassConfig::addPreISel() { return false; }
bool TeakPassConfig::addPreISel()
{
addPass(createHardwareLoopsPass());
return false;
}
void TeakPassConfig::addPreSched2()
{
@ -90,6 +95,7 @@ bool TeakPassConfig::addInstSelector()
void TeakPassConfig::addPreEmitPass()
{
addPass(createTeakOptimizeMovImmPass());
addPass(&BranchRelaxationPassID);
}