Imported Upstream version 5.18.0.167

Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-10-20 08:25:10 +00:00
parent e19d552987
commit b084638f15
28489 changed files with 184 additions and 3866856 deletions

View File

@ -1,56 +0,0 @@
//===-- AVR.h - Top-level interface for AVR representation ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the entry points for global functions defined in the LLVM
// AVR back-end.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_H
#define LLVM_AVR_H
#include "llvm/CodeGen/SelectionDAGNodes.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class AVRTargetMachine;
class FunctionPass;
FunctionPass *createAVRISelDag(AVRTargetMachine &TM,
CodeGenOpt::Level OptLevel);
FunctionPass *createAVRExpandPseudoPass();
FunctionPass *createAVRFrameAnalyzerPass();
FunctionPass *createAVRRelaxMemPass();
FunctionPass *createAVRDynAllocaSRPass();
FunctionPass *createAVRBranchSelectionPass();
void initializeAVRExpandPseudoPass(PassRegistry&);
void initializeAVRRelaxMemPass(PassRegistry&);
/// Contains the AVR backend.
namespace AVR {
enum AddressSpace { DataMemory, ProgramMemory };
template <typename T> bool isProgramMemoryAddress(T *V) {
return cast<PointerType>(V->getType())->getAddressSpace() == ProgramMemory;
}
inline bool isProgramMemoryAccess(MemSDNode const *N) {
auto V = N->getMemOperand()->getValue();
return (V != nullptr) ? isProgramMemoryAddress(V) : false;
}
} // end of namespace AVR
} // end namespace llvm
#endif // LLVM_AVR_H

View File

@ -1,81 +0,0 @@
//===-- AVR.td - Describe the AVR Target Machine ----------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
// This is the top level entry point for the AVR target.
//===---------------------------------------------------------------------===//
//===---------------------------------------------------------------------===//
// Target-independent interfaces which we are implementing
//===---------------------------------------------------------------------===//
include "llvm/Target/Target.td"
//===---------------------------------------------------------------------===//
// AVR Device Definitions
//===---------------------------------------------------------------------===//
include "AVRDevices.td"
//===---------------------------------------------------------------------===//
// Register File Description
//===---------------------------------------------------------------------===//
include "AVRRegisterInfo.td"
//===---------------------------------------------------------------------===//
// Instruction Descriptions
//===---------------------------------------------------------------------===//
include "AVRInstrInfo.td"
def AVRInstrInfo : InstrInfo;
//===---------------------------------------------------------------------===//
// Calling Conventions
//===---------------------------------------------------------------------===//
include "AVRCallingConv.td"
//===---------------------------------------------------------------------===//
// Assembly Printers
//===---------------------------------------------------------------------===//
def AVRAsmWriter : AsmWriter {
string AsmWriterClassName = "InstPrinter";
bit isMCAsmWriter = 1;
}
//===---------------------------------------------------------------------===//
// Assembly Parsers
//===---------------------------------------------------------------------===//
def AVRAsmParser : AsmParser {
let ShouldEmitMatchRegisterName = 1;
let ShouldEmitMatchRegisterAltName = 1;
}
def AVRAsmParserVariant : AsmParserVariant {
int Variant = 0;
// Recognize hard coded registers.
string RegisterPrefix = "$";
string TokenizingCharacters = "+";
}
//===---------------------------------------------------------------------===//
// Target Declaration
//===---------------------------------------------------------------------===//
def AVR : Target {
let InstructionSet = AVRInstrInfo;
let AssemblyWriters = [AVRAsmWriter];
let AssemblyParsers = [AVRAsmParser];
let AssemblyParserVariants = [AVRAsmParserVariant];
}

View File

@ -1,189 +0,0 @@
//===-- AVRAsmPrinter.cpp - AVR LLVM assembly writer ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains a printer that converts from our internal representation
// of machine-dependent LLVM code to GAS-format AVR assembly language.
//
//===----------------------------------------------------------------------===//
#include "AVR.h"
#include "AVRMCInstLower.h"
#include "AVRSubtarget.h"
#include "InstPrinter/AVRInstPrinter.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#define DEBUG_TYPE "avr-asm-printer"
namespace llvm {
/// An AVR assembly code printer.
class AVRAsmPrinter : public AsmPrinter {
public:
AVRAsmPrinter(TargetMachine &TM,
std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)), MRI(*TM.getMCRegisterInfo()) { }
StringRef getPassName() const override { return "AVR Assembly Printer"; }
void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O,
const char *Modifier = 0);
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O) override;
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O) override;
void EmitInstruction(const MachineInstr *MI) override;
private:
const MCRegisterInfo &MRI;
};
void AVRAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
raw_ostream &O, const char *Modifier) {
const MachineOperand &MO = MI->getOperand(OpNo);
switch (MO.getType()) {
case MachineOperand::MO_Register:
O << AVRInstPrinter::getPrettyRegisterName(MO.getReg(), MRI);
break;
case MachineOperand::MO_Immediate:
O << MO.getImm();
break;
case MachineOperand::MO_GlobalAddress:
O << getSymbol(MO.getGlobal());
break;
case MachineOperand::MO_ExternalSymbol:
O << *GetExternalSymbolSymbol(MO.getSymbolName());
break;
case MachineOperand::MO_MachineBasicBlock:
O << *MO.getMBB()->getSymbol();
break;
default:
llvm_unreachable("Not implemented yet!");
}
}
bool AVRAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O) {
// Default asm printer can only deal with some extra codes,
// so try it first.
bool Error = AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O);
if (Error && ExtraCode && ExtraCode[0]) {
if (ExtraCode[1] != 0)
return true; // Unknown modifier.
if (ExtraCode[0] >= 'A' && ExtraCode[0] <= 'Z') {
const MachineOperand &RegOp = MI->getOperand(OpNum);
assert(RegOp.isReg() && "Operand must be a register when you're"
"using 'A'..'Z' operand extracodes.");
unsigned Reg = RegOp.getReg();
unsigned ByteNumber = ExtraCode[0] - 'A';
unsigned OpFlags = MI->getOperand(OpNum - 1).getImm();
unsigned NumOpRegs = InlineAsm::getNumOperandRegisters(OpFlags);
(void)NumOpRegs;
const AVRSubtarget &STI = MF->getSubtarget<AVRSubtarget>();
const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
unsigned BytesPerReg = TRI.getRegSizeInBits(*RC) / 8;
assert(BytesPerReg <= 2 && "Only 8 and 16 bit regs are supported.");
unsigned RegIdx = ByteNumber / BytesPerReg;
assert(RegIdx < NumOpRegs && "Multibyte index out of range.");
Reg = MI->getOperand(OpNum + RegIdx).getReg();
if (BytesPerReg == 2) {
Reg = TRI.getSubReg(Reg, ByteNumber % BytesPerReg ? AVR::sub_hi
: AVR::sub_lo);
}
O << AVRInstPrinter::getPrettyRegisterName(Reg, MRI);
return false;
}
}
if (Error)
printOperand(MI, OpNum, O);
return false;
}
bool AVRAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNum, unsigned AsmVariant,
const char *ExtraCode,
raw_ostream &O) {
if (ExtraCode && ExtraCode[0]) {
llvm_unreachable("This branch is not implemented yet");
}
const MachineOperand &MO = MI->getOperand(OpNum);
(void)MO;
assert(MO.isReg() && "Unexpected inline asm memory operand");
// TODO: We should be able to look up the alternative name for
// the register if it's given.
// TableGen doesn't expose a way of getting retrieving names
// for registers.
if (MI->getOperand(OpNum).getReg() == AVR::R31R30) {
O << "Z";
} else {
assert(MI->getOperand(OpNum).getReg() == AVR::R29R28 &&
"Wrong register class for memory operand.");
O << "Y";
}
// If NumOpRegs == 2, then we assume it is product of a FrameIndex expansion
// and the second operand is an Imm.
unsigned OpFlags = MI->getOperand(OpNum - 1).getImm();
unsigned NumOpRegs = InlineAsm::getNumOperandRegisters(OpFlags);
if (NumOpRegs == 2) {
O << '+' << MI->getOperand(OpNum + 1).getImm();
}
return false;
}
void AVRAsmPrinter::EmitInstruction(const MachineInstr *MI) {
AVRMCInstLower MCInstLowering(OutContext, *this);
MCInst I;
MCInstLowering.lowerInstruction(*MI, I);
EmitToStreamer(*OutStreamer, I);
}
} // end of namespace llvm
extern "C" void LLVMInitializeAVRAsmPrinter() {
llvm::RegisterAsmPrinter<llvm::AVRAsmPrinter> X(llvm::getTheAVRTarget());
}

