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