brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.2 KiB · 4e94b2e Raw
437 lines · plain
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// 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  [~]     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 all29///   [!] - requires extarnal stuff implemented30///   [~] - in progress but usable31///   [x] - done32///33///34///                                   NOTE35///      Though branch and jump instructions are using memory operands they36///      DO NOT read the jump address from memory, they just calculate EA37///      and jump there.38///39//===----------------------------------------------------------------------===//40 41//===----------------------------------------------------------------------===//42// NOP43//===----------------------------------------------------------------------===//44 45let hasSideEffects = 0 in {46  def NOP : MxInst<(outs), (ins), "nop", []> {47    let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0001);48  }49}50 51 52//===----------------------------------------------------------------------===//53// Conditions54//===----------------------------------------------------------------------===//55 56/// CC—Carry clear      GE—Greater than or equal57/// LS—Lower or same    PL—Plus58/// CS—Carry set        GT—Greater than59/// LT—Less than        T—Always true*60/// EQ—Equal            HI—Higher61/// MI—Minus            VC—Overflow clear62/// F—Never true*       LE—Less than or equal63/// NE—Not equal        VS—Overflow set64///65/// *Not applicable to the Bcc instructions.66class MxEncCondOp<bits<4> cond> {67  dag Value = (descend cond);68}69 70def MxCCt  : MxEncCondOp<0b0000>;71def MxCCf  : MxEncCondOp<0b0001>;72def MxCChi : MxEncCondOp<0b0010>;73def MxCCls : MxEncCondOp<0b0011>;74def MxCCcc : MxEncCondOp<0b0100>;75def MxCCcs : MxEncCondOp<0b0101>;76def MxCCne : MxEncCondOp<0b0110>;77def MxCCeq : MxEncCondOp<0b0111>;78def MxCCvc : MxEncCondOp<0b1000>;79def MxCCvs : MxEncCondOp<0b1001>;80def MxCCpl : MxEncCondOp<0b1010>;81def MxCCmi : MxEncCondOp<0b1011>;82def MxCCge : MxEncCondOp<0b1100>;83def MxCClt : MxEncCondOp<0b1101>;84def MxCCgt : MxEncCondOp<0b1110>;85def MxCCle : MxEncCondOp<0b1111>;86 87 88 89/// --------------------------------+---------+---------90///  F  E  D  C | B  A  9  8 | 7  6 | 5  4  3 | 2  1  091/// --------------------------------+---------+---------92///  0  1  0  1 | CONDITION  | 1  1 |   MODE  |   REG93/// ----------------------------------------------------94 95let Uses = [CCR] in {96class MxSccR<string CC>97    : MxInst<(outs MxDRD8:$dst), (ins), "s"#CC#"\t$dst",98             [(set i8:$dst, (MxSetCC !cast<PatLeaf>("MxCOND"#CC), CCR))]> {99  let Inst = (descend 0b0101, !cast<MxEncCondOp>("MxCC"#CC).Value, 0b11,100              /*MODE without last bit*/0b00,101              /*REGISTER prefixed with D/A bit*/(operand "$dst", 4));102}103 104class MxSccM<string CC, MxOperand MEMOpd, ComplexPattern MEMPat, MxEncMemOp DST_ENC>105    : MxInst<(outs), (ins MEMOpd:$dst), "s"#CC#"\t$dst",106             [(store (MxSetCC !cast<PatLeaf>("MxCOND"#CC), CCR), MEMPat:$dst)]> {107  let Inst =108    (ascend109      (descend 0b0101, !cast<MxEncCondOp>("MxCC"#CC).Value, 0b11, DST_ENC.EA),110      DST_ENC.Supplement111    );112}113}114 115foreach cc = [ "cc", "ls", "lt", "eq", "mi", "f", "ne", "ge",116               "cs", "pl", "gt", "t", "hi", "vc", "le", "vs"] in {117def SET#"d8"#cc : MxSccR<cc>;118def SET#"j8"#cc : MxSccM<cc, MxType8.JOp, MxType8.JPat, MxEncAddrMode_j<"dst">>;119def SET#"p8"#cc : MxSccM<cc, MxType8.POp, MxType8.PPat, MxEncAddrMode_p<"dst">>;120}121 122//===----------------------------------------------------------------------===//123// Jumps124//===----------------------------------------------------------------------===//125 126///------------------------------+---------+---------127/// F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0128///------------------------------+---------+---------129/// 0  1  0  0  1  1  1  0  1  1 |  MODE   |   REG130///------------------------------+---------+---------131let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in132class MxJMP<MxOperand LOCOp, MxEncMemOp DST_ENC>133    : MxInst<(outs), (ins LOCOp:$dst), "jmp\t$dst", [(brind iPTR:$dst)]> {134  let Inst =135    (ascend136      (descend 0b0100, 0b1110, 0b11, DST_ENC.EA),137      DST_ENC.Supplement138    );139}140 141def JMP32j : MxJMP<MxARI32, MxEncAddrMode_j<"dst">>;142 143 144// FIXME Support 16 bit indirect jump.145// Currently M68k does not allow 16 bit indirect jumps use sext operands146// def JMP16r     : MxInst<(outs), (ins M68k_ARI16:$dst),147//                             "jmp\t$dst",148//                             [(brind AR16:$dst)]>;149 150//===----------------------------------------------------------------------===//151// Branches152//===----------------------------------------------------------------------===//153 154/// --------------------------------------------------155///  F  E  D  C | B  A  9  8 | 7  6  5  4  3  2  1  0156/// --------------------------------------------------157///  0  1  1  0 | CONDITION |   8-BIT DISPLACEMENT158/// --------------------------------------------------159///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00160/// --------------------------------------------------161///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF162/// --------------------------------------------------163let isBranch = 1, isTerminator = 1, Uses = [CCR] in164class MxBcc<string cc, Operand TARGET, dag disp_8, dag disp_16_32>165    : MxInst<(outs), (ins TARGET:$dst), "b"#cc#"\t$dst", []> {166  // FIXME: If we want to avoid supplying disp_16_32 with empty167  //        (ascend) for 16/32 bits variants, we can use conditional168  //        bang operator like this:169  //        ```170  //        class MxBcc<string cc, Operand TARGET, int SIZE>171  //        ...172  //        let Inst = !cond(173  //            !eq(SIZE, 8):   /* encoding for Bcc8  */174  //            !eq(SIZE, 16):  /* encoding for Bcc16 */175  //            !eq(SIZE, 32):  /* encoding for Bcc32 */176  //        );177  let Inst =178      (ascend179        (descend 0b0110, !cast<MxEncCondOp>("MxCC"#cc).Value, disp_8),180        disp_16_32181      );182 183  let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);184}185 186foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",187               "cs", "pl", "gt", "hi", "vc", "le", "vs"] in {188  def B#cc#"8"189    : MxBcc<cc, MxBrTarget8,190            (operand "$dst", 8, (encoder "encodePCRelImm<8>")), (ascend)>;191 192  def B#cc#"16"193    : MxBcc<cc, MxBrTarget16, (descend 0b0000, 0b0000),194            (operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;195 196  def B#cc#"32"197    : MxBcc<cc, MxBrTarget32, (descend 0b1111, 0b1111),198            (operand "$dst", 32, (encoder "encodePCRelImm<32>"))>;199}200 201foreach cc = [ "cc", "ls", "lt", "eq", "mi", "ne", "ge",202               "cs", "pl", "gt", "hi", "vc", "le", "vs"] in {203def : Pat<(MxBrCond bb:$target, !cast<PatLeaf>("MxCOND"#cc), CCR),204          (!cast<Instruction>("B"#cc#"8") MxBrTarget8:$target)>;205}206 207/// -------------------------------------------------208///  F  E  D  C  B  A  9  8 | 7  6  5  4  3  2  1  0209/// -------------------------------------------------210///  0  1  1  0  0  0  0  0 |   8-BIT DISPLACEMENT211/// -------------------------------------------------212///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00213/// -------------------------------------------------214///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF215/// -------------------------------------------------216let isBranch = 1, isTerminator = 1, isBarrier = 1 in217class MxBra<Operand TARGET, dag disp_8, dag disp_16_32>218    : MxInst<(outs), (ins TARGET:$dst), "bra\t$dst", []> {219  let Inst =220    (ascend221      (descend 0b0110, 0b0000, disp_8),222      disp_16_32223    );224  225  let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);226}227 228def BRA8  : MxBra<MxBrTarget8,229                  (operand "$dst", 8, (encoder "encodePCRelImm<8>")), (ascend)>;230 231def BRA16 : MxBra<MxBrTarget16, (descend 0b0000, 0b0000),232                  (operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;233 234def BRA32 : MxBra<MxBrTarget32, (descend 0b1111, 0b1111),235                  (operand "$dst", 32, (encoder "encodePCRelImm<32>"),236                                       (decoder "DecodeImm32"))>;237 238def : Pat<(br bb:$target), (BRA8 MxBrTarget8:$target)>;239 240/// -------------------------------------------------241///  F  E  D  C  B  A  9  8 | 7  6  5  4  3  2  1  0242/// -------------------------------------------------243///  0  1  1  0  0  0  0  1 |   8-BIT DISPLACEMENT244/// -------------------------------------------------245///  16-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $00246/// -------------------------------------------------247///  32-BIT DISPLACEMENT IF 8-BIT DISPLACEMENT = $FF248/// -------------------------------------------------249 250let isBranch = 1, isTerminator = 1 in251class MxBsr<Operand TARGET, MxType TYPE, dag disp_8, dag disp_16_32>252    : MxInst<(outs), (ins TARGET:$dst), "bsr."#TYPE.Prefix#"\t$dst"> {253  let Inst = (ascend254                (descend 0b0110, 0b0001, disp_8),255                 disp_16_32256              );257  let Predicates = !if(!eq(TARGET, MxBrTarget32), [AtLeastM68020], []);258}259 260def BSR8 : MxBsr<MxBrTarget8, MxType8,261                (operand "$dst", 8, (encoder "encodePCRelImm<8>")), (ascend)>;262 263def BSR16 : MxBsr<MxBrTarget16, MxType16, (descend 0b0000, 0b0000),264                (operand "$dst", 16, (encoder "encodePCRelImm<16>"))>;265 266def BSR32 : MxBsr<MxBrTarget32, MxType32, (descend 0b1111, 0b1111),267                (operand "$dst", 32, (encoder "encodePCRelImm<32>"),268                                     (decoder "DecodeImm32"))>;269 270//===----------------------------------------------------------------------===//271// Call272//===----------------------------------------------------------------------===//273 274// All calls clobber the non-callee saved registers. %SP is marked as275// a use to prevent stack-pointer assignments that appear immediately276// before calls from potentially appearing dead. Uses for argument277// registers are added manually.278let Uses = [SP] in279let isCall = 1 in280///------------------------------+---------+---------281/// F  E  D  C  B  A  9  8  7  6 | 5  4  3 | 2  1  0282///------------------------------+---------+---------283/// 0  1  0  0  1  1  1  0  1  0 |  MODE   |   REG284///------------------------------+---------+---------285class MxCall<MxOperand LOCOp, MxEncMemOp DST_ENC>286    : MxInst<(outs), (ins LOCOp:$dst), "jsr\t$dst", []> {287  let Inst =288    (ascend289      (descend 0b0100, 0b1110, 0b10, DST_ENC.EA),290      DST_ENC.Supplement291    );292}293 294def CALLk : MxCall<MxPCI32, MxEncAddrMode_k<"dst">>;295def CALLq : MxCall<MxPCD32, MxEncAddrMode_q<"dst">>;296def CALLb : MxCall<MxAL32,  MxEncAddrMode_abs<"dst", true>>;297def CALLj : MxCall<MxARI32, MxEncAddrMode_j<"dst">>;298 299multiclass CallPat<MxCall callOp, Predicate pred> {300  let Predicates = [pred] in {301    def : Pat<(MxCall (i32 tglobaladdr:$dst)),  (callOp tglobaladdr:$dst)>;302    def : Pat<(MxCall (i32 texternalsym:$dst)), (callOp texternalsym:$dst)>;303    def : Pat<(MxCall (i32 imm:$dst)),          (callOp imm:$dst)>;304  }305}306 307defm : CallPat<CALLq, IsPIC>;308defm : CallPat<CALLb, IsNotPIC>;309 310def : Pat<(MxCall iPTR:$dst), (CALLj MxARI32:$dst)>;311 312//===----------------------------------------------------------------------===//313// Tail Call314//===----------------------------------------------------------------------===//315 316let isCodeGenOnly = 1 in {317let Uses = [SP] in {318let isCall = 1, isTerminator = 1, isBarrier = 1 in {319 320let isReturn = 1 in321def TCRETURNq : MxPseudo<(outs), (ins MxPCD32:$dst,    i32imm:$adj)>;322def TAILJMPq  : MxPseudo<(outs), (ins MxPCD32:$dst)>;323 324// NOTE j does not mean load and jump M68k jmp just calculates EA and jumps325// and it is using Mem form like (An) thus j letter.326let isReturn = 1 in327def TCRETURNj : MxPseudo<(outs), (ins MxARI32_TC:$dst, i32imm:$adj)>;328def TAILJMPj  : MxPseudo<(outs), (ins MxARI32_TC:$dst)>;329} // isCall = 1, isTerminator = 1, isBarrier = 1330} // Uses = [SP]331} // isCodeGenOnly = 1332 333//===----------------------------------------------------------------------===//334// Return335//===----------------------------------------------------------------------===//336 337let isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1 in {338 339def RTS : MxInst<(outs), (ins), "rts", []> {340  let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0101);341}342 343def RTE: MxInst<(outs), (ins), "rte", []> {344  let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0011);345}346 347let isCodeGenOnly = 1 in348def RET : MxPseudo<(outs), (ins i32imm:$adj, variable_ops),349                   [(MxRet timm:$adj)]>;350} // isTerminator = 1, isReturn = 1, isBarrier = 1, hasCtrlDep = 1351 352//===----------------------------------------------------------------------===//353// SETCC_C Patterns354//===----------------------------------------------------------------------===//355 356// Use subx to materialize carry bit.357let Uses = [CCR], Defs = [CCR], isPseudo = 1 in {358// FIXME These are pseudo ops that should be replaced with Pat<> patterns.359// However, Pat<> can't replicate the destination reg into the inputs of the360// result.361def SETCS_C8d : MxPseudo<(outs MxDRD8:$dst), (ins),362                         [(set MxDRD8:$dst, (MxSetCC_C MxCONDcs, CCR))]>;363def SETCS_C16d : MxPseudo<(outs MxDRD16:$dst), (ins),364                          [(set MxDRD16:$dst, (MxSetCC_C MxCONDcs, CCR))]>;365def SETCS_C32d : MxPseudo<(outs MxXRD32:$dst), (ins),366                          [(set MxXRD32:$dst, (MxSetCC_C MxCONDcs, CCR))]>;367} // Uses = [CCR], Defs = [CCR], isPseudo = 1368 369 370def : Pat<(i16 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>;371def : Pat<(i32 (anyext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>;372 373def : Pat<(i16 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C16d)>;374def : Pat<(i32 (sext (i8 (MxSetCC_C MxCONDcs, CCR)))), (SETCS_C32d)>;375 376// We canonicalize 'scs' to "(and (subx reg,reg), 1)" on the hope that the and377// will be eliminated and that the subx can be extended up to a wider type.  When378// this happens, it is great.  However, if we are left with an 8-bit subx and an379// and, we might as well just match it as a setb.380def : Pat<(and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), (SETd8cs)>;381 382// (add OP, SETB) -> (addx OP, (move 0))383def : Pat<(add (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1), MxDRD8:$op),384          (ADDX8dd MxDRD8:$op, (MOV8di 0))>;385def : Pat<(add (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1), MxXRD32:$op),386          (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;387 388// (sub OP, SETB) -> (subx OP, (move 0))389def : Pat<(sub MxDRD8:$op, (and (i8 (MxSetCC_C MxCONDcs, CCR)), 1)),390          (SUBX8dd MxDRD8:$op, (MOV8di 0))>;391def : Pat<(sub MxXRD32:$op, (and (i32 (MxSetCC_C MxCONDcs, CCR)), 1)),392          (SUBX32dd MxDRD32:$op, (MOV32ri 0))>;393 394// (sub OP, SETCC_CARRY) -> (addx OP, (move 0))395def : Pat<(sub MxDRD8:$op, (i8 (MxSetCC_C MxCONDcs, CCR))),396          (ADDX8dd MxDRD8:$op, (MOV8di 0))>;397def : Pat<(sub MxXRD32:$op, (i32 (MxSetCC_C MxCONDcs, CCR))),398          (ADDX32dd MxDRD32:$op, (MOV32ri 0))>;399 400//===------------===//401// Trap / Breakpoint402//===------------===//403 404let RenderMethod = "addImmOperands", ParserMethod = "parseImm" in {405  def MxTrapImm : AsmOperandClass {406    let Name = "MxTrapImm";407    let PredicateMethod = "isTrapImm";408  }409 410  def MxBkptImm : AsmOperandClass {411    let Name = "MxBkptImm";412    let PredicateMethod = "isBkptImm";413  }414}415 416let ParserMatchClass = MxTrapImm in417def MxTrapimm : MxOp<i8,  MxSize8,  "i">;418 419let ParserMatchClass = MxBkptImm in420def MxBkptimm : MxOp<i8,  MxSize8,  "i">;421 422def TRAP : MxInst<(outs), (ins MxTrapimm:$vect), "trap\t$vect", []> {423  let Inst = (descend 0b0100, 0b1110, 0b0100, (operand "$vect", 4));424}425 426def TRAPV : MxInst<(outs), (ins), "trapv", []> {427  let Inst = (descend 0b0100, 0b1110, 0b0111, 0b0110);428}429 430def BKPT : MxInst<(outs), (ins MxBkptimm:$vect), "bkpt\t$vect", []> {431  let Inst = (descend 0b0100, 0b1000, 0b0100, 0b1 , (operand "$vect", 3));432}433 434def ILLEGAL : MxInst<(outs), (ins), "illegal", []> {435  let Inst = (descend 0b0100, 0b1010, 0b1111, 0b1100);436}437