Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / AVR / AVRInstrFormats.td
blob06d14a2fb47fecaba6c174c618b845dccb3c8c06
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>
15     : 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> {
29   field bits<16> Inst;
31   let Size = 2;
34 /// a 32-bit AVR instruction.
35 class AVRInst32<dag outs, dag ins, string asmstr, list<dag> pattern>
36     : AVRInst<outs, ins, asmstr, pattern> {
37   field bits<32> Inst;
39   let Size = 4;
42 // A class for pseudo instructions.
43 // Pseudo instructions are not real AVR instructions. The DAG stores
44 // pseudo instructions which are replaced by real AVR instructions by
45 // AVRExpandPseudoInsts.cpp.
47 // For example, the ADDW (add wide, as in add 16 bit values) instruction
48 // is defined as a pseudo instruction. In AVRExpandPseudoInsts.cpp,
49 // the instruction is then replaced by two add instructions - one for each byte.
50 class Pseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
51     : AVRInst16<outs, ins, asmstr, pattern> {
52   let Pattern = pattern;
54   let isPseudo = 1;
55   let isCodeGenOnly = 1;
58 //===----------------------------------------------------------------------===//
59 // Register / register instruction: <|opcode|ffrd|dddd|rrrr|>
60 // opcode = 4 bits.
61 // f = secondary opcode = 2 bits
62 // d = destination = 5 bits
63 // r = source = 5 bits
64 // (Accepts all registers)
65 //===----------------------------------------------------------------------===//
66 class FRdRr<bits<4> opcode, bits<2> f, dag outs, dag ins, string asmstr,
67             list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
68   bits<5> rd;
69   bits<5> rr;
71   let Inst{15 - 12} = opcode;
72   let Inst{11 - 10} = f;
73   let Inst{9} = rr{4};
74   let Inst{8 - 4} = rd;
75   let Inst{3 - 0} = rr{3 - 0};
78 //===----------------------------------------------------------------------===//
79 // Instruction of the format `<mnemonic> Z, Rd`
80 // <|1001|001r|rrrr|0ttt>
81 //===----------------------------------------------------------------------===//
82 class FZRd<bits<3> t, dag outs, dag ins, string asmstr, list<dag> pattern>
83     : AVRInst16<outs, ins, asmstr, pattern> {
84   bits<5> rd;
86   let Inst{15 - 12} = 0b1001;
88   let Inst{11 - 9} = 0b001;
89   let Inst{8} = rd{4};
91   let Inst{7 - 4} = rd{3 - 0};
93   let Inst{3} = 0;
94   let Inst{2 - 0} = t;
97 //===----------------------------------------------------------------------===//
98 // Register / immediate8 instruction: <|opcode|KKKK|dddd|KKKK|>
99 // opcode = 4 bits.
100 // K = constant data = 8 bits
101 // d = destination = 4 bits
102 // (Only accepts r16-r31)
103 //===----------------------------------------------------------------------===//
104 class FRdK<bits<4> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
105     : AVRInst16<outs, ins, asmstr, pattern> {
106   bits<4> rd;
107   bits<8> k;
109   let Inst{15 - 12} = opcode;
110   let Inst{11 - 8} = k{7 - 4};
111   let Inst{7 - 4} = rd{3 - 0};
112   let Inst{3 - 0} = k{3 - 0};
114   let isAsCheapAsAMove = 1;
117 //===----------------------------------------------------------------------===//
118 // Register instruction: <|opcode|fffd|dddd|ffff|>
119 // opcode = 4 bits.
120 // f = secondary opcode = 7 bits
121 // d = destination = 5 bits
122 // (Accepts all registers)
123 //===----------------------------------------------------------------------===//
124 class FRd<bits<4> opcode, bits<7> f, dag outs, dag ins, string asmstr,
125           list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
126   bits<5> rd;
128   let Inst{15 - 12} = opcode;
129   let Inst{11 - 9} = f{6 - 4};
130   let Inst{8 - 4} = rd;
131   let Inst{3 - 0} = f{3 - 0};
133   let DecoderMethod = "decodeFRd";
136 //===----------------------------------------------------------------------===//
137 // [STD/LDD] P+q, Rr special encoding: <|10q0|qqtr|rrrr|pqqq>
138 // t = type (1 for STD, 0 for LDD)
139 // q = displacement (6 bits)
140 // r = register (5 bits)
141 // p = pointer register (1 bit) [1 for Y, 0 for Z]
142 //===----------------------------------------------------------------------===//
143 class FSTDLDD<bit type, dag outs, dag ins, string asmstr, list<dag> pattern>
144     : AVRInst16<outs, ins, asmstr, pattern> {
145   bits<7> memri;
146   bits<5> reg; // the GP register
148   let Inst{15 - 14} = 0b10;
149   let Inst{13} = memri{5};
150   let Inst{12} = 0;
152   let Inst{11 - 10} = memri{4 - 3};
153   let Inst{9} = type;
154   let Inst{8} = reg{4};
156   let Inst{7 - 4} = reg{3 - 0};
158   let Inst{3} = memri{6};
159   let Inst{2 - 0} = memri{2 - 0};
162 //===---------------------------------------------------------------------===//
163 // An ST/LD instruction.
164 // <|100i|00tr|rrrr|ppaa|>
165 // t = type (1 for store, 0 for load)
166 // a = regular/postinc/predec (reg = 0b00, postinc = 0b01, predec = 0b10)
167 // p = pointer register
168 // r = src/dst register
170 // Note that the bit labelled 'i' above does not follow a simple pattern,
171 // so there exists a post encoder method to set it manually. Also a specified
172 // decoder method is needed.
173 //===---------------------------------------------------------------------===//
174 class FSTLD<bit type, bits<2> mode, dag outs, dag ins, string asmstr,
175             list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
176   bits<2> ptrreg;
177   bits<5> reg;
179   let Inst{15 - 13} = 0b100;
180   // This bit varies depending on the arguments and the mode.
181   // We have a post encoder method to set this bit manually.
182   let Inst{12} = 0;
184   let Inst{11 - 10} = 0b00;
185   let Inst{9} = type;
186   let Inst{8} = reg{4};
188   let Inst{7 - 4} = reg{3 - 0};
190   let Inst{3 - 2} = ptrreg{1 - 0};
191   let Inst{1 - 0} = mode{1 - 0};
193   let DecoderMethod = "decodeLoadStore";
194   let PostEncoderMethod = "loadStorePostEncoder";
197 //===---------------------------------------------------------------------===//
198 // Special format for the LPM/ELPM instructions
199 // [E]LPM Rd, Z[+]
200 // <|1001|000d|dddd|01ep>
201 // d = destination register
202 // e = is elpm
203 // p = is postincrement
204 //===---------------------------------------------------------------------===//
205 class FLPMX<bit e, bit p, dag outs, dag ins, string asmstr, list<dag> pattern>
206     : AVRInst16<outs, ins, asmstr, pattern> {
207   bits<5> rd;
209   let Inst{15 - 12} = 0b1001;
211   let Inst{11 - 9} = 0b000;
212   let Inst{8} = rd{4};
214   let Inst{7 - 4} = rd{3 - 0};
216   let Inst{3 - 2} = 0b01;
217   let Inst{1} = e;
218   let Inst{0} = p;
220   let DecoderMethod = "decodeFLPMX";
223 //===----------------------------------------------------------------------===//
224 // MOVWRdRr special encoding: <|0000|0001|dddd|rrrr|>
225 // d = destination = 4 bits
226 // r = source = 4 bits
227 // (Only accepts even registers)
228 //===----------------------------------------------------------------------===//
229 class FMOVWRdRr<dag outs, dag ins, string asmstr, list<dag> pattern>
230     : AVRInst16<outs, ins, asmstr, pattern> {
231   bits<5> rd;
232   bits<5> rr;
234   let Inst{15 - 8} = 0b00000001;
235   let Inst{7 - 4} = rd{4 - 1};
236   let Inst{3 - 0} = rr{4 - 1};
238   let DecoderMethod = "decodeFMOVWRdRr";
241 //===----------------------------------------------------------------------===//
242 // MULSrr special encoding: <|0000|0010|dddd|rrrr|>
243 // d = multiplicand = 4 bits
244 // r = multiplier = 4 bits
245 // (Only accepts r16-r31)
246 //===----------------------------------------------------------------------===//
247 class FMUL2RdRr<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
248     : AVRInst16<outs, ins, asmstr, pattern> {
249   bits<5> rd; // accept 5 bits but only encode the lower 4
250   bits<5> rr; // accept 5 bits but only encode the lower 4
252   let Inst{15 - 9} = 0b0000001;
253   let Inst{8} = f;
254   let Inst{7 - 4} = rd{3 - 0};
255   let Inst{3 - 0} = rr{3 - 0};
257   let DecoderMethod = "decodeFMUL2RdRr";
260 // Special encoding for the FMUL family of instructions.
262 // <0000|0011|fddd|frrr|>
264 // ff = 0b01 for FMUL
265 //      0b10 for FMULS
266 //      0b11 for FMULSU
268 // ddd = destination register
269 // rrr = source register
270 class FFMULRdRr<bits<2> f, dag outs, dag ins, string asmstr, list<dag> pattern>
271     : AVRInst16<outs, ins, asmstr, pattern> {
272   bits<3> rd;
273   bits<3> rr;
275   let Inst{15 - 8} = 0b00000011;
276   let Inst{7} = f{1};
277   let Inst{6 - 4} = rd;
278   let Inst{3} = f{0};
279   let Inst{2 - 0} = rr;
281   let DecoderMethod = "decodeFFMULRdRr";
284 //===----------------------------------------------------------------------===//
285 // Arithmetic word instructions (ADIW / SBIW): <|1001|011f|kkdd|kkkk|>
286 // f = secondary opcode = 1 bit
287 // k = constant data = 6 bits
288 // d = destination = 2 bits
289 // (Only accepts r25:24 r27:26 r29:28 r31:30)
290 //===----------------------------------------------------------------------===//
291 class FWRdK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
292     : AVRInst16<outs, ins, asmstr, pattern> {
293   bits<5> rd; // accept 5 bits but only encode bits 1 and 2
294   bits<6> k;
296   let Inst{15 - 9} = 0b1001011;
297   let Inst{8} = f;
298   let Inst{7 - 6} = k{5 - 4};
299   let Inst{5 - 4} = rd{2 - 1};
300   let Inst{3 - 0} = k{3 - 0};
302   let DecoderMethod = "decodeFWRdK";
305 //===----------------------------------------------------------------------===//
306 // In I/O instruction: <|1011|0AAd|dddd|AAAA|>
307 // A = I/O location address = 6 bits
308 // d = destination = 5 bits
309 // (Accepts all registers)
310 //===----------------------------------------------------------------------===//
311 class FIORdA<dag outs, dag ins, string asmstr, list<dag> pattern>
312     : AVRInst16<outs, ins, asmstr, pattern> {
313   bits<5> rd;
314   bits<6> A;
316   let Inst{15 - 11} = 0b10110;
317   let Inst{10 - 9} = A{5 - 4};
318   let Inst{8 - 4} = rd;
319   let Inst{3 - 0} = A{3 - 0};
321   let DecoderMethod = "decodeFIORdA";
324 //===----------------------------------------------------------------------===//
325 // Out I/O instruction: <|1011|1AAr|rrrr|AAAA|>
326 // A = I/O location address = 6 bits
327 // d = destination = 5 bits
328 // (Accepts all registers)
329 //===----------------------------------------------------------------------===//
330 class FIOARr<dag outs, dag ins, string asmstr, list<dag> pattern>
331     : AVRInst16<outs, ins, asmstr, pattern> {
332   bits<6> A;
333   bits<5> rr;
335   let Inst{15 - 11} = 0b10111;
336   let Inst{10 - 9} = A{5 - 4};
337   let Inst{8 - 4} = rr;
338   let Inst{3 - 0} = A{3 - 0};
340   let DecoderMethod = "decodeFIOARr";
343 //===----------------------------------------------------------------------===//
344 // I/O bit instruction.
345 // <|1001|10tt|AAAA|Abbb>
346 // t = type (1 for SBI, 0 for CBI)
347 // A = I/O location address (5 bits)
348 // b = bit number
349 //===----------------------------------------------------------------------===//
350 class FIOBIT<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
351     : AVRInst16<outs, ins, asmstr, pattern> {
352   bits<5> addr;
353   bits<3> b;
355   let Inst{15 - 12} = 0b1001;
357   let Inst{11 - 10} = 0b10;
358   let Inst{9 - 8} = t;
360   let Inst{7 - 4} = addr{4 - 1};
362   let Inst{3} = addr{0};
363   let Inst{2 - 0} = b{2 - 0};
365   let DecoderMethod = "decodeFIOBIT";
368 //===----------------------------------------------------------------------===//
369 // BST/BLD instruction.
370 // <|1111|1ttd|dddd|0bbb>
371 // t = type (1 for BST, 0 for BLD)
372 // d = destination register
373 // b = bit
374 //===----------------------------------------------------------------------===//
375 class FRdB<bits<2> t, dag outs, dag ins, string asmstr, list<dag> pattern>
376     : AVRInst16<outs, ins, asmstr, pattern> {
377   bits<5> rd;
378   bits<3> b;
380   let Inst{15 - 12} = 0b1111;
382   let Inst{11} = 0b1;
383   let Inst{10 - 9} = t;
384   let Inst{8} = rd{4};
386   let Inst{7 - 4} = rd{3 - 0};
388   let Inst{3} = 0;
389   let Inst{2 - 0} = b;
392 // Special encoding for the `DES K` instruction.
394 // <|1001|0100|KKKK|1011>
396 // KKKK = 4 bit immediate
397 class FDES<dag outs, dag ins, string asmstr, list<dag> pattern>
398     : AVRInst16<outs, ins, asmstr, pattern> {
399   bits<4> k;
401   let Inst{15 - 12} = 0b1001;
403   let Inst{11 - 8} = 0b0100;
405   let Inst{7 - 4} = k;
407   let Inst{3 - 0} = 0b1011;
410 //===----------------------------------------------------------------------===//
411 // Conditional Branching instructions: <|1111|0fkk|kkkk|ksss|>
412 // f = secondary opcode = 1 bit
413 // k = constant address = 7 bits
414 // s = bit in status register = 3 bits
415 //===----------------------------------------------------------------------===//
416 class FBRsk<bit f, bits<3> s, dag outs, dag ins, string asmstr,
417             list<dag> pattern> : AVRInst16<outs, ins, asmstr, pattern> {
418   bits<7> k;
420   let Inst{15 - 11} = 0b11110;
421   let Inst{10} = f;
422   let Inst{9 - 3} = k;
423   let Inst{2 - 0} = s;
425   let DecoderMethod = "decodeCondBranch";
428 //===----------------------------------------------------------------------===//
429 // Special, opcode only instructions: <|opcode|>
430 //===----------------------------------------------------------------------===//
432 class F16<bits<16> opcode, dag outs, dag ins, string asmstr, list<dag> pattern>
433     : AVRInst16<outs, ins, asmstr, pattern> {
434   let Inst = opcode;
437 //===----------------------------------------------------------------------===//
438 // Branching instructions with immediate12: <|110f|kkkk|kkkk|kkkk|>
439 // f = secondary opcode = 1 bit
440 // k = constant address = 12 bits
441 //===----------------------------------------------------------------------===//
442 class FBRk<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
443     : AVRInst16<outs, ins, asmstr, pattern> {
444   bits<12> k;
446   let Inst{15 - 13} = 0b110;
447   let Inst{12} = f;
448   let Inst{11 - 0} = k;
450   let DecoderMethod = "decodeFBRk";
453 //===----------------------------------------------------------------------===//
454 // 32 bits branching instructions: <|1001|010k|kkkk|fffk|kkkk|kkkk|kkkk|kkkk|>
455 // f = secondary opcode = 3 bits
456 // k = constant address = 22 bits
457 //===----------------------------------------------------------------------===//
458 class F32BRk<bits<3> f, dag outs, dag ins, string asmstr, list<dag> pattern>
459     : AVRInst32<outs, ins, asmstr, pattern> {
460   bits<22> k;
462   let Inst{31 - 25} = 0b1001010;
463   let Inst{24 - 20} = k{21 - 17};
464   let Inst{19 - 17} = f;
465   let Inst{16 - 0} = k{16 - 0};
468 //===----------------------------------------------------------------------===//
469 // 32 bits direct mem instructions: <|1001|00fd|dddd|0000|kkkk|kkkk|kkkk|kkkk|>
470 // f = secondary opcode = 1 bit
471 // d = destination = 5 bits
472 // k = constant address = 16 bits
473 // (Accepts all registers)
474 //===----------------------------------------------------------------------===//
475 class F32DM<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
476     : AVRInst32<outs, ins, asmstr, pattern> {
477   bits<5> rd;
478   bits<16> k;
480   let Inst{31 - 28} = 0b1001;
482   let Inst{27 - 26} = 0b00;
483   let Inst{25} = f;
484   let Inst{24} = rd{4};
486   let Inst{23 - 20} = rd{3 - 0};
488   let Inst{19 - 16} = 0b0000;
490   let Inst{15 - 0} = k;
493 //===---------------------------------------------------------------------===//
494 // Special format for the LDS/STS instructions on AVRTiny.
495 // <|1010|ikkk|dddd|kkkk>
496 // d = R16 ~ R31
497 // i = 0 - lds, 1 - sts
498 // k = 7-bit data space address
499 //===---------------------------------------------------------------------===//
500 class FLDSSTSTINY<bit i, dag outs, dag ins, string asmstr, list<dag> pattern>
501     : AVRInst16<outs, ins, asmstr, pattern> {
502   bits<5> rd;
503   bits<7> k;
505   let Inst{15 - 12} = 0b1010;
507   let Inst{11} = i;
509   let Inst{10 - 8} = k{6 - 4};
510   let Inst{7 - 4} = rd{3 - 0};
511   let Inst{3 - 0} = k{3 - 0};
513   let DecoderNamespace = "AVRTiny";
516 // <|1001|0100|bfff|1000>
517 class FS<bit b, dag outs, dag ins, string asmstr, list<dag> pattern>
518     : AVRInst16<outs, ins, asmstr, pattern> {
519   bits<3> s;
521   let Inst{15 - 12} = 0b1001;
523   let Inst{11 - 8} = 0b0100;
525   let Inst{7} = b;
526   let Inst{6 - 4} = s;
528   let Inst{3 - 0} = 0b1000;
531 // Set/clr bit in status flag instructions/
532 // <BRBS|BRBC> s, k
533 // ---------------------
534 // <|1111|0fkk|kkkk|ksss>
535 class FSK<bit f, dag outs, dag ins, string asmstr, list<dag> pattern>
536     : AVRInst16<outs, ins, asmstr, pattern> {
537   bits<7> k;
538   bits<3> s;
540   let Inst{15 - 12} = 0b1111;
542   let Inst{11} = 0;
543   let Inst{10} = f;
544   let Inst{9 - 8} = k{6 - 5};
546   let Inst{7 - 4} = k{4 - 1};
548   let Inst{3} = k{0};
549   let Inst{2 - 0} = s;
551   let DecoderMethod = "decodeCondBranch";
554 class ExtensionPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
555     : Pseudo<outs, ins, asmstr, pattern> {
556   let Defs = [SREG];
559 class StorePseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
560     : Pseudo<outs, ins, asmstr, pattern> {
561   let Defs = [SP];
564 class SelectPseudo<dag outs, dag ins, string asmstr, list<dag> pattern>
565     : 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> {
573   let usesCustomInserter = 1;
575   let Defs = [SREG];