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