View File

@ -1,58 +0,0 @@
//===-- AVRCallingConv.td - Calling Conventions for AVR ----*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This describes the calling conventions for AVR architecture.
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// AVR Return Value Calling Convention
//===----------------------------------------------------------------------===//
def RetCC_AVR : CallingConv
<[
// i8 is returned in R24.
CCIfType<[i8], CCAssignToReg<[R24]>>,
// i16 are returned in R25:R24, R23:R22, R21:R20 and R19:R18.
CCIfType<[i16], CCAssignToReg<[R25R24, R23R22, R21R20, R19R18]>>
]>;
// Special return value calling convention for runtime functions.
def RetCC_AVR_BUILTIN : CallingConv
<[
CCIfType<[i8], CCAssignToReg<[R24,R25]>>,
CCIfType<[i16], CCAssignToReg<[R23R22, R25R24]>>
]>;
//===----------------------------------------------------------------------===//
// AVR Argument Calling Conventions
//===----------------------------------------------------------------------===//
// The calling conventions are implemented in custom C++ code
// Calling convention for variadic functions.
def ArgCC_AVR_Vararg : CallingConv
<[
// i16 are always passed through the stack with an alignment of 1.
CCAssignToStack<2, 1>
]>;
// Special argument calling convention for
// division runtime functions.
def ArgCC_AVR_BUILTIN_DIV : CallingConv
<[
CCIfType<[i8], CCAssignToReg<[R24,R22]>>,
CCIfType<[i16], CCAssignToReg<[R25R24, R23R22]>>
]>;
//===----------------------------------------------------------------------===//
// Callee-saved register lists.
//===----------------------------------------------------------------------===//
def CSR_Normal : CalleeSavedRegs<(add R29, R28, (sequence "R%u", 17, 2))>;
def CSR_Interrupts : CalleeSavedRegs<(add (sequence "R%u", 31, 0))>;

View File

