Home | History | Annotate | Download | only in AVR
      1 //===-- AVRInstrInfo.td - AVR Instruction defs -------------*- tablegen -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file describes the AVR instructions in TableGen format.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 include "AVRInstrFormats.td"
     15 
     16 //===----------------------------------------------------------------------===//
     17 // AVR Type Profiles
     18 //===----------------------------------------------------------------------===//
     19 
     20 def SDT_AVRCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>;
     21 def SDT_AVRCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i16>, SDTCisVT<1, i16>]>;
     22 def SDT_AVRCall : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;
     23 def SDT_AVRWrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;
     24 def SDT_AVRBrcond : SDTypeProfile<0, 2,
     25                                   [SDTCisVT<0, OtherVT>, SDTCisVT<1, i8>]>;
     26 def SDT_AVRCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>;
     27 def SDT_AVRTst : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
     28 def SDT_AVRSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
     29                                     SDTCisSameAs<1, 2>, SDTCisVT<3, i8>]>;
     30 
     31 //===----------------------------------------------------------------------===//
     32 // AVR Specific Node Definitions
     33 //===----------------------------------------------------------------------===//
     34 
     35 def AVRretflag : SDNode<"AVRISD::RET_FLAG", SDTNone,
     36                         [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
     37 def AVRretiflag : SDNode<"AVRISD::RETI_FLAG", SDTNone,
     38                          [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;
     39 
     40 def AVRcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_AVRCallSeqStart,
     41                               [SDNPHasChain, SDNPOutGlue]>;
     42 def AVRcallseq_end : SDNode<"ISD::CALLSEQ_END", SDT_AVRCallSeqEnd,
     43                             [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
     44 
     45 def AVRcall : SDNode<"AVRISD::CALL", SDT_AVRCall,
     46                      [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, SDNPVariadic]>;
     47 
     48 def AVRWrapper : SDNode<"AVRISD::WRAPPER", SDT_AVRWrapper>;
     49 
     50 def AVRbrcond : SDNode<"AVRISD::BRCOND", SDT_AVRBrcond,
     51                        [SDNPHasChain, SDNPInGlue]>;
     52 def AVRcmp : SDNode<"AVRISD::CMP", SDT_AVRCmp, [SDNPOutGlue]>;
     53 def AVRcmpc : SDNode<"AVRISD::CMPC", SDT_AVRCmp, [SDNPInGlue, SDNPOutGlue]>;
     54 def AVRtst : SDNode<"AVRISD::TST", SDT_AVRTst, [SDNPOutGlue]>;
     55 def AVRselectcc: SDNode<"AVRISD::SELECT_CC", SDT_AVRSelectCC, [SDNPInGlue]>;
     56 
     57 // Shift nodes.
     58 def AVRlsl : SDNode<"AVRISD::LSL", SDTIntUnaryOp>;
     59 def AVRlsr : SDNode<"AVRISD::LSR", SDTIntUnaryOp>;
     60 def AVRrol : SDNode<"AVRISD::ROL", SDTIntUnaryOp>;
     61 def AVRror : SDNode<"AVRISD::ROR", SDTIntUnaryOp>;
     62 def AVRasr : SDNode<"AVRISD::ASR", SDTIntUnaryOp>;
     63 
     64 // Pseudo shift nodes for non-constant shift amounts.
     65 def AVRlslLoop : SDNode<"AVRISD::LSLLOOP", SDTIntShiftOp>;
     66 def AVRlsrLoop : SDNode<"AVRISD::LSRLOOP", SDTIntShiftOp>;
     67 def AVRrolLoop : SDNode<"AVRISD::ROLLOOP", SDTIntShiftOp>;
     68 def AVRrorLoop : SDNode<"AVRISD::RORLOOP", SDTIntShiftOp>;
     69 def AVRasrLoop : SDNode<"AVRISD::ASRLOOP", SDTIntShiftOp>;
     70 
     71 //===----------------------------------------------------------------------===//
     72 // AVR Operands, Complex Patterns and Transformations Definitions.
     73 //===----------------------------------------------------------------------===//
     74 
     75 def imm8_neg_XFORM : SDNodeXForm<imm,
     76 [{
     77   return CurDAG->getTargetConstant(-N->getAPIntValue(), SDLoc(N), MVT::i8);
     78 }]>;
     79 
     80 def imm16_neg_XFORM : SDNodeXForm<imm,
     81 [{
     82   return CurDAG->getTargetConstant(-N->getAPIntValue(), SDLoc(N), MVT::i16);
     83 }]>;
     84 
     85 def imm0_63_neg : PatLeaf<(imm),
     86 [{
     87   int64_t val = -N->getSExtValue();
     88   return val >= 0 && val < 64;
     89 }], imm16_neg_XFORM>;
     90 
     91 def uimm6 : PatLeaf<(imm), [{ return isUInt<6>(N->getZExtValue()); }]>;
     92 
     93 def ioaddr_XFORM : SDNodeXForm<imm,
     94 [{
     95   return CurDAG->getTargetConstant(uint8_t(N->getZExtValue()) - 0x20, SDLoc(N), MVT::i8);
     96 }]>;
     97 
     98 def iobitpos8_XFORM : SDNodeXForm<imm,
     99 [{
    100   return CurDAG->getTargetConstant(Log2_32(uint8_t(N->getZExtValue())),
    101                                    SDLoc(N), MVT::i8);
    102 }]>;
    103 
    104 def iobitposn8_XFORM : SDNodeXForm<imm,
    105 [{
    106   return CurDAG->getTargetConstant(Log2_32(uint8_t(~N->getZExtValue())),
    107                                    SDLoc(N), MVT::i8);
    108 }]>;
    109 
    110 def ioaddr8 : PatLeaf<(imm),
    111 [{
    112   uint64_t val = N->getZExtValue();
    113   return val >= 0x20 && val < 0x60;
    114 }], ioaddr_XFORM>;
    115 
    116 def lowioaddr8 : PatLeaf<(imm),
    117 [{
    118   uint64_t val = N->getZExtValue();
    119   return val >= 0x20 && val < 0x40;
    120 }], ioaddr_XFORM>;
    121 
    122 def ioaddr16 : PatLeaf<(imm),
    123 [{
    124   uint64_t val = N->getZExtValue();
    125   return val >= 0x20 && val < 0x5f;
    126 }], ioaddr_XFORM>;
    127 
    128 def iobitpos8 : PatLeaf<(imm),
    129 [{
    130   return isPowerOf2_32(uint8_t(N->getZExtValue()));
    131 }], iobitpos8_XFORM>;
    132 
    133 def iobitposn8 : PatLeaf<(imm),
    134 [{
    135   return isPowerOf2_32(uint8_t(~N->getZExtValue()));
    136 }], iobitposn8_XFORM>;
    137 
    138 def MemriAsmOperand : AsmOperandClass {
    139   let Name = "Memri";
    140   let ParserMethod = "parseMemriOperand";
    141 }
    142 
    143 /// Address operand for `reg+imm` used by STD and LDD.
    144 def memri : Operand<iPTR>
    145 {
    146   let MIOperandInfo = (ops PTRDISPREGS, i16imm);
    147 
    148   let PrintMethod = "printMemri";
    149   let EncoderMethod = "encodeMemri";
    150 
    151   let ParserMatchClass = MemriAsmOperand;
    152 }
    153 
    154 // Address operand for `SP+imm` used by STD{W}SPQRr
    155 def memspi : Operand<iPTR>
    156 {
    157   let MIOperandInfo = (ops GPRSP, i16imm);
    158 }
    159 
    160 def imm_com8 : Operand<i8>
    161 {
    162   let EncoderMethod = "encodeComplement";
    163 
    164   let MIOperandInfo = (ops i8imm);
    165 }
    166 
    167 def relbrtarget_7 : Operand<OtherVT>
    168 {
    169     let PrintMethod   = "printPCRelImm";
    170     let EncoderMethod = "encodeRelCondBrTarget<AVR::fixup_7_pcrel>";
    171 }
    172 
    173 def brtarget_13 : Operand<OtherVT>
    174 {
    175     let PrintMethod   = "printPCRelImm";
    176     let EncoderMethod = "encodeRelCondBrTarget<AVR::fixup_13_pcrel>";
    177 }
    178 
    179 // The target of a 22 or 16-bit call/jmp instruction.
    180 def call_target : Operand<iPTR>
    181 {
    182     let EncoderMethod = "encodeCallTarget";
    183 }
    184 
    185 // A 16-bit address (which can lead to an R_AVR_16 relocation).
    186 def imm16 : Operand<i16>
    187 {
    188     let EncoderMethod = "encodeImm<AVR::fixup_16, 2>";
    189 }
    190 
    191 /// A 6-bit immediate used in the ADIW/SBIW instructions.
    192 def imm_arith6 : Operand<i16>
    193 {
    194     let EncoderMethod = "encodeImm<AVR::fixup_6_adiw, 0>";
    195 }
    196 
    197 /// An 8-bit immediate inside an instruction with the same format
    198 /// as the `LDI` instruction (the `FRdK` format).
    199 def imm_ldi8 : Operand<i8>
    200 {
    201     let EncoderMethod = "encodeImm<AVR::fixup_ldi, 0>";
    202 }
    203 
    204 /// A 5-bit port number used in SBIC and friends (the `FIOBIT` format).
    205 def imm_port5 : Operand<i8>
    206 {
    207     let EncoderMethod = "encodeImm<AVR::fixup_port5, 0>";
    208 }
    209 
    210 /// A 6-bit port number used in the `IN` instruction and friends (the
    211 /// `FIORdA` format.
    212 def imm_port6 : Operand<i8>
    213 {
    214     let EncoderMethod = "encodeImm<AVR::fixup_port6, 0>";
    215 }
    216 
    217 // Addressing mode pattern reg+imm6
    218 def addr : ComplexPattern<iPTR, 2, "SelectAddr", [], [SDNPWantRoot]>;
    219 
    220 // AsmOperand class for a pointer register.
    221 // Used with the LD/ST family of instructions.
    222 // See FSTLD in AVRInstrFormats.td
    223 def PtrRegAsmOperand : AsmOperandClass
    224 {
    225    let Name = "Reg";
    226 }
    227 
    228 // A special operand type for the LD/ST instructions.
    229 // It converts the pointer register number into a two-bit field used in the
    230 // instruction.
    231 def LDSTPtrReg : Operand<i16>
    232 {
    233     let MIOperandInfo = (ops PTRREGS);
    234     let EncoderMethod = "encodeLDSTPtrReg";
    235 
    236     let ParserMatchClass = PtrRegAsmOperand;
    237 }
    238 
    239 // A special operand type for the LDD/STD instructions.
    240 // It behaves identically to the LD/ST version, except restricts
    241 // the pointer registers to Y and Z.
    242 def LDDSTDPtrReg : Operand<i16>
    243 {
    244     let MIOperandInfo = (ops PTRDISPREGS);
    245     let EncoderMethod = "encodeLDSTPtrReg";
    246 
    247     let ParserMatchClass = PtrRegAsmOperand;
    248 }
    249 
    250 //===----------------------------------------------------------------------===//
    251 // AVR predicates for subtarget features
    252 //===----------------------------------------------------------------------===//
    253 
    254 def HasSRAM       :    Predicate<"Subtarget->hasSRAM()">,
    255                          AssemblerPredicate<"FeatureSRAM">;
    256 
    257 def HasJMPCALL    :    Predicate<"Subtarget->hasJMPCALL()">,
    258                          AssemblerPredicate<"FeatureJMPCALL">;
    259 
    260 def HasIJMPCALL   :    Predicate<"Subtarget->hasIJMPCALL()">,
    261                          AssemblerPredicate<"FeatureIJMPCALL">;
    262 
    263 def HasEIJMPCALL  :    Predicate<"Subtarget->hasEIJMPCALL()">,
    264                          AssemblerPredicate<"FeatureEIJMPCALL">;
    265 
    266 def HasADDSUBIW   :    Predicate<"Subtarget->hasADDSUBIW()">,
    267                          AssemblerPredicate<"FeatureADDSUBIW">;
    268 
    269 def HasSmallStack :    Predicate<"Subtarget->HasSmallStack()">,
    270                          AssemblerPredicate<"FeatureSmallStack">;
    271 
    272 def HasMOVW       :    Predicate<"Subtarget->hasMOVW()">,
    273                          AssemblerPredicate<"FeatureMOVW">;
    274 
    275 def HasLPM        :    Predicate<"Subtarget->hasLPM()">,
    276                          AssemblerPredicate<"FeatureLPM">;
    277 
    278 def HasLPMX       :    Predicate<"Subtarget->hasLPMX()">,
    279                          AssemblerPredicate<"FeatureLPMX">;
    280 
    281 def HasELPM       :    Predicate<"Subtarget->hasELPM()">,
    282                          AssemblerPredicate<"FeatureELPM">;
    283 
    284 def HasELPMX      :    Predicate<"Subtarget->hasELPMX()">,
    285                          AssemblerPredicate<"FeatureELPMX">;
    286 
    287 def HasSPM        :    Predicate<"Subtarget->hasSPM()">,
    288                          AssemblerPredicate<"FeatureSPM">;
    289 
    290 def HasSPMX       :    Predicate<"Subtarget->hasSPMX()">,
    291                          AssemblerPredicate<"FeatureSPMX">;
    292 
    293 def HasDES        :    Predicate<"Subtarget->hasDES()">,
    294                          AssemblerPredicate<"FeatureDES">;
    295 
    296 def SupportsRMW   :    Predicate<"Subtarget->supportsRMW()">,
    297                          AssemblerPredicate<"FeatureRMW">;
    298 
    299 def SupportsMultiplication : Predicate<"Subtarget->supportsMultiplication()">,
    300                                AssemblerPredicate<"FeatureMultiplication">;
    301 
    302 def HasBREAK      :    Predicate<"Subtarget->hasBREAK()">,
    303                          AssemblerPredicate<"FeatureBREAK">;
    304 
    305 def HasTinyEncoding : Predicate<"Subtarget->hasTinyEncoding()">,
    306                         AssemblerPredicate<"FeatureTinyEncoding">;
    307 
    308 
    309 // AVR specific condition code. These correspond to AVR_*_COND in
    310 // AVRInstrInfo.td. They must be kept in synch.
    311 def AVR_COND_EQ : PatLeaf<(i8 0)>;
    312 def AVR_COND_NE : PatLeaf<(i8 1)>;
    313 def AVR_COND_GE : PatLeaf<(i8 2)>;
    314 def AVR_COND_LT : PatLeaf<(i8 3)>;
    315 def AVR_COND_SH : PatLeaf<(i8 4)>;
    316 def AVR_COND_LO : PatLeaf<(i8 5)>;
    317 def AVR_COND_MI : PatLeaf<(i8 6)>;
    318 def AVR_COND_PL : PatLeaf<(i8 7)>;
    319 
    320 
    321 //===----------------------------------------------------------------------===//
    322 //===----------------------------------------------------------------------===//
    323 // AVR Instruction list
    324 //===----------------------------------------------------------------------===//
    325 //===----------------------------------------------------------------------===//
    326 
    327 // ADJCALLSTACKDOWN/UP implicitly use/def SP because they may be expanded into
    328 // a stack adjustment and the codegen must know that they may modify the stack
    329 // pointer before prolog-epilog rewriting occurs.
    330 // Pessimistically assume ADJCALLSTACKDOWN / ADJCALLSTACKUP will become
    331 // sub / add which can clobber SREG.
    332 let Defs = [SP, SREG],
    333 Uses = [SP] in
    334 {
    335   def ADJCALLSTACKDOWN : Pseudo<(outs),
    336                                 (ins i16imm:$amt, i16imm:$amt2),
    337                                 "#ADJCALLSTACKDOWN",
    338                                 [(AVRcallseq_start timm:$amt, timm:$amt2)]>;
    339 
    340   // R31R30 is used to update SP, since it is a scratch reg and this instruction
    341   // is placed after the function call then R31R30 should be always free.
    342   //let Defs = [R31R30],
    343   //Uses = [R31R30] in
    344   //:TODO: if we enable this, the pseudo is killed because it looks dead
    345   def ADJCALLSTACKUP : Pseudo<(outs),
    346                               (ins i16imm:$amt1, i16imm:$amt2),
    347                               "#ADJCALLSTACKUP",
    348                               [(AVRcallseq_end timm:$amt1, timm:$amt2)]>;
    349 }
    350 
    351 //===----------------------------------------------------------------------===//
    352 // Addition
    353 //===----------------------------------------------------------------------===//
    354 let isCommutable = 1,
    355 Constraints = "$src = $rd",
    356 Defs = [SREG] in
    357 {
    358   // ADD Rd, Rr
    359   // Adds two 8-bit registers.
    360   def ADDRdRr : FRdRr<0b0000,
    361                       0b11,
    362                       (outs GPR8:$rd),
    363                       (ins GPR8:$src, GPR8:$rr),
    364                       "add\t$rd, $rr",
    365                       [(set i8:$rd, (add i8:$src, i8:$rr)),
    366                        (implicit SREG)]>;
    367 
    368   // ADDW Rd+1:Rd, Rr+1:Rr
    369   // Pseudo instruction to add four 8-bit registers as two 16-bit values.
    370   //
    371   // Expands to:
    372   // add Rd,    Rr
    373   // adc Rd+1, Rr+1
    374   def ADDWRdRr : Pseudo<(outs DREGS:$rd),
    375                         (ins DREGS:$src, DREGS:$rr),
    376                         "addw\t$rd, $rr",
    377                         [(set i16:$rd, (add i16:$src, i16:$rr)),
    378                          (implicit SREG)]>;
    379 
    380   // ADC Rd, Rr
    381   // Adds two 8-bit registers with carry.
    382   let Uses = [SREG] in
    383   def ADCRdRr : FRdRr<0b0001,
    384                       0b11,
    385                       (outs GPR8:$rd),
    386                       (ins GPR8:$src, GPR8:$rr),
    387                       "adc\t$rd, $rr",
    388                       [(set i8:$rd, (adde i8:$src, i8:$rr)),
    389                        (implicit SREG)]>;
    390 
    391   // ADCW Rd+1:Rd, Rr+1:Rr
    392   // Pseudo instruction to add four 8-bit registers as two 16-bit values with
    393   // carry.
    394   //
    395   // Expands to:
    396   // adc Rd,   Rr
    397   // adc Rd+1, Rr+1
    398   let Uses = [SREG] in
    399   def ADCWRdRr : Pseudo<(outs DREGS:$rd),
    400                         (ins DREGS:$src, DREGS:$rr),
    401                         "adcw\t$rd, $rr",
    402                         [(set i16:$rd, (adde i16:$src, i16:$rr)),
    403                          (implicit SREG)]>;
    404 
    405   // AIDW Rd, k
    406   // Adds an immediate 6-bit value K to Rd, placing the result in Rd.
    407   def ADIWRdK : FWRdK<0b0,
    408                       (outs IWREGS:$rd),
    409                       (ins IWREGS:$src, imm_arith6:$k),
    410                       "adiw\t$rd, $k",
    411                       [(set i16:$rd, (add i16:$src, uimm6:$k)),
    412                        (implicit SREG)]>,
    413                 Requires<[HasADDSUBIW]>;
    414 }
    415 
    416 //===----------------------------------------------------------------------===//
    417 // Subtraction
    418 //===----------------------------------------------------------------------===//
    419 let Constraints = "$src = $rd",
    420 Defs = [SREG] in
    421 {
    422   // SUB Rd, Rr
    423   // Subtracts the 8-bit value of Rr from Rd and places the value in Rd.
    424   def SUBRdRr : FRdRr<0b0001,
    425                       0b10,
    426                       (outs GPR8:$rd),
    427                       (ins GPR8:$src, GPR8:$rr),
    428                       "sub\t$rd, $rr",
    429                       [(set i8:$rd, (sub i8:$src, i8:$rr)),
    430                        (implicit SREG)]>;
    431 
    432   // SUBW Rd+1:Rd, Rr+1:Rr
    433   // Subtracts two 16-bit values and places the result into Rd.
    434   //
    435   // Expands to:
    436   // sub Rd,   Rr
    437   // sbc Rd+1, Rr+1
    438   def SUBWRdRr : Pseudo<(outs DREGS:$rd),
    439                         (ins DREGS:$src, DREGS:$rr),
    440                         "subw\t$rd, $rr",
    441                         [(set i16:$rd, (sub i16:$src, i16:$rr)),
    442                          (implicit SREG)]>;
    443 
    444   def SUBIRdK : FRdK<0b0101,
    445                      (outs LD8:$rd),
    446                      (ins LD8:$src, imm_ldi8:$k),
    447                      "subi\t$rd, $k",
    448                      [(set i8:$rd, (sub i8:$src, imm:$k)),
    449                       (implicit SREG)]>;
    450 
    451   // SUBIW Rd+1:Rd, K+1:K
    452   //
    453   // Expands to:
    454   // subi Rd,   K
    455   // sbci Rd+1, K+1
    456   def SUBIWRdK : Pseudo<(outs DLDREGS:$rd),
    457                         (ins DLDREGS:$src, i16imm:$rr),
    458                         "subiw\t$rd, $rr",
    459                         [(set i16:$rd, (sub i16:$src, imm:$rr)),
    460                          (implicit SREG)]>;
    461 
    462   def SBIWRdK : FWRdK<0b1,
    463                       (outs IWREGS:$rd),
    464                       (ins IWREGS:$src, imm_arith6:$k),
    465                       "sbiw\t$rd, $k",
    466                       [(set i16:$rd, (sub i16:$src, uimm6:$k)),
    467                        (implicit SREG)]>,
    468                 Requires<[HasADDSUBIW]>;
    469 
    470   // Subtract with carry operations which must read the carry flag in SREG.
    471   let Uses = [SREG] in
    472   {
    473     def SBCRdRr : FRdRr<0b0000,
    474                         0b10,
    475                         (outs GPR8:$rd),
    476                         (ins GPR8:$src, GPR8:$rr),
    477                         "sbc\t$rd, $rr",
    478                         [(set i8:$rd, (sube i8:$src, i8:$rr)),
    479                          (implicit SREG)]>;
    480 
    481     // SBCW Rd+1:Rd, Rr+1:Rr
    482     //
    483     // Expands to:
    484     // sbc Rd,   Rr
    485     // sbc Rd+1, Rr+1
    486     def SBCWRdRr : Pseudo<(outs DREGS:$rd),
    487                           (ins DREGS:$src, DREGS:$rr),
    488                           "sbcw\t$rd, $rr",
    489                           [(set i16:$rd, (sube i16:$src, i16:$rr)),
    490                            (implicit SREG)]>;
    491 
    492     def SBCIRdK : FRdK<0b0100,
    493                        (outs LD8:$rd),
    494                        (ins LD8:$src, imm_ldi8:$k),
    495                        "sbci\t$rd, $k",
    496                        [(set i8:$rd, (sube i8:$src, imm:$k)),
    497                         (implicit SREG)]>;
    498 
    499     // SBCIW Rd+1:Rd, K+1:K
    500     // sbci Rd,   K
    501     // sbci Rd+1, K+1
    502     def SBCIWRdK : Pseudo<(outs DLDREGS:$rd),
    503                           (ins DLDREGS:$src, i16imm:$rr),
    504                           "sbciw\t$rd, $rr",
    505                           [(set i16:$rd, (sube i16:$src, imm:$rr)),
    506                            (implicit SREG)]>;
    507   }
    508 }
    509 
    510 //===----------------------------------------------------------------------===//
    511 // Increment and Decrement
    512 //===----------------------------------------------------------------------===//
    513 let Constraints = "$src = $rd",
    514 Defs = [SREG] in
    515 {
    516   def INCRd : FRd<0b1001,
    517                   0b0100011,
    518                   (outs GPR8:$rd),
    519                   (ins GPR8:$src),
    520                   "inc\t$rd",
    521                   [(set i8:$rd, (add i8:$src, 1)), (implicit SREG)]>;
    522 
    523   def DECRd : FRd<0b1001,
    524                   0b0101010,
    525                   (outs GPR8:$rd),
    526                   (ins GPR8:$src),
    527                   "dec\t$rd",
    528                   [(set i8:$rd, (add i8:$src, -1)), (implicit SREG)]>;
    529 }
    530 
    531 //===----------------------------------------------------------------------===//
    532 // Multiplication
    533 //===----------------------------------------------------------------------===//
    534 
    535 let isCommutable = 1,
    536 Defs = [R1, R0, SREG] in
    537 {
    538   // MUL Rd, Rr
    539   // Multiplies Rd by Rr and places the result into R1:R0.
    540   let usesCustomInserter = 1 in {
    541     def MULRdRr : FRdRr<0b1001, 0b11,
    542                         (outs),
    543                         (ins GPR8:$lhs, GPR8:$rhs),
    544                         "mul\t$lhs, $rhs",
    545                         [/*(set R1, R0, (smullohi i8:$lhs, i8:$rhs))*/]>,
    546                     Requires<[SupportsMultiplication]>;
    547 
    548     def MULSRdRr : FMUL2RdRr<0,
    549                              (outs),
    550                              (ins GPR8:$lhs, GPR8:$rhs),
    551                              "muls\t$lhs, $rhs",
    552                              []>,
    553                    Requires<[SupportsMultiplication]>;
    554   }
    555 
    556   def MULSURdRr : FMUL2RdRr<1,
    557                             (outs),
    558                             (ins GPR8:$lhs, GPR8:$rhs),
    559                             "mulsu\t$lhs, $rhs",
    560                             []>,
    561                   Requires<[SupportsMultiplication]>;
    562 
    563   def FMUL : FFMULRdRr<0b01,
    564                        (outs),
    565                        (ins GPR8:$lhs, GPR8:$rhs),
    566                        "fmul\t$lhs, $rhs",
    567                        []>,
    568              Requires<[SupportsMultiplication]>;
    569 
    570   def FMULS : FFMULRdRr<0b10,
    571                         (outs),
    572                         (ins GPR8:$lhs, GPR8:$rhs),
    573                         "fmuls\t$lhs, $rhs",
    574                         []>,
    575               Requires<[SupportsMultiplication]>;
    576 
    577   def FMULSU : FFMULRdRr<0b11,
    578                          (outs),
    579                          (ins GPR8:$lhs, GPR8:$rhs),
    580                          "fmulsu\t$lhs, $rhs",
    581                          []>,
    582                Requires<[SupportsMultiplication]>;
    583 }
    584 
    585 let Defs = [R15, R14, R13, R12, R11, R10, R9,
    586             R8, R7, R6, R5, R4, R3, R2, R1, R0] in
    587 def DESK : FDES<(outs),
    588                 (ins i8imm:$k),
    589                 "des\t$k",
    590                 []>,
    591            Requires<[HasDES]>;
    592 
    593 //===----------------------------------------------------------------------===//
    594 // Logic
    595 //===----------------------------------------------------------------------===//
    596 let Constraints = "$src = $rd",
    597 Defs = [SREG] in
    598 {
    599   // Register-Register logic instructions (which have the
    600   // property of commutativity).
    601   let isCommutable = 1 in
    602   {
    603     def ANDRdRr : FRdRr<0b0010,
    604                         0b00,
    605                         (outs GPR8:$rd),
    606                         (ins GPR8:$src, GPR8:$rr),
    607                         "and\t$rd, $rr",
    608                         [(set i8:$rd, (and i8:$src, i8:$rr)),
    609                          (implicit SREG)]>;
    610 
    611     // ANDW Rd+1:Rd, Rr+1:Rr
    612     //
    613     // Expands to:
    614     // and Rd,   Rr
    615     // and Rd+1, Rr+1
    616     def ANDWRdRr : Pseudo<(outs DREGS:$rd),
    617                           (ins DREGS:$src, DREGS:$rr),
    618                           "andw\t$rd, $rr",
    619                           [(set i16:$rd, (and i16:$src, i16:$rr)),
    620                            (implicit SREG)]>;
    621 
    622     def ORRdRr : FRdRr<0b0010,
    623                        0b10,
    624                        (outs GPR8:$rd),
    625                        (ins GPR8:$src, GPR8:$rr),
    626                        "or\t$rd, $rr",
    627                        [(set i8:$rd, (or i8:$src, i8:$rr)),
    628                         (implicit SREG)]>;
    629 
    630     // ORW Rd+1:Rd, Rr+1:Rr
    631     //
    632     // Expands to:
    633     // or Rd,   Rr
    634     // or Rd+1, Rr+1
    635     def ORWRdRr : Pseudo<(outs DREGS:$rd),
    636                          (ins DREGS:$src, DREGS:$rr),
    637                          "orw\t$rd, $rr",
    638                          [(set i16:$rd, (or i16:$src, i16:$rr)),
    639                           (implicit SREG)]>;
    640 
    641     def EORRdRr : FRdRr<0b0010,
    642                         0b01,
    643                         (outs GPR8:$rd),
    644                         (ins GPR8:$src, GPR8:$rr),
    645                         "eor\t$rd, $rr",
    646                         [(set i8:$rd, (xor i8:$src, i8:$rr)),
    647                          (implicit SREG)]>;
    648 
    649     // EORW Rd+1:Rd, Rr+1:Rr
    650     //
    651     // Expands to:
    652     // eor Rd,   Rr
    653     // eor Rd+1, Rr+1
    654     def EORWRdRr : Pseudo<(outs DREGS:$rd),
    655                           (ins DREGS:$src, DREGS:$rr),
    656                           "eorw\t$rd, $rr",
    657                           [(set i16:$rd, (xor i16:$src, i16:$rr)),
    658                            (implicit SREG)]>;
    659   }
    660 
    661   def ANDIRdK : FRdK<0b0111,
    662                      (outs LD8:$rd),
    663                      (ins LD8:$src, imm_ldi8:$k),
    664                      "andi\t$rd, $k",
    665                      [(set i8:$rd, (and i8:$src, imm:$k)),
    666                       (implicit SREG)]>;
    667 
    668   // ANDI Rd+1:Rd, K+1:K
    669   //
    670   // Expands to:
    671   // andi Rd,   K
    672   // andi Rd+1, K+1
    673   def ANDIWRdK : Pseudo<(outs DLDREGS:$rd),
    674                         (ins DLDREGS:$src, i16imm:$k),
    675                         "andiw\t$rd, $k",
    676                         [(set i16:$rd, (and i16:$src, imm:$k)),
    677                          (implicit SREG)]>;
    678 
    679   def ORIRdK : FRdK<0b0110,
    680                     (outs LD8:$rd),
    681                     (ins LD8:$src, imm_ldi8:$k),
    682                     "ori\t$rd, $k",
    683                     [(set i8:$rd, (or i8:$src, imm:$k)),
    684                      (implicit SREG)]>;
    685 
    686   // ORIW Rd+1:Rd, K+1,K
    687   //
    688   // Expands to:
    689   // ori Rd,   K
    690   // ori Rd+1, K+1
    691   def ORIWRdK : Pseudo<(outs DLDREGS:$rd),
    692                        (ins DLDREGS:$src, i16imm:$rr),
    693                        "oriw\t$rd, $rr",
    694                        [(set i16:$rd, (or i16:$src, imm:$rr)),
    695                         (implicit SREG)]>;
    696 }
    697 
    698 //===----------------------------------------------------------------------===//
    699 // One's/Two's Complement
    700 //===----------------------------------------------------------------------===//
    701 let Constraints = "$src = $rd",
    702 Defs = [SREG] in
    703 {
    704   def COMRd : FRd<0b1001,
    705                   0b0100000,
    706                   (outs GPR8:$rd),
    707                   (ins GPR8:$src),
    708                   "com\t$rd",
    709                   [(set i8:$rd, (not i8:$src)), (implicit SREG)]>;
    710 
    711   // COMW Rd+1:Rd
    712   //
    713   // Expands to:
    714   // com Rd
    715   // com Rd+1
    716   def COMWRd : Pseudo<(outs DREGS:$rd),
    717                       (ins DREGS:$src),
    718                       "comw\t$rd",
    719                       [(set i16:$rd, (not i16:$src)), (implicit SREG)]>;
    720 
    721   //:TODO: optimize NEG for wider types
    722   def NEGRd : FRd<0b1001,
    723                   0b0100001,
    724                   (outs GPR8:$rd),
    725                   (ins GPR8:$src),
    726                   "neg\t$rd",
    727                   [(set i8:$rd, (ineg i8:$src)), (implicit SREG)]>;
    728 }
    729 
    730 // TST Rd
    731 // Test for zero of minus.
    732 // This operation is identical to a `Rd AND Rd`.
    733 //def : InstAlias<"tst\t$rd", (ANDRdRr GPR8:$rd, GPR8:$rd), 1>;
    734 
    735 let Defs = [SREG] in
    736 def TSTRd : FTST<0b0010,
    737                   0b00,
    738                   (outs),
    739                   (ins GPR8:$rd),
    740                   "tst\t$rd",
    741                   [(AVRtst i8:$rd)]>;
    742 
    743 //===----------------------------------------------------------------------===//
    744 // Jump instructions
    745 //===----------------------------------------------------------------------===//
    746 let isBarrier = 1,
    747 isBranch = 1,
    748 isTerminator = 1 in
    749 {
    750   def RJMPk : FBRk<0,
    751                    (outs),
    752                    (ins brtarget_13:$target),
    753                    "rjmp\t$target",
    754                    [(br bb:$target)]>;
    755 
    756   let isIndirectBranch = 1,
    757   Uses = [R31R30] in
    758   def IJMP : F16<0b1001010000001001,
    759                  (outs),
    760                  (ins),
    761                  "ijmp",
    762                  []>,
    763              Requires<[HasIJMPCALL]>;
    764 
    765   let isIndirectBranch = 1,
    766   Uses = [R31R30] in
    767   def EIJMP : F16<0b1001010000011001,
    768                   (outs),
    769                   (ins),
    770                   "eijmp",
    771                   []>,
    772               Requires<[HasEIJMPCALL]>;
    773 
    774   def JMPk : F32BRk<0b110,
    775                     (outs),
    776                     (ins call_target:$k),
    777                     "jmp\t$k",
    778                     []>,
    779              Requires<[HasJMPCALL]>;
    780 }
    781 
    782 //===----------------------------------------------------------------------===//
    783 // Call instructions
    784 //===----------------------------------------------------------------------===//
    785 let isCall = 1 in
    786 {
    787   // SP is marked as a use to prevent stack-pointer assignments that appear
    788   // immediately before calls from potentially appearing dead.
    789   let Uses = [SP] in
    790   def RCALLk : FBRk<1,
    791                     (outs),
    792                     (ins brtarget_13:$target),
    793                     "rcall\t$target",
    794                     []>;
    795 
    796   // SP is marked as a use to prevent stack-pointer assignments that appear
    797   // immediately before calls from potentially appearing dead.
    798   let Uses = [SP, R31R30] in
    799   def ICALL : F16<0b1001010100001001,
    800                   (outs),
    801                   (ins variable_ops),
    802                   "icall",
    803                   []>,
    804               Requires<[HasIJMPCALL]>;
    805 
    806   // SP is marked as a use to prevent stack-pointer assignments that appear
    807   // immediately before calls from potentially appearing dead.
    808   let Uses = [SP, R31R30] in
    809   def EICALL : F16<0b1001010100011001,
    810                    (outs),
    811                    (ins variable_ops),
    812                    "eicall",
    813                    []>,
    814                Requires<[HasEIJMPCALL]>;
    815 
    816   // SP is marked as a use to prevent stack-pointer assignments that appear
    817   // immediately before calls from potentially appearing dead.
    818   //
    819   //:TODO: the imm field can be either 16 or 22 bits in devices with more
    820   // than 64k of ROM, fix it once we support the largest devices.
    821   let Uses = [SP] in
    822   def CALLk : F32BRk<0b111,
    823                      (outs),
    824                      (ins call_target:$k),
    825                      "call\t$k",
    826                      [(AVRcall imm:$k)]>,
    827               Requires<[HasJMPCALL]>;
    828 }
    829 
    830 //===----------------------------------------------------------------------===//
    831 // Return instructions.
    832 //===----------------------------------------------------------------------===//
    833 let isTerminator = 1,
    834 isReturn = 1,
    835 isBarrier = 1 in 
    836 {
    837   def RET : F16<0b1001010100001000,
    838                 (outs),
    839                 (ins),
    840                 "ret",
    841                 [(AVRretflag)]>;
    842 
    843   def RETI : F16<0b1001010100011000,
    844                  (outs),
    845                  (ins),
    846                  "reti",
    847                  [(AVRretiflag)]>;
    848 }
    849 
    850 //===----------------------------------------------------------------------===//
    851 // Compare operations.
    852 //===----------------------------------------------------------------------===//
    853 let Defs = [SREG] in
    854 {
    855   // CPSE Rd, Rr
    856   // Compare Rd and Rr, skipping the next instruction if they are equal.
    857   let isBarrier = 1,
    858   isBranch = 1,
    859   isTerminator = 1 in
    860   def CPSE : FRdRr<0b0001,
    861                    0b00,
    862                    (outs),
    863                    (ins GPR8:$rd, GPR8:$rr),
    864                    "cpse\t$rd, $rr",
    865                    []>;
    866 
    867   def CPRdRr : FRdRr<0b0001,
    868                      0b01,
    869                      (outs),
    870                      (ins GPR8:$rd, GPR8:$rr),
    871                      "cp\t$rd, $rr",
    872                      [(AVRcmp i8:$rd, i8:$rr), (implicit SREG)]>;
    873 
    874   // CPW Rd+1:Rd, Rr+1:Rr
    875   //
    876   // Expands to:
    877   // cp  Rd,   Rr
    878   // cpc Rd+1, Rr+1
    879   def CPWRdRr : Pseudo<(outs),
    880                        (ins DREGS:$src, DREGS:$src2),
    881                        "cpw\t$src, $src2",
    882                        [(AVRcmp i16:$src, i16:$src2), (implicit SREG)]>;
    883 
    884   let Uses = [SREG] in
    885   def CPCRdRr : FRdRr<0b0000,
    886                       0b01,
    887                       (outs),
    888                       (ins GPR8:$rd, GPR8:$rr),
    889                       "cpc\t$rd, $rr",
    890                       [(AVRcmpc i8:$rd, i8:$rr), (implicit SREG)]>;
    891 
    892   // CPCW Rd+1:Rd. Rr+1:Rr
    893   //
    894   // Expands to:
    895   // cpc Rd,   Rr
    896   // cpc Rd+1, Rr+1
    897   let Uses = [SREG] in
    898   def CPCWRdRr : Pseudo<(outs),
    899                         (ins DREGS:$src, DREGS:$src2),
    900                         "cpcw\t$src, $src2",
    901                         [(AVRcmpc i16:$src, i16:$src2), (implicit SREG)]>;
    902 
    903   // CPI Rd, K
    904   // Compares a register with an 8 bit immediate.
    905   def CPIRdK : FRdK<0b0011,
    906                     (outs),
    907                     (ins LD8:$rd, imm_ldi8:$k),
    908                     "cpi\t$rd, $k",
    909                     [(AVRcmp i8:$rd, imm:$k), (implicit SREG)]>;
    910 }
    911 
    912 //===----------------------------------------------------------------------===//
    913 // Register conditional skipping/branching operations.
    914 //===----------------------------------------------------------------------===//
    915 let isBranch = 1,
    916 isTerminator = 1 in
    917 {
    918   // Conditional skipping on GPR register bits, and
    919   // conditional skipping on IO register bits.
    920   let isBarrier = 1 in
    921   {
    922     def SBRCRrB : FRdB<0b10,
    923                        (outs),
    924                        (ins GPR8:$rr, i8imm:$b),
    925                        "sbrc\t$rr, $b",
    926                        []>;
    927 
    928     def SBRSRrB : FRdB<0b11,
    929                        (outs),
    930                        (ins GPR8:$rr, i8imm:$b),
    931                        "sbrs\t$rr, $b",
    932                        []>;
    933 
    934     def SBICAb : FIOBIT<0b01,
    935                         (outs),
    936                         (ins imm_port5:$a, i8imm:$b),
    937                         "sbic\t$a, $b",
    938                         []>;
    939 
    940     def SBISAb : FIOBIT<0b11,
    941                         (outs),
    942                         (ins imm_port5:$a, i8imm:$b),
    943                         "sbis\t$a, $b",
    944                         []>;
    945   }
    946 
    947   // Relative branches on status flag bits.
    948   let Uses = [SREG] in
    949   {
    950     // BRBS s, k
    951     // Branch if `s` flag in status register is set.
    952     def BRBSsk : FSK<0,
    953                      (outs),
    954                      (ins i8imm:$s, relbrtarget_7:$k),
    955                      "brbs\t$s, $k",
    956                      []>;
    957 
    958     // BRBC s, k
    959     // Branch if `s` flag in status register is clear.
    960     def BRBCsk : FSK<1,
    961                      (outs),
    962                      (ins i8imm:$s, relbrtarget_7:$k),
    963                      "brbc\t$s, $k",
    964                      []>;
    965   }
    966 }
    967 
    968 
    969 // BRCS k
    970 // Branch if carry flag is set
    971 def : InstAlias<"brcs\t$k", (BRBSsk 0, relbrtarget_7:$k)>;
    972 
    973 // BRCC k
    974 // Branch if carry flag is clear
    975 def : InstAlias<"brcc\t$k", (BRBCsk 0, relbrtarget_7:$k)>;
    976 
    977 // BRHS k
    978 // Branch if half carry flag is set
    979 def : InstAlias<"brhs\t$k", (BRBSsk 5, relbrtarget_7:$k)>;
    980 
    981 // BRHC k
    982 // Branch if half carry flag is clear
    983 def : InstAlias<"brhc\t$k", (BRBCsk 5, relbrtarget_7:$k)>;
    984 
    985 // BRTS k
    986 // Branch if the T flag is set
    987 def : InstAlias<"brts\t$k", (BRBSsk 6, relbrtarget_7:$k)>;
    988 
    989 // BRTC k
    990 // Branch if the T flag is clear
    991 def : InstAlias<"brtc\t$k", (BRBCsk 6, relbrtarget_7:$k)>;
    992 
    993 // BRVS k
    994 // Branch if the overflow flag is set
    995 def : InstAlias<"brvs\t$k", (BRBSsk 3, relbrtarget_7:$k)>;
    996 
    997 // BRVC k
    998 // Branch if the overflow flag is clear
    999 def : InstAlias<"brvc\t$k", (BRBCsk 3, relbrtarget_7:$k)>;
   1000 
   1001 // BRIE k
   1002 // Branch if the global interrupt flag is enabled
   1003 def : InstAlias<"brie\t$k", (BRBSsk 7, relbrtarget_7:$k)>;
   1004 
   1005 // BRID k
   1006 // Branch if the global interrupt flag is disabled
   1007 def : InstAlias<"brid\t$k", (BRBCsk 7, relbrtarget_7:$k)>;
   1008 
   1009 //===----------------------------------------------------------------------===//
   1010 // PC-relative conditional branches
   1011 //===----------------------------------------------------------------------===//
   1012 // Based on status register. We cannot simplify these into instruction aliases
   1013 // because we also need to be able to specify a pattern to match for ISel.
   1014 let isBranch = 1,
   1015 isTerminator = 1,
   1016 Uses = [SREG] in
   1017 {
   1018   def BREQk : FBRsk<0,
   1019                     0b001,
   1020                     (outs),
   1021                     (ins relbrtarget_7:$target),
   1022                     "breq\t$target",
   1023                     [(AVRbrcond bb:$target, AVR_COND_EQ)]>;
   1024 
   1025   def BRNEk : FBRsk<1,
   1026                     0b001,
   1027                     (outs),
   1028                     (ins relbrtarget_7:$target),
   1029                     "brne\t$target",
   1030                     [(AVRbrcond bb:$target, AVR_COND_NE)]>;
   1031 
   1032 
   1033   def BRSHk : FBRsk<1,
   1034                     0b000,
   1035                     (outs),
   1036                     (ins relbrtarget_7:$target),
   1037                     "brsh\t$target",
   1038                     [(AVRbrcond bb:$target, AVR_COND_SH)]>;
   1039 
   1040   def BRLOk : FBRsk<0,
   1041                     0b000,
   1042                     (outs),
   1043                     (ins relbrtarget_7:$target),
   1044                     "brlo\t$target",
   1045                     [(AVRbrcond bb:$target, AVR_COND_LO)]>;
   1046 
   1047   def BRMIk : FBRsk<0,
   1048                     0b010,
   1049                     (outs),
   1050                     (ins relbrtarget_7:$target),
   1051                     "brmi\t$target",
   1052                     [(AVRbrcond bb:$target, AVR_COND_MI)]>;
   1053 
   1054   def BRPLk : FBRsk<1,
   1055                     0b010,
   1056                     (outs),
   1057                     (ins relbrtarget_7:$target),
   1058                     "brpl\t$target",
   1059                     [(AVRbrcond bb:$target, AVR_COND_PL)]>;
   1060 
   1061   def BRGEk : FBRsk<1,
   1062                     0b100,
   1063                     (outs),
   1064                     (ins relbrtarget_7:$target),
   1065                     "brge\t$target",
   1066                     [(AVRbrcond bb:$target, AVR_COND_GE)]>;
   1067 
   1068   def BRLTk : FBRsk<0,
   1069                     0b100,
   1070                     (outs),
   1071                     (ins relbrtarget_7:$target),
   1072                     "brlt\t$target",
   1073                     [(AVRbrcond bb:$target, AVR_COND_LT)]>;
   1074 }
   1075 
   1076 //===----------------------------------------------------------------------===//
   1077 // Data transfer instructions
   1078 //===----------------------------------------------------------------------===//
   1079 // 8 and 16-bit register move instructions.
   1080 let hasSideEffects = 0 in
   1081 {
   1082   def MOVRdRr : FRdRr<0b0010,
   1083                       0b11,
   1084                       (outs GPR8:$rd),
   1085                       (ins GPR8:$rr),
   1086                       "mov\t$rd, $rr",
   1087                       []>;
   1088 
   1089   def MOVWRdRr : FMOVWRdRr<(outs DREGS:$dst),
   1090                            (ins DREGS:$src),
   1091                            "movw\t$dst, $src",
   1092                            []>,
   1093                  Requires<[HasMOVW]>;
   1094 }
   1095 
   1096 // Load immediate values into registers.
   1097 let isReMaterializable = 1 in
   1098 {
   1099   def LDIRdK : FRdK<0b1110,
   1100                     (outs LD8:$rd),
   1101                     (ins imm_ldi8:$k),
   1102                     "ldi\t$rd, $k",
   1103                     [(set i8:$rd, imm:$k)]>;
   1104 
   1105   // LDIW Rd+1:Rd, K+1:K
   1106   //
   1107   // Expands to:
   1108   // ldi Rd,   K
   1109   // ldi Rd+1, K+1
   1110   def LDIWRdK : Pseudo<(outs DLDREGS:$dst),
   1111                        (ins i16imm:$src),
   1112                        "ldiw\t$dst, $src",
   1113                        [(set i16:$dst, imm:$src)]>;
   1114 }
   1115 
   1116 // Load from data space into register.
   1117 let canFoldAsLoad = 1,
   1118 isReMaterializable = 1 in
   1119 {
   1120   def LDSRdK : F32DM<0b0,
   1121                      (outs GPR8:$rd),
   1122                      (ins imm16:$k),
   1123                      "lds\t$rd, $k",
   1124                      [(set i8:$rd, (load imm:$k))]>,
   1125                Requires<[HasSRAM]>;
   1126 
   1127   // LDSW Rd+1:Rd, K+1:K
   1128   //
   1129   // Expands to:
   1130   // lds Rd,  (K+1:K)
   1131   // lds Rd+1 (K+1:K) + 1
   1132   def LDSWRdK : Pseudo<(outs DREGS:$dst),
   1133                        (ins i16imm:$src),
   1134                        "ldsw\t$dst, $src",
   1135                        [(set i16:$dst, (load imm:$src))]>,
   1136                 Requires<[HasSRAM]>;
   1137 }
   1138 
   1139 // Indirect loads.
   1140 let canFoldAsLoad = 1,
   1141 isReMaterializable = 1 in
   1142 {
   1143   def LDRdPtr : FSTLD<0,
   1144                       0b00,
   1145                       (outs GPR8:$reg),
   1146                       (ins LDSTPtrReg:$ptrreg),
   1147                       "ld\t$reg, $ptrreg",
   1148                       [(set GPR8:$reg, (load i16:$ptrreg))]>,
   1149                 Requires<[HasSRAM]>;
   1150 
   1151   // LDW Rd+1:Rd, P
   1152   //
   1153   // Expands to:
   1154   // ld Rd,   P+
   1155   // ld Rd+1, P
   1156   let Constraints = "@earlyclobber $reg" in
   1157   def LDWRdPtr : Pseudo<(outs DREGS:$reg),
   1158                         (ins PTRREGS:$ptrreg),
   1159                         "ldw\t$reg, $ptrreg",
   1160                         [(set i16:$reg, (load i16:$ptrreg))]>,
   1161                  Requires<[HasSRAM]>;
   1162 }
   1163 
   1164 // Indirect loads (with postincrement or predecrement).
   1165 let mayLoad = 1,
   1166 hasSideEffects = 0,
   1167 Constraints = "$ptrreg = $base_wb,@earlyclobber $reg" in
   1168 {
   1169   def LDRdPtrPi : FSTLD<0,
   1170                         0b01,
   1171                         (outs GPR8:$reg, PTRREGS:$base_wb),
   1172                         (ins LDSTPtrReg:$ptrreg),
   1173                         "ld\t$reg, $ptrreg+",
   1174                         []>,
   1175                   Requires<[HasSRAM]>;
   1176 
   1177   // LDW Rd+1:Rd, P+
   1178   // Expands to:
   1179   // ld Rd,   P+
   1180   // ld Rd+1, P+
   1181   def LDWRdPtrPi : Pseudo<(outs DREGS:$reg, PTRREGS:$base_wb),
   1182                           (ins PTRREGS:$ptrreg),
   1183                           "ldw\t$reg, $ptrreg+",
   1184                           []>,
   1185                    Requires<[HasSRAM]>;
   1186 
   1187   def LDRdPtrPd : FSTLD<0,
   1188                         0b10,
   1189                         (outs GPR8:$reg, PTRREGS:$base_wb),
   1190                         (ins LDSTPtrReg:$ptrreg),
   1191                         "ld\t$reg, -$ptrreg",
   1192                         []>,
   1193                   Requires<[HasSRAM]>;
   1194 
   1195   // LDW Rd+1:Rd, -P
   1196   //
   1197   // Expands to:
   1198   // ld Rd+1, -P
   1199   // ld Rd,   -P
   1200   def LDWRdPtrPd : Pseudo<(outs DREGS:$reg, PTRREGS:$base_wb),
   1201                           (ins PTRREGS:$ptrreg),
   1202                           "ldw\t$reg, -$ptrreg",
   1203                           []>,
   1204                    Requires<[HasSRAM]>;
   1205 }
   1206 
   1207 // Load indirect with displacement operations.
   1208 let canFoldAsLoad = 1,
   1209 isReMaterializable = 1 in
   1210 {
   1211   let Constraints = "@earlyclobber $reg" in
   1212   def LDDRdPtrQ : FSTDLDD<0,
   1213                           (outs GPR8:$reg),
   1214                           (ins memri:$memri),
   1215                           "ldd\t$reg, $memri",
   1216                           [(set i8:$reg, (load addr:$memri))]>,
   1217                   Requires<[HasSRAM]>;
   1218 
   1219   // LDDW Rd+1:Rd, P+q
   1220   //
   1221   // Expands to:
   1222   // ldd Rd,   P+q
   1223   // ldd Rd+1, P+q+1
   1224   let Constraints = "@earlyclobber $dst" in
   1225   def LDDWRdPtrQ : Pseudo<(outs DREGS:$dst),
   1226                           (ins memri:$memri),
   1227                           "lddw\t$dst, $memri",
   1228                           [(set i16:$dst, (load addr:$memri))]>,
   1229                    Requires<[HasSRAM]>;
   1230 
   1231   // An identical pseudo instruction to LDDWRdPtrQ, expect restricted to the Y
   1232   // register and without the @earlyclobber flag.
   1233   //
   1234   // Used to work around a bug caused by the register allocator not
   1235   // being able to handle the expansion of a COPY into an machine instruction
   1236   // that has an earlyclobber flag. This is because the register allocator will
   1237   // try expand a copy from a register slot into an earlyclobber instruction.
   1238   // Instructions that are earlyclobber need to be in a dedicated earlyclobber slot.
   1239   //
   1240   // This pseudo instruction can be used pre-AVR pseudo expansion in order to
   1241   // get a frame index load without directly using earlyclobber instructions.
   1242   //
   1243   // The pseudo expansion pass trivially expands this into LDDWRdPtrQ.
   1244   //
   1245   // This instruction may be removed once PR13375 is fixed.
   1246   let mayLoad = 1,
   1247   hasSideEffects = 0 in
   1248   def LDDWRdYQ : Pseudo<(outs DREGS:$dst),
   1249                         (ins memri:$memri),
   1250                         "lddw\t$dst, $memri",
   1251                         []>,
   1252                  Requires<[HasSRAM]>;
   1253 }
   1254 
   1255 class AtomicLoad<PatFrag Op, RegisterClass DRC,
   1256                  RegisterClass PTRRC> :
   1257   Pseudo<(outs DRC:$rd), (ins PTRRC:$rr), "atomic_op",
   1258          [(set DRC:$rd, (Op i16:$rr))]>;
   1259 
   1260 class AtomicStore<PatFrag Op, RegisterClass DRC,
   1261                   RegisterClass PTRRC> :
   1262   Pseudo<(outs), (ins PTRRC:$rd, DRC:$rr), "atomic_op",
   1263          [(Op i16:$rd, DRC:$rr)]>;
   1264 
   1265 class AtomicLoadOp<PatFrag Op, RegisterClass DRC,
   1266                    RegisterClass PTRRC> :
   1267   Pseudo<(outs DRC:$rd), (ins PTRRC:$rr, DRC:$operand),
   1268          "atomic_op",
   1269          [(set DRC:$rd, (Op i16:$rr, DRC:$operand))]>;
   1270 
   1271 // FIXME: I think 16-bit atomic binary ops need to mark
   1272 // r0 as clobbered.
   1273 
   1274 // Atomic instructions
   1275 // ===================
   1276 //
   1277 // These are all expanded by AVRExpandPseudoInsts
   1278 //
   1279 // 8-bit operations can use any pointer register because
   1280 // they are expanded directly into an LD/ST instruction.
   1281 //
   1282 // 16-bit operations use 16-bit load/store postincrement instructions,
   1283 // which require PTRDISPREGS.
   1284 
   1285 def AtomicLoad8   : AtomicLoad<atomic_load_8, GPR8, PTRREGS>;
   1286 def AtomicLoad16  : AtomicLoad<atomic_load_16, DREGS, PTRDISPREGS>;
   1287 
   1288 def AtomicStore8  : AtomicStore<atomic_store_8, GPR8, PTRREGS>;
   1289 def AtomicStore16 : AtomicStore<atomic_store_16, DREGS, PTRDISPREGS>;
   1290 
   1291 class AtomicLoadOp8<PatFrag Op> : AtomicLoadOp<Op, GPR8, PTRREGS>;
   1292 class AtomicLoadOp16<PatFrag Op> : AtomicLoadOp<Op, DREGS, PTRDISPREGS>;
   1293 
   1294 def AtomicLoadAdd8  : AtomicLoadOp8<atomic_load_add_8>;
   1295 def AtomicLoadAdd16 : AtomicLoadOp16<atomic_load_add_16>;
   1296 def AtomicLoadSub8  : AtomicLoadOp8<atomic_load_sub_8>;
   1297 def AtomicLoadSub16 : AtomicLoadOp16<atomic_load_sub_16>;
   1298 def AtomicLoadAnd8  : AtomicLoadOp8<atomic_load_and_8>;
   1299 def AtomicLoadAnd16 : AtomicLoadOp16<atomic_load_and_16>;
   1300 def AtomicLoadOr8   : AtomicLoadOp8<atomic_load_or_8>;
   1301 def AtomicLoadOr16  : AtomicLoadOp16<atomic_load_or_16>;
   1302 def AtomicLoadXor8  : AtomicLoadOp8<atomic_load_xor_8>;
   1303 def AtomicLoadXor16 : AtomicLoadOp16<atomic_load_xor_16>;
   1304 def AtomicFence     : Pseudo<(outs), (ins), "atomic_fence",
   1305                              [(atomic_fence imm, imm)]>;
   1306 
   1307 // Indirect store from register to data space.
   1308 def STSKRr : F32DM<0b1,
   1309                    (outs),
   1310                    (ins imm16:$k, GPR8:$rd),
   1311                    "sts\t$k, $rd",
   1312                    [(store i8:$rd, imm:$k)]>,
   1313              Requires<[HasSRAM]>;
   1314 
   1315 // STSW K+1:K, Rr+1:Rr
   1316 //
   1317 // Expands to:
   1318 // sts Rr+1, (K+1:K) + 1
   1319 // sts Rr,   (K+1:K)
   1320 def STSWKRr : Pseudo<(outs),
   1321                      (ins i16imm:$dst, DREGS:$src),
   1322                      "stsw\t$dst, $src",
   1323                      [(store i16:$src, imm:$dst)]>,
   1324               Requires<[HasSRAM]>;
   1325 
   1326 // Indirect stores.
   1327 // ST P, Rr
   1328 // Stores the value of Rr into the location addressed by pointer P.
   1329 def STPtrRr : FSTLD<1,
   1330                     0b00,
   1331                     (outs),
   1332                     (ins LDSTPtrReg:$ptrreg, GPR8:$reg),
   1333                     "st\t$ptrreg, $reg",
   1334                     [(store GPR8:$reg, i16:$ptrreg)]>,
   1335               Requires<[HasSRAM]>;
   1336 
   1337 // STW P, Rr+1:Rr
   1338 // Stores the value of Rr into the location addressed by pointer P.
   1339 //
   1340 // Expands to:
   1341 // st P, Rr
   1342 // std P+1, Rr+1
   1343 def STWPtrRr : Pseudo<(outs),
   1344                       (ins PTRDISPREGS:$ptrreg, DREGS:$reg),
   1345                       "stw\t$ptrreg, $reg",
   1346                       [(store i16:$reg, i16:$ptrreg)]>,
   1347                Requires<[HasSRAM]>;
   1348 
   1349 // Indirect stores (with postincrement or predecrement).
   1350 let Constraints = "$ptrreg = $base_wb,@earlyclobber $base_wb" in
   1351 {
   1352 
   1353   // ST P+, Rr
   1354   // Stores the value of Rr into the location addressed by pointer P.
   1355   // Post increments P.
   1356   def STPtrPiRr : FSTLD<1,
   1357                         0b01,
   1358                         (outs LDSTPtrReg:$base_wb),
   1359                         (ins LDSTPtrReg:$ptrreg, GPR8:$reg, i8imm:$offs),
   1360                         "st\t$ptrreg+, $reg",
   1361                         [(set i16:$base_wb,
   1362                          (post_store GPR8:$reg, i16:$ptrreg, imm:$offs))]>,
   1363                   Requires<[HasSRAM]>;
   1364 
   1365   // STW P+, Rr+1:Rr
   1366   // Stores the value of Rr into the location addressed by pointer P.
   1367   // Post increments P.
   1368   //
   1369   // Expands to:
   1370   // st P+, Rr
   1371   // st P+, Rr+1
   1372   def STWPtrPiRr : Pseudo<(outs PTRREGS:$base_wb),
   1373                           (ins PTRREGS:$ptrreg, DREGS:$trh, i8imm:$offs),
   1374                           "stw\t$ptrreg+, $trh",
   1375                           [(set PTRREGS:$base_wb,
   1376                            (post_store DREGS:$trh, PTRREGS:$ptrreg, imm:$offs))]>,
   1377                    Requires<[HasSRAM]>;
   1378 
   1379   // ST -P, Rr
   1380   // Stores the value of Rr into the location addressed by pointer P.
   1381   // Pre decrements P.
   1382   def STPtrPdRr : FSTLD<1,
   1383                         0b10,
   1384                         (outs LDSTPtrReg:$base_wb),
   1385                         (ins LDSTPtrReg:$ptrreg, GPR8:$reg, i8imm:$offs),
   1386                         "st\t-$ptrreg, $reg",
   1387                         [(set i16:$base_wb,
   1388                          (pre_store GPR8:$reg, i16:$ptrreg, imm:$offs))]>,
   1389                   Requires<[HasSRAM]>;
   1390 
   1391   // STW -P, Rr+1:Rr
   1392   // Stores the value of Rr into the location addressed by pointer P.
   1393   // Pre decrements P.
   1394   //
   1395   // Expands to:
   1396   // st -P, Rr+1
   1397   // st -P, Rr
   1398   def STWPtrPdRr : Pseudo<(outs PTRREGS:$base_wb),
   1399                           (ins PTRREGS:$ptrreg, DREGS:$reg, i8imm:$offs),
   1400                           "stw\t-$ptrreg, $reg",
   1401                           [(set PTRREGS:$base_wb,
   1402                            (pre_store i16:$reg, i16:$ptrreg, imm:$offs))]>,
   1403                    Requires<[HasSRAM]>;
   1404 }
   1405 
   1406 // Store indirect with displacement operations.
   1407 // STD P+q, Rr
   1408 // Stores the value of Rr into the location addressed by pointer P with a
   1409 // displacement of q. Does not modify P.
   1410 def STDPtrQRr : FSTDLDD<1,
   1411                         (outs),
   1412                         (ins memri:$memri, GPR8:$reg),
   1413                         "std\t$memri, $reg",
   1414                         [(store i8:$reg, addr:$memri)]>,
   1415                 Requires<[HasSRAM]>;
   1416 
   1417 // STDW P+q, Rr+1:Rr
   1418 // Stores the value of Rr into the location addressed by pointer P with a
   1419 // displacement of q. Does not modify P.
   1420 //
   1421 // Expands to:
   1422 // std P+q,   Rr
   1423 // std P+q+1, Rr+1
   1424 def STDWPtrQRr : Pseudo<(outs),
   1425                         (ins memri:$memri, DREGS:$src),
   1426                         "stdw\t$memri, $src",
   1427                         [(store i16:$src, addr:$memri)]>,
   1428                  Requires<[HasSRAM]>;
   1429 
   1430 
   1431 // Load program memory operations.
   1432 let canFoldAsLoad = 1,
   1433 isReMaterializable = 1,
   1434 mayLoad = 1,
   1435 hasSideEffects = 0 in
   1436 {
   1437   let Defs = [R0],
   1438       Uses = [R31R30] in
   1439   def LPM : F16<0b1001010111001000,
   1440                 (outs),
   1441                 (ins),
   1442                 "lpm",
   1443                 []>,
   1444             Requires<[HasLPM]>;
   1445 
   1446   def LPMRdZ : FLPMX<0,
   1447                      0,
   1448                      (outs GPR8:$dst),
   1449                      (ins ZREG:$z),
   1450                      "lpm\t$dst, $z",
   1451                      []>,
   1452                Requires<[HasLPMX]>;
   1453 
   1454   // Load program memory, while postincrementing the Z register.
   1455   let Defs = [R31R30] in
   1456   {
   1457     def LPMRdZPi : FLPMX<0,
   1458                          1,
   1459                          (outs GPR8:$dst),
   1460                          (ins ZREG:$z),
   1461                          "lpm\t$dst, $z+",
   1462                          []>,
   1463                    Requires<[HasLPMX]>;
   1464 
   1465     def LPMWRdZ : Pseudo<(outs DREGS:$dst),
   1466                          (ins ZREG:$z),
   1467                          "lpmw\t$dst, $z",
   1468                          []>,
   1469                   Requires<[HasLPMX]>;
   1470 
   1471     def LPMWRdZPi : Pseudo<(outs DREGS:$dst),
   1472                            (ins ZREG:$z),
   1473                            "lpmw\t$dst, $z+",
   1474                            []>,
   1475                     Requires<[HasLPMX]>;
   1476   }
   1477 }
   1478 
   1479 // Extended load program memory operations.
   1480 let mayLoad = 1,
   1481 hasSideEffects = 0 in
   1482 {
   1483   let Defs = [R0],
   1484       Uses = [R31R30] in
   1485   def ELPM : F16<0b1001010111011000,
   1486                  (outs),
   1487                  (ins),
   1488                  "elpm",
   1489                  []>,
   1490              Requires<[HasELPM]>;
   1491 
   1492   def ELPMRdZ : FLPMX<1,
   1493                       0,
   1494                       (outs GPR8:$dst),
   1495                       (ins ZREG:$z),
   1496                       "elpm\t$dst, $z",
   1497                       []>,
   1498                 Requires<[HasELPMX]>;
   1499 
   1500   let Defs = [R31R30] in
   1501   def ELPMRdZPi : FLPMX<1,
   1502                         1,
   1503                         (outs GPR8:$dst),
   1504                         (ins ZREG: $z),
   1505                         "elpm\t$dst, $z+",
   1506                         []>,
   1507                   Requires<[HasELPMX]>;
   1508 }
   1509 
   1510 // Store program memory operations.
   1511 let Uses = [R1, R0] in
   1512 {
   1513   let Uses = [R31R30, R1, R0] in
   1514   def SPM : F16<0b1001010111101000,
   1515                 (outs),
   1516                 (ins),
   1517                 "spm",
   1518                 []>,
   1519             Requires<[HasSPM]>;
   1520 
   1521   let Defs = [R31R30] in
   1522   def SPMZPi : F16<0b1001010111111000,
   1523                    (outs),
   1524                    (ins ZREG:$z),
   1525                    "spm $z+",
   1526                    []>,
   1527                Requires<[HasSPMX]>;
   1528 }
   1529 
   1530 // Read data from IO location operations.
   1531 let canFoldAsLoad = 1,
   1532 isReMaterializable = 1 in
   1533 {
   1534   def INRdA : FIORdA<(outs GPR8:$dst),
   1535                      (ins imm_port6:$src),
   1536                      "in\t$dst, $src",
   1537                      [(set i8:$dst, (load ioaddr8:$src))]>;
   1538 
   1539   def INWRdA : Pseudo<(outs DREGS:$dst),
   1540                       (ins imm_port6:$src),
   1541                       "inw\t$dst, $src",
   1542                       [(set i16:$dst, (load ioaddr16:$src))]>;
   1543 }
   1544 
   1545 // Write data to IO location operations.
   1546 def OUTARr : FIOARr<(outs),
   1547                     (ins imm_port6:$dst, GPR8:$src),
   1548                     "out\t$dst, $src",
   1549                     [(store i8:$src, ioaddr8:$dst)]>;
   1550 
   1551 def OUTWARr : Pseudo<(outs),
   1552                      (ins imm_port6:$dst, DREGS:$src),
   1553                      "outw\t$dst, $src",
   1554                      [(store i16:$src, ioaddr16:$dst)]>;
   1555 
   1556 // Stack push/pop operations.
   1557 let Defs = [SP],
   1558 Uses = [SP],
   1559 hasSideEffects = 0 in
   1560 {
   1561   // Stack push operations.
   1562   let mayStore = 1 in
   1563   {
   1564     def PUSHRr : FRd<0b1001,
   1565                      0b0011111,
   1566                      (outs),
   1567                      (ins GPR8:$reg),
   1568                      "push\t$reg",
   1569                      []>,
   1570                  Requires<[HasSRAM]>;
   1571 
   1572     def PUSHWRr : Pseudo<(outs),
   1573                          (ins DREGS:$reg),
   1574                          "pushw\t$reg",
   1575                          []>,
   1576                   Requires<[HasSRAM]>;
   1577   }
   1578 
   1579   // Stack pop operations.
   1580   let mayLoad = 1 in
   1581   {
   1582     def POPRd : FRd<0b1001,
   1583                     0b0001111,
   1584                     (outs GPR8:$reg),
   1585                     (ins),
   1586                     "pop\t$reg",
   1587                     []>,
   1588                 Requires<[HasSRAM]>;
   1589 
   1590     def POPWRd : Pseudo<(outs DREGS:$reg),
   1591                         (ins),
   1592                         "popw\t$reg",
   1593                         []>,
   1594                  Requires<[HasSRAM]>;
   1595   }
   1596 }
   1597 
   1598 // Read-Write-Modify (RMW) instructions.
   1599 def XCHZRd : FZRd<0b100,
   1600                   (outs GPR8:$rd),
   1601                   (ins ZREG:$z),
   1602                   "xch\t$z, $rd",
   1603                   []>,
   1604              Requires<[SupportsRMW]>;
   1605 
   1606 def LASZRd : FZRd<0b101,
   1607                   (outs GPR8:$rd),
   1608                   (ins ZREG:$z),
   1609                   "las\t$z, $rd",
   1610                   []>,
   1611              Requires<[SupportsRMW]>;
   1612 
   1613 def LACZRd : FZRd<0b110,
   1614                   (outs GPR8:$rd),
   1615                   (ins ZREG:$z),
   1616                   "lac\t$z, $rd",
   1617                   []>,
   1618              Requires<[SupportsRMW]>;
   1619 
   1620 def LATZRd : FZRd<0b111,
   1621                   (outs GPR8:$rd),
   1622                   (ins ZREG:$z),
   1623                   "lat\t$z, $rd",
   1624                   []>,
   1625              Requires<[SupportsRMW]>;
   1626 
   1627 //===----------------------------------------------------------------------===//
   1628 // Bit and bit-test instructions
   1629 //===----------------------------------------------------------------------===//
   1630 
   1631 // Bit shift/rotate operations.
   1632 let Constraints = "$src = $rd",
   1633 Defs = [SREG] in
   1634 {
   1635   def LSLRd : FRdRr<0b0000,
   1636                     0b11,
   1637                     (outs GPR8:$rd),
   1638                     (ins GPR8:$src),
   1639                     "lsl\t$rd",
   1640                     [(set i8:$rd, (AVRlsl i8:$src)), (implicit SREG)]>;
   1641 
   1642   def LSLWRd : Pseudo<(outs DREGS:$rd),
   1643                       (ins DREGS:$src),
   1644                       "lslw\t$rd",
   1645                       [(set i16:$rd, (AVRlsl i16:$src)), (implicit SREG)]>;
   1646 
   1647   def LSRRd : FRd<0b1001,
   1648                   0b0100110,
   1649                   (outs GPR8:$rd),
   1650                   (ins GPR8:$src),
   1651                   "lsr\t$rd",
   1652                   [(set i8:$rd, (AVRlsr i8:$src)), (implicit SREG)]>;
   1653 
   1654   def LSRWRd : Pseudo<(outs DREGS:$rd),
   1655                       (ins DREGS:$src),
   1656                       "lsrw\t$rd",
   1657                       [(set i16:$rd, (AVRlsr i16:$src)), (implicit SREG)]>;
   1658 
   1659   def ASRRd : FRd<0b1001,
   1660                   0b0100101,
   1661                   (outs GPR8:$rd),
   1662                   (ins GPR8:$src),
   1663                   "asr\t$rd",
   1664                   [(set i8:$rd, (AVRasr i8:$src)), (implicit SREG)]>;
   1665 
   1666   def ASRWRd : Pseudo<(outs DREGS:$rd),
   1667                       (ins DREGS:$src),
   1668                       "asrw\t$rd",
   1669                       [(set i16:$rd, (AVRasr i16:$src)), (implicit SREG)]>;
   1670 
   1671   // Bit rotate operations.
   1672   let Uses = [SREG] in
   1673   {
   1674     def ROLRd : FRdRr<0b0001,
   1675                       0b11,
   1676                       (outs GPR8:$rd),
   1677                       (ins GPR8:$src),
   1678                       "rol\t$rd",
   1679                       [(set i8:$rd, (AVRrol i8:$src)), (implicit SREG)]>;
   1680 
   1681     def ROLWRd : Pseudo<(outs DREGS:$rd),
   1682                         (ins DREGS:$src),
   1683                         "rolw\t$rd",
   1684                         [(set i16:$rd, (AVRrol i16:$src)), (implicit SREG)]>;
   1685 
   1686     def RORRd : FRd<0b1001,
   1687                     0b0100111,
   1688                     (outs GPR8:$rd),
   1689                     (ins GPR8:$src),
   1690                     "ror\t$rd",
   1691                     [(set i8:$rd, (AVRror i8:$src)), (implicit SREG)]>;
   1692 
   1693     def RORWRd : Pseudo<(outs DREGS:$rd),
   1694                         (ins DREGS:$src),
   1695                         "rorw\t$rd",
   1696                         [(set i16:$rd, (AVRror i16:$src)), (implicit SREG)]>;
   1697   }
   1698 }
   1699 
   1700 // SWAP Rd
   1701 // Swaps the high and low nibbles in a register.
   1702 let Constraints = "$src = $rd" in
   1703 def SWAPRd : FRd<0b1001,
   1704                  0b0100010,
   1705                  (outs GPR8:$rd),
   1706                  (ins GPR8:$src),
   1707                  "swap\t$rd",
   1708                  [(set i8:$rd, (bswap i8:$src))]>;
   1709 
   1710 // IO register bit set/clear operations.
   1711 //:TODO: add patterns when popcount(imm)==2 to be expanded with 2 sbi/cbi
   1712 // instead of in+ori+out which requires one more instr.
   1713 def SBIAb : FIOBIT<0b10,
   1714                    (outs),
   1715                    (ins imm_port5:$addr, i8imm:$bit),
   1716                    "sbi\t$addr, $bit",
   1717                    [(store (or (i8 (load lowioaddr8:$addr)), iobitpos8:$bit),
   1718                      lowioaddr8:$addr)]>;
   1719 
   1720 def CBIAb : FIOBIT<0b00,
   1721                    (outs),
   1722                    (ins imm_port5:$addr, i8imm:$bit),
   1723                    "cbi\t$addr, $bit",
   1724                    [(store (and (i8 (load lowioaddr8:$addr)), iobitposn8:$bit),
   1725                      lowioaddr8:$addr)]>;
   1726 
   1727 // Status register bit load/store operations.
   1728 let Defs = [SREG] in
   1729 def BST : FRdB<0b01,
   1730                (outs),
   1731                (ins GPR8:$rd, i8imm:$b),
   1732                "bst\t$rd, $b",
   1733                []>;
   1734 
   1735 let Uses = [SREG] in
   1736 def BLD : FRdB<0b00,
   1737                (outs),
   1738                (ins GPR8:$rd, i8imm:$b),
   1739                "bld\t$rd, $b",
   1740                []>;
   1741 
   1742 // Set/clear bit in register operations.
   1743 let Constraints = "$src = $rd",
   1744 Defs = [SREG] in
   1745 {
   1746   // SBR Rd, K
   1747   // Alias for ORI Rd, K
   1748   def SBRRdK : FRdK<0b0110,
   1749                     (outs LD8:$rd),
   1750                     (ins LD8:$src, imm_ldi8:$k),
   1751                     "sbr\t$rd, $k",
   1752                     [(set i8:$rd, (or i8:$src, imm:$k)),
   1753                      (implicit SREG)]>;
   1754 
   1755   // CBR Rd, K
   1756   // Alias for `ANDI Rd, COM(K)` where COM(K) is the complement of K.
   1757   // FIXME: This uses the 'complement' encoder. We need it to also use the
   1758   // imm_ldi8 encoder. This will cause no fixups to be created on this instruction.
   1759   def CBRRdK : FRdK<0b0111,
   1760                     (outs LD8:$rd),
   1761                     (ins LD8:$src, imm_com8:$k),
   1762                     "cbr\t$rd, $k",
   1763                     []>;
   1764 }
   1765 
   1766 // CLR Rd
   1767 // Alias for EOR Rd, Rd
   1768 // -------------
   1769 // Clears all bits in a register.
   1770 def CLR : InstAlias<"clr\t$rd", (EORRdRr GPR8:$rd, GPR8:$rd)>;
   1771 
   1772 // SER Rd
   1773 // Alias for LDI Rd, 0xff
   1774 // ---------
   1775 // Sets all bits in a register.
   1776 def : InstAlias<"ser\t$rd", (LDIRdK LD8:$rd, 0xff), 0>;
   1777 
   1778 let Defs = [SREG] in
   1779 def BSETs : FS<0,
   1780                (outs),
   1781                (ins i8imm:$s),
   1782                "bset\t$s",
   1783                []>;
   1784 
   1785 let Defs = [SREG] in
   1786 def BCLRs : FS<1,
   1787                (outs),
   1788                (ins i8imm:$s),
   1789                "bclr\t$s",
   1790                []>;
   1791 
   1792 // Set/clear aliases for the carry (C) status flag (bit 0).
   1793 def : InstAlias<"sec", (BSETs 0)>;
   1794 def : InstAlias<"clc", (BCLRs 0)>;
   1795 
   1796 // Set/clear aliases for the zero (Z) status flag (bit 1).
   1797 def : InstAlias<"sez", (BSETs 1)>;
   1798 def : InstAlias<"clz", (BCLRs 1)>;
   1799 
   1800 // Set/clear aliases for the negative (N) status flag (bit 2).
   1801 def : InstAlias<"sen", (BSETs 2)>;
   1802 def : InstAlias<"cln", (BCLRs 2)>;
   1803 
   1804 // Set/clear aliases for the overflow (V) status flag (bit 3).
   1805 def : InstAlias<"sev", (BSETs 3)>;
   1806 def : InstAlias<"clv", (BCLRs 3)>;
   1807 
   1808 // Set/clear aliases for the signed (S) status flag (bit 4).
   1809 def : InstAlias<"ses", (BSETs 4)>;
   1810 def : InstAlias<"cls", (BCLRs 4)>;
   1811 
   1812 // Set/clear aliases for the half-carry (H) status flag (bit 5).
   1813 def : InstAlias<"seh", (BSETs 5)>;
   1814 def : InstAlias<"clh", (BCLRs 5)>;
   1815 
   1816 // Set/clear aliases for the T status flag (bit 6).
   1817 def : InstAlias<"set", (BSETs 6)>;
   1818 def : InstAlias<"clt", (BCLRs 6)>;
   1819 
   1820 // Set/clear aliases for the interrupt (I) status flag (bit 7).
   1821 def : InstAlias<"sei", (BSETs 7)>;
   1822 def : InstAlias<"cli", (BCLRs 7)>;
   1823 
   1824 //===----------------------------------------------------------------------===//
   1825 // Special/Control instructions
   1826 //===----------------------------------------------------------------------===//
   1827 
   1828 // BREAK
   1829 // Breakpoint instruction
   1830 // ---------
   1831 // <|1001|0101|1001|1000>
   1832 def BREAK : F16<0b1001010110011000,
   1833                 (outs),
   1834                 (ins),
   1835                 "break",
   1836                 []>,
   1837             Requires<[HasBREAK]>;
   1838 
   1839 // NOP
   1840 // No-operation instruction
   1841 // ---------
   1842 // <|0000|0000|0000|0000>
   1843 def NOP : F16<0b0000000000000000,
   1844               (outs),
   1845               (ins),
   1846               "nop",
   1847               []>;
   1848 
   1849 // SLEEP
   1850 // Sleep instruction
   1851 // ---------
   1852 // <|1001|0101|1000|1000>
   1853 def SLEEP : F16<0b1001010110001000,
   1854                 (outs),
   1855                 (ins),
   1856                 "sleep",
   1857                 []>;
   1858 
   1859 // WDR
   1860 // Watchdog reset
   1861 // ---------
   1862 // <|1001|0101|1010|1000>
   1863 def WDR : F16<0b1001010110101000,
   1864               (outs),
   1865               (ins),
   1866               "wdr",
   1867               []>;
   1868 
   1869 //===----------------------------------------------------------------------===//
   1870 // Pseudo instructions for later expansion
   1871 //===----------------------------------------------------------------------===//
   1872 
   1873 //:TODO: Optimize this for wider types AND optimize the following code
   1874 //       compile int foo(char a, char b, char c, char d) {return d+b;}
   1875 //       looks like a missed sext_inreg opportunity.
   1876 def SEXT : ExtensionPseudo<
   1877   (outs DREGS:$dst),
   1878   (ins GPR8:$src),
   1879   "sext\t$dst, $src",
   1880   [(set i16:$dst, (sext i8:$src)), (implicit SREG)]
   1881 >;
   1882 
   1883 def ZEXT : ExtensionPseudo<
   1884   (outs DREGS:$dst),
   1885   (ins GPR8:$src),
   1886   "zext\t$dst, $src",
   1887   [(set i16:$dst, (zext i8:$src)), (implicit SREG)]
   1888 >;
   1889 
   1890 // This pseudo gets expanded into a movw+adiw thus it clobbers SREG.
   1891 let Defs = [SREG],
   1892     hasSideEffects = 0 in
   1893 def FRMIDX : Pseudo<(outs DLDREGS:$dst),
   1894                     (ins DLDREGS:$src, i16imm:$src2),
   1895                     "frmidx\t$dst, $src, $src2",
   1896                     []>;
   1897 
   1898 // This pseudo is either converted to a regular store or a push which clobbers
   1899 // SP.
   1900 def STDSPQRr : StorePseudo<
   1901   (outs),
   1902   (ins memspi:$dst, GPR8:$src),
   1903   "stdstk\t$dst, $src",
   1904   [(store i8:$src, addr:$dst)]
   1905 >;
   1906 
   1907 // This pseudo is either converted to a regular store or a push which clobbers
   1908 // SP.
   1909 def STDWSPQRr : StorePseudo<
   1910   (outs),
   1911   (ins memspi:$dst, DREGS:$src),
   1912   "stdwstk\t$dst, $src",
   1913   [(store i16:$src, addr:$dst)]
   1914 >;
   1915 
   1916 // SP read/write pseudos.
   1917 let hasSideEffects = 0 in
   1918 {
   1919   let Uses = [SP] in
   1920   def SPREAD : Pseudo<
   1921     (outs DREGS:$dst),
   1922     (ins GPRSP:$src),
   1923     "spread\t$dst, $src",
   1924     []
   1925   >;
   1926 
   1927   let Defs = [SP] in
   1928   def SPWRITE : Pseudo<
   1929     (outs GPRSP:$dst),
   1930     (ins DREGS:$src),
   1931     "spwrite\t$dst, $src",
   1932     []>;
   1933 }
   1934 
   1935 def Select8 : SelectPseudo<
   1936   (outs GPR8:$dst),
   1937   (ins GPR8:$src, GPR8:$src2, i8imm:$cc),
   1938   "# Select8 PSEUDO",
   1939   [(set i8:$dst, (AVRselectcc i8:$src, i8:$src2, imm:$cc))]
   1940 >;
   1941 
   1942 def Select16 : SelectPseudo<
   1943   (outs DREGS:$dst),
   1944   (ins DREGS:$src, DREGS:$src2, i8imm:$cc),
   1945   "# Select16 PSEUDO",
   1946   [(set i16:$dst, (AVRselectcc i16:$src, i16:$src2, imm:$cc))]
   1947 >;
   1948 
   1949 def Lsl8 : ShiftPseudo<
   1950   (outs GPR8:$dst),
   1951   (ins GPR8:$src, GPR8:$cnt),
   1952   "# Lsl8 PSEUDO",
   1953   [(set i8:$dst, (AVRlslLoop i8:$src, i8:$cnt))]
   1954 >;
   1955 
   1956 def Lsl16 : ShiftPseudo<
   1957   (outs DREGS:$dst),
   1958   (ins DREGS:$src, GPR8:$cnt),
   1959   "# Lsl16 PSEUDO",
   1960   [(set i16:$dst, (AVRlslLoop i16:$src, i8:$cnt))]
   1961 >;
   1962 
   1963 def Lsr8 : ShiftPseudo<
   1964   (outs GPR8:$dst),
   1965   (ins GPR8:$src, GPR8:$cnt),
   1966   "# Lsr8 PSEUDO",
   1967   [(set i8:$dst, (AVRlsrLoop i8:$src, i8:$cnt))]
   1968 >;
   1969 
   1970 def Lsr16 : ShiftPseudo<
   1971   (outs DREGS:$dst),
   1972    (ins DREGS:$src, GPR8:$cnt),
   1973    "# Lsr16 PSEUDO",
   1974    [(set i16:$dst, (AVRlsrLoop i16:$src, i8:$cnt))]
   1975 >;
   1976 
   1977 def Rol8 : ShiftPseudo<
   1978   (outs GPR8:$dst),
   1979   (ins GPR8:$src, GPR8:$cnt),
   1980   "# Rol8 PSEUDO",
   1981   [(set i8:$dst, (AVRrolLoop i8:$src, i8:$cnt))]
   1982 >;
   1983 
   1984 def Rol16 : ShiftPseudo<
   1985   (outs DREGS:$dst),
   1986   (ins DREGS:$src, GPR8:$cnt),
   1987   "# Rol16 PSEUDO",
   1988   [(set i16:$dst, (AVRrolLoop i16:$src, i8:$cnt))]
   1989 >;
   1990 
   1991 def Ror8 : ShiftPseudo<
   1992   (outs GPR8:$dst),
   1993   (ins GPR8:$src, GPR8:$cnt),
   1994   "# Ror8 PSEUDO",
   1995   [(set i8:$dst, (AVRrorLoop i8:$src, i8:$cnt))]
   1996 >;
   1997 
   1998 def Ror16 : ShiftPseudo<
   1999   (outs DREGS:$dst),
   2000   (ins DREGS:$src, GPR8:$cnt),
   2001   "# Ror16 PSEUDO",
   2002   [(set i16:$dst, (AVRrorLoop i16:$src, i8:$cnt))]
   2003 >;
   2004 
   2005 def Asr8 : ShiftPseudo<
   2006   (outs GPR8:$dst),
   2007   (ins GPR8:$src, GPR8:$cnt),
   2008   "# Asr8 PSEUDO",
   2009   [(set i8:$dst, (AVRasrLoop i8:$src, i8:$cnt))]
   2010 >;
   2011 
   2012 def Asr16 : ShiftPseudo<
   2013   (outs DREGS:$dst),
   2014    (ins DREGS:$src, GPR8:$cnt),
   2015    "# Asr16 PSEUDO",
   2016    [(set i16:$dst, (AVRasrLoop i16:$src, i8:$cnt))]
   2017 >;
   2018 
   2019 
   2020 //===----------------------------------------------------------------------===//
   2021 // Non-Instruction Patterns
   2022 //===----------------------------------------------------------------------===//
   2023 
   2024 //:TODO: look in x86InstrCompiler.td for odd encoding trick related to
   2025 // add x, 128 -> sub x, -128. Clang is emitting an eor for this (ldi+eor)
   2026 
   2027 // the add instruction always writes the carry flag
   2028 def : Pat<(addc i8:$src, i8:$src2),
   2029           (ADDRdRr i8:$src, i8:$src2)>;
   2030 def : Pat<(addc DREGS:$src, DREGS:$src2),
   2031           (ADDWRdRr DREGS:$src, DREGS:$src2)>;
   2032 
   2033 // all sub instruction variants always writes the carry flag
   2034 def : Pat<(subc i8:$src, i8:$src2),
   2035           (SUBRdRr i8:$src, i8:$src2)>;
   2036 def : Pat<(subc i16:$src, i16:$src2),
   2037           (SUBWRdRr i16:$src, i16:$src2)>;
   2038 def : Pat<(subc i8:$src, imm:$src2),
   2039           (SUBIRdK i8:$src, imm:$src2)>;
   2040 def : Pat<(subc i16:$src, imm:$src2),
   2041           (SUBIWRdK i16:$src, imm:$src2)>;
   2042 
   2043 // These patterns convert add (x, -imm) to sub (x, imm) since we dont have
   2044 // any add with imm instructions. Also take care of the adiw/sbiw instructions.
   2045 def : Pat<(add i16:$src1, imm0_63_neg:$src2),
   2046           (SBIWRdK i16:$src1, (imm0_63_neg:$src2))>;
   2047 def : Pat<(add i16:$src1, imm:$src2),
   2048           (SUBIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>;
   2049 def : Pat<(addc i16:$src1, imm:$src2),
   2050           (SUBIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>;
   2051 def : Pat<(adde i16:$src1, imm:$src2),
   2052           (SBCIWRdK i16:$src1, (imm16_neg_XFORM imm:$src2))>;
   2053 
   2054 def : Pat<(add i8:$src1, imm:$src2),
   2055           (SUBIRdK i8:$src1, (imm8_neg_XFORM imm:$src2))>;
   2056 def : Pat<(addc i8:$src1, imm:$src2),
   2057           (SUBIRdK i8:$src1, (imm8_neg_XFORM imm:$src2))>;
   2058 def : Pat<(adde i8:$src1, imm:$src2),
   2059           (SBCIRdK i8:$src1, (imm8_neg_XFORM imm:$src2))>;
   2060 
   2061 // Calls.
   2062 def : Pat<(AVRcall (i16 tglobaladdr:$dst)),
   2063           (CALLk tglobaladdr:$dst)>;
   2064 def : Pat<(AVRcall (i16 texternalsym:$dst)),
   2065           (CALLk texternalsym:$dst)>;
   2066 
   2067 // `anyext`
   2068 def : Pat<(i16 (anyext i8:$src)),
   2069           (INSERT_SUBREG (i16 (IMPLICIT_DEF)), i8:$src, sub_lo)>;
   2070 
   2071 // `trunc`
   2072 def : Pat<(i8 (trunc i16:$src)),
   2073           (EXTRACT_SUBREG i16:$src, sub_lo)>;
   2074 
   2075 // sext_inreg
   2076 def : Pat<(sext_inreg i16:$src, i8),
   2077           (SEXT (i8 (EXTRACT_SUBREG i16:$src, sub_lo)))>;
   2078 
   2079 // GlobalAddress
   2080 def : Pat<(i16 (AVRWrapper tglobaladdr:$dst)),
   2081           (LDIWRdK tglobaladdr:$dst)>;
   2082 def : Pat<(add i16:$src, (AVRWrapper tglobaladdr:$src2)),
   2083           (SUBIWRdK i16:$src, tglobaladdr:$src2)>;
   2084 def : Pat<(i8 (load (AVRWrapper tglobaladdr:$dst))),
   2085           (LDSRdK tglobaladdr:$dst)>;
   2086 def : Pat<(i16 (load (AVRWrapper tglobaladdr:$dst))),
   2087           (LDSWRdK tglobaladdr:$dst)>;
   2088 def : Pat<(store i8:$src, (i16 (AVRWrapper tglobaladdr:$dst))),
   2089           (STSKRr tglobaladdr:$dst, i8:$src)>;
   2090 def : Pat<(store i16:$src, (i16 (AVRWrapper tglobaladdr:$dst))),
   2091           (STSWKRr tglobaladdr:$dst, i16:$src)>;
   2092 
   2093 // BlockAddress
   2094 def : Pat<(i16 (AVRWrapper tblockaddress:$dst)),
   2095           (LDIWRdK tblockaddress:$dst)>;
   2096 
   2097 // hi-reg truncation : trunc(int16 >> 8)
   2098 //:FIXME: i think it's better to emit an extract subreg node in the DAG than
   2099 // all this mess once we get optimal shift code
   2100 // lol... I think so, too. [@agnat]
   2101 def : Pat<(i8 (trunc (AVRlsr (AVRlsr (AVRlsr (AVRlsr (AVRlsr (AVRlsr (AVRlsr
   2102                      (AVRlsr DREGS:$src)))))))))),
   2103           (EXTRACT_SUBREG DREGS:$src, sub_hi)>;
   2104 
   2105 // :FIXME: DAGCombiner produces an shl node after legalization from these seq:
   2106 // BR_JT -> (mul x, 2) -> (shl x, 1)
   2107 def : Pat<(shl i16:$src1, (i8 1)),
   2108           (LSLWRd i16:$src1)>;
   2109 
   2110