[InstCombine] Signed saturation patterns
[llvm-complete.git] / lib / Target / AVR / AVRInstrFormats.td
blob347e683cd47f51b535fd32824d4db463be911118
1 //===-- AVRInstrInfo.td - AVR Instruction Formats ----------*- 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 // AVR Instruction Format Definitions.
11 //===----------------------------------------------------------------------===//
13 // A generic AVR instruction.
14 class AVRInst<dag outs, dag ins, string asmstr, list<dag> pattern> : Instruction
16   let Namespace = "AVR";
18   dag OutOperandList = outs;
19   dag InOperandList = ins;
20   let AsmString = asmstr;
21   let Pattern = pattern;
23   field bits<32> SoftFail = 0;
26 /// A 16-bit AVR instruction.
27 class AVRInst16<dag outs, dag ins, string asmstr, list<dag> pattern>
28   : AVRInst<outs, ins, asmstr, pattern>
30   field bits<16> Inst;
32   let Size = 2;
35 /// a 32-bit AVR instruction.
36 class AVRInst32<dag outs, dag ins, string asmstr, list<dag> pattern>
37   : AVRInst<outs, ins, asmstr, pattern>
39   field bits<32> Inst;
41   let Size = 4;
44 // A class for pseudo instructions.
45 // Psuedo instructions are not real AVR instructions. The DAG stores
46 // psuedo instructions which are replaced by real AVR instructions by
47 // AVRExpandPseudoInsts.cpp.
49 // For example, the ADDW (add wide, as in add 16 bit values) instruction
50 // is defined as a pseudo instruction. In AVRExpandPseudoInsts.cpp,
51 // the instruction is then replaced by two add instructions - one for each byte.
52 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
53   : AVRInst16<outs, ins, asmstr, pattern>
55   let Pattern = pattern;
57   let isPseudo = 1;
58   let isCodeGenOnly = 1;
61 //===----------------------------------------------------------------------===//
62 // Register / register instruction: <|opcode|ffrd|dddd|rrrr|>
63 // opcode = 4 bits.
64 // f = secondary opcode = 2 bits
65 // d = destination = 5 bits
66 // r = source = 5 bits
67 // (Accepts all registers)
68 //===----------------------------------------------------------------------===//
69 class FRdRr<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr,
70             list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern>
72   bits<5> rd;
73   bits<5> rr;
75   let Inst{15-12} = opcode;
76   let Inst{11-10} = f;
77   let Inst{9} = rr{4};
78   let Inst{8-4} = rd;
79   let Inst{3-0} = rr{3-0};
82 class FTST<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr,
83             list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern>
85   bits<5> rd;
87   let Inst{15-12} = opcode;
88   let Inst{11-10} = f;
89   let Inst{9} = rd{4};
90   let Inst{8-4} = rd;
91   let Inst{3-0} = rd{3-0};
94 //===----------------------------------------------------------------------===//
95 // Instruction of the format `<mnemonic> Z, Rd`
96 // <|1001|001r|rrrr|0ttt>
97 //===----------------------------------------------------------------------===//
98 class FZRd<bits<3> t, dag outs, dag ins, string asmstr, list<dag> pattern>
99   : AVRInst16<outs, ins, asmstr, pattern>
101   bits<5> rd;
103   let Inst{15-12} = 0b1001;
105   let Inst{11-9} = 0b001;
106   let Inst{8} = rd{4};
108   let Inst{7-4} = rd{3-0};
110   let Inst{3} = 0;
111   let Inst{2-0} = t;
114 //===----------------------------------------------------------------------===//
115 // Register / immediate8 instruction: <|opcode|KKKK|dddd|KKKK|>
116 // opcode = 4 bits.
117 // K = constant data = 8 bits
118 // d = destination = 4 bits
119 // (Only accepts r16-r31)
120 //===----------------------------------------------------------------------===//
121 class FRdK<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
122   : AVRInst16<outs, ins, asmstr, pattern>
124   bits<4> rd;
125   bits<8> k;
127   let Inst{15-12} = opcode;
128   let Inst{11-8} = k{7-4};
129   let Inst{7-4} = rd{3-0};
130   let Inst{3-0} = k{3-0};
132   let isAsCheapAsAMove = 1;
135 //===----------------------------------------------------------------------===//
136 // Register instruction: <|opcode|fffd|dddd|ffff|>
137 // opcode = 4 bits.
138 // f = secondary opcode = 7 bits
139 // d = destination = 5 bits
140 // (Accepts all registers)
141 //===----------------------------------------------------------------------===//
142 class FRd<bits<4> opcode, bits<7> f, dag outs, dag ins, string asmstr,
143           list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern>
145   bits<5> d;
147   let Inst{15-12} = opcode;
148   let Inst{11-9} = f{6-4};
149   let Inst{8-4} = d;
150   let Inst{3-0} = f{3-0};
153 //===----------------------------------------------------------------------===//
154 // [STD/LDD] P+q, Rr special encoding: <|10q0|qqtr|rrrr|pqqq>
155 // t = type (1 for STD, 0 for LDD)
156 // q = displacement (6 bits)
157 // r = register (5 bits)
158 // p = pointer register (1 bit) [1 for Y, 0 for Z]
159 //===----------------------------------------------------------------------===//
160 class FSTDLDD<bit type, dag outs, dag ins, string asmstr, list<dag> pattern>
161   : AVRInst16<outs, ins, asmstr, pattern>
163   bits<7> memri;
164   bits<5> reg; // the GP register
166   let Inst{15-14} = 0b10;
167   let Inst{13} = memri{5};
168   let Inst{12} = 0;
170   let Inst{11-10} = memri{4-3};
171   let Inst{9} = type;
172   let Inst{8} = reg{4};
174   let Inst{7-4} = reg{3-0};
176   let Inst{3} = memri{6};
177   let Inst{2-0} = memri{2-0};
180 //===---------------------------------------------------------------------===//
181 // An ST/LD instruction.
182 // <|100i|00tr|rrrr|ppaa|>
183 // t = type (1 for store, 0 for load)
184 // a = regular/postinc/predec (reg = 0b00, postinc = 0b01, predec = 0b10)
185 // p = pointer register
186 // r = src/dst register
188 // Note that the bit labelled 'i' above does not follow a simple pattern,
189 // so there exists a post encoder method to set it manually.
190 //===---------------------------------------------------------------------===//
191 class FSTLD<bit type, bits<2> mode, dag outs, dag ins,
192             string asmstr, list<dag> pattern>
193   : AVRInst16<outs, ins, asmstr, pattern>
195   bits<2> ptrreg;
196   bits<5> reg;
198   let Inst{15-13} = 0b100;
199   // This bit varies depending on the arguments and the mode.
200   // We have a post encoder method to set this bit manually.
201   let Inst{12} = 0;
203   let Inst{11-10} = 0b00;
204   let Inst{9} = type;
205   let Inst{8} = reg{4};
207   let Inst{7-4} = reg{3-0};
209   let Inst{3-2} = ptrreg{1-0};
210   let Inst{1-0} = mode{1-0};
212   let PostEncoderMethod = "loadStorePostEncoder";
215 //===---------------------------------------------------------------------===//
216 // Special format for the LPM/ELPM instructions
217 // [E]LPM Rd, Z[+]
218 // <|1001|000d|dddd|01ep>
219 // d = destination register
220 // e = is elpm
221 // p = is postincrement
222 //===---------------------------------------------------------------------===//
223 class FLPMX<bit e, bit p, dag outs, dag ins, string asmstr, list<dag> pattern>
224   : AVRInst16<outs, ins, asmstr, pattern>
226    bits<5> reg;
228    let Inst{15-12} = 0b1001;
230    let Inst{11-9} = 0b000;
231    let Inst{8} = reg{4};
233    let Inst{7-4} = reg{3-0};
235    let Inst{3-2} = 0b01;
236    let Inst{1} = e;
237    let Inst{0} = p;
240 //===----------------------------------------------------------------------===//
241 // MOVWRdRr special encoding: <|0000|0001|dddd|rrrr|>
242 // d = destination = 4 bits
243 // r = source = 4 bits
244 // (Only accepts even registers)
245 //===----------------------------------------------------------------------===//
246 class FMOVWRdRr<dag outs, dag ins, string asmstr, list<dag> pattern>
247   : AVRInst16<outs, ins, asmstr, pattern>
249   bits<5> d;
250   bits<5> r;
252   let Inst{15-8} = 0b00000001;
253   let Inst{7-4} = d{4-1};
254   let Inst{3-0} = r{4-1};
257 //===----------------------------------------------------------------------===//
258 // MULSrr special encoding: <|0000|0010|dddd|rrrr|>
259 // d = multiplicand = 4 bits
260 // r = multiplier = 4 bits
261 // (Only accepts r16-r31)
262 //===----------------------------------------------------------------------===//
263 class FMUL2RdRr<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
264   : AVRInst16<outs, ins, asmstr, pattern>
266   bits<5> rd;              // accept 5 bits but only encode the lower 4
267   bits<5> rr;              // accept 5 bits but only encode the lower 4
269   let Inst{15-9} = 0b0000001;
270   let Inst{8} = f;
271   let Inst{7-4} = rd{3-0};
272   let Inst{3-0} = rr{3-0};
275 // Special encoding for the FMUL family of instructions.
277 // <0000|0011|fddd|frrr|>
279 // ff = 0b01 for FMUL
280 //      0b10 for FMULS
281 //      0b11 for FMULSU
283 // ddd = destination register
284 // rrr = source register
285 class FFMULRdRr<bits<2> f, dag outs, dag ins, string asmstr, list<dag> pattern>
286   : AVRInst16<outs, ins, asmstr, pattern>
288   bits<3> rd;
289   bits<3> rr;
291   let Inst{15-8} = 0b00000011;
292   let Inst{7} = f{1};
293   let Inst{6-4} = rd;
294   let Inst{3} = f{0};
295   let Inst{2-0} = rr;
299 //===----------------------------------------------------------------------===//
300 // Arithmetic word instructions (ADIW / SBIW): <|1001|011f|kkdd|kkkk|>
301 // f = secondary opcode = 1 bit
302 // k = constant data = 6 bits
303 // d = destination = 4 bits
304 // (Only accepts r25:24 r27:26 r29:28 r31:30)
305 //===----------------------------------------------------------------------===//
306 class FWRdK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
307   : AVRInst16<outs, ins, asmstr, pattern>
309   bits<5> dst;              // accept 5 bits but only encode bits 1 and 2
310   bits<6> k;
312   let Inst{15-9} = 0b1001011;
313   let Inst{8} = f;
314   let Inst{7-6} = k{5-4};
315   let Inst{5-4} = dst{2-1};
316   let Inst{3-0} = k{3-0};
319 //===----------------------------------------------------------------------===//
320 // In I/O instruction: <|1011|0AAd|dddd|AAAA|>
321 // A = I/O location address = 6 bits
322 // d = destination = 5 bits
323 // (Accepts all registers)
324 //===----------------------------------------------------------------------===//
325 class FIORdA<dag outs, dag ins, string asmstr, list<dag> pattern>
326   : AVRInst16<outs, ins, asmstr, pattern>
328   bits<5> d;
329   bits<6> A;
331   let Inst{15-11} = 0b10110;
332   let Inst{10-9} = A{5-4};
333   let Inst{8-4} = d;
334   let Inst{3-0} = A{3-0};
337 //===----------------------------------------------------------------------===//
338 // Out I/O instruction: <|1011|1AAr|rrrr|AAAA|>
339 // A = I/O location address = 6 bits
340 // d = destination = 5 bits
341 // (Accepts all registers)
342 //===----------------------------------------------------------------------===//
343 class FIOARr<dag outs, dag ins, string asmstr, list<dag> pattern>
344   : AVRInst16<outs, ins, asmstr, pattern>
346   bits<6> A;
347   bits<5> r;
349   let Inst{15-11} = 0b10111;
350   let Inst{10-9} = A{5-4};
351   let Inst{8-4} = r;
352   let Inst{3-0} = A{3-0};
355 //===----------------------------------------------------------------------===//
356 // I/O bit instruction.
357 // <|1001|10tt|AAAA|Abbb>
358 // t = type (1 for SBI, 0 for CBI)
359 // A = I/O location address (5 bits)
360 // b = bit number
361 //===----------------------------------------------------------------------===//
362 class FIOBIT<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
363   : AVRInst16<outs, ins, asmstr, pattern>
365   bits<5> A;
366   bits<3> b;
368   let Inst{15-12} = 0b1001;
370   let Inst{11-10} = 0b10;
371   let Inst{9-8} = t;
373   let Inst{7-4} = A{4-1};
375   let Inst{3} = A{0};
376   let Inst{2-0} = b{2-0};
379 //===----------------------------------------------------------------------===//
380 // BST/BLD instruction.
381 // <|1111|1ttd|dddd|0bbb>
382 // t = type (1 for BST, 0 for BLD)
383 // d = destination register
384 // b = bit
385 //===----------------------------------------------------------------------===//
386 class FRdB<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
387   : AVRInst16<outs, ins, asmstr, pattern>
389   bits<5> rd;
390   bits<3> b;
392   let Inst{15-12} = 0b1111;
394   let Inst{11} = 0b1;
395   let Inst{10-9} = t;
396   let Inst{8} = rd{4};
398   let Inst{7-4} = rd{3-0};
400   let Inst{3} = 0;
401   let Inst{2-0} = b;
404 // Special encoding for the `DES K` instruction.
406 // <|1001|0100|KKKK|1011>
408 // KKKK = 4 bit immediate
409 class FDES<dag outs, dag ins, string asmstr, list<dag> pattern>
410   : AVRInst16<outs, ins, asmstr, pattern>
412   bits<4> k;
414   let Inst{15-12} = 0b1001;
416   let Inst{11-8} = 0b0100;
418   let Inst{7-4} = k;
420   let Inst{3-0} = 0b1011;
423 //===----------------------------------------------------------------------===//
424 // Conditional Branching instructions: <|1111|0fkk|kkkk|ksss|>
425 // f = secondary opcode = 1 bit
426 // k = constant address = 7 bits
427 // s = bit in status register = 3 bits
428 //===----------------------------------------------------------------------===//
429 class FBRsk<bit f, bits<3> s, dag outs, dag ins, string asmstr, list<dag> pattern>
430   : AVRInst16<outs, ins, asmstr, pattern>
432   bits<7> k;
434   let Inst{15-11} = 0b11110;
435   let Inst{10} = f;
436   let Inst{9-3} = k;
437   let Inst{2-0} = s;
440 //===----------------------------------------------------------------------===//
441 // Special, opcode only instructions: <|opcode|>
442 //===----------------------------------------------------------------------===//
444 class F16<bits<16> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
445   : AVRInst16<outs, ins, asmstr, pattern>
447   let Inst = opcode;
450 class F32<bits<32> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
451   : AVRInst32<outs, ins, asmstr, pattern>
453   let Inst = opcode;
456 //===----------------------------------------------------------------------===//
457 // Branching instructions with immediate12: <|110f|kkkk|kkkk|kkkk|>
458 // f = secondary opcode = 1 bit
459 // k = constant address = 12 bits
460 //===----------------------------------------------------------------------===//
461 class FBRk<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
462   : AVRInst16<outs, ins, asmstr, pattern>
464   bits<12> k;
466   let Inst{15-13} = 0b110;
467   let Inst{12} = f;
468   let Inst{11-0} = k;
471 //===----------------------------------------------------------------------===//
472 // 32 bits branching instructions: <|1001|010k|kkkk|fffk|kkkk|kkkk|kkkk|kkkk|>
473 // f = secondary opcode = 3 bits
474 // k = constant address = 22 bits
475 //===----------------------------------------------------------------------===//
476 class F32BRk<bits<3> f, dag outs, dag ins, string asmstr, list<dag> pattern>
477   : AVRInst32<outs, ins, asmstr, pattern>
479   bits<22> k;
481   let Inst{31-25} = 0b1001010;
482   let Inst{24-20} = k{21-17};
483   let Inst{19-17} = f;
484   let Inst{16-0} = k{16-0};
487 //===----------------------------------------------------------------------===//
488 // 32 bits direct mem instructions: <|1001|00fd|dddd|0000|kkkk|kkkk|kkkk|kkkk|> 
489 // f = secondary opcode = 1 bit
490 // d = destination = 5 bits
491 // k = constant address = 16 bits
492 // (Accepts all registers)
493 //===----------------------------------------------------------------------===//
494 class F32DM<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
495   : AVRInst32<outs, ins, asmstr, pattern>
497   bits<5> rd;
498   bits<16> k;
500   let Inst{31-28} = 0b1001;
502   let Inst{27-26} = 0b00;
503   let Inst{25} = f;
504   let Inst{24} = rd{4};
506   let Inst{23-20} = rd{3-0};
508   let Inst{19-16} = 0b0000;
510   let Inst{15-0} = k;
513 // <|1001|0100|bfff|1000>
514 class FS<bit b, dag outs, dag ins, string asmstr, list<dag> pattern>
515   : AVRInst16<outs, ins, asmstr, pattern>
517   bits<3> s;
519   let Inst{15-12} = 0b1001;
521   let Inst{11-8} = 0b0100;
523   let Inst{7} = b;
524   let Inst{6-4} = s;
526   let Inst{3-0} = 0b1000;
529 // Set/clr bit in status flag instructions/
530 // <BRBS|BRBC> s, k
531 // ---------------------
532 // <|1111|0fkk|kkkk|ksss>
533 class FSK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
534   : AVRInst16<outs, ins, asmstr, pattern>
536   bits<7> k;
537   bits<3> s;
539   let Inst{15-12} = 0b1111;
541   let Inst{11} = 0;
542   let Inst{10} = f;
543   let Inst{9-8} = k{6-5};
545   let Inst{7-4} = k{4-1};
547   let Inst{3} = k{0};
548   let Inst{2-0} = s;
551 class ExtensionPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
552   : Pseudo<outs, ins, asmstr, pattern>
554   let Defs = [SREG];
557 class StorePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
558   : Pseudo<outs, ins, asmstr, pattern>
560   let Defs = [SP];
563 class SelectPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
564   : Pseudo<outs, ins, asmstr, pattern>
566   let usesCustomInserter = 1;
568   let Uses = [SREG];
571 class ShiftPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
572   : Pseudo<outs, ins, asmstr, pattern>
574   let usesCustomInserter = 1;
576   let Defs = [SREG];