@ -1,490 +0,0 @@
//===---------------------------------------------------------------------===//
// AVR Device Definitions
//===---------------------------------------------------------------------===//
// :TODO: Implement the skip errata, see `gcc/config/avr/avr-arch.h` for details
// :TODO: We define all devices with SRAM to have all variants of LD/ST/LDD/STD.
// In reality, avr1 (no SRAM) has one variant each of `LD` and `ST`.
// avr2 (with SRAM) adds the rest of the variants.
// A feature set aggregates features, grouping them. We don't want to create a
// new member in AVRSubtarget (to store a value) for each set because we do not
// care if the set is supported, only the subfeatures inside the set. We fix
// this by simply setting the same dummy member for all feature sets, which is
// then ignored.
class FeatureSet<string name, string desc, list<SubtargetFeature> i>
: SubtargetFeature<name, "m_FeatureSetDummy", "true", desc, i>;
// A family of microcontrollers, defining a set of supported features.
class Family<string name, list<SubtargetFeature> i>
: FeatureSet<name, !strconcat("The device is a part of the ",
name, " family"), i>;
// The device has SRAM, and supports the bare minimum of
// SRAM-relevant instructions.
//
// These are:
// LD - all 9 variants
// ST - all 9 variants
// LDD - two variants for Y and Z
// STD - two variants for Y and Z
// `LDS Rd, K`
// `STS k, Rr`
// `PUSH`/`POP`
def FeatureSRAM : SubtargetFeature<"sram", "m_hasSRAM", "true",
"The device has random access memory">;
// The device supports the `JMP k` and `CALL k` instructions.
def FeatureJMPCALL : SubtargetFeature<"jmpcall", "m_hasJMPCALL", "true",
"The device supports the `JMP` and "
"`CALL` instructions">;
// The device supports the indirect branches `IJMP` and `ICALL`.
def FeatureIJMPCALL : SubtargetFeature<"ijmpcall", "m_hasIJMPCALL",
"true",
"The device supports `IJMP`/`ICALL`"
"instructions">;
// The device supports the extended indirect branches `EIJMP` and `EICALL`.
def FeatureEIJMPCALL : SubtargetFeature<"eijmpcall", "m_hasEIJMPCALL",
"true", "The device supports the "
"`EIJMP`/`EICALL` instructions">;
// The device supports `ADDI Rd, K`, `SUBI Rd, K`.
def FeatureADDSUBIW : SubtargetFeature<"addsubiw", "m_hasADDSUBIW",
"true", "Enable 16-bit register-immediate "
"addition and subtraction instructions">;
// The device has an 8-bit stack pointer (SP) register.
def FeatureSmallStack : SubtargetFeature<"smallstack", "m_hasSmallStack",
"true", "The device has an 8-bit "
"stack pointer">;
// The device supports the 16-bit GPR pair MOVW instruction.
def FeatureMOVW : SubtargetFeature<"movw", "m_hasMOVW", "true",
"The device supports the 16-bit MOVW "
"instruction">;
// The device supports the `LPM` instruction, with implied destination being r0.
def FeatureLPM : SubtargetFeature<"lpm", "m_hasLPM", "true",
"The device supports the `LPM` instruction">;
// The device supports the `LPM Rd, Z[+] instruction.
def FeatureLPMX : SubtargetFeature<"lpmx", "m_hasLPMX", "true",
"The device supports the `LPM Rd, Z[+]` "
"instruction">;
// The device supports the `ELPM` instruction.
def FeatureELPM : SubtargetFeature<"elpm", "m_hasELPM", "true",
"The device supports the ELPM instruction">;
// The device supports the `ELPM Rd, Z[+]` instructions.
def FeatureELPMX : SubtargetFeature<"elpmx", "m_hasELPMX", "true",
"The device supports the `ELPM Rd, Z[+]` "
"instructions">;
// The device supports the `SPM` instruction.
def FeatureSPM : SubtargetFeature<"spm", "m_hasSPM", "true",
"The device supports the `SPM` instruction">;
// The device supports the `SPM Z+` instruction.
def FeatureSPMX : SubtargetFeature<"spmx", "m_hasSPMX", "true",
"The device supports the `SPM Z+` "
"instruction">;
// The device supports the `DES k` instruction.
def FeatureDES : SubtargetFeature<"des", "m_hasDES", "true",
"The device supports the `DES k` encryption "
"instruction">;
// The device supports the Read-Write-Modify instructions
// XCH, LAS, LAC, and LAT.
def FeatureRMW : SubtargetFeature<"rmw", "m_supportsRMW", "true",
"The device supports the read-write-modify "
"instructions: XCH, LAS, LAC, LAT">;
// The device supports the `[F]MUL[S][U]` family of instructions.
def FeatureMultiplication : SubtargetFeature<"mul", "m_supportsMultiplication",
"true", "The device supports the "
"multiplication instructions">;
// The device supports the `BREAK` instruction.
def FeatureBREAK : SubtargetFeature<"break", "m_hasBREAK", "true",
"The device supports the `BREAK` debugging "
"instruction">;
// The device has instruction encodings specific to the Tiny core.
def FeatureTinyEncoding : SubtargetFeature<"tinyencoding",
"m_hasTinyEncoding", "true",
"The device has Tiny core specific "
"instruction encodings">;
class ELFArch<string name> : SubtargetFeature<"", "ELFArch",
!strconcat("ELF::",name), "">;
// ELF e_flags architecture values
def ELFArchAVR1 : ELFArch<"EF_AVR_ARCH_AVR1">;
def ELFArchAVR2 : ELFArch<"EF_AVR_ARCH_AVR2">;
def ELFArchAVR25 : ELFArch<"EF_AVR_ARCH_AVR25">;
def ELFArchAVR3 : ELFArch<"EF_AVR_ARCH_AVR3">;
def ELFArchAVR31 : ELFArch<"EF_AVR_ARCH_AVR31">;
def ELFArchAVR35 : ELFArch<"EF_AVR_ARCH_AVR35">;
def ELFArchAVR4 : ELFArch<"EF_AVR_ARCH_AVR4">;
def ELFArchAVR5 : ELFArch<"EF_AVR_ARCH_AVR5">;
def ELFArchAVR51 : ELFArch<"EF_AVR_ARCH_AVR51">;
def ELFArchAVR6 : ELFArch<"EF_AVR_ARCH_AVR6">;
def ELFArchTiny : ELFArch<"EF_AVR_ARCH_AVRTINY">;
def ELFArchXMEGA1 : ELFArch<"EF_AVR_ARCH_XMEGA1">;
def ELFArchXMEGA2 : ELFArch<"EF_AVR_ARCH_XMEGA2">;
def ELFArchXMEGA3 : ELFArch<"EF_AVR_ARCH_XMEGA3">;
def ELFArchXMEGA4 : ELFArch<"EF_AVR_ARCH_XMEGA4">;
def ELFArchXMEGA5 : ELFArch<"EF_AVR_ARCH_XMEGA5">;
def ELFArchXMEGA6 : ELFArch<"EF_AVR_ARCH_XMEGA6">;
def ELFArchXMEGA7 : ELFArch<"EF_AVR_ARCH_XMEGA7">;
//===---------------------------------------------------------------------===//
// AVR Families
//===---------------------------------------------------------------------===//
// The device has at least the bare minimum that **every** single AVR
// device should have.
def FamilyAVR0 : Family<"avr0", []>;
def FamilyAVR1 : Family<"avr1", [FamilyAVR0, FeatureLPM]>;
def FamilyAVR2 : Family<"avr2",
[FamilyAVR1, FeatureIJMPCALL, FeatureADDSUBIW,
FeatureSRAM]>;
def FamilyAVR25 : Family<"avr25",
[FamilyAVR2, FeatureMOVW, FeatureLPMX,
FeatureSPM, FeatureBREAK]>;
def FamilyAVR3 : Family<"avr3",
[FamilyAVR2, FeatureJMPCALL]>;
def FamilyAVR31 : Family<"avr31",
[FamilyAVR3, FeatureELPM]>;
def FamilyAVR35 : Family<"avr35",
[FamilyAVR3, FeatureMOVW, FeatureLPMX,
FeatureSPM, FeatureBREAK]>;
def FamilyAVR4 : Family<"avr4",
[FamilyAVR2, FeatureMultiplication,
FeatureMOVW, FeatureLPMX, FeatureSPM,
FeatureBREAK]>;
def FamilyAVR5 : Family<"avr5",
[FamilyAVR3, FeatureMultiplication,
FeatureMOVW, FeatureLPMX, FeatureSPM,
FeatureBREAK]>;
def FamilyAVR51 : Family<"avr51",
[FamilyAVR5, FeatureELPM, FeatureELPMX]>;
def FamilyAVR6 : Family<"avr6",
[FamilyAVR51]>;
def FamilyTiny : Family<"avrtiny",
[FamilyAVR0, FeatureBREAK, FeatureSRAM,
FeatureTinyEncoding]>;
def FamilyXMEGA : Family<"xmega",
[FamilyAVR51, FeatureEIJMPCALL, FeatureSPMX,
FeatureDES]>;
def FamilyXMEGAU : Family<"xmegau",
[FamilyXMEGA, FeatureRMW]>;
def FeatureSetSpecial : FeatureSet<"special",
"Enable use of the entire instruction "
"set - used for debugging",
[FeatureSRAM, FeatureJMPCALL,
FeatureIJMPCALL, FeatureEIJMPCALL,
FeatureADDSUBIW, FeatureMOVW,
FeatureLPM, FeatureLPMX, FeatureELPM,
FeatureELPMX, FeatureSPM, FeatureSPMX,
FeatureDES, FeatureRMW,
FeatureMultiplication, FeatureBREAK]>;
//===---------------------------------------------------------------------===//
// AVR microcontrollers supported.
//===---------------------------------------------------------------------===//
class Device<string Name, Family Fam, ELFArch Arch,
list<SubtargetFeature> ExtraFeatures = []>
: Processor<Name, NoItineraries, !listconcat([Fam,Arch],ExtraFeatures)>;
// Generic MCUs
// Note that several versions of GCC has strange ELF architecture
// settings for backwards compatibility - see `gas/config/tc-avr.c`
// in AVR binutils. We do not replicate this.
def : Device<"avr1", FamilyAVR1, ELFArchAVR1>;
def : Device<"avr2", FamilyAVR2, ELFArchAVR2>;
def : Device<"avr25", FamilyAVR25, ELFArchAVR25>;
def : Device<"avr3", FamilyAVR3, ELFArchAVR3>;
def : Device<"avr31", FamilyAVR31, ELFArchAVR31>;
def : Device<"avr35", FamilyAVR35, ELFArchAVR35>;
def : Device<"avr4", FamilyAVR4, ELFArchAVR4>;
def : Device<"avr5", FamilyAVR5, ELFArchAVR5>;
def : Device<"avr51", FamilyAVR51, ELFArchAVR51>;
def : Device<"avr6", FamilyAVR6, ELFArchAVR6>;
def : Device<"avrxmega1", FamilyXMEGA, ELFArchXMEGA1>;
def : Device<"avrxmega2", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"avrxmega3", FamilyXMEGA, ELFArchXMEGA3>;
def : Device<"avrxmega4", FamilyXMEGA, ELFArchXMEGA4>;
def : Device<"avrxmega5", FamilyXMEGA, ELFArchXMEGA5>;
def : Device<"avrxmega6", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"avrxmega7", FamilyXMEGA, ELFArchXMEGA7>;
def : Device<"avrtiny", FamilyTiny, ELFArchTiny>;
// Specific MCUs
def : Device<"at90s1200", FamilyAVR0, ELFArchAVR1>;
def : Device<"attiny11", FamilyAVR1, ELFArchAVR1>;
def : Device<"attiny12", FamilyAVR1, ELFArchAVR1>;
def : Device<"attiny15", FamilyAVR1, ELFArchAVR1>;
def : Device<"attiny28", FamilyAVR1, ELFArchAVR1>;
def : Device<"at90s2313", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s2323", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s2333", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s2343", FamilyAVR2, ELFArchAVR2>;
def : Device<"attiny22", FamilyAVR2, ELFArchAVR2>;
def : Device<"attiny26", FamilyAVR2, ELFArchAVR2, [FeatureLPMX]>;
def : Device<"at86rf401", FamilyAVR2, ELFArchAVR25,
[FeatureMOVW, FeatureLPMX]>;
def : Device<"at90s4414", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s4433", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s4434", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s8515", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90c8534", FamilyAVR2, ELFArchAVR2>;
def : Device<"at90s8535", FamilyAVR2, ELFArchAVR2>;
def : Device<"ata5272", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny13", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny13a", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny2313", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny2313a", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny24", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny24a", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny4313", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny44", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny44a", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny84", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny84a", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny25", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny45", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny85", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny261", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny261a", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny461", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny461a", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny861", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny861a", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny87", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny43u", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny48", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny88", FamilyAVR25, ELFArchAVR25>;
def : Device<"attiny828", FamilyAVR25, ELFArchAVR25>;
def : Device<"at43usb355", FamilyAVR3, ELFArchAVR3>;
def : Device<"at76c711", FamilyAVR3, ELFArchAVR3>;
def : Device<"atmega103", FamilyAVR31, ELFArchAVR31>;
def : Device<"at43usb320", FamilyAVR31, ELFArchAVR31>;
def : Device<"attiny167", FamilyAVR35, ELFArchAVR35>;
def : Device<"at90usb82", FamilyAVR35, ELFArchAVR35>;
def : Device<"at90usb162", FamilyAVR35, ELFArchAVR35>;
def : Device<"ata5505", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega8u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega16u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega32u2", FamilyAVR35, ELFArchAVR35>;
def : Device<"attiny1634", FamilyAVR35, ELFArchAVR35>;
def : Device<"atmega8", FamilyAVR4, ELFArchAVR4>; // FIXME: family may be wrong
def : Device<"ata6289", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega8a", FamilyAVR4, ELFArchAVR4>;
def : Device<"ata6285", FamilyAVR4, ELFArchAVR4>;
def : Device<"ata6286", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega48", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega48a", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega48pa", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega48p", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88a", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88p", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega88pa", FamilyAVR4, ELFArchAVR4>;
def : Device<"atmega8515", FamilyAVR2, ELFArchAVR4,
[FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
def : Device<"atmega8535", FamilyAVR2, ELFArchAVR4,
[FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
def : Device<"atmega8hva", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm1", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm2", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm2b", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm3", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm3b", FamilyAVR4, ELFArchAVR4>;
def : Device<"at90pwm81", FamilyAVR4, ELFArchAVR4>;
def : Device<"ata5790", FamilyAVR5, ELFArchAVR5>;
def : Device<"ata5795", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega16", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega16a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega161", FamilyAVR3, ELFArchAVR5,
[FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
def : Device<"atmega162", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega163", FamilyAVR3, ELFArchAVR5,
[FeatureMultiplication, FeatureMOVW, FeatureLPMX, FeatureSPM]>;
def : Device<"atmega164a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega164p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega164pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega165", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega165a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega165p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega165pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega168", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega168a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega168p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega168pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega169", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega169a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega169p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega169pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega32", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega32a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega323", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega324a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega324p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega324pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega325", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega325a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega325p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega325pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega3250", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega3250a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega3250p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega3250pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega328", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega328p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega329", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega329a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega329p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega329pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega3290", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega3290a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega3290p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega3290pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega406", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega64", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega64a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega640", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega644", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega644a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega644p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega644pa", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega645", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega645a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega645p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega649", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega649a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega649p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega6450", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega6450a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega6450p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega6490", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega6490a", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega6490p", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega64rfr2", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega644rfr2", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega16hva", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega16hva2", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega16hvb", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega16hvbrevb", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega32hvb", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega32hvbrevb", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega64hve", FamilyAVR5, ELFArchAVR5>;
def : Device<"at90can32", FamilyAVR5, ELFArchAVR5>;
def : Device<"at90can64", FamilyAVR5, ELFArchAVR5>;
def : Device<"at90pwm161", FamilyAVR5, ELFArchAVR5>;
def : Device<"at90pwm216", FamilyAVR5, ELFArchAVR5>;
def : Device<"at90pwm316", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega32c1", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega64c1", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega16m1", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega32m1", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega64m1", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega16u4", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega32u4", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega32u6", FamilyAVR5, ELFArchAVR5>;
def : Device<"at90usb646", FamilyAVR5, ELFArchAVR5>;
def : Device<"at90usb647", FamilyAVR5, ELFArchAVR5>;
def : Device<"at90scr100", FamilyAVR5, ELFArchAVR5>;
def : Device<"at94k", FamilyAVR3, ELFArchAVR5,
[FeatureMultiplication, FeatureMOVW, FeatureLPMX]>;
def : Device<"m3000", FamilyAVR5, ELFArchAVR5>;
def : Device<"atmega128", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega128a", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega1280", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega1281", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega1284", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega1284p", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega128rfa1", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega128rfr2", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega1284rfr2", FamilyAVR51, ELFArchAVR51>;
def : Device<"at90can128", FamilyAVR51, ELFArchAVR51>;
def : Device<"at90usb1286", FamilyAVR51, ELFArchAVR51>;
def : Device<"at90usb1287", FamilyAVR51, ELFArchAVR51>;
def : Device<"atmega2560", FamilyAVR6, ELFArchAVR6>;
def : Device<"atmega2561", FamilyAVR6, ELFArchAVR6>;
def : Device<"atmega256rfr2", FamilyAVR6, ELFArchAVR6>;
def : Device<"atmega2564rfr2", FamilyAVR6, ELFArchAVR6>;
def : Device<"atxmega16a4", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"atxmega16a4u", FamilyXMEGAU, ELFArchXMEGA2>;
def : Device<"atxmega16c4", FamilyXMEGAU, ELFArchXMEGA2>;
def : Device<"atxmega16d4", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"atxmega32a4", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"atxmega32a4u", FamilyXMEGAU, ELFArchXMEGA2>;
def : Device<"atxmega32c4", FamilyXMEGAU, ELFArchXMEGA2>;
def : Device<"atxmega32d4", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"atxmega32e5", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"atxmega16e5", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"atxmega8e5", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"atxmega32x1", FamilyXMEGA, ELFArchXMEGA2>;
def : Device<"atxmega64a3", FamilyXMEGA, ELFArchXMEGA4>;
def : Device<"atxmega64a3u", FamilyXMEGAU, ELFArchXMEGA4>;
def : Device<"atxmega64a4u", FamilyXMEGAU, ELFArchXMEGA4>;
def : Device<"atxmega64b1", FamilyXMEGAU, ELFArchXMEGA4>;
def : Device<"atxmega64b3", FamilyXMEGAU, ELFArchXMEGA4>;
def : Device<"atxmega64c3", FamilyXMEGAU, ELFArchXMEGA4>;
def : Device<"atxmega64d3", FamilyXMEGA, ELFArchXMEGA4>;
def : Device<"atxmega64d4", FamilyXMEGA, ELFArchXMEGA4>;
def : Device<"atxmega64a1", FamilyXMEGA, ELFArchXMEGA5>;
def : Device<"atxmega64a1u", FamilyXMEGAU, ELFArchXMEGA5>;
def : Device<"atxmega128a3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega128a3u", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega128b1", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega128b3", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega128c3", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega128d3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega128d4", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega192a3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega192a3u", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega192c3", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega192d3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega256a3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega256a3u", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega256a3b", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega256a3bu", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega256c3", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega256d3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega384c3", FamilyXMEGAU, ELFArchXMEGA6>;
def : Device<"atxmega384d3", FamilyXMEGA, ELFArchXMEGA6>;
def : Device<"atxmega128a1", FamilyXMEGA, ELFArchXMEGA7>;
def : Device<"atxmega128a1u", FamilyXMEGAU, ELFArchXMEGA7>;
def : Device<"atxmega128a4u", FamilyXMEGAU, ELFArchXMEGA7>;
def : Device<"attiny4", FamilyTiny, ELFArchTiny>;
def : Device<"attiny5", FamilyTiny, ELFArchTiny>;
def : Device<"attiny9", FamilyTiny, ELFArchTiny>;
def : Device<"attiny10", FamilyTiny, ELFArchTiny>;
def : Device<"attiny20", FamilyTiny, ELFArchTiny>;
def : Device<"attiny40", FamilyTiny, ELFArchTiny>;
def : Device<"attiny102", FamilyTiny, ELFArchTiny>;
def : Device<"attiny104", FamilyTiny, ELFArchTiny>;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,46 +0,0 @@
//===-- AVRFrameLowering.h - Define frame lowering for AVR ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_FRAME_LOWERING_H
#define LLVM_AVR_FRAME_LOWERING_H
#include "llvm/CodeGen/TargetFrameLowering.h"
namespace llvm {
/// Utilities for creating function call frames.
class AVRFrameLowering : public TargetFrameLowering {
public:
explicit AVRFrameLowering();
public:
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
bool hasFP(const MachineFunction &MF) const override;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override;
bool
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const override;
bool hasReservedCallFrame(const MachineFunction &MF) const override;
bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS = nullptr) const override;
MachineBasicBlock::iterator
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const override;
};
} // end namespace llvm
#endif // LLVM_AVR_FRAME_LOWERING_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,174 +0,0 @@
//===-- AVRISelLowering.h - AVR DAG Lowering Interface ----------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the interfaces that AVR uses to lower LLVM code into a
// selection DAG.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_ISEL_LOWERING_H
#define LLVM_AVR_ISEL_LOWERING_H
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/TargetLowering.h"
namespace llvm {
namespace AVRISD {
/// AVR Specific DAG Nodes
enum NodeType {
/// Start the numbering where the builtin ops leave off.
FIRST_NUMBER = ISD::BUILTIN_OP_END,
/// Return from subroutine.
RET_FLAG,
/// Return from ISR.
RETI_FLAG,
/// Represents an abstract call instruction,
/// which includes a bunch of information.
CALL,
/// A wrapper node for TargetConstantPool,
/// TargetExternalSymbol, and TargetGlobalAddress.
WRAPPER,
LSL, ///< Logical shift left.
LSR, ///< Logical shift right.
ASR, ///< Arithmetic shift right.
ROR, ///< Bit rotate right.
ROL, ///< Bit rotate left.
LSLLOOP, ///< A loop of single logical shift left instructions.
LSRLOOP, ///< A loop of single logical shift right instructions.
ROLLOOP, ///< A loop of single left bit rotate instructions.
RORLOOP, ///< A loop of single right bit rotate instructions.
ASRLOOP, ///< A loop of single arithmetic shift right instructions.
/// AVR conditional branches. Operand 0 is the chain operand, operand 1
/// is the block to branch if condition is true, operand 2 is the
/// condition code, and operand 3 is the flag operand produced by a CMP
/// or TEST instruction.
BRCOND,
/// Compare instruction.
CMP,
/// Compare with carry instruction.
CMPC,
/// Test for zero or minus instruction.
TST,
/// Operand 0 and operand 1 are selection variable, operand 2
/// is condition code and operand 3 is flag operand.
SELECT_CC
};
} // end of namespace AVRISD
class AVRTargetMachine;
/// Performs target lowering for the AVR.
class AVRTargetLowering : public TargetLowering {
public:
explicit AVRTargetLowering(AVRTargetMachine &TM);
public:
MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override {
return MVT::i8;
}
MVT::SimpleValueType getCmpLibcallReturnType() const override {
return MVT::i8;
}
const char *getTargetNodeName(unsigned Opcode) const override;
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
SelectionDAG &DAG) const override;
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
unsigned AS,
Instruction *I = nullptr) const override;
bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset,
ISD::MemIndexedMode &AM,
SelectionDAG &DAG) const override;
bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base,
SDValue &Offset, ISD::MemIndexedMode &AM,
SelectionDAG &DAG) const override;
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
EVT VT) const override;
MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *MBB) const override;
ConstraintType getConstraintType(StringRef Constraint) const override;
ConstraintWeight
getSingleConstraintMatchWeight(AsmOperandInfo &info,
const char *constraint) const override;
std::pair<unsigned, const TargetRegisterClass *>
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
StringRef Constraint, MVT VT) const override;
unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
std::vector<SDValue> &Ops,
SelectionDAG &DAG) const override;
unsigned getRegisterByName(const char* RegName, EVT VT,
SelectionDAG &DAG) const override;
private:
SDValue getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &AVRcc,
SelectionDAG &DAG, SDLoc dl) const;
SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC) const;
bool CanLowerReturn(CallingConv::ID CallConv,
MachineFunction &MF, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
LLVMContext &Context) const override;
SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
SelectionDAG &DAG) const override;
SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const override;
SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
const SDLoc &dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const;
private:
MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB) const;
MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const;
};
} // end namespace llvm
#endif // LLVM_AVR_ISEL_LOWERING_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,122 +0,0 @@
//===-- AVRInstrInfo.h - AVR Instruction Information ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the AVR implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_INSTR_INFO_H
#define LLVM_AVR_INSTR_INFO_H
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "AVRRegisterInfo.h"
#define GET_INSTRINFO_HEADER
#include "AVRGenInstrInfo.inc"
#undef GET_INSTRINFO_HEADER
namespace llvm {
namespace AVRCC {
/// AVR specific condition codes.
/// These correspond to `AVR_*_COND` in `AVRInstrInfo.td`.
/// They must be kept in synch.
enum CondCodes {
COND_EQ, //!< Equal
COND_NE, //!< Not equal
COND_GE, //!< Greater than or equal
COND_LT, //!< Less than
COND_SH, //!< Unsigned same or higher
COND_LO, //!< Unsigned lower
COND_MI, //!< Minus
COND_PL, //!< Plus
COND_INVALID
};
} // end of namespace AVRCC
namespace AVRII {
/// Specifies a target operand flag.
enum TOF {
MO_NO_FLAG,
/// On a symbol operand, this represents the lo part.
MO_LO = (1 << 1),
/// On a symbol operand, this represents the hi part.
MO_HI = (1 << 2),
/// On a symbol operand, this represents it has to be negated.
MO_NEG = (1 << 3)
};
} // end of namespace AVRII
/// Utilities related to the AVR instruction set.
class AVRInstrInfo : public AVRGenInstrInfo {
public:
explicit AVRInstrInfo();
const AVRRegisterInfo &getRegisterInfo() const { return RI; }
const MCInstrDesc &getBrCond(AVRCC::CondCodes CC) const;
AVRCC::CondCodes getCondFromBranchOpc(unsigned Opc) const;
AVRCC::CondCodes getOppositeCondition(AVRCC::CondCodes CC) const;
unsigned getInstSizeInBytes(const MachineInstr &MI) const override;
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
const DebugLoc &DL, unsigned DestReg, unsigned SrcReg,
bool KillSrc) const override;
void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, unsigned SrcReg,
bool isKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;
void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI, unsigned DestReg,
int FrameIndex, const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const override;
unsigned isLoadFromStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;
unsigned isStoreToStackSlot(const MachineInstr &MI,
int &FrameIndex) const override;
// Branch analysis.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond,
bool AllowModify = false) const override;
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
const DebugLoc &DL,
int *BytesAdded = nullptr) const override;
unsigned removeBranch(MachineBasicBlock &MBB,
int *BytesRemoved = nullptr) const override;
bool
reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override;
MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override;
bool isBranchOffsetInRange(unsigned BranchOpc,
int64_t BrOffset) const override;
unsigned insertIndirectBranch(MachineBasicBlock &MBB,
MachineBasicBlock &NewDestBB,
const DebugLoc &DL,
int64_t BrOffset,
RegScavenger *RS) const override;
private:
const AVRRegisterInfo RI;
};
} // end namespace llvm
#endif // LLVM_AVR_INSTR_INFO_H

