brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.2 KiB · 1200c49 Raw
831 lines · plain
1//===-- M68kInstrInfo.td - Main M68k Instruction Definition -*- 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 instruction set, defining the instructions11/// and properties of the instructions which are needed for code generation,12/// machine code emission, and analysis.13///14//===----------------------------------------------------------------------===//15 16include "M68kInstrFormats.td"17 18//===----------------------------------------------------------------------===//19// Profiles20//===----------------------------------------------------------------------===//21 22def MxSDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;23def MxSDT_CallSeqEnd   : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;24 25def MxSDT_Call    : SDTypeProfile<0, -1, [SDTCisVT<0, iPTR>]>;26 27def MxSDT_Ret     : SDTypeProfile<0, -1, [28  /* ADJ */ SDTCisVT<0, i32>29]>;30 31def MxSDT_TCRet   : SDTypeProfile<0, 2, [SDTCisPtrTy<0>, SDTCisVT<1, i32>]>;32 33def MxSDT_Wrapper : SDTypeProfile<1, 1, [SDTCisSameAs<0, 1>, SDTCisPtrTy<0>]>;34 35def MxSDT_UnArithCCROut : SDTypeProfile<2, 1, [36  /* RES */ SDTCisInt<0>,37  /* CCR */ SDTCisVT<1, i8>,38  /* OPD */ SDTCisSameAs<0, 2>39]>;40 41// RES, CCR <- op LHS, RHS42def MxSDT_BiArithCCROut : SDTypeProfile<2, 2, [43  /* RES */ SDTCisInt<0>,44  /* CCR */ SDTCisVT<1, i8>,45  /* LHS */ SDTCisSameAs<0, 2>,46  /* RHS */ SDTCisSameAs<0, 3>47]>;48 49// RES, CCR <- op LHS, RHS, CCR50def MxSDT_BiArithCCRInOut : SDTypeProfile<2, 3, [51  /* RES 1 */ SDTCisInt<0>,52  /*   CCR */ SDTCisVT<1, i8>,53  /*   LHS */ SDTCisSameAs<0, 2>,54  /*   RHS */ SDTCisSameAs<0, 3>,55  /*   CCR */ SDTCisSameAs<1, 4>56]>;57 58def MxSDT_CmpTest : SDTypeProfile<1, 2, [59   /* CCR */ SDTCisVT<0, i8>,60   /* Ops */ SDTCisSameAs<1, 2>61]>;62 63def MxSDT_Cmov : SDTypeProfile<1, 4, [64  /*  ARG */ SDTCisSameAs<0, 1>,65  /*  ARG */ SDTCisSameAs<1, 2>,66  /* Cond */ SDTCisVT<3, i8>,67  /*  CCR */ SDTCisVT<4, i8>68]>;69 70def MxSDT_BrCond : SDTypeProfile<0, 3, [71  /* Dest */ SDTCisVT<0, OtherVT>,72  /* Cond */ SDTCisVT<1, i8>,73  /*  CCR */ SDTCisVT<2, i8>74]>;75 76def MxSDT_SetCC : SDTypeProfile<1, 2, [77  /* BOOL */ SDTCisVT<0, i8>,78  /* Cond */ SDTCisVT<1, i8>,79  /*  CCR */ SDTCisVT<2, i8>80]>;81 82def MxSDT_SetCC_C : SDTypeProfile<1, 2, [83  /* BOOL */ SDTCisInt<0>,84  /* Cond */ SDTCisVT<1, i8>,85  /*  CCR */ SDTCisVT<2, i8>86]>;87 88 89def MxSDT_SEG_ALLOCA : SDTypeProfile<1, 1,[90  /*  MEM */ SDTCisVT<0, iPTR>,91  /* SIZE */ SDTCisVT<1, iPTR>92]>;93 94 95//===----------------------------------------------------------------------===//96// Nodes97//===----------------------------------------------------------------------===//98 99def MxCallSeqStart : SDNode<"ISD::CALLSEQ_START", MxSDT_CallSeqStart,100                            [SDNPHasChain, SDNPOutGlue]>;101 102def MxCallSeqEnd   : SDNode<"ISD::CALLSEQ_END", MxSDT_CallSeqEnd,103                            [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;104 105def MxCall         : SDNode<"M68kISD::CALL", MxSDT_Call,106                            [SDNPHasChain, SDNPOutGlue,107                             SDNPOptInGlue, SDNPVariadic]>;108 109def MxRet   : SDNode<"M68kISD::RET", MxSDT_Ret,110                     [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>;111 112def MxTCRet : SDNode<"M68kISD::TC_RETURN", MxSDT_TCRet,113                     [SDNPHasChain,  SDNPOptInGlue, SDNPVariadic]>;114 115def MxGlobalBaseReg : SDNode<"M68kISD::GLOBAL_BASE_REG",116                             SDTypeProfile<1, 0, [SDTCisVT<0, iPTR>]>>;117 118// A wrapper node for TargetConstantPool,119// TargetExternalSymbol, and TargetGlobalAddress.120def MxWrapper   : SDNode<"M68kISD::Wrapper",   MxSDT_Wrapper>;121 122// Special wrapper used under M68k PIC mode for PC123// relative displacements.124def MxWrapperPC : SDNode<"M68kISD::WrapperPC", MxSDT_Wrapper>;125 126// Arithmetic operations with CCR results.127def MxAdd  : SDNode<"M68kISD::ADD",  MxSDT_BiArithCCROut, [SDNPCommutative]>;128def MxSub  : SDNode<"M68kISD::SUB",  MxSDT_BiArithCCROut>;129def MxOr   : SDNode<"M68kISD::OR",   MxSDT_BiArithCCROut, [SDNPCommutative]>;130def MxXor  : SDNode<"M68kISD::XOR",  MxSDT_BiArithCCROut, [SDNPCommutative]>;131def MxAnd  : SDNode<"M68kISD::AND",  MxSDT_BiArithCCROut, [SDNPCommutative]>;132 133def MxAddX : SDNode<"M68kISD::ADDX", MxSDT_BiArithCCRInOut>;134def MxSubX : SDNode<"M68kISD::SUBX", MxSDT_BiArithCCRInOut>;135 136def MxSMul : SDNode<"M68kISD::SMUL", MxSDT_BiArithCCROut, [SDNPCommutative]>;137def MxUMul : SDNode<"M68kISD::UMUL", MxSDT_BiArithCCROut, [SDNPCommutative]>;138 139// M68k compare and logical compare instructions. Subtracts the source140// operand from the destination data register and sets the condition141// codes according to the result. Immediate always goes first.142def MxCmp     : SDNode<"M68kISD::CMP", MxSDT_CmpTest>;143 144// M68k bit-test instructions.145def MxBtst    : SDNode<"M68kISD::BTST", MxSDT_CmpTest>;146 147// M68k conditional moves. Operand 0 and operand 1 are the two values148// to select from. Operand 2 is the condition code, and operand 3 is the149// flag operand produced by a CMP or TEST instruction. It also writes a150// flag result.151def MxCmov    : SDNode<"M68kISD::CMOV",        MxSDT_Cmov>;152 153// M68k conditional branches. Operand 0 is the chain operand, operand 1154// is the block to branch if condition is true, operand 2 is the155// condition code, and operand 3 is the flag operand produced by a CMP156// or TEST instruction.157def MxBrCond  : SDNode<"M68kISD::BRCOND",      MxSDT_BrCond, [SDNPHasChain]>;158 159// M68k SetCC. Operand 0 is condition code, and operand 1 is the CCR160// operand, usually produced by a CMP instruction.161def MxSetCC   : SDNode<"M68kISD::SETCC",       MxSDT_SetCC>;162 163// Same as SETCC except it's materialized with a subx and the value is all164// one's or all zero's.165def MxSetCC_C : SDNode<"M68kISD::SETCC_CARRY", MxSDT_SetCC_C>;166 167// For allocating variable amounts of stack space when using168// segmented stacks. Check if the current stacklet has enough space, and169// falls back to heap allocation if not.170def MxSegAlloca : SDNode<"M68kISD::SEG_ALLOCA", MxSDT_SEG_ALLOCA,171                         [SDNPHasChain]>;172 173 174//===----------------------------------------------------------------------===//175// Operands176//===----------------------------------------------------------------------===//177 178/// Size is the size of the data, either bits of a register or number of bits179/// addressed in memory. Size id is a letter that identifies size.180class MxSize<int num, string id, string full> {181  int Num = num;182  string Id = id;183  string Full = full;184}185 186def MxSize8  : MxSize<8,  "b", "byte">;187def MxSize16 : MxSize<16, "w", "word">;188def MxSize32 : MxSize<32, "l", "long">;189def MxSizeF32 : MxSize<32, "s", "f32">;190def MxSizeF64 : MxSize<64, "d", "f64">;191def MxSizeF80 : MxSize<80, "x", "f80">;192 193class MxOpClass<string name,194                list<AsmOperandClass> superClasses = []> : AsmOperandClass {195  let Name = name;196  let ParserMethod = "parseMemOp";197  let SuperClasses = superClasses;198}199 200def MxRegClass : MxOpClass<"Reg">;201// Splitting asm register class to avoid ambiguous on operands'202// MatchClassKind. For instance, without this separation,203// both ADD32dd and ADD32dr has {MCK_RegClass, MCK_RegClass} for204// their operands, which makes AsmParser unable to pick the correct205// one in a deterministic way.206let RenderMethod = "addRegOperands", SuperClasses = [MxRegClass]in {207  def MxARegClass : MxOpClass<"AReg">;208  def MxDRegClass : MxOpClass<"DReg">;209 210  def MxFPDRegClass : MxOpClass<"FPDReg">;211  def MxFPCRegClass : MxOpClass<"FPCReg">;212}213 214class MxOperand<ValueType vt, MxSize size, string letter, RegisterClass rc, dag pat = (null_frag)> {215  ValueType VT = vt;216  string Letter = letter;217  MxSize Size = size;218  RegisterClass RC = rc;219  dag Pat = pat;220}221 222class MxRegOp<ValueType vt,223              RegisterClass rc,224              MxSize size,225              string letter,226              string pm = "printOperand">227    : RegisterOperand<rc, pm>,228      MxOperand<vt, size, letter, rc> {229  let ParserMatchClass = MxRegClass;230}231 232// REGISTER DIRECT. The operand is in the data register specified by233// the effective address register field.234foreach size = [16, 32] in {235  def MxXRD # size : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("XR"#size),236                             !cast<MxSize>("MxSize"#size), "r">;237  def MxXRD # size # _TC : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("XR"#size#"_TC"),238                                   !cast<MxSize>("MxSize"#size), "r">;239} // foreach size240 241// DATA REGISTER DIRECT. The operand is in the data register specified by242// the effective address register field.243let ParserMatchClass = MxDRegClass in {244foreach size = [8, 16, 32] in {245  def MxDRD # size : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("DR"#size),246                             !cast<MxSize>("MxSize"#size), "d">;247  if !gt(size, 8) then248  def MxDRD # size # _TC : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("DR"#size#"_TC"),249                                   !cast<MxSize>("MxSize"#size), "d">;250} // foreach size251} // let ParserMatchClass252 253// ADDRESS REGISTER DIRECT. The operand is in the address register specified by254// the effective address register field.255let ParserMatchClass = MxARegClass in {256foreach size = [16, 32] in {257  def MxARD # size : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("AR"#size),258                             !cast<MxSize>("MxSize"#size), "a">;259  def MxARD # size # _TC : MxRegOp<!cast<ValueType>("i"#size), !cast<MxRegClass>("AR"#size#"_TC"),260                                   !cast<MxSize>("MxSize"#size), "a">;261} // foreach size262} // let ParserMatchClass263 264// FLOATING POINT DATA REGISTER.265let ParserMatchClass = MxFPDRegClass in {266  def MxFPR32 : MxRegOp<f32, FPDR32, MxSizeF32, "fp">;267  def MxFPR64 : MxRegOp<f64, FPDR64, MxSizeF64, "fp">;268  def MxFPR80 : MxRegOp<f80, FPDR80, MxSizeF80, "fp">;269}270 271// FLOATING POINT SYSTEM CONTROL REGISTER272let ParserMatchClass = MxFPCRegClass in {273  def MxFPCSR : MxRegOp<i32, FPCSC, MxSize32, "fpcs">;274  def MxFPIR  : MxRegOp<i32, FPIC,  MxSize32, "fpi">;275}276 277class MxMemOp<dag ops, MxSize size, string letter,278              string printMethod = "printOperand",279              AsmOperandClass parserMatchClass = ImmAsmOperand>280    : Operand<iPTR>, MxOperand<iPTR, size, letter, ?> {281  let PrintMethod = printMethod;282  let MIOperandInfo = ops;283  let ParserMatchClass = parserMatchClass;284  let OperandType = "OPERAND_MEMORY";285}286 287// ADDRESS REGISTER INDIRECT. The address of the operand is in the address288// register specified by the register field. The reference is classified as289// a data reference with the exception of the jump and jump-to-subroutine290// instructions.291def MxARI         : MxOpClass<"ARI">;292foreach size = ["8", "16", "32"] in {293  defvar ResSize = !cast<MxSize>("MxSize"#size);294  def MxARI # size       : MxMemOp<(ops AR32),    ResSize, "j", "printARI"#size#"Mem", MxARI>;295  def MxARI # size # _TC : MxMemOp<(ops AR32_TC), ResSize, "j", "printARI"#size#"Mem", MxARI>;296} // foreach size297 298// ADDRESS REGISTER INDIRECT WITH POSTINCREMENT. The address of the operand is299// in the address register specified by the register field. After the operand300// address is used, it is incremented by one, two, or four depending upon whether301// the size of the operand is byte, word, or long word. If the address register302// is the stack pointer and the operand size is byte, the address is incremented303// by two rather than one to keep the stack pointer on a word boundary.304// The reference is classified as a data reference.305def MxARIPI       : MxOpClass<"ARIPI">;306foreach size = ["8", "16", "32"] in {307  defvar ResSize = !cast<MxSize>("MxSize"#size);308  def MxARIPI # size       : MxMemOp<(ops AR32),    ResSize, "o", "printARIPI"#size#"Mem", MxARIPI>;309  def MxARIPI # size # _TC : MxMemOp<(ops AR32_TC), ResSize, "o", "printARIPI"#size#"Mem", MxARIPI>;310} // foreach size311 312// ADDRESS REGISTER INDIRECT WITH PREDECREMENT. The address of the operand is in313// the address register specified by the register field. Before the operand314// address is used, it is decremented by one, two, or four depending upon whether315// the operand size is byte, word, or long word. If the address register is316// the stack pointer and the operand size is byte, the address is decremented by317// two rather than one to keep the stack pointer on a word boundary.318// The reference is classified as a data reference.319def MxARIPD       : MxOpClass<"ARIPD">;320foreach size = ["8", "16", "32"] in {321  defvar ResSize = !cast<MxSize>("MxSize"#size);322  def MxARIPD # size       : MxMemOp<(ops AR32),    ResSize, "e", "printARIPD"#size#"Mem", MxARIPD>;323  def MxARIPD # size # _TC : MxMemOp<(ops AR32_TC), ResSize, "e", "printARIPD"#size#"Mem", MxARIPD>;324} // foreach size325 326// ADDRESS REGISTER INDIRECT WITH DISPLACEMENT. This addressing mode requires one327// word of extension. The address of the operand is the sum of the address in328// the address register and the sign-extended 16-bit displacement integer in the329// extension word. The reference is classified as a data reference with the330// exception of the jump and jump-to-subroutine instructions.331def MxARID        : MxOpClass<"ARID">;332foreach size = ["8", "16", "32"] in {333  defvar ResSize = !cast<MxSize>("MxSize"#size);334  def MxARID # size       : MxMemOp<(ops i16imm:$disp, AR32:$reg),    ResSize, "p", "printARID"#size#"Mem", MxARID>;335  def MxARID # size # _TC : MxMemOp<(ops i16imm:$disp, AR32_TC:$reg), ResSize, "p", "printARID"#size#"Mem", MxARID>;336} // foreach size337 338// ADDRESS REGISTER INDIRECT WITH INDEX. This addressing mode requires one word339// of extension. The address of the operand is the sum of the address in the340// address register, the signextended displacement integer in the low order eight341// bits of the extension word, and the contents of the index register.342// The reference is classified as a data reference with the exception of the343// jump and jump-to-subroutine instructions344def MxARII       : MxOpClass<"ARII">;345foreach size = ["8", "16", "32"] in {346  defvar ResSize = !cast<MxSize>("MxSize"#size);347  def MxARII # size       : MxMemOp<(ops i8imm:$disp, AR32:$reg,    XR32:$index), ResSize, "f", "printARII"#size#"Mem", MxARII>;348  def MxARII # size # _TC : MxMemOp<(ops i8imm:$disp, AR32_TC:$reg, XR32:$index), ResSize, "f", "printARII"#size#"Mem", MxARII>;349} // foreach size350 351// ABSOLUTE SHORT ADDRESS. This addressing mode requires one word of extension.352// The address of the operand is the extension word. The 16-bit address is sign353// extended before it is used.  The reference is classified as a data reference354// with the exception of the jump and jump-tosubroutine instructions.355def MxAddr     : MxOpClass<"Addr">;356let RenderMethod = "addAddrOperands" in {357  // This hierarchy ensures Addr8 will always be parsed358  // before other larger-width variants.359  def MxAddr32   : MxOpClass<"Addr32", [MxAddr]>;360  def MxAddr16   : MxOpClass<"Addr16", [MxAddr32]>;361  def MxAddr8    : MxOpClass<"Addr8",  [MxAddr16]>;362}363 364def MxAS8      : MxMemOp<(ops OtherVT), MxSize8,  "B", "printAS8Mem",  MxAddr8>;365def MxAS16     : MxMemOp<(ops OtherVT), MxSize16, "B", "printAS16Mem", MxAddr16>;366def MxAS32     : MxMemOp<(ops OtherVT), MxSize32, "B", "printAS32Mem", MxAddr32>;367 368// ABSOLUTE LONG ADDRESS. This addressing mode requires two words of extension.369// The address of the operand is developed by the concatenation of the extension370// words. The high order part of the address is the first extension word; the low371// order part of the address is the second extension word. The reference is372// classified as a data reference with the exception of the jump and jump373// to-subroutine instructions.374def MxAL8      : MxMemOp<(ops OtherVT), MxSize8,  "b", "printAL8Mem",  MxAddr8>;375def MxAL16     : MxMemOp<(ops OtherVT), MxSize16, "b", "printAL16Mem", MxAddr16>;376def MxAL32     : MxMemOp<(ops OtherVT), MxSize32, "b", "printAL32Mem", MxAddr32>;377 378def MxPCD : MxOpClass<"PCD">;379def MxPCI : MxOpClass<"PCI">;380 381let OperandType = "OPERAND_PCREL" in {382foreach size = ["8", "16", "32"] in {383defvar ResSize = !cast<MxSize>("MxSize"#size);384// PROGRAM COUNTER WITH DISPLACEMENT. This addressing mode requires one word of385// extension. The address of the operand is the sum of the address in the program386// counter and the Sign-extended 16-bit displacement integer in the extension387// word. The value in the program counter is the address of the extension word.388// The reference is classified as a program reference.389def MxPCD # size : MxMemOp<(ops i16imm), ResSize,  "q", "printPCD"#size#"Mem", MxPCD>;390 391// PROGRAM COUNTER WITH INDEX. This addressing mode requires one word of392// extension. The address is the sum of the address in the program counter, the393// sign-extended displacement integer in the lower eight bits of the extension394// word, and the contents of the index register.  The value in the program395// counter is the address of the extension word. This reference is classified as396// a program reference.397def MxPCI # size : MxMemOp<(ops i8imm:$disp, XR32:$index), ResSize,  "k", "printPCI"#size#"Mem", MxPCI>;398} // foreach size399} // OPERAND_PCREL400 401def MxImm : AsmOperandClass {402  let Name = "MxImm";403  let PredicateMethod = "isImm";404  let RenderMethod = "addImmOperands";405  let ParserMethod = "parseImm";406}407 408class MxOp<ValueType vt, MxSize size, string letter>409    : Operand<vt>,410      MxOperand<vt, size, letter, ?> {411  let ParserMatchClass = MxImm;412}413 414let OperandType = "OPERAND_IMMEDIATE",415    PrintMethod = "printImmediate" in {416// IMMEDIATE DATA. This addressing mode requires either one or two words of417// extension depending on the size of the operation.418//     Byte Operation - operand is low order byte of extension word419//     Word Operation - operand is extension word420//     Long Word Operation - operand is in the two extension words,421//                           high order 16 bits are in the first422//                           extension word, low order 16 bits are423//                           in the second extension word.424def Mxi8imm  : MxOp<i8,  MxSize8,  "i">;425def Mxi16imm : MxOp<i16, MxSize16, "i">;426def Mxi32imm : MxOp<i32, MxSize32, "i">;427} // OPERAND_IMMEDIATE428 429class MxBrTargetOperand<int N> : Operand<OtherVT> {430  let OperandType = "OPERAND_PCREL";431  let PrintMethod = "printPCRelImm";432  let ParserMatchClass = !cast<AsmOperandClass>("MxAddr"#N);433}434// Branch targets have OtherVT type and print as pc-relative values.435def MxBrTarget8  : MxBrTargetOperand<8>;436def MxBrTarget16 : MxBrTargetOperand<16>;437def MxBrTarget32 : MxBrTargetOperand<32>;438 439// Used with MOVEM440def MxMoveMaskClass : MxOpClass<"MoveMask">;441class MxMoveMaskOp : MxOp<i16, MxSize16, "m"> {442  let OperandType = "OPERAND_IMMEDIATE";443  let PrintMethod = "printMoveMask";444  let ParserMatchClass = MxMoveMaskClass;445}446 447def MxMoveMask : MxMoveMaskOp;448// The encoding of mask is reversed when the memory operand has an addressing449// mode of 'e', that is, pre-decrement.450def MxInverseMoveMask : MxMoveMaskOp {451  let EncoderMethod = "encodeInverseMoveMask";452}453 454//===----------------------------------------------------------------------===//455// Predicates456//===----------------------------------------------------------------------===//457 458def SmallCode    : Predicate<"TM.getCodeModel() == CodeModel::Small">;459def KernelCode   : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;460def FarData      : Predicate<"TM.getCodeModel() != CodeModel::Small &&"461                             "TM.getCodeModel() != CodeModel::Kernel">;462def NearData     : Predicate<"TM.getCodeModel() == CodeModel::Small ||"463                             "TM.getCodeModel() == CodeModel::Kernel">;464def IsPIC        : Predicate<"TM.isPositionIndependent()">;465def IsNotPIC     : Predicate<"!TM.isPositionIndependent()">;466 467// ISA versions468foreach i = [0,1,2,4,6] in469def AtLeastM680 # i # "0" : Predicate<"Subtarget->atLeastM680"#i#"0()">,470                            AssemblerPredicate<(all_of471                                                !cast<SubtargetFeature>("FeatureISA"#i#"0"))>;472def AtLeastM68881 : Predicate<"Subtarget->atLeastM68881()">,473                    AssemblerPredicate<(all_of FeatureISA881)>;474def AtLeastM68882 : Predicate<"Subtarget->atLeastM68882()">,475                    AssemblerPredicate<(all_of FeatureISA882)>;476 477//===----------------------------------------------------------------------===//478// Condition Codes479//480// These MUST be kept in sync with codes enum in M68kInstrInfo.h481//===----------------------------------------------------------------------===//482 483def MxCONDt   : PatLeaf<(i8 0)>;  // True484def MxCONDf   : PatLeaf<(i8 1)>;  // False485def MxCONDhi  : PatLeaf<(i8 2)>;  // High486def MxCONDls  : PatLeaf<(i8 3)>;  // Less or Same487def MxCONDcc  : PatLeaf<(i8 4)>;  // Carry Clear488def MxCONDcs  : PatLeaf<(i8 5)>;  // Carry Set489def MxCONDne  : PatLeaf<(i8 6)>;  // Not Equal490def MxCONDeq  : PatLeaf<(i8 7)>;  // Equal491def MxCONDvc  : PatLeaf<(i8 8)>;  // Overflow Clear492def MxCONDvs  : PatLeaf<(i8 9)>;  // Overflow Set493def MxCONDpl  : PatLeaf<(i8 10)>; // Plus494def MxCONDmi  : PatLeaf<(i8 11)>; // Minus495def MxCONDge  : PatLeaf<(i8 12)>; // Greater or Equal496def MxCONDlt  : PatLeaf<(i8 13)>; // Less Than497def MxCONDgt  : PatLeaf<(i8 14)>; // Greater Than498def MxCONDle  : PatLeaf<(i8 15)>; // Less or Equal499 500 501//===----------------------------------------------------------------------===//502// Complex Patterns503//===----------------------------------------------------------------------===//504 505// NOTE Though this CP is not strictly necessarily it will simplify instruciton506// definitions507let WantsParent = true in {508  def MxCP_ARI   : ComplexPattern<iPTR, 1, "SelectARI">;509 510  def MxCP_ARIPI : ComplexPattern<iPTR, 1, "SelectARIPI">;511 512  def MxCP_ARIPD : ComplexPattern<iPTR, 1, "SelectARIPD">;513 514  def MxCP_ARID  : ComplexPattern<iPTR, 2, "SelectARID",515                                  [add, sub, mul, or, shl, frameindex]>;516 517  def MxCP_ARII  : ComplexPattern<iPTR, 3, "SelectARII",518                                  [add, sub, mul, or, shl, frameindex]>;519 520  def MxCP_AL    : ComplexPattern<iPTR, 1, "SelectAL",521                                  [add, sub, mul, or, shl]>;522 523  def MxCP_PCD   : ComplexPattern<iPTR, 1, "SelectPCD",524                                  [add, sub, mul, or, shl]>;525 526  def MxCP_PCI   : ComplexPattern<iPTR, 2, "SelectPCI",527                                  [add, sub, mul, or, shl]>;528}529 530//===----------------------------------------------------------------------===//531// Pattern Fragments532//===----------------------------------------------------------------------===//533 534def Mxi8immSExt8  : PatLeaf<(i8  imm)>;535def MximmSExt8    : PatLeaf<(imm), [{ return isInt<8>(N->getSExtValue()); }]>;536 537def Mxi16immSExt16 : PatLeaf<(i16 imm)>;538def MximmSExt16    : PatLeaf<(imm), [{ return isInt<16>(N->getSExtValue()); }]>;539 540def Mxi32immSExt32 : PatLeaf<(i32 imm)>;541def MximmSExt32    : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;542 543// Used for Shifts and Rotations, since M68k immediates in these instructions544// are 1 <= i <= 8. Generally, if immediate is bigger than 8 it will be moved545// to a register and then an operation is performed.546//547// TODO Need to evaluate whether splitting one big shift(or rotate)548// into a few smaller is faster than doing a move, if so do custom lowering549def Mximm8_1to8   : ImmLeaf<i8,  [{ return Imm >= 1 && Imm <= 8; }]>;550def Mximm16_1to8  : ImmLeaf<i16, [{ return Imm >= 1 && Imm <= 8; }]>;551def Mximm32_1to8  : ImmLeaf<i32, [{ return Imm >= 1 && Imm <= 8; }]>;552 553// Helper fragments for loads.554// It's always safe to treat a anyext i16 load as a i32 load if the i16 is555// known to be 32-bit aligned or better. Ditto for i8 to i16.556def Mxloadi16 : PatFrag<(ops node:$ptr), (i16 (unindexedload node:$ptr)), [{557  LoadSDNode *LD = cast<LoadSDNode>(N);558  ISD::LoadExtType ExtType = LD->getExtensionType();559  if (ExtType == ISD::NON_EXTLOAD)560    return true;561  if (ExtType == ISD::EXTLOAD)562    return LD->getAlign() >= 2 && !LD->isSimple();563  return false;564}]>;565 566def Mxloadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{567  LoadSDNode *LD = cast<LoadSDNode>(N);568  ISD::LoadExtType ExtType = LD->getExtensionType();569  if (ExtType == ISD::NON_EXTLOAD)570    return true;571  if (ExtType == ISD::EXTLOAD)572    return LD->getAlign() >= 4 && !LD->isSimple();573  return false;574}]>;575 576def Mxloadi8         : PatFrag<(ops node:$ptr), (i8  (load node:$ptr))>;577 578def MxSExtLoadi16i8  : PatFrag<(ops node:$ptr), (i16 (sextloadi8 node:$ptr))>;579def MxSExtLoadi32i8  : PatFrag<(ops node:$ptr), (i32 (sextloadi8 node:$ptr))>;580def MxSExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (sextloadi16 node:$ptr))>;581 582def MxZExtLoadi8i1   : PatFrag<(ops node:$ptr), (i8  (zextloadi1 node:$ptr))>;583def MxZExtLoadi16i1  : PatFrag<(ops node:$ptr), (i16 (zextloadi1 node:$ptr))>;584def MxZExtLoadi32i1  : PatFrag<(ops node:$ptr), (i32 (zextloadi1 node:$ptr))>;585def MxZExtLoadi16i8  : PatFrag<(ops node:$ptr), (i16 (zextloadi8 node:$ptr))>;586def MxZExtLoadi32i8  : PatFrag<(ops node:$ptr), (i32 (zextloadi8 node:$ptr))>;587def MxZExtLoadi32i16 : PatFrag<(ops node:$ptr), (i32 (zextloadi16 node:$ptr))>;588 589def MxExtLoadi8i1    : PatFrag<(ops node:$ptr), (i8  (extloadi1 node:$ptr))>;590def MxExtLoadi16i1   : PatFrag<(ops node:$ptr), (i16 (extloadi1 node:$ptr))>;591def MxExtLoadi32i1   : PatFrag<(ops node:$ptr), (i32 (extloadi1 node:$ptr))>;592def MxExtLoadi16i8   : PatFrag<(ops node:$ptr), (i16 (extloadi8 node:$ptr))>;593def MxExtLoadi32i8   : PatFrag<(ops node:$ptr), (i32 (extloadi8 node:$ptr))>;594def MxExtLoadi32i16  : PatFrag<(ops node:$ptr), (i32 (extloadi16 node:$ptr))>;595 596 597//===----------------------------------------------------------------------===//598// Type Fixtures599//600// Type Fixtures are ValueType related information sets that usually go together601//===----------------------------------------------------------------------===//602 603// TODO make it folded like MxType8.F.Op nad MxType8.F.Pat604// TODO move strings into META subclass605// vt: Type of data this fixture refers to606// prefix: Prefix used to identify type607// postfix: Prefix used to qualify type608class MxType<ValueType vt, string prefix, string postfix,609             // rLet: Register letter610             // rOp:  Supported any register operand611             string rLet, MxOperand rOp,612             // jOp:  Supported ARI operand613             // jPat: What ARI pattern to use614             MxOperand jOp, ComplexPattern jPat,615             // oOp:  Supported ARIPI operand616             // oPat: What ARIPI pattern is used617             MxOperand oOp, ComplexPattern oPat,618             // eOp:  Supported ARIPD operand619             // ePat: What ARIPD pattern is used620             MxOperand eOp, ComplexPattern ePat,621             // pOp:  Supported ARID operand622             // pPat: What ARID pattern is used623             MxOperand pOp, ComplexPattern pPat,624             // fOp:  Supported ARII operand625             // fPat: What ARII pattern is used626             MxOperand fOp, ComplexPattern fPat,627             // bOp:  Supported absolute operand628             // bPat: What absolute pattern is used629             MxOperand bOp, ComplexPattern bPat,630             // qOp:  Supported PCD operand631             // qPat: What PCD pattern is used632             MxOperand qOp, ComplexPattern qPat,633             // kOp:  Supported PCI operand634             // kPat: What PCI pattern is used635             MxOperand kOp, ComplexPattern kPat,636             // iOp:  Supported immediate operand637             // iPat: What immediate pattern is used638             MxOperand iOp, PatFrag iPat,639             // load: What load operation is used with MEM640             PatFrag load> {641  int Size = vt.Size;642  ValueType VT = vt;643  string Prefix = prefix;644  string Postfix = postfix;645 646  string RLet = rLet;647  MxOperand ROp = rOp;648 649  MxOperand JOp = jOp;650  ComplexPattern JPat = jPat;651 652  MxOperand OOp = oOp;653  ComplexPattern OPat = oPat;654 655  MxOperand EOp = eOp;656  ComplexPattern EPat = ePat;657 658  MxOperand POp = pOp;659  ComplexPattern PPat = pPat;660 661  MxOperand FOp = fOp;662  ComplexPattern FPat = fPat;663 664  MxOperand BOp = bOp;665  ComplexPattern BPat = bPat;666 667  MxOperand QOp = qOp;668  ComplexPattern QPat = qPat;669 670  MxOperand KOp = kOp;671  ComplexPattern KPat = kPat;672 673  MxOperand IOp = iOp;674  PatFrag IPat = iPat;675 676  PatFrag Load = load;677}678 679// Provides an alternative way to access the MxOperand and680// patterns w.r.t a specific addressing mode.681class MxOpBundle<int size, MxOperand op, ComplexPattern pat> {682  int Size = size;683  MxOperand Op = op;684  ComplexPattern Pat = pat;685}686 687class MxImmOpBundle<int size, MxOperand op, PatFrag pat>688  : MxOpBundle<size, op, ?> {689  PatFrag ImmPat = pat;690}691 692// TODO: We can use MxOp<S>AddrMode_<AM> in more places to693// replace MxType-based operand factoring.694foreach size = [8, 16, 32] in {695  // Dn696  def MxOp#size#AddrMode_d697    : MxOpBundle<size, !cast<MxOperand>("MxDRD"#size), ?>;698 699  // (An)700  def MxOp#size#AddrMode_j701    : MxOpBundle<size, !cast<MxOperand>("MxARI"#size), MxCP_ARI>;702 703  // (An)+704  def MxOp#size#AddrMode_o705    : MxOpBundle<size, !cast<MxOperand>("MxARIPI"#size), MxCP_ARIPI>;706 707  // -(An)708  def MxOp#size#AddrMode_e709    : MxOpBundle<size, !cast<MxOperand>("MxARIPD"#size), MxCP_ARIPD>;710 711  // (i,An)712  def MxOp#size#AddrMode_p713    : MxOpBundle<size, !cast<MxOperand>("MxARID"#size), MxCP_ARID>;714 715  // (i,An,Xn)716  def MxOp#size#AddrMode_f717    : MxOpBundle<size, !cast<MxOperand>("MxARII"#size), MxCP_ARII>;718 719  // (ABS).L720  def MxOp#size#AddrMode_b721    : MxOpBundle<size, !cast<MxOperand>("MxAL"#size), MxCP_AL>;722 723  // (i,PC)724  def MxOp#size#AddrMode_q725    : MxOpBundle<size, !cast<MxOperand>("MxPCD"#size), MxCP_PCD>;726 727  // (i,PC,Xn)728  def MxOp#size#AddrMode_k729    : MxOpBundle<size, !cast<MxOperand>("MxPCI"#size), MxCP_PCI>;730 731  // #imm732  def MxOp#size#AddrMode_i733    : MxImmOpBundle<size, !cast<MxOperand>("Mxi"#size#"imm"),734                    !cast<PatFrag>("Mxi"#size#"immSExt"#size)>;735} // foreach size = [8, 16, 32]736 737foreach size = [16, 32] in {738  // An739  def MxOp#size#AddrMode_a740    : MxOpBundle<size, !cast<MxOperand>("MxARD"#size), ?>;741 742  // Xn743  def MxOp#size#AddrMode_r744    : MxOpBundle<size, !cast<MxOperand>("MxXRD"#size), ?>;745} // foreach size = [16, 32]746 747foreach size = [32, 64, 80] in748def MxOp#size#AddrMode_fpr749  : MxOpBundle<size, !cast<MxOperand>("MxFPR"#size), ?>;750 751def MxOp32AddrMode_fpcs : MxOpBundle<32, MxFPCSR, ?>;752def MxOp32AddrMode_fpi  : MxOpBundle<32, MxFPIR, ?>;753 754class MxType8Class<string rLet, MxOperand reg>755    : MxType<i8, "b", "", rLet, reg,756             MxARI8,   MxCP_ARI,757             MxARIPI8, MxCP_ARIPI,758             MxARIPD8, MxCP_ARIPD,759             MxARID8,  MxCP_ARID,760             MxARII8,  MxCP_ARII,761             MxAL8,    MxCP_AL,762             MxPCD8,   MxCP_PCD,763             MxPCI8,   MxCP_PCI,764             Mxi8imm,  Mxi8immSExt8,765             Mxloadi8>;766 767def MxType8 : MxType8Class<?,?>;768 769class MxType16Class<string rLet, MxOperand reg>770    : MxType<i16, "w", "", rLet, reg,771             MxARI16,   MxCP_ARI,772             MxARIPI16, MxCP_ARIPI,773             MxARIPD16, MxCP_ARIPD,774             MxARID16,  MxCP_ARID,775             MxARII16,  MxCP_ARII,776             MxAL16,    MxCP_AL,777             MxPCD16,   MxCP_PCD,778             MxPCI16,   MxCP_PCI,779             Mxi16imm,  Mxi16immSExt16,780             Mxloadi16>;781 782def MxType16 : MxType16Class<?,?>;783 784class MxType32Class<string rLet, MxOperand reg>785    : MxType<i32, "l", "", rLet, reg,786             MxARI32,   MxCP_ARI,787             MxARIPI32, MxCP_ARIPI,788             MxARIPD32, MxCP_ARIPD,789             MxARID32,  MxCP_ARID,790             MxARII32,  MxCP_ARII,791             MxAL32,    MxCP_AL,792             MxPCD32,   MxCP_PCD,793             MxPCI32,   MxCP_PCI,794             Mxi32imm,  Mxi32immSExt32,795             Mxloadi32>;796 797def MxType32 : MxType32Class<?,?>;798 799 800def MxType8d : MxType8Class<"d", MxDRD8>;801 802def MxType16d : MxType16Class<"d", MxDRD16>;803def MxType16a : MxType16Class<"a", MxARD16>;804def MxType16r : MxType16Class<"r", MxXRD16>;805def MxType32d : MxType32Class<"d", MxDRD32>;806def MxType32a : MxType32Class<"a", MxARD32>;807def MxType32r : MxType32Class<"r", MxXRD32>;808 809let Postfix = "_TC" in {810def MxType16d_TC : MxType16Class<"d", MxDRD16_TC>;811def MxType16a_TC : MxType16Class<"a", MxARD16_TC>;812def MxType16r_TC : MxType16Class<"r", MxXRD16_TC>;813def MxType32d_TC : MxType32Class<"d", MxDRD32_TC>;814def MxType32a_TC : MxType32Class<"a", MxARD32_TC>;815def MxType32r_TC : MxType32Class<"r", MxXRD32_TC>;816}817 818 819//===----------------------------------------------------------------------===//820// Subsystems821//===----------------------------------------------------------------------===//822 823include "M68kInstrData.td"824include "M68kInstrShiftRotate.td"825include "M68kInstrBits.td"826include "M68kInstrArithmetic.td"827include "M68kInstrControl.td"828include "M68kInstrAtomics.td"829 830include "M68kInstrCompiler.td"831