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 TeakISelDAGToDAG.cpp
TeakAsmPrinter.cpp TeakAsmPrinter.cpp
TeakMCInstLower.cpp TeakMCInstLower.cpp
TeakOptimizeMovImmPass.cpp
) )
add_subdirectory(AsmParser) add_subdirectory(AsmParser)

View File

@ -4,4 +4,5 @@ add_llvm_component_library(LLVMTeakDesc
TeakMCCodeEmitter.cpp TeakMCCodeEmitter.cpp
TeakAsmBackend.cpp TeakAsmBackend.cpp
TeakELFObjectWriter.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::B1H: return 0x11;
case Teak::B0L: return 0x12; case Teak::B0L: return 0x12;
case Teak::B1L: return 0x13; case Teak::B1L: return 0x13;
//case Teak::EXT0: return 0x14; case Teak::EXT0: return 0x14;
//case Teak::EXT1: return 0x15; case Teak::EXT1: return 0x15;
//case Teak::EXT2: return 0x16; case Teak::EXT2: return 0x16;
//case Teak::EXT3: return 0x17; case Teak::EXT3: return 0x17;
case Teak::A0: return 0x18; case Teak::A0: return 0x18;
case Teak::A1: return 0x19; case Teak::A1: return 0x19;
case Teak::A0L: return 0x1A; case Teak::A0L: return 0x1A;
@ -175,10 +175,10 @@ static unsigned encodeRegisterP0Op(unsigned reg)
case Teak::B1H: return 0x11; case Teak::B1H: return 0x11;
case Teak::B0L: return 0x12; case Teak::B0L: return 0x12;
case Teak::B1L: return 0x13; case Teak::B1L: return 0x13;
//case Teak::EXT0: return 0x14; case Teak::EXT0: return 0x14;
//case Teak::EXT1: return 0x15; case Teak::EXT1: return 0x15;
//case Teak::EXT2: return 0x16; case Teak::EXT2: return 0x16;
//case Teak::EXT3: return 0x17; case Teak::EXT3: return 0x17;
case Teak::A0: return 0x18; case Teak::A0: return 0x18;
case Teak::A1: return 0x19; case Teak::A1: return 0x19;
case Teak::A0L: return 0x1A; 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) static unsigned encodeBxOp(unsigned reg)
{ {
switch (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) static unsigned encodeRnOp(unsigned reg)
{ {
switch (reg) switch (reg)
@ -377,6 +437,18 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::ADD_memrn_a: case Teak::ADD_memrn_a:
EmitConstant(0x8680 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS); EmitConstant(0x8680 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
break; 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: case Teak::ADDL_memrn_a:
EmitConstant(0x9480 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS); EmitConstant(0x9480 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS);
break; break;
@ -558,6 +630,18 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::INC_a: case Teak::INC_a:
EmitConstant(0x67D0 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS); EmitConstant(0x67D0 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS);
break; 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_imm16_regnob16:
case Teak::MOV_imm16neg_ab: case Teak::MOV_imm16neg_ab:
case Teak::MOV_imm16_ab: case Teak::MOV_imm16_ab:
@ -583,6 +667,35 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
} }
break; 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: case Teak::MOV_ab_ab:
EmitConstant(0xD290 | (encodeAbOp(MI.getOperand(1).getReg()) << 10) | (encodeAbOp(MI.getOperand(0).getReg()) << 5), 2, OS); EmitConstant(0xD290 | (encodeAbOp(MI.getOperand(1).getReg()) << 10) | (encodeAbOp(MI.getOperand(0).getReg()) << 5), 2, OS);
break; break;
@ -590,11 +703,14 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::MOV_regnobp016_ab: case Teak::MOV_regnobp016_ab:
case Teak::MOV_regnobp016_abl: case Teak::MOV_regnobp016_abl:
case Teak::MOV_p0_ab: case Teak::MOV_p0_ab:
case Teak::MOV_p0_regnob16:
{ {
unsigned dstReg = MI.getOperand(0).getReg(); unsigned dstReg = MI.getOperand(0).getReg();
if(MI.getOpcode() == Teak::MOV_regnobp016_abl) if(MI.getOpcode() == Teak::MOV_regnobp016_abl)
dstReg = teakGetAbLReg(dstReg); 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(MI.getOperand(1).getReg() == Teak::R6)
{ {
if(TeakMCRegisterClasses[Teak::BRegsRegClassID].contains(dstReg)) if(TeakMCRegisterClasses[Teak::BRegsRegClassID].contains(dstReg))
@ -614,12 +730,16 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
break; break;
} }
case Teak::MOV_regnob16_memrn: case Teak::MOV_regnob16_memrn:
case Teak::MOV_regnob16_memrn_postinc:
case Teak::MOV_regnob16_memrn_postdec: case Teak::MOV_regnob16_memrn_postdec:
case Teak::MOV_abl_memrn: case Teak::MOV_abl_memrn:
{ {
TeakStepZIDS::Steps step = TeakStepZIDS::Steps step = TeakStepZIDS::Zero;
MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec ? TeakStepZIDS::SubOne : TeakStepZIDS::Zero; if (MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec)
int opOffset = MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec ? 1 : 0; 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(); unsigned reg = MI.getOperand(opOffset).getReg();
if(MI.getOpcode() == Teak::MOV_abl_memrn) if(MI.getOpcode() == Teak::MOV_abl_memrn)
reg = teakGetAbLReg(reg); reg = teakGetAbLReg(reg);
@ -642,13 +762,17 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
break; break;
} }
case Teak::MOV_memrn_regnob16: case Teak::MOV_memrn_regnob16:
case Teak::MOV_memrn_regnob16_postinc:
case Teak::MOV_memrn_regnob16_postdec: case Teak::MOV_memrn_regnob16_postdec:
case Teak::MOV_memrn_ab: case Teak::MOV_memrn_ab:
case Teak::MOV_memrn_ab1: case Teak::MOV_memrn_ab1:
{ {
unsigned dstReg = MI.getOperand(0).getReg(); unsigned dstReg = MI.getOperand(0).getReg();
TeakStepZIDS::Steps step = TeakStepZIDS::Steps step = TeakStepZIDS::Zero;
MI.getOpcode() == Teak::MOV_memrn_regnob16_postdec ? TeakStepZIDS::SubOne : 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) if(MI.getOpcode() == Teak::MOV_memrn_ab1)
dstReg = teakGetAbLReg(dstReg); dstReg = teakGetAbLReg(dstReg);
if(dstReg == Teak::R6) if(dstReg == Teak::R6)
@ -693,6 +817,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
} }
break; break;
} }
case Teak::MPYI_y0_imm8s:
EmitConstant(0x0800 | (MI.getOperand(2).getImm() & 0xFF), 2, OS);
break;
case Teak::MPY_y0_regnob16: case Teak::MPY_y0_regnob16:
if(MI.getOperand(2).getReg() == Teak::R6) if(MI.getOperand(2).getReg() == Teak::R6)
EmitConstant(0x5EA0, 2, OS); EmitConstant(0x5EA0, 2, OS);
@ -702,6 +829,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::NEG_a: case Teak::NEG_a:
EmitConstant(0x6790 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS); EmitConstant(0x6790 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS);
break; break;
case Teak::NOP:
EmitConstant(0, 2, OS);
break;
case Teak::NOT_a: case Teak::NOT_a:
EmitConstant(0x6780 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS); EmitConstant(0x6780 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS);
break; break;
@ -888,6 +1018,17 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
EmitConstant(0x4980 | swapOp, 2, OS); EmitConstant(0x4980 | swapOp, 2, OS);
break; 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: case Teak::PUSH_regnob16:
{ {
unsigned reg = MI.getOperand(0).getReg(); unsigned reg = MI.getOperand(0).getReg();
@ -902,6 +1043,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::PUSH_ararpsttmod: case Teak::PUSH_ararpsttmod:
EmitConstant(0xD3D0 | encodeArArpSttModOp(MI.getOperand(0).getReg()), 2, OS); EmitConstant(0xD3D0 | encodeArArpSttModOp(MI.getOperand(0).getReg()), 2, OS);
break; break;
case Teak::PUSH_abe:
EmitConstant(0xD7C8 | (encodeAbeOp(MI.getOperand(0).getReg()) << 1), 2, OS);
break;
case Teak::POP_regnob16: case Teak::POP_regnob16:
{ {
unsigned reg = MI.getOperand(0).getReg(); unsigned reg = MI.getOperand(0).getReg();
@ -916,6 +1060,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
case Teak::POP_ararpsttmod: case Teak::POP_ararpsttmod:
EmitConstant(0x80C7 | (encodeArArpSttModOp(MI.getOperand(0).getReg()) << 8), 2, OS); EmitConstant(0x80C7 | (encodeArArpSttModOp(MI.getOperand(0).getReg()) << 8), 2, OS);
break; break;
case Teak::POP_abe:
EmitConstant(0x47B4 | encodeAbeOp(MI.getOperand(0).getReg()), 2, OS);
break;
case Teak::RET: case Teak::RET:
EmitConstant(0x4580 | MI.getOperand(0).getImm(), 2, OS); EmitConstant(0x4580 | MI.getOperand(0).getImm(), 2, OS);
break; 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 "../TargetInfo/TeakTargetInfo.h"
#include "llvm/MC/MCAsmBackend.h"
#include "TeakMCTargetDesc.h" #include "TeakMCTargetDesc.h"
#include "InstPrinter/TeakInstPrinter.h" #include "InstPrinter/TeakInstPrinter.h"
#include "TeakMCAsmInfo.h" #include "TeakMCAsmInfo.h"
#include "TeakELFStreamer.h"
//\#include "llvm/MC/MCCodeGenInfo.h" //\#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCStreamer.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/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h" #include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetRegistry.h"
@ -77,36 +69,45 @@ static MCAsmInfo *createTeakMCAsmInfo(const MCRegisterInfo &MRI,
// return X; // return X;
// } // }
static MCInstPrinter * static MCInstPrinter* createTeakMCInstPrinter(const Triple &TT, unsigned SyntaxVariant,
createTeakMCInstPrinter(const Triple &TT, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)
const MCAsmInfo &MAI, const MCInstrInfo &MII, {
const MCRegisterInfo &MRI) { return new TeakInstPrinter(MAI, MII, 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. // Force static initialization.
extern "C" void LLVMInitializeTeakTargetMC() { extern "C" void LLVMInitializeTeakTargetMC()
// Register the MC asm info. {
RegisterMCAsmInfoFn X(getTheTeakTarget(), createTeakMCAsmInfo); // Register the MC asm info.
RegisterMCAsmInfoFn X(getTheTeakTarget(), createTeakMCAsmInfo);
// Register the MC codegen info. // Register the MC codegen info.
//TargetRegistry::RegisterMCCodeGenInfo(getTheTeakTarget(), createTeakMCCodeGenInfo); //TargetRegistry::RegisterMCCodeGenInfo(getTheTeakTarget(), createTeakMCCodeGenInfo);
// Register the MC instruction info. // Register the MC instruction info.
TargetRegistry::RegisterMCInstrInfo(getTheTeakTarget(), createTeakMCInstrInfo); TargetRegistry::RegisterMCInstrInfo(getTheTeakTarget(), createTeakMCInstrInfo);
// Register the MC register info. // Register the MC register info.
TargetRegistry::RegisterMCRegInfo(getTheTeakTarget(), createTeakMCRegisterInfo); TargetRegistry::RegisterMCRegInfo(getTheTeakTarget(), createTeakMCRegisterInfo);
// Register the MC subtarget info. // Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(getTheTeakTarget(), createTeakMCSubtargetInfo); TargetRegistry::RegisterMCSubtargetInfo(getTheTeakTarget(), createTeakMCSubtargetInfo);
// Register the MCInstPrinter // Register the MCInstPrinter
TargetRegistry::RegisterMCInstPrinter(getTheTeakTarget(), createTeakMCInstPrinter); TargetRegistry::RegisterMCInstPrinter(getTheTeakTarget(), createTeakMCInstPrinter);
// Register the ASM Backend. // Register the ASM Backend.
TargetRegistry::RegisterMCAsmBackend(getTheTeakTarget(), createTeakAsmBackend); TargetRegistry::RegisterMCAsmBackend(getTheTeakTarget(), createTeakAsmBackend);
// Register the MCCodeEmitter // Register the MCCodeEmitter
TargetRegistry::RegisterMCCodeEmitter(getTheTeakTarget(), createTeakMCCodeEmitter); TargetRegistry::RegisterMCCodeEmitter(getTheTeakTarget(), createTeakMCCodeEmitter);
TargetRegistry::RegisterELFStreamer(getTheTeakTarget(), createTeakMCStreamer);
} }

View File

@ -23,7 +23,8 @@ namespace llvm
class TargetMachine; class TargetMachine;
class TeakTargetMachine; class TeakTargetMachine;
FunctionPass *createTeakISelDag(TeakTargetMachine &TM, CodeGenOpt::Level OptLevel); FunctionPass* createTeakISelDag(TeakTargetMachine &TM, CodeGenOpt::Level OptLevel);
FunctionPass* createTeakOptimizeMovImmPass();
namespace TeakCC 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) inline static unsigned teakGetAbLReg(unsigned reg)
{ {
switch(reg) switch(reg)
@ -133,6 +159,23 @@ namespace llvm
llvm_unreachable("Invalid reg"); 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; } // end namespace llvm;
#endif #endif

View File

@ -55,5 +55,5 @@ def CC_Teak : CallingConv<[
//CCIfType<[i32], CCAssignToStack<4, 4>> //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)>; def CSR_NoRegs : CalleeSavedRegs<(add)>;

View File

@ -86,33 +86,36 @@ uint64_t TeakFrameLowering::computeStackSize(MachineFunction &MF) const {
void TeakFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const void TeakFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const
{ {
// Compute the stack size, to determine if we need a prologue at all. // Compute the stack size, to determine if we need a prologue at all.
const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();
MachineBasicBlock::iterator MBBI = MBB.begin(); MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
uint64_t StackSize = computeStackSize(MF); uint64_t StackSize = computeStackSize(MF);
if (!StackSize) if (!StackSize)
return; return;
MachineFrameInfo& MFI = MF.getFrameInfo(); MachineFrameInfo& MFI = MF.getFrameInfo();
const std::vector<CalleeSavedInfo>& CSI = MFI.getCalleeSavedInfo(); const std::vector<CalleeSavedInfo>& CSI = MFI.getCalleeSavedInfo();
StackSize -= CSI.size() * 2; StackSize -= CSI.size() * 2;
if (!StackSize) if (!StackSize)
return; return;
BuildMI(MBB, MBBI, dl, TII.get(Teak::PUSH_regnob16), Teak::R7) BuildMI(MBB, MBBI, dl, TII.get(Teak::PUSH_regnob16), Teak::R7)
.setMIFlag(MachineInstr::FrameSetup); .setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, dl, TII.get(Teak::MOV_regnobp016_regnob16), Teak::R7) BuildMI(MBB, MBBI, dl, TII.get(Teak::MOV_regnobp016_regnob16), Teak::R7)
.addReg(Teak::SP) .addReg(Teak::SP)
.setMIFlag(MachineInstr::FrameSetup); .setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, dl, TII.get(Teak::ADDV_imm16_RegNoBRegs16), Teak::SP) BuildMI(MBB, MBBI, dl, TII.get(Teak::ADDV_imm16_RegNoBRegs16), Teak::SP)
.addImm(-(StackSize >> 1)) .addImm(-(StackSize >> 1))
.addReg(Teak::SP) .addReg(Teak::SP)
.setMIFlag(MachineInstr::FrameSetup); .setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, dl, TII.get(Teak::NOP))
.setMIFlag(MachineInstr::FrameSetup);
} }
void TeakFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const 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) BuildMI(MBB, MBBI, dl, TII.get(Teak::MOV_regnobp016_regnob16), Teak::SP)
.addReg(Teak::R7) .addReg(Teak::R7)
.setMIFlag(MachineInstr::FrameSetup); .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) BuildMI(MBB, MBBI, dl, TII.get(Teak::POP_regnob16), Teak::R7)
.setMIFlag(MachineInstr::FrameSetup); .setMIFlag(MachineInstr::FrameSetup);
} }

View File

@ -73,6 +73,7 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM)
addRegisterClass(MVT::i16, &Teak::ABLRegsRegClass); addRegisterClass(MVT::i16, &Teak::ABLRegsRegClass);
//addRegisterClass(MVT::i16, &Teak::ALRegsRegClass); //addRegisterClass(MVT::i16, &Teak::ALRegsRegClass);
addRegisterClass(MVT::i16, &Teak::RegNoBRegs16_nohRegClass); addRegisterClass(MVT::i16, &Teak::RegNoBRegs16_nohRegClass);
// addRegisterClass(MVT::i16, &Teak::RegNoBRegs16_noh_pageRegClass);
//addRegisterClass(MVT::i16, &Teak::Y0RegsRegClass); //addRegisterClass(MVT::i16, &Teak::Y0RegsRegClass);
//addRegisterClass(MVT::i32, &Teak::P0RegsRegClass); //addRegisterClass(MVT::i32, &Teak::P0RegsRegClass);
//addRegisterClass(MVT::i16, &Teak::ABHRegsRegClass); //addRegisterClass(MVT::i16, &Teak::ABHRegsRegClass);
@ -99,6 +100,7 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM)
setOperationAction(ISD::ADD, MVT::i16, Custom); setOperationAction(ISD::ADD, MVT::i16, Custom);
setOperationAction(ISD::SUB, 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::i16, Custom);
setOperationAction(ISD::AND, MVT::i40, Custom); setOperationAction(ISD::AND, MVT::i40, Custom);
setOperationAction(ISD::XOR, MVT::i16, 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, bool TeakTargetLowering::getPostIndexedAddressParts(SDNode* N, SDNode* Op,
SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const
{ {
return false; 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); // SDLoc DL(N);
// const LoadSDNode* ld = dyn_cast<LoadSDNode>(N); // Op->dump();
// if (!ld) // N->dump();
// return false; 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;
} }
bool TeakTargetLowering::allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace, 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; SDValue CompareFlag;
if (LHS.getValueType().isInteger()) if (LHS.getValueType().isInteger())
{ {
CompareFlag = DAG.getNode(TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS);
Opc = TeakISD::SELECT_ICC; Opc = TeakISD::SELECT_ICC;
if (SPCC == ~0U) if (SPCC == ~0U)
SPCC = IntCondCCodeToICC(CC); SPCC = IntCondCCodeToICC(CC);
CompareFlag = DAG.getNode((SPCC == TeakCC::Eq || SPCC == TeakCC::Neq) ? TeakISD::CMPZICC : TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS);
} }
else else
llvm_unreachable("!LHS.getValueType().isInteger()"); llvm_unreachable("!LHS.getValueType().isInteger()");
@ -415,10 +416,10 @@ SDValue TeakTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
SDValue CompareFlag; SDValue CompareFlag;
if (LHS.getValueType().isInteger()) if (LHS.getValueType().isInteger())
{ {
CompareFlag = DAG.getNode(TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS);
if (SPCC == ~0U) if (SPCC == ~0U)
SPCC = IntCondCCodeToICC(CC); 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; Opc = TeakISD::BRICC;
} }
else else
@ -454,13 +455,9 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const
const SDNode *N = Op.getNode(); const SDNode *N = Op.getNode();
SDLoc dl(N); SDLoc dl(N);
assert(N->getValueType(0) == MVT::i16 && "Unexpected custom legalisation"); assert(N->getValueType(0) == MVT::i16 && "Unexpected custom legalisation");
//this seems to give problems for some reason if(isa<ConstantSDNode>(N->getOperand(1)))
// if(isa<ConstantSDNode>(N->getOperand(1))) return DAG.getNode(Op.getOpcode(), dl, MVT::i16, N->getOperand(0), N->getOperand(1));
// {
// dbgs() << "constant!\n";
// return Op;
// }
//dbgs() << "Lowering!\n";
SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i40, N->getOperand(0)); 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 NewOp1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i40, N->getOperand(1));
SDValue NewWOp = DAG.getNode(Op.getOpcode(), dl, MVT::i40, NewOp0, NewOp1); 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); SDValue NewWOp = DAG.getNode(nodeType, dl, MVT::i40, NewOp0, NewOp1);
return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, NewWOp); 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: case ISD::SHL:
{ {
const SDNode *N = Op.getNode(); const SDNode *N = Op.getNode();

View File

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

View File

@ -285,41 +285,82 @@ void TeakInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
MCRegister DestReg, MCRegister SrcReg, MCRegister DestReg, MCRegister SrcReg,
bool KillSrc) const bool KillSrc) const
{ {
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
const TeakSubtarget &st = MF.getSubtarget<TeakSubtarget>(); const TeakSubtarget &st = MF.getSubtarget<TeakSubtarget>();
dbgs() << "copyPhysReg(" << SrcReg.id() << ", " << DestReg.id() << ")\n"; const TargetRegisterInfo *RegInfo = st.getRegisterInfo();
unsigned op; bool keepFlags = MBB.computeRegisterLiveness(RegInfo, Teak::ICC, I) != MachineBasicBlock::LQR_Dead;
// if(Teak::ARegsRegClass.contains(SrcReg) && Teak::ARegsRegClass.contains(DestReg) && SrcReg != DestReg) dbgs() << "copyPhysReg(" << SrcReg.id() << ", " << DestReg.id() << ")\n";
// op = Teak::COPY_a; unsigned op;
// else // if(Teak::ABLRegsRegClass.contains(DestReg))
if(Teak::ABRegsRegClass.contains(SrcReg) && Teak::ABRegsRegClass.contains(DestReg)) // {
op = Teak::MOV_ab_ab; // // unsigned fullDst = teakGetAbReg(DestReg.id());
else if(Teak::RegNoBRegs16RegClass.contains(SrcReg) && Teak::RegNoBRegs40RegClass.contains(DestReg)) // // unsigned hiDst = teakGetAbHReg(fullDst);
op = Teak::MOV_regnobp016_abl;
else if(Teak::RegNoBRegs16RegClass.contains(SrcReg) && Teak::RegNoBRegs16RegClass.contains(DestReg))
op = Teak::MOV_regnobp016_regnob16;
// else if(Teak::P0RegsRegClass.contains(SrcReg) && Teak::ABRegsRegClass.contains(DestReg))
// op = Teak::MOV_p0_ab; //with sign extension, might be bad?
// else if(Teak::P0RegsRegClass.contains(SrcReg) && Teak::RegNoBRegs16RegClass.contains(DestReg))
// op = Teak::MOV_p0_regnob16;
else
assert(0 && "Unimplemented copyPhysReg");
const TargetRegisterInfo *RegInfo = st.getRegisterInfo(); // // //special handling for subreg copies, which cannot be done directly
if (MBB.computeRegisterLiveness(RegInfo, Teak::ICC, I) == MachineBasicBlock::LQR_Dead) // // // if(keepFlags)
{ // // // BuildMI(MBB, I, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
BuildMI(MBB, I, DL, get(op), DestReg) // // // BuildMI(MBB, I, DL, get(Teak::RST_imm16_regnob16), DestReg)
.addReg(SrcReg, getKillRegState(KillSrc)) // // // .addImm(0xFFFF)
->addRegisterDead(Teak::ICC, RegInfo); // // // .addReg(DestReg);
} // // // if(keepFlags)
else // // // BuildMI(MBB, I, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
{ // // bool hiAlive = MBB.computeRegisterLiveness(RegInfo, hiDst, I) != MachineBasicBlock::LQR_Dead;
BuildMI(MBB, I, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); // // dbgs() << "Hi dst alive: " << hiAlive << "\n";
BuildMI(MBB, I, DL, get(op), DestReg) // // if(hiAlive)
.addReg(SrcReg, getKillRegState(KillSrc)); // // {
BuildMI(MBB, I, DL, get(Teak::POP_ararpsttmod), Teak::STT0); // llvm_unreachable("Invalid low destination register!");
//llvm_unreachable("Help! Can't preserve ICC"); // 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::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;
else if(Teak::RegNoBRegs16RegClass.contains(SrcReg) && Teak::RegNoBRegs16RegClass.contains(DestReg))
op = Teak::MOV_regnobp016_regnob16;
// else if(Teak::P0RegsRegClass.contains(SrcReg) && Teak::ABRegsRegClass.contains(DestReg))
// op = Teak::MOV_p0_ab; //with sign extension, might be bad?
// else if(Teak::P0RegsRegClass.contains(SrcReg) && Teak::RegNoBRegs16RegClass.contains(DestReg))
// op = Teak::MOV_p0_regnob16;
else
assert(0 && "Unimplemented copyPhysReg");
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);
}
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);
//llvm_unreachable("Help! Can't preserve ICC");
}
} }
void TeakInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, void TeakInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
@ -457,110 +498,90 @@ bool TeakInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TBB, unsigned TCycles
return true; 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 bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
{ {
DebugLoc DL = MI.getDebugLoc(); DebugLoc DL = MI.getDebugLoc();
MachineBasicBlock &MBB = *MI.getParent(); MachineBasicBlock &MBB = *MI.getParent();
MachineFunction &MF = *MBB.getParent(); MachineFunction &MF = *MBB.getParent();
const TeakSubtarget &st = MF.getSubtarget<TeakSubtarget>(); const TeakSubtarget &st = MF.getSubtarget<TeakSubtarget>();
const TargetRegisterInfo *RegInfo = st.getRegisterInfo(); const TargetRegisterInfo *RegInfo = st.getRegisterInfo();
dbgs() << "Expand post, live: " << MBB.computeRegisterLiveness(RegInfo, Teak::ICC, MI) << "\n"; dbgs() << "Expand post, live: " << MBB.computeRegisterLiveness(RegInfo, Teak::ICC, MI) << "\n";
bool keepFlags = MBB.computeRegisterLiveness(RegInfo, Teak::ICC, MI) != MachineBasicBlock::LQR_Dead; bool keepFlags = MBB.computeRegisterLiveness(RegInfo, Teak::ICC, MI) != MachineBasicBlock::LQR_Dead;
switch (MI.getOpcode()) switch (MI.getOpcode())
{ {
default: default:
return false; return false;
case Teak::STORE_REG_TO_STACK_PSEUDO_16: case Teak::STORE_REG_TO_STACK_PSEUDO_16:
{ {
dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_16\n"; 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) if(keepFlags && frameOffset)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(frameOffset) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn))
.addImm(frameOffset) .addReg(MI.getOperand(0).getReg(), getKillRegState(MI.getOperand(0).isKill()))
.addReg(MI.getOperand(1).getReg()); .addReg(MI.getOperand(1).getReg());
BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn)) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
.addReg(MI.getOperand(0).getReg(), getKillRegState(MI.getOperand(0).isKill())) if(keepFlags && frameOffset)
.addReg(MI.getOperand(1).getReg()); BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
if(frameOffset) MBB.erase(MI);
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) return true;
.addImm(-frameOffset) }
.addReg(MI.getOperand(1).getReg());
if(keepFlags && frameOffset)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
MBB.erase(MI);
return true;
}
case Teak::STORE_REG_TO_STACK_PSEUDO_TRUNC16: case Teak::STORE_REG_TO_STACK_PSEUDO_TRUNC16:
{ {
dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_TRUNC16\n"; dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_TRUNC16\n";
unsigned srcReg = MI.getOperand(0).getReg(); unsigned srcReg = MI.getOperand(0).getReg();
unsigned loReg; unsigned loReg = teakGetAbLReg(srcReg);
if(srcReg == Teak::A0) signed short frameOffset = (signed short)MI.getOperand(2).getImm();
loReg = Teak::A0L; if(keepFlags && frameOffset)
else if(srcReg == Teak::A1) BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
loReg = Teak::A1L; makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
else if(srcReg == Teak::B0) BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn))
loReg = Teak::B0L; .addReg(loReg, getKillRegState(MI.getOperand(0).isKill()))
else if(srcReg == Teak::B1)
loReg = Teak::B1L;
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2;
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());
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());
if(keepFlags && frameOffset)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
MBB.erase(MI);
return true;
}
case Teak::STORE_REG_TO_STACK_PSEUDO_32:
{
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;
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()); .addReg(MI.getOperand(1).getReg());
if(loReg == Teak::A0L || loReg == Teak::A1L) 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);
return true;
}
case Teak::STORE_REG_TO_STACK_PSEUDO_32:
{
dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_32\n";
unsigned srcReg = MI.getOperand(0).getReg();
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);
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)) BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn))
.addReg(hiReg, getKillRegState(MI.getOperand(0).isKill())) .addReg(hiReg, getKillRegState(MI.getOperand(0).isKill()))
.addReg(MI.getOperand(1).getReg()); .addReg(MI.getOperand(1).getReg());
@ -568,38 +589,33 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
.addReg(loReg, getKillRegState(MI.getOperand(0).isKill())) .addReg(loReg, getKillRegState(MI.getOperand(0).isKill()))
.addReg(Teak::R7) .addReg(Teak::R7)
.addImm(-1); .addImm(-1);
if(frameOffset) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) }
.addImm(-frameOffset) else
.addReg(MI.getOperand(1).getReg()); {
}
else
{
BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn_postdec), MI.getOperand(1).getReg()) BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn_postdec), MI.getOperand(1).getReg())
.addReg(hiReg, getKillRegState(MI.getOperand(0).isKill())) .addReg(hiReg, getKillRegState(MI.getOperand(0).isKill()))
.addReg(MI.getOperand(1).getReg()); .addReg(MI.getOperand(1).getReg());
BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn)) BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn))
.addReg(loReg, getKillRegState(MI.getOperand(0).isKill())) .addReg(loReg, getKillRegState(MI.getOperand(0).isKill()))
.addReg(MI.getOperand(1).getReg()); .addReg(MI.getOperand(1).getReg());
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset + 1);
.addImm(-frameOffset + 1) }
.addReg(MI.getOperand(1).getReg()); if(keepFlags)
} BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
if(keepFlags) MBB.erase(MI);
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); return true;
MBB.erase(MI); }
return true;
}
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16: case Teak::LOAD_REG_FROM_STACK_PSEUDO_16:
{ {
dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16\n"; dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16\n";
unsigned dstReg = MI.getOperand(0).getReg(); 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) if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(dstReg == Teak::A0L || dstReg == Teak::A1L) if(dstReg == Teak::A0L || dstReg == Teak::A1L)
{ {
if(frameOffset >= -64 && frameOffset <= 63) if(frameOffset >= -64 && frameOffset <= 63)
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg == Teak::A0L ? Teak::A0 : Teak::A1) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg == Teak::A0L ? Teak::A0 : Teak::A1)
.addReg(Teak::R7) .addReg(Teak::R7)
@ -608,35 +624,29 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg == Teak::A0L ? Teak::A0 : Teak::A1) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg == Teak::A0L ? Teak::A0 : Teak::A1)
.addReg(Teak::R7) .addReg(Teak::R7)
.addImm(frameOffset); .addImm(frameOffset);
} }
else else
{ {
if(frameOffset) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_regnob16), dstReg)
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg()); .addReg(MI.getOperand(1).getReg());
BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_regnob16), dstReg) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
.addReg(MI.getOperand(1).getReg()); }
if(frameOffset) if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
.addImm(-frameOffset) MBB.erase(MI);
.addReg(MI.getOperand(1).getReg()); return true;
} }
if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
MBB.erase(MI);
return true;
}
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40: case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40:
{ {
dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40\n"; dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40\n";
unsigned dstReg = MI.getOperand(0).getReg(); 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) if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(dstReg == Teak::A0 || dstReg == Teak::A1) if(dstReg == Teak::A0 || dstReg == Teak::A1)
{ {
if(frameOffset >= -64 && frameOffset <= 63) if(frameOffset >= -64 && frameOffset <= 63)
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg)
.addReg(Teak::R7) .addReg(Teak::R7)
@ -645,207 +655,228 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg)
.addReg(Teak::R7) .addReg(Teak::R7)
.addImm(frameOffset); .addImm(frameOffset);
} }
else else
{ {
if(frameOffset) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab), dstReg)
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg()); .addReg(MI.getOperand(1).getReg());
BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab), dstReg) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
.addReg(MI.getOperand(1).getReg()); if(keepFlags)
if(frameOffset) BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) }
.addImm(-frameOffset) MBB.erase(MI);
.addReg(MI.getOperand(1).getReg()); return true;
if(keepFlags) }
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
}
MBB.erase(MI);
return true;
}
case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40: case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40:
{ {
dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40\n"; 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) if(keepFlags)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
if(frameOffset) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset);
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab1), MI.getOperand(0).getReg())
.addImm(frameOffset)
.addReg(MI.getOperand(1).getReg()); .addReg(MI.getOperand(1).getReg());
BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab1), MI.getOperand(0).getReg()) makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset);
.addReg(MI.getOperand(1).getReg()); if(keepFlags)
if(frameOffset) BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) MBB.erase(MI);
.addImm(-frameOffset) return true;
.addReg(MI.getOperand(1).getReg()); }
if(keepFlags) case Teak::LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40:
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); {
MBB.erase(MI); dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40\n";
return true; unsigned dstReg = MI.getOperand(0).getReg();
} signed short frameOffset = (signed short)MI.getOperand(2).getImm();
case Teak::LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40: if(keepFlags)
{ BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0);
dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40\n"; if(dstReg == Teak::A0 || dstReg == Teak::A1)
unsigned dstReg = MI.getOperand(0).getReg(); {
signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2; if(frameOffset >= -64 && frameOffset <= 63)
if(keepFlags) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg)
BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); .addReg(Teak::R7)
if(dstReg == Teak::A0 || dstReg == Teak::A1) .addImm(frameOffset);
{ else
if(frameOffset >= -64 && frameOffset <= 63) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg)
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg) .addReg(Teak::R7)
.addReg(Teak::R7) .addImm(frameOffset);
.addImm(frameOffset); BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), dstReg)
else .addReg(dstReg)
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg) .addImm(16);
.addReg(Teak::R7) if(frameOffset - 1 >= -64 && frameOffset - 1 <= 63)
.addImm(frameOffset); BuildMI(MBB, MI, DL, get(Teak::OR_r7offset7s_a), dstReg)
BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), dstReg) .addReg(Teak::R7)
.addReg(dstReg) .addImm(frameOffset - 1)
.addImm(16); .addReg(dstReg);
if(frameOffset - 1 >= -64 && frameOffset - 1 <= 63) else
BuildMI(MBB, MI, DL, get(Teak::OR_r7offset7s_a), dstReg) BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), dstReg)
.addReg(Teak::R7) .addReg(Teak::R7)
.addImm(frameOffset - 1) .addImm(frameOffset - 1)
.addReg(dstReg); .addReg(dstReg);
else }
BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), dstReg) else
.addReg(Teak::R7) {
.addImm(frameOffset - 1) BuildMI(MBB, MI, DL, get(Teak::MOV_ab_ab), dstReg)
.addReg(dstReg);
}
else
{
BuildMI(MBB, MI, DL, get(Teak::MOV_ab_ab), dstReg)
.addReg(Teak::A0);
if(frameOffset >= -64 && frameOffset <= 63)
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), Teak::A0)
.addReg(Teak::R7)
.addImm(frameOffset);
else
BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), Teak::A0)
.addReg(Teak::R7)
.addImm(frameOffset);
BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), Teak::A0)
.addReg(Teak::A0)
.addImm(16);
if(frameOffset - 1 >= -64 && frameOffset - 1 <= 63)
BuildMI(MBB, MI, DL, get(Teak::OR_r7offset7s_a), Teak::A0)
.addReg(Teak::R7)
.addImm(frameOffset - 1)
.addReg(Teak::A0); .addReg(Teak::A0);
else if(frameOffset >= -64 && frameOffset <= 63)
BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), Teak::A0) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), Teak::A0)
.addReg(Teak::R7) .addReg(Teak::R7)
.addImm(frameOffset - 1) .addImm(frameOffset);
.addReg(Teak::A0); else
BuildMI(MBB, MI, DL, get(Teak::SWAP_ab)) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), Teak::A0)
.addReg(dstReg, RegState::Define) .addReg(Teak::R7)
.addReg(Teak::A0, RegState::Define) .addImm(frameOffset);
.addReg(Teak::A0) BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), Teak::A0)
.addReg(dstReg); .addReg(Teak::A0)
} .addImm(16);
if(keepFlags) if(frameOffset - 1 >= -64 && frameOffset - 1 <= 63)
BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); BuildMI(MBB, MI, DL, get(Teak::OR_r7offset7s_a), Teak::A0)
MBB.erase(MI); .addReg(Teak::R7)
return true; .addImm(frameOffset - 1)
} .addReg(Teak::A0);
case Teak::MPY_y0_regnob16_RegNoBRegs16: else
{ BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), Teak::A0)
BuildMI(MBB, MI, DL, get(Teak::MPY_y0_regnob16), Teak::P0) .addReg(Teak::R7)
.addReg(MI.getOperand(1).getReg()) .addImm(frameOffset - 1)
.addReg(MI.getOperand(2).getReg()); .addReg(Teak::A0);
BuildMI(MBB, MI, DL, get(Teak::MOV_p0_regnob16), MI.getOperand(0).getReg()) BuildMI(MBB, MI, DL, get(Teak::SWAP_ab))
.addReg(Teak::P0); .addReg(dstReg, RegState::Define)
MBB.erase(MI); .addReg(Teak::A0, RegState::Define)
return true; .addReg(Teak::A0)
} .addReg(dstReg);
// case Teak::SHL_PSEUDO_ab_ab_sv: }
// { if(keepFlags)
// BuildMI(MBB, MI, DL, get(Teak::MOV_regnobp016_regnob16), Teak::SV) BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0);
// .addReg(MI.getOperand(2).getReg()); MBB.erase(MI);
// BuildMI(MBB, MI, DL, get(Teak::SHFC_ab_ab_sv), MI.getOperand(0).getReg()) return true;
// .addReg(MI.getOperand(1).getReg()); }
// .addReg(MI.getOperand(2).getReg()); case Teak::MPYI_y0_imm8s_ab:
// MBB.erase(MI); case Teak::MPYI_y0_imm8s_ab_ADD:
// return true; {
// } BuildMI(MBB, MI, DL, get(Teak::MPYI_y0_imm8s), Teak::P0)
case Teak::SHFI_logic_ab_ab: .addReg(MI.getOperand(1).getReg())
{ .addImm(MI.getOperand(2).getImm());
BuildMI(MBB, MI, DL, get(Teak::SET_imm16_sttmod), Teak::MOD0) if (MI.getOpcode() == Teak::MPYI_y0_imm8s_ab_ADD)
.addImm(0x80) BuildMI(MBB, MI, DL, get(Teak::ADD_px_ab), MI.getOperand(0).getReg())
.addReg(Teak::MOD0); .addReg(Teak::P0)
BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), MI.getOperand(0).getReg()) .addReg(MI.getOperand(0).getReg());
.add(MI.getOperand(1)) else
.add(MI.getOperand(2)); BuildMI(MBB, MI, DL, get(Teak::MOV_p0_ab), MI.getOperand(0).getReg())
BuildMI(MBB, MI, DL, get(Teak::RST_imm16_sttmod), Teak::MOD0) .addReg(Teak::P0);
.addImm(0x80) MBB.erase(MI);
.addReg(Teak::MOD0); return true;
MBB.erase(MI); }
return true; case Teak::MPY_y0_regnob16_ab:
} case Teak::MPY_y0_regnob16_ab_ADD:
case Teak::SHFC_logic_ab_ab_sv: {
{ BuildMI(MBB, MI, DL, get(Teak::MPY_y0_regnob16), Teak::P0)
BuildMI(MBB, MI, DL, get(Teak::SET_imm16_sttmod), Teak::MOD0) .addReg(MI.getOperand(1).getReg())
.addImm(0x80) .addReg(MI.getOperand(2).getReg());
.addReg(Teak::MOD0);
BuildMI(MBB, MI, DL, get(Teak::SHFC_arith_ab_ab_sv), MI.getOperand(0).getReg())
.add(MI.getOperand(1))
.add(MI.getOperand(2))
.add(MI.getOperand(3));
BuildMI(MBB, MI, DL, get(Teak::RST_imm16_sttmod), Teak::MOD0)
.addImm(0x80)
.addReg(Teak::MOD0);
MBB.erase(MI);
return true;
}
// case Teak::SRA_PSEUDO_ab_ab_sv:
// {
// BuildMI(MBB, MI, DL, get(Teak::MOV_regnobp016_regnob16), Teak::SV)
// .addReg(MI.getOperand(2).getReg());
// BuildMI(MBB, MI, DL, get(Teak::SHFC_ab_ab_sv), MI.getOperand(0).getReg())
// .addReg(MI.getOperand(1).getReg());
// .addReg(MI.getOperand(2).getReg());
// MBB.erase(MI);
// return true;
// }
}
// switch (MI->getOpcode())
// {
// default:
// return false;
// case Teak::MOVi32: {
// DebugLoc DL = MI->getDebugLoc();
// MachineBasicBlock &MBB = *MI->getParent();
// const unsigned DstReg = MI->getOperand(0).getReg(); if (MI.getOpcode() == Teak::MPY_y0_regnob16_ab_ADD)
// const bool DstIsDead = MI->getOperand(0).isDead(); 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)
// .addReg(MI.getOperand(2).getReg());
// BuildMI(MBB, MI, DL, get(Teak::SHFC_ab_ab_sv), MI.getOperand(0).getReg())
// .addReg(MI.getOperand(1).getReg());
// .addReg(MI.getOperand(2).getReg());
// MBB.erase(MI);
// return true;
// }
case Teak::SHFI_logic_ab_ab:
{
BuildMI(MBB, MI, DL, get(Teak::SET_imm16_sttmod), Teak::MOD0)
.addImm(0x80)
.addReg(Teak::MOD0);
BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), MI.getOperand(0).getReg())
.add(MI.getOperand(1))
.add(MI.getOperand(2));
BuildMI(MBB, MI, DL, get(Teak::RST_imm16_sttmod), Teak::MOD0)
.addImm(0x80)
.addReg(Teak::MOD0);
MBB.erase(MI);
return true;
}
case Teak::SHFC_logic_ab_ab_sv:
{
BuildMI(MBB, MI, DL, get(Teak::SET_imm16_sttmod), Teak::MOD0)
.addImm(0x80)
.addReg(Teak::MOD0);
BuildMI(MBB, MI, DL, get(Teak::SHFC_arith_ab_ab_sv), MI.getOperand(0).getReg())
.add(MI.getOperand(1))
.add(MI.getOperand(2))
.add(MI.getOperand(3));
BuildMI(MBB, MI, DL, get(Teak::RST_imm16_sttmod), Teak::MOD0)
.addImm(0x80)
.addReg(Teak::MOD0);
MBB.erase(MI);
return true;
}
// case Teak::SRA_PSEUDO_ab_ab_sv:
// {
// BuildMI(MBB, MI, DL, get(Teak::MOV_regnobp016_regnob16), Teak::SV)
// .addReg(MI.getOperand(2).getReg());
// BuildMI(MBB, MI, DL, get(Teak::SHFC_ab_ab_sv), MI.getOperand(0).getReg())
// .addReg(MI.getOperand(1).getReg());
// .addReg(MI.getOperand(2).getReg());
// MBB.erase(MI);
// return true;
// }
}
// switch (MI->getOpcode())
// {
// default:
// return false;
// case Teak::MOVi32: {
// DebugLoc DL = MI->getDebugLoc();
// MachineBasicBlock &MBB = *MI->getParent();
// const MachineOperand &MO = MI->getOperand(1); // const unsigned DstReg = MI->getOperand(0).getReg();
// const bool DstIsDead = MI->getOperand(0).isDead();
// auto LO16 = BuildMI(MBB, MI, DL, get(Teak::MOV_imm16_b), DstReg); // const MachineOperand &MO = MI->getOperand(1);
// auto HI16 = BuildMI(MBB, MI, DL, get(Teak::MOVHIi16))
// .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
// .addReg(DstReg);
// if (MO.isImm()) { // auto LO16 = BuildMI(MBB, MI, DL, get(Teak::MOV_imm16_b), DstReg);
// const unsigned Imm = MO.getImm(); // auto HI16 = BuildMI(MBB, MI, DL, get(Teak::MOVHIi16))
// const unsigned Lo16 = Imm & 0xffff; // .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
// const unsigned Hi16 = (Imm >> 16) & 0xffff; // .addReg(DstReg);
// LO16 = LO16.addImm(Lo16);
// HI16 = HI16.addImm(Hi16);
// } else {
// const GlobalValue *GV = MO.getGlobal();
// const unsigned TF = MO.getTargetFlags();
// LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | TeakII::MO_LO16);
// HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | TeakII::MO_HI16);
// }
// MBB.erase(MI); // if (MO.isImm()) {
// return true; // const unsigned Imm = MO.getImm();
// } // const unsigned Lo16 = Imm & 0xffff;
// } // const unsigned Hi16 = (Imm >> 16) & 0xffff;
// LO16 = LO16.addImm(Lo16);
// HI16 = HI16.addImm(Hi16);
// } else {
// const GlobalValue *GV = MO.getGlobal();
// const unsigned TF = MO.getTargetFlags();
// LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | TeakII::MO_LO16);
// HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | TeakII::MO_HI16);
// }
// MBB.erase(MI);
// return true;
// }
// }
} }

