xref: /freebsd/contrib/llvm-project/llvm/lib/Target/M68k/M68kInstrControl.td (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
104eeddc0SDimitry Andric//===-- M68kInstrControl.td - Control Flow Instructions ----*- tablegen -*-===//
2fe6060f1SDimitry Andric//
3fe6060f1SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric//
7fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric///
9fe6060f1SDimitry Andric/// \file
10fe6060f1SDimitry Andric/// This file describes the M68k jump, return, call, and related instructions.
11fe6060f1SDimitry Andric/// Here is the current status of the file:
12fe6060f1SDimitry Andric///
13fe6060f1SDimitry Andric///  Machine:
14fe6060f1SDimitry Andric///
1506c3fb27SDimitry Andric///       BRA   [x]     BSR  [~]     Bcc [~]     DBcc [ ]     FBcc [ ]
16fe6060f1SDimitry Andric///       FDBcc [ ]     FNOP [ ]     FPn [ ]     FScc [ ]     FTST [ ]
17fe6060f1SDimitry Andric///       JMP   [~]     JSR  [x]     NOP [x]     RTD  [!]     RTR  [ ]
1881ad6265SDimitry Andric///       RTS   [x]     Scc  [~]     TST [ ]
19fe6060f1SDimitry Andric///
20fe6060f1SDimitry Andric///  Pseudo:
21fe6060f1SDimitry Andric///
22fe6060f1SDimitry Andric///          RET [x]
23fe6060f1SDimitry Andric///    TCRETURNj [x]   TCRETURNq [x]
24fe6060f1SDimitry Andric///     TAILJMPj [x]    TAILJMPq [x]
25fe6060f1SDimitry Andric///
26fe6060f1SDimitry Andric///  Map:
27fe6060f1SDimitry Andric///
28fe6060f1SDimitry Andric///   [ ] - was not touched at all
29fe6060f1SDimitry Andric///   [!] - requires extarnal stuff implemented
30fe6060f1SDimitry Andric///   [~] - in progress but usable
31fe6060f1SDimitry Andric///   [x] - done
32fe6060f1SDimitry Andric///
33fe6060f1SDimitry Andric///
34fe6060f1SDimitry Andric///                                   NOTE
35fe6060f1SDimitry Andric///      Though branch and jump instructions are using memory operands they
36fe6060f1SDimitry Andric///      DO NOT read the jump address from memory, they just calculate EA
37fe6060f1SDimitry Andric///      and jump there.
38fe6060f1SDimitry Andric///
39fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
40fe6060f1SDimitry Andric
41fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
42fe6060f1SDimitry Andric// NOP
43fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
44fe6060f1SDimitry Andric
45fe6060f1SDimitry Andriclet hasSideEffects = 0 in {
4681ad6265SDimitry Andric  def NOP : MxInst<(outs), (ins), "nop", []> {
4781ad6265SDimitry Andric    let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0001);
4881ad6265SDimitry Andric  }
49fe6060f1SDimitry Andric}
50fe6060f1SDimitry Andric
51fe6060f1SDimitry Andric
52fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
53fe6060f1SDimitry Andric// Conditions
54fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
55fe6060f1SDimitry Andric
56fe6060f1SDimitry Andric/// CC—Carry clear      GE—Greater than or equal
57fe6060f1SDimitry Andric/// LS—Lower or same    PL—Plus
58fe6060f1SDimitry Andric/// CS—Carry set        GT—Greater than
59fe6060f1SDimitry Andric/// LT—Less than        T—Always true*
60fe6060f1SDimitry Andric/// EQ—Equal            HI—Higher
61fe6060f1SDimitry Andric/// MI—Minus            VC—Overflow clear
62fe6060f1SDimitry Andric/// F—Never true*       LE—Less than or equal
63fe6060f1SDimitry Andric/// NE—Not equal        VS—Overflow set
64fe6060f1SDimitry Andric///
65fe6060f1SDimitry Andric/// *Not applicable to the Bcc instructions.
6681ad6265SDimitry Andricclass MxEncCondOp<bits<4> cond> {
6781ad6265SDimitry Andric  dag Value = (descend cond);
6881ad6265SDimitry Andric}
6981ad6265SDimitry Andric
7081ad6265SDimitry Andricdef MxCCt  : MxEncCondOp<0b0000>;
7181ad6265SDimitry Andricdef MxCCf  : MxEncCondOp<0b0001>;
7281ad6265SDimitry Andricdef MxCChi : MxEncCondOp<0b0010>;
7381ad6265SDimitry Andricdef MxCCls : MxEncCondOp<0b0011>;
7481ad6265SDimitry Andricdef MxCCcc : MxEncCondOp<0b0100>;
7581ad6265SDimitry Andricdef MxCCcs : MxEncCondOp<0b0101>;
7681ad6265SDimitry Andricdef MxCCne : MxEncCondOp<0b0110>;
7781ad6265SDimitry Andricdef MxCCeq : MxEncCondOp<0b0111>;
7881ad6265SDimitry Andricdef MxCCvc : MxEncCondOp<0b1000>;
7981ad6265SDimitry Andricdef MxCCvs : MxEncCondOp<0b1001>;
8081ad6265SDimitry Andricdef MxCCpl : MxEncCondOp<0b1010>;
8181ad6265SDimitry Andricdef MxCCmi : MxEncCondOp<0b1011>;
8281ad6265SDimitry Andricdef MxCCge : MxEncCondOp<0b1100>;
8381ad6265SDimitry Andricdef MxCClt : MxEncCondOp<0b1101>;
8481ad6265SDimitry Andricdef MxCCgt : MxEncCondOp<0b1110>;
8581ad6265SDimitry Andricdef MxCCle : MxEncCondOp<0b1111>;
8681ad6265SDimitry Andric
8781ad6265SDimitry Andric
88fe6060f1SDimitry Andric
89fe6060f1SDimitry Andric/// --------------------------------+---------+---------
90fe6060f1SDimitry Andric///  F  E  D  C | B  A  9  8 | 7  6 | 5  4  3 | 2  1  0
91fe6060f1SDimitry Andric/// --------------------------------+---------+---------
92fe6060f1SDimitry Andric///  0  1  0  1 | CONDITION  | 1  1 |   MODE  |   REG
93fe6060f1SDimitry Andric/// ----------------------------------------------------
94fe6060f1SDimitry Andric
95fe6060f1SDimitry Andriclet Uses = [CCR] in {
96fe6060f1SDimitry Andricclass MxSccR<string CC>
97fe6060f1SDimitry Andric    : MxInst<(outs MxDRD8:$dst), (ins), "s"#CC#"\t$dst",
9881ad6265SDimitry Andric             [(set i8:$dst, (MxSetCC !cast<PatLeaf>("MxCOND"#CC), CCR))]> {
9981ad6265SDimitry Andric  let Inst = (descend 0b0101, !cast<MxEncCondOp>("MxCC"#CC).Value, 0b11,
10081ad6265SDimitry Andric              /*MODE without last bit*/0b00,
10181ad6265SDimitry Andric              /*REGISTER prefixed with D/A bit*/(operand "$dst", 4));
10281ad6265SDimitry Andric}
103fe6060f1SDimitry Andric
10481ad6265SDimitry Andricclass MxSccM<string CC, MxOperand MEMOpd, ComplexPattern MEMPat, MxEncMemOp DST_ENC>
105fe6060f1SDimitry Andric    : MxInst<(outs), (ins MEMOpd:$dst), "s"#CC#"\t$dst",
10681ad6265SDimitry Andric             [(store (MxSetCC !cast<PatLeaf>("MxCOND"#CC), CCR), MEMPat:$dst)]> {
10781ad6265SDimitry Andric  let Inst =
10881ad6265SDimitry Andric    (ascend
10981ad6265SDimitry Andric      (descend 0b0101, !cast<MxEncCondOp>("MxCC"#CC).Value, 0b11, DST_ENC.EA),
11081ad6265SDimitry Andric      DST_ENC.Supplement
11181ad6265SDimitry Andric    );
11281ad6265SDimitry Andric}
113fe6060f1SDimitry Andric}
114fe6060f1SDimitry Andric
115fe6060f1SDimitry Andricforeach cc = [ "cc", "ls", "lt", "eq", "mi", "f", "ne", "ge",
116fe6060f1SDimitry Andric               "cs", "pl", "gt", "t", "hi", "vc", "le", "vs"] in {
117fe6060f1SDimitry Andricdef SET#"d8"#cc : MxSccR<cc>;
11881ad6265SDimitry Andricdef SET#"j8"#cc : MxSccM<cc, MxType8.JOp, MxType8.JPat, MxEncAddrMode_j<"dst">>;
11981ad6265SDimitry Andricdef SET#"p8"#cc : MxSccM<cc, MxType8.POp, MxType8.PPat, MxEncAddrMode_p<"dst">>;
120fe6060f1SDimitry Andric}
121fe6060f1SDimitry Andric
122fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
123fe6060f1SDimitry Andric// Jumps
124fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
125fe6060f1SDimitry Andric
126fe6060f1SDimitry Andric///------------------------------+---------+---------
127fe6060f1SDimitry Andric/// F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
128fe6060f1SDimitry Andric///------------------------------+---------+---------
129fe6060f1SDimitry Andric/// 0  1  0  0  1  1  1  0  1  1 |  MODE   |   REG
130fe6060f1SDimitry Andric///------------------------------+---------+---------
131fe6060f1SDimitry Andriclet isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in
13281ad6265SDimitry Andricclass MxJMP<MxOperand LOCOp, MxEncMemOp DST_ENC>
13381ad6265SDimitry Andric    : MxInst<(outs), (ins LOCOp:$dst), "jmp\t$dst", [(brind iPTR:$dst)]> {
13481ad6265SDimitry Andric  let Inst =
13581ad6265SDimitry Andric    (ascend
13681ad6265SDimitry Andric      (descend 0b0100, 0b1110, 0b11, DST_ENC.EA),
13781ad6265SDimitry Andric      DST_ENC.Supplement
13881ad6265SDimitry Andric    );
13981ad6265SDimitry Andric}
140fe6060f1SDimitry Andric
14181ad6265SDimitry Andricdef JMP32j : MxJMP<MxARI32, MxEncAddrMode_j<"dst">>;
142fe6060f1SDimitry Andric
143fe6060f1SDimitry Andric
144fe6060f1SDimitry Andric// FIXME Support 16 bit indirect jump.
145fe6060f1SDimitry Andric// Currently M68k does not allow 16 bit indirect jumps use sext operands
146fe6060f1SDimitry Andric// def JMP16r     : MxInst<(outs), (ins M68k_ARI16:$dst),
147fe6060f1SDimitry Andric//                             "jmp\t$dst",
148fe6060f1SDimitry Andric//                             [(brind AR16:$dst)]>;
149fe6060f1SDimitry Andric
150fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
151fe6060f1SDimitry Andric// Branches
152fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
153fe6060f1SDimitry Andric
154fe6060f1SDimitry Andric/// --------------------------------------------------
155fe6060f1SDimitry Andric///  F  E  D  C | B  A  9  8 | 7  6  5  4  3  2  1  0
156fe6060f1SDimitry Andric/// --------------------------------------------------
157fe6060f1SDimitry Andric///  0  1  1  0 | CONDITION |   8-BIT DISPLACEMENT
158fe6060f1SDimitry Andric/// --------------------------------------------------
159fe6060f1SDimitry Andric///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00
160fe6060f1SDimitry Andric/// --------------------------------------------------
161fe6060f1SDimitry Andric///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF
162fe6060f1SDimitry Andric/// --------------------------------------------------
163fe6060f1SDimitry Andriclet isBranch = 1, isTerminator = 1, Uses = [CCR] in
16481ad6265SDimitry Andricclass MxBcc<string cc, Operand TARGET, dag disp_8, dag disp_16_32>
16581ad6265SDimitry Andric    : MxInst<(outs), (ins TARGET:$dst), "b"#cc#"\t$dst", []> {
16681ad6265SDimitry Andric  // FIXME: If we want to avoid supplying disp_16_32 with empty
16781ad6265SDimitry Andric  //        (ascend) for 16/32 bits variants, we can use conditional
16881ad6265SDimitry Andric  //        bang operator like this:
16981ad6265SDimitry Andric  //        ```
17081ad6265SDimitry Andric  //        class MxBcc<string cc, Operand TARGET, int SIZE>
17181ad6265SDimitry Andric  //        ...
17281ad6265SDimitry Andric  //        let Inst = !cond(
17381ad6265SDimitry Andric  //            !eq(SIZE, 8):   /* encoding for Bcc8  */
17481ad6265SDimitry Andric  //            !eq(SIZE, 16):  /* encoding for Bcc16 */
17581ad6265SDimitry Andric  //            !eq(SIZE, 32):  /* encoding for Bcc32 */
17681ad6265SDimitry Andric  //        );
17781ad6265SDimitry Andric  let Inst =
17881ad6265SDimitry Andric      (ascend
17981ad6265SDimitry Andric        (descend 0b0110, !cast<MxEncCondOp>("MxCC"#cc).Value, disp_8),
18081ad6265SDimitry Andric        disp_16_32
18181ad6265SDimitry Andric      );
18281ad6265SDimitry Andric}
183fe6060f1SDimitry Andric
184fe6060f1SDimitry Andricforeach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
185fe6060f1SDimitry Andric               "cs", "pl", "gt", "hi", "vc", "le", "vs"] in {
186fe6060f1SDimitry Andric  def B#cc#"8"
1870eae32dcSDimitry Andric    : MxBcc<cc, MxBrTarget8,
18881ad6265SDimitry Andric            (operand "$dst", 8, (encoder "encodePCRelImm<8>")), (ascend)>;
18981ad6265SDimitry Andric
190fe6060f1SDimitry Andric  def B#cc#"16"
19181ad6265SDimitry Andric    : MxBcc<cc, MxBrTarget16, (descend 0b0000, 0b0000),
19281ad6265SDimitry Andric            (operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;
193fe6060f1SDimitry Andric}
194fe6060f1SDimitry Andric
195fe6060f1SDimitry Andricforeach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",
196fe6060f1SDimitry Andric               "cs", "pl", "gt", "hi", "vc", "le", "vs"] in {
197fe6060f1SDimitry Andricdef : Pat<(MxBrCond bb:$target, !cast<PatLeaf>("MxCOND"#cc), CCR),
198fe6060f1SDimitry Andric          (!cast<Instruction>("B"#cc#"8") MxBrTarget8:$target)>;
199fe6060f1SDimitry Andric}
200fe6060f1SDimitry Andric
201fe6060f1SDimitry Andric/// -------------------------------------------------
202fe6060f1SDimitry Andric///  F  E  D  C  B  A  9  8 | 7  6  5  4  3  2  1  0
203fe6060f1SDimitry Andric/// -------------------------------------------------
204fe6060f1SDimitry Andric///  0  1  1  0  0  0  0  0 |   8-BIT DISPLACEMENT
205fe6060f1SDimitry Andric/// -------------------------------------------------
206fe6060f1SDimitry Andric///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00
207fe6060f1SDimitry Andric/// -------------------------------------------------
208fe6060f1SDimitry Andric///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF
209fe6060f1SDimitry Andric/// -------------------------------------------------
210fe6060f1SDimitry Andriclet isBranch = 1, isTerminator = 1, isBarrier = 1 in
21181ad6265SDimitry Andricclass MxBra<Operand TARGET, dag disp_8, dag disp_16_32>
21281ad6265SDimitry Andric    : MxInst<(outs), (ins TARGET:$dst), "bra\t$dst", []> {
21381ad6265SDimitry Andric  let Inst =
21481ad6265SDimitry Andric    (ascend
21581ad6265SDimitry Andric      (descend 0b0110, 0b0000, disp_8),
21681ad6265SDimitry Andric      disp_16_32
21781ad6265SDimitry Andric    );
21881ad6265SDimitry Andric}
219fe6060f1SDimitry Andric
2200eae32dcSDimitry Andricdef BRA8  : MxBra<MxBrTarget8,
22181ad6265SDimitry Andric                  (operand "$dst", 8, (encoder "encodePCRelImm<8>")), (ascend)>;
22281ad6265SDimitry Andric
22381ad6265SDimitry Andricdef BRA16 : MxBra<MxBrTarget16, (descend 0b0000, 0b0000),
22481ad6265SDimitry Andric                  (operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;
225fe6060f1SDimitry Andric
226fe6060f1SDimitry Andricdef : Pat<(br bb:$target), (BRA8 MxBrTarget8:$target)>;
227fe6060f1SDimitry Andric
22806c3fb27SDimitry Andric/// -------------------------------------------------
22906c3fb27SDimitry Andric///  F  E  D  C  B  A  9  8 | 7  6  5  4  3  2  1  0
23006c3fb27SDimitry Andric/// -------------------------------------------------
23106c3fb27SDimitry Andric///  0  1  1  0  0  0  0  1 |   8-BIT DISPLACEMENT
23206c3fb27SDimitry Andric/// -------------------------------------------------
23306c3fb27SDimitry Andric///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00
23406c3fb27SDimitry Andric/// -------------------------------------------------
23506c3fb27SDimitry Andric///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF
23606c3fb27SDimitry Andric/// -------------------------------------------------
23706c3fb27SDimitry Andric
23806c3fb27SDimitry Andriclet isBranch = 1, isTerminator = 1 in
23906c3fb27SDimitry Andricclass MxBsr<Operand TARGET, MxType TYPE, dag disp_8, dag disp_16_32>
24006c3fb27SDimitry Andric    : MxInst<(outs), (ins TARGET:$dst), "bsr."#TYPE.Prefix#"\t$dst"> {
24106c3fb27SDimitry Andric  let Inst = (ascend
24206c3fb27SDimitry Andric                (descend 0b0110, 0b0001, disp_8),
24306c3fb27SDimitry Andric                 disp_16_32
24406c3fb27SDimitry Andric              );
24506c3fb27SDimitry Andric}
24606c3fb27SDimitry Andric
24706c3fb27SDimitry Andricdef BSR8 : MxBsr<MxBrTarget8, MxType8,
24806c3fb27SDimitry Andric                (operand "$dst", 8, (encoder "encodePCRelImm<8>")), (ascend)>;
24906c3fb27SDimitry Andric
25006c3fb27SDimitry Andricdef BSR16 : MxBsr<MxBrTarget16, MxType16, (descend 0b0000, 0b0000),
25106c3fb27SDimitry Andric                (operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;
25206c3fb27SDimitry Andric
25306c3fb27SDimitry Andricdef BSR32 : MxBsr<MxBrTarget32, MxType32, (descend 0b1111, 0b1111),
25406c3fb27SDimitry Andric                (operand "$dst", 32, (encoder "encodePCRelImm<32>"),
25506c3fb27SDimitry Andric                                     (decoder "DecodeImm32"))>;
256fe6060f1SDimitry Andric
257fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
258fe6060f1SDimitry Andric// Call
259fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
260fe6060f1SDimitry Andric
261fe6060f1SDimitry Andric// All calls clobber the non-callee saved registers. %SP is marked as
262fe6060f1SDimitry Andric// a use to prevent stack-pointer assignments that appear immediately
263fe6060f1SDimitry Andric// before calls from potentially appearing dead. Uses for argument
264fe6060f1SDimitry Andric// registers are added manually.
265fe6060f1SDimitry Andriclet Uses = [SP] in
266fe6060f1SDimitry Andriclet isCall = 1 in
267fe6060f1SDimitry Andric///------------------------------+---------+---------
268fe6060f1SDimitry Andric/// F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0
269fe6060f1SDimitry Andric///------------------------------+---------+---------
270fe6060f1SDimitry Andric/// 0  1  0  0  1  1  1  0  1  0 |  MODE   |   REG
271fe6060f1SDimitry Andric///------------------------------+---------+---------
27281ad6265SDimitry Andricclass MxCall<MxOperand LOCOp, MxEncMemOp DST_ENC>
27381ad6265SDimitry Andric    : MxInst<(outs), (ins LOCOp:$dst), "jsr\t$dst", []> {
27481ad6265SDimitry Andric  let Inst =
27581ad6265SDimitry Andric    (ascend
27681ad6265SDimitry Andric      (descend 0b0100, 0b1110, 0b10, DST_ENC.EA),
27781ad6265SDimitry Andric      DST_ENC.Supplement
27881ad6265SDimitry Andric    );
27981ad6265SDimitry Andric}
280fe6060f1SDimitry Andric
28181ad6265SDimitry Andricdef CALLk : MxCall<MxPCI32, MxEncAddrMode_k<"dst">>;
28281ad6265SDimitry Andricdef CALLq : MxCall<MxPCD32, MxEncAddrMode_q<"dst">>;
28381ad6265SDimitry Andricdef CALLb : MxCall<MxAL32,  MxEncAddrMode_abs<"dst", true>>;
28481ad6265SDimitry Andricdef CALLj : MxCall<MxARI32, MxEncAddrMode_j<"dst">>;
285fe6060f1SDimitry Andric
286fe6060f1SDimitry Andricmulticlass CallPat<MxCall callOp, Predicate pred> {
287fe6060f1SDimitry Andric  let Predicates = [pred] in {
288fe6060f1SDimitry Andric    def : Pat<(MxCall (i32 tglobaladdr:$dst)),  (callOp tglobaladdr:$dst)>;
289fe6060f1SDimitry Andric    def : Pat<(MxCall (i32 texternalsym:$dst)), (callOp texternalsym:$dst)>;
290fe6060f1SDimitry Andric    def : Pat<(MxCall (i32 imm:$dst)),          (callOp imm:$dst)>;
291fe6060f1SDimitry Andric  }
292fe6060f1SDimitry Andric}
293fe6060f1SDimitry Andric
294fe6060f1SDimitry Andricdefm : CallPat<CALLq, IsPIC>;
295fe6060f1SDimitry Andricdefm : CallPat<CALLb, IsNotPIC>;
296fe6060f1SDimitry Andric
297fe6060f1SDimitry Andricdef : Pat<(MxCall iPTR:$dst), (CALLj MxARI32:$dst)>;
298fe6060f1SDimitry Andric
299fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
300fe6060f1SDimitry Andric// Tail Call
301fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
302fe6060f1SDimitry Andric
303fe6060f1SDimitry Andriclet isCodeGenOnly = 1 in {
304fe6060f1SDimitry Andriclet Uses = [SP] in {
305fe6060f1SDimitry Andriclet isCall = 1, isTerminator = 1, isBarrier = 1 in {
306fe6060f1SDimitry Andric
307fe6060f1SDimitry Andriclet isReturn = 1 in
308fe6060f1SDimitry Andricdef TCRETURNq : MxPseudo<(outs), (ins MxPCD32:$dst,    i32imm:$adj)>;
309fe6060f1SDimitry Andricdef TAILJMPq  : MxPseudo<(outs), (ins MxPCD32:$dst)>;
310fe6060f1SDimitry Andric
311fe6060f1SDimitry Andric// NOTE j does not mean load and jump M68k jmp just calculates EA and jumps
312fe6060f1SDimitry Andric// and it is using Mem form like (An) thus j letter.
313fe6060f1SDimitry Andriclet isReturn = 1 in
314fe6060f1SDimitry Andricdef TCRETURNj : MxPseudo<(outs), (ins MxARI32_TC:$dst, i32imm:$adj)>;
315fe6060f1SDimitry Andricdef TAILJMPj  : MxPseudo<(outs), (ins MxARI32_TC:$dst)>;
316fe6060f1SDimitry Andric} // isCall = 1, isTerminator = 1, isBarrier = 1
317fe6060f1SDimitry Andric} // Uses = [SP]
318fe6060f1SDimitry Andric} // isCodeGenOnly = 1
319fe6060f1SDimitry Andric
320fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
321fe6060f1SDimitry Andric// Return
322fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
323fe6060f1SDimitry Andric
324fe6060f1SDimitry Andriclet isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {
325fe6060f1SDimitry Andric
32681ad6265SDimitry Andricdef RTS : MxInst<(outs), (ins), "rts", []> {
32781ad6265SDimitry Andric  let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0101);
32881ad6265SDimitry Andric}
329fe6060f1SDimitry Andric
330*5f757f3fSDimitry Andricdef RTE: MxInst<(outs), (ins), "rte", []> {
331*5f757f3fSDimitry Andric  let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0011);
332*5f757f3fSDimitry Andric}
333*5f757f3fSDimitry Andric
334fe6060f1SDimitry Andriclet isCodeGenOnly = 1 in
335fe6060f1SDimitry Andricdef RET : MxPseudo<(outs), (ins i32imm:$adj, variable_ops),
336fe6060f1SDimitry Andric                   [(MxRet timm:$adj)]>;
337fe6060f1SDimitry Andric} // isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1
338fe6060f1SDimitry Andric
339fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
340fe6060f1SDimitry Andric// SETCC_C Patterns
341fe6060f1SDimitry Andric//===----------------------------------------------------------------------===//
342fe6060f1SDimitry Andric
343fe6060f1SDimitry Andric// Use subx to materialize carry bit.
344fe6060f1SDimitry Andriclet Uses = [CCR], Defs = [CCR], isPseudo = 1 in {
345fe6060f1SDimitry Andric// FIXME These are pseudo ops that should be replaced with Pat<> patterns.
346fe6060f1SDimitry Andric// However, Pat<> can't replicate the destination reg into the inputs of the
347fe6060f1SDimitry Andric// result.
348fe6060f1SDimitry Andricdef SETCS_C8d : MxPseudo<(outs MxDRD8:$dst), (ins),
349fe6060f1SDimitry Andric                         [(set MxDRD8:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
350fe6060f1SDimitry Andricdef SETCS_C16d : MxPseudo<(outs MxDRD16:$dst), (ins),
351fe6060f1SDimitry Andric                          [(set MxDRD16:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
352fe6060f1SDimitry Andricdef SETCS_C32d : MxPseudo<(outs MxXRD32:$dst), (ins),
353fe6060f1SDimitry Andric                          [(set MxXRD32:$dst, (MxSetCC_C MxCONDcs, CCR))]>;
354fe6060f1SDimitry Andric} // Uses = [CCR], Defs = [CCR], isPseudo = 1
355fe6060f1SDimitry Andric
356fe6060f1SDimitry Andric
357fe6060f1SDimitry Andricdef : Pat<(i16 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>;
358fe6060f1SDimitry Andricdef : Pat<(i32 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>;
359fe6060f1SDimitry Andric
360fe6060f1SDimitry Andricdef : Pat<(i16 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>;
361fe6060f1SDimitry Andricdef : Pat<(i32 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>;
362fe6060f1SDimitry Andric
363fe6060f1SDimitry Andric// We canonicalize 'scs' to "(and (subx reg,reg), 1)" on the hope that the and
364fe6060f1SDimitry Andric// will be eliminated and that the subx can be extended up to a wider type.  When
365fe6060f1SDimitry Andric// this happens, it is great.  However, if we are left with an 8-bit subx and an
366fe6060f1SDimitry Andric// and, we might as well just match it as a setb.
367fe6060f1SDimitry Andricdef : Pat<(and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), (SETd8cs)>;
368fe6060f1SDimitry Andric
369fe6060f1SDimitry Andric// (add OP, SETB) -> (addx OP, (move 0))
370fe6060f1SDimitry Andricdef : Pat<(add (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), MxDRD8:$op),
371fe6060f1SDimitry Andric          (ADDX8dd MxDRD8:$op, (MOV8di 0))>;
372fe6060f1SDimitry Andricdef : Pat<(add (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1), MxXRD32:$op),
373fe6060f1SDimitry Andric          (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;
374fe6060f1SDimitry Andric
375fe6060f1SDimitry Andric// (sub OP, SETB) -> (subx OP, (move 0))
376fe6060f1SDimitry Andricdef : Pat<(sub MxDRD8:$op, (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1)),
377fe6060f1SDimitry Andric          (SUBX8dd MxDRD8:$op, (MOV8di 0))>;
378fe6060f1SDimitry Andricdef : Pat<(sub MxXRD32:$op, (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1)),
379fe6060f1SDimitry Andric          (SUBX32dd MxDRD32:$op, (MOV32ri 0))>;
380fe6060f1SDimitry Andric
381fe6060f1SDimitry Andric// (sub OP, SETCC_CARRY) -> (addx OP, (move 0))
382fe6060f1SDimitry Andricdef : Pat<(sub MxDRD8:$op, (i8 (MxSetCC_C MxCONDcs, CCR))),
383fe6060f1SDimitry Andric          (ADDX8dd MxDRD8:$op, (MOV8di 0))>;
384fe6060f1SDimitry Andricdef : Pat<(sub MxXRD32:$op, (i32 (MxSetCC_C MxCONDcs, CCR))),
385fe6060f1SDimitry Andric          (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;
38606c3fb27SDimitry Andric
38706c3fb27SDimitry Andric//===------------===//
38806c3fb27SDimitry Andric// Trap / Breakpoint
38906c3fb27SDimitry Andric//===------------===//
39006c3fb27SDimitry Andric
39106c3fb27SDimitry Andriclet RenderMethod = "addImmOperands", ParserMethod = "parseImm" in {
39206c3fb27SDimitry Andric  def MxTrapImm : AsmOperandClass {
39306c3fb27SDimitry Andric    let Name = "MxTrapImm";
39406c3fb27SDimitry Andric    let PredicateMethod = "isTrapImm";
39506c3fb27SDimitry Andric  }
39606c3fb27SDimitry Andric
39706c3fb27SDimitry Andric  def MxBkptImm : AsmOperandClass {
39806c3fb27SDimitry Andric    let Name = "MxBkptImm";
39906c3fb27SDimitry Andric    let PredicateMethod = "isBkptImm";
40006c3fb27SDimitry Andric  }
40106c3fb27SDimitry Andric}
40206c3fb27SDimitry Andric
40306c3fb27SDimitry Andriclet ParserMatchClass = MxTrapImm in
40406c3fb27SDimitry Andricdef MxTrapimm : MxOp<i8,  MxSize8,  "i">;
40506c3fb27SDimitry Andric
40606c3fb27SDimitry Andriclet ParserMatchClass = MxBkptImm in
40706c3fb27SDimitry Andricdef MxBkptimm : MxOp<i8,  MxSize8,  "i">;
40806c3fb27SDimitry Andric
40906c3fb27SDimitry Andricdef TRAP : MxInst<(outs), (ins MxTrapimm:$vect), "trap\t$vect", []> {
41006c3fb27SDimitry Andric  let Inst = (descend 0b0100, 0b1110, 0b0100, (operand "$vect", 4));
41106c3fb27SDimitry Andric}
41206c3fb27SDimitry Andric
41306c3fb27SDimitry Andricdef TRAPV : MxInst<(outs), (ins), "trapv", []> {
41406c3fb27SDimitry Andric  let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0110);
41506c3fb27SDimitry Andric}
41606c3fb27SDimitry Andric
41706c3fb27SDimitry Andricdef BKPT : MxInst<(outs), (ins MxBkptimm:$vect), "bkpt\t$vect", []> {
41806c3fb27SDimitry Andric  let Inst = (descend 0b0100, 0b1000, 0b0100, 0b1 , (operand "$vect", 3));
41906c3fb27SDimitry Andric}
42006c3fb27SDimitry Andric
42106c3fb27SDimitry Andricdef ILLEGAL : MxInst<(outs), (ins), "illegal", []> {
42206c3fb27SDimitry Andric  let Inst = (descend 0b0100, 0b1010, 0b1111, 0b1100);
42306c3fb27SDimitry Andric}
424