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