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