diff --git a/llvm/lib/Target/Teak/CMakeLists.txt b/llvm/lib/Target/Teak/CMakeLists.txt index 6ef61634172..92e77817e04 100644 --- a/llvm/lib/Target/Teak/CMakeLists.txt +++ b/llvm/lib/Target/Teak/CMakeLists.txt @@ -20,6 +20,7 @@ add_llvm_target(TeakCodeGen TeakISelDAGToDAG.cpp TeakAsmPrinter.cpp TeakMCInstLower.cpp + TeakOptimizeMovImmPass.cpp ) add_subdirectory(AsmParser) diff --git a/llvm/lib/Target/Teak/MCTargetDesc/CMakeLists.txt b/llvm/lib/Target/Teak/MCTargetDesc/CMakeLists.txt index 305375be38d..54fc68210d3 100644 --- a/llvm/lib/Target/Teak/MCTargetDesc/CMakeLists.txt +++ b/llvm/lib/Target/Teak/MCTargetDesc/CMakeLists.txt @@ -4,4 +4,5 @@ add_llvm_component_library(LLVMTeakDesc TeakMCCodeEmitter.cpp TeakAsmBackend.cpp TeakELFObjectWriter.cpp + TeakELFStreamer.cpp ) \ No newline at end of file diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakELFStreamer.cpp b/llvm/lib/Target/Teak/MCTargetDesc/TeakELFStreamer.cpp new file mode 100644 index 00000000000..c07e0221bbc --- /dev/null +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakELFStreamer.cpp @@ -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 MAB, + std::unique_ptr OW, std::unique_ptr 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 MAB, + std::unique_ptr OW, std::unique_ptr Emitter, bool RelaxAll) +{ + return new TeakELFStreamer(Context, std::move(MAB), std::move(OW), std::move(Emitter)); +} \ No newline at end of file diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakELFStreamer.h b/llvm/lib/Target/Teak/MCTargetDesc/TeakELFStreamer.h new file mode 100644 index 00000000000..70e73be3ee5 --- /dev/null +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakELFStreamer.h @@ -0,0 +1,25 @@ +#pragma once + +#include "llvm/MC/MCELFStreamer.h" +#include + +namespace llvm +{ + class MCAsmBackend; + class MCCodeEmitter; + class MCContext; + class MCSubtargetInfo; + class MCObjectWriter; + + class TeakELFStreamer : public MCELFStreamer + { + public: + TeakELFStreamer(MCContext &Context, std::unique_ptr MAB, + std::unique_ptr OW, std::unique_ptr Emitter); + + void EmitIntValue(uint64_t Value, unsigned Size) override; + }; + + MCELFStreamer* createTeakELFStreamer(MCContext &Context, std::unique_ptr MAB, + std::unique_ptr OW, std::unique_ptr Emitter, bool RelaxAll); +} \ No newline at end of file diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp b/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp index ba584334037..ec98a2feb8e 100644 --- a/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakMCCodeEmitter.cpp @@ -132,10 +132,10 @@ static unsigned encodeRegisterOp(unsigned reg) case Teak::B1H: return 0x11; case Teak::B0L: return 0x12; case Teak::B1L: return 0x13; - //case Teak::EXT0: return 0x14; - //case Teak::EXT1: return 0x15; - //case Teak::EXT2: return 0x16; - //case Teak::EXT3: return 0x17; + case Teak::EXT0: return 0x14; + case Teak::EXT1: return 0x15; + case Teak::EXT2: return 0x16; + case Teak::EXT3: return 0x17; case Teak::A0: return 0x18; case Teak::A1: return 0x19; case Teak::A0L: return 0x1A; @@ -175,10 +175,10 @@ static unsigned encodeRegisterP0Op(unsigned reg) case Teak::B1H: return 0x11; case Teak::B0L: return 0x12; case Teak::B1L: return 0x13; - //case Teak::EXT0: return 0x14; - //case Teak::EXT1: return 0x15; - //case Teak::EXT2: return 0x16; - //case Teak::EXT3: return 0x17; + case Teak::EXT0: return 0x14; + case Teak::EXT1: return 0x15; + case Teak::EXT2: return 0x16; + case Teak::EXT3: return 0x17; case Teak::A0: return 0x18; case Teak::A1: return 0x19; case Teak::A0L: return 0x1A; @@ -235,6 +235,19 @@ static unsigned encodeAxlOp(unsigned reg) } } +static unsigned encodeAxhOp(unsigned reg) +{ + switch (reg) + { + case Teak::A0H: return 0; + case Teak::A1H: return 1; + default: + dbgs() << "encodeAxhOp(" << reg << ")\n"; + llvm_unreachable("Unsupported register"); + break; + } +} + static unsigned encodeBxOp(unsigned reg) { switch (reg) @@ -248,6 +261,53 @@ static unsigned encodeBxOp(unsigned reg) } } +static unsigned encodeAbeOp(unsigned reg) +{ + switch (reg) + { + case Teak::B0E: return 0; + case Teak::B1E: return 1; + case Teak::A0E: return 2; + case Teak::A1E: return 3; + default: + dbgs() << "encodeAbeOp(" << reg << ")\n"; + llvm_unreachable("Unsupported register"); + break; + } +} + +static unsigned encodePxOp(unsigned reg) +{ + switch (reg) + { + case Teak::P0: return 0; + case Teak::P1: return 1; + default: + dbgs() << "encodePxOp(" << reg << ")\n"; + llvm_unreachable("Unsupported register"); + break; + } +} + +static unsigned encodeR0123457Y0Op(unsigned reg) +{ + switch (reg) + { + case Teak::R0: return 0; + case Teak::R1: return 1; + case Teak::R2: return 2; + case Teak::R3: return 3; + case Teak::R4: return 4; + case Teak::R5: return 5; + case Teak::R7: return 6; + case Teak::Y0: return 7; + default: + dbgs() << "encodeR0123457Y0Op(" << reg << ")\n"; + llvm_unreachable("Unsupported register"); + break; + } +} + static unsigned encodeRnOp(unsigned reg) { switch (reg) @@ -377,6 +437,18 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, case Teak::ADD_memrn_a: EmitConstant(0x8680 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS); break; + case Teak::ADD_px_ab: + { + unsigned abReg = MI.getOperand(0).getReg(); + unsigned pReg = MI.getOperand(1).getReg(); + if (pReg == Teak::P0 && TeakMCRegisterClasses[Teak::ARegsRegClassID].contains(abReg)) + EmitConstant(0x86A0 | encodeRegisterP0Op(pReg) | (encodeAxOp(abReg) << 8), 2, OS); + else if (pReg == Teak::P1 && TeakMCRegisterClasses[Teak::ARegsRegClassID].contains(abReg)) + EmitConstant(0xD782 | encodeAxOp(abReg), 2, OS); + else + EmitConstant(0x5DF8 | (encodePxOp(pReg) << 1) | encodeBxOp(abReg), 2, OS); + break; + } case Teak::ADDL_memrn_a: EmitConstant(0x9480 | encodeRnOp(MI.getOperand(1).getReg()) | (encodeAxOp(MI.getOperand(0).getReg()) << 8), 2, OS); break; @@ -558,6 +630,18 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, case Teak::INC_a: EmitConstant(0x67D0 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS); break; + case Teak::MODR_inc1: + EmitConstant(0x0080 | encodeRnOp(MI.getOperand(0).getReg()) | (TeakStepZIDS::AddOne << 3), 2, OS); + break; + case Teak::MODR_dec1: + EmitConstant(0x0080 | encodeRnOp(MI.getOperand(0).getReg()) | (TeakStepZIDS::SubOne << 3), 2, OS); + break; + case Teak::MODR_inc2: + EmitConstant(0x4990 | encodeRnOp(MI.getOperand(0).getReg()), 2, OS); + break; + case Teak::MODR_dec2: + EmitConstant(0x5DA0 | encodeRnOp(MI.getOperand(0).getReg()), 2, OS); + break; case Teak::MOV_imm16_regnob16: case Teak::MOV_imm16neg_ab: case Teak::MOV_imm16_ab: @@ -583,6 +667,35 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, } break; } + case Teak::MOV_imm8s: + { + unsigned reg = MI.getOperand(0).getReg(); + int64_t imm = MI.getOperand(1).getImm(); + if (reg == Teak::A0H || reg == Teak::A1H) + EmitConstant(0x2500 | (encodeAxhOp(reg) << 12) | (imm & 0xFF), 2, OS); + else if (reg == Teak::EXT0) + EmitConstant(0x2900 | (imm & 0xFF), 2, OS); + else if (reg == Teak::EXT1) + EmitConstant(0x2D00 | (imm & 0xFF), 2, OS); + else if (reg == Teak::EXT2) + EmitConstant(0x3900 | (imm & 0xFF), 2, OS); + else if (reg == Teak::EXT3) + EmitConstant(0x3D00 | (imm & 0xFF), 2, OS); + else if (reg == Teak::R0 || reg == Teak::R1 || reg == Teak::R2 || + reg == Teak::R3 || reg == Teak::R4 || reg == Teak::R5 || + reg == Teak::R7 || reg == Teak::Y0) + { + EmitConstant(0x2300 | (encodeR0123457Y0Op(reg) << 10) | (imm & 0xFF), 2, OS); + } + else if(reg == Teak::SV) + EmitConstant(0x0500 | (imm & 0xFF), 2, OS); + else + llvm_unreachable("mov imm8s unsupported register"); + break; + } + case Teak::MOV_imm8u: + EmitConstant(0x2100 | (encodeAxlOp(MI.getOperand(0).getReg()) << 12) | (MI.getOperand(1).getImm() & 0xFF), 2, OS); + break; case Teak::MOV_ab_ab: EmitConstant(0xD290 | (encodeAbOp(MI.getOperand(1).getReg()) << 10) | (encodeAbOp(MI.getOperand(0).getReg()) << 5), 2, OS); break; @@ -590,11 +703,14 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, case Teak::MOV_regnobp016_ab: case Teak::MOV_regnobp016_abl: case Teak::MOV_p0_ab: - case Teak::MOV_p0_regnob16: { unsigned dstReg = MI.getOperand(0).getReg(); if(MI.getOpcode() == Teak::MOV_regnobp016_abl) dstReg = teakGetAbLReg(dstReg); + + if(MI.getOperand(1).getReg() == Teak::P0 && !TeakMCRegisterClasses[Teak::ABRegsRegClassID].contains(dstReg)) + llvm_unreachable("Register P0 can only be moved to ABx!"); + if(MI.getOperand(1).getReg() == Teak::R6) { if(TeakMCRegisterClasses[Teak::BRegsRegClassID].contains(dstReg)) @@ -614,12 +730,16 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, break; } case Teak::MOV_regnob16_memrn: + case Teak::MOV_regnob16_memrn_postinc: case Teak::MOV_regnob16_memrn_postdec: case Teak::MOV_abl_memrn: { - TeakStepZIDS::Steps step = - MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec ? TeakStepZIDS::SubOne : TeakStepZIDS::Zero; - int opOffset = MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec ? 1 : 0; + TeakStepZIDS::Steps step = TeakStepZIDS::Zero; + if (MI.getOpcode() == Teak::MOV_regnob16_memrn_postdec) + step = TeakStepZIDS::SubOne; + else if (MI.getOpcode() == Teak::MOV_regnob16_memrn_postinc) + step = TeakStepZIDS::AddOne; + int opOffset = step == TeakStepZIDS::Zero ? 0 : 1; unsigned reg = MI.getOperand(opOffset).getReg(); if(MI.getOpcode() == Teak::MOV_abl_memrn) reg = teakGetAbLReg(reg); @@ -642,13 +762,17 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, break; } case Teak::MOV_memrn_regnob16: + case Teak::MOV_memrn_regnob16_postinc: case Teak::MOV_memrn_regnob16_postdec: case Teak::MOV_memrn_ab: case Teak::MOV_memrn_ab1: { unsigned dstReg = MI.getOperand(0).getReg(); - TeakStepZIDS::Steps step = - MI.getOpcode() == Teak::MOV_memrn_regnob16_postdec ? TeakStepZIDS::SubOne : TeakStepZIDS::Zero; + TeakStepZIDS::Steps step = TeakStepZIDS::Zero; + if (MI.getOpcode() == Teak::MOV_memrn_regnob16_postdec) + step = TeakStepZIDS::SubOne; + else if (MI.getOpcode() == Teak::MOV_memrn_regnob16_postinc) + step = TeakStepZIDS::AddOne; if(MI.getOpcode() == Teak::MOV_memrn_ab1) dstReg = teakGetAbLReg(dstReg); if(dstReg == Teak::R6) @@ -693,6 +817,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, } break; } + case Teak::MPYI_y0_imm8s: + EmitConstant(0x0800 | (MI.getOperand(2).getImm() & 0xFF), 2, OS); + break; case Teak::MPY_y0_regnob16: if(MI.getOperand(2).getReg() == Teak::R6) EmitConstant(0x5EA0, 2, OS); @@ -702,6 +829,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, case Teak::NEG_a: EmitConstant(0x6790 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS); break; + case Teak::NOP: + EmitConstant(0, 2, OS); + break; case Teak::NOT_a: EmitConstant(0x6780 | (encodeAxOp(MI.getOperand(0).getReg()) << 12) | MI.getOperand(2).getImm(), 2, OS); break; @@ -888,6 +1018,17 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, EmitConstant(0x4980 | swapOp, 2, OS); break; } + case Teak::TST0_imm16_RegNoBRegs16: + if (MI.getOperand(1).getReg() == Teak::R6) + EmitConstant(0x47BC, 2, OS); + else + EmitConstant(0x89E0 | encodeRegisterOp(MI.getOperand(1).getReg()), 2, OS); + EmitConstant(MI.getOperand(0).getImm() & 0xFFFF, 2, OS); + break; + case Teak::TST0_imm16_memrn: + EmitConstant(0x88E0 | encodeRnOp(MI.getOperand(1).getReg()), 2, OS); + EmitConstant(MI.getOperand(0).getImm() & 0xFFFF, 2, OS); + break; case Teak::PUSH_regnob16: { unsigned reg = MI.getOperand(0).getReg(); @@ -902,6 +1043,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, case Teak::PUSH_ararpsttmod: EmitConstant(0xD3D0 | encodeArArpSttModOp(MI.getOperand(0).getReg()), 2, OS); break; + case Teak::PUSH_abe: + EmitConstant(0xD7C8 | (encodeAbeOp(MI.getOperand(0).getReg()) << 1), 2, OS); + break; case Teak::POP_regnob16: { unsigned reg = MI.getOperand(0).getReg(); @@ -916,6 +1060,9 @@ void TeakMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS, case Teak::POP_ararpsttmod: EmitConstant(0x80C7 | (encodeArArpSttModOp(MI.getOperand(0).getReg()) << 8), 2, OS); break; + case Teak::POP_abe: + EmitConstant(0x47B4 | encodeAbeOp(MI.getOperand(0).getReg()), 2, OS); + break; case Teak::RET: EmitConstant(0x4580 | MI.getOperand(0).getImm(), 2, OS); break; diff --git a/llvm/lib/Target/Teak/MCTargetDesc/TeakMCTargetDesc.cpp b/llvm/lib/Target/Teak/MCTargetDesc/TeakMCTargetDesc.cpp index a9452e310de..49448582935 100644 --- a/llvm/lib/Target/Teak/MCTargetDesc/TeakMCTargetDesc.cpp +++ b/llvm/lib/Target/Teak/MCTargetDesc/TeakMCTargetDesc.cpp @@ -1,25 +1,17 @@ -//===-- TeakMCTargetDesc.cpp - Teak Target Descriptions -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file provides Teak specific target descriptions. -// -//===----------------------------------------------------------------------===// - #include "../TargetInfo/TeakTargetInfo.h" +#include "llvm/MC/MCAsmBackend.h" #include "TeakMCTargetDesc.h" #include "InstPrinter/TeakInstPrinter.h" #include "TeakMCAsmInfo.h" +#include "TeakELFStreamer.h" //\#include "llvm/MC/MCCodeGenInfo.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCObjectWriter.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/TargetRegistry.h" @@ -77,36 +69,45 @@ static MCAsmInfo *createTeakMCAsmInfo(const MCRegisterInfo &MRI, // return X; // } -static MCInstPrinter * -createTeakMCInstPrinter(const Triple &TT, unsigned SyntaxVariant, - const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI) { - return new TeakInstPrinter(MAI, MII, MRI); +static MCInstPrinter* createTeakMCInstPrinter(const Triple &TT, unsigned SyntaxVariant, + const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI) +{ + return new TeakInstPrinter(MAI, MII, MRI); +} + +static MCStreamer* createTeakMCStreamer(const Triple &T, MCContext &Context, + std::unique_ptr &&MAB, std::unique_ptr &&OW, + std::unique_ptr &&Emitter, bool RelaxAll) +{ + return createTeakELFStreamer(Context, std::move(MAB), std::move(OW), std::move(Emitter), RelaxAll); } // Force static initialization. -extern "C" void LLVMInitializeTeakTargetMC() { - // Register the MC asm info. - RegisterMCAsmInfoFn X(getTheTeakTarget(), createTeakMCAsmInfo); +extern "C" void LLVMInitializeTeakTargetMC() +{ + // Register the MC asm info. + RegisterMCAsmInfoFn X(getTheTeakTarget(), createTeakMCAsmInfo); - // Register the MC codegen info. - //TargetRegistry::RegisterMCCodeGenInfo(getTheTeakTarget(), createTeakMCCodeGenInfo); + // Register the MC codegen info. + //TargetRegistry::RegisterMCCodeGenInfo(getTheTeakTarget(), createTeakMCCodeGenInfo); - // Register the MC instruction info. - TargetRegistry::RegisterMCInstrInfo(getTheTeakTarget(), createTeakMCInstrInfo); + // Register the MC instruction info. + TargetRegistry::RegisterMCInstrInfo(getTheTeakTarget(), createTeakMCInstrInfo); - // Register the MC register info. - TargetRegistry::RegisterMCRegInfo(getTheTeakTarget(), createTeakMCRegisterInfo); + // Register the MC register info. + TargetRegistry::RegisterMCRegInfo(getTheTeakTarget(), createTeakMCRegisterInfo); - // Register the MC subtarget info. - TargetRegistry::RegisterMCSubtargetInfo(getTheTeakTarget(), createTeakMCSubtargetInfo); + // Register the MC subtarget info. + TargetRegistry::RegisterMCSubtargetInfo(getTheTeakTarget(), createTeakMCSubtargetInfo); - // Register the MCInstPrinter - TargetRegistry::RegisterMCInstPrinter(getTheTeakTarget(), createTeakMCInstPrinter); + // Register the MCInstPrinter + TargetRegistry::RegisterMCInstPrinter(getTheTeakTarget(), createTeakMCInstPrinter); - // Register the ASM Backend. - TargetRegistry::RegisterMCAsmBackend(getTheTeakTarget(), createTeakAsmBackend); + // Register the ASM Backend. + TargetRegistry::RegisterMCAsmBackend(getTheTeakTarget(), createTeakAsmBackend); - // Register the MCCodeEmitter - TargetRegistry::RegisterMCCodeEmitter(getTheTeakTarget(), createTeakMCCodeEmitter); + // Register the MCCodeEmitter + TargetRegistry::RegisterMCCodeEmitter(getTheTeakTarget(), createTeakMCCodeEmitter); + + TargetRegistry::RegisterELFStreamer(getTheTeakTarget(), createTeakMCStreamer); } \ No newline at end of file diff --git a/llvm/lib/Target/Teak/Teak.h b/llvm/lib/Target/Teak/Teak.h index 15b3c1956fe..589e6157773 100644 --- a/llvm/lib/Target/Teak/Teak.h +++ b/llvm/lib/Target/Teak/Teak.h @@ -23,7 +23,8 @@ namespace llvm class TargetMachine; class TeakTargetMachine; - FunctionPass *createTeakISelDag(TeakTargetMachine &TM, CodeGenOpt::Level OptLevel); + FunctionPass* createTeakISelDag(TeakTargetMachine &TM, CodeGenOpt::Level OptLevel); + FunctionPass* createTeakOptimizeMovImmPass(); namespace TeakCC { @@ -100,6 +101,31 @@ namespace llvm } } + inline static unsigned teakGetAbReg(unsigned reg) + { + switch(reg) + { + case Teak::A0: return Teak::A0; + case Teak::A0L: return Teak::A0; + case Teak::A0H: return Teak::A0; + case Teak::A0E: return Teak::A0; + case Teak::A1: return Teak::A1; + case Teak::A1L: return Teak::A1; + case Teak::A1H: return Teak::A1; + case Teak::A1E: return Teak::A1; + case Teak::B0: return Teak::B0; + case Teak::B0L: return Teak::B0; + case Teak::B0H: return Teak::B0; + case Teak::B0E: return Teak::B0; + case Teak::B1: return Teak::B1; + case Teak::B1L: return Teak::B1; + case Teak::B1H: return Teak::B1; + case Teak::B1E: return Teak::B1; + default: + llvm_unreachable("Invalid reg"); + } + } + inline static unsigned teakGetAbLReg(unsigned reg) { switch(reg) @@ -133,6 +159,23 @@ namespace llvm llvm_unreachable("Invalid reg"); } } + + inline static unsigned teakGetAbEReg(unsigned reg) + { + switch(reg) + { + case Teak::A0: return Teak::A0E; + case Teak::A0E: return Teak::A0E; + case Teak::A1: return Teak::A1E; + case Teak::A1E: return Teak::A1E; + case Teak::B0: return Teak::B0E; + case Teak::B0E: return Teak::B0E; + case Teak::B1: return Teak::B1E; + case Teak::B1E: return Teak::B1E; + default: + llvm_unreachable("Invalid reg"); + } + } } // end namespace llvm; #endif \ No newline at end of file diff --git a/llvm/lib/Target/Teak/TeakCallingConv.td b/llvm/lib/Target/Teak/TeakCallingConv.td index 07655f43a5b..37d73fa8d9d 100644 --- a/llvm/lib/Target/Teak/TeakCallingConv.td +++ b/llvm/lib/Target/Teak/TeakCallingConv.td @@ -55,5 +55,5 @@ def CC_Teak : CallingConv<[ //CCIfType<[i32], CCAssignToStack<4, 4>> ]>; -def CSR : CalleeSavedRegs<(add Y0, Y1, R0, R1, R2, R3, R4, R5, R6, R7)>; +def CSR : CalleeSavedRegs<(add Y0, Y1, R0, R1, R2, R3, R4, R5, R6, R7, (sequence "PAGE%u", 0, 39))>; def CSR_NoRegs : CalleeSavedRegs<(add)>; \ No newline at end of file diff --git a/llvm/lib/Target/Teak/TeakFrameLowering.cpp b/llvm/lib/Target/Teak/TeakFrameLowering.cpp index fb63ecf1d0e..e4ec72e98bc 100644 --- a/llvm/lib/Target/Teak/TeakFrameLowering.cpp +++ b/llvm/lib/Target/Teak/TeakFrameLowering.cpp @@ -86,33 +86,36 @@ uint64_t TeakFrameLowering::computeStackSize(MachineFunction &MF) const { void TeakFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { - // Compute the stack size, to determine if we need a prologue at all. - const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); - MachineBasicBlock::iterator MBBI = MBB.begin(); - DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); - uint64_t StackSize = computeStackSize(MF); - if (!StackSize) - return; + // Compute the stack size, to determine if we need a prologue at all. + const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); + MachineBasicBlock::iterator MBBI = MBB.begin(); + DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); + uint64_t StackSize = computeStackSize(MF); + if (!StackSize) + return; - MachineFrameInfo& MFI = MF.getFrameInfo(); - const std::vector& CSI = MFI.getCalleeSavedInfo(); + MachineFrameInfo& MFI = MF.getFrameInfo(); + const std::vector& CSI = MFI.getCalleeSavedInfo(); - StackSize -= CSI.size() * 2; + StackSize -= CSI.size() * 2; - if (!StackSize) - return; + if (!StackSize) + return; - BuildMI(MBB, MBBI, dl, TII.get(Teak::PUSH_regnob16), Teak::R7) - .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, dl, TII.get(Teak::PUSH_regnob16), Teak::R7) + .setMIFlag(MachineInstr::FrameSetup); - BuildMI(MBB, MBBI, dl, TII.get(Teak::MOV_regnobp016_regnob16), Teak::R7) - .addReg(Teak::SP) - .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, dl, TII.get(Teak::MOV_regnobp016_regnob16), Teak::R7) + .addReg(Teak::SP) + .setMIFlag(MachineInstr::FrameSetup); - BuildMI(MBB, MBBI, dl, TII.get(Teak::ADDV_imm16_RegNoBRegs16), Teak::SP) - .addImm(-(StackSize >> 1)) - .addReg(Teak::SP) - .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, dl, TII.get(Teak::ADDV_imm16_RegNoBRegs16), Teak::SP) + .addImm(-(StackSize >> 1)) + .addReg(Teak::SP) + .setMIFlag(MachineInstr::FrameSetup); + + BuildMI(MBB, MBBI, dl, TII.get(Teak::NOP)) + .setMIFlag(MachineInstr::FrameSetup); } void TeakFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const @@ -136,6 +139,8 @@ void TeakFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB BuildMI(MBB, MBBI, dl, TII.get(Teak::MOV_regnobp016_regnob16), Teak::SP) .addReg(Teak::R7) .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, dl, TII.get(Teak::NOP)) + .setMIFlag(MachineInstr::FrameSetup); BuildMI(MBB, MBBI, dl, TII.get(Teak::POP_regnob16), Teak::R7) .setMIFlag(MachineInstr::FrameSetup); } diff --git a/llvm/lib/Target/Teak/TeakISelLowering.cpp b/llvm/lib/Target/Teak/TeakISelLowering.cpp index 22f97cd1560..52e553b2b4b 100644 --- a/llvm/lib/Target/Teak/TeakISelLowering.cpp +++ b/llvm/lib/Target/Teak/TeakISelLowering.cpp @@ -73,6 +73,7 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM) addRegisterClass(MVT::i16, &Teak::ABLRegsRegClass); //addRegisterClass(MVT::i16, &Teak::ALRegsRegClass); addRegisterClass(MVT::i16, &Teak::RegNoBRegs16_nohRegClass); + // addRegisterClass(MVT::i16, &Teak::RegNoBRegs16_noh_pageRegClass); //addRegisterClass(MVT::i16, &Teak::Y0RegsRegClass); //addRegisterClass(MVT::i32, &Teak::P0RegsRegClass); //addRegisterClass(MVT::i16, &Teak::ABHRegsRegClass); @@ -99,6 +100,7 @@ TeakTargetLowering::TeakTargetLowering(const TeakTargetMachine &TeakTM) setOperationAction(ISD::ADD, MVT::i16, Custom); setOperationAction(ISD::SUB, MVT::i16, Custom); + setOperationAction(ISD::MUL, MVT::i16, Custom); setOperationAction(ISD::AND, MVT::i16, Custom); setOperationAction(ISD::AND, MVT::i40, Custom); setOperationAction(ISD::XOR, MVT::i16, Custom); @@ -240,36 +242,35 @@ bool TeakTargetLowering::isNarrowingProfitable(EVT VT1, EVT VT2) const bool TeakTargetLowering::getPostIndexedAddressParts(SDNode* N, SDNode* Op, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, SelectionDAG &DAG) const { - return false; + SDLoc DL(N); + const LoadSDNode* ld = dyn_cast(N); + const StoreSDNode* st = dyn_cast(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(Op->getOperand(1))) + { + int rhsc = rhs->getSExtValue(); + if (Op->getOpcode() == ISD::SUB) + rhsc = -rhsc; + if (rhsc != 1 && rhsc != -1) + return false; + + Base = Op->getOperand(0); + Offset = DAG.getConstant(rhsc, DL, MVT::i16); + AM = ISD::POST_INC; + + return true; + } + // dbgs() << "getPostIndexedAddressParts\n"; + // EVT VT; // SDLoc DL(N); - // const LoadSDNode* ld = dyn_cast(N); - // if (!ld) - // return false; - // if(ld->getMemoryVT() != MVT::i16) - // return false; - // if (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB) - // return false; - - // if (const ConstantSDNode* rhs = dyn_cast(Op->getOperand(1))) - // { - // int rhsc = rhs->getSExtValue(); - // if (Op->getOpcode() == ISD::SUB) - // rhsc = -rhsc; - // if (rhsc != 1 && rhsc != -1) - // return false; - - // Base = Op->getOperand(0); - // Offset = DAG.getConstant(rhsc, DL, MVT::i16); - // AM = ISD::POST_INC; - - // return true; - // } - // // dbgs() << "getPostIndexedAddressParts\n"; - // // EVT VT; - // // SDLoc DL(N); - // // Op->dump(); - // // N->dump(); - // return false; + // Op->dump(); + // N->dump(); + return false; } bool TeakTargetLowering::allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace, @@ -376,10 +377,10 @@ SDValue TeakTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const SDValue CompareFlag; if (LHS.getValueType().isInteger()) { - CompareFlag = DAG.getNode(TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS); Opc = TeakISD::SELECT_ICC; if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); + CompareFlag = DAG.getNode((SPCC == TeakCC::Eq || SPCC == TeakCC::Neq) ? TeakISD::CMPZICC : TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS); } else llvm_unreachable("!LHS.getValueType().isInteger()"); @@ -415,10 +416,10 @@ SDValue TeakTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const SDValue CompareFlag; if (LHS.getValueType().isInteger()) { - CompareFlag = DAG.getNode(TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS); if (SPCC == ~0U) SPCC = IntCondCCodeToICC(CC); - // 32-bit compares use the icc flags, 64-bit uses the xcc flags. + + CompareFlag = DAG.getNode((SPCC == TeakCC::Eq || SPCC == TeakCC::Neq) ? TeakISD::CMPZICC : TeakISD::CMPICC, dl, MVT::Glue, LHS, RHS); Opc = TeakISD::BRICC; } else @@ -454,13 +455,9 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const const SDNode *N = Op.getNode(); SDLoc dl(N); assert(N->getValueType(0) == MVT::i16 && "Unexpected custom legalisation"); - //this seems to give problems for some reason - // if(isa(N->getOperand(1))) - // { - // dbgs() << "constant!\n"; - // return Op; - // } - //dbgs() << "Lowering!\n"; + if(isa(N->getOperand(1))) + return DAG.getNode(Op.getOpcode(), dl, MVT::i16, N->getOperand(0), N->getOperand(1)); + SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i40, N->getOperand(0)); SDValue NewOp1 = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i40, N->getOperand(1)); SDValue NewWOp = DAG.getNode(Op.getOpcode(), dl, MVT::i40, NewOp0, NewOp1); @@ -495,6 +492,13 @@ SDValue TeakTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const SDValue NewWOp = DAG.getNode(nodeType, dl, MVT::i40, NewOp0, NewOp1); return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, NewWOp); } + case ISD::MUL: + { + const SDNode *N = Op.getNode(); + SDLoc dl(N); + assert(N->getValueType(0) == MVT::i16 && "Unexpected custom legalisation"); + return DAG.getNode(ISD::TRUNCATE, dl, MVT::i16, DAG.getNode(TeakISD::MPY, dl, MVT::i40, N->getOperand(0), N->getOperand(1))); + } case ISD::SHL: { const SDNode *N = Op.getNode(); diff --git a/llvm/lib/Target/Teak/TeakISelLowering.h b/llvm/lib/Target/Teak/TeakISelLowering.h index d574d4b9231..3639e0181b7 100644 --- a/llvm/lib/Target/Teak/TeakISelLowering.h +++ b/llvm/lib/Target/Teak/TeakISelLowering.h @@ -36,6 +36,7 @@ enum NodeType { MOVEi32, CALL, CMPICC, + CMPZICC, BRICC, SELECT_ICC, WRAPPER, @@ -43,7 +44,10 @@ enum NodeType { SHIFT_LOGIC, AND, OR, - XOR + XOR, + ADD, + SUB, + MPY }; } diff --git a/llvm/lib/Target/Teak/TeakInstrInfo.cpp b/llvm/lib/Target/Teak/TeakInstrInfo.cpp index a35d7d4a621..74964374143 100644 --- a/llvm/lib/Target/Teak/TeakInstrInfo.cpp +++ b/llvm/lib/Target/Teak/TeakInstrInfo.cpp @@ -285,41 +285,82 @@ void TeakInstrInfo::copyPhysReg(MachineBasicBlock &MBB, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const { - MachineFunction &MF = *MBB.getParent(); - const TeakSubtarget &st = MF.getSubtarget(); - dbgs() << "copyPhysReg(" << SrcReg.id() << ", " << DestReg.id() << ")\n"; - unsigned op; - // if(Teak::ARegsRegClass.contains(SrcReg) && Teak::ARegsRegClass.contains(DestReg) && SrcReg != DestReg) - // op = Teak::COPY_a; - // else - if(Teak::ABRegsRegClass.contains(SrcReg) && Teak::ABRegsRegClass.contains(DestReg)) - 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"); + MachineFunction &MF = *MBB.getParent(); + const TeakSubtarget &st = MF.getSubtarget(); + const TargetRegisterInfo *RegInfo = st.getRegisterInfo(); + bool keepFlags = MBB.computeRegisterLiveness(RegInfo, Teak::ICC, I) != MachineBasicBlock::LQR_Dead; + dbgs() << "copyPhysReg(" << SrcReg.id() << ", " << DestReg.id() << ")\n"; + unsigned op; + // if(Teak::ABLRegsRegClass.contains(DestReg)) + // { + // // unsigned fullDst = teakGetAbReg(DestReg.id()); + // // unsigned hiDst = teakGetAbHReg(fullDst); - const TargetRegisterInfo *RegInfo = st.getRegisterInfo(); - if (MBB.computeRegisterLiveness(RegInfo, Teak::ICC, I) == MachineBasicBlock::LQR_Dead) - { - 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); - 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"); - } + // // //special handling for subreg copies, which cannot be done directly + // // // if(keepFlags) + // // // BuildMI(MBB, I, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); + // // // BuildMI(MBB, I, DL, get(Teak::RST_imm16_regnob16), DestReg) + // // // .addImm(0xFFFF) + // // // .addReg(DestReg); + // // // if(keepFlags) + // // // BuildMI(MBB, I, DL, get(Teak::POP_ararpsttmod), Teak::STT0); + // // bool hiAlive = MBB.computeRegisterLiveness(RegInfo, hiDst, I) != MachineBasicBlock::LQR_Dead; + // // dbgs() << "Hi dst alive: " << hiAlive << "\n"; + // // if(hiAlive) + // // { + // llvm_unreachable("Invalid low destination register!"); + // return; + // // } + // } + // else if(Teak::ABHRegsRegClass.contains(DestReg)) + // { + // llvm_unreachable("Invalid high destination register!"); + // return; + // } + // if(Teak::ARegsRegClass.contains(SrcReg) && Teak::ARegsRegClass.contains(DestReg) && SrcReg != DestReg) + // op = Teak::COPY_a; + // else + if(Teak::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, @@ -457,110 +498,90 @@ bool TeakInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TBB, unsigned TCycles return true; } +void TeakInstrInfo::makeRnRegDisplacement(MachineBasicBlock& mbb, MachineInstr& mi, const DebugLoc& dl, Register reg, signed short offset) const +{ + if(offset == 0) + return; + + if(offset == 1) + BuildMI(mbb, mi, dl, get(Teak::MODR_inc1), reg) + .addReg(reg); + else if(offset == -1) + BuildMI(mbb, mi, dl, get(Teak::MODR_dec1), reg) + .addReg(reg); + else if(offset == 2) + BuildMI(mbb, mi, dl, get(Teak::MODR_inc2), reg) + .addReg(reg); + else if(offset == -2) + BuildMI(mbb, mi, dl, get(Teak::MODR_dec2), reg) + .addReg(reg); + else + BuildMI(mbb, mi, dl, get(Teak::ADDV_imm16_RegNoBRegs16), reg) + .addImm(offset) + .addReg(reg); +} + bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { - DebugLoc DL = MI.getDebugLoc(); - MachineBasicBlock &MBB = *MI.getParent(); - MachineFunction &MF = *MBB.getParent(); - const TeakSubtarget &st = MF.getSubtarget(); - const TargetRegisterInfo *RegInfo = st.getRegisterInfo(); - dbgs() << "Expand post, live: " << MBB.computeRegisterLiveness(RegInfo, Teak::ICC, MI) << "\n"; - bool keepFlags = MBB.computeRegisterLiveness(RegInfo, Teak::ICC, MI) != MachineBasicBlock::LQR_Dead; - switch (MI.getOpcode()) - { - default: - return false; - case Teak::STORE_REG_TO_STACK_PSEUDO_16: - { - dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_16\n"; - signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2; - 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) + DebugLoc DL = MI.getDebugLoc(); + MachineBasicBlock &MBB = *MI.getParent(); + MachineFunction &MF = *MBB.getParent(); + const TeakSubtarget &st = MF.getSubtarget(); + const TargetRegisterInfo *RegInfo = st.getRegisterInfo(); + dbgs() << "Expand post, live: " << MBB.computeRegisterLiveness(RegInfo, Teak::ICC, MI) << "\n"; + bool keepFlags = MBB.computeRegisterLiveness(RegInfo, Teak::ICC, MI) != MachineBasicBlock::LQR_Dead; + switch (MI.getOpcode()) + { + default: + return false; + case Teak::STORE_REG_TO_STACK_PSEUDO_16: + { + dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_16\n"; + signed short frameOffset = (signed short)MI.getOperand(2).getImm(); + if(keepFlags && frameOffset) + BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset); + BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn)) + .addReg(MI.getOperand(0).getReg(), getKillRegState(MI.getOperand(0).isKill())) .addReg(MI.getOperand(1).getReg()); - BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn)) - .addReg(MI.getOperand(0).getReg(), getKillRegState(MI.getOperand(0).isKill())) - .addReg(MI.getOperand(1).getReg()); - if(frameOffset) - BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) - .addImm(-frameOffset) - .addReg(MI.getOperand(1).getReg()); - if(keepFlags && frameOffset) - BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); - MBB.erase(MI); - return true; - } + 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_TRUNC16: - { - dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_TRUNC16\n"; - unsigned srcReg = MI.getOperand(0).getReg(); - unsigned loReg; - if(srcReg == Teak::A0) - loReg = Teak::A0L; - else if(srcReg == Teak::A1) - loReg = Teak::A1L; - else if(srcReg == Teak::B0) - loReg = Teak::B0L; - else if(srcReg == Teak::B1) - loReg = Teak::B1L; - signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2; - 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) + case Teak::STORE_REG_TO_STACK_PSEUDO_TRUNC16: + { + dbgs() << "expandPostRAPseudo for STORE_REG_TO_STACK_PSEUDO_TRUNC16\n"; + unsigned srcReg = MI.getOperand(0).getReg(); + unsigned loReg = teakGetAbLReg(srcReg); + signed short frameOffset = (signed short)MI.getOperand(2).getImm(); + if(keepFlags && frameOffset) + BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset); + BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn)) + .addReg(loReg, getKillRegState(MI.getOperand(0).isKill())) .addReg(MI.getOperand(1).getReg()); - if(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)) .addReg(hiReg, getKillRegState(MI.getOperand(0).isKill())) .addReg(MI.getOperand(1).getReg()); @@ -568,38 +589,33 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const .addReg(loReg, getKillRegState(MI.getOperand(0).isKill())) .addReg(Teak::R7) .addImm(-1); - if(frameOffset) - BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) - .addImm(-frameOffset) - .addReg(MI.getOperand(1).getReg()); - } - else - { + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset); + } + else + { BuildMI(MBB, MI, DL, get(Teak::MOV_regnob16_memrn_postdec), MI.getOperand(1).getReg()) .addReg(hiReg, getKillRegState(MI.getOperand(0).isKill())) .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()); - BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) - .addImm(-frameOffset + 1) - .addReg(MI.getOperand(1).getReg()); - } - if(keepFlags) - BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); - MBB.erase(MI); - return true; - } + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset + 1); + } + 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: - { - dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16\n"; - unsigned dstReg = MI.getOperand(0).getReg(); - signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2; - if(keepFlags) - BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); - if(dstReg == Teak::A0L || dstReg == Teak::A1L) - { + case Teak::LOAD_REG_FROM_STACK_PSEUDO_16: + { + dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16\n"; + unsigned dstReg = MI.getOperand(0).getReg(); + signed short frameOffset = (signed short)MI.getOperand(2).getImm(); + if(keepFlags) + BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); + if(dstReg == Teak::A0L || dstReg == Teak::A1L) + { if(frameOffset >= -64 && frameOffset <= 63) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg == Teak::A0L ? Teak::A0 : Teak::A1) .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) .addReg(Teak::R7) .addImm(frameOffset); - } - else - { - if(frameOffset) - BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) - .addImm(frameOffset) + } + else + { + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset); + BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_regnob16), dstReg) .addReg(MI.getOperand(1).getReg()); - BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_regnob16), dstReg) - .addReg(MI.getOperand(1).getReg()); - if(frameOffset) - BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) - .addImm(-frameOffset) - .addReg(MI.getOperand(1).getReg()); - } - if(keepFlags) - BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); - MBB.erase(MI); - return true; - } + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset); + } + 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: - { - dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40\n"; - unsigned dstReg = MI.getOperand(0).getReg(); - signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2; - if(keepFlags) - BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); - if(dstReg == Teak::A0 || dstReg == Teak::A1) - { + case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40: + { + dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_SEXT40\n"; + unsigned dstReg = MI.getOperand(0).getReg(); + signed short frameOffset = (signed short)MI.getOperand(2).getImm(); + if(keepFlags) + BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); + if(dstReg == Teak::A0 || dstReg == Teak::A1) + { if(frameOffset >= -64 && frameOffset <= 63) BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg) .addReg(Teak::R7) @@ -645,207 +655,228 @@ bool TeakInstrInfo::expandPostRAPseudo(MachineInstr &MI) const BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg) .addReg(Teak::R7) .addImm(frameOffset); - } - else - { - if(frameOffset) - BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) - .addImm(frameOffset) + } + else + { + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset); + BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab), dstReg) .addReg(MI.getOperand(1).getReg()); - BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab), dstReg) - .addReg(MI.getOperand(1).getReg()); - if(frameOffset) - BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) - .addImm(-frameOffset) - .addReg(MI.getOperand(1).getReg()); - if(keepFlags) - BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); - } - MBB.erase(MI); - return true; - } + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset); + 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: - { - dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40\n"; - 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) + case Teak::LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40: + { + dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_16_ZEXT40\n"; + signed short frameOffset = (signed short)MI.getOperand(2).getImm(); + if(keepFlags) + BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), frameOffset); + BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab1), MI.getOperand(0).getReg()) .addReg(MI.getOperand(1).getReg()); - BuildMI(MBB, MI, DL, get(Teak::MOV_memrn_ab1), MI.getOperand(0).getReg()) - .addReg(MI.getOperand(1).getReg()); - if(frameOffset) - BuildMI(MBB, MI, DL, get(Teak::ADDV_imm16_RegNoBRegs16), MI.getOperand(1).getReg()) - .addImm(-frameOffset) - .addReg(MI.getOperand(1).getReg()); - if(keepFlags) - BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); - MBB.erase(MI); - return true; - } - case Teak::LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40: - { - dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40\n"; - unsigned dstReg = MI.getOperand(0).getReg(); - signed short frameOffset = (signed short)MI.getOperand(2).getImm();// / 2; - if(keepFlags) - BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); - if(dstReg == Teak::A0 || dstReg == Teak::A1) - { - if(frameOffset >= -64 && frameOffset <= 63) - BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg) - .addReg(Teak::R7) - .addImm(frameOffset); - else - BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg) - .addReg(Teak::R7) - .addImm(frameOffset); - BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), dstReg) - .addReg(dstReg) - .addImm(16); - if(frameOffset - 1 >= -64 && frameOffset - 1 <= 63) - BuildMI(MBB, MI, DL, get(Teak::OR_r7offset7s_a), dstReg) - .addReg(Teak::R7) - .addImm(frameOffset - 1) - .addReg(dstReg); - else - BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), dstReg) - .addReg(Teak::R7) - .addImm(frameOffset - 1) - .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) + makeRnRegDisplacement(MBB, MI, DL, MI.getOperand(1).getReg(), -frameOffset); + if(keepFlags) + BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); + MBB.erase(MI); + return true; + } + case Teak::LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40: + { + dbgs() << "expandPostRAPseudo for LOAD_REG_FROM_STACK_PSEUDO_32_SEXT40\n"; + unsigned dstReg = MI.getOperand(0).getReg(); + signed short frameOffset = (signed short)MI.getOperand(2).getImm(); + if(keepFlags) + BuildMI(MBB, MI, DL, get(Teak::PUSH_ararpsttmod), Teak::STT0); + if(dstReg == Teak::A0 || dstReg == Teak::A1) + { + if(frameOffset >= -64 && frameOffset <= 63) + BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset7s_a), dstReg) + .addReg(Teak::R7) + .addImm(frameOffset); + else + BuildMI(MBB, MI, DL, get(Teak::MOV_r7offset16_a), dstReg) + .addReg(Teak::R7) + .addImm(frameOffset); + BuildMI(MBB, MI, DL, get(Teak::SHFI_arith_ab_ab), dstReg) + .addReg(dstReg) + .addImm(16); + if(frameOffset - 1 >= -64 && frameOffset - 1 <= 63) + BuildMI(MBB, MI, DL, get(Teak::OR_r7offset7s_a), dstReg) + .addReg(Teak::R7) + .addImm(frameOffset - 1) + .addReg(dstReg); + else + BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), dstReg) + .addReg(Teak::R7) + .addImm(frameOffset - 1) + .addReg(dstReg); + } + else + { + BuildMI(MBB, MI, DL, get(Teak::MOV_ab_ab), dstReg) .addReg(Teak::A0); - else - BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), Teak::A0) - .addReg(Teak::R7) - .addImm(frameOffset - 1) - .addReg(Teak::A0); - BuildMI(MBB, MI, DL, get(Teak::SWAP_ab)) - .addReg(dstReg, RegState::Define) - .addReg(Teak::A0, RegState::Define) - .addReg(Teak::A0) - .addReg(dstReg); - } - if(keepFlags) - BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); - 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(); + 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); + else + BuildMI(MBB, MI, DL, get(Teak::OR_r7offset16_a), Teak::A0) + .addReg(Teak::R7) + .addImm(frameOffset - 1) + .addReg(Teak::A0); + BuildMI(MBB, MI, DL, get(Teak::SWAP_ab)) + .addReg(dstReg, RegState::Define) + .addReg(Teak::A0, RegState::Define) + .addReg(Teak::A0) + .addReg(dstReg); + } + if(keepFlags) + BuildMI(MBB, MI, DL, get(Teak::POP_ararpsttmod), Teak::STT0); + MBB.erase(MI); + return true; + } + case Teak::MPYI_y0_imm8s_ab: + case Teak::MPYI_y0_imm8s_ab_ADD: + { + BuildMI(MBB, MI, DL, get(Teak::MPYI_y0_imm8s), Teak::P0) + .addReg(MI.getOperand(1).getReg()) + .addImm(MI.getOperand(2).getImm()); + if (MI.getOpcode() == Teak::MPYI_y0_imm8s_ab_ADD) + BuildMI(MBB, MI, DL, get(Teak::ADD_px_ab), MI.getOperand(0).getReg()) + .addReg(Teak::P0) + .addReg(MI.getOperand(0).getReg()); + else + BuildMI(MBB, MI, DL, get(Teak::MOV_p0_ab), MI.getOperand(0).getReg()) + .addReg(Teak::P0); + MBB.erase(MI); + return true; + } + case Teak::MPY_y0_regnob16_ab: + case Teak::MPY_y0_regnob16_ab_ADD: + { + BuildMI(MBB, MI, DL, get(Teak::MPY_y0_regnob16), Teak::P0) + .addReg(MI.getOperand(1).getReg()) + .addReg(MI.getOperand(2).getReg()); - // const unsigned DstReg = MI->getOperand(0).getReg(); - // const bool DstIsDead = MI->getOperand(0).isDead(); + if (MI.getOpcode() == Teak::MPY_y0_regnob16_ab_ADD) + BuildMI(MBB, MI, DL, get(Teak::ADD_px_ab), MI.getOperand(0).getReg()) + .addReg(Teak::P0) + .addReg(MI.getOperand(0).getReg()); + else + BuildMI(MBB, MI, DL, get(Teak::MOV_p0_ab), MI.getOperand(0).getReg()) + .addReg(Teak::P0); + MBB.erase(MI); + return true; + } + // case Teak::MPY_y0_regnob16_RegNoBRegs16: + // { + // BuildMI(MBB, MI, DL, get(Teak::MPY_y0_regnob16), Teak::P0) + // .addReg(MI.getOperand(1).getReg()) + // .addReg(MI.getOperand(2).getReg()); + // BuildMI(MBB, MI, DL, get(Teak::MOV_p0_regnob16), MI.getOperand(0).getReg()) + // .addReg(Teak::P0); + // MBB.erase(MI); + // return true; + // } + // case Teak::SHL_PSEUDO_ab_ab_sv: + // { + // BuildMI(MBB, MI, DL, get(Teak::MOV_regnobp016_regnob16), Teak::SV) + // .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); - // auto HI16 = BuildMI(MBB, MI, DL, get(Teak::MOVHIi16)) - // .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) - // .addReg(DstReg); + // const MachineOperand &MO = MI->getOperand(1); - // if (MO.isImm()) { - // 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); - // } + // auto LO16 = BuildMI(MBB, MI, DL, get(Teak::MOV_imm16_b), DstReg); + // auto HI16 = BuildMI(MBB, MI, DL, get(Teak::MOVHIi16)) + // .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) + // .addReg(DstReg); - // MBB.erase(MI); - // return true; - // } - // } + // if (MO.isImm()) { + // 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; + // } + // } } \ No newline at end of file diff --git a/llvm/lib/Target/Teak/TeakInstrInfo.h b/llvm/lib/Target/Teak/TeakInstrInfo.h index 0bf0287af85..99bbbddf137 100644 --- a/llvm/lib/Target/Teak/TeakInstrInfo.h +++ b/llvm/lib/Target/Teak/TeakInstrInfo.h @@ -26,6 +26,8 @@ class TeakInstrInfo : public TeakGenInstrInfo { const TeakRegisterInfo RI; virtual void anchor(); + void makeRnRegDisplacement(MachineBasicBlock& mbb, MachineInstr& mi, const DebugLoc& dl, Register reg, signed short offset) const; + public: TeakInstrInfo(); diff --git a/llvm/lib/Target/Teak/TeakInstrInfo.td b/llvm/lib/Target/Teak/TeakInstrInfo.td index ac692b9da40..3606bacf45c 100644 --- a/llvm/lib/Target/Teak/TeakInstrInfo.td +++ b/llvm/lib/Target/Teak/TeakInstrInfo.td @@ -1,6 +1,11 @@ include "TeakInstrFormats.td" include "TeakOperators.td" +// An 'and' node with a single use. +// def and_su : PatFrag<(ops node:$lhs, node:$rhs), (TeakAnd node:$lhs, node:$rhs), [{ +// return N->hasOneUse(); +// }]>; + //def : Pattern<(i32 (load_sym tglobaladdr:$addr)), [(MOVi32 $addr)]>; // def MOVi32 : InstTeak<(outs BRegs:$dst), (ins i32imm:$src), "", @@ -50,6 +55,13 @@ def Imm8u_16 : Operand, ImmLeaf { let Name = "Imm8s_16"; } +def Imm8s_16 : Operand, ImmLeaf= -128 && Imm <= 127; +}]> { + let ParserMatchClass = Imm8s_16AsmOperand; +} + def Imm0_65535AsmOperand: ImmAsmOperand<0,65535> { let Name = "Imm0_65535"; } def imm0_65535 : Operand, ImmLeaf= 0 && Imm < 65536; @@ -147,6 +159,34 @@ def load_postdec : PatFrag<(ops node:$base), let IsNonExtLoad = 1; } +def store_postinc : PatFrag<(ops node:$val, node:$base), + (st node:$val, node:$base), [{ + const StoreSDNode* st = cast(N); + ISD::MemIndexedMode idxMode = st->getAddressingMode(); + if (idxMode != ISD::POST_INC && idxMode != ISD::POST_DEC) + return false; + int offs = cast(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(N); + ISD::MemIndexedMode idxMode = st->getAddressingMode(); + if (idxMode != ISD::POST_INC && idxMode != ISD::POST_DEC) + return false; + int offs = cast(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 { let PrintMethod = "printCondCode"; @@ -168,53 +208,77 @@ def MemR0425 : RegisterOperand // "addv $val, [$addr]", // [(store (add (load GRRegs:$addr), immNeg32768_32767_16:$val), GRRegs:$addr)]>; +def NOP : InstTeak<(outs), (ins), "nop", []>; let Defs = [ICC] in { - let isCommutable = 1, mayStore = 1, mayLoad = 1 in - def ADDV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767_16:$val, GRRegs:$addr), "addv $val, [$addr]", [(store (add (i16 (load GRRegs:$addr)), immNeg32768_32767_16:$val), GRRegs:$addr)]>; + let mayLoad = 1 in + def TST0_imm16_memrn : InstTeakImm16<(outs), (ins imm0_65535_16:$val, GRRegs:$addr), "tst0 $val, [$addr]", [(TeakCmpzICC (i40 (sext (TeakAnd (i16 (load GRRegs:$addr)), imm0_65535_16:$val))), 0)]>; + + def TST0_imm16_RegNoBRegs16 : InstTeakImm16<(outs), (ins imm0_65535_16:$val, RegNoBRegs16:$a), "tst0 $val, $a", [(TeakCmpzICC (i40 (sext (TeakAnd RegNoBRegs16:$a, imm0_65535_16:$val))), 0)]>; + + // let isCommutable = 1, mayStore = 1, mayLoad = 1 in + // def ADDV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, GRRegs:$addr), "addv $val, [$addr]", [(store (i16 (trunc (add (anyext (i16 (load GRRegs:$addr))), immNeg32768_32767:$val))), GRRegs:$addr)]>; + + // let mayStore = 1, mayLoad = 1 in + // def SUBV_imm16_memrn : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, GRRegs:$addr), "subv $val, [$addr]", [(store (i16 (trunc (sub (anyext (i16 (load GRRegs:$addr))), immNeg32768_32767:$val))), GRRegs:$addr)]>; let mayStore = 1, mayLoad = 1 in - def 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))]>; + // let Constraints = "$dst = $a", isCommutable = 1 in + // def ADDV_imm16_RegNoBRegs16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins immNeg32768_32767:$val, RegNoBRegs16:$a), "addv $val, $a", [(set RegNoBRegs16:$dst, (trunc (add (anyext RegNoBRegs16:$a), immNeg32768_32767:$val)))]>; + let Constraints = "$dst = $a" in def SUBV_imm16_RegNoBRegs16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins immNeg32768_32767_16:$val, RegNoBRegs16:$a), "subv $val, $a", [(set RegNoBRegs16:$dst, (sub RegNoBRegs16:$a, immNeg32768_32767_16:$val))]>; - let Constraints = "$dst = $a", isCommutable = 1 in - def INC_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "inc $a, $p", [(set ARegs:$dst, (add ARegs:$a, 1))]>; - - let Constraints = "$dst = $a", isCommutable = 1 in - def DEC_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "dec $a, $p", [(set ARegs:$dst, (add ARegs:$a, -1))]>; - - let Constraints = "$dst = $a", isCommutable = 1 in - def RND_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$a, pred:$p), "rnd $a, $p", [(set ARegs:$dst, (add ARegs:$a, 0x8000))]>; - - let Constraints = "$dst = $a", isCommutable = 1 in - def ADD_imm8u_a : InstTeak<(outs ARegs:$dst), (ins Imm8u:$val, ARegs:$a), "add ${val}u8, $a", [(set ARegs:$dst, (add ARegs:$a, Imm8u:$val))]>; - - let Constraints = "$dst = $a", isCommutable = 1 in - def ADD_imm16_a : InstTeakImm16<(outs ARegs:$dst), (ins immNeg32768_32767:$val, ARegs:$a), "add $val, $a", [(set ARegs:$dst, (add ARegs:$a, immNeg32768_32767:$val))]>; - - let Constraints = "$dst = $a", isCommutable = 1, mayLoad = 1 in - def ADD_memimm16_a : InstTeakImm16<(outs ARegs:$dst), (ins Operand:$addr, ARegs:$a), "add [$addr], $a", [(set ARegs:$dst, (add ARegs:$a, (sextloadi16 imm:$addr)))]>; - - let Constraints = "$dst = $a", isCommutable = 1, mayLoad = 1 in - def ADD_memrn_a : InstTeak<(outs ARegs:$dst), (ins GRRegs:$addr, ARegs:$a), "add [$addr], $a", [(set ARegs:$dst, (add ARegs:$a, (sextloadi16 GRRegs:$addr)))]>; - - let Constraints = "$dst = $a", mayLoad = 1 in - def ADDL_memrn_a : InstTeak<(outs ARegs:$dst), (ins GRRegs:$addr, ARegs:$a), "addl [$addr], $a", [(set ARegs:$dst, (add ARegs:$a, (zextloadi16 GRRegs:$addr)))]>; + // let Constraints = "$dst = $a" in + // def SUBV_imm16_RegNoBRegs16 : InstTeakImm16<(outs RegNoBRegs16:$dst), (ins immNeg32768_32767:$val, RegNoBRegs16:$a), "subv $val, $a", [(set RegNoBRegs16:$dst, (trunc (sub (anyext RegNoBRegs16:$a), immNeg32768_32767:$val)))]>; let Constraints = "$dst = $a" in - def 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 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_imm8u_a : InstTeak<(outs ARegs:$dst), (ins Imm8u:$val, ARegs:$a), "add ${val}u8, $a", [(set ARegs:$dst, (add ARegs:$a, Imm8u:$val))]>; + 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 - def ADD_ab_ab : InstTeak<(outs ABRegs:$dst), (ins ABRegs:$b, ABRegs:$a), "add $b, $a", [(set ABRegs:$dst, (add ABRegs:$a, ABRegs:$b))]>; + let mayLoad = 1 in + { + def ADD_memimm16_a : InstTeakImm16<(outs ARegs:$dst), (ins Operand:$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 //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_regnobp016_a : InstTeak<(outs ARegs:$dst), (ins RegNoBRegs16:$b, ARegs:$a), "xor $b, $a", [(set ARegs:$dst, (TeakXor ARegs:$a, (zext RegNoBRegs16:$b)))]>; // def XOR_regnobp016_al : InstTeak<(outs ALRegs:$dst), (ins RegNoBRegs16:$b, ALRegs:$a), "xor $b, $a", [(set ALRegs:$dst, (TeakXor ALRegs:$a, RegNoBRegs16:$b))]>; + let isCommutable = 1 in def XOR_a_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$b, ARegs:$a), "xor $b, $a", [(set ARegs:$dst, (TeakXor ARegs:$a, ARegs:$b))]>; } - 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 isCommutable = 1 in + { + def AND_ab_ab_a : InstTeak<(outs ARegs:$dst), (ins ABRegs:$b, ABRegs:$a), "and $b, $a, $dst", [(set ARegs:$dst, (TeakAnd ABRegs:$a, ABRegs:$b))]>; + def OR_ab_ab_a : InstTeak<(outs ARegs:$dst), (ins ABRegs:$b, ABRegs:$a), "or $b, $a, $dst", [(set ARegs:$dst, (TeakOr ABRegs:$a, ABRegs:$b))]>; + } let isMoveImm = 1 in { @@ -304,6 +372,8 @@ let Defs = [ICC] in def MOV_imm16neg_ab : InstTeakImm16<(outs ABRegs:$dst), (ins immNeg32768_32767:$val), "mov $val, $dst", [(set ABRegs:$dst, immNeg32768_32767:$val)]>; def MOV_imm16_ab : InstTeakImm16<(outs ABRegs:$dst), (ins imm0_65535:$val), "mov $val, ${dst}l", [(set ABRegs:$dst, imm0_65535:$val)]>; def MOV_imm16_abh : InstTeakImm16<(outs ABRegs:$dst), (ins immUpper16Signed:$val), "mov $val, ${dst}h", [(set ABRegs:$dst, immUpper16Signed:$val)]>; + def MOV_imm8s : InstTeak<(outs MovImm8sRegs:$dst), (ins Imm8s_16:$val), "mov ${val}s8, $dst", []>; + def MOV_imm8u : InstTeak<(outs ALRegs:$dst), (ins Imm8u_16:$val), "mov ${val}u8, $dst", []>; } let isMoveReg = 1 in @@ -312,7 +382,7 @@ let Defs = [ICC] in def COPY_a : InstTeak<(outs ARegs:$dst), (ins ARegs:$src, pred:$p), "copy $dst, $p", []>; def MOV_ab_ab : InstTeak<(outs ABRegs:$dst), (ins ABRegs:$src), "mov $src, $dst", [/*(set ABRegs:$dst, ABRegs:$src)*/]>; def MOV_regnobp016_regnob16 : InstTeak<(outs RegNoBRegs16:$dst), (ins RegNoBRegs16:$src), "mov $src, $dst", [/*(set RegNoBRegs16:$dst, RegNoBRegs16:$src)*/]>; - def MOV_p0_regnob16 : InstTeak<(outs RegNoBRegs16:$dst), (ins P0Regs:$src), "mov $src, $dst", [/*(set RegNoBRegs16:$dst, RegNoBRegs16:$src)*/]>; + //def MOV_p0_regnob16 : InstTeak<(outs RegNoBRegs16:$dst), (ins P0Regs:$src), "mov $src, $dst", [/*(set RegNoBRegs16:$dst, RegNoBRegs16:$src)*/]>; def MOV_regnobp016_ab : InstTeak<(outs ABRegs:$dst), (ins RegNoBRegs16:$src), "mov $src, $dst", [(set ABRegs:$dst, (sext RegNoBRegs16:$src))]>; def MOV_p0_ab : InstTeak<(outs ABRegs:$dst), (ins P0Regs:$src), "mov $src, $dst", [/*(set ABRegs:$dst, (sext P0Regs:$src))*/]>; def MOV_regnobp016_abl : InstTeak<(outs ABRegs:$dst), (ins RegNoBRegs16:$src), "mov $src, ${dst}l", [(set ABRegs:$dst, (zext RegNoBRegs16:$src))]>; @@ -323,10 +393,20 @@ let Defs = [ICC] in def SHFC_arith_ab_ab_sv : InstTeak<(outs ABRegs:$dst), (ins ABRegs:$src, SVReg:$shift, pred:$p), "shfc $src, $dst, $p", [(set ABRegs:$dst, (TeakShiftArith ABRegs:$src, SVReg:$shift))]>; def SHFC_logic_ab_ab_sv : TeakPseudoInst<(outs ABRegs:$dst), (ins ABRegs:$src, SVReg:$shift, pred:$p), "shfc $src, $dst, $p", [(set ABRegs:$dst, (TeakShiftLogic ABRegs:$src, SVReg:$shift))]>; - 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 - def MPY_y0_regnob16_RegNoBRegs16 : TeakPseudoInst<(outs RegNoBRegs16:$dst), (ins Y0Regs:$y, RegNoBRegs16:$x), "mpy $y, $x", [(set RegNoBRegs16:$dst, (mul RegNoBRegs16:$x, Y0Regs:$y))]>; + let Constraints = "$dst = $ab" in + { + def MPYI_y0_imm8s_ab_ADD : TeakPseudoInst<(outs ABRegs:$dst), (ins Y0Regs:$y, Imm8s_16:$x, ABRegs:$ab), "MPYI_y0_imm8s_ab $y, $x, $ab", [(set ABRegs:$dst, (add ABRegs:$ab, (TeakMpy Y0Regs:$y, Imm8s_16:$x)))]>; + def MPY_y0_regnob16_ab_ADD : TeakPseudoInst<(outs ABRegs:$dst), (ins Y0Regs:$y, RegNoBRegs16:$x, ABRegs:$ab), "MPY_y0_regnob16_ab_ADD $y, $x, $ab", [(set ABRegs:$dst, (add ABRegs:$ab, (TeakMpy RegNoBRegs16:$x, Y0Regs:$y)))]>; + } + + def MPYI_y0_imm8s_ab : TeakPseudoInst<(outs ABRegs:$dst), (ins Y0Regs:$y, Imm8s_16:$x), "MPYI_y0_imm8s_ab $y, $x, $dst", [(set ABRegs:$dst, (TeakMpy Y0Regs:$y, Imm8s_16:$x))]>; + def MPY_y0_regnob16_ab : TeakPseudoInst<(outs ABRegs:$dst), (ins Y0Regs:$y, RegNoBRegs16:$x), "MPY_y0_regnob16_ab $y, $x, $dst", [(set ABRegs:$dst, (TeakMpy RegNoBRegs16:$x, Y0Regs:$y))]>; + } let Constraints = "$asrc = $bdst, $bsrc = $adst" in def SWAP_ab : InstTeak<(outs BRegs:$adst, ARegs:$bdst), (ins ARegs:$asrc, BRegs:$bsrc), "swap ($asrc, $bsrc)", []>; @@ -384,7 +464,10 @@ let mayStore = 1 in def MOV_regnob16_memrn : InstTeak<(outs), (ins RegNoBRegs16:$a, GRRegs:$dstAddr), "mov $a, [$dstAddr]", [(store RegNoBRegs16:$a, GRRegs:$dstAddr)]>; let mayStore = 1, Constraints = "$dstAddr = $dstAddrOut" in -def MOV_regnob16_memrn_postdec : InstTeak<(outs GRRegs:$dstAddrOut), (ins RegNoBRegs16:$a, GRRegs:$dstAddr), "mov $a, [${dstAddr}--]", []>; +def MOV_regnob16_memrn_postinc : InstTeak<(outs GRRegs:$dstAddrOut), (ins RegNoBRegs16:$a, GRRegs:$dstAddr), "mov $a, [${dstAddr}++]", [(set GRRegs:$dstAddrOut, (store_postinc RegNoBRegs16:$a, GRRegs:$dstAddr))]>; + +let mayStore = 1, Constraints = "$dstAddr = $dstAddrOut" in +def MOV_regnob16_memrn_postdec : InstTeak<(outs GRRegs:$dstAddrOut), (ins RegNoBRegs16:$a, GRRegs:$dstAddr), "mov $a, [${dstAddr}--]", [(set GRRegs:$dstAddrOut, (store_postdec RegNoBRegs16:$a, GRRegs:$dstAddr))]>; let mayStore = 1 in def MOV_abl_memrn : InstTeak<(outs), (ins ABRegs:$a, GRRegs:$dstAddr), "mov ${a}l, [$dstAddr]", [(truncstorei16 ABRegs:$a, GRRegs:$dstAddr)]>; @@ -392,8 +475,8 @@ def MOV_abl_memrn : InstTeak<(outs), (ins ABRegs:$a, GRRegs:$dstAddr), "mov ${a} let Defs = [ICC], mayLoad = 1 in def MOV_memrn_regnob16 : InstTeak<(outs RegNoBRegs16_nolh:$dst), (ins GRRegs:$srcAddr), "mov [$srcAddr], $dst", [(set RegNoBRegs16_nolh:$dst, (load GRRegs:$srcAddr))]>; -// let Defs = [ICC], mayLoad = 1, Constraints = "$srcAddr = $srcAddrOut" in -// def MOV_memrn_regnob16_postinc : InstTeak<(outs RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut), (ins GRRegs:$srcAddr), "mov [${srcAddr}++], $dst", [(set RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut, (load_postinc GRRegs:$srcAddr))]>; +let Defs = [ICC], mayLoad = 1, Constraints = "$srcAddr = $srcAddrOut" in +def MOV_memrn_regnob16_postinc : InstTeak<(outs RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut), (ins GRRegs:$srcAddr), "mov [${srcAddr}++], $dst", [(set RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut, (load_postinc GRRegs:$srcAddr))]>; let Defs = [ICC], mayLoad = 1, Constraints = "$srcAddr = $srcAddrOut" in def MOV_memrn_regnob16_postdec : InstTeak<(outs RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut), (ins GRRegs:$srcAddr), "mov [${srcAddr}--], $dst", [(set RegNoBRegs16_nolh:$dst, GRRegs:$srcAddrOut, (load_postdec GRRegs:$srcAddr))]>; @@ -479,33 +562,45 @@ let Defs = [SP], Uses = [SP] in def PUSH_regnob16 : InstTeak<(outs), (ins RegNoBRegs16:$reg), "push $reg", []>; //def PUSH_px : InstTeak<(outs), (ins PRegs:$reg), "push $reg", []>; def PUSH_ararpsttmod : InstTeak<(outs), (ins ArArpSttMod:$reg), "push $reg", []>; + def PUSH_abe : InstTeak<(outs), (ins ABERegs:$reg), "push $reg", []>; } let Defs = [SP, ICC], mayLoad = 1 in { def POP_regnob16 : InstTeak<(outs RegNoBRegs16_nolh:$reg), (ins), "pop $reg", []>; //def POP_px : InstTeak<(outs PRegs:$reg), (ins), "pop $reg", []>; def POP_ararpsttmod : InstTeak<(outs ArArpSttMod:$reg), (ins), "pop $reg", []>; + def POP_abe : InstTeak<(outs ABERegs:$reg), (ins), "pop $reg", []>; } } 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_imm16_a : InstTeakImm16<(outs), (ins immNeg32768_32767:$val, ARegs:$a), "cmp $val, $a", [(TeakCmpICC ARegs:$a, immNeg32768_32767:$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 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 { def CMP_memimm16_a : InstTeakImm16<(outs), (ins Operand:$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 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 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 { def SELECT_CC_Int_ICC : TeakPseudoInst<(outs ABRegs:$dst), (ins ABRegs:$T, ABRegs:$F, Operand:$Cond), "; SELECT_CC_Int_ICC PSEUDO!", @@ -555,6 +650,7 @@ def : Pat<(i40 (TeakOr ARegs:$a, (extloadi16 (TeakWrapper tglobaladdr:$src)))), def : Pat<(i40 (TeakXor ARegs:$a, (zextloadi16 (TeakWrapper tglobaladdr:$src)))), (XOR_memimm16_a tglobaladdr:$src, ARegs:$a)>; def : Pat<(i40 (TeakXor ARegs:$a, (extloadi16 (TeakWrapper tglobaladdr:$src)))), (XOR_memimm16_a tglobaladdr:$src, ARegs:$a)>; def : Pat<(TeakCmpICC ARegs:$a, (i40 (sextloadi16 (TeakWrapper tglobaladdr:$src)))), (CMP_memimm16_a tglobaladdr:$src, ARegs:$a)>; +def : Pat<(TeakCmpzICC ARegs:$a, (i40 (sextloadi16 (TeakWrapper tglobaladdr:$src)))), (CMP_memimm16_a tglobaladdr:$src, ARegs:$a)>; def : Pat<(store ALRegs:$src, (i16 (TeakWrapper tglobaladdr:$dst))), (MOV_al2_memimm16 ALRegs:$src, tglobaladdr:$dst)>; def : Pat<(truncstorei16 ARegs:$src, (i16 (TeakWrapper tglobaladdr:$dst))), (MOV_al_memimm16 ARegs:$src, tglobaladdr:$dst)>; def : Pat<(i40 (sextloadi16 (TeakWrapper tglobaladdr:$src))), (MOV_memimm16_a tglobaladdr:$src)>; diff --git a/llvm/lib/Target/Teak/TeakOperators.td b/llvm/lib/Target/Teak/TeakOperators.td index 9c503b863ba..4b0be07bd9e 100644 --- a/llvm/lib/Target/Teak/TeakOperators.td +++ b/llvm/lib/Target/Teak/TeakOperators.td @@ -33,6 +33,9 @@ def SDT_TeakCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; def SDT_TeakCmpICC : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; def TeakCmpICC : SDNode<"TeakISD::CMPICC", SDT_TeakCmpICC, [SDNPOutGlue]>; +def SDT_TeakCmpzICC : SDTypeProfile<0, 2, [SDTCisInt<0>, SDTCisSameAs<0, 1>]>; +def TeakCmpzICC : SDNode<"TeakISD::CMPZICC", SDT_TeakCmpzICC, [SDNPOutGlue]>; + def SDT_TeakSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i40>]>; def TeakSelectICC : SDNode<"TeakISD::SELECT_ICC", SDT_TeakSelectCC, [SDNPInGlue]>; @@ -79,6 +82,9 @@ def TeakOr : SDNode<"TeakISD::OR", SDT_TeakOr>; def SDT_TeakXor : SDTypeProfile<1, 2, [SDTCisInt<0>, SDTCisSameAs<1, 0>, SDTCisSameAs<2, 0>]>; def TeakXor : SDNode<"TeakISD::XOR", SDT_TeakXor>; +def SDT_TeakMpy : SDTypeProfile<1, 2, [SDTCisVT<0, i40>, SDTCisVT<1, i16>, SDTCisVT<2, i16>]>; +def TeakMpy : SDNode<"TeakISD::MPY", SDT_TeakMpy>; + // //===----------------------------------------------------------------------===// // // Operand Definitions. // //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/Teak/TeakOptimizeMovImmPass.cpp b/llvm/lib/Target/Teak/TeakOptimizeMovImmPass.cpp new file mode 100644 index 00000000000..8fcb739a4e0 --- /dev/null +++ b/llvm/lib/Target/Teak/TeakOptimizeMovImmPass.cpp @@ -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 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(); +} \ No newline at end of file diff --git a/llvm/lib/Target/Teak/TeakRegisterInfo.cpp b/llvm/lib/Target/Teak/TeakRegisterInfo.cpp index da2b537bf28..c08b445d8a0 100644 --- a/llvm/lib/Target/Teak/TeakRegisterInfo.cpp +++ b/llvm/lib/Target/Teak/TeakRegisterInfo.cpp @@ -56,6 +56,10 @@ BitVector TeakRegisterInfo::getReservedRegs(const MachineFunction &MF) const Reserved.set(Teak::PC); Reserved.set(Teak::R7); Reserved.set(Teak::LC); + Reserved.set(Teak::EXT0); + Reserved.set(Teak::EXT1); + Reserved.set(Teak::EXT2); + Reserved.set(Teak::EXT3); return Reserved; } @@ -127,6 +131,8 @@ unsigned TeakRegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC, Ma return 4; case Teak::RegNoBRegs16_nohRegClassID: return 12; + case Teak::RegNoBRegs16_noh_pageRegClassID: + return 12 + 80; } } @@ -264,29 +270,36 @@ bool TeakRegisterInfo::shouldCoalesce(MachineInstr *MI, const TargetRegisterClas dbgs() << "DstSubReg: " << DstSubReg << "\n"; dbgs() << "NewRC: " << NewRC->getID() << "\n"; - if (SrcRC->hasSuperClassEq(&Teak::SVRegRegClass) || - DstRC->hasSuperClassEq(&Teak::SVRegRegClass) || - NewRC->hasSuperClassEq(&Teak::SVRegRegClass)) - return false; + // if (SrcRC->hasSuperClassEq(&Teak::SVRegRegClass) || + // DstRC->hasSuperClassEq(&Teak::SVRegRegClass) || + // NewRC->hasSuperClassEq(&Teak::SVRegRegClass)) + // return false; - if(DstSubReg == Teak::sub_16bit) - return true; - //if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass)) - // return true; - if(SrcRC->hasSuperClassEq(&Teak::ABLRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass)) - return true; + // if(DstSubReg == Teak::sub_16bit) + // return true; + // //if(SrcRC->hasSubClassEq(&Teak::GRRegsRegClass) && DstRC->hasSubClassEq(&Teak::GRRegsRegClass) && NewRC->hasSubClassEq(&Teak::GRRegsRegClass)) + // // return true; + // if(SrcRC->hasSuperClassEq(&Teak::ABLRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass)) + // return true; - if(SrcRC->hasSuperClassEq(&Teak::ABRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass)) - return true; - //return true;//false; - if(SrcRC->hasSuperClassEq(&Teak::ARegsRegClass) && DstRC->hasSuperClassEq(&Teak::ARegsRegClass) && NewRC->hasSuperClassEq(&Teak::ARegsRegClass)) - return true; - if(SrcRC->hasSuperClassEq(&Teak::ALRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ALRegsRegClass)) - return true; + // if(SrcRC->hasSuperClassEq(&Teak::ABRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ABRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ABRegsRegClass)) + // return true; + // //return true;//false; + // if(SrcRC->hasSuperClassEq(&Teak::ARegsRegClass) && DstRC->hasSuperClassEq(&Teak::ARegsRegClass) && NewRC->hasSuperClassEq(&Teak::ARegsRegClass)) + // return true; + // if(SrcRC->hasSuperClassEq(&Teak::ALRegsRegClass) && DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) && NewRC->hasSuperClassEq(&Teak::ALRegsRegClass)) + // return true; - if (DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) || NewRC->hasSuperClassEq(&Teak::ALRegsRegClass) || - DstRC->hasSuperClassEq(&Teak::ARegsRegClass) || NewRC->hasSuperClassEq(&Teak::ARegsRegClass)) - return false; + // if (DstRC->hasSuperClassEq(&Teak::ALRegsRegClass) || NewRC->hasSuperClassEq(&Teak::ALRegsRegClass) || + // DstRC->hasSuperClassEq(&Teak::ARegsRegClass) || NewRC->hasSuperClassEq(&Teak::ARegsRegClass)) + // return false; return true; +} + +const TargetRegisterClass* TeakRegisterInfo::getCrossCopyRegClass(const TargetRegisterClass* RC) const +{ + //if (RC == &Teak::RegNoBRegs16RegClass) + // return &Teak::RegNoBRegs16_nolhRegClass; + return RC; } \ No newline at end of file diff --git a/llvm/lib/Target/Teak/TeakRegisterInfo.h b/llvm/lib/Target/Teak/TeakRegisterInfo.h index 19467f0ee5b..f608d41343d 100644 --- a/llvm/lib/Target/Teak/TeakRegisterInfo.h +++ b/llvm/lib/Target/Teak/TeakRegisterInfo.h @@ -72,6 +72,8 @@ public: unsigned DstSubReg, const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override; + + virtual const TargetRegisterClass* getCrossCopyRegClass(const TargetRegisterClass* RC) const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/Teak/TeakRegisterInfo.td b/llvm/lib/Target/Teak/TeakRegisterInfo.td index 347995b9d09..75fb1b1c0eb 100644 --- a/llvm/lib/Target/Teak/TeakRegisterInfo.td +++ b/llvm/lib/Target/Teak/TeakRegisterInfo.td @@ -95,15 +95,111 @@ def MOD1 : TeakReg<0, "mod1">; def MOD2 : TeakReg<0, "mod2">; def MOD3 : TeakReg<0, "mod3">; +def EXT0 : TeakReg<0, "ext0">; +def EXT1 : TeakReg<0, "ext1">; +def EXT2 : TeakReg<0, "ext2">; +def EXT3 : TeakReg<0, "ext3">; + def ICC : TeakReg<0, "ICC">;//for flag setting ops, maybe rename +// Page registers: 80 fake registers that are actually in memory +// Since memory is as fast as the cpu, there's no performance difference +// between using those fake registers or real registers using the short +// 8 bit page addressing mode, given that an instruction supports this ofc + +// The first 40 page registers are preserved over function calls +def PAGE0 : TeakReg<0, "[page:0x0000u8]">; +def PAGE1 : TeakReg<0, "[page:0x0001u8]">; +def PAGE2 : TeakReg<0, "[page:0x0002u8]">; +def PAGE3 : TeakReg<0, "[page:0x0003u8]">; +def PAGE4 : TeakReg<0, "[page:0x0004u8]">; +def PAGE5 : TeakReg<0, "[page:0x0005u8]">; +def PAGE6 : TeakReg<0, "[page:0x0006u8]">; +def PAGE7 : TeakReg<0, "[page:0x0007u8]">; +def PAGE8 : TeakReg<0, "[page:0x0008u8]">; +def PAGE9 : TeakReg<0, "[page:0x0009u8]">; +def PAGE10 : TeakReg<0, "[page:0x000Au8]">; +def PAGE11 : TeakReg<0, "[page:0x000Bu8]">; +def PAGE12 : TeakReg<0, "[page:0x000Cu8]">; +def PAGE13 : TeakReg<0, "[page:0x000Du8]">; +def PAGE14 : TeakReg<0, "[page:0x000Eu8]">; +def PAGE15 : TeakReg<0, "[page:0x000Fu8]">; +def PAGE16 : TeakReg<0, "[page:0x0010u8]">; +def PAGE17 : TeakReg<0, "[page:0x0011u8]">; +def PAGE18 : TeakReg<0, "[page:0x0012u8]">; +def PAGE19 : TeakReg<0, "[page:0x0013u8]">; +def PAGE20 : TeakReg<0, "[page:0x0014u8]">; +def PAGE21 : TeakReg<0, "[page:0x0015u8]">; +def PAGE22 : TeakReg<0, "[page:0x0016u8]">; +def PAGE23 : TeakReg<0, "[page:0x0017u8]">; +def PAGE24 : TeakReg<0, "[page:0x0018u8]">; +def PAGE25 : TeakReg<0, "[page:0x0019u8]">; +def PAGE26 : TeakReg<0, "[page:0x001Au8]">; +def PAGE27 : TeakReg<0, "[page:0x001Bu8]">; +def PAGE28 : TeakReg<0, "[page:0x001Cu8]">; +def PAGE29 : TeakReg<0, "[page:0x001Du8]">; +def PAGE30 : TeakReg<0, "[page:0x001Eu8]">; +def PAGE31 : TeakReg<0, "[page:0x001Fu8]">; +def PAGE32 : TeakReg<0, "[page:0x0020u8]">; +def PAGE33 : TeakReg<0, "[page:0x0021u8]">; +def PAGE34 : TeakReg<0, "[page:0x0022u8]">; +def PAGE35 : TeakReg<0, "[page:0x0023u8]">; +def PAGE36 : TeakReg<0, "[page:0x0024u8]">; +def PAGE37 : TeakReg<0, "[page:0x0025u8]">; +def PAGE38 : TeakReg<0, "[page:0x0026u8]">; +def PAGE39 : TeakReg<0, "[page:0x0027u8]">; + +// The second 40 page registers are not preserved +def PAGE40 : TeakReg<0, "[page:0x0028u8]">; +def PAGE41 : TeakReg<0, "[page:0x0029u8]">; +def PAGE42 : TeakReg<0, "[page:0x002Au8]">; +def PAGE43 : TeakReg<0, "[page:0x002Bu8]">; +def PAGE44 : TeakReg<0, "[page:0x002Cu8]">; +def PAGE45 : TeakReg<0, "[page:0x002Du8]">; +def PAGE46 : TeakReg<0, "[page:0x002Eu8]">; +def PAGE47 : TeakReg<0, "[page:0x002Fu8]">; +def PAGE48 : TeakReg<0, "[page:0x0030u8]">; +def PAGE49 : TeakReg<0, "[page:0x0031u8]">; +def PAGE50 : TeakReg<0, "[page:0x0032u8]">; +def PAGE51 : TeakReg<0, "[page:0x0033u8]">; +def PAGE52 : TeakReg<0, "[page:0x0034u8]">; +def PAGE53 : TeakReg<0, "[page:0x0035u8]">; +def PAGE54 : TeakReg<0, "[page:0x0036u8]">; +def PAGE55 : TeakReg<0, "[page:0x0037u8]">; +def PAGE56 : TeakReg<0, "[page:0x0038u8]">; +def PAGE57 : TeakReg<0, "[page:0x0039u8]">; +def PAGE58 : TeakReg<0, "[page:0x003Au8]">; +def PAGE59 : TeakReg<0, "[page:0x003Bu8]">; +def PAGE60 : TeakReg<0, "[page:0x003Cu8]">; +def PAGE61 : TeakReg<0, "[page:0x003Du8]">; +def PAGE62 : TeakReg<0, "[page:0x003Eu8]">; +def PAGE63 : TeakReg<0, "[page:0x003Fu8]">; +def PAGE64 : TeakReg<0, "[page:0x0040u8]">; +def PAGE65 : TeakReg<0, "[page:0x0041u8]">; +def PAGE66 : TeakReg<0, "[page:0x0042u8]">; +def PAGE67 : TeakReg<0, "[page:0x0043u8]">; +def PAGE68 : TeakReg<0, "[page:0x0044u8]">; +def PAGE69 : TeakReg<0, "[page:0x0045u8]">; +def PAGE70 : TeakReg<0, "[page:0x0046u8]">; +def PAGE71 : TeakReg<0, "[page:0x0047u8]">; +def PAGE72 : TeakReg<0, "[page:0x0048u8]">; +def PAGE73 : TeakReg<0, "[page:0x0049u8]">; +def PAGE74 : TeakReg<0, "[page:0x004Au8]">; +def PAGE75 : TeakReg<0, "[page:0x004Bu8]">; +def PAGE76 : TeakReg<0, "[page:0x004Cu8]">; +def PAGE77 : TeakReg<0, "[page:0x004Du8]">; +def PAGE78 : TeakReg<0, "[page:0x004Eu8]">; +def PAGE79 : TeakReg<0, "[page:0x004Fu8]">; + // Register classes. // def GRRegs : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7)>; def RegNoBRegs40 : RegisterClass<"Teak", [i40], 32, (add A0, A1)>; -def RegNoBRegs16 : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV)>; -def RegNoBRegs16_nolh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, LC, SV)>; -def RegNoBRegs16_noh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, A0L, A1L, B0L, B1L, LC, SV)>; +def RegNoBRegs16 : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV, EXT0, EXT1, EXT2, EXT3)>; +def RegNoBRegs16_nolh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, LC, SV, EXT0, EXT1, EXT2, EXT3)>; +def RegNoBRegs16_noh : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, A0L, A1L, B0L, B1L, LC, SV, EXT0, EXT1, EXT2, EXT3)>; +def RegNoBRegs16_page : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV, EXT0, EXT1, EXT2, EXT3, (sequence "PAGE%u", 0, 79))>; +def RegNoBRegs16_noh_page : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R6, R7, Y0, SP, A0L, A1L, B0L, B1L, LC, SV, EXT0, EXT1, EXT2, EXT3, (sequence "PAGE%u", 0, 79))>; def RegR0425 : RegisterClass<"Teak", [i16], 16, (add R0, R4, R2, R5)>; //def RegNoBRegsP040 : RegisterClass<"Teak", [i40], 32, (add A0, A1)>; //def RegNoBRegsP016 : RegisterClass<"Teak", [i16], 16, (add R0, R1, R2, R3, R4, R5, R7, Y0, /**/ SP, B0H, B1H, B0L, B1L, A0L, A1L, A0H, A1H, LC, SV)>; @@ -112,12 +208,13 @@ def BRegs : RegisterClass<"Teak", [i40], 32, (add B0, B1)>; def B0Reg : RegisterClass<"Teak", [i40], 32, (add B0)>; def B1Reg : RegisterClass<"Teak", [i40], 32, (add B1)>; def ABRegs : RegisterClass<"Teak", [i40], 32, (add A0, A1, B0, B1)>; -def ABLRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L, B0L, B1L)>; -def ALRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L)>; -// { -// let CopyCost = -1; -// } -def ABHRegs : RegisterClass<"Teak", [i16], 16, (add A0H, A1H, B0H, B1H)>; +let CopyCost = -1 in +{ + def ABLRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L, B0L, B1L)>; + def ALRegs : RegisterClass<"Teak", [i16], 16, (add A0L, A1L)>; + def ABHRegs : RegisterClass<"Teak", [i16], 16, (add A0H, A1H, B0H, B1H)>; + def ABERegs : RegisterClass<"Teak", [i8], 16, (add A0E, A1E, B0E, B1E)>; +} def ArArpSttMod : RegisterClass<"Teak", [i16], 16, (add STT0)>; def FP : RegisterClass<"Teak", [i16], 16, (add R7)>; def Y0Regs : RegisterClass<"Teak", [i16], 16, (add Y0)>; @@ -128,4 +225,10 @@ def SVReg : RegisterClass<"Teak", [i16], 16, (add SV)>; //def YRegs : RegisterClass<"Teak", [i16], 16, (add Y0, Y1)>; //def PRegs : RegisterClass<"Teak", [i32], 32, (add P0, P1)>; -def SttModRegs : RegisterClass<"Teak", [i16], 16, (add STT0, STT1, STT2, MOD0, MOD1, MOD2, MOD3)>; \ No newline at end of file +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))>; \ No newline at end of file diff --git a/llvm/lib/Target/Teak/TeakTargetMachine.cpp b/llvm/lib/Target/Teak/TeakTargetMachine.cpp index a6188a466ac..6dcf4581d1b 100644 --- a/llvm/lib/Target/Teak/TeakTargetMachine.cpp +++ b/llvm/lib/Target/Teak/TeakTargetMachine.cpp @@ -70,11 +70,16 @@ public: }; } // namespace -TargetPassConfig *TeakTargetMachine::createPassConfig(PassManagerBase &PM) { - return new TeakPassConfig(*this, PM); +TargetPassConfig *TeakTargetMachine::createPassConfig(PassManagerBase &PM) +{ + return new TeakPassConfig(*this, PM); } -bool TeakPassConfig::addPreISel() { return false; } +bool TeakPassConfig::addPreISel() +{ + addPass(createHardwareLoopsPass()); + return false; +} void TeakPassConfig::addPreSched2() { @@ -90,6 +95,7 @@ bool TeakPassConfig::addInstSelector() void TeakPassConfig::addPreEmitPass() { + addPass(createTeakOptimizeMovImmPass()); addPass(&BranchRelaxationPassID); }