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//===----------------------------------------------------------------------===// 40 41//===----------------------------------------------------------------------===// 42// NOP 43//===----------------------------------------------------------------------===// 44 45let hasSideEffects = 0 in { 46 def NOP : MxInst<(outs), (ins), "nop", [], MxEncFixed<0x4E71>>; 47} 48 49 50//===----------------------------------------------------------------------===// 51// Conditions 52//===----------------------------------------------------------------------===// 53 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. 64def MxCCt : MxBead4Bits<0b0000>; 65def MxCCf : MxBead4Bits<0b0001>; 66def MxCChi : MxBead4Bits<0b0010>; 67def MxCCls : MxBead4Bits<0b0011>; 68def MxCCcc : MxBead4Bits<0b0100>; 69def MxCCcs : MxBead4Bits<0b0101>; 70def MxCCne : MxBead4Bits<0b0110>; 71def MxCCeq : MxBead4Bits<0b0111>; 72def MxCCvc : MxBead4Bits<0b1000>; 73def MxCCvs : MxBead4Bits<0b1001>; 74def MxCCpl : MxBead4Bits<0b1010>; 75def MxCCmi : MxBead4Bits<0b1011>; 76def MxCCge : MxBead4Bits<0b1100>; 77def MxCClt : MxBead4Bits<0b1101>; 78def MxCCgt : MxBead4Bits<0b1110>; 79def MxCCle : MxBead4Bits<0b1111>; 80 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/// ---------------------------------------------------- 86class 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>; 89 90let Uses = [CCR] in { 91class 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)>>; 96 97class 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)>>; 102} 103 104foreach cc = [ "cc", "ls", "lt", "eq", "mi", "f", "ne", "ge", 105 "cs", "pl", "gt", "t", "hi", "vc", "le", "vs"] in { 106def SET#"d8"#cc : MxSccR<cc>; 107def SET#"j8"#cc : MxSccM<cc, MxType8.JOp, MxType8.JPat, MxEncEAj_0, MxExtEmpty>; 108def SET#"p8"#cc : MxSccM<cc, MxType8.POp, MxType8.PPat, MxEncEAp_0, MxExtI16_0>; 109} 110 111//===----------------------------------------------------------------------===// 112// Jumps 113//===----------------------------------------------------------------------===// 114 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///------------------------------+---------+--------- 120let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in 121class 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>>; 126 127def JMP32j : MxJMP<MxARI32, MxCP_ARI, MxEncEAj_0, MxExtEmpty>; 128 129 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)]>; 135 136//===----------------------------------------------------------------------===// 137// Branches 138//===----------------------------------------------------------------------===// 139 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/// -------------------------------------------------- 149let isBranch = 1, isTerminator = 1, Uses = [CCR] in 150class MxBcc<string cc, Operand TARGET, MxType TYPE, MxEncoding ENC = MxEncEmpty> 151 : MxInst<(outs), (ins TARGET:$dst), "b"#cc#"\t$dst", [], ENC>; 152 153foreach 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>>>; 164} 165 166foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge", 167 "cs", "pl", "gt", "hi", "vc", "le", "vs"] in { 168def : Pat<(MxBrCond bb:$target, !cast<PatLeaf>("MxCOND"#cc), CCR), 169 (!cast<Instruction>("B"#cc#"8") MxBrTarget8:$target)>; 170} 171 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/// ------------------------------------------------- 181let isBranch = 1, isTerminator = 1, isBarrier=1 in 182class MxBra<Operand TARGET, MxType TYPE, MxEncoding ENC = MxEncEmpty> 183 : MxInst<(outs), (ins TARGET:$dst), "bra\t$dst", [], ENC>; 184 185def BRA8 : MxBra<MxBrTarget8, MxType8, 186 MxEncoding<MxBead8Disp<0>, MxBead4Bits<0x0>, 187 MxBead4Bits<0x6>>>; 188def BRA16 : MxBra<MxBrTarget16, MxType16, 189 MxEncoding<MxBead4Bits<0x0>, MxBead4Bits<0x0>, 190 MxBead4Bits<0x0>, MxBead4Bits<0x6>, 191 MxBead16Imm<0>>>; 192 193def : Pat<(br bb:$target), (BRA8 MxBrTarget8:$target)>; 194 195 196//===----------------------------------------------------------------------===// 197// Call 198//===----------------------------------------------------------------------===// 199 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. 204let Uses = [SP] in 205let 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///------------------------------+---------+--------- 211class 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>>; 216 217def CALLk : MxCall<MxPCI32, MxEncEAk, MxExtBrief_0>; 218def CALLq : MxCall<MxPCD32, MxEncEAq, MxExtI16_0>; 219def CALLb : MxCall<MxAL32, MxEncEAb, MxExtI32_0>; 220def CALLj : MxCall<MxARI32, MxEncEAj_0, MxExtEmpty>; 221 222multiclass 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 } 228} 229 230defm : CallPat<CALLq, IsPIC>; 231defm : CallPat<CALLb, IsNotPIC>; 232 233def : Pat<(MxCall iPTR:$dst), (CALLj MxARI32:$dst)>; 234 235//===----------------------------------------------------------------------===// 236// Tail Call 237//===----------------------------------------------------------------------===// 238 239let isCodeGenOnly = 1 in { 240let Uses = [SP] in { 241let isCall = 1, isTerminator = 1, isBarrier = 1 in { 242 243let isReturn = 1 in 244def TCRETURNq : MxPseudo<(outs), (ins MxPCD32:$dst, i32imm:$adj)>; 245def TAILJMPq : MxPseudo<(outs), (ins MxPCD32:$dst)>; 246 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. 249let isReturn = 1 in 250def TCRETURNj : MxPseudo<(outs), (ins MxARI32_TC:$dst, i32imm:$adj)>; 251def TAILJMPj : MxPseudo<(outs), (ins MxARI32_TC:$dst)>; 252} // isCall = 1, isTerminator = 1, isBarrier = 1 253} // Uses = [SP] 254} // isCodeGenOnly = 1 255 256//===----------------------------------------------------------------------===// 257// Return 258//===----------------------------------------------------------------------===// 259 260// TODO Implement LINK/UNLK 261 262let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in { 263 264def RTS : MxInst<(outs), (ins), "rts", [], MxEncFixed<0x4E75>>; 265 266let isCodeGenOnly = 1 in 267def RET : MxPseudo<(outs), (ins i32imm:$adj, variable_ops), 268 [(MxRet timm:$adj)]>; 269} // isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 270 271//===----------------------------------------------------------------------===// 272// SETCC_C Patterns 273//===----------------------------------------------------------------------===// 274 275// Use subx to materialize carry bit. 276let 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. 280def SETCS_C8d : MxPseudo<(outs MxDRD8:$dst), (ins), 281 [(set MxDRD8:$dst, (MxSetCC_C MxCONDcs, CCR))]>; 282def SETCS_C16d : MxPseudo<(outs MxDRD16:$dst), (ins), 283 [(set MxDRD16:$dst, (MxSetCC_C MxCONDcs, CCR))]>; 284def SETCS_C32d : MxPseudo<(outs MxXRD32:$dst), (ins), 285 [(set MxXRD32:$dst, (MxSetCC_C MxCONDcs, CCR))]>; 286} // Uses = [CCR], Defs = [CCR], isPseudo = 1 287 288 289def : Pat<(i16 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>; 290def : Pat<(i32 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>; 291 292def : Pat<(i16 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>; 293def : Pat<(i32 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>; 294 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. 299def : Pat<(and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), (SETd8cs)>; 300 301// (add OP, SETB) -> (addx OP, (move 0)) 302def : Pat<(add (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), MxDRD8:$op), 303 (ADDX8dd MxDRD8:$op, (MOV8di 0))>; 304def : Pat<(add (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1), MxXRD32:$op), 305 (ADDX32dd MxDRD32:$op, (MOV32ri 0))>; 306 307// (sub OP, SETB) -> (subx OP, (move 0)) 308def : Pat<(sub MxDRD8:$op, (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1)), 309 (SUBX8dd MxDRD8:$op, (MOV8di 0))>; 310def : Pat<(sub MxXRD32:$op, (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1)), 311 (SUBX32dd MxDRD32:$op, (MOV32ri 0))>; 312 313// (sub OP, SETCC_CARRY) -> (addx OP, (move 0)) 314def : Pat<(sub MxDRD8:$op, (i8 (MxSetCC_C MxCONDcs, CCR))), 315 (ADDX8dd MxDRD8:$op, (MOV8di 0))>; 316def : Pat<(sub MxXRD32:$op, (i32 (MxSetCC_C MxCONDcs, CCR))), 317 (ADDX32dd MxDRD32:$op, (MOV32ri 0))>; 318