summaryrefslogtreecommitdiff
path: root/lib/Target/AVR
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:10:56 +0000
commit044eb2f6afba375a914ac9d8024f8f5142bb912e (patch)
tree1475247dc9f9fe5be155ebd4c9069c75aadf8c20 /lib/Target/AVR
parenteb70dddbd77e120e5d490bd8fbe7ff3f8fa81c6b (diff)
Notes
Diffstat (limited to 'lib/Target/AVR')
-rw-r--r--lib/Target/AVR/AVR.h2
-rw-r--r--lib/Target/AVR/AVRAsmPrinter.cpp4
-rw-r--r--lib/Target/AVR/AVRExpandPseudoInsts.cpp2
-rw-r--r--lib/Target/AVR/AVRFrameLowering.cpp6
-rw-r--r--lib/Target/AVR/AVRFrameLowering.h4
-rw-r--r--lib/Target/AVR/AVRISelLowering.cpp9
-rw-r--r--lib/Target/AVR/AVRISelLowering.h5
-rw-r--r--lib/Target/AVR/AVRInstrInfo.h2
-rw-r--r--lib/Target/AVR/AVRInstrumentFunctions.cpp222
-rw-r--r--lib/Target/AVR/AVRRegisterInfo.cpp4
-rw-r--r--lib/Target/AVR/AVRRegisterInfo.h2
-rw-r--r--lib/Target/AVR/AVRRelaxMemOperations.cpp2
-rw-r--r--lib/Target/AVR/AVRSubtarget.h2
-rw-r--r--lib/Target/AVR/AVRTargetMachine.cpp18
-rw-r--r--lib/Target/AVR/AVRTargetMachine.h6
-rw-r--r--lib/Target/AVR/AsmParser/AVRAsmParser.cpp94
-rw-r--r--lib/Target/AVR/CMakeLists.txt1
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp28
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRAsmBackend.h2
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRELFObjectWriter.cpp55
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRFixupKinds.h7
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.cpp51
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRMCELFStreamer.h54
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRMCExpr.cpp32
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRMCExpr.h6
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.cpp18
-rw-r--r--lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h7
-rw-r--r--lib/Target/AVR/MCTargetDesc/CMakeLists.txt1
-rw-r--r--lib/Target/AVR/TargetInfo/AVRTargetInfo.cpp2
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");
}