View File

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

View File

@ -1,6 +1,11 @@
include "TeakInstrFormats.td" include "TeakInstrFormats.td"
include "TeakOperators.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 : Pattern<(i32 (load_sym tglobaladdr:$addr)), [(MOVi32 $addr)]>;
// def MOVi32 : InstTeak<(outs BRegs:$dst), (ins i32imm:$src), "", // def MOVi32 : InstTeak<(outs BRegs:$dst), (ins i32imm:$src), "",
@ -50,6 +55,13 @@ def Imm8u_16 : Operand<i16>, ImmLeaf<i16, [{
let ParserMatchClass = Imm8u_16AsmOperand; 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_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; }
def imm0_65535 : Operand<i40>, ImmLeaf<i40, [{ def imm0_65535 : Operand<i40>, ImmLeaf<i40, [{
return Imm >= 0 && Imm < 65536; return Imm >= 0 && Imm < 65536;
@ -147,6 +159,34 @@ def load_postdec : PatFrag<(ops node:$base),
let IsNonExtLoad = 1; 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))> def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm), (ops (i32 0), (i32 zero_reg))>
{ {
let PrintMethod = "printCondCode"; let PrintMethod = "printCondCode";
@ -168,53 +208,77 @@ def MemR0425 : RegisterOperand<RegR0425>
// "addv $val, [$addr]", // "addv $val, [$addr]",
// [(store (add (load GRRegs:$addr), immNeg32768_32767_16:$val), GRRegs:$addr)]>; // [(store (add (load GRRegs:$addr), immNeg32768_32767_16:$val), GRRegs:$addr)]>;
def NOP : InstTeak<(outs), (ins), "nop", []>;
let Defs = [ICC] in let Defs = [ICC] in
{ {
let isCommutable = 1, mayStore = 1, mayLoad = 1 in let 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 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 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)]>; {
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))]>; 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 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))]>; 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 INC_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "inc $a, $p", [(set ARegs:$dst, (add ARegs:$a, 1))]>; // 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", 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
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 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)))]>; {
def INC_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "inc $a, $p", [(set ARegs:$dst, (add ARegs:$a, 1))]>;
def DEC_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "dec $a, $p", [(set ARegs:$dst, (add ARegs:$a, -1))]>;
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" 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))]>;
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)))]>; 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 in let mayLoad = 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_memimm16_a : InstTeakImm16<(outs ARegs:$dst), (ins Operand<i16>:$addr, ARegs:$a), "add [$addr], $a", [(set ARegs:$dst, (add ARegs:$a, (sextloadi16 imm:$addr)))]>;
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)))]>;
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)))]>;
}
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)))]>;
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 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 //this does not give the expected result, it is actually
//a = a & (0xFF00 | val) //a = a & (0xFF00 | val)
@ -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_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_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))]>; // 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))]>; def XOR_a_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$b, ARegs:$a), "xor $b, $a", [(set ARegs:$dst, (TeakXor ARegs:$a, ARegs:$b))]>;
} }
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))]>; let isCommutable = 1 in
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))]>; {
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 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_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_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_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 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 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_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_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_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_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))]>; 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_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))]>; 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))]>;
def MPY_y0_regnob16 : InstTeak<(outs P0Regs:$p), (ins Y0Regs:$y, RegNoBRegs16:$x), "mpy $y, $x", []>; 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 let Constraints = "$dst = $ab" 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))]>; {
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 let Constraints = "$asrc = $bdst, $bsrc = $adst" in
def SWAP_ab : InstTeak<(outs BRegs:$adst, ARegs:$bdst), (ins ARegs:$asrc, BRegs:$bsrc), "swap ($asrc, $bsrc)", []>; 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)]>; 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 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 let mayStore = 1 in
def MOV_abl_memrn : InstTeak<(outs), (ins ABRegs:$a, GRRegs:$dstAddr), "mov ${a}l, [$dstAddr]", [(truncstorei16 ABRegs:$a, GRRegs:$dstAddr)]>; 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 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))]>; 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 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))]>; 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 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))]>; 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,33 +562,45 @@ let Defs = [SP], Uses = [SP] in
def PUSH_regnob16 : InstTeak<(outs), (ins RegNoBRegs16:$reg), "push $reg", []>; def PUSH_regnob16 : InstTeak<(outs), (ins RegNoBRegs16:$reg), "push $reg", []>;
//def PUSH_px : InstTeak<(outs), (ins PRegs:$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_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 let Defs = [SP, ICC], mayLoad = 1 in
{ {
def POP_regnob16 : InstTeak<(outs RegNoBRegs16_nolh:$reg), (ins), "pop $reg", []>; def POP_regnob16 : InstTeak<(outs RegNoBRegs16_nolh:$reg), (ins), "pop $reg", []>;
//def POP_px : InstTeak<(outs PRegs:$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_ararpsttmod : InstTeak<(outs ArArpSttMod:$reg), (ins), "pop $reg", []>;
def POP_abe : InstTeak<(outs ABERegs:$reg), (ins), "pop $reg", []>;
} }
} }
let isCompare = 1, Defs = [ICC] in let isCompare = 1, Defs = [ICC] in
{ {
def CMP_imm8u_a : InstTeak <(outs), (ins Imm8u:$val, ARegs:$a), "cmp ${val}u8, $a", [(TeakCmpICC ARegs:$a, Imm8u:$val)]>; def CMP_imm8u_a : InstTeak <(outs), (ins Imm8u:$val, ARegs:$a), "cmp ${val}u8, $a", [(TeakCmpICC ARegs:$a, Imm8u:$val)]>;
def CMP_imm16_a : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, ARegs:$a), "cmp $val, $a", [(TeakCmpICC ARegs:$a, immNeg32768_32767:$val)]>; def CMP_imm16_a : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, ARegs:$a), "cmp $val, $a", [(TeakCmpICC ARegs:$a, immNeg32768_32767:$val)]>;
def CMPV_imm16_RegNoBRegs16 : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, RegNoBRegs16:$a), "cmpv $val, $a", [(TeakCmpICC (sext RegNoBRegs16:$a), immNeg32768_32767:$val)]>; def CMPV_imm16_RegNoBRegs16 : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, RegNoBRegs16:$a), "cmpv $val, $a", [(TeakCmpICC (sext RegNoBRegs16:$a), immNeg32768_32767:$val)]>;
let mayLoad = 1 in let mayLoad = 1 in
{ {
def CMP_memimm16_a : InstTeakImm16<(outs), (ins Operand<i16>:$addr, ARegs:$a), "cmp [$addr], $a", [(TeakCmpICC ARegs:$a, (sextloadi16 imm:$addr))]>; def CMP_memimm16_a : InstTeakImm16<(outs), (ins Operand<i16>:$addr, ARegs:$a), "cmp [$addr], $a", [(TeakCmpICC ARegs:$a, (sextloadi16 imm:$addr))]>;
def CMP_memrn_a : InstTeak<(outs), (ins GRRegs:$addr, ARegs:$a), "cmp [$addr], $a", [(TeakCmpICC ARegs:$a, (sextloadi16 GRRegs:$addr))]>; def CMP_memrn_a : InstTeak<(outs), (ins GRRegs:$addr, ARegs:$a), "cmp [$addr], $a", [(TeakCmpICC ARegs:$a, (sextloadi16 GRRegs:$addr))]>;
def CMPU_memrn_a : InstTeak<(outs), (ins GRRegs:$addr, ARegs:$a), "cmpu [$addr], $a", [(TeakCmpICC ARegs:$a, (zextloadi16 GRRegs:$addr))]>; def CMPU_memrn_a : InstTeak<(outs), (ins GRRegs:$addr, ARegs:$a), "cmpu [$addr], $a", [(TeakCmpICC ARegs:$a, (zextloadi16 GRRegs:$addr))]>;
} }
def CMP_regnobp016_a : InstTeak<(outs), (ins RegNoBRegs16:$b, ARegs:$a), "cmp $b, $a", [(TeakCmpICC ARegs:$a, (sext RegNoBRegs16:$b))]>; def CMP_regnobp016_a : InstTeak<(outs), (ins RegNoBRegs16:$b, ARegs:$a), "cmp $b, $a", [(TeakCmpICC ARegs:$a, (sext RegNoBRegs16:$b))]>;
def CMPU_regnob016_a : InstTeak<(outs), (ins RegNoBRegs16:$b, ARegs:$a), "cmpu $b, $a", [(TeakCmpICC ARegs:$a, (zext RegNoBRegs16:$b))]>; def CMPU_regnob016_a : InstTeak<(outs), (ins RegNoBRegs16:$b, ARegs:$a), "cmpu $b, $a", [(TeakCmpICC ARegs:$a, (zext RegNoBRegs16:$b))]>;
def CMP_ab_ab : InstTeak<(outs), (ins ABRegs:$b, ABRegs:$a), "cmp $b, $a", [(TeakCmpICC ABRegs:$a, ABRegs:$b)]>; 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 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!", 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, (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<(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<(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<(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<(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)>; 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 SDT_TeakCmpICC : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>;
def TeakCmpICC : SDNode<"TeakISD::CMPICC", SDT_TeakCmpICC, [SDNPOutGlue]>; 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 SDT_TeakSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i40>]>;
def TeakSelectICC : SDNode<"TeakISD::SELECT_ICC", SDT_TeakSelectCC, [SDNPInGlue]>; 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 SDT_TeakXor : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>]>;
def TeakXor : SDNode<"TeakISD::XOR", SDT_TeakXor>; 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. // // 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::PC);
Reserved.set(Teak::R7); Reserved.set(Teak::R7);
Reserved.set(Teak::LC); Reserved.set(Teak::LC);
Reserved.set(Teak::EXT0);
Reserved.set(Teak::EXT1);
Reserved.set(Teak::EXT2);
Reserved.set(Teak::EXT3);
return Reserved; return Reserved;
} }
@ -127,6 +131,8 @@ unsigned TeakRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, Ma
return 4; return 4;
case Teak::RegNoBRegs16_nohRegClassID: case Teak::RegNoBRegs16_nohRegClassID:
return 12; 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() << "DstSubReg: " << DstSubReg << "\n";
dbgs() << "NewRC: " << NewRC->getID() << "\n"; dbgs() << "NewRC: " << NewRC->getID() << "\n";
if (SrcRC->hasSuperClassEq(&Teak::SVRegRegClass) || // if (SrcRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
DstRC->hasSuperClassEq(&Teak::SVRegRegClass) || // DstRC->hasSuperClassEq(&Teak::SVRegRegClass) ||
NewRC->hasSuperClassEq(&Teak::SVRegRegClass)) // NewRC->hasSuperClassEq(&Teak::SVRegRegClass))
return false; // return false;
if(DstSubReg == Teak::sub_16bit) // if(DstSubReg == Teak::sub_16bit)
return true; // return true;
//if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass)) // //if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass))
// return true; // // return true;
if(SrcRC->hasSuperClassEq(&Teak::ABLRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass)) // if(SrcRC->hasSuperClassEq(&Teak::ABLRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass))
return true; // return true;
if(SrcRC->hasSuperClassEq(&Teak::ABRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass)) // if(SrcRC->hasSuperClassEq(&Teak::ABRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass))
return true; // return true;
//return true;//false; // //return true;//false;
if(SrcRC->hasSuperClassEq(&Teak::ARegsRegClass) && DstRC->hasSuperClassEq(&Teak::ARegsRegClass) && NewRC->hasSuperClassEq(&Teak::ARegsRegClass)) // if(SrcRC->hasSuperClassEq(&Teak::ARegsRegClass) && DstRC->hasSuperClassEq(&Teak::ARegsRegClass) && NewRC->hasSuperClassEq(&Teak::ARegsRegClass))
return true; // return true;
if(SrcRC->hasSuperClassEq(&Teak::ALRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ALRegsRegClass)) // if(SrcRC->hasSuperClassEq(&Teak::ALRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ALRegsRegClass))
return true; // return true;
if (DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) || NewRC->hasSuperClassEq(&Teak::ALRegsRegClass) || // if (DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) || NewRC->hasSuperClassEq(&Teak::ALRegsRegClass) ||
DstRC->hasSuperClassEq(&Teak::ARegsRegClass) || NewRC->hasSuperClassEq(&Teak::ARegsRegClass)) // DstRC->hasSuperClassEq(&Teak::ARegsRegClass) || NewRC->hasSuperClassEq(&Teak::ARegsRegClass))
return false; // return false;
return true; 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, unsigned DstSubReg,
const TargetRegisterClass *NewRC, const TargetRegisterClass *NewRC,
LiveIntervals &LIS) const override; LiveIntervals &LIS) const override;
virtual const TargetRegisterClass* getCrossCopyRegClass(const TargetRegisterClass* RC) const override;
}; };
} // end namespace llvm } // end namespace llvm

