Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / Target / M68k / M68kInstrFormats.td
blob38d3127ac6a6da6c04dae60c8281050157e96598
1 //===-- M68kInstrFormats.td - M68k Instruction Formats -----*- tablegen -*-===//
2 //                     The LLVM Compiler Infrastructure
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 /// \file
9 /// This file contains M68k instruction formats.
10 ///
11 /// Since M68k has quite a lot memory addressing modes there are more
12 /// instruction prefixes than just i, r and m:
13 /// TSF  Since     Form                     Letter  Description
14 ///  00   M68000    Dn or An                 r       any register
15 ///  01   M68000    Dn                       d       data register direct
16 ///  02   M68000    An                       a       address register direct
17 ///  03   M68000    (An)                     j       address register indirect
18 ///  04   M68000    (An)+                    o       address register indirect with postincrement
19 ///  05   M68000    -(An)                    e       address register indirect with predecrement
20 ///  06   M68000    (i,An)                   p       address register indirect with displacement
21 ///  10   M68000    (i,An,Xn.L)              f       address register indirect with index and scale = 1
22 ///  07   M68000    (i,An,Xn.W)              F       address register indirect with index and scale = 1
23 ///  12   M68020    (i,An,Xn.L,SCALE)        g       address register indirect with index
24 ///  11   M68020    (i,An,Xn.W,SCALE)        G       address register indirect with index
25 ///  14   M68020    ([bd,An],Xn.L,SCALE,od)  u       memory indirect postindexed mode
26 ///  13   M68020    ([bd,An],Xn.W,SCALE,od)  U       memory indirect postindexed mode
27 ///  16   M68020    ([bd,An,Xn.L,SCALE],od)  v       memory indirect preindexed mode
28 ///  15   M68020    ([bd,An,Xn.W,SCALE],od)  V       memory indirect preindexed mode
29 ///  20   M68000    abs.L                    b       absolute long address
30 ///  17   M68000    abs.W                    B       absolute short address
31 ///  21   M68000    (i,PC)                   q       program counter with displacement
32 ///  23   M68000    (i,PC,Xn.L)              k       program counter with index and scale = 1
33 ///  22   M68000    (i,PC,Xn.W)              K       program counter with index and scale = 1
34 ///  25   M68020    (i,PC,Xn.L,SCALE)        l       program counter with index
35 ///  24   M68020    (i,PC,Xn.W,SCALE)        L       program counter with index
36 ///  27   M68020    ([bd,PC],Xn.L,SCALE,od)  x       program counter memory indirect postindexed mode
37 ///  26   M68020    ([bd,PC],Xn.W,SCALE,od)  X       program counter memory indirect postindexed mode
38 ///  31   M68020    ([bd,PC,Xn.L,SCALE],od)  y       program counter memory indirect preindexed mode
39 ///  30   M68020    ([bd,PC,Xn.W,SCALE],od)  Y       program counter memory indirect preindexed mode
40 ///  32   M68000    #immediate               i       immediate data
41 ///
42 /// NOTE that long form is always lowercase, word variants are capitalized
43 ///
44 /// Operand can be qualified with size where appropriate to force a particular
45 /// instruction encoding, e.g.:
46 ///    (i8,An,Xn.W)             f8      1 extension word
47 ///    (i16,An,Xn.W)            f16     2 extension words
48 ///    (i32,An,Xn.W)            f32     3 extension words
49 ///
50 /// Form without size qualifier will adapt to operand size automatically, e.g.:
51 ///    (i,An,Xn.W)              f       1, 2 or 3 extension words
52 ///
53 /// Some forms already imply a particular size of their operands, e.g.:
54 ///    (i,An)                   p       1 extension word and i is 16bit
55 ///
56 /// Operand order follows x86 Intel order(destination before source), e.g.:
57 ///    MOV8df                   MOVE (4,A0,D0), D1
58 ///
59 /// Number after instruction mnemonics determines the size of the data
60 ///
61 //===----------------------------------------------------------------------===//
63 /// ??? Is it possible to use this stuff for disassembling?
64 /// NOTE 1: In case of conditional beads(DA, DAReg), cond part is able to
65 /// consume any bit, though a more general instructions must be chosen, e.g.
66 /// d -> r, a -> r
68 //===----------------------------------------------------------------------===//
69 // Encoding primitives
70 //===----------------------------------------------------------------------===//
72 class MxEncMemOp {
73   dag EA = (ascend);
74   dag Supplement = (ascend);
77 class MxEncBriefExt<string reg_opnd, string disp_opnd,
78                     bit size_w_l = false, int scale = 1,
79                     string disp_encoder = ""> {
80   dag Value = (descend
81     // D/A + REGISTER
82     (operand "$"#reg_opnd, 4),
83     // W/L
84     size_w_l,
85     // SCALE
86     !cond(
87       !eq(scale, 1) : 0b00,
88       !eq(scale, 2) : 0b01,
89       !eq(scale, 4) : 0b10,
90       !eq(scale, 8) : 0b11
91     ),
92     0b0,
93     // Displacement
94     (operand "$"#disp_opnd, 8, (encoder disp_encoder))
95   );
98 class MxEncAddrMode_d<string reg_opnd> : MxEncMemOp {
99   let EA = (descend /*MODE*/0b000,
100                     /*REGISTER*/(operand "$"#reg_opnd, 3));
103 class MxEncAddrMode_a<string reg_opnd> : MxEncMemOp {
104   let EA = (descend /*MODE*/0b001,
105                     /*REGISTER*/(operand "$"#reg_opnd, 3));
108 class MxEncAddrMode_r<string reg_opnd> : MxEncMemOp {
109   let EA = (descend /*MODE without the last bit*/0b00,
110                     /*REGISTER with D/A bit*/(operand "$"#reg_opnd, 4));
113 class MxEncAddrMode_k<string opnd_name> : MxEncMemOp {
114   let EA = (descend /*MODE*/0b111,
115                     /*REGISTER*/0b011);
117   let Supplement = MxEncBriefExt<opnd_name#".index", opnd_name#".disp",
118                                  /*W/L*/true, /*SCALE*/1,
119                                  "encodePCRelImm<8>">.Value;
122 class MxEncAddrMode_q<string opnd_name> : MxEncMemOp {
123   let EA = (descend /*MODE*/0b111,
124                      /*REGISTER*/0b010);
126   // 16-bit Displacement
127   let Supplement = (operand "$"#opnd_name, 16,
128                             (encoder "encodePCRelImm<16>"));
131 class MxEncAddrMode_p<string opnd_name> : MxEncMemOp {
132   let EA = (descend /*MODE*/0b101,
133                      /*REGISTER*/(operand "$"#opnd_name#".reg", 3));
135   // 16-bit Displacement
136   let Supplement = (operand "$"#opnd_name#".disp", 16,
137                             (encoder "encodeRelocImm<16>"));
140 class MxEncAddrMode_f<string opnd_name> : MxEncMemOp {
141   let EA = (descend /*MODE*/0b110,
142                      /*REGISTER*/(operand "$"#opnd_name#".reg", 3));
144   let Supplement = MxEncBriefExt<opnd_name#".index", opnd_name#".disp",
145                                  /*W/L*/true, /*SCALE*/1,
146                                  "encodeRelocImm<8>">.Value;
149 class MxEncAddrMode_j<string reg_opnd> : MxEncMemOp {
150   let EA = (descend /*MODE*/0b010,
151                      /*REGISTER*/(operand "$"#reg_opnd, 3));
154 class MxEncAddrMode_i<string opnd_name, int size> : MxEncMemOp {
155   let EA = (descend /*MODE*/0b111,
156                      /*REGISTER*/0b100);
158   // Immediate
159   let Supplement =
160     !cond(
161       !eq(size, 8)  : (descend 0b00000000, (operand "$"#opnd_name, 8,
162                            (encoder "encodeRelocImm<8>"))),
163       !eq(size, 16) : (operand "$"#opnd_name, 16,
164                            (encoder "encodeRelocImm<16>")),
165       !eq(size, 32) : (operand "$"#opnd_name, 32,
166                            (encoder "encodeRelocImm<32>"),
167                            (decoder "DecodeImm32"))
168     );
171 // abs.W -> size_w_l = false
172 // abs.L -> size_w_l = true
173 class MxEncAddrMode_abs<string opnd_name, bit size_w_l = false> : MxEncMemOp {
174   let EA = (descend /*MODE*/0b111,
175                     // Wrap the REGISTER part in another dag to make sure
176                     // the dag assigned to EA only has two arguments. Such
177                     // that it's easier for MOV instructions to reverse
178                     // on its destination part.
179                     /*REGISTER*/(descend 0b00, size_w_l));
181   // Absolute address
182   let Supplement = !if(size_w_l,
183     // abs.L
184     (operand "$"#opnd_name, 32, (encoder "encodeRelocImm<32>"),
185                                 (decoder "DecodeImm32")),
186     // abs.W
187     (operand "$"#opnd_name, 16, (encoder "encodeRelocImm<16>"))
188   );
191 class MxEncAddrMode_o<string reg_opnd> : MxEncMemOp {
192   let EA = (descend /*MODE*/0b011,
193                     /*REGISTER*/(operand "$"#reg_opnd, 3));
196 class MxEncAddrMode_e<string reg_opnd> : MxEncMemOp {
197   let EA = (descend /*MODE*/0b100,
198                     /*REGISTER*/(operand "$"#reg_opnd, 3));
201 class MxEncSize<bits<2> value> {
202   bits<2> Value = value;
204 def MxEncSize8  : MxEncSize<0b00>;
205 def MxEncSize16 : MxEncSize<0b01>;
206 def MxEncSize32 : MxEncSize<0b10>;
207 def MxEncSize64 : MxEncSize<0b11>;
209 // M68k INSTRUCTION. Most instructions specify the location of an operand by
210 // using the effective address field in the operation word. The effective address
211 // is composed of two 3-bit fields: the mode field and the register field. The
212 // value in the mode field selects the different address modes. The register
213 // field contains the number of a register.  The effective address field may
214 // require additional information to fully specify the operand. This additional
215 // information, called the effective address extension, is contained in the
216 // following word or words and is considered part of the instruction. The
217 // effective address modes are grouped into three categories: register direct,
218 // memory addressing, and special.
219 class MxInst<dag outs, dag ins,
220              string asmStr = "",
221              list<dag> pattern = [],
222              InstrItinClass itin = NoItinerary>
223     : Instruction {
224   let Namespace      = "M68k";
225   let OutOperandList = outs;
226   let InOperandList  = ins;
227   let AsmString      = asmStr;
228   let Pattern        = pattern;
229   let Itinerary      = itin;
231   dag Inst = (ascend);
233   // Number of bytes
234   let Size = 0;
236   let UseLogicalOperandMappings = 1;
239 // M68k PSEUDO INSTRUCTION
240 class MxPseudo<dag outs, dag ins, list<dag> pattern = []>
241     : MxInst<outs, ins, "; error: this should not be emitted", pattern> {
242   let isPseudo = 1;