File diff suppressed because it is too large Load Diff

View File

@ -1,112 +0,0 @@
//===-- AVRMCInstLower.cpp - Convert AVR MachineInstr to an MCInst --------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains code to lower AVR MachineInstrs to their corresponding
// MCInst records.
//
//===----------------------------------------------------------------------===//
#include "AVRMCInstLower.h"
#include "AVRInstrInfo.h"
#include "MCTargetDesc/AVRMCExpr.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
MCOperand AVRMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
MCSymbol *Sym) const {
unsigned char TF = MO.getTargetFlags();
const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
bool IsNegated = false;
if (TF & AVRII::MO_NEG) { IsNegated = true; }
if (!MO.isJTI() && MO.getOffset()) {
Expr = MCBinaryExpr::createAdd(
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
}
bool IsFunction = MO.isGlobal() && isa<Function>(MO.getGlobal());
if (TF & AVRII::MO_LO) {
if (IsFunction) {
// N.B. Should we use _GS fixups here to cope with >128k progmem?
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_LO8, Expr, IsNegated, Ctx);
} else {
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, IsNegated, Ctx);
}
} else if (TF & AVRII::MO_HI) {
if (IsFunction) {
// N.B. Should we use _GS fixups here to cope with >128k progmem?
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_PM_HI8, Expr, IsNegated, Ctx);
} else {
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8, Expr, IsNegated, Ctx);
}
} else if (TF != 0) {
llvm_unreachable("Unknown target flag on symbol operand");
}
return MCOperand::createExpr(Expr);
}
void AVRMCInstLower::lowerInstruction(const MachineInstr &MI, MCInst &OutMI) const {
OutMI.setOpcode(MI.getOpcode());
for (MachineOperand const &MO : MI.operands()) {
MCOperand MCOp;
switch (MO.getType()) {
default:
MI.print(errs());
llvm_unreachable("unknown operand type");
case MachineOperand::MO_Register:
// Ignore all implicit register operands.
if (MO.isImplicit())
continue;
MCOp = MCOperand::createReg(MO.getReg());
break;
case MachineOperand::MO_Immediate:
MCOp = MCOperand::createImm(MO.getImm());
break;
case MachineOperand::MO_GlobalAddress:
MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal()));
break;
case MachineOperand::MO_ExternalSymbol:
MCOp = lowerSymbolOperand(
MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName()));
break;
case MachineOperand::MO_MachineBasicBlock:
MCOp = MCOperand::createExpr(
MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
break;
case MachineOperand::MO_RegisterMask:
continue;
case MachineOperand::MO_BlockAddress:
MCOp = lowerSymbolOperand(
MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
break;
case MachineOperand::MO_JumpTableIndex:
MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
break;
case MachineOperand::MO_ConstantPoolIndex:
MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
break;
}
OutMI.addOperand(MCOp);
}
}
} // end of namespace llvm

