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