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