[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / M68k / M68kInstrControl.td
blob70847472686125845d713a04896c26ebaff422c5
1 //===-- M68kInstrControl.td - Control Flow Instructions --*- 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 /// \file
10 /// This file describes the M68k jump, return, call, and related instructions.
11 /// Here is the current status of the file:
12 ///
13 ///  Machine:
14 ///
15 ///       BRA   [x]     BSR  [ ]     Bcc [ ]     DBcc [ ]     FBcc [ ]
16 ///       FDBcc [ ]     FNOP [ ]     FPn [ ]     FScc [ ]     FTST [ ]
17 ///       JMP   [~]     JSR  [x]     NOP [x]     RTD  [!]     RTR  [ ]
18 ///       RTS   [x]     Scc  [x]     TST [ ]
19 ///
20 ///  Pseudo:
21 ///
22 ///          RET [x]
23 ///    TCRETURNj [x]   TCRETURNq [x]
24 ///     TAILJMPj [x]    TAILJMPq [x]
25 ///
26 ///  Map:
27 ///
28 ///   [ ] - was not touched at all
29 ///   [!] - requires extarnal stuff implemented
30 ///   [~] - in progress but usable
31 ///   [x] - done
32 ///
33 ///
34 ///                                   NOTE
35 ///      Though branch and jump instructions are using memory operands they
36 ///      DO NOT read the jump address from memory, they just calculate EA
37 ///      and jump there.
38 ///
39 //===----------------------------------------------------------------------===//
41 //===----------------------------------------------------------------------===//
42 // NOP
43 //===----------------------------------------------------------------------===//
45 let hasSideEffects = 0 in {
46   def NOP : MxInst<(outs), (ins), "nop", [], MxEncFixed<0x4E71>>;
50 //===----------------------------------------------------------------------===//
51 // Conditions
52 //===----------------------------------------------------------------------===//
54 /// CC—Carry clear      GE—Greater than or equal
55 /// LS—Lower or same    PL—Plus
56 /// CS—Carry set        GT—Greater than
57 /// LT—Less than        T—Always true*
58 /// EQ—Equal            HI—Higher
59 /// MI—Minus            VC—Overflow clear
60 /// F—Never true*       LE—Less than or equal
61 /// NE—Not equal        VS—Overflow set
62 ///
63 /// *Not applicable to the Bcc instructions.
64 def MxCCt  : MxBead4Bits<0b0000>;
65 def MxCCf  : MxBead4Bits<0b0001>;
66 def MxCChi : MxBead4Bits<0b0010>;
67 def MxCCls : MxBead4Bits<0b0011>;
68 def MxCCcc : MxBead4Bits<0b0100>;
69 def MxCCcs : MxBead4Bits<0b0101>;
70 def MxCCne : MxBead4Bits<0b0110>;
71 def MxCCeq : MxBead4Bits<0b0111>;
72 def MxCCvc : MxBead4Bits<0b1000>;
73 def MxCCvs : MxBead4Bits<0b1001>;
74 def MxCCpl : MxBead4Bits<0b1010>;
75 def MxCCmi : MxBead4Bits<0b1011>;
76 def MxCCge : MxBead4Bits<0b1100>;
77 def MxCClt : MxBead4Bits<0b1101>;
78 def MxCCgt : MxBead4Bits<0b1110>;
79 def MxCCle : MxBead4Bits<0b1111>;
81 /// --------------------------------+---------+---------
82 ///  F  E  D  C | B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
83 /// --------------------------------+---------+---------
84 ///  0  1  0  1 | CONDITION  | 1  1 |   MODE  |   REG
85 /// ----------------------------------------------------
86 class MxSccEncoding<MxEncEA EA, MxEncExt EXT, MxBead4Bits CC>
87     : MxEncoding<EA.Reg, EA.DA, EA.Mode, MxBead2Bits<0b11>, CC, MxBead4Bits<0b0101>,
88                  EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>;
90 let Uses = [CCR] in {
91 class MxSccR<string CC>
92     : MxInst<(outs MxDRD8:$dst), (ins), "s"#CC#"\t$dst",
93              [(set i8:$dst, (MxSetCC !cast<PatLeaf>("MxCOND"#CC), CCR))],
94              MxSccEncoding<MxEncEAd_0, MxExtEmpty,
95                            !cast<MxBead4Bits>("MxCC"#CC)>>;
97 class MxSccM<string CC, MxOperand MEMOpd, ComplexPattern MEMPat,
98              MxEncEA EA, MxEncExt EXT>
99     : MxInst<(outs), (ins MEMOpd:$dst), "s"#CC#"\t$dst",
100              [(store (MxSetCC !cast<PatLeaf>("MxCOND"#CC), CCR), MEMPat:$dst)],
101              MxSccEncoding<EA, EXT, !cast<MxBead4Bits>("MxCC"#CC)>>;
104 foreach cc = [ "cc", "ls", "lt", "eq", "mi", "f", "ne", "ge",
105                "cs", "pl", "gt", "t", "hi", "vc", "le", "vs"] in {
106 def SET#"d8"#cc : MxSccR<cc>;
107 def SET#"j8"#cc : MxSccM<cc, MxType8.JOp, MxType8.JPat, MxEncEAj_0, MxExtEmpty>;
108 def SET#"p8"#cc : MxSccM<cc, MxType8.POp, MxType8.PPat, MxEncEAp_0, MxExtI16_0>;
111 //===----------------------------------------------------------------------===//
112 // Jumps
113 //===----------------------------------------------------------------------===//
115 ///------------------------------+---------+---------
116 /// F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
117 ///------------------------------+---------+---------
118 /// 0  1  0  0  1  1  1  0  1  1 |  MODE   |   REG
119 ///------------------------------+---------+---------
120 let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
121 class MxJMP<MxOperand LOCOp, ComplexPattern LOCPat, MxEncEA EA, MxEncExt EXT>
122     : MxInst<(outs), (ins LOCOp:$dst), "jmp\t$dst", [(brind iPTR:$dst)],
123              MxEncoding<EA.Reg, EA.DA, EA.Mode, MxBead2Bits<0b11>,
124                         MxBead4Bits<0b1110>, MxBead4Bits<0b0100>,
125                         EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>;
127 def JMP32j : MxJMP<MxARI32, MxCP_ARI, MxEncEAj_0, MxExtEmpty>;
130 // FIXME Support 16 bit indirect jump.
131 // Currently M68k does not allow 16 bit indirect jumps use sext operands
132 // def JMP16r     : MxInst<(outs), (ins M68k_ARI16:$dst),
133 //                             "jmp\t$dst",
134 //                             [(brind AR16:$dst)]>;
136 //===----------------------------------------------------------------------===//
137 // Branches
138 //===----------------------------------------------------------------------===//
140 /// --------------------------------------------------
141 ///  F  E  D  C | B  A  9  8 | 7  6  5  4  3  2  1  0
142 /// --------------------------------------------------
143 ///  0  1  1  0 | CONDITION |   8-BIT DISPLACEMENT
144 /// --------------------------------------------------
145 ///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00
146 /// --------------------------------------------------
147 ///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF
148 /// --------------------------------------------------
149 let isBranch = 1, isTerminator = 1, Uses = [CCR] in
150 class MxBcc<string cc, Operand TARGET, MxType TYPE, MxEncoding ENC = MxEncEmpty>
151     : MxInst<(outs), (ins TARGET:$dst), "b"#cc#"\t$dst", [], ENC>;
153 foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
154                "cs", "pl", "gt", "hi", "vc", "le", "vs"] in {
155   def B#cc#"8"
156     : MxBcc<cc, MxBrTarget8, MxType8,
157             MxEncoding<MxBead8Disp<0>,
158                        !cast<MxBead4Bits>("MxCC"#cc), MxBead4Bits<0x6>>>;
159   def B#cc#"16"
160     : MxBcc<cc, MxBrTarget16, MxType16,
161             MxEncoding<MxBead4Bits<0x0>,
162                        MxBead4Bits<0x0>, !cast<MxBead4Bits>("MxCC"#cc),
163                        MxBead4Bits<0x6>, MxBead16Imm<0>>>;
166 foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
167                "cs", "pl", "gt", "hi", "vc", "le", "vs"] in {
168 def : Pat<(MxBrCond bb:$target, !cast<PatLeaf>("MxCOND"#cc), CCR),
169           (!cast<Instruction>("B"#cc#"8") MxBrTarget8:$target)>;
172 /// -------------------------------------------------
173 ///  F  E  D  C  B  A  9  8 | 7  6  5  4  3  2  1  0
174 /// -------------------------------------------------
175 ///  0  1  1  0  0  0  0  0 |   8-BIT DISPLACEMENT
176 /// -------------------------------------------------
177 ///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00
178 /// -------------------------------------------------
179 ///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF
180 /// -------------------------------------------------
181 let isBranch = 1, isTerminator = 1, isBarrier=1 in
182 class MxBra<Operand TARGET, MxType TYPE, MxEncoding ENC = MxEncEmpty>
183     : MxInst<(outs), (ins TARGET:$dst), "bra\t$dst", [], ENC>;
185 def BRA8  : MxBra<MxBrTarget8, MxType8,
186                   MxEncoding<MxBead8Disp<0>, MxBead4Bits<0x0>,
187                              MxBead4Bits<0x6>>>;
188 def BRA16 : MxBra<MxBrTarget16, MxType16,
189                   MxEncoding<MxBead4Bits<0x0>, MxBead4Bits<0x0>,
190                              MxBead4Bits<0x0>, MxBead4Bits<0x6>,
191                              MxBead16Imm<0>>>;
193 def : Pat<(br bb:$target), (BRA8 MxBrTarget8:$target)>;
196 //===----------------------------------------------------------------------===//
197 // Call
198 //===----------------------------------------------------------------------===//
200 // All calls clobber the non-callee saved registers. %SP is marked as
201 // a use to prevent stack-pointer assignments that appear immediately
202 // before calls from potentially appearing dead. Uses for argument
203 // registers are added manually.
204 let Uses = [SP] in
205 let isCall = 1 in
206 ///------------------------------+---------+---------
207 /// F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
208 ///------------------------------+---------+---------
209 /// 0  1  0  0  1  1  1  0  1  0 |  MODE   |   REG
210 ///------------------------------+---------+---------
211 class MxCall<MxOperand LOCOp, MxEncEA EA, MxEncExt EXT>
212     : MxInst<(outs), (ins LOCOp:$dst), "jsr\t$dst", [],
213              MxEncoding<EA.Reg, EA.DA, EA.Mode, MxBead2Bits<0b10>,
214                         MxBead4Bits<0b1110>, MxBead4Bits<0b0100>,
215                         EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>;
217 def CALLk : MxCall<MxPCI32, MxEncEAk,   MxExtBrief_0>;
218 def CALLq : MxCall<MxPCD32, MxEncEAq,   MxExtI16_0>;
219 def CALLb : MxCall<MxAL32,  MxEncEAb,   MxExtI32_0>;
220 def CALLj : MxCall<MxARI32, MxEncEAj_0, MxExtEmpty>;
222 multiclass CallPat<MxCall callOp, Predicate pred> {
223   let Predicates = [pred] in {
224     def : Pat<(MxCall (i32 tglobaladdr:$dst)),  (callOp tglobaladdr:$dst)>;
225     def : Pat<(MxCall (i32 texternalsym:$dst)), (callOp texternalsym:$dst)>;
226     def : Pat<(MxCall (i32 imm:$dst)),          (callOp imm:$dst)>;
227   }
230 defm : CallPat<CALLq, IsPIC>;
231 defm : CallPat<CALLb, IsNotPIC>;
233 def : Pat<(MxCall iPTR:$dst), (CALLj MxARI32:$dst)>;
235 //===----------------------------------------------------------------------===//
236 // Tail Call
237 //===----------------------------------------------------------------------===//
239 let isCodeGenOnly = 1 in {
240 let Uses = [SP] in {
241 let isCall = 1, isTerminator = 1, isBarrier = 1 in {
243 let isReturn = 1 in
244 def TCRETURNq : MxPseudo<(outs), (ins MxPCD32:$dst,    i32imm:$adj)>;
245 def TAILJMPq  : MxPseudo<(outs), (ins MxPCD32:$dst)>;
247 // NOTE j does not mean load and jump M68k jmp just calculates EA and jumps
248 // and it is using Mem form like (An) thus j letter.
249 let isReturn = 1 in
250 def TCRETURNj : MxPseudo<(outs), (ins MxARI32_TC:$dst, i32imm:$adj)>;
251 def TAILJMPj  : MxPseudo<(outs), (ins MxARI32_TC:$dst)>;
252 } // isCall = 1, isTerminator = 1, isBarrier = 1
253 } // Uses = [SP]
254 } // isCodeGenOnly = 1
256 //===----------------------------------------------------------------------===//
257 // Return
258 //===----------------------------------------------------------------------===//
260 // TODO Implement LINK/UNLK
262 let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
264 def RTS : MxInst<(outs), (ins), "rts", [], MxEncFixed<0x4E75>>;
266 let isCodeGenOnly = 1 in
267 def RET : MxPseudo<(outs), (ins i32imm:$adj, variable_ops),
268                    [(MxRet timm:$adj)]>;
269 } // isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1
271 //===----------------------------------------------------------------------===//
272 // SETCC_C Patterns
273 //===----------------------------------------------------------------------===//
275 // Use subx to materialize carry bit.
276 let Uses = [CCR], Defs = [CCR], isPseudo = 1 in {
277 // FIXME These are pseudo ops that should be replaced with Pat<> patterns.
278 // However, Pat<> can't replicate the destination reg into the inputs of the
279 // result.
280 def SETCS_C8d : MxPseudo<(outs MxDRD8:$dst), (ins),
281                          [(set MxDRD8:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
282 def SETCS_C16d : MxPseudo<(outs MxDRD16:$dst), (ins),
283                           [(set MxDRD16:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
284 def SETCS_C32d : MxPseudo<(outs MxXRD32:$dst), (ins),
285                           [(set MxXRD32:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
286 } // Uses = [CCR], Defs = [CCR], isPseudo = 1
289 def : Pat<(i16 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>;
290 def : Pat<(i32 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>;
292 def : Pat<(i16 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>;
293 def : Pat<(i32 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>;
295 // We canonicalize 'scs' to "(and (subx reg,reg), 1)" on the hope that the and
296 // will be eliminated and that the subx can be extended up to a wider type.  When
297 // this happens, it is great.  However, if we are left with an 8-bit subx and an
298 // and, we might as well just match it as a setb.
299 def : Pat<(and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), (SETd8cs)>;
301 // (add OP, SETB) -> (addx OP, (move 0))
302 def : Pat<(add (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), MxDRD8:$op),
303           (ADDX8dd MxDRD8:$op, (MOV8di 0))>;
304 def : Pat<(add (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1), MxXRD32:$op),
305           (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;
307 // (sub OP, SETB) -> (subx OP, (move 0))
308 def : Pat<(sub MxDRD8:$op, (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1)),
309           (SUBX8dd MxDRD8:$op, (MOV8di 0))>;
310 def : Pat<(sub MxXRD32:$op, (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1)),
311           (SUBX32dd MxDRD32:$op, (MOV32ri 0))>;
313 // (sub OP, SETCC_CARRY) -> (addx OP, (move 0))
314 def : Pat<(sub MxDRD8:$op, (i8 (MxSetCC_C MxCONDcs, CCR))),
315           (ADDX8dd MxDRD8:$op, (MOV8di 0))>;
316 def : Pat<(sub MxXRD32:$op, (i32 (MxSetCC_C MxCONDcs, CCR))),
317           (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;