View File

@ -95,15 +95,111 @@ def MOD1 : TeakReg<0, "mod1">;
def MOD2 : TeakReg<0, "mod2">; def MOD2 : TeakReg<0, "mod2">;
def MOD3 : TeakReg<0, "mod3">; 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 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. // Register classes.
// //
def GRRegs : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>; 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 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 : 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)>; 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)>; 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 RegR0425 : RegisterClass<"Teak", [i16], 16, (add R0, R4, R2, R5)>;
//def RegNoBRegsP040 : RegisterClass<"Teak", [i40], 32, (add A0, A1)>; //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)>; //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 B0Reg : RegisterClass<"Teak", [i40], 32, (add B0)>;
def B1Reg : RegisterClass<"Teak", [i40], 32, (add B1)>; def B1Reg : RegisterClass<"Teak", [i40], 32, (add B1)>;
def ABRegs : RegisterClass<"Teak", [i40], 32, (add A0, A1, B0, B1)>; def ABRegs : RegisterClass<"Teak", [i40], 32, (add A0, A1, B0, B1)>;
def ABLRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L, B0L, B1L)>; let CopyCost = -1 in
def ALRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L)>; {
// { def ABLRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L, B0L, B1L)>;
// let CopyCost = -1; def ALRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L)>;
// } def ABHRegs : RegisterClass<"Teak", [i16], 16, (add A0H, A1H, B0H, B1H)>;
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 ArArpSttMod : RegisterClass<"Teak", [i16], 16, (add STT0)>;
def FP : RegisterClass<"Teak", [i16], 16, (add R7)>; def FP : RegisterClass<"Teak", [i16], 16, (add R7)>;
def Y0Regs : RegisterClass<"Teak", [i16], 16, (add Y0)>; def Y0Regs : RegisterClass<"Teak", [i16], 16, (add Y0)>;
@ -128,4 +225,10 @@ def SVReg : RegisterClass<"Teak", [i16], 16, (add SV)>;
//def YRegs : RegisterClass<"Teak", [i16], 16, (add Y0, Y1)>; //def YRegs : RegisterClass<"Teak", [i16], 16, (add Y0, Y1)>;
//def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>; //def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>;
def SttModRegs : RegisterClass<"Teak", [i16], 16, (add STT0, STT1, STT2, MOD0, MOD1, MOD2, MOD3)>; 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 } // namespace
TargetPassConfig *TeakTargetMachine::createPassConfig(PassManagerBase &PM) { TargetPassConfig *TeakTargetMachine::createPassConfig(PassManagerBase &PM)
return new TeakPassConfig(*this, PM); {
return new TeakPassConfig(*this, PM);
} }
bool TeakPassConfig::addPreISel() { return false; } bool TeakPassConfig::addPreISel()
{
addPass(createHardwareLoopsPass());
return false;
}
void TeakPassConfig::addPreSched2() void TeakPassConfig::addPreSched2()
{ {
@ -90,6 +95,7 @@ bool TeakPassConfig::addInstSelector()
void TeakPassConfig::addPreEmitPass() void TeakPassConfig::addPreEmitPass()
{ {
addPass(createTeakOptimizeMovImmPass());
addPass(&BranchRelaxationPassID); addPass(&BranchRelaxationPassID);
} }