View File

@ -1,43 +0,0 @@
//===-- AVRMCInstLower.h - Lower MachineInstr to MCInst ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_MCINST_LOWER_H
#define LLVM_AVR_MCINST_LOWER_H
#include "llvm/Support/Compiler.h"
namespace llvm {
class AsmPrinter;
class MachineInstr;
class MachineOperand;
class MCContext;
class MCInst;
class MCOperand;
class MCSymbol;
/// Lowers `MachineInstr` objects into `MCInst` objects.
class AVRMCInstLower {
public:
AVRMCInstLower(MCContext &Ctx, AsmPrinter &Printer)
: Ctx(Ctx), Printer(Printer) {}
/// Lowers a `MachineInstr` into a `MCInst`.
void lowerInstruction(const MachineInstr &MI, MCInst &OutMI) const;
MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
private:
MCContext &Ctx;
AsmPrinter &Printer;
};
} // end namespace llvm
#endif // LLVM_AVR_MCINST_LOWER_H

View File

@ -1,69 +0,0 @@
//===-- AVRMachineFuctionInfo.h - AVR machine function info -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares AVR-specific per-machine-function information.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_MACHINE_FUNCTION_INFO_H
#define LLVM_AVR_MACHINE_FUNCTION_INFO_H
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
/// Contains AVR-specific information for each MachineFunction.
class AVRMachineFunctionInfo : public MachineFunctionInfo {
/// Indicates if a register has been spilled by the register
/// allocator.
bool HasSpills;
/// Indicates if there are any fixed size allocas present.
/// Note that if there are only variable sized allocas this is set to false.
bool HasAllocas;
/// Indicates if arguments passed using the stack are being
/// used inside the function.
bool HasStackArgs;
/// Size of the callee-saved register portion of the
/// stack frame in bytes.
unsigned CalleeSavedFrameSize;
/// FrameIndex for start of varargs area.
int VarArgsFrameIndex;
public:
AVRMachineFunctionInfo()
: HasSpills(false), HasAllocas(false), HasStackArgs(false),
CalleeSavedFrameSize(0), VarArgsFrameIndex(0) {}
explicit AVRMachineFunctionInfo(MachineFunction &MF)
: HasSpills(false), HasAllocas(false), HasStackArgs(false),
CalleeSavedFrameSize(0), VarArgsFrameIndex(0) {}
bool getHasSpills() const { return HasSpills; }
void setHasSpills(bool B) { HasSpills = B; }
bool getHasAllocas() const { return HasAllocas; }
void setHasAllocas(bool B) { HasAllocas = B; }
bool getHasStackArgs() const { return HasStackArgs; }
void setHasStackArgs(bool B) { HasStackArgs = B; }
unsigned getCalleeSavedFrameSize() const { return CalleeSavedFrameSize; }
void setCalleeSavedFrameSize(unsigned Bytes) { CalleeSavedFrameSize = Bytes; }
int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }
void setVarArgsFrameIndex(int Idx) { VarArgsFrameIndex = Idx; }
};
} // end llvm namespace
#endif // LLVM_AVR_MACHINE_FUNCTION_INFO_H

