1*fe6060f1SDimitry Andric//== M68kInstrData.td - M68k Data Movement Instructions -*- tablegen --===// 2*fe6060f1SDimitry Andric// 3*fe6060f1SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*fe6060f1SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 5*fe6060f1SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*fe6060f1SDimitry Andric// 7*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 8*fe6060f1SDimitry Andric/// 9*fe6060f1SDimitry Andric/// \file 10*fe6060f1SDimitry Andric/// This file describes the Motorola 680x0 data movement instructions which are 11*fe6060f1SDimitry Andric/// the basic means of transferring and storing addresses and data. Here is the 12*fe6060f1SDimitry Andric/// current status of the file: 13*fe6060f1SDimitry Andric/// 14*fe6060f1SDimitry Andric/// Machine: 15*fe6060f1SDimitry Andric/// 16*fe6060f1SDimitry Andric/// EXG [ ] FMOVE [ ] FSMOVE [ ] FDMOVE [ ] FMOVEM [ ] 17*fe6060f1SDimitry Andric/// LEA [~] PEA [ ] MOVE [~] MOVE16 [ ] MOVEA [ ] 18*fe6060f1SDimitry Andric/// MOVEM [ ] MOVEP [ ] MOVEQ [ ] LINK [ ] UNLK [ ] 19*fe6060f1SDimitry Andric/// 20*fe6060f1SDimitry Andric/// Pseudo: 21*fe6060f1SDimitry Andric/// 22*fe6060f1SDimitry Andric/// MOVSX [x] MOVZX [x] MOVX [x] 23*fe6060f1SDimitry Andric/// 24*fe6060f1SDimitry Andric/// Map: 25*fe6060f1SDimitry Andric/// 26*fe6060f1SDimitry Andric/// [ ] - was not touched at all 27*fe6060f1SDimitry Andric/// [!] - requires extarnal stuff implemented 28*fe6060f1SDimitry Andric/// [~] - in progress but usable 29*fe6060f1SDimitry Andric/// [x] - done 30*fe6060f1SDimitry Andric/// 31*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 32*fe6060f1SDimitry Andric 33*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 34*fe6060f1SDimitry Andric// MOVE 35*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 36*fe6060f1SDimitry Andric 37*fe6060f1SDimitry Andric/// ----------------------------------------------------- 38*fe6060f1SDimitry Andric/// F E | D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0 39*fe6060f1SDimitry Andric/// ----------------------------------------------------- 40*fe6060f1SDimitry Andric/// | | DESTINATION | SOURCE 41*fe6060f1SDimitry Andric/// 0 0 | SIZE | REG | MODE | MODE | REG 42*fe6060f1SDimitry Andric/// ----------------------------------------------------- 43*fe6060f1SDimitry Andric/// 44*fe6060f1SDimitry Andric/// NOTE Move requires EA X version for direct register destination(0) 45*fe6060f1SDimitry Andricclass MxMoveEncoding<MxBead2Bits size, 46*fe6060f1SDimitry Andric MxEncEA srcEA, MxEncExt srcExt, 47*fe6060f1SDimitry Andric MxEncEA dstEA, MxEncExt dstExt> 48*fe6060f1SDimitry Andric : MxEncoding<srcEA.Reg, srcEA.DA, srcEA.Mode, dstEA.DA, dstEA.Mode, dstEA.Reg, 49*fe6060f1SDimitry Andric size, MxBead2Bits<0b00>, 50*fe6060f1SDimitry Andric srcExt.Imm, srcExt.B8, srcExt.Scale, srcExt.WL, srcExt.DAReg, 51*fe6060f1SDimitry Andric dstExt.Imm, dstExt.B8, dstExt.Scale, dstExt.WL, dstExt.DAReg>; 52*fe6060f1SDimitry Andric 53*fe6060f1SDimitry Andric/// MOVE has alternate size encoding 54*fe6060f1SDimitry Andricclass MxMoveSize<bits<2> value> : MxBead2Bits<value>; 55*fe6060f1SDimitry Andricdef MxMoveSize8 : MxMoveSize<0b01>; 56*fe6060f1SDimitry Andricdef MxMoveSize16 : MxMoveSize<0b11>; 57*fe6060f1SDimitry Andricdef MxMoveSize32 : MxMoveSize<0b10>; 58*fe6060f1SDimitry Andric 59*fe6060f1SDimitry Andriclet Defs = [CCR] in 60*fe6060f1SDimitry Andricclass MxMove<string size, dag outs, dag ins, list<dag> pattern, MxEncoding enc> 61*fe6060f1SDimitry Andric : MxInst<outs, ins, "move."#size#"\t$src, $dst", pattern, enc>; 62*fe6060f1SDimitry Andric 63*fe6060f1SDimitry Andricclass MxMove_RR<MxType DST, MxType SRC, MxMoveEncoding ENC> 64*fe6060f1SDimitry Andric : MxMove<DST.Prefix, (outs DST.ROp:$dst), (ins SRC.ROp:$src), 65*fe6060f1SDimitry Andric [(null_frag)], ENC>; 66*fe6060f1SDimitry Andric 67*fe6060f1SDimitry Andriclet mayStore = 1 in { 68*fe6060f1SDimitry Andricclass MxMove_MR<MxOperand MEMOpd, ComplexPattern MEMPat, MxType REG, 69*fe6060f1SDimitry Andric MxMoveEncoding ENC> 70*fe6060f1SDimitry Andric : MxMove<REG.Prefix, (outs), (ins MEMOpd:$dst, REG.ROp:$src), 71*fe6060f1SDimitry Andric [(store REG.VT:$src, MEMPat:$dst)], ENC>; 72*fe6060f1SDimitry Andric 73*fe6060f1SDimitry Andricclass MxMove_MI<MxOperand MEMOpd, ComplexPattern MEMPat, MxType TYPE, 74*fe6060f1SDimitry Andric MxMoveEncoding ENC> 75*fe6060f1SDimitry Andric : MxMove<TYPE.Prefix, (outs), (ins MEMOpd:$dst, TYPE.IOp:$src), 76*fe6060f1SDimitry Andric [(store TYPE.IPat:$src, MEMPat:$dst)], ENC>; 77*fe6060f1SDimitry Andric} // let mayStore = 1 78*fe6060f1SDimitry Andric 79*fe6060f1SDimitry Andricclass MxMove_RI<MxType DST, MxMoveEncoding ENC> 80*fe6060f1SDimitry Andric : MxMove<DST.Prefix, (outs DST.ROp:$dst), (ins DST.IOp:$src), 81*fe6060f1SDimitry Andric [(set DST.VT:$dst, DST.IPat:$src)], ENC>; 82*fe6060f1SDimitry Andric 83*fe6060f1SDimitry Andric 84*fe6060f1SDimitry Andriclet mayLoad = 1 in 85*fe6060f1SDimitry Andricclass MxMove_RM<MxType REG, MxOperand MEMOpd, ComplexPattern MEMPat, 86*fe6060f1SDimitry Andric MxBead2Bits SIZE, 87*fe6060f1SDimitry Andric MxEncEA SRCEA, MxEncExt SRCEXT, 88*fe6060f1SDimitry Andric MxEncEA DSTEA, MxEncExt DSTEXT> 89*fe6060f1SDimitry Andric : MxMove<REG.Prefix, (outs REG.ROp:$dst), (ins MEMOpd:$src), 90*fe6060f1SDimitry Andric [(set REG.VT:$dst, (REG.Load MEMPat:$src))], 91*fe6060f1SDimitry Andric MxMoveEncoding<SIZE, SRCEA, SRCEXT, DSTEA, DSTEXT>>; 92*fe6060f1SDimitry Andric 93*fe6060f1SDimitry Andricmulticlass MMxMove_RM<MxType REG, MxMoveSize SIZE, MxEncEA EA_0> { 94*fe6060f1SDimitry Andric 95*fe6060f1SDimitry Andric // REG <- (An)+ 96*fe6060f1SDimitry Andric def NAME#REG.OOp.Letter#REG.Postfix : MxMove_RM<REG, REG.OOp, REG.OPat, 97*fe6060f1SDimitry Andric SIZE, MxEncEAo_1, MxExtEmpty, EA_0, MxExtEmpty>; 98*fe6060f1SDimitry Andric 99*fe6060f1SDimitry Andric // REG <- -(An) 100*fe6060f1SDimitry Andric def NAME#REG.EOp.Letter#REG.Postfix : MxMove_RM<REG, REG.EOp, REG.EPat, 101*fe6060f1SDimitry Andric SIZE, MxEncEAe_1, MxExtEmpty, EA_0, MxExtEmpty>; 102*fe6060f1SDimitry Andric 103*fe6060f1SDimitry Andric // REG <- (i,PC,Xn) 104*fe6060f1SDimitry Andric def NAME#REG.KOp.Letter#REG.Postfix : MxMove_RM<REG, REG.KOp, REG.KPat, 105*fe6060f1SDimitry Andric SIZE, MxEncEAk, MxExtBrief_1, EA_0, MxExtEmpty>; 106*fe6060f1SDimitry Andric 107*fe6060f1SDimitry Andric // REG <- (i,PC) 108*fe6060f1SDimitry Andric def NAME#REG.QOp.Letter#REG.Postfix : MxMove_RM<REG, REG.QOp, REG.QPat, 109*fe6060f1SDimitry Andric SIZE, MxEncEAq, MxExtI16_1, EA_0, MxExtEmpty>; 110*fe6060f1SDimitry Andric 111*fe6060f1SDimitry Andric // REG <- (i,An,Xn) 112*fe6060f1SDimitry Andric def NAME#REG.FOp.Letter#REG.Postfix : MxMove_RM<REG, REG.FOp, REG.FPat, 113*fe6060f1SDimitry Andric SIZE, MxEncEAf_1, MxExtBrief_1, EA_0, MxExtEmpty>; 114*fe6060f1SDimitry Andric 115*fe6060f1SDimitry Andric // REG <- (i,An) 116*fe6060f1SDimitry Andric def NAME#REG.POp.Letter#REG.Postfix : MxMove_RM<REG, REG.POp, REG.PPat, 117*fe6060f1SDimitry Andric SIZE, MxEncEAp_1, MxExtI16_1, EA_0, MxExtEmpty>; 118*fe6060f1SDimitry Andric 119*fe6060f1SDimitry Andric // REG <- (ABS) 120*fe6060f1SDimitry Andric def NAME#REG.BOp.Letter#REG.Postfix : MxMove_RM<REG, REG.BOp, REG.BPat, 121*fe6060f1SDimitry Andric SIZE, MxEncEAb, MxExtI32_1, EA_0, MxExtEmpty>; 122*fe6060f1SDimitry Andric 123*fe6060f1SDimitry Andric // REG <- (An) 124*fe6060f1SDimitry Andric def NAME#REG.JOp.Letter#REG.Postfix : MxMove_RM<REG, REG.JOp, REG.JPat, 125*fe6060f1SDimitry Andric SIZE, MxEncEAj_1, MxExtEmpty, EA_0, MxExtEmpty>; 126*fe6060f1SDimitry Andric} 127*fe6060f1SDimitry Andric 128*fe6060f1SDimitry Andriclet mayLoad = 1, mayStore = 1 in { 129*fe6060f1SDimitry Andricclass MxMove_MM<string SIZE, PatFrag LOAD, 130*fe6060f1SDimitry Andric MxOperand DSTOpd, ComplexPattern DSTPat, 131*fe6060f1SDimitry Andric MxOperand SRCOpd, ComplexPattern SRCPat, 132*fe6060f1SDimitry Andric MxBead2Bits ESIZE, 133*fe6060f1SDimitry Andric MxEncEA SRCEA, MxEncExt SRCEXT, 134*fe6060f1SDimitry Andric MxEncEA DSTEA, MxEncExt DSTEXT> 135*fe6060f1SDimitry Andric : MxMove<SIZE, (outs), (ins DSTOpd:$dst, SRCOpd:$src), 136*fe6060f1SDimitry Andric [(store (LOAD SRCPat:$src), DSTPat:$dst)], 137*fe6060f1SDimitry Andric MxMoveEncoding<ESIZE, SRCEA, SRCEXT, DSTEA, DSTEXT>>; 138*fe6060f1SDimitry Andric} // let mayLoad = 1, mayStore = 1 139*fe6060f1SDimitry Andric 140*fe6060f1SDimitry Andricmulticlass MMxMove_MM<MxType TYPE, MxOperand DSTOpd, ComplexPattern DSTPat, 141*fe6060f1SDimitry Andric MxMoveSize SIZE, MxEncEA EA_0, MxEncExt EXT_0> { 142*fe6060f1SDimitry Andric 143*fe6060f1SDimitry Andric // MEM <- (An)+ 144*fe6060f1SDimitry Andric def NAME#TYPE.OOp.Letter#TYPE.Postfix 145*fe6060f1SDimitry Andric : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.OOp, TYPE.OPat, 146*fe6060f1SDimitry Andric SIZE, MxEncEAo_1, MxExtEmpty, EA_0, EXT_0>; 147*fe6060f1SDimitry Andric 148*fe6060f1SDimitry Andric // MEM <- -(An) 149*fe6060f1SDimitry Andric def NAME#TYPE.EOp.Letter#TYPE.Postfix 150*fe6060f1SDimitry Andric : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.EOp, TYPE.EPat, 151*fe6060f1SDimitry Andric SIZE, MxEncEAe_1, MxExtEmpty, EA_0, EXT_0>; 152*fe6060f1SDimitry Andric 153*fe6060f1SDimitry Andric // MEM <- (i,An) 154*fe6060f1SDimitry Andric def NAME#TYPE.POp.Letter#TYPE.Postfix 155*fe6060f1SDimitry Andric : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.POp, TYPE.PPat, 156*fe6060f1SDimitry Andric SIZE, MxEncEAp_1, MxExtI16_1, EA_0, EXT_0>; 157*fe6060f1SDimitry Andric 158*fe6060f1SDimitry Andric // MEM <- (i,An,Xn) 159*fe6060f1SDimitry Andric def NAME#TYPE.FOp.Letter#TYPE.Postfix 160*fe6060f1SDimitry Andric : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.FOp, TYPE.FPat, 161*fe6060f1SDimitry Andric SIZE, MxEncEAf_1, MxExtBrief_1, EA_0, EXT_0>; 162*fe6060f1SDimitry Andric 163*fe6060f1SDimitry Andric // MEM <- (i,PC,Xn) 164*fe6060f1SDimitry Andric def NAME#TYPE.KOp.Letter#TYPE.Postfix 165*fe6060f1SDimitry Andric : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.KOp, TYPE.KPat, 166*fe6060f1SDimitry Andric SIZE, MxEncEAk, MxExtBrief_1, EA_0, EXT_0>; 167*fe6060f1SDimitry Andric 168*fe6060f1SDimitry Andric // MEM <- (i,PC) 169*fe6060f1SDimitry Andric def NAME#TYPE.QOp.Letter#TYPE.Postfix 170*fe6060f1SDimitry Andric : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.QOp, TYPE.QPat, 171*fe6060f1SDimitry Andric SIZE, MxEncEAq, MxExtI16_1, EA_0, EXT_0>; 172*fe6060f1SDimitry Andric 173*fe6060f1SDimitry Andric // MEM <- (ABS) 174*fe6060f1SDimitry Andric def NAME#TYPE.BOp.Letter#TYPE.Postfix 175*fe6060f1SDimitry Andric : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.BOp, TYPE.BPat, 176*fe6060f1SDimitry Andric SIZE, MxEncEAb, MxExtI32_1, EA_0, EXT_0>; 177*fe6060f1SDimitry Andric 178*fe6060f1SDimitry Andric // MEM <- (An) 179*fe6060f1SDimitry Andric def NAME#TYPE.JOp.Letter#TYPE.Postfix 180*fe6060f1SDimitry Andric : MxMove_MM<TYPE.Prefix, TYPE.Load, DSTOpd, DSTPat, TYPE.JOp, TYPE.JPat, 181*fe6060f1SDimitry Andric SIZE, MxEncEAj_1, MxExtEmpty, EA_0, EXT_0>; 182*fe6060f1SDimitry Andric} 183*fe6060f1SDimitry Andric 184*fe6060f1SDimitry Andricdef MOV8dd 185*fe6060f1SDimitry Andric : MxMove_RR<MxType8d, MxType8d, 186*fe6060f1SDimitry Andric MxMoveEncoding<MxMoveSize8, MxEncEAd_1, MxExtEmpty, MxEncEAd_0, MxExtEmpty>>; 187*fe6060f1SDimitry Andric 188*fe6060f1SDimitry Andric// M <- R 189*fe6060f1SDimitry Andricdef MOV8fd : MxMove_MR<MxType8.FOp, MxType8.FPat, MxType8d, 190*fe6060f1SDimitry Andric MxMoveEncoding<MxMoveSize8, 191*fe6060f1SDimitry Andric /*src*/ MxEncEAd_1, MxExtEmpty, 192*fe6060f1SDimitry Andric /*dst*/ MxEncEAf_0, MxExtBrief_0>>; 193*fe6060f1SDimitry Andric 194*fe6060f1SDimitry Andricdef MOV8pd : MxMove_MR<MxType8.POp, MxType8.PPat, MxType8d, 195*fe6060f1SDimitry Andric MxMoveEncoding<MxMoveSize8, 196*fe6060f1SDimitry Andric /*src*/ MxEncEAd_1, MxExtEmpty, 197*fe6060f1SDimitry Andric /*dst*/ MxEncEAp_0, MxExtI16_0>>; 198*fe6060f1SDimitry Andric 199*fe6060f1SDimitry Andricdef MOV8ed : MxMove_MR<MxType8.EOp, MxType8.EPat, MxType8d, 200*fe6060f1SDimitry Andric MxMoveEncoding<MxMoveSize8, 201*fe6060f1SDimitry Andric /*src*/ MxEncEAd_1, MxExtEmpty, 202*fe6060f1SDimitry Andric /*dst*/ MxEncEAe_0, MxExtEmpty>>; 203*fe6060f1SDimitry Andric 204*fe6060f1SDimitry Andricdef MOV8od : MxMove_MR<MxType8.OOp, MxType8.OPat, MxType8d, 205*fe6060f1SDimitry Andric MxMoveEncoding<MxMoveSize8, 206*fe6060f1SDimitry Andric /*src*/ MxEncEAd_1, MxExtEmpty, 207*fe6060f1SDimitry Andric /*dst*/ MxEncEAo_0, MxExtEmpty>>; 208*fe6060f1SDimitry Andric 209*fe6060f1SDimitry Andricdef MOV8bd : MxMove_MR<MxType8.BOp, MxType8.BPat, MxType8d, 210*fe6060f1SDimitry Andric MxMoveEncoding<MxMoveSize8, 211*fe6060f1SDimitry Andric /*src*/ MxEncEAd_1, MxExtEmpty, 212*fe6060f1SDimitry Andric /*dst*/ MxEncEAb, MxExtI32_0>>; 213*fe6060f1SDimitry Andric 214*fe6060f1SDimitry Andricdef MOV8jd : MxMove_MR<MxType8.JOp, MxType8.JPat, MxType8d, 215*fe6060f1SDimitry Andric MxMoveEncoding<MxMoveSize8, 216*fe6060f1SDimitry Andric /*src*/ MxEncEAd_1, MxExtEmpty, 217*fe6060f1SDimitry Andric /*dst*/ MxEncEAj_0, MxExtEmpty>>; 218*fe6060f1SDimitry Andric 219*fe6060f1SDimitry Andric 220*fe6060f1SDimitry Andric// R <- I 221*fe6060f1SDimitry Andricdef MOV8di : MxMove_RI<MxType8d, 222*fe6060f1SDimitry Andric MxMoveEncoding<MxMoveSize8, MxEncEAi, MxExtI8_1, MxEncEAd_0, MxExtEmpty>>; 223*fe6060f1SDimitry Andric 224*fe6060f1SDimitry Andricforeach S = [16, 32] in { 225*fe6060f1SDimitry Andric foreach D = [ "r", "a" ] in { 226*fe6060f1SDimitry Andric 227*fe6060f1SDimitry Andric foreach O = [ "r", "a" ] in { 228*fe6060f1SDimitry Andric def MOV#S#D#O : MxMove_RR< 229*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#D), 230*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#O), 231*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 232*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty, 233*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_0_reflected"), MxExtEmpty>>; 234*fe6060f1SDimitry Andric } 235*fe6060f1SDimitry Andric 236*fe6060f1SDimitry Andric // M <- R 237*fe6060f1SDimitry Andric def MOV#S#"f"#D : MxMove_MR< 238*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).FOp, 239*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).FPat, 240*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#D), 241*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 242*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty, 243*fe6060f1SDimitry Andric MxEncEAf_0, MxExtBrief_0>>; 244*fe6060f1SDimitry Andric 245*fe6060f1SDimitry Andric def MOV#S#"p"#D : MxMove_MR< 246*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).POp, 247*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).PPat, 248*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#D), 249*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 250*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty, 251*fe6060f1SDimitry Andric MxEncEAp_0, MxExtI16_0>>; 252*fe6060f1SDimitry Andric 253*fe6060f1SDimitry Andric def MOV#S#"e"#D : MxMove_MR< 254*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).EOp, 255*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).EPat, 256*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#D), 257*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 258*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty, 259*fe6060f1SDimitry Andric MxEncEAe_0, MxExtEmpty>>; 260*fe6060f1SDimitry Andric 261*fe6060f1SDimitry Andric def MOV#S#"o"#D : MxMove_MR< 262*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).OOp, 263*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).OPat, 264*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#D), 265*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 266*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty, 267*fe6060f1SDimitry Andric MxEncEAo_0, MxExtEmpty>>; 268*fe6060f1SDimitry Andric 269*fe6060f1SDimitry Andric def MOV#S#"b"#D : MxMove_MR< 270*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).BOp, 271*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).BPat, 272*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#D), 273*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 274*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty, 275*fe6060f1SDimitry Andric MxEncEAb, MxExtI32_0>>; 276*fe6060f1SDimitry Andric 277*fe6060f1SDimitry Andric def MOV#S#"j"#D : MxMove_MR< 278*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).JOp, 279*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).JPat, 280*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#D), 281*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 282*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_1"), MxExtEmpty, 283*fe6060f1SDimitry Andric MxEncEAj_0, MxExtEmpty>>; 284*fe6060f1SDimitry Andric 285*fe6060f1SDimitry Andric 286*fe6060f1SDimitry Andric // R <- I 287*fe6060f1SDimitry Andric def MOV#S#D#"i" : MxMove_RI< 288*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S#D), 289*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 290*fe6060f1SDimitry Andric MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"), 291*fe6060f1SDimitry Andric !cast<MxEncEA>("MxEncEA"#D#"_0_reflected"), MxExtEmpty>>; 292*fe6060f1SDimitry Andric } 293*fe6060f1SDimitry Andric} 294*fe6060f1SDimitry Andric 295*fe6060f1SDimitry Andric// M <- I 296*fe6060f1SDimitry Andricforeach S = [8, 16, 32] in { 297*fe6060f1SDimitry Andric def MOV#S#"f"#"i" : MxMove_MI< 298*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).FOp, 299*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).FPat, 300*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S), 301*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 302*fe6060f1SDimitry Andric MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"), 303*fe6060f1SDimitry Andric MxEncEAf_0, MxExtBrief_0>>; 304*fe6060f1SDimitry Andric 305*fe6060f1SDimitry Andric def MOV#S#"p"#"i" : MxMove_MI< 306*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).POp, 307*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).PPat, 308*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S), 309*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 310*fe6060f1SDimitry Andric MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"), 311*fe6060f1SDimitry Andric MxEncEAp_0, MxExtI16_0>>; 312*fe6060f1SDimitry Andric 313*fe6060f1SDimitry Andric def MOV#S#"b"#"i" : MxMove_MI< 314*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).BOp, 315*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).BPat, 316*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S), 317*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 318*fe6060f1SDimitry Andric MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"), 319*fe6060f1SDimitry Andric MxEncEAb, MxExtI32_0>>; 320*fe6060f1SDimitry Andric 321*fe6060f1SDimitry Andric def MOV#S#"j"#"i" : MxMove_MI< 322*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).JOp, 323*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S).JPat, 324*fe6060f1SDimitry Andric !cast<MxType>("MxType"#S), 325*fe6060f1SDimitry Andric MxMoveEncoding<!cast<MxMoveSize>("MxMoveSize"#S), 326*fe6060f1SDimitry Andric MxEncEAi, !cast<MxEncExt>("MxExtI"#S#"_1"), 327*fe6060f1SDimitry Andric MxEncEAj_0, MxExtEmpty>>; 328*fe6060f1SDimitry Andric} 329*fe6060f1SDimitry Andric 330*fe6060f1SDimitry Andric// Store ABS(basically pointer) as Immdiate to Mem 331*fe6060f1SDimitry Andricdef : Pat<(store MxType32.BPat :$src, MxType32.PPat :$dst), 332*fe6060f1SDimitry Andric (MOV32pi MxType32.POp :$dst, MxType32.IOp :$src)>; 333*fe6060f1SDimitry Andric 334*fe6060f1SDimitry Andricdef : Pat<(store MxType32.BPat :$src, MxType32.FPat :$dst), 335*fe6060f1SDimitry Andric (MOV32fi MxType32.FOp :$dst, MxType32.IOp :$src)>; 336*fe6060f1SDimitry Andric 337*fe6060f1SDimitry Andricdef : Pat<(store MxType32.BPat :$src, MxType32.BPat :$dst), 338*fe6060f1SDimitry Andric (MOV32bi MxType32.BOp :$dst, MxType32.IOp :$src)>; 339*fe6060f1SDimitry Andric 340*fe6060f1SDimitry Andricdef : Pat<(store MxType32.BPat :$src, MxType32.JPat :$dst), 341*fe6060f1SDimitry Andric (MOV32ji MxType32.JOp :$dst, MxType32.IOp :$src)>; 342*fe6060f1SDimitry Andric 343*fe6060f1SDimitry Andric// R <- M 344*fe6060f1SDimitry Andricdefm MOV8d : MMxMove_RM<MxType8d, MxMoveSize8, MxEncEAd_0>; 345*fe6060f1SDimitry Andric 346*fe6060f1SDimitry Andricdefm MOV16r : MMxMove_RM<MxType16r, MxMoveSize16, MxEncEAr_0_reflected>; 347*fe6060f1SDimitry Andricdefm MOV16a : MMxMove_RM<MxType16a, MxMoveSize16, MxEncEAa_0>; 348*fe6060f1SDimitry Andric 349*fe6060f1SDimitry Andricdefm MOV32r : MMxMove_RM<MxType32r, MxMoveSize32, MxEncEAr_0_reflected>; 350*fe6060f1SDimitry Andricdefm MOV32a : MMxMove_RM<MxType32a, MxMoveSize32, MxEncEAa_0>; 351*fe6060f1SDimitry Andric 352*fe6060f1SDimitry Andriclet Pattern = [(null_frag)] in { 353*fe6060f1SDimitry Andricdefm MOV16r : MMxMove_RM<MxType16r_TC, MxMoveSize16, MxEncEAr_0_reflected>; 354*fe6060f1SDimitry Andricdefm MOV16a : MMxMove_RM<MxType16a_TC, MxMoveSize16, MxEncEAa_0>; 355*fe6060f1SDimitry Andric 356*fe6060f1SDimitry Andricdefm MOV32r : MMxMove_RM<MxType32r_TC, MxMoveSize32, MxEncEAr_0_reflected>; 357*fe6060f1SDimitry Andricdefm MOV32a : MMxMove_RM<MxType32a_TC, MxMoveSize32, MxEncEAa_0>; 358*fe6060f1SDimitry Andric} // Pattern 359*fe6060f1SDimitry Andric 360*fe6060f1SDimitry Andric// M <- M 361*fe6060f1SDimitry Andricdefm MOV8p : MMxMove_MM<MxType8, MxType8.POp, MxType8.PPat, 362*fe6060f1SDimitry Andric MxMoveSize8, MxEncEAp_0, MxExtI16_0>; 363*fe6060f1SDimitry Andricdefm MOV16p : MMxMove_MM<MxType16, MxType16.POp, MxType16.PPat, 364*fe6060f1SDimitry Andric MxMoveSize16, MxEncEAp_0, MxExtI16_0>; 365*fe6060f1SDimitry Andricdefm MOV32p : MMxMove_MM<MxType32, MxType32.POp, MxType32.PPat, 366*fe6060f1SDimitry Andric MxMoveSize32, MxEncEAp_0, MxExtI16_0>; 367*fe6060f1SDimitry Andric 368*fe6060f1SDimitry Andricdefm MOV8f : MMxMove_MM<MxType8, MxType8.FOp, MxType8.FPat, 369*fe6060f1SDimitry Andric MxMoveSize8, MxEncEAf_0, MxExtBrief_0>; 370*fe6060f1SDimitry Andricdefm MOV16f : MMxMove_MM<MxType16, MxType16.FOp, MxType16.FPat, 371*fe6060f1SDimitry Andric MxMoveSize16, MxEncEAf_0, MxExtBrief_0>; 372*fe6060f1SDimitry Andricdefm MOV32f : MMxMove_MM<MxType32, MxType32.FOp, MxType32.FPat, 373*fe6060f1SDimitry Andric MxMoveSize32, MxEncEAf_0, MxExtBrief_0>; 374*fe6060f1SDimitry Andric 375*fe6060f1SDimitry Andricdefm MOV8b : MMxMove_MM<MxType8, MxType8.BOp, MxType8.BPat, 376*fe6060f1SDimitry Andric MxMoveSize8, MxEncEAb, MxExtI32_0>; 377*fe6060f1SDimitry Andricdefm MOV16b : MMxMove_MM<MxType16, MxType16.BOp, MxType16.BPat, 378*fe6060f1SDimitry Andric MxMoveSize16, MxEncEAb, MxExtI32_0>; 379*fe6060f1SDimitry Andricdefm MOV32b : MMxMove_MM<MxType32, MxType32.BOp, MxType32.BPat, 380*fe6060f1SDimitry Andric MxMoveSize32, MxEncEAb, MxExtI32_0>; 381*fe6060f1SDimitry Andric 382*fe6060f1SDimitry Andricdefm MOV8e : MMxMove_MM<MxType8, MxType8.EOp, MxType8.EPat, 383*fe6060f1SDimitry Andric MxMoveSize8, MxEncEAe_0, MxExtEmpty>; 384*fe6060f1SDimitry Andricdefm MOV16e : MMxMove_MM<MxType16, MxType16.EOp, MxType16.EPat, 385*fe6060f1SDimitry Andric MxMoveSize16, MxEncEAe_0, MxExtEmpty>; 386*fe6060f1SDimitry Andricdefm MOV32e : MMxMove_MM<MxType32, MxType32.EOp, MxType32.EPat, 387*fe6060f1SDimitry Andric MxMoveSize32, MxEncEAe_0, MxExtEmpty>; 388*fe6060f1SDimitry Andric 389*fe6060f1SDimitry Andricdefm MOV8o : MMxMove_MM<MxType8, MxType8.OOp, MxType8.OPat, 390*fe6060f1SDimitry Andric MxMoveSize8, MxEncEAo_0, MxExtEmpty>; 391*fe6060f1SDimitry Andricdefm MOV16o : MMxMove_MM<MxType16, MxType16.OOp, MxType16.OPat, 392*fe6060f1SDimitry Andric MxMoveSize16, MxEncEAo_0, MxExtEmpty>; 393*fe6060f1SDimitry Andricdefm MOV32o : MMxMove_MM<MxType32, MxType32.OOp, MxType32.OPat, 394*fe6060f1SDimitry Andric MxMoveSize32, MxEncEAo_0, MxExtEmpty>; 395*fe6060f1SDimitry Andric 396*fe6060f1SDimitry Andricdefm MOV8j : MMxMove_MM<MxType8, MxType8.JOp, MxType8.JPat, 397*fe6060f1SDimitry Andric MxMoveSize8, MxEncEAj_0, MxExtEmpty>; 398*fe6060f1SDimitry Andricdefm MOV16j : MMxMove_MM<MxType16, MxType16.JOp, MxType16.JPat, 399*fe6060f1SDimitry Andric MxMoveSize16, MxEncEAj_0, MxExtEmpty>; 400*fe6060f1SDimitry Andricdefm MOV32j : MMxMove_MM<MxType32, MxType32.JOp, MxType32.JPat, 401*fe6060f1SDimitry Andric MxMoveSize32, MxEncEAj_0, MxExtEmpty>; 402*fe6060f1SDimitry Andric 403*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 404*fe6060f1SDimitry Andric// MOVEM 405*fe6060f1SDimitry Andric// 406*fe6060f1SDimitry Andric// The mask is already pre-processed by the save/restore spill hook 407*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 408*fe6060f1SDimitry Andric 409*fe6060f1SDimitry Andric// Direction 410*fe6060f1SDimitry Andricdef MxMOVEM_MR : MxBead1Bit<0>; 411*fe6060f1SDimitry Andricdef MxMOVEM_RM : MxBead1Bit<1>; 412*fe6060f1SDimitry Andric 413*fe6060f1SDimitry Andric// Size 414*fe6060f1SDimitry Andricdef MxMOVEM_W : MxBead1Bit<0>; 415*fe6060f1SDimitry Andricdef MxMOVEM_L : MxBead1Bit<1>; 416*fe6060f1SDimitry Andric 417*fe6060f1SDimitry Andric/// ---------------+-------------+-------------+--------- 418*fe6060f1SDimitry Andric/// F E D C B | A | 9 8 7 | 6 | 5 4 3 | 2 1 0 419*fe6060f1SDimitry Andric/// ---------------+---+---------+---+---------+--------- 420*fe6060f1SDimitry Andric/// 0 1 0 0 1 | D | 0 0 1 | S | MODE | REG 421*fe6060f1SDimitry Andric/// ---------------+---+---------+---+---------+--------- 422*fe6060f1SDimitry Andric/// REGISTER LIST MASK 423*fe6060f1SDimitry Andric/// ----------------------------------------------------- 424*fe6060f1SDimitry Andric/// D - direction(RM,MR) 425*fe6060f1SDimitry Andric/// S - size(W,L) 426*fe6060f1SDimitry Andricclass MxMOVEMEncoding<MxEncEA EA, MxEncExt EXT, MxBead1Bit SIZE, MxBead1Bit DIR, 427*fe6060f1SDimitry Andric MxBead16Imm IMM> 428*fe6060f1SDimitry Andric : MxEncoding<EA.Reg, EA.DA, EA.Mode, SIZE, MxBead3Bits<0b001>, DIR, 429*fe6060f1SDimitry Andric MxBead1Bit<1>, MxBead4Bits<0b0100>, IMM, 430*fe6060f1SDimitry Andric EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>; 431*fe6060f1SDimitry Andric 432*fe6060f1SDimitry Andriclet mayStore = 1 in 433*fe6060f1SDimitry Andricclass MxMOVEM_MR<MxType TYPE, MxBead1Bit SIZE, 434*fe6060f1SDimitry Andric MxOperand MEMOp, MxEncEA EA, MxEncExt EXT> 435*fe6060f1SDimitry Andric : MxInst<(outs), (ins MEMOp:$dst, MxMoveMask:$mask), 436*fe6060f1SDimitry Andric "movem."#TYPE.Prefix#"\t$mask, $dst", [], 437*fe6060f1SDimitry Andric MxMOVEMEncoding<EA, EXT, SIZE, MxMOVEM_MR, MxBead16Imm<1>>>; 438*fe6060f1SDimitry Andric 439*fe6060f1SDimitry Andriclet mayLoad = 1 in 440*fe6060f1SDimitry Andricclass MxMOVEM_RM<MxType TYPE, MxBead1Bit SIZE, 441*fe6060f1SDimitry Andric MxOperand MEMOp, MxEncEA EA, MxEncExt EXT> 442*fe6060f1SDimitry Andric : MxInst<(outs), (ins MxMoveMask:$mask, MEMOp:$src), 443*fe6060f1SDimitry Andric "movem."#TYPE.Prefix#"\t$src, $mask", [], 444*fe6060f1SDimitry Andric MxMOVEMEncoding<EA, EXT, SIZE, MxMOVEM_RM, MxBead16Imm<0>>>; 445*fe6060f1SDimitry Andric 446*fe6060f1SDimitry Andricdef MOVM32jm : MxMOVEM_MR<MxType32, MxMOVEM_L, MxType32.JOp, MxEncEAj_0, MxExtEmpty>; 447*fe6060f1SDimitry Andricdef MOVM32pm : MxMOVEM_MR<MxType32, MxMOVEM_L, MxType32.POp, MxEncEAp_0, MxExtI16_0>; 448*fe6060f1SDimitry Andric 449*fe6060f1SDimitry Andricdef MOVM32mj : MxMOVEM_RM<MxType32, MxMOVEM_L, MxType32.JOp, MxEncEAj_1, MxExtEmpty>; 450*fe6060f1SDimitry Andricdef MOVM32mp : MxMOVEM_RM<MxType32, MxMOVEM_L, MxType32.POp, MxEncEAp_1, MxExtI16_1>; 451*fe6060f1SDimitry Andric 452*fe6060f1SDimitry Andric// Pseudo versions. These a required by virtual register spill/restore since 453*fe6060f1SDimitry Andric// the mask requires real register to encode. These instruction will be expanded 454*fe6060f1SDimitry Andric// into real MOVEM after RA finishes. 455*fe6060f1SDimitry Andriclet mayStore = 1 in 456*fe6060f1SDimitry Andricclass MxMOVEM_MR_Pseudo<MxType TYPE, MxOperand MEMOp> 457*fe6060f1SDimitry Andric : MxPseudo<(outs), (ins MEMOp:$dst, TYPE.ROp:$reg)>; 458*fe6060f1SDimitry Andriclet mayLoad = 1 in 459*fe6060f1SDimitry Andricclass MxMOVEM_RM_Pseudo<MxType TYPE, MxOperand MEMOp> 460*fe6060f1SDimitry Andric : MxPseudo<(outs TYPE.ROp:$dst), (ins MEMOp:$src)>; 461*fe6060f1SDimitry Andric 462*fe6060f1SDimitry Andric// Mem <- Reg 463*fe6060f1SDimitry Andricdef MOVM8jm_P : MxMOVEM_MR_Pseudo<MxType8d, MxType8.JOp>; 464*fe6060f1SDimitry Andricdef MOVM16jm_P : MxMOVEM_MR_Pseudo<MxType16r, MxType16.JOp>; 465*fe6060f1SDimitry Andricdef MOVM32jm_P : MxMOVEM_MR_Pseudo<MxType32r, MxType32.JOp>; 466*fe6060f1SDimitry Andric 467*fe6060f1SDimitry Andricdef MOVM8pm_P : MxMOVEM_MR_Pseudo<MxType8d, MxType8.POp>; 468*fe6060f1SDimitry Andricdef MOVM16pm_P : MxMOVEM_MR_Pseudo<MxType16r, MxType16.POp>; 469*fe6060f1SDimitry Andricdef MOVM32pm_P : MxMOVEM_MR_Pseudo<MxType32r, MxType32.POp>; 470*fe6060f1SDimitry Andric 471*fe6060f1SDimitry Andric// Reg <- Mem 472*fe6060f1SDimitry Andricdef MOVM8mj_P : MxMOVEM_RM_Pseudo<MxType8d, MxType8.JOp>; 473*fe6060f1SDimitry Andricdef MOVM16mj_P : MxMOVEM_RM_Pseudo<MxType16r, MxType16.JOp>; 474*fe6060f1SDimitry Andricdef MOVM32mj_P : MxMOVEM_RM_Pseudo<MxType32r, MxType32.JOp>; 475*fe6060f1SDimitry Andric 476*fe6060f1SDimitry Andricdef MOVM8mp_P : MxMOVEM_RM_Pseudo<MxType8d, MxType8.POp>; 477*fe6060f1SDimitry Andricdef MOVM16mp_P : MxMOVEM_RM_Pseudo<MxType16r, MxType16.POp>; 478*fe6060f1SDimitry Andricdef MOVM32mp_P : MxMOVEM_RM_Pseudo<MxType32r, MxType32.POp>; 479*fe6060f1SDimitry Andric 480*fe6060f1SDimitry Andric 481*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 482*fe6060f1SDimitry Andric// MOVE to/from SR/CCR 483*fe6060f1SDimitry Andric// 484*fe6060f1SDimitry Andric// A special care must be taken working with to/from CCR since it is basically 485*fe6060f1SDimitry Andric// word-size SR register truncated for user mode thus it only supports word-size 486*fe6060f1SDimitry Andric// instructions. Plus the original M68000 does not support moves from CCR. So in 487*fe6060f1SDimitry Andric// order to use CCR effectively one MUST use proper byte-size pseudo instructi- 488*fe6060f1SDimitry Andric// ons that will be resolved sometime after RA pass. 489*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 490*fe6060f1SDimitry Andric 491*fe6060f1SDimitry Andric/// -------------------------------------------------- 492*fe6060f1SDimitry Andric/// F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 493*fe6060f1SDimitry Andric/// -------------------------------------------------- 494*fe6060f1SDimitry Andric/// | EFFECTIVE ADDRESS 495*fe6060f1SDimitry Andric/// 0 1 0 0 0 1 0 0 1 1 | MODE | REG 496*fe6060f1SDimitry Andric/// -------------------------------------------------- 497*fe6060f1SDimitry Andriclet Defs = [CCR] in 498*fe6060f1SDimitry Andricclass MxMoveToCCR<dag INS, MxEncEA EA, MxEncExt EXT> 499*fe6060f1SDimitry Andric : MxInst<(outs CCRC:$dst), INS, "move.w\t$src, $dst", [], 500*fe6060f1SDimitry Andric MxEncoding<EA.Reg, EA.DA, EA.Mode, 501*fe6060f1SDimitry Andric MxBead4Bits<0b0011>, MxBead4Bits<0b0001>, MxBead2Bits<0b01>, 502*fe6060f1SDimitry Andric EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>; 503*fe6060f1SDimitry Andric 504*fe6060f1SDimitry Andricclass MxMoveToCCRPseudo<dag INS> : MxPseudo<(outs CCRC:$dst), INS>; 505*fe6060f1SDimitry Andric 506*fe6060f1SDimitry Andriclet mayLoad = 1 in { 507*fe6060f1SDimitry Andricdef MOV16cp : MxMoveToCCR<(ins MxType16d.POp:$src), MxEncEAp_1, MxExtI16_1>; 508*fe6060f1SDimitry Andricdef MOV8cp : MxMoveToCCRPseudo<(ins MxType8d.POp:$src)>; 509*fe6060f1SDimitry Andric} // let mayLoad = 1 510*fe6060f1SDimitry Andric 511*fe6060f1SDimitry Andricdef MOV16cd : MxMoveToCCR<(ins MxType16d.ROp:$src), MxEncEAd_1, MxExtEmpty>; 512*fe6060f1SDimitry Andricdef MOV8cd : MxMoveToCCRPseudo<(ins MxType8d.ROp:$src)>; 513*fe6060f1SDimitry Andric 514*fe6060f1SDimitry Andric/// Move from CCR 515*fe6060f1SDimitry Andric/// -------------------------------------------------- 516*fe6060f1SDimitry Andric/// F E D C B A 9 8 7 6 | 5 4 3 | 2 1 0 517*fe6060f1SDimitry Andric/// -------------------------------------------------- 518*fe6060f1SDimitry Andric/// | EFFECTIVE ADDRESS 519*fe6060f1SDimitry Andric/// 0 1 0 0 0 0 1 0 1 1 | MODE | REG 520*fe6060f1SDimitry Andric/// -------------------------------------------------- 521*fe6060f1SDimitry Andriclet Uses = [CCR] in 522*fe6060f1SDimitry Andricclass MxMoveFromCCR<dag OUTS, dag INS, MxEncEA EA, MxEncExt EXT> 523*fe6060f1SDimitry Andric : MxInst<OUTS, INS, "move.w\t$src, $dst", [], 524*fe6060f1SDimitry Andric MxEncoding<EA.Reg, EA.DA, EA.Mode, 525*fe6060f1SDimitry Andric MxBead4Bits<0b1011>, MxBead4Bits<0b0000>, MxBead2Bits<0b01>, 526*fe6060f1SDimitry Andric EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>, 527*fe6060f1SDimitry Andric Requires<[ IsM68010 ]>; 528*fe6060f1SDimitry Andric 529*fe6060f1SDimitry Andricclass MxMoveFromCCRPseudo<dag INS> : MxPseudo<(outs), INS>; 530*fe6060f1SDimitry Andric 531*fe6060f1SDimitry Andriclet mayStore = 1 in { 532*fe6060f1SDimitry Andricdef MOV16pc 533*fe6060f1SDimitry Andric : MxMoveFromCCR<(outs), (ins MxType16d.POp:$dst, CCRC:$src), MxEncEAp_0, MxExtI16_0>; 534*fe6060f1SDimitry Andricdef MOV8pc : MxMoveFromCCRPseudo<(ins MxType8d.POp:$dst, CCRC:$src)>; 535*fe6060f1SDimitry Andric} // let mayStore = 1 536*fe6060f1SDimitry Andric 537*fe6060f1SDimitry Andricdef MOV16dc 538*fe6060f1SDimitry Andric : MxMoveFromCCR<(outs MxType16d.ROp:$dst), (ins CCRC:$src), MxEncEAd_0, MxExtEmpty>; 539*fe6060f1SDimitry Andric 540*fe6060f1SDimitry Andricdef MOV8dc : MxMoveFromCCRPseudo<(ins MxType8d.ROp:$dst, CCRC:$src)>; 541*fe6060f1SDimitry Andric 542*fe6060f1SDimitry Andric 543*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 544*fe6060f1SDimitry Andric// LEA 545*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 546*fe6060f1SDimitry Andric 547*fe6060f1SDimitry Andric/// ---------------------------------------------------- 548*fe6060f1SDimitry Andric/// F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0 549*fe6060f1SDimitry Andric/// ---------------------------------------------------- 550*fe6060f1SDimitry Andric/// 0 1 0 0 | DST REG | 1 1 1 | MODE | REG 551*fe6060f1SDimitry Andric/// ---------------------------------------------------- 552*fe6060f1SDimitry Andricclass MxLEA<MxOperand SRCOpd, ComplexPattern SRCPat, MxEncEA EA, MxEncExt EXT> 553*fe6060f1SDimitry Andric : MxInst<(outs MxARD32:$dst), (ins SRCOpd:$src), 554*fe6060f1SDimitry Andric "lea\t$src, $dst", [(set i32:$dst, SRCPat:$src)], 555*fe6060f1SDimitry Andric MxEncoding<EA.Reg, EA.DA, EA.Mode, 556*fe6060f1SDimitry Andric MxBead3Bits<0b111>, MxBeadReg<0>, MxBead4Bits<0x4>, 557*fe6060f1SDimitry Andric EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>>; 558*fe6060f1SDimitry Andric 559*fe6060f1SDimitry Andricdef LEA32p : MxLEA<MxARID32, MxCP_ARID, MxEncEAp_1, MxExtI16_1>; 560*fe6060f1SDimitry Andricdef LEA32f : MxLEA<MxARII32, MxCP_ARII, MxEncEAf_1, MxExtBrief_1>; 561*fe6060f1SDimitry Andricdef LEA32q : MxLEA<MxPCD32, MxCP_PCD, MxEncEAq, MxExtI16_1>; 562*fe6060f1SDimitry Andricdef LEA32b : MxLEA<MxAL32, MxCP_AL, MxEncEAb, MxExtI32_1>; 563*fe6060f1SDimitry Andric 564*fe6060f1SDimitry Andric 565*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 566*fe6060f1SDimitry Andric// Pseudos 567*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 568*fe6060f1SDimitry Andric 569*fe6060f1SDimitry Andric/// Pushe/Pop to/from SP for simplicity 570*fe6060f1SDimitry Andriclet Uses = [SP], Defs = [SP], hasSideEffects = 0 in { 571*fe6060f1SDimitry Andric 572*fe6060f1SDimitry Andric// SP <- SP - <size>; (SP) <- Dn 573*fe6060f1SDimitry Andriclet mayStore = 1 in { 574*fe6060f1SDimitry Andricdef PUSH8d : MxPseudo<(outs), (ins DR8:$reg)>; 575*fe6060f1SDimitry Andricdef PUSH16d : MxPseudo<(outs), (ins DR16:$reg)>; 576*fe6060f1SDimitry Andricdef PUSH32r : MxPseudo<(outs), (ins XR32:$reg)>; 577*fe6060f1SDimitry Andric} // let mayStore = 1 578*fe6060f1SDimitry Andric 579*fe6060f1SDimitry Andric// Dn <- (SP); SP <- SP + <size> 580*fe6060f1SDimitry Andriclet mayLoad = 1 in { 581*fe6060f1SDimitry Andricdef POP8d : MxPseudo<(outs DR8:$reg), (ins)>; 582*fe6060f1SDimitry Andricdef POP16d : MxPseudo<(outs DR16:$reg), (ins)>; 583*fe6060f1SDimitry Andricdef POP32r : MxPseudo<(outs XR32:$reg), (ins)>; 584*fe6060f1SDimitry Andric} // let mayLoad = 1 585*fe6060f1SDimitry Andric 586*fe6060f1SDimitry Andric} // let Uses/Defs = [SP], hasSideEffects = 0 587*fe6060f1SDimitry Andric 588*fe6060f1SDimitry Andric 589*fe6060f1SDimitry Andriclet Defs = [CCR] in { 590*fe6060f1SDimitry Andricclass MxPseudoMove_RR<MxType DST, MxType SRC, list<dag> PAT = []> 591*fe6060f1SDimitry Andric : MxPseudo<(outs DST.ROp:$dst), (ins SRC.ROp:$src), PAT>; 592*fe6060f1SDimitry Andric 593*fe6060f1SDimitry Andricclass MxPseudoMove_RM<MxType DST, MxOperand SRCOpd, list<dag> PAT = []> 594*fe6060f1SDimitry Andric : MxPseudo<(outs DST.ROp:$dst), (ins SRCOpd:$src), PAT>; 595*fe6060f1SDimitry Andric} 596*fe6060f1SDimitry Andric 597*fe6060f1SDimitry Andric/// This group of Pseudos is analogues to the real x86 extending moves, but 598*fe6060f1SDimitry Andric/// since M68k does not have those we need to emulate. These instructions 599*fe6060f1SDimitry Andric/// will be expanded right after RA completed because we need to know precisely 600*fe6060f1SDimitry Andric/// what registers are allocated for the operands and if they overlap we just 601*fe6060f1SDimitry Andric/// extend the value if the registers are completely different we need to move 602*fe6060f1SDimitry Andric/// first. 603*fe6060f1SDimitry Andricforeach EXT = ["S", "Z"] in { 604*fe6060f1SDimitry Andric let hasSideEffects = 0 in { 605*fe6060f1SDimitry Andric 606*fe6060f1SDimitry Andric def MOV#EXT#Xd16d8 : MxPseudoMove_RR<MxType16d, MxType8d>; 607*fe6060f1SDimitry Andric def MOV#EXT#Xd32d8 : MxPseudoMove_RR<MxType32d, MxType8d>; 608*fe6060f1SDimitry Andric def MOV#EXT#Xd32d16 : MxPseudoMove_RR<MxType32r, MxType16r>; 609*fe6060f1SDimitry Andric 610*fe6060f1SDimitry Andric let mayLoad = 1 in { 611*fe6060f1SDimitry Andric 612*fe6060f1SDimitry Andric def MOV#EXT#Xd16j8 : MxPseudoMove_RM<MxType16d, MxType8.JOp>; 613*fe6060f1SDimitry Andric def MOV#EXT#Xd32j8 : MxPseudoMove_RM<MxType32d, MxType8.JOp>; 614*fe6060f1SDimitry Andric def MOV#EXT#Xd32j16 : MxPseudoMove_RM<MxType32d, MxType16.JOp>; 615*fe6060f1SDimitry Andric 616*fe6060f1SDimitry Andric def MOV#EXT#Xd16p8 : MxPseudoMove_RM<MxType16d, MxType8.POp>; 617*fe6060f1SDimitry Andric def MOV#EXT#Xd32p8 : MxPseudoMove_RM<MxType32d, MxType8.POp>; 618*fe6060f1SDimitry Andric def MOV#EXT#Xd32p16 : MxPseudoMove_RM<MxType32d, MxType16.POp>; 619*fe6060f1SDimitry Andric 620*fe6060f1SDimitry Andric def MOV#EXT#Xd16f8 : MxPseudoMove_RM<MxType16d, MxType8.FOp>; 621*fe6060f1SDimitry Andric def MOV#EXT#Xd32f8 : MxPseudoMove_RM<MxType32d, MxType8.FOp>; 622*fe6060f1SDimitry Andric def MOV#EXT#Xd32f16 : MxPseudoMove_RM<MxType32d, MxType16.FOp>; 623*fe6060f1SDimitry Andric 624*fe6060f1SDimitry Andric } 625*fe6060f1SDimitry Andric } 626*fe6060f1SDimitry Andric} 627*fe6060f1SDimitry Andric 628*fe6060f1SDimitry Andric/// This group of instructions is similar to the group above but DOES NOT do 629*fe6060f1SDimitry Andric/// any value extension, they just load a smaller register into the lower part 630*fe6060f1SDimitry Andric/// of another register if operands' real registers are different or does 631*fe6060f1SDimitry Andric/// nothing if they are the same. 632*fe6060f1SDimitry Andricdef MOVXd16d8 : MxPseudoMove_RR<MxType16d, MxType8d>; 633*fe6060f1SDimitry Andricdef MOVXd32d8 : MxPseudoMove_RR<MxType32d, MxType8d>; 634*fe6060f1SDimitry Andricdef MOVXd32d16 : MxPseudoMove_RR<MxType32r, MxType16r>; 635*fe6060f1SDimitry Andric 636*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 637*fe6060f1SDimitry Andric// Extend/Truncate Patterns 638*fe6060f1SDimitry Andric//===----------------------------------------------------------------------===// 639*fe6060f1SDimitry Andric 640*fe6060f1SDimitry Andric// i16 <- sext i8 641*fe6060f1SDimitry Andricdef: Pat<(i16 (sext i8:$src)), 642*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVSXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>; 643*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi16i8 MxCP_ARI:$src), 644*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVSXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>; 645*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi16i8 MxCP_ARID:$src), 646*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVSXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>; 647*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi16i8 MxCP_ARII:$src), 648*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVSXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>; 649*fe6060f1SDimitry Andric 650*fe6060f1SDimitry Andric// i32 <- sext i8 651*fe6060f1SDimitry Andricdef: Pat<(i32 (sext i8:$src)), (MOVSXd32d8 MxDRD8:$src)>; 652*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi32i8 MxCP_ARI :$src), (MOVSXd32j8 MxARI8 :$src)>; 653*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi32i8 MxCP_ARID:$src), (MOVSXd32p8 MxARID8:$src)>; 654*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi32i8 MxCP_ARII:$src), (MOVSXd32f8 MxARII8:$src)>; 655*fe6060f1SDimitry Andric 656*fe6060f1SDimitry Andric// i32 <- sext i16 657*fe6060f1SDimitry Andricdef: Pat<(i32 (sext i16:$src)), (MOVSXd32d16 MxDRD16:$src)>; 658*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi32i16 MxCP_ARI :$src), (MOVSXd32j16 MxARI16 :$src)>; 659*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi32i16 MxCP_ARID:$src), (MOVSXd32p16 MxARID16:$src)>; 660*fe6060f1SDimitry Andricdef: Pat<(MxSExtLoadi32i16 MxCP_ARII:$src), (MOVSXd32f16 MxARII16:$src)>; 661*fe6060f1SDimitry Andric 662*fe6060f1SDimitry Andric// i16 <- zext i8 663*fe6060f1SDimitry Andricdef: Pat<(i16 (zext i8:$src)), 664*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVZXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>; 665*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi16i8 MxCP_ARI:$src), 666*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVZXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>; 667*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi16i8 MxCP_ARID:$src), 668*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>; 669*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi16i8 MxCP_ARII:$src), 670*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>; 671*fe6060f1SDimitry Andric 672*fe6060f1SDimitry Andric// i32 <- zext i8 673*fe6060f1SDimitry Andricdef: Pat<(i32 (zext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>; 674*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>; 675*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>; 676*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>; 677*fe6060f1SDimitry Andric 678*fe6060f1SDimitry Andric// i32 <- zext i16 679*fe6060f1SDimitry Andricdef: Pat<(i32 (zext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>; 680*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>; 681*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>; 682*fe6060f1SDimitry Andricdef: Pat<(MxZExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>; 683*fe6060f1SDimitry Andric 684*fe6060f1SDimitry Andric// i16 <- anyext i8 685*fe6060f1SDimitry Andricdef: Pat<(i16 (anyext i8:$src)), 686*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVZXd32d8 MxDRD8:$src), MxSubRegIndex16Lo)>; 687*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi16i8 MxCP_ARI:$src), 688*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVZXd32j8 MxARI8:$src), MxSubRegIndex16Lo)>; 689*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi16i8 MxCP_ARID:$src), 690*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVZXd32p8 MxARID8:$src), MxSubRegIndex16Lo)>; 691*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi16i8 MxCP_ARII:$src), 692*fe6060f1SDimitry Andric (EXTRACT_SUBREG (MOVZXd32f8 MxARII8:$src), MxSubRegIndex16Lo)>; 693*fe6060f1SDimitry Andric 694*fe6060f1SDimitry Andric// i32 <- anyext i8 695*fe6060f1SDimitry Andricdef: Pat<(i32 (anyext i8:$src)), (MOVZXd32d8 MxDRD8:$src)>; 696*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi32i8 MxCP_ARI :$src), (MOVZXd32j8 MxARI8 :$src)>; 697*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi32i8 MxCP_ARID:$src), (MOVZXd32p8 MxARID8:$src)>; 698*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi32i8 MxCP_ARII:$src), (MOVZXd32f8 MxARII8:$src)>; 699*fe6060f1SDimitry Andric 700*fe6060f1SDimitry Andric// i32 <- anyext i16 701*fe6060f1SDimitry Andricdef: Pat<(i32 (anyext i16:$src)), (MOVZXd32d16 MxDRD16:$src)>; 702*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi32i16 MxCP_ARI :$src), (MOVZXd32j16 MxARI16 :$src)>; 703*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi32i16 MxCP_ARID:$src), (MOVZXd32p16 MxARID16:$src)>; 704*fe6060f1SDimitry Andricdef: Pat<(MxExtLoadi32i16 MxCP_ARII:$src), (MOVZXd32f16 MxARII16:$src)>; 705*fe6060f1SDimitry Andric 706*fe6060f1SDimitry Andric// trunc patterns 707*fe6060f1SDimitry Andricdef : Pat<(i16 (trunc i32:$src)), 708*fe6060f1SDimitry Andric (EXTRACT_SUBREG MxXRD32:$src, MxSubRegIndex16Lo)>; 709*fe6060f1SDimitry Andricdef : Pat<(i8 (trunc i32:$src)), 710*fe6060f1SDimitry Andric (EXTRACT_SUBREG MxXRD32:$src, MxSubRegIndex8Lo)>; 711*fe6060f1SDimitry Andricdef : Pat<(i8 (trunc i16:$src)), 712*fe6060f1SDimitry Andric (EXTRACT_SUBREG MxXRD16:$src, MxSubRegIndex8Lo)>; 713