diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:10:56 +0000 |
| commit | 044eb2f6afba375a914ac9d8024f8f5142bb912e (patch) | |
| tree | 1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Target/AVR | |
| parent | eb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff) | |
Notes
Diffstat (limited to 'lib/Target/AVR')
29 files changed, 354 insertions, 294 deletions
diff --git a/lib/Target/AVR/AVR.h b/lib/Target/AVR/AVR.h index 5eadf7bdcef6..2535b63dccdd 100644 --- a/lib/Target/AVR/AVR.h +++ b/lib/Target/AVR/AVR.h @@ -27,13 +27,11 @@ FunctionPass *createAVRISelDag(AVRTargetMachine &TM, CodeGenOpt::Level OptLevel); FunctionPass *createAVRExpandPseudoPass(); FunctionPass *createAVRFrameAnalyzerPass(); -FunctionPass *createAVRInstrumentFunctionsPass(); FunctionPass *createAVRRelaxMemPass(); FunctionPass *createAVRDynAllocaSRPass(); FunctionPass *createAVRBranchSelectionPass(); void initializeAVRExpandPseudoPass(PassRegistry&); -void initializeAVRInstrumentFunctionsPass(PassRegistry&); void initializeAVRRelaxMemPass(PassRegistry&); /// Contains the AVR backend. diff --git a/lib/Target/AVR/AVRAsmPrinter.cpp b/lib/Target/AVR/AVRAsmPrinter.cpp index c058c9e1f534..f9a6e77387b2 100644 --- a/lib/Target/AVR/AVRAsmPrinter.cpp +++ b/lib/Target/AVR/AVRAsmPrinter.cpp @@ -20,6 +20,8 @@ #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" @@ -27,8 +29,6 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetSubtargetInfo.h" #define DEBUG_TYPE "avr-asm-printer" diff --git a/lib/Target/AVR/AVRExpandPseudoInsts.cpp b/lib/Target/AVR/AVRExpandPseudoInsts.cpp index d6f85edae47c..fec7080081d0 100644 --- a/lib/Target/AVR/AVRExpandPseudoInsts.cpp +++ b/lib/Target/AVR/AVRExpandPseudoInsts.cpp @@ -22,7 +22,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" using namespace llvm; diff --git a/lib/Target/AVR/AVRFrameLowering.cpp b/lib/Target/AVR/AVRFrameLowering.cpp index 0ec8e8b08ceb..3b7322365772 100644 --- a/lib/Target/AVR/AVRFrameLowering.cpp +++ b/lib/Target/AVR/AVRFrameLowering.cpp @@ -53,7 +53,7 @@ bool AVRFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { void AVRFrameLowering::emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const { MachineBasicBlock::iterator MBBI = MBB.begin(); - CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); + CallingConv::ID CallConv = MF.getFunction().getCallingConv(); DebugLoc DL = (MBBI != MBB.end()) ? MBBI->getDebugLoc() : DebugLoc(); const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>(); const AVRInstrInfo &TII = *STI.getInstrInfo(); @@ -143,7 +143,7 @@ void AVRFrameLowering::emitPrologue(MachineFunction &MF, void AVRFrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { - CallingConv::ID CallConv = MF.getFunction()->getCallingConv(); + CallingConv::ID CallConv = MF.getFunction().getCallingConv(); bool isHandler = (CallConv == CallingConv::AVR_INTR || CallConv == CallingConv::AVR_SIGNAL); @@ -275,7 +275,7 @@ bool AVRFrameLowering::spillCalleeSavedRegisters( bool AVRFrameLowering::restoreCalleeSavedRegisters( MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, + std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const { if (CSI.empty()) { return false; diff --git a/lib/Target/AVR/AVRFrameLowering.h b/lib/Target/AVR/AVRFrameLowering.h index 850a43abebfa..a0ba6c951276 100644 --- a/lib/Target/AVR/AVRFrameLowering.h +++ b/lib/Target/AVR/AVRFrameLowering.h @@ -10,7 +10,7 @@ #ifndef LLVM_AVR_FRAME_LOWERING_H #define LLVM_AVR_FRAME_LOWERING_H -#include "llvm/Target/TargetFrameLowering.h" +#include "llvm/CodeGen/TargetFrameLowering.h" namespace llvm { @@ -30,7 +30,7 @@ public: bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, - const std::vector<CalleeSavedInfo> &CSI, + std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const override; bool hasReservedCallFrame(const MachineFunction &MF) const override; bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override; diff --git a/lib/Target/AVR/AVRISelLowering.cpp b/lib/Target/AVR/AVRISelLowering.cpp index d8e8bc1ff554..d9e27e91405c 100644 --- a/lib/Target/AVR/AVRISelLowering.cpp +++ b/lib/Target/AVR/AVRISelLowering.cpp @@ -44,6 +44,7 @@ AVRTargetLowering::AVRTargetLowering(AVRTargetMachine &tm) setBooleanVectorContents(ZeroOrOneBooleanContent); setSchedulingPreference(Sched::RegPressure); setStackPointerRegisterToSaveRestore(AVR::SP); + setSupportsUnalignedAtomics(true); setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); setOperationAction(ISD::BlockAddress, MVT::i16, Custom); @@ -724,7 +725,7 @@ void AVRTargetLowering::ReplaceNodeResults(SDNode *N, /// by AM is legal for this target, for a load/store of the specified type. bool AVRTargetLowering::isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, - unsigned AS) const { + unsigned AS, Instruction *I) const { int64_t Offs = AM.BaseOffs; // Allow absolute addresses. @@ -1038,7 +1039,7 @@ SDValue AVRTargetLowering::LowerFormalArguments( CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext()); - analyzeArguments(nullptr, MF.getFunction(), &DL, 0, &Ins, CallConv, ArgLocs, CCInfo, + analyzeArguments(nullptr, &MF.getFunction(), &DL, 0, &Ins, CallConv, ArgLocs, CCInfo, false, isVarArg); SDValue ArgValue; @@ -1390,7 +1391,7 @@ AVRTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, // Don't emit the ret/reti instruction when the naked attribute is present in // the function being compiled. - if (MF.getFunction()->getAttributes().hasAttribute( + if (MF.getFunction().getAttributes().hasAttribute( AttributeList::FunctionIndex, Attribute::Naked)) { return Chain; } @@ -1471,7 +1472,7 @@ MachineBasicBlock *AVRTargetLowering::insertShift(MachineInstr &MI, const BasicBlock *LLVM_BB = BB->getBasicBlock(); MachineFunction::iterator I; - for (I = F->begin(); I != F->end() && &(*I) != BB; ++I); + for (I = BB->getIterator(); I != F->end() && &(*I) != BB; ++I); if (I != F->end()) ++I; // Create loop block. diff --git a/lib/Target/AVR/AVRISelLowering.h b/lib/Target/AVR/AVRISelLowering.h index 85f9552cd75c..c90c65c81f70 100644 --- a/lib/Target/AVR/AVRISelLowering.h +++ b/lib/Target/AVR/AVRISelLowering.h @@ -16,7 +16,7 @@ #define LLVM_AVR_ISEL_LOWERING_H #include "llvm/CodeGen/CallingConvLower.h" -#include "llvm/Target/TargetLowering.h" +#include "llvm/CodeGen/TargetLowering.h" namespace llvm { @@ -88,7 +88,8 @@ public: SelectionDAG &DAG) const override; bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, - unsigned AS) const override; + unsigned AS, + Instruction *I = nullptr) const override; bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, ISD::MemIndexedMode &AM, diff --git a/lib/Target/AVR/AVRInstrInfo.h b/lib/Target/AVR/AVRInstrInfo.h index eee8a92c6191..354edcec3466 100644 --- a/lib/Target/AVR/AVRInstrInfo.h +++ b/lib/Target/AVR/AVRInstrInfo.h @@ -14,7 +14,7 @@ #ifndef LLVM_AVR_INSTR_INFO_H #define LLVM_AVR_INSTR_INFO_H -#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetInstrInfo.h" #include "AVRRegisterInfo.h" diff --git a/lib/Target/AVR/AVRInstrumentFunctions.cpp b/lib/Target/AVR/AVRInstrumentFunctions.cpp deleted file mode 100644 index e7fca74e1701..000000000000 --- a/lib/Target/AVR/AVRInstrumentFunctions.cpp +++ /dev/null @@ -1,222 +0,0 @@ -//===-- AVRInstrumentFunctions.cpp - Insert instrumentation for testing ---===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass takes a function and inserts calls to hook functions which are -// told the name, arguments, and results of function calls. -// -// The hooks can do anything with the information given. It is possible to -// send the data through a serial connection in order to runs tests on -// bare metal. -// -//===----------------------------------------------------------------------===// - -#include "AVR.h" - -#include <llvm/IR/Function.h> -#include <llvm/IR/Module.h> - -using namespace llvm; - -#define AVR_INSTRUMENT_FUNCTIONS_NAME "AVR function instrumentation pass" - -namespace { - -// External symbols that we emit calls to. -namespace symbols { - -#define SYMBOL_PREFIX "avr_instrumentation" - - const StringRef PREFIX = SYMBOL_PREFIX; - - // void (i16 argCount); - const StringRef BEGIN_FUNCTION_SIGNATURE = SYMBOL_PREFIX "_begin_signature"; - // void(i16 argCount); - const StringRef END_FUNCTION_SIGNATURE = SYMBOL_PREFIX "_end_signature"; - -#undef SYMBOL_PREFIX -} - -class AVRInstrumentFunctions : public FunctionPass { -public: - static char ID; - - AVRInstrumentFunctions() : FunctionPass(ID) { - initializeAVRInstrumentFunctionsPass(*PassRegistry::getPassRegistry()); - } - - bool runOnFunction(Function &F) override; - - StringRef getPassName() const override { return AVR_INSTRUMENT_FUNCTIONS_NAME; } -}; - -char AVRInstrumentFunctions::ID = 0; - -/// Creates a pointer to a string. -static Value *CreateStringPtr(BasicBlock &BB, StringRef Str) { - LLVMContext &Ctx = BB.getContext(); - IntegerType *I8 = Type::getInt8Ty(Ctx); - - Constant *ConstantStr = ConstantDataArray::getString(Ctx, Str); - GlobalVariable *GlobalStr = new GlobalVariable(*BB.getParent()->getParent(), - ConstantStr->getType(), - true, /* is a constant */ - GlobalValue::PrivateLinkage, - ConstantStr); - return GetElementPtrInst::CreateInBounds(GlobalStr, - {ConstantInt::get(I8, 0), ConstantInt::get(I8, 0)}, "", &BB); -} - -static std::string GetTypeName(Type &Ty) { - if (auto *IntTy = dyn_cast<IntegerType>(&Ty)) { - return std::string("i") + std::to_string(IntTy->getBitWidth()); - } - - if (Ty.isFloatingPointTy()) { - return std::string("f") + std::to_string(Ty.getPrimitiveSizeInBits()); - } - - llvm_unreachable("unknown return type"); -} - -/// Builds a call to one of the signature begin/end hooks. -static void BuildSignatureCall(StringRef SymName, BasicBlock &BB, Function &F) { - LLVMContext &Ctx = F.getContext(); - IntegerType *I16 = Type::getInt16Ty(Ctx); - - FunctionType *FnType = FunctionType::get(Type::getVoidTy(Ctx), - {Type::getInt8PtrTy(Ctx), I16}, false); - - Constant *Fn = F.getParent()->getOrInsertFunction(SymName, FnType); - Value *FunctionName = CreateStringPtr(BB, F.getName()); - - Value *Args[] = {FunctionName, - ConstantInt::get(I16, F.arg_size())}; - CallInst::Create(Fn, Args, "", &BB); -} - -/// Builds instructions to call into an external function to -/// notify about a function signature beginning. -static void BuildBeginSignature(BasicBlock &BB, Function &F) { - return BuildSignatureCall(symbols::BEGIN_FUNCTION_SIGNATURE, BB, F); -} - -/// Builds instructions to call into an external function to -/// notify about a function signature ending. -static void BuildEndSignature(BasicBlock &BB, Function &F) { - return BuildSignatureCall(symbols::END_FUNCTION_SIGNATURE, BB, F); -} - -/// Get the name of the external symbol that we need to call -/// to notify about this argument. -static std::string GetArgumentSymbolName(Argument &Arg) { - return (symbols::PREFIX + "_argument_" + GetTypeName(*Arg.getType())).str(); -} - -/// Builds a call to one of the argument hooks. -static void BuildArgument(BasicBlock &BB, Argument &Arg) { - Function &F = *Arg.getParent(); - LLVMContext &Ctx = F.getContext(); - - Type *I8 = Type::getInt8Ty(Ctx); - - FunctionType *FnType = FunctionType::get(Type::getVoidTy(Ctx), - {Type::getInt8PtrTy(Ctx), I8, Arg.getType()}, false); - - Constant *Fn = F.getParent()->getOrInsertFunction( - GetArgumentSymbolName(Arg), FnType); - Value *ArgName = CreateStringPtr(BB, Arg.getName()); - - Value *Args[] = {ArgName, ConstantInt::get(I8, Arg.getArgNo()), &Arg}; - CallInst::Create(Fn, Args, "", &BB); -} - -/// Builds a call to all of the function signature hooks. -static void BuildSignature(BasicBlock &BB, Function &F) { - BuildBeginSignature(BB, F); - for (Argument &Arg : F.args()) { BuildArgument(BB, Arg); } - BuildEndSignature(BB, F); -} - -/// Builds the instrumentation entry block. -static void BuildEntryBlock(Function &F) { - BasicBlock &EntryBlock = F.getEntryBlock(); - - // Create a new basic block at the start of the existing entry block. - BasicBlock *BB = BasicBlock::Create(F.getContext(), - "instrumentation_entry", - &F, &EntryBlock); - - BuildSignature(*BB, F); - - // Jump to the actual entry block. - BranchInst::Create(&EntryBlock, BB); -} - -static std::string GetReturnSymbolName(Value &Val) { - return (symbols::PREFIX + "_result_" + GetTypeName(*Val.getType())).str(); -} - -static void BuildExitHook(Instruction &I) { - Function &F = *I.getParent()->getParent(); - LLVMContext &Ctx = F.getContext(); - - if (auto *Ret = dyn_cast<ReturnInst>(&I)) { - Value *RetVal = Ret->getReturnValue(); - assert(RetVal && "should only be instrumenting functions with return values"); - - FunctionType *FnType = FunctionType::get(Type::getVoidTy(Ctx), - {RetVal->getType()}, false); - - Constant *Fn = F.getParent()->getOrInsertFunction( - GetReturnSymbolName(*RetVal), FnType); - - // Call the result hook just before the return. - CallInst::Create(Fn, {RetVal}, "", &I); - } -} - -/// Runs return hooks before all returns in a function. -static void BuildExitHooks(Function &F) { - for (BasicBlock &BB : F) { - auto BBI = BB.begin(), E = BB.end(); - while (BBI != E) { - auto NBBI = std::next(BBI); - - BuildExitHook(*BBI); - - // Modified |= expandMI(BB, MBBI); - BBI = NBBI; - } - } -} - -static bool ShouldInstrument(Function &F) { - // No point reporting results if there are none. - return !F.getReturnType()->isVoidTy(); -} - -bool AVRInstrumentFunctions::runOnFunction(Function &F) { - if (ShouldInstrument(F)) { - BuildEntryBlock(F); - BuildExitHooks(F); - } - - return true; -} - -} // end of anonymous namespace - -INITIALIZE_PASS(AVRInstrumentFunctions, "avr-instrument-functions", - AVR_INSTRUMENT_FUNCTIONS_NAME, false, false) - -namespace llvm { - -FunctionPass *createAVRInstrumentFunctionsPass() { return new AVRInstrumentFunctions(); } - -} // end of namespace llvm diff --git a/lib/Target/AVR/AVRRegisterInfo.cpp b/lib/Target/AVR/AVRRegisterInfo.cpp index 7099b29a8bcd..d171a620760e 100644 --- a/lib/Target/AVR/AVRRegisterInfo.cpp +++ b/lib/Target/AVR/AVRRegisterInfo.cpp @@ -18,7 +18,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/IR/Function.h" -#include "llvm/Target/TargetFrameLowering.h" +#include "llvm/CodeGen/TargetFrameLowering.h" #include "AVR.h" #include "AVRInstrInfo.h" @@ -34,7 +34,7 @@ AVRRegisterInfo::AVRRegisterInfo() : AVRGenRegisterInfo(0) {} const uint16_t * AVRRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { - CallingConv::ID CC = MF->getFunction()->getCallingConv(); + CallingConv::ID CC = MF->getFunction().getCallingConv(); return ((CC == CallingConv::AVR_INTR || CC == CallingConv::AVR_SIGNAL) ? CSR_Interrupts_SaveList diff --git a/lib/Target/AVR/AVRRegisterInfo.h b/lib/Target/AVR/AVRRegisterInfo.h index b97e32ea203f..f8fefb859682 100644 --- a/lib/Target/AVR/AVRRegisterInfo.h +++ b/lib/Target/AVR/AVRRegisterInfo.h @@ -14,7 +14,7 @@ #ifndef LLVM_AVR_REGISTER_INFO_H #define LLVM_AVR_REGISTER_INFO_H -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" #define GET_REGINFO_HEADER #include "AVRGenRegisterInfo.inc" diff --git a/lib/Target/AVR/AVRRelaxMemOperations.cpp b/lib/Target/AVR/AVRRelaxMemOperations.cpp index 26dbcf77b452..fdb09897eda8 100644 --- a/lib/Target/AVR/AVRRelaxMemOperations.cpp +++ b/lib/Target/AVR/AVRRelaxMemOperations.cpp @@ -20,7 +20,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/TargetRegisterInfo.h" using namespace llvm; diff --git a/lib/Target/AVR/AVRSubtarget.h b/lib/Target/AVR/AVRSubtarget.h index b0e634f86168..fa26738da190 100644 --- a/lib/Target/AVR/AVRSubtarget.h +++ b/lib/Target/AVR/AVRSubtarget.h @@ -14,9 +14,9 @@ #ifndef LLVM_AVR_SUBTARGET_H #define LLVM_AVR_SUBTARGET_H +#include "llvm/CodeGen/TargetSubtargetInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetSubtargetInfo.h" #include "AVRFrameLowering.h" #include "AVRISelLowering.h" diff --git a/lib/Target/AVR/AVRTargetMachine.cpp b/lib/Target/AVR/AVRTargetMachine.cpp index e698b6e694cf..f9a738b2182c 100644 --- a/lib/Target/AVR/AVRTargetMachine.cpp +++ b/lib/Target/AVR/AVRTargetMachine.cpp @@ -40,14 +40,21 @@ static Reloc::Model getEffectiveRelocModel(Optional<Reloc::Model> RM) { return RM.hasValue() ? *RM : Reloc::Static; } +static CodeModel::Model getEffectiveCodeModel(Optional<CodeModel::Model> CM) { + if (CM) + return *CM; + return CodeModel::Small; +} + AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, - Optional<Reloc::Model> RM, CodeModel::Model CM, - CodeGenOpt::Level OL) - : LLVMTargetMachine( - T, AVRDataLayout, TT, - getCPU(CPU), FS, Options, getEffectiveRelocModel(RM), CM, OL), + Optional<Reloc::Model> RM, + Optional<CodeModel::Model> CM, + CodeGenOpt::Level OL, bool JIT) + : LLVMTargetMachine(T, AVRDataLayout, TT, getCPU(CPU), FS, Options, + getEffectiveRelocModel(RM), getEffectiveCodeModel(CM), + OL), SubTarget(TT, getCPU(CPU), FS, *this) { this->TLOF = make_unique<AVRTargetObjectFile>(); initAsmInfo(); @@ -81,7 +88,6 @@ extern "C" void LLVMInitializeAVRTarget() { auto &PR = *PassRegistry::getPassRegistry(); initializeAVRExpandPseudoPass(PR); - initializeAVRInstrumentFunctionsPass(PR); initializeAVRRelaxMemPass(PR); } diff --git a/lib/Target/AVR/AVRTargetMachine.h b/lib/Target/AVR/AVRTargetMachine.h index 795e94e6af03..ffcf4350d45a 100644 --- a/lib/Target/AVR/AVRTargetMachine.h +++ b/lib/Target/AVR/AVRTargetMachine.h @@ -29,8 +29,10 @@ namespace llvm { class AVRTargetMachine : public LLVMTargetMachine { public: AVRTargetMachine(const Target &T, const Triple &TT, StringRef CPU, - StringRef FS, const TargetOptions &Options, Optional<Reloc::Model> RM, - CodeModel::Model CM, CodeGenOpt::Level OL); + StringRef FS, const TargetOptions &Options, + Optional<Reloc::Model> RM, + Optional<CodeModel::Model> CM, + CodeGenOpt::Level OL, bool JIT); const AVRSubtarget *getSubtargetImpl() const; const AVRSubtarget *getSubtargetImpl(const Function &) const override; diff --git a/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/lib/Target/AVR/AsmParser/AVRAsmParser.cpp index 5004736365c7..b527ad3e0b14 100644 --- a/lib/Target/AVR/AsmParser/AVRAsmParser.cpp +++ b/lib/Target/AVR/AsmParser/AVRAsmParser.cpp @@ -9,6 +9,7 @@ #include "AVR.h" #include "AVRRegisterInfo.h" +#include "MCTargetDesc/AVRMCELFStreamer.h" #include "MCTargetDesc/AVRMCExpr.h" #include "MCTargetDesc/AVRMCTargetDesc.h" @@ -40,6 +41,7 @@ class AVRAsmParser : public MCTargetAsmParser { const MCSubtargetInfo &STI; MCAsmParser &Parser; const MCRegisterInfo *MRI; + const std::string GENERATE_STUBS = "gs"; #define GET_ASSEMBLER_HEADER #include "AVRGenAsmMatcher.inc" @@ -54,7 +56,7 @@ class AVRAsmParser : public MCTargetAsmParser { bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands) override; - bool ParseDirective(AsmToken directiveID) override; + bool ParseDirective(AsmToken DirectiveID) override; OperandMatchResultTy parseMemriOperand(OperandVector &Operands); @@ -80,10 +82,12 @@ class AVRAsmParser : public MCTargetAsmParser { uint64_t const &ErrorInfo); bool missingFeature(SMLoc const &Loc, uint64_t const &ErrorInfo); + bool parseLiteralValues(unsigned SizeInBytes, SMLoc L); + public: AVRAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options) - : MCTargetAsmParser(Options, STI), STI(STI), Parser(Parser) { + : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) { MCAsmParserExtension::Initialize(Parser); MRI = getContext().getRegisterInfo(); @@ -404,11 +408,14 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) { size_t ReadCount = Parser.getLexer().peekTokens(tokens); if (ReadCount == 2) { - if (tokens[0].getKind() == AsmToken::Identifier && - tokens[1].getKind() == AsmToken::LParen) { + if ((tokens[0].getKind() == AsmToken::Identifier && + tokens[1].getKind() == AsmToken::LParen) || + (tokens[0].getKind() == AsmToken::LParen && + tokens[1].getKind() == AsmToken::Minus)) { AsmToken::TokenKind CurTok = Parser.getLexer().getKind(); - if (CurTok == AsmToken::Minus) { + if (CurTok == AsmToken::Minus || + tokens[1].getKind() == AsmToken::Minus) { isNegated = true; } else { assert(CurTok == AsmToken::Plus); @@ -416,7 +423,8 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) { } // Eat the sign - Parser.Lex(); + if (CurTok == AsmToken::Minus || CurTok == AsmToken::Plus) + Parser.Lex(); } } @@ -432,14 +440,34 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) { if (ModifierKind != AVRMCExpr::VK_AVR_None) { Parser.Lex(); Parser.Lex(); // Eat modifier name and parenthesis + if (Parser.getTok().getString() == GENERATE_STUBS && + Parser.getTok().getKind() == AsmToken::Identifier) { + std::string GSModName = ModifierName.str() + "_" + GENERATE_STUBS; + ModifierKind = AVRMCExpr::getKindByName(GSModName.c_str()); + if (ModifierKind != AVRMCExpr::VK_AVR_None) + Parser.Lex(); // Eat gs modifier name + } } else { return Error(Parser.getTok().getLoc(), "unknown modifier"); } + if (tokens[1].getKind() == AsmToken::Minus || + tokens[1].getKind() == AsmToken::Plus) { + Parser.Lex(); + assert(Parser.getTok().getKind() == AsmToken::LParen); + Parser.Lex(); // Eat the sign and parenthesis + } + MCExpr const *InnerExpression; if (getParser().parseExpression(InnerExpression)) return true; + if (tokens[1].getKind() == AsmToken::Minus || + tokens[1].getKind() == AsmToken::Plus) { + assert(Parser.getTok().getKind() == AsmToken::RParen); + Parser.Lex(); // Eat closing parenthesis + } + // If we have a modifier wrap the inner expression assert(Parser.getTok().getKind() == AsmToken::RParen); Parser.Lex(); // Eat closing parenthesis @@ -580,7 +608,59 @@ bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info, return false; } -bool AVRAsmParser::ParseDirective(llvm::AsmToken DirectiveID) { return true; } +bool AVRAsmParser::ParseDirective(llvm::AsmToken DirectiveID) { + StringRef IDVal = DirectiveID.getIdentifier(); + if (IDVal.lower() == ".long") { + parseLiteralValues(SIZE_LONG, DirectiveID.getLoc()); + } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") { + parseLiteralValues(SIZE_WORD, DirectiveID.getLoc()); + } else if (IDVal.lower() == ".byte") { + parseLiteralValues(1, DirectiveID.getLoc()); + } + return true; +} + +bool AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) { + MCAsmParser &Parser = getParser(); + AVRMCELFStreamer &AVRStreamer = + static_cast<AVRMCELFStreamer &>(Parser.getStreamer()); + AsmToken Tokens[2]; + size_t ReadCount = Parser.getLexer().peekTokens(Tokens); + if (ReadCount == 2 && Parser.getTok().getKind() == AsmToken::Identifier && + Tokens[0].getKind() == AsmToken::Minus && + Tokens[1].getKind() == AsmToken::Identifier) { + MCSymbol *Symbol = getContext().getOrCreateSymbol(".text"); + AVRStreamer.EmitValueForModiferKind(Symbol, SizeInBytes, L, + AVRMCExpr::VK_AVR_None); + return false; + } + + if (Parser.getTok().getKind() == AsmToken::Identifier && + Parser.getLexer().peekTok().getKind() == AsmToken::LParen) { + StringRef ModifierName = Parser.getTok().getString(); + AVRMCExpr::VariantKind ModifierKind = + AVRMCExpr::getKindByName(ModifierName.str().c_str()); + if (ModifierKind != AVRMCExpr::VK_AVR_None) { + Parser.Lex(); + Parser.Lex(); // Eat the modifier and parenthesis + } else { + return Error(Parser.getTok().getLoc(), "unknown modifier"); + } + MCSymbol *Symbol = + getContext().getOrCreateSymbol(Parser.getTok().getString()); + AVRStreamer.EmitValueForModiferKind(Symbol, SizeInBytes, L, ModifierKind); + return false; + } + + auto parseOne = [&]() -> bool { + const MCExpr *Value; + if (Parser.parseExpression(Value)) + return true; + Parser.getStreamer().EmitValue(Value, SizeInBytes, L); + return false; + }; + return (parseMany(parseOne)); +} extern "C" void LLVMInitializeAVRAsmParser() { RegisterMCAsmParser<AVRAsmParser> X(getTheAVRTarget()); diff --git a/lib/Target/AVR/CMakeLists.txt b/lib/Target/AVR/CMakeLists.txt index e103a60fa6ff..af89a2476c4c 100644 --- a/lib/Target/AVR/CMakeLists.txt +++ b/lib/Target/AVR/CMakeLists.txt @@ -21,7 +21,6 @@ add_llvm_target(AVRCodeGen AVRExpandPseudoInsts.cpp AVRFrameLowering.cpp AVRInstrInfo.cpp - AVRInstrumentFunctions.cpp AVRISelDAGToDAG.cpp AVRISelLowering.cpp AVRMCInstLower.cpp diff --git a/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp b/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp index d18298385adf..2d9dd4f8f83f 100644 --- a/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp +++ b/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp @@ -265,15 +265,19 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, adjust::ldi::fixup(Size, Fixup, Value, Ctx); break; case AVR::fixup_lo8_ldi: + adjust::ldi::lo8(Size, Fixup, Value, Ctx); + break; case AVR::fixup_lo8_ldi_pm: - if (Kind == AVR::fixup_lo8_ldi_pm) adjust::pm(Value); - + case AVR::fixup_lo8_ldi_gs: + adjust::pm(Value); adjust::ldi::lo8(Size, Fixup, Value, Ctx); break; case AVR::fixup_hi8_ldi: + adjust::ldi::hi8(Size, Fixup, Value, Ctx); + break; case AVR::fixup_hi8_ldi_pm: - if (Kind == AVR::fixup_hi8_ldi_pm) adjust::pm(Value); - + case AVR::fixup_hi8_ldi_gs: + adjust::pm(Value); adjust::ldi::hi8(Size, Fixup, Value, Ctx); break; case AVR::fixup_hh8_ldi: @@ -316,6 +320,13 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, Value &= 0xffff; break; + case AVR::fixup_16_pm: + Value >>= 1; // Flash addresses are always shifted. + adjust::unsigned_width(16, Value, std::string("port number"), Fixup, Ctx); + + Value &= 0xffff; + break; + case AVR::fixup_6_adiw: adjust::fixup_6_adiw(Fixup, Value, Ctx); break; @@ -329,6 +340,7 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, break; // Fixups which do not require adjustments. + case FK_Data_1: case FK_Data_2: case FK_Data_4: case FK_Data_8: @@ -340,7 +352,8 @@ void AVRAsmBackend::adjustFixupValue(const MCFixup &Fixup, } } -MCObjectWriter *AVRAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { +std::unique_ptr<MCObjectWriter> +AVRAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const { return createAVRELFObjectWriter(OS, MCELFObjectTargetWriter::getOSABI(OSType)); } @@ -421,8 +434,9 @@ MCFixupKindInfo const &AVRAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_8_hi8", 0, 8, 0}, {"fixup_8_hlo8", 0, 8, 0}, - {"fixup_sym_diff", 0, 32, 0}, - {"fixup_16_ldst", 0, 16, 0}, + {"fixup_diff8", 0, 8, 0}, + {"fixup_diff16", 0, 16, 0}, + {"fixup_diff32", 0, 32, 0}, {"fixup_lds_sts_16", 0, 16, 0}, diff --git a/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h b/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h index 4a75e3b0d22d..af615df033aa 100644 --- a/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h +++ b/lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h @@ -38,7 +38,7 @@ public: void adjustFixupValue(const MCFixup &Fixup, const MCValue &Target, uint64_t &Value, MCContext *Ctx = nullptr) const; - MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; + std::unique_ptr<MCObjectWriter> createObjectWriter(raw_pwrite_stream &OS) const override; void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target, MutableArrayRef<char> Data, diff --git a/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp b/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp index 161f305fd014..412f66fbcf22 100644 --- a/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp +++ b/lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp @@ -13,6 +13,7 @@ #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" @@ -33,18 +34,49 @@ public: }; AVRELFObjectWriter::AVRELFObjectWriter(uint8_t OSABI) - : MCELFObjectTargetWriter(false, OSABI, ELF::EM_AVR, true, false) {} + : MCELFObjectTargetWriter(false, OSABI, ELF::EM_AVR, true) {} unsigned AVRELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, bool IsPCRel) const { + MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); switch ((unsigned) Fixup.getKind()) { case FK_Data_1: + switch (Modifier) { + default: + llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + return ELF::R_AVR_8; + case MCSymbolRefExpr::VK_AVR_DIFF8: + return ELF::R_AVR_DIFF8; + case MCSymbolRefExpr::VK_AVR_LO8: + return ELF::R_AVR_8_LO8; + case MCSymbolRefExpr::VK_AVR_HI8: + return ELF::R_AVR_8_HI8; + case MCSymbolRefExpr::VK_AVR_HLO8: + return ELF::R_AVR_8_HLO8; + } case FK_Data_4: - llvm_unreachable("unsupported relocation type"); + switch (Modifier) { + default: + llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + return ELF::R_AVR_32; + case MCSymbolRefExpr::VK_AVR_DIFF32: + return ELF::R_AVR_DIFF32; + } case FK_Data_2: - return ELF::R_AVR_16_PM; + switch (Modifier) { + default: + llvm_unreachable("Unsupported Modifier"); + case MCSymbolRefExpr::VK_None: + return ELF::R_AVR_16; + case MCSymbolRefExpr::VK_AVR_NONE: + return ELF::R_AVR_16_PM; + case MCSymbolRefExpr::VK_AVR_DIFF16: + return ELF::R_AVR_DIFF16; + } case AVR::fixup_32: return ELF::R_AVR_32; case AVR::fixup_7_pcrel: @@ -103,10 +135,12 @@ unsigned AVRELFObjectWriter::getRelocType(MCContext &Ctx, return ELF::R_AVR_8_HI8; case AVR::fixup_8_hlo8: return ELF::R_AVR_8_HLO8; - case AVR::fixup_sym_diff: - return ELF::R_AVR_SYM_DIFF; - case AVR::fixup_16_ldst: - return ELF::R_AVR_16_LDST; + case AVR::fixup_diff8: + return ELF::R_AVR_DIFF8; + case AVR::fixup_diff16: + return ELF::R_AVR_DIFF16; + case AVR::fixup_diff32: + return ELF::R_AVR_DIFF32; case AVR::fixup_lds_sts_16: return ELF::R_AVR_LDS_STS_16; case AVR::fixup_port6: @@ -118,9 +152,10 @@ unsigned AVRELFObjectWriter::getRelocType(MCContext &Ctx, } } -MCObjectWriter *createAVRELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI) { - MCELFObjectTargetWriter *MOTW = new AVRELFObjectWriter(OSABI); - return createELFObjectWriter(MOTW, OS, true); +std::unique_ptr<MCObjectWriter> +createAVRELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI) { + std::unique_ptr<MCELFObjectTargetWriter> MOTW(new AVRELFObjectWriter(OSABI)); + return createELFObjectWriter(std::move(MOTW), OS, true); } } // end of namespace llvm diff --git a/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h b/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h index d3bd52d343fc..cdb0b215bc60 100644 --- a/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h +++ b/lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h @@ -115,10 +115,9 @@ enum Fixups { fixup_8_hi8, fixup_8_hlo8, - /// Fixup to calculate the difference between two symbols. - /// Is the only stateful fixup. We do not support it yet. - fixup_sym_diff, - fixup_16_ldst, + fixup_diff8, + fixup_diff16, + fixup_diff32, fixup_lds_sts_16, diff --git a/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp b/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp new file mode 100644 index 000000000000..c60ea7a92e6f --- /dev/null +++ b/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp @@ -0,0 +1,51 @@ +//===--------- AVRMCELFStreamer.cpp - AVR subclass of MCELFStreamer -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a stub that parses a MCInst bundle and passes the +// instructions on to the real streamer. +// +//===----------------------------------------------------------------------===// +#define DEBUG_TYPE "avrmcelfstreamer" + +#include "MCTargetDesc/AVRMCELFStreamer.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCSymbol.h" + +using namespace llvm; + +void AVRMCELFStreamer::EmitValueForModiferKind( + const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc, + AVRMCExpr::VariantKind ModifierKind) { + MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_AVR_NONE; + if (ModifierKind == AVRMCExpr::VK_AVR_None) { + Kind = MCSymbolRefExpr::VK_AVR_DIFF8; + if (SizeInBytes == SIZE_LONG) + Kind = MCSymbolRefExpr::VK_AVR_DIFF32; + else if (SizeInBytes == SIZE_WORD) + Kind = MCSymbolRefExpr::VK_AVR_DIFF16; + } else if (ModifierKind == AVRMCExpr::VK_AVR_LO8) + Kind = MCSymbolRefExpr::VK_AVR_LO8; + else if (ModifierKind == AVRMCExpr::VK_AVR_HI8) + Kind = MCSymbolRefExpr::VK_AVR_HI8; + else if (ModifierKind == AVRMCExpr::VK_AVR_HH8) + Kind = MCSymbolRefExpr::VK_AVR_HLO8; + MCELFStreamer::EmitValue(MCSymbolRefExpr::create(Sym, Kind, getContext()), + SizeInBytes, Loc); +} + +namespace llvm { +MCStreamer *createAVRELFStreamer(Triple const &TT, MCContext &Context, + std::unique_ptr<MCAsmBackend> MAB, + raw_pwrite_stream &OS, + std::unique_ptr<MCCodeEmitter> CE) { + return new AVRMCELFStreamer(Context, std::move(MAB), OS, std::move(CE)); +} + +} // end namespace llvm diff --git a/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h b/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h new file mode 100644 index 000000000000..398b409f4586 --- /dev/null +++ b/lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h @@ -0,0 +1,54 @@ +//===--------- AVRMCELFStreamer.h - AVR subclass of MCELFStreamer ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_AVR_MCTARGETDESC_AVRMCELFSTREAMER_H +#define LLVM_LIB_TARGET_AVR_MCTARGETDESC_AVRMCELFSTREAMER_H + +#include "MCTargetDesc/AVRMCExpr.h" +#include "MCTargetDesc/AVRMCTargetDesc.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCInstrInfo.h" + +namespace llvm { + +const int SIZE_LONG = 4; +const int SIZE_WORD = 2; + +class AVRMCELFStreamer : public MCELFStreamer { + std::unique_ptr<MCInstrInfo> MCII; + +public: + AVRMCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, + raw_pwrite_stream &OS, + std::unique_ptr<MCCodeEmitter> Emitter) + : MCELFStreamer(Context, std::move(TAB), OS, std::move(Emitter)), + MCII(createAVRMCInstrInfo()) {} + + AVRMCELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, + raw_pwrite_stream &OS, + std::unique_ptr<MCCodeEmitter> Emitter, + MCAssembler *Assembler) + : MCELFStreamer(Context, std::move(TAB), OS, std::move(Emitter)), + MCII(createAVRMCInstrInfo()) {} + + void EmitValueForModiferKind( + const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc = SMLoc(), + AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None); +}; + +MCStreamer *createAVRELFStreamer(Triple const &TT, MCContext &Context, + std::unique_ptr<MCAsmBackend> MAB, + raw_pwrite_stream &OS, + std::unique_ptr<MCCodeEmitter> CE); + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_AVR_MCTARGETDESC_AVRMCELFSTREAMER_H diff --git a/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp b/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp index 085afd23a83c..d4a67973af7f 100644 --- a/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp +++ b/lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp @@ -29,6 +29,9 @@ const struct ModifierEntry { {"pm_lo8", AVRMCExpr::VK_AVR_PM_LO8}, {"pm_hi8", AVRMCExpr::VK_AVR_PM_HI8}, {"pm_hh8", AVRMCExpr::VK_AVR_PM_HH8}, + + {"lo8_gs", AVRMCExpr::VK_AVR_LO8_GS}, {"hi8_gs", AVRMCExpr::VK_AVR_HI8_GS}, + {"gs", AVRMCExpr::VK_AVR_GS}, }; } // end of anonymous namespace @@ -99,24 +102,38 @@ int64_t AVRMCExpr::evaluateAsInt64(int64_t Value) const { switch (Kind) { case AVRMCExpr::VK_AVR_LO8: + Value &= 0xff; break; case AVRMCExpr::VK_AVR_HI8: + Value &= 0xff00; Value >>= 8; break; case AVRMCExpr::VK_AVR_HH8: + Value &= 0xff0000; Value >>= 16; break; case AVRMCExpr::VK_AVR_HHI8: + Value &= 0xff000000; Value >>= 24; break; case AVRMCExpr::VK_AVR_PM_LO8: - Value >>= 1; + case AVRMCExpr::VK_AVR_LO8_GS: + Value >>= 1; // Program memory addresses must always be shifted by one. + Value &= 0xff; break; case AVRMCExpr::VK_AVR_PM_HI8: - Value >>= 9; + case AVRMCExpr::VK_AVR_HI8_GS: + Value >>= 1; // Program memory addresses must always be shifted by one. + Value &= 0xff00; + Value >>= 8; break; case AVRMCExpr::VK_AVR_PM_HH8: - Value >>= 17; + Value >>= 1; // Program memory addresses must always be shifted by one. + Value &= 0xff0000; + Value >>= 16; + break; + case AVRMCExpr::VK_AVR_GS: + Value >>= 1; // Program memory addresses must always be shifted by one. break; case AVRMCExpr::VK_AVR_None: @@ -151,6 +168,15 @@ AVR::Fixups AVRMCExpr::getFixupKind() const { case VK_AVR_PM_HH8: Kind = isNegated() ? AVR::fixup_hh8_ldi_pm_neg : AVR::fixup_hh8_ldi_pm; break; + case VK_AVR_GS: + Kind = AVR::fixup_16_pm; + break; + case VK_AVR_LO8_GS: + Kind = AVR::fixup_lo8_ldi_gs; + break; + case VK_AVR_HI8_GS: + Kind = AVR::fixup_hi8_ldi_gs; + break; case VK_AVR_None: llvm_unreachable("Uninitialized expression"); diff --git a/lib/Target/AVR/MCTargetDesc/AVRMCExpr.h b/lib/Target/AVR/MCTargetDesc/AVRMCExpr.h index be565a8be340..a166b0946749 100644 --- a/lib/Target/AVR/MCTargetDesc/AVRMCExpr.h +++ b/lib/Target/AVR/MCTargetDesc/AVRMCExpr.h @@ -30,7 +30,11 @@ public: VK_AVR_PM_LO8, ///< Corresponds to `pm_lo8()`. VK_AVR_PM_HI8, ///< Corresponds to `pm_hi8()`. - VK_AVR_PM_HH8 ///< Corresponds to `pm_hh8()`. + VK_AVR_PM_HH8, ///< Corresponds to `pm_hh8()`. + + VK_AVR_LO8_GS, ///< Corresponds to `lo8(gs())`. + VK_AVR_HI8_GS, ///< Corresponds to `hi8(gs())`. + VK_AVR_GS, ///< Corresponds to `gs()`. }; public: diff --git a/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp b/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp index 826430e94b9c..dd65a4312077 100644 --- a/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp +++ b/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp @@ -11,13 +11,16 @@ // //===----------------------------------------------------------------------===// -#include "AVRMCTargetDesc.h" #include "AVRELFStreamer.h" #include "AVRMCAsmInfo.h" +#include "AVRMCELFStreamer.h" +#include "AVRMCTargetDesc.h" #include "AVRTargetStreamer.h" #include "InstPrinter/AVRInstPrinter.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -34,7 +37,7 @@ using namespace llvm; -static MCInstrInfo *createAVRMCInstrInfo() { +MCInstrInfo *llvm::createAVRMCInstrInfo() { MCInstrInfo *X = new MCInstrInfo(); InitAVRMCInstrInfo(X); @@ -66,9 +69,12 @@ static MCInstPrinter *createAVRMCInstPrinter(const Triple &T, } static MCStreamer *createMCStreamer(const Triple &T, MCContext &Context, - MCAsmBackend &MAB, raw_pwrite_stream &OS, - MCCodeEmitter *Emitter, bool RelaxAll) { - return createELFStreamer(Context, MAB, OS, Emitter, RelaxAll); + std::unique_ptr<MCAsmBackend> &&MAB, + raw_pwrite_stream &OS, + std::unique_ptr<MCCodeEmitter> &&Emitter, + bool RelaxAll) { + return createELFStreamer(Context, std::move(MAB), OS, + std::move(Emitter), RelaxAll); } static MCTargetStreamer * @@ -104,7 +110,7 @@ extern "C" void LLVMInitializeAVRTargetMC() { // Register the MC Code Emitter TargetRegistry::RegisterMCCodeEmitter(getTheAVRTarget(), createAVRMCCodeEmitter); - // Register the ELF streamer + // Register the obj streamer TargetRegistry::RegisterELFStreamer(getTheAVRTarget(), createMCStreamer); // Register the obj target streamer. diff --git a/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h b/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h index 41a574767910..5615fd72e456 100644 --- a/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h +++ b/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h @@ -16,6 +16,8 @@ #include "llvm/Support/DataTypes.h" +#include <memory> + namespace llvm { class MCAsmBackend; @@ -32,6 +34,8 @@ class raw_pwrite_stream; Target &getTheAVRTarget(); +MCInstrInfo *createAVRMCInstrInfo(); + /// Creates a machine code emitter for AVR. MCCodeEmitter *createAVRMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, @@ -43,7 +47,8 @@ MCAsmBackend *createAVRAsmBackend(const Target &T, const MCRegisterInfo &MRI, const llvm::MCTargetOptions &TO); /// Creates an ELF object writer for AVR. -MCObjectWriter *createAVRELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI); +std::unique_ptr<MCObjectWriter> +createAVRELFObjectWriter(raw_pwrite_stream &OS, uint8_t OSABI); } // end namespace llvm diff --git a/lib/Target/AVR/MCTargetDesc/CMakeLists.txt b/lib/Target/AVR/MCTargetDesc/CMakeLists.txt index 5bad6494c8a9..eb7fe956cf34 100644 --- a/lib/Target/AVR/MCTargetDesc/CMakeLists.txt +++ b/lib/Target/AVR/MCTargetDesc/CMakeLists.txt @@ -4,6 +4,7 @@ add_llvm_library(LLVMAVRDesc AVRELFStreamer.cpp AVRMCAsmInfo.cpp AVRMCCodeEmitter.cpp + AVRMCELFStreamer.cpp AVRMCExpr.cpp AVRMCTargetDesc.cpp AVRTargetStreamer.cpp diff --git a/lib/Target/AVR/TargetInfo/AVRTargetInfo.cpp b/lib/Target/AVR/TargetInfo/AVRTargetInfo.cpp index 36cecaa7ac7a..abe9cf45fcb3 100644 --- a/lib/Target/AVR/TargetInfo/AVRTargetInfo.cpp +++ b/lib/Target/AVR/TargetInfo/AVRTargetInfo.cpp @@ -18,6 +18,6 @@ Target &getTheAVRTarget() { extern "C" void LLVMInitializeAVRTargetInfo() { llvm::RegisterTarget<llvm::Triple::avr> X(llvm::getTheAVRTarget(), "avr", - "Atmel AVR Microcontroller"); + "Atmel AVR Microcontroller", "AVR"); } |