View File

@ -1,275 +0,0 @@
//===-- AVRRegisterInfo.cpp - AVR Register Information --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the AVR implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#include "AVRRegisterInfo.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "AVR.h"
#include "AVRInstrInfo.h"
#include "AVRTargetMachine.h"
#include "MCTargetDesc/AVRMCTargetDesc.h"
#define GET_REGINFO_TARGET_DESC
#include "AVRGenRegisterInfo.inc"
namespace llvm {
AVRRegisterInfo::AVRRegisterInfo() : AVRGenRegisterInfo(0) {}
const uint16_t *
AVRRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
CallingConv::ID CC = MF->getFunction().getCallingConv();
return ((CC == CallingConv::AVR_INTR || CC == CallingConv::AVR_SIGNAL)
? CSR_Interrupts_SaveList
: CSR_Normal_SaveList);
}
const uint32_t *
AVRRegisterInfo::getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const {
return ((CC == CallingConv::AVR_INTR || CC == CallingConv::AVR_SIGNAL)
? CSR_Interrupts_RegMask
: CSR_Normal_RegMask);
}
BitVector AVRRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
// Reserve the intermediate result registers r1 and r2
// The result of instructions like 'mul' is always stored here.
Reserved.set(AVR::R0);
Reserved.set(AVR::R1);
Reserved.set(AVR::R1R0);
// Reserve the stack pointer.
Reserved.set(AVR::SPL);
Reserved.set(AVR::SPH);
Reserved.set(AVR::SP);
// We tenatively reserve the frame pointer register r29:r28 because the
// function may require one, but we cannot tell until register allocation
// is complete, which can be too late.
//
// Instead we just unconditionally reserve the Y register.
//
// TODO: Write a pass to enumerate functions which reserved the Y register
// but didn't end up needing a frame pointer. In these, we can
// convert one or two of the spills inside to use the Y register.
Reserved.set(AVR::R28);
Reserved.set(AVR::R29);
Reserved.set(AVR::R29R28);
return Reserved;
}
const TargetRegisterClass *
AVRRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
const MachineFunction &MF) const {
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
return &AVR::DREGSRegClass;
}
if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
return &AVR::GPR8RegClass;
}
llvm_unreachable("Invalid register size");
}
/// Fold a frame offset shared between two add instructions into a single one.
static void foldFrameOffset(MachineBasicBlock::iterator &II, int &Offset, unsigned DstReg) {
MachineInstr &MI = *II;
int Opcode = MI.getOpcode();
// Don't bother trying if the next instruction is not an add or a sub.
if ((Opcode != AVR::SUBIWRdK) && (Opcode != AVR::ADIWRdK)) {
return;
}
// Check that DstReg matches with next instruction, otherwise the instruction
// is not related to stack address manipulation.
if (DstReg != MI.getOperand(0).getReg()) {
return;
}
// Add the offset in the next instruction to our offset.
switch (Opcode) {
case AVR::SUBIWRdK:
Offset += -MI.getOperand(2).getImm();
break;
case AVR::ADIWRdK:
Offset += MI.getOperand(2).getImm();
break;
}
// Finally remove the instruction.
II++;
MI.eraseFromParent();
}
void AVRRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
assert(SPAdj == 0 && "Unexpected SPAdj value");
MachineInstr &MI = *II;
DebugLoc dl = MI.getDebugLoc();
MachineBasicBlock &MBB = *MI.getParent();
const MachineFunction &MF = *MBB.getParent();
const AVRTargetMachine &TM = (const AVRTargetMachine &)MF.getTarget();
const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
const MachineFrameInfo &MFI = MF.getFrameInfo();
const TargetFrameLowering *TFI = TM.getSubtargetImpl()->getFrameLowering();
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
int Offset = MFI.getObjectOffset(FrameIndex);
// Add one to the offset because SP points to an empty slot.
Offset += MFI.getStackSize() - TFI->getOffsetOfLocalArea() + 1;
// Fold incoming offset.
Offset += MI.getOperand(FIOperandNum + 1).getImm();
// This is actually "load effective address" of the stack slot
// instruction. We have only two-address instructions, thus we need to
// expand it into move + add.
if (MI.getOpcode() == AVR::FRMIDX) {
MI.setDesc(TII.get(AVR::MOVWRdRr));
MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
assert(Offset > 0 && "Invalid offset");
// We need to materialize the offset via an add instruction.
unsigned Opcode;
unsigned DstReg = MI.getOperand(0).getReg();
assert(DstReg != AVR::R29R28 && "Dest reg cannot be the frame pointer");
II++; // Skip over the FRMIDX (and now MOVW) instruction.
// Generally, to load a frame address two add instructions are emitted that
// could get folded into a single one:
// movw r31:r30, r29:r28
// adiw r31:r30, 29
// adiw r31:r30, 16
// to:
// movw r31:r30, r29:r28
// adiw r31:r30, 45
if (II != MBB.end())
foldFrameOffset(II, Offset, DstReg);
// Select the best opcode based on DstReg and the offset size.
switch (DstReg) {
case AVR::R25R24:
case AVR::R27R26:
case AVR::R31R30: {
if (isUInt<6>(Offset)) {
Opcode = AVR::ADIWRdK;
break;
}
LLVM_FALLTHROUGH;
}
default: {
// This opcode will get expanded into a pair of subi/sbci.
Opcode = AVR::SUBIWRdK;
Offset = -Offset;
break;
}
}
MachineInstr *New = BuildMI(MBB, II, dl, TII.get(Opcode), DstReg)
.addReg(DstReg, RegState::Kill)
.addImm(Offset);
New->getOperand(3).setIsDead();
return;
}
// If the offset is too big we have to adjust and restore the frame pointer
// to materialize a valid load/store with displacement.
//:TODO: consider using only one adiw/sbiw chain for more than one frame index
if (Offset > 62) {
unsigned AddOpc = AVR::ADIWRdK, SubOpc = AVR::SBIWRdK;
int AddOffset = Offset - 63 + 1;
// For huge offsets where adiw/sbiw cannot be used use a pair of subi/sbci.
if ((Offset - 63 + 1) > 63) {
AddOpc = AVR::SUBIWRdK;
SubOpc = AVR::SUBIWRdK;
AddOffset = -AddOffset;
}
// It is possible that the spiller places this frame instruction in between
// a compare and branch, invalidating the contents of SREG set by the
// compare instruction because of the add/sub pairs. Conservatively save and
// restore SREG before and after each add/sub pair.
BuildMI(MBB, II, dl, TII.get(AVR::INRdA), AVR::R0).addImm(0x3f);
MachineInstr *New = BuildMI(MBB, II, dl, TII.get(AddOpc), AVR::R29R28)
.addReg(AVR::R29R28, RegState::Kill)
.addImm(AddOffset);
New->getOperand(3).setIsDead();
// Restore SREG.
BuildMI(MBB, std::next(II), dl, TII.get(AVR::OUTARr))
.addImm(0x3f)
.addReg(AVR::R0, RegState::Kill);
// No need to set SREG as dead here otherwise if the next instruction is a
// cond branch it will be using a dead register.
New = BuildMI(MBB, std::next(II), dl, TII.get(SubOpc), AVR::R29R28)
.addReg(AVR::R29R28, RegState::Kill)
.addImm(Offset - 63 + 1);
Offset = 62;
}
MI.getOperand(FIOperandNum).ChangeToRegister(AVR::R29R28, false);
assert(isUInt<6>(Offset) && "Offset is out of range");
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
}
unsigned AVRRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
if (TFI->hasFP(MF)) {
// The Y pointer register
return AVR::R28;
}
return AVR::SP;
}
const TargetRegisterClass *
AVRRegisterInfo::getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const {
// FIXME: Currently we're using avr-gcc as reference, so we restrict
// ptrs to Y and Z regs. Though avr-gcc has buggy implementation
// of memory constraint, so we can fix it and bit avr-gcc here ;-)
return &AVR::PTRDISPREGSRegClass;
}
void AVRRegisterInfo::splitReg(unsigned Reg,
unsigned &LoReg,
unsigned &HiReg) const {
assert(AVR::DREGSRegClass.contains(Reg) && "can only split 16-bit registers");
LoReg = getSubReg(Reg, AVR::sub_lo);
HiReg = getSubReg(Reg, AVR::sub_hi);
}
} // end of namespace llvm

