[llvm] r268722 - [AVR] Add a majority of the backend code

Dylan McKay via llvm-commits llvm-commits at lists.llvm.org
Wed May 11 04:43:23 PDT 2016


The code is in a half-migrated state, where it should mostly compile but
there are a few problems. With regards to the eliminateCallFramePseudoInstr
problem, a fix was made to the offline repo but hasn't been upstreamed yet.

There are also a few functions which don't have definitions (mostly the
global createSomething() functions). I have left the definitions out so it
compiles, but it doesn't link yet.

I will remove the unused variable AFI.

Will also change the signature of getTargetCPU, nice catch. I will be doing
work on getting the backend to compile and link properly.



On Wed, May 11, 2016 at 11:03 AM, Justin Bogner <mail at justinbogner.com>
wrote:

> Dylan McKay via llvm-commits <llvm-commits at lists.llvm.org> writes:
> > Author: dylanmckay
> > Date: Fri May  6 05:12:31 2016
> > New Revision: 268722
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=268722&view=rev
> > Log:
> > [AVR] Add a majority of the backend code
> >
> > Summary: This adds the majority of the AVR backend.
>
> Um, this doesn't seem to even compile. Am I missing something here? I
> tried to work around the compiler errors that popped up, but then there
> were a slew of linker errors I didn't have time to dig into.
>
> > Reviewers: hfinkel, dsanders, vkalintiris, arsenm
> >
> > Subscribers: dylanmckay
> >
> > Differential Revision: http://reviews.llvm.org/D17906
> >
> > Added:
> >     llvm/trunk/lib/Target/AVR/AVRFrameLowering.h
> >     llvm/trunk/lib/Target/AVR/AVRISelLowering.h
> >     llvm/trunk/lib/Target/AVR/AVRInstrInfo.cpp
> >     llvm/trunk/lib/Target/AVR/AVRInstrInfo.h
> >     llvm/trunk/lib/Target/AVR/AVRRegisterInfo.cpp
> >     llvm/trunk/lib/Target/AVR/AVRRegisterInfo.h
> >     llvm/trunk/lib/Target/AVR/AVRSubtarget.cpp
> >     llvm/trunk/lib/Target/AVR/AVRSubtarget.h
> >     llvm/trunk/lib/Target/AVR/AVRTargetMachine.h
> >     llvm/trunk/lib/Target/AVR/MCTargetDesc/
> >     llvm/trunk/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h
> > Modified:
> >     llvm/trunk/lib/Target/AVR/AVRInstrInfo.td
> >     llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp
> >     llvm/trunk/lib/Target/AVR/CMakeLists.txt
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRFrameLowering.h
> > URL:
> >
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRFrameLowering.h?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRFrameLowering.h (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRFrameLowering.h Fri May  6 05:12:31 2016
> > @@ -0,0 +1,48 @@
> > +//===-- 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 "AVRConfig.h"
> > +
> > +#include "llvm/Target/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,
> > +                              const 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;
> > +  void
> > +  eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock
> &MBB,
> > +                                MachineBasicBlock::iterator MI) const
> override;
>
> This isn't the correct signature for eliminateCallFramePseudoInstr. It
> was changed to return a MachineBasicBlock::iterator a couple of months
> ago.
>
> Also as far as I can tell none of these have definitions. They're
> declared and never defined.
>
> > +};
> > +
> > +} // end namespace llvm
> > +
> > +#endif // LLVM_AVR_FRAME_LOWERING_H
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRISelLowering.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRISelLowering.h?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRISelLowering.h (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRISelLowering.h Fri May  6 05:12:31 2016
> > @@ -0,0 +1,154 @@
> > +//===-- 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 "AVRConfig.h"
> > +
> > +#include "llvm/Target/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.
> > +  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;
> > +  }
> > +  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) 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;
> > +
> > +  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;
> > +
> > +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;
> > +
> > +  SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool
> isVarArg,
> > +                      const SmallVectorImpl<ISD::OutputArg> &Outs,
> > +                      const SmallVectorImpl<SDValue> &OutVals, SDLoc dl,
> > +                      SelectionDAG &DAG) const override;
> > +  SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
> > +                               bool isVarArg,
> > +                               const SmallVectorImpl<ISD::InputArg>
> &Ins,
> > +                               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,
> 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
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRInstrInfo.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRInstrInfo.cpp?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRInstrInfo.cpp (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRInstrInfo.cpp Fri May  6 05:12:31 2016
> > @@ -0,0 +1,467 @@
> > +//===-- AVRInstrInfo.cpp - AVR Instruction 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 TargetInstrInfo
> class.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#include "AVRInstrInfo.h"
> > +
> > +#include "llvm/ADT/STLExtras.h"
> > +#include "llvm/CodeGen/MachineConstantPool.h"
> > +#include "llvm/CodeGen/MachineFrameInfo.h"
> > +#include "llvm/CodeGen/MachineInstrBuilder.h"
> > +#include "llvm/CodeGen/MachineMemOperand.h"
> > +#include "llvm/IR/Constants.h"
> > +#include "llvm/IR/Function.h"
> > +#include "llvm/MC/MCContext.h"
> > +#include "llvm/Support/Debug.h"
> > +#include "llvm/Support/ErrorHandling.h"
> > +#include "llvm/Support/TargetRegistry.h"
> > +
> > +#include "AVR.h"
> > +#include "AVRMachineFunctionInfo.h"
> > +#include "AVRTargetMachine.h"
> > +#include "MCTargetDesc/AVRMCTargetDesc.h"
> > +
> > +#define GET_INSTRINFO_CTOR_DTOR
> > +#include "AVRGenInstrInfo.inc"
> > +
> > +namespace llvm {
> > +
> > +AVRInstrInfo::AVRInstrInfo()
> > +    : AVRGenInstrInfo(AVR::ADJCALLSTACKDOWN, AVR::ADJCALLSTACKUP), RI()
> {}
> > +
> > +void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
> > +                               MachineBasicBlock::iterator MI, DebugLoc
> DL,
> > +                               unsigned DestReg, unsigned SrcReg,
> > +                               bool KillSrc) const {
> > +  unsigned Opc;
> > +
> > +  if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) {
> > +    Opc = AVR::MOVRdRr;
> > +  } else if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) {
> > +    Opc = AVR::MOVWRdRr;
> > +  } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg))
> {
> > +    Opc = AVR::SPREAD;
> > +  } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg))
> {
> > +    Opc = AVR::SPWRITE;
> > +  } else {
> > +    llvm_unreachable("Impossible reg-to-reg copy");
> > +  }
> > +
> > +  BuildMI(MBB, MI, DL, get(Opc), DestReg)
> > +      .addReg(SrcReg, getKillRegState(KillSrc));
> > +}
> > +
> > +unsigned AVRInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
> > +                                           int &FrameIndex) const {
> > +  switch (MI->getOpcode()) {
> > +  case AVR::LDDRdPtrQ:
> > +  case AVR::LDDWRdYQ: { //:FIXME: remove this once PR13375 gets fixed
> > +    if ((MI->getOperand(1).isFI()) && (MI->getOperand(2).isImm()) &&
> > +        (MI->getOperand(2).getImm() == 0)) {
> > +      FrameIndex = MI->getOperand(1).getIndex();
> > +      return MI->getOperand(0).getReg();
> > +    }
> > +    break;
> > +  }
> > +  default:
> > +    break;
> > +  }
> > +
> > +  return 0;
> > +}
> > +
> > +unsigned AVRInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
> > +                                          int &FrameIndex) const {
> > +  switch (MI->getOpcode()) {
> > +  case AVR::STDPtrQRr:
> > +  case AVR::STDWPtrQRr: {
> > +    if ((MI->getOperand(0).isFI()) && (MI->getOperand(1).isImm()) &&
> > +        (MI->getOperand(1).getImm() == 0)) {
> > +      FrameIndex = MI->getOperand(0).getIndex();
> > +      return MI->getOperand(2).getReg();
> > +    }
> > +    break;
> > +  }
> > +  default:
> > +    break;
> > +  }
> > +
> > +  return 0;
> > +}
> > +
> > +void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
> > +                                       MachineBasicBlock::iterator MI,
> > +                                       unsigned SrcReg, bool isKill,
> > +                                       int FrameIndex,
> > +                                       const TargetRegisterClass *RC,
> > +                                       const TargetRegisterInfo *TRI)
> const {
> > +  MachineFunction &MF = *MBB.getParent();
> > +  AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
>
> AFI isn't used.
>
> > +
> > +  DebugLoc DL;
> > +  if (MI != MBB.end()) {
> > +    DL = MI->getDebugLoc();
> > +  }
> > +
> > +  const MachineFrameInfo &MFI = *MF.getFrameInfo();
> > +
> > +  MachineMemOperand *MMO = MF.getMachineMemOperand(
> > +      MachinePointerInfo::getFixedStack(MF, FrameIndex),
> > +      MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex),
> > +      MFI.getObjectAlignment(FrameIndex));
> > +
> > +  unsigned Opcode = 0;
> > +  if (RC->hasType(MVT::i8)) {
> > +    Opcode = AVR::STDPtrQRr;
> > +  } else if (RC->hasType(MVT::i16)) {
> > +    Opcode = AVR::STDWPtrQRr;
> > +  } else {
> > +    llvm_unreachable("Cannot store this register into a stack slot!");
> > +  }
> > +
> > +  BuildMI(MBB, MI, DL, get(Opcode))
> > +      .addFrameIndex(FrameIndex)
> > +      .addImm(0)
> > +      .addReg(SrcReg, getKillRegState(isKill))
> > +      .addMemOperand(MMO);
> > +}
> > +
> > +void AVRInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
> > +                                        MachineBasicBlock::iterator MI,
> > +                                        unsigned DestReg, int
> FrameIndex,
> > +                                        const TargetRegisterClass *RC,
> > +                                        const TargetRegisterInfo *TRI)
> const {
> > +  DebugLoc DL;
> > +  if (MI != MBB.end()) {
> > +    DL = MI->getDebugLoc();
> > +  }
> > +
> > +  MachineFunction &MF = *MBB.getParent();
> > +  const MachineFrameInfo &MFI = *MF.getFrameInfo();
> > +
> > +  MachineMemOperand *MMO = MF.getMachineMemOperand(
> > +      MachinePointerInfo::getFixedStack(MF, FrameIndex),
> > +      MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex),
> > +      MFI.getObjectAlignment(FrameIndex));
> > +
> > +  unsigned Opcode = 0;
> > +  if (RC->hasType(MVT::i8)) {
> > +    Opcode = AVR::LDDRdPtrQ;
> > +  } else if (RC->hasType(MVT::i16)) {
> > +    // Opcode = AVR::LDDWRdPtrQ;
> > +    //:FIXME: remove this once PR13375 gets fixed
> > +    Opcode = AVR::LDDWRdYQ;
> > +  } else {
> > +    llvm_unreachable("Cannot load this register from a stack slot!");
> > +  }
> > +
> > +  BuildMI(MBB, MI, DL, get(Opcode), DestReg)
> > +      .addFrameIndex(FrameIndex)
> > +      .addImm(0)
> > +      .addMemOperand(MMO);
> > +}
> > +
> > +const MCInstrDesc &AVRInstrInfo::getBrCond(AVRCC::CondCodes CC) const {
> > +  switch (CC) {
> > +  default:
> > +    llvm_unreachable("Unknown condition code!");
> > +  case AVRCC::COND_EQ:
> > +    return get(AVR::BREQk);
> > +  case AVRCC::COND_NE:
> > +    return get(AVR::BRNEk);
> > +  case AVRCC::COND_GE:
> > +    return get(AVR::BRGEk);
> > +  case AVRCC::COND_LT:
> > +    return get(AVR::BRLTk);
> > +  case AVRCC::COND_SH:
> > +    return get(AVR::BRSHk);
> > +  case AVRCC::COND_LO:
> > +    return get(AVR::BRLOk);
> > +  case AVRCC::COND_MI:
> > +    return get(AVR::BRMIk);
> > +  case AVRCC::COND_PL:
> > +    return get(AVR::BRPLk);
> > +  }
> > +}
> > +
> > +AVRCC::CondCodes AVRInstrInfo::getCondFromBranchOpc(unsigned Opc) const
> {
> > +  switch (Opc) {
> > +  default:
> > +    return AVRCC::COND_INVALID;
> > +  case AVR::BREQk:
> > +    return AVRCC::COND_EQ;
> > +  case AVR::BRNEk:
> > +    return AVRCC::COND_NE;
> > +  case AVR::BRSHk:
> > +    return AVRCC::COND_SH;
> > +  case AVR::BRLOk:
> > +    return AVRCC::COND_LO;
> > +  case AVR::BRMIk:
> > +    return AVRCC::COND_MI;
> > +  case AVR::BRPLk:
> > +    return AVRCC::COND_PL;
> > +  case AVR::BRGEk:
> > +    return AVRCC::COND_GE;
> > +  case AVR::BRLTk:
> > +    return AVRCC::COND_LT;
> > +  }
> > +}
> > +
> > +AVRCC::CondCodes AVRInstrInfo::getOppositeCondition(AVRCC::CondCodes
> CC) const {
> > +  switch (CC) {
> > +  default:
> > +    llvm_unreachable("Invalid condition!");
> > +  case AVRCC::COND_EQ:
> > +    return AVRCC::COND_NE;
> > +  case AVRCC::COND_NE:
> > +    return AVRCC::COND_EQ;
> > +  case AVRCC::COND_SH:
> > +    return AVRCC::COND_LO;
> > +  case AVRCC::COND_LO:
> > +    return AVRCC::COND_SH;
> > +  case AVRCC::COND_GE:
> > +    return AVRCC::COND_LT;
> > +  case AVRCC::COND_LT:
> > +    return AVRCC::COND_GE;
> > +  case AVRCC::COND_MI:
> > +    return AVRCC::COND_PL;
> > +  case AVRCC::COND_PL:
> > +    return AVRCC::COND_MI;
> > +  }
> > +}
> > +
> > +bool AVRInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
> > +                                 MachineBasicBlock *&TBB,
> > +                                 MachineBasicBlock *&FBB,
> > +                                 SmallVectorImpl<MachineOperand> &Cond,
> > +                                 bool AllowModify) const {
> > +  // Start from the bottom of the block and work up, examining the
> > +  // terminator instructions.
> > +  MachineBasicBlock::iterator I = MBB.end();
> > +  MachineBasicBlock::iterator UnCondBrIter = MBB.end();
> > +
> > +  while (I != MBB.begin()) {
> > +    --I;
> > +    if (I->isDebugValue()) {
> > +      continue;
> > +    }
> > +
> > +    // Working from the bottom, when we see a non-terminator
> > +    // instruction, we're done.
> > +    if (!isUnpredicatedTerminator(*I)) {
> > +      break;
> > +    }
> > +
> > +    // A terminator that isn't a branch can't easily be handled
> > +    // by this analysis.
> > +    if (!I->getDesc().isBranch()) {
> > +      return true;
> > +    }
> > +
> > +    // Handle unconditional branches.
> > +    //:TODO: add here jmp
> > +    if (I->getOpcode() == AVR::RJMPk) {
> > +      UnCondBrIter = I;
> > +
> > +      if (!AllowModify) {
> > +        TBB = I->getOperand(0).getMBB();
> > +        continue;
> > +      }
> > +
> > +      // If the block has any instructions after a JMP, delete them.
> > +      while (std::next(I) != MBB.end()) {
> > +        std::next(I)->eraseFromParent();
> > +      }
> > +
> > +      Cond.clear();
> > +      FBB = 0;
> > +
> > +      // Delete the JMP if it's equivalent to a fall-through.
> > +      if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
> > +        TBB = 0;
> > +        I->eraseFromParent();
> > +        I = MBB.end();
> > +        UnCondBrIter = MBB.end();
> > +        continue;
> > +      }
> > +
> > +      // TBB is used to indicate the unconditinal destination.
> > +      TBB = I->getOperand(0).getMBB();
> > +      continue;
> > +    }
> > +
> > +    // Handle conditional branches.
> > +    AVRCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode());
> > +    if (BranchCode == AVRCC::COND_INVALID) {
> > +      return true; // Can't handle indirect branch.
> > +    }
> > +
> > +    // Working from the bottom, handle the first conditional branch.
> > +    if (Cond.empty()) {
> > +      MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
> > +      if (AllowModify && UnCondBrIter != MBB.end() &&
> > +          MBB.isLayoutSuccessor(TargetBB)) {
> > +        // If we can modify the code and it ends in something like:
> > +        //
> > +        //     jCC L1
> > +        //     jmp L2
> > +        //   L1:
> > +        //     ...
> > +        //   L2:
> > +        //
> > +        // Then we can change this to:
> > +        //
> > +        //     jnCC L2
> > +        //   L1:
> > +        //     ...
> > +        //   L2:
> > +        //
> > +        // Which is a bit more efficient.
> > +        // We conditionally jump to the fall-through block.
> > +        BranchCode = getOppositeCondition(BranchCode);
> > +        unsigned JNCC = getBrCond(BranchCode).getOpcode();
> > +        MachineBasicBlock::iterator OldInst = I;
> > +
> > +        BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(JNCC))
> > +            .addMBB(UnCondBrIter->getOperand(0).getMBB());
> > +        BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(AVR::RJMPk))
> > +            .addMBB(TargetBB);
> > +
> > +        OldInst->eraseFromParent();
> > +        UnCondBrIter->eraseFromParent();
> > +
> > +        // Restart the analysis.
> > +        UnCondBrIter = MBB.end();
> > +        I = MBB.end();
> > +        continue;
> > +      }
> > +
> > +      FBB = TBB;
> > +      TBB = I->getOperand(0).getMBB();
> > +      Cond.push_back(MachineOperand::CreateImm(BranchCode));
> > +      continue;
> > +    }
> > +
> > +    // Handle subsequent conditional branches. Only handle the case
> where all
> > +    // conditional branches branch to the same destination.
> > +    assert(Cond.size() == 1);
> > +    assert(TBB);
> > +
> > +    // Only handle the case where all conditional branches branch to
> > +    // the same destination.
> > +    if (TBB != I->getOperand(0).getMBB()) {
> > +      return true;
> > +    }
> > +
> > +    AVRCC::CondCodes OldBranchCode = (AVRCC::CondCodes)Cond[0].getImm();
> > +    // If the conditions are the same, we can leave them alone.
> > +    if (OldBranchCode == BranchCode) {
> > +      continue;
> > +    }
> > +
> > +    return true;
> > +  }
> > +
> > +  return false;
> > +}
> > +
> > +unsigned AVRInstrInfo::InsertBranch(MachineBasicBlock &MBB,
> > +                                    MachineBasicBlock *TBB,
> > +                                    MachineBasicBlock *FBB,
> > +                                    ArrayRef<MachineOperand> Cond,
> > +                                    DebugLoc DL) const {
> > +  // Shouldn't be a fall through.
> > +  assert(TBB && "InsertBranch must not be told to insert a
> fallthrough");
> > +  assert((Cond.size() == 1 || Cond.size() == 0) &&
> > +         "AVR branch conditions have one component!");
> > +
> > +  if (Cond.empty()) {
> > +    assert(!FBB && "Unconditional branch with multiple successors!");
> > +    BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
> > +    return 1;
> > +  }
> > +
> > +  // Conditional branch.
> > +  unsigned Count = 0;
> > +  AVRCC::CondCodes CC = (AVRCC::CondCodes)Cond[0].getImm();
> > +  BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
> > +  ++Count;
> > +
> > +  if (FBB) {
> > +    // Two-way Conditional branch. Insert the second branch.
> > +    BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
> > +    ++Count;
> > +  }
> > +
> > +  return Count;
> > +}
> > +
> > +unsigned AVRInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
> > +  MachineBasicBlock::iterator I = MBB.end();
> > +  unsigned Count = 0;
> > +
> > +  while (I != MBB.begin()) {
> > +    --I;
> > +    if (I->isDebugValue()) {
> > +      continue;
> > +    }
> > +    //:TODO: add here the missing jmp instructions once they are
> implemented
> > +    // like jmp, {e}ijmp, and other cond branches, ...
> > +    if (I->getOpcode() != AVR::RJMPk &&
> > +        getCondFromBranchOpc(I->getOpcode()) == AVRCC::COND_INVALID) {
> > +      break;
> > +    }
> > +
> > +    // Remove the branch.
> > +    I->eraseFromParent();
> > +    I = MBB.end();
> > +    ++Count;
> > +  }
> > +
> > +  return Count;
> > +}
> > +
> > +bool AVRInstrInfo::ReverseBranchCondition(
> > +    SmallVectorImpl<MachineOperand> &Cond) const {
> > +  assert(Cond.size() == 1 && "Invalid AVR branch condition!");
> > +
> > +  AVRCC::CondCodes CC = static_cast<AVRCC::CondCodes>(Cond[0].getImm());
> > +  Cond[0].setImm(getOppositeCondition(CC));
> > +
> > +  return false;
> > +}
> > +
> > +unsigned AVRInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const
> {
> > +  unsigned Opcode = MI->getOpcode();
> > +
> > +  switch (Opcode) {
> > +  // A regular instruction
> > +  default: {
> > +    const MCInstrDesc &Desc = get(Opcode);
> > +    return Desc.getSize();
> > +  }
> > +  case TargetOpcode::EH_LABEL:
> > +  case TargetOpcode::IMPLICIT_DEF:
> > +  case TargetOpcode::KILL:
> > +  case TargetOpcode::DBG_VALUE:
> > +    return 0;
> > +  case TargetOpcode::INLINEASM: {
> > +    const MachineFunction *MF = MI->getParent()->getParent();
> > +    const AVRTargetMachine &TM = static_cast<const
> AVRTargetMachine&>(MF->getTarget());
> > +    const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
> > +    return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(),
> > +                                  *TM.getMCAsmInfo());
> > +  }
> > +  }
> > +}
> > +
> > +} // end of namespace llvm
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRInstrInfo.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRInstrInfo.h?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRInstrInfo.h (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRInstrInfo.h Fri May  6 05:12:31 2016
> > @@ -0,0 +1,112 @@
> > +//===-- 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/Target/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;
> > +
> > +  void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator
> MI,
> > +                   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,
> > +                        DebugLoc DL) const override;
> > +  unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
> > +  bool
> > +  ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const
> override;
> > +
> > +private:
> > +  const AVRRegisterInfo RI;
> > +};
> > +
> > +} // end namespace llvm
> > +
> > +#endif // LLVM_AVR_INSTR_INFO_H
> >
> > Modified: llvm/trunk/lib/Target/AVR/AVRInstrInfo.td
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRInstrInfo.td?rev=268722&r1=268721&r2=268722&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRInstrInfo.td (original)
> > +++ llvm/trunk/lib/Target/AVR/AVRInstrInfo.td Fri May  6 05:12:31 2016
> > @@ -45,7 +45,7 @@ def AVRcallseq_end : SDNode<"ISD::CALLSE
> >  def AVRcall : SDNode<"AVRISD::CALL", SDT_AVRCall,
> >                       [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue,
> SDNPVariadic]>;
> >
> > -def AVRWrapper : SDNode<"AVRISD::Wrapper", SDT_AVRWrapper>;
> > +def AVRWrapper : SDNode<"AVRISD::WRAPPER", SDT_AVRWrapper>;
> >
> >  def AVRbrcond : SDNode<"AVRISD::BRCOND", SDT_AVRBrcond,
> >                         [SDNPHasChain, SDNPInGlue]>;
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRRegisterInfo.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRRegisterInfo.cpp?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRRegisterInfo.cpp (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRRegisterInfo.cpp Fri May  6 05:12:31
> 2016
> > @@ -0,0 +1,256 @@
> > +//===-- 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/Target/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());
> > +  const AVRTargetMachine &TM = static_cast<const
> AVRTargetMachine&>(MF.getTarget());
> > +  const TargetFrameLowering *TFI =
> TM.getSubtargetImpl()->getFrameLowering();
> > +
> > +  // 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);
> > +
> > +  // Reserve the frame pointer registers r28 and r29 if the function
> requires one.
> > +  if (TFI->hasFP(MF)) {
> > +    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 {
> > +  if (RC->hasType(MVT::i16)) {
> > +    return &AVR::DREGSRegClass;
> > +  }
> > +
> > +  if (RC->hasType(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(MachineInstr &MI, int &Offset, unsigned
> DstReg) {
> > +  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.
> > +  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");
> > +
> > +    // 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
> > +    foldFrameOffset(*std::next(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;
> > +      }
> > +      // Fallthrough
> > +    }
> > +    default: {
> > +      // This opcode will get expanded into a pair of subi/sbci.
> > +      Opcode = AVR::SUBIWRdK;
> > +      Offset = -Offset;
> > +      break;
> > +    }
> > +    }
> > +
> > +    MachineInstr *New = BuildMI(MBB, std::next(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 >= 63) {
> > +    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;
> > +}
> > +
> > +} // end of namespace llvm
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRRegisterInfo.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRRegisterInfo.h?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRRegisterInfo.h (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRRegisterInfo.h Fri May  6 05:12:31 2016
> > @@ -0,0 +1,56 @@
> > +//===-- 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/Target/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;
> > +
> > +  /// Debug information queries.
> > +  unsigned getFrameRegister(const MachineFunction &MF) const override;
> > +
> > +  /// Returns a TargetRegisterClass used for pointer values.
> > +  const TargetRegisterClass *
> > +  getPointerRegClass(const MachineFunction &MF,
> > +                     unsigned Kind = 0) const override;
> > +};
> > +
> > +} // end namespace llvm
> > +
> > +#endif // LLVM_AVR_REGISTER_INFO_H
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRSubtarget.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRSubtarget.cpp?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRSubtarget.cpp (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRSubtarget.cpp Fri May  6 05:12:31 2016
> > @@ -0,0 +1,47 @@
> > +//===-- AVRSubtarget.cpp - AVR Subtarget Information
> ----------------------===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +//
> > +// This file implements the AVR specific subclass of
> TargetSubtargetInfo.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#include "AVRSubtarget.h"
> > +
> > +#include "llvm/Support/ELF.h"
> > +#include "llvm/Support/TargetRegistry.h"
> > +
> > +#include "AVR.h"
> > +#include "AVRTargetMachine.h"
> > +#include "MCTargetDesc/AVRMCTargetDesc.h"
> > +
> > +#define DEBUG_TYPE "avr-subtarget"
> > +
> > +#define GET_SUBTARGETINFO_TARGET_DESC
> > +#define GET_SUBTARGETINFO_CTOR
> > +#include "AVRGenSubtargetInfo.inc"
> > +
> > +namespace llvm {
> > +
> > +AVRSubtarget::AVRSubtarget(const Triple &TT, const std::string &CPU,
> > +                           const std::string &FS, AVRTargetMachine &TM)
> > +    : AVRGenSubtargetInfo(TT, CPU, FS), InstrInfo(), FrameLowering(),
> > +      TLInfo(TM), TSInfo(),
> > +
> > +      // Subtarget features
> > +      m_hasSRAM(false), m_hasJMPCALL(false), m_hasIJMPCALL(false),
> > +      m_hasEIJMPCALL(false), m_hasADDSUBIW(false),
> m_hasSmallStack(false),
> > +      m_hasMOVW(false), m_hasLPM(false), m_hasLPMX(false),
> m_hasELPM(false),
> > +      m_hasELPMX(false), m_hasSPM(false), m_hasSPMX(false),
> m_hasDES(false),
> > +      m_supportsRMW(false), m_supportsMultiplication(false),
> m_hasBREAK(false),
> > +      m_hasTinyEncoding(false), ELFArch(false),
> m_FeatureSetDummy(false) {
> > +  // Parse features string.
> > +  ParseSubtargetFeatures(CPU, FS);
> > +}
> > +
> > +} // end of namespace llvm
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRSubtarget.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRSubtarget.h?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRSubtarget.h (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRSubtarget.h Fri May  6 05:12:31 2016
> > @@ -0,0 +1,121 @@
> > +//===-- AVRSubtarget.h - Define Subtarget for the AVR -----------*- 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 the AVR specific subclass of TargetSubtargetInfo.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef LLVM_AVR_SUBTARGET_H
> > +#define LLVM_AVR_SUBTARGET_H
> > +
> > +#include "AVRConfig.h"
> > +
> > +#include "llvm/Target/TargetSubtargetInfo.h"
> > +#include "llvm/IR/DataLayout.h"
> > +#include "llvm/IR/DataLayout.h"
> > +#include "llvm/Target/TargetMachine.h"
> > +
> > +#include "AVRFrameLowering.h"
> > +#include "AVRISelLowering.h"
> > +#include "AVRInstrInfo.h"
> > +#include "AVRSelectionDAGInfo.h"
> > +
> > +#define GET_SUBTARGETINFO_HEADER
> > +#include "AVRGenSubtargetInfo.inc"
> > +
> > +namespace llvm {
> > +
> > +/// A specific AVR target MCU.
> > +class AVRSubtarget : public AVRGenSubtargetInfo {
> > +public:
> > +  //! Creates an AVR subtarget.
> > +  //! \param TT  The target triple.
> > +  //! \param CPU The CPU to target.
> > +  //! \param FS  The feature string.
> > +  //! \param TM  The target machine.
> > +  AVRSubtarget(const Triple &TT, const std::string &CPU, const
> std::string &FS,
> > +               AVRTargetMachine &TM);
> > +
> > +  const AVRInstrInfo *getInstrInfo() const override { return
> &InstrInfo; }
> > +  const TargetFrameLowering *getFrameLowering() const override { return
> &FrameLowering; }
> > +  const AVRTargetLowering *getTargetLowering() const override { return
> &TLInfo; }
> > +  const AVRSelectionDAGInfo *getSelectionDAGInfo() const override {
> return &TSInfo; }
> > +  const AVRRegisterInfo *getRegisterInfo() const override { return
> &InstrInfo.getRegisterInfo(); }
> > +
> > +  /// Parses a subtarget feature string, setting appropriate options.
> > +  /// \note Definition of function is auto generated by `tblgen`.
> > +  void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
> > +
> > +  // Subtarget feature getters.
> > +  // See AVR.td for details.
> > +  bool hasSRAM() const { return m_hasSRAM; }
> > +  bool hasJMPCALL() const { return m_hasJMPCALL; }
> > +  bool hasIJMPCALL() const { return m_hasIJMPCALL; }
> > +  bool hasEIJMPCALL() const { return m_hasEIJMPCALL; }
> > +  bool hasADDSUBIW() const { return m_hasADDSUBIW; }
> > +  bool hasSmallStack() const { return m_hasSmallStack; }
> > +  bool hasMOVW() const { return m_hasMOVW; }
> > +  bool hasLPM() const { return m_hasLPM; }
> > +  bool hasLPMX() const { return m_hasLPMX; }
> > +  bool hasELPM() const { return m_hasELPM; }
> > +  bool hasELPMX() const { return m_hasELPMX; }
> > +  bool hasSPM() const { return m_hasSPM; }
> > +  bool hasSPMX() const { return m_hasSPMX; }
> > +  bool hasDES() const { return m_hasDES; }
> > +  bool supportsRMW() const { return m_supportsRMW; }
> > +  bool supportsMultiplication() const { return
> m_supportsMultiplication; }
> > +  bool hasBREAK() const { return m_hasBREAK; }
> > +  bool hasTinyEncoding() const { return m_hasTinyEncoding; }
> > +
> > +  /// Gets the ELF architecture for the e_flags field
> > +  /// of an ELF object file.
> > +  unsigned getELFArch() const {
> > +    assert(ELFArch != 0 &&
> > +           "every device must have an associate ELF architecture");
> > +    return ELFArch;
> > +  }
> > +
> > +private:
> > +  AVRInstrInfo InstrInfo;
> > +  AVRFrameLowering FrameLowering;
> > +  AVRTargetLowering TLInfo;
> > +  AVRSelectionDAGInfo TSInfo;
> > +
> > +  // Subtarget feature settings
> > +  // See AVR.td for details.
> > +  bool m_hasSRAM;
> > +  bool m_hasJMPCALL;
> > +  bool m_hasIJMPCALL;
> > +  bool m_hasEIJMPCALL;
> > +  bool m_hasADDSUBIW;
> > +  bool m_hasSmallStack;
> > +  bool m_hasMOVW;
> > +  bool m_hasLPM;
> > +  bool m_hasLPMX;
> > +  bool m_hasELPM;
> > +  bool m_hasELPMX;
> > +  bool m_hasSPM;
> > +  bool m_hasSPMX;
> > +  bool m_hasDES;
> > +  bool m_supportsRMW;
> > +  bool m_supportsMultiplication;
> > +  bool m_hasBREAK;
> > +  bool m_hasTinyEncoding;
> > +
> > +  /// The ELF e_flags architecture.
> > +  unsigned ELFArch;
> > +
> > +  // Dummy member, used by FeatureSet's. We cannot have a
> SubtargetFeature with
> > +  // no variable, so we instead bind pseudo features to this variable.
> > +  bool m_FeatureSetDummy;
> > +};
> > +
> > +} // end namespace llvm
> > +
> > +#endif // LLVM_AVR_SUBTARGET_H
> >
> > Modified: llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp?rev=268722&r1=268721&r2=268722&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp (original)
> > +++ llvm/trunk/lib/Target/AVR/AVRTargetMachine.cpp Fri May  6 05:12:31
> 2016
> > @@ -1,4 +1,100 @@
> > +//===-- AVRTargetMachine.cpp - Define TargetMachine for AVR
> ---------------===//
> > +//
> > +//                     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 AVR specific subclass of TargetMachine.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#include "AVRTargetMachine.h"
> > +
> > +#include "llvm/CodeGen/Passes.h"
> > +#include "llvm/IR/Module.h"
> > +#include "llvm/IR/LegacyPassManager.h"
> > +#include "llvm/Support/TargetRegistry.h"
> > +
> > +#include "AVRTargetObjectFile.h"
> > +#include "AVR.h"
> > +#include "MCTargetDesc/AVRMCTargetDesc.h"
> > +
> > +namespace llvm {
> > +
> > +/// Processes a CPU name.
> > +static StringRef getTargetCPU(StringRef CPU) {
> > +  if (CPU.empty() || CPU == "generic") {
> > +    return "avr2";
> > +  }
> > +
> > +  return CPU;
> > +}
> > +
> > +AVRTargetMachine::AVRTargetMachine(const Target &T, const Triple &TT,
> > +                                   StringRef CPU, StringRef FS,
> > +                                   const TargetOptions &Options,
> > +                                   Reloc::Model RM, CodeModel::Model CM,
> > +                                   CodeGenOpt::Level OL)
> > +    : LLVMTargetMachine(
> > +          T,
> "e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8-i64:8:8-f32:8:8-f64:8:8-n8", TT,
> > +          getTargetCPU(CPU), FS, Options, RM, CM, OL),
> > +      SubTarget(TT, GetTargetCPU(CPU), FS, *this) {
>
> There is no function called GetTargetCPU. I assume this is supposed to
> be calling getTargetCPU like above, but that doesn't really work either
> since TargetMachine has a member function called getTargetCPU that
> resolves first but doesn't match the signature.
>
> > +  this->TLOF = make_unique<AVRTargetObjectFile>();
> > +  initAsmInfo();
> > +}
> > +
> > +namespace {
> > +/// AVR Code Generator Pass Configuration Options.
> > +class AVRPassConfig : public TargetPassConfig {
> > +public:
> > +  AVRPassConfig(AVRTargetMachine *TM, PassManagerBase &PM)
> > +      : TargetPassConfig(TM, PM) {}
> > +
> > +  AVRTargetMachine &getAVRTargetMachine() const {
> > +    return getTM<AVRTargetMachine>();
> > +  }
> > +
> > +  bool addInstSelector() override;
> > +  void addPreSched2() override;
> > +  void addPreRegAlloc() override;
> > +  void addPreEmitPass() override;
> > +};
> > +} // namespace
> > +
> > +TargetPassConfig *AVRTargetMachine::createPassConfig(PassManagerBase
> &PM) {
> > +  return new AVRPassConfig(this, PM);
> > +}
> >
> >  extern "C" void LLVMInitializeAVRTarget() {
> > +  // Register the target.
> > +  RegisterTargetMachine<AVRTargetMachine> X(TheAVRTarget);
> > +}
> > +
> > +const AVRSubtarget *AVRTargetMachine::getSubtargetImpl() const {
> > +  return &SubTarget;
> > +}
> > +
> > +const AVRSubtarget *AVRTargetMachine::getSubtargetImpl(const Function
> &) const {
> > +  return &SubTarget;
> > +}
> > +
> >
> +//===----------------------------------------------------------------------===//
> > +// Pass Pipeline Configuration
> >
> +//===----------------------------------------------------------------------===//
> >
> > +bool AVRPassConfig::addInstSelector() {
> > +  return false;
> >  }
> > +
> > +void AVRPassConfig::addPreRegAlloc() {
> > +}
> > +
> > +void AVRPassConfig::addPreSched2() { }
> > +
> > +void AVRPassConfig::addPreEmitPass() {
> > +}
> > +
> > +} // end of namespace llvm
> >
> > Added: llvm/trunk/lib/Target/AVR/AVRTargetMachine.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRTargetMachine.h?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/AVRTargetMachine.h (added)
> > +++ llvm/trunk/lib/Target/AVR/AVRTargetMachine.h Fri May  6 05:12:31 2016
> > @@ -0,0 +1,56 @@
> > +//===-- AVRTargetMachine.h - Define TargetMachine for AVR -------*- 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 the AVR specific subclass of TargetMachine.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef LLVM_AVR_TARGET_MACHINE_H
> > +#define LLVM_AVR_TARGET_MACHINE_H
> > +
> > +#include "AVRConfig.h"
> > +
> > +#include "llvm/IR/DataLayout.h"
> > +#include "llvm/Target/TargetMachine.h"
> > +
> > +#include "AVRFrameLowering.h"
> > +#include "AVRISelLowering.h"
> > +#include "AVRInstrInfo.h"
> > +#include "AVRSelectionDAGInfo.h"
> > +#include "AVRSubtarget.h"
> > +
> > +namespace llvm {
> > +
> > +/**
> > + * A generic AVR implementation.
> > + */
> > +class AVRTargetMachine : public LLVMTargetMachine {
> > +public:
> > +  AVRTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
> > +                   StringRef FS, const TargetOptions &Options,
> Reloc::Model RM,
> > +                   CodeModel::Model CM, CodeGenOpt::Level OL);
> > +
> > +  const AVRSubtarget *getSubtargetImpl() const;
> > +  const AVRSubtarget *getSubtargetImpl(const Function &) const override;
> > +
> > +  TargetLoweringObjectFile *getObjFileLowering() const override {
> > +    return this->TLOF.get();
> > +  }
> > +
> > +  // Pass Pipeline Configuration.
> > +  TargetPassConfig *createPassConfig(PassManagerBase &PM) override;
> > +
> > +private:
> > +  std::unique_ptr<TargetLoweringObjectFile> TLOF;
> > +  AVRSubtarget SubTarget;
> > +};
> > +
> > +} // end namespace llvm
> > +
> > +#endif // LLVM_AVR_TARGET_MACHINE_H
> >
> > Modified: llvm/trunk/lib/Target/AVR/CMakeLists.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/CMakeLists.txt?rev=268722&r1=268721&r2=268722&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/CMakeLists.txt (original)
> > +++ llvm/trunk/lib/Target/AVR/CMakeLists.txt Fri May  6 05:12:31 2016
> > @@ -3,11 +3,15 @@ set(LLVM_TARGET_DEFINITIONS AVR.td)
> >  tablegen(LLVM AVRGenRegisterInfo.inc -gen-register-info)
> >  tablegen(LLVM AVRGenInstrInfo.inc -gen-instr-info)
> >  tablegen(LLVM AVRGenCallingConv.inc -gen-callingconv)
> > +tablegen(LLVM AVRGenSubtargetInfo.inc -gen-subtarget)
> >  add_public_tablegen_target(AVRCommonTableGen)
> >
> >  add_llvm_target(AVRCodeGen
> >      AVRTargetMachine.cpp
> >      AVRTargetObjectFile.cpp
> > +    AVRSubtarget.cpp
> > +    AVRInstrInfo.cpp
> > +    AVRRegisterInfo.cpp
> >    )
> >
> >  add_dependencies(LLVMAVRCodeGen intrinsics_gen)
> >
> > Added: llvm/trunk/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h?rev=268722&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h (added)
> > +++ llvm/trunk/lib/Target/AVR/MCTargetDesc/AVRMCTargetDesc.h Fri May  6
> 05:12:31 2016
> > @@ -0,0 +1,65 @@
> > +//===-- AVRMCTargetDesc.h - AVR Target Descriptions -------------*- C++
> -*-===//
> > +//
> > +//                     The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +//
> > +// This file provides AVR specific target descriptions.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +#ifndef LLVM_AVR_MCTARGET_DESC_H
> > +#define LLVM_AVR_MCTARGET_DESC_H
> > +
> > +#include "AVRConfig.h"
> > +
> > +#include "llvm/Support/DataTypes.h"
> > +
> > +namespace llvm {
> > +
> > +class MCAsmBackend;
> > +class MCCodeEmitter;
> > +class MCContext;
> > +class MCInstrInfo;
> > +class MCObjectWriter;
> > +class MCRegisterInfo;
> > +class StringRef;
> > +class Target;
> > +class Triple;
> > +class raw_pwrite_stream;
> > +
> > +extern Target TheAVRTarget;
> > +
> > +/**
> > + * Creates a machine code emitter for AVR.
> > + */
> > +MCCodeEmitter *createAVRMCCodeEmitter(const MCInstrInfo &MCII,
> > +                                      const MCRegisterInfo &MRI,
> > +                                      MCContext &Ctx);
> > +
> > +/**
> > + * Creates an assembly backend for AVR.
> > + */
> > +MCAsmBackend *createAVRAsmBackend(const Target &T, const MCRegisterInfo
> &MRI,
> > +                                  const Triple &TT, StringRef CPU);
> > +
> > +/**
> > + * Creates an ELF object writer for AVR.
> > + */
> > +MCObjectWriter *createAVRELFObjectWriter(raw_pwrite_stream &OS, uint8_t
> OSABI);
> > +
> > +} // end namespace llvm
> > +
> > +#define GET_REGINFO_ENUM
> > +#include "AVRGenRegisterInfo.inc"
> > +
> > +#define GET_INSTRINFO_ENUM
> > +#include "AVRGenInstrInfo.inc"
> > +
> > +#define GET_SUBTARGETINFO_ENUM
> > +#include "AVRGenSubtargetInfo.inc"
> > +
> > +#endif // LLVM_AVR_MCTARGET_DESC_H
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160511/a156927d/attachment-0001.html>


More information about the llvm-commits mailing list