View File

@ -1,58 +0,0 @@
//===-- AVRRegisterInfo.h - AVR Register Information Impl -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the AVR implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_AVR_REGISTER_INFO_H
#define LLVM_AVR_REGISTER_INFO_H
#include "llvm/CodeGen/TargetRegisterInfo.h"
#define GET_REGINFO_HEADER
#include "AVRGenRegisterInfo.inc"
namespace llvm {
/// Utilities relating to AVR registers.
class AVRRegisterInfo : public AVRGenRegisterInfo {
public:
AVRRegisterInfo();
public:
const uint16_t *
getCalleeSavedRegs(const MachineFunction *MF = 0) const override;
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const override;
BitVector getReservedRegs(const MachineFunction &MF) const override;
const TargetRegisterClass *
getLargestLegalSuperClass(const TargetRegisterClass *RC,
const MachineFunction &MF) const override;
/// Stack Frame Processing Methods
void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
unsigned FIOperandNum,
RegScavenger *RS = NULL) const override;
unsigned getFrameRegister(const MachineFunction &MF) const override;
const TargetRegisterClass *
getPointerRegClass(const MachineFunction &MF,
unsigned Kind = 0) const override;
/// Splits a 16-bit `DREGS` register into the lo/hi register pair.
/// \param Reg A 16-bit register to split.
void splitReg(unsigned Reg, unsigned &LoReg, unsigned &HiReg) const;
};
} // end namespace llvm
#endif // LLVM_AVR_REGISTER_INFO_H

Some files were not shown because too many files have changed in this diff Show More