1//===-- M68kInstrArithmetic.td - Integer Arith Instrs ------*- 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 integer arithmetic instructions in the M68k 11/// architecture. Here is the current status of the file: 12/// 13/// Machine: 14/// 15/// ADD [~] ADDA [~] ADDI [~] ADDQ [ ] ADDX [~] 16/// CLR [ ] CMP [~] CMPA [~] CMPI [~] CMPM [ ] 17/// CMP2 [ ] DIVS/DIVU [~] DIVSL/DIVUL [ ] EXT [~] EXTB [ ] 18/// MULS/MULU [~] NEG [~] NEGX [~] SUB [~] SUBA [~] 19/// SUBI [~] SUBQ [ ] SUBX [~] 20/// 21/// Map: 22/// 23/// [ ] - was not touched at all 24/// [!] - requires extarnal stuff implemented 25/// [~] - functional implementation 26/// [X] - complete implementation 27/// 28//===----------------------------------------------------------------------===// 29 30//===----------------------------------------------------------------------===// 31// Encoding 32//===----------------------------------------------------------------------===// 33 34/// Encoding for Normal forms 35/// ---------------------------------------------------- 36/// F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0 37/// ---------------------------------------------------- 38/// | | | EFFECTIVE ADDRESS 39/// x x x x | REG | OP MODE | MODE | REG 40/// ---------------------------------------------------- 41class MxArithEncoding<MxBead4Bits CMD, MxEncOpMode OPMODE, MxBead REG, 42 MxEncEA EA, MxEncExt EXT> 43 : MxEncoding<EA.Reg, EA.DA, EA.Mode, OPMODE.B0, OPMODE.B1, OPMODE.B2, REG, 44 CMD,EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>; 45 46/// Encoding for Extended forms 47/// ------------------------------------------------------ 48/// F E D C | B A 9 | 8 | 7 6 | 5 4 | 3 | 2 1 0 49/// ------------------------------------------------------ 50/// x x x x | REG Rx | 1 | SIZE | 0 0 | M | REG Ry 51/// ------------------------------------------------------ 52/// Rx - destination 53/// Ry - source 54/// M - address mode switch 55class MxArithXEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxBead1Bit MODE, 56 MxBeadDReg SRC, MxBeadDReg DST> 57 : MxEncoding<SRC, MODE, MxBead2Bits<0b00>, SIZE, MxBead1Bit<0b1>, DST, CMD>; 58 59/// Encoding for Immediate forms 60/// --------------------------------------------------- 61/// F E D C B A 9 8 | 7 6 | 5 4 3 | 2 1 0 62/// --------------------------------------------------- 63/// | | EFFECTIVE ADDRESS 64/// x x x x x x x x | SIZE | MODE | REG 65/// --------------------------------------------------- 66/// 16-BIT WORD DATA | 8-BIT BYTE DATA 67/// --------------------------------------------------- 68/// 32-BIT LONG DATA 69/// --------------------------------------------------- 70/// NOTE It is used to store an immediate to memory, imm-to-reg are handled with 71/// normal version 72class MxArithImmEncoding<MxBead4Bits CMD, MxEncSize SIZE, 73 MxEncEA DST_EA, MxEncExt DST_EXT, MxEncExt SRC_EXT> 74 : MxEncoding<DST_EA.Reg, DST_EA.DA, DST_EA.Mode, SIZE, CMD, MxBead4Bits<0>, 75 // Source 76 SRC_EXT.Imm, SRC_EXT.B8, SRC_EXT.Scale, 77 SRC_EXT.WL, SRC_EXT.DAReg, 78 // Destination 79 DST_EXT.Imm, DST_EXT.B8, DST_EXT.Scale, 80 DST_EXT.WL, DST_EXT.DAReg>; 81 82 83//===----------------------------------------------------------------------===// 84// Add/Sub 85//===----------------------------------------------------------------------===// 86 87let Defs = [CCR] in { 88let Constraints = "$src = $dst" in { 89 90// $reg, $ccr <- $reg op $reg 91class MxBiArOp_RFRR_xEA<string MN, SDNode NODE, MxType DST_TYPE, MxType SRC_TYPE, 92 bits<4> CMD, MxBead REG> 93 : MxInst<(outs DST_TYPE.ROp:$dst), (ins DST_TYPE.ROp:$src, SRC_TYPE.ROp:$opd), 94 MN#"."#DST_TYPE.Prefix#"\t$opd, $dst", 95 [(set DST_TYPE.VT:$dst, CCR, (NODE DST_TYPE.VT:$src, SRC_TYPE.VT:$opd))], 96 MxArithEncoding<MxBead4Bits<CMD>, 97 !cast<MxEncOpMode>("MxOpMode"#DST_TYPE.Size#DST_TYPE.RLet#"EA"), 98 REG, 99 !cast<MxEncEA>("MxEncEA"#SRC_TYPE.RLet#"_2"), 100 MxExtEmpty>>; 101 102/// This Op is similar to the one above except it uses reversed opmode, some 103/// commands(e.g. eor) do not support dEA or rEA modes and require EAd for 104/// register only operations. 105/// NOTE when using dd commands it is irrelevant which opmode to use(as it seems) 106/// but some opcodes support address register and some do not which creates this 107/// mess. 108class MxBiArOp_RFRR_EAd<string MN, SDNode NODE, MxType TYPE, bits<4> CMD> 109 : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd), 110 MN#"."#TYPE.Prefix#"\t$opd, $dst", 111 [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd))], 112 MxArithEncoding<MxBead4Bits<CMD>, 113 !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EAd"), 114 MxBeadDReg<2>, MxEncEAd_0, MxExtEmpty>>; 115 116// $reg <- $reg op $imm 117class MxBiArOp_RFRI_xEA<string MN, SDNode NODE, MxType TYPE, bits<4> CMD> 118 : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd), 119 MN#"."#TYPE.Prefix#"\t$opd, $dst", 120 [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))], 121 MxArithEncoding<MxBead4Bits<CMD>, 122 !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"), 123 MxBeadDReg<0>, MxEncEAi, 124 !cast<MxEncExt>("MxExtI"#TYPE.Size#"_2")>>; 125 126// Again, there are two ways to write an immediate to Dn register either dEA 127// opmode or using *I encoding, and again some instrucitons also support address 128// registers some do not. 129class MxBiArOp_RFRI<string MN, SDNode NODE, MxType TYPE, bits<4> CMD> 130 : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.IOp:$opd), 131 MN#"i."#TYPE.Prefix#"\t$opd, $dst", 132 [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.IPat:$opd))], 133 MxArithImmEncoding<MxBead4Bits<CMD>, !cast<MxEncSize>("MxEncSize"#TYPE.Size), 134 !cast<MxEncEA>("MxEncEA"#TYPE.RLet#"_0"), MxExtEmpty, 135 !cast<MxEncExt>("MxExtI"#TYPE.Size#"_2")>>; 136 137let mayLoad = 1 in 138class MxBiArOp_RFRM<string MN, SDNode NODE, MxType TYPE, MxOperand OPD, ComplexPattern PAT, 139 bits<4> CMD, MxEncEA EA, MxEncExt EXT> 140 : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, OPD:$opd), 141 MN#"."#TYPE.Prefix#"\t$opd, $dst", 142 [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, (TYPE.Load PAT:$opd)))], 143 MxArithEncoding<MxBead4Bits<CMD>, 144 !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#TYPE.RLet#"EA"), 145 MxBeadDReg<0>, EA, EXT>>; 146 147} // Constraints 148 149let mayLoad = 1, mayStore = 1 in { 150 151// FIXME MxBiArOp_FMR/FMI cannot consume CCR from MxAdd/MxSub which leads for 152// MxAdd to survive the match and subsequent mismatch. 153class MxBiArOp_FMR<string MN, MxType TYPE, MxOperand MEMOpd, 154 bits<4> CMD, MxEncEA EA, MxEncExt EXT> 155 : MxInst<(outs), (ins MEMOpd:$dst, TYPE.ROp:$opd), 156 MN#"."#TYPE.Prefix#"\t$opd, $dst", 157 [], 158 MxArithEncoding<MxBead4Bits<CMD>, 159 !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"EA"#TYPE.RLet), 160 MxBeadDReg<1>, EA, EXT>>; 161 162class MxBiArOp_FMI<string MN, MxType TYPE, MxOperand MEMOpd, 163 bits<4> CMD, MxEncEA MEMEA, MxEncExt MEMExt> 164 : MxInst<(outs), (ins MEMOpd:$dst, TYPE.IOp:$opd), 165 MN#"."#TYPE.Prefix#"\t$opd, $dst", 166 [], 167 MxArithImmEncoding<MxBead4Bits<CMD>, 168 !cast<MxEncSize>("MxEncSize"#TYPE.Size), 169 MEMEA, MEMExt, 170 !cast<MxEncExt>("MxExtI"#TYPE.Size#"_1")>>; 171} // mayLoad, mayStore 172} // Defs = [CCR] 173 174multiclass MxBiArOp_DF<string MN, SDNode NODE, bit isComm, 175 bits<4> CMD, bits<4> CMDI> { 176 177 // op $mem, $reg 178 def NAME#"8dk" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.KOp, MxType8.KPat, 179 CMD, MxEncEAk, MxExtBrief_2>; 180 def NAME#"16dk" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.KOp, MxType16.KPat, 181 CMD, MxEncEAk, MxExtBrief_2>; 182 def NAME#"32dk" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.KOp, MxType32.KPat, 183 CMD, MxEncEAk, MxExtBrief_2>; 184 185 def NAME#"8dq" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.QOp, MxType8.QPat, 186 CMD, MxEncEAq, MxExtI16_2>; 187 def NAME#"16dq" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.QOp, MxType16.QPat, 188 CMD, MxEncEAq, MxExtI16_2>; 189 def NAME#"32dq" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.QOp, MxType32.QPat, 190 CMD, MxEncEAq, MxExtI16_2>; 191 192 def NAME#"8dp" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.POp, MxType8.PPat, 193 CMD, MxEncEAp_2, MxExtI16_2>; 194 def NAME#"16dp" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.POp, MxType16.PPat, 195 CMD, MxEncEAp_2, MxExtI16_2>; 196 def NAME#"32dp" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.POp, MxType32.PPat, 197 CMD, MxEncEAp_2, MxExtI16_2>; 198 199 def NAME#"8df" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.FOp, MxType8.FPat, 200 CMD, MxEncEAf_2, MxExtBrief_2>; 201 def NAME#"16df" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.FOp, MxType16.FPat, 202 CMD, MxEncEAf_2, MxExtBrief_2>; 203 def NAME#"32df" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.FOp, MxType32.FPat, 204 CMD, MxEncEAf_2, MxExtBrief_2>; 205 206 def NAME#"8dj" : MxBiArOp_RFRM<MN, NODE, MxType8d, MxType8.JOp, MxType8.JPat, 207 CMD, MxEncEAj_2, MxExtEmpty>; 208 def NAME#"16dj" : MxBiArOp_RFRM<MN, NODE, MxType16d, MxType16.JOp, MxType16.JPat, 209 CMD, MxEncEAj_2, MxExtEmpty>; 210 def NAME#"32dj" : MxBiArOp_RFRM<MN, NODE, MxType32d, MxType32.JOp, MxType32.JPat, 211 CMD, MxEncEAj_2, MxExtEmpty>; 212 213 // op $imm, $reg 214 def NAME#"8di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType8d, CMD>; 215 def NAME#"16di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType16d, CMD>; 216 def NAME#"32di" : MxBiArOp_RFRI_xEA<MN, NODE, MxType32d, CMD>; 217 218 // op $reg, $mem 219 def NAME#"8pd" : MxBiArOp_FMR<MN, MxType8d, MxType8.POp, 220 CMD, MxEncEAp_0, MxExtI16_0>; 221 def NAME#"16pd" : MxBiArOp_FMR<MN, MxType16d, MxType16.POp, 222 CMD, MxEncEAp_0, MxExtI16_0>; 223 def NAME#"32pd" : MxBiArOp_FMR<MN, MxType32d, MxType32.POp, 224 CMD, MxEncEAp_0, MxExtI16_0>; 225 226 def NAME#"8fd" : MxBiArOp_FMR<MN, MxType8d, MxType8.FOp, 227 CMD, MxEncEAf_0, MxExtBrief_0>; 228 def NAME#"16fd" : MxBiArOp_FMR<MN, MxType16d, MxType16.FOp, 229 CMD, MxEncEAf_0, MxExtBrief_0>; 230 def NAME#"32fd" : MxBiArOp_FMR<MN, MxType32d, MxType32.FOp, 231 CMD, MxEncEAf_0, MxExtBrief_0>; 232 233 def NAME#"8jd" : MxBiArOp_FMR<MN, MxType8d, MxType8.JOp, 234 CMD, MxEncEAj_0, MxExtEmpty>; 235 def NAME#"16jd" : MxBiArOp_FMR<MN, MxType16d, MxType16.JOp, 236 CMD, MxEncEAj_0, MxExtEmpty>; 237 def NAME#"32jd" : MxBiArOp_FMR<MN, MxType32d, MxType32.JOp, 238 CMD, MxEncEAj_0, MxExtEmpty>; 239 240 // op $imm, $mem 241 def NAME#"8pi" : MxBiArOp_FMI<MN, MxType8, MxType8.POp, 242 CMDI, MxEncEAp_0, MxExtI16_0>; 243 def NAME#"16pi" : MxBiArOp_FMI<MN, MxType16, MxType16.POp, 244 CMDI, MxEncEAp_0, MxExtI16_0>; 245 def NAME#"32pi" : MxBiArOp_FMI<MN, MxType32, MxType32.POp, 246 CMDI, MxEncEAp_0, MxExtI16_0>; 247 248 def NAME#"8fi" : MxBiArOp_FMI<MN, MxType8, MxType8.FOp, 249 CMDI, MxEncEAf_0, MxExtBrief_0>; 250 def NAME#"16fi" : MxBiArOp_FMI<MN, MxType16, MxType16.FOp, 251 CMDI, MxEncEAf_0, MxExtBrief_0>; 252 def NAME#"32fi" : MxBiArOp_FMI<MN, MxType32, MxType32.FOp, 253 CMDI, MxEncEAf_0, MxExtBrief_0>; 254 255 def NAME#"8ji" : MxBiArOp_FMI<MN, MxType8, MxType8.JOp, 256 CMDI, MxEncEAj_0, MxExtEmpty>; 257 def NAME#"16ji" : MxBiArOp_FMI<MN, MxType16, MxType16.JOp, 258 CMDI, MxEncEAj_0, MxExtEmpty>; 259 def NAME#"32ji" : MxBiArOp_FMI<MN, MxType32, MxType32.JOp, 260 CMDI, MxEncEAj_0, MxExtEmpty>; 261 262 def NAME#"16dr" : MxBiArOp_RFRR_xEA<MN, NODE, MxType16d, MxType16r, 263 CMD, MxBeadDReg<0>>; 264 def NAME#"32dr" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32d, MxType32r, 265 CMD, MxBeadDReg<0>>; 266 267 let isCommutable = isComm in { 268 269 def NAME#"8dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType8d, MxType8d, 270 CMD, MxBeadDReg<0>>; 271 def NAME#"16dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType16d, MxType16d, 272 CMD, MxBeadDReg<0>>; 273 def NAME#"32dd" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32d, MxType32d, 274 CMD, MxBeadDReg<0>>; 275 276 } // isComm 277 278} // MxBiArOp_DF 279 280 281// These special snowflakes allowed to match address registers but since *A 282// operations do not produce CCR we should not match them against Mx nodes that 283// produce it. 284let Pattern = [(null_frag)] in 285multiclass MxBiArOp_AF<string MN, SDNode NODE, bits<4> CMD> { 286 287 def NAME#"32ak" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.KOp, MxType32.KPat, 288 CMD, MxEncEAk, MxExtBrief_2>; 289 def NAME#"32aq" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.QOp, MxType32.QPat, 290 CMD, MxEncEAq, MxExtI16_2>; 291 def NAME#"32af" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.FOp, MxType32.FPat, 292 CMD, MxEncEAf_2, MxExtBrief_2>; 293 def NAME#"32ap" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.POp, MxType32.PPat, 294 CMD, MxEncEAp_2, MxExtI16_2>; 295 def NAME#"32aj" : MxBiArOp_RFRM<MN, NODE, MxType32a, MxType32.JOp, MxType32.JPat, 296 CMD, MxEncEAj_2, MxExtEmpty>; 297 def NAME#"32ai" : MxBiArOp_RFRI_xEA<MN, NODE, MxType32a, CMD>; 298 299 def NAME#"32ar" : MxBiArOp_RFRR_xEA<MN, NODE, MxType32a, MxType32r, 300 CMD, MxBeadReg<0>>; 301 302} // MxBiArOp_AF 303 304// NOTE These naturally produce CCR 305 306defm ADD : MxBiArOp_DF<"add", MxAdd, 1, 0xD, 0x6>; 307defm ADD : MxBiArOp_AF<"adda", MxAdd, 0xD>; 308defm SUB : MxBiArOp_DF<"sub", MxSub, 0, 0x9, 0x4>; 309defm SUB : MxBiArOp_AF<"suba", MxSub, 0x9>; 310 311 312let Uses = [CCR], Defs = [CCR] in { 313let Constraints = "$src = $dst" in { 314 315// $reg, ccr <- $reg op $reg op ccr 316class MxBiArOp_RFRRF<string MN, SDNode NODE, MxType TYPE, bits<4> CMD> 317 : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src, TYPE.ROp:$opd), 318 MN#"."#TYPE.Prefix#"\t$opd, $dst", 319 [(set TYPE.VT:$dst, CCR, (NODE TYPE.VT:$src, TYPE.VT:$opd, CCR))], 320 MxArithXEncoding<MxBead4Bits<CMD>, 321 !cast<MxEncSize>("MxEncSize"#TYPE.Size), 322 MxBead1Bit<0>, MxBeadDReg<2>, MxBeadDReg<0>>>; 323 324} // Constraints 325} // Uses, Defs 326 327multiclass MxBiArOp_RFF<string MN, SDNode NODE, bit isComm, bits<4> CMD> { 328 329let isCommutable = isComm in { 330 331 def NAME#"8dd" : MxBiArOp_RFRRF<MN, NODE, MxType8d, CMD>; 332 def NAME#"16dd" : MxBiArOp_RFRRF<MN, NODE, MxType16d, CMD>; 333 def NAME#"32dd" : MxBiArOp_RFRRF<MN, NODE, MxType32d, CMD>; 334 335} // isComm 336 337} // MxBiArOp_RFF 338 339// NOTE These consume and produce CCR 340defm ADDX : MxBiArOp_RFF<"addx", MxAddX, 1, 0xD>; 341defm SUBX : MxBiArOp_RFF<"subx", MxSubX, 0, 0x9>; 342 343 344//===----------------------------------------------------------------------===// 345// And/Xor/Or 346//===----------------------------------------------------------------------===// 347 348defm AND : MxBiArOp_DF<"and", MxAnd, 1, 0xC, 0x2>; 349defm OR : MxBiArOp_DF<"or", MxOr, 1, 0x8, 0x0>; 350 351multiclass MxBiArOp_DF_EAd<string MN, SDNode NODE, bits<4> CMD, bits<4> CMDI> { 352 353 let isCommutable = 1 in { 354 355 def NAME#"8dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType8d, CMD>; 356 def NAME#"16dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType16d, CMD>; 357 def NAME#"32dd" : MxBiArOp_RFRR_EAd<MN, NODE, MxType32d, CMD>; 358 359 } // isCommutable = 1 360 361 def NAME#"8di" : MxBiArOp_RFRI<MN, NODE, MxType8d, CMDI>; 362 def NAME#"16di" : MxBiArOp_RFRI<MN, NODE, MxType16d, CMDI>; 363 def NAME#"32di" : MxBiArOp_RFRI<MN, NODE, MxType32d, CMDI>; 364 365} // MxBiArOp_DF_EAd 366 367defm XOR : MxBiArOp_DF_EAd<"eor", MxXor, 0xB, 0xA>; 368 369 370//===----------------------------------------------------------------------===// 371// CMP 372//===----------------------------------------------------------------------===// 373 374let Defs = [CCR] in { 375class MxCmp_RR<MxType LHS_TYPE, MxType RHS_TYPE = LHS_TYPE, 376 MxBead REG = MxBeadDReg<1>> 377 : MxInst<(outs), (ins LHS_TYPE.ROp:$lhs, RHS_TYPE.ROp:$rhs), 378 "cmp."#RHS_TYPE.Prefix#"\t$lhs, $rhs", 379 [(set CCR, (MxCmp LHS_TYPE.VT:$lhs, RHS_TYPE.VT:$rhs))], 380 MxArithEncoding<MxBead4Bits<0xB>, 381 !cast<MxEncOpMode>("MxOpMode"#RHS_TYPE.Size#RHS_TYPE.RLet#"EA"), 382 REG, 383 !cast<MxEncEA>("MxEncEA"#LHS_TYPE.RLet#"_0"), 384 MxExtEmpty>>; 385 386class MxCmp_RI<MxType TYPE> 387 : MxInst<(outs), (ins TYPE.IOp:$imm, TYPE.ROp:$reg), 388 "cmpi."#TYPE.Prefix#"\t$imm, $reg", 389 [(set CCR, (MxCmp TYPE.IPat:$imm, TYPE.VT:$reg))], 390 MxArithImmEncoding<MxBead4Bits<0xC>, 391 !cast<MxEncSize>("MxEncSize"#TYPE.Size), 392 MxEncEAd_1, MxExtEmpty, 393 !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>; 394 395let mayLoad = 1 in { 396 397class MxCmp_MI<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat, 398 MxEncEA EA, MxEncExt EXT> 399 : MxInst<(outs), (ins TYPE.IOp:$imm, MEMOpd:$mem), 400 "cmpi."#TYPE.Prefix#"\t$imm, $mem", 401 [(set CCR, (MxCmp TYPE.IPat:$imm, (load MEMPat:$mem)))], 402 MxArithImmEncoding<MxBead4Bits<0xC>, 403 !cast<MxEncSize>("MxEncSize"#TYPE.Size), 404 EA, EXT, 405 !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>; 406 407class MxCmp_BI<MxType TYPE> 408 : MxInst<(outs), (ins TYPE.IOp:$imm, MxAL32:$abs), 409 "cmpi."#TYPE.Prefix#"\t$imm, $abs", 410 [(set CCR, (MxCmp TYPE.IPat:$imm, 411 (load (i32 (MxWrapper tglobaladdr:$abs)))))], 412 MxArithImmEncoding<MxBead4Bits<0xC>, 413 !cast<MxEncSize>("MxEncSize"#TYPE.Size), 414 MxEncEAb, MxExtI32_1, 415 !cast<MxEncExt>("MxExtI"#TYPE.Size#"_0")>>; 416 417class MxCmp_RM<MxType TYPE, MxOperand MEMOpd, ComplexPattern MEMPat, 418 MxEncEA EA, MxEncExt EXT> 419 : MxInst<(outs), (ins TYPE.ROp:$reg, MEMOpd:$mem), 420 "cmp."#TYPE.Prefix#"\t$mem, $reg", 421 [(set CCR, (MxCmp (load MEMPat:$mem), TYPE.ROp:$reg))], 422 MxArithEncoding<MxBead4Bits<0xB>, 423 !cast<MxEncOpMode>("MxOpMode"#TYPE.Size#"dEA"), 424 MxBeadDReg<0>, EA, EXT>>; 425} // let mayLoad = 1 426 427} // let Defs = [CCR] 428 429multiclass MMxCmp_RM<MxType TYPE> { 430 def NAME#TYPE.KOp.Letter : MxCmp_RM<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk, 431 MxExtBrief_1>; 432 def NAME#TYPE.QOp.Letter : MxCmp_RM<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq, 433 MxExtI16_1>; 434 def NAME#TYPE.POp.Letter : MxCmp_RM<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1, 435 MxExtI16_1>; 436 def NAME#TYPE.FOp.Letter : MxCmp_RM<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1, 437 MxExtBrief_1>; 438 def NAME#TYPE.JOp.Letter : MxCmp_RM<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1, 439 MxExtEmpty>; 440} 441 442multiclass MMxCmp_MI<MxType TYPE> { 443 def NAME#TYPE.KOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.KOp, TYPE.KPat, MxEncEAk, 444 MxExtBrief_1>; 445 def NAME#TYPE.QOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.QOp, TYPE.QPat, MxEncEAq, 446 MxExtI16_1>; 447 def NAME#TYPE.POp.Letter#"i" : MxCmp_MI<TYPE, TYPE.POp, TYPE.PPat, MxEncEAp_1, 448 MxExtI16_1>; 449 def NAME#TYPE.FOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.FOp, TYPE.FPat, MxEncEAf_1, 450 MxExtBrief_1>; 451 def NAME#TYPE.JOp.Letter#"i" : MxCmp_MI<TYPE, TYPE.JOp, TYPE.JPat, MxEncEAj_1, 452 MxExtEmpty>; 453} 454 455foreach S = [8, 16, 32] in { 456 def CMP#S#di : MxCmp_RI<!cast<MxType>("MxType"#S#"d")>; 457 def CMP#S#bi : MxCmp_BI<!cast<MxType>("MxType"#S#"d")>; 458} // foreach 459 460def CMP8dd : MxCmp_RR<MxType8d>; 461foreach S = [16, 32] in { 462 def CMP#S#dr : MxCmp_RR<!cast<MxType>("MxType"#S#"r"), 463 !cast<MxType>("MxType"#S#"d")>; 464} 465 466// cmp mem, Dn 467defm CMP8d : MMxCmp_RM<MxType8d>; 468defm CMP16d : MMxCmp_RM<MxType16d>; 469defm CMP32d : MMxCmp_RM<MxType32d>; 470 471// cmp #imm, mem 472defm CMP8 : MMxCmp_MI<MxType8d>; 473defm CMP16 : MMxCmp_MI<MxType16d>; 474defm CMP32 : MMxCmp_MI<MxType32d>; 475 476 477//===----------------------------------------------------------------------===// 478// EXT 479//===----------------------------------------------------------------------===// 480 481def MxExtOpmode_wb : MxBead3Bits<0b010>; 482def MxExtOpmode_lw : MxBead3Bits<0b011>; 483def MxExtOpmode_lb : MxBead3Bits<0b111>; 484 485/// --------------------------------------------------- 486/// F E D C B A 9 | 8 7 6 | 5 4 3 | 2 1 0 487/// --------------------------------------------------- 488/// 0 1 0 0 1 0 0 | OPMODE | 0 0 0 | REG 489/// --------------------------------------------------- 490class MxExtEncoding<MxBead3Bits OPMODE> 491 : MxEncoding<MxBeadDReg<0>, MxBead3Bits<0b000>, OPMODE, 492 MxBead3Bits<0b100>, MxBead4Bits<0b0100>>; 493 494let Defs = [CCR] in 495let Constraints = "$src = $dst" in 496class MxExt<MxType TO, MxType FROM> 497 : MxInst<(outs TO.ROp:$dst), (ins TO.ROp:$src), 498 "ext."#TO.Prefix#"\t$src", [], 499 MxExtEncoding<!cast<MxBead3Bits>("MxExtOpmode_"#TO.Prefix#FROM.Prefix)>>; 500 501def EXT16 : MxExt<MxType16d, MxType8d>; 502def EXT32 : MxExt<MxType32d, MxType16d>; 503 504def : Pat<(sext_inreg i16:$src, i8), (EXT16 $src)>; 505def : Pat<(sext_inreg i32:$src, i16), (EXT32 $src)>; 506def : Pat<(sext_inreg i32:$src, i8), 507 (EXT32 (MOVXd32d16 (EXT16 (EXTRACT_SUBREG $src, MxSubRegIndex16Lo))))>; 508 509 510//===----------------------------------------------------------------------===// 511// DIV/MUL 512//===----------------------------------------------------------------------===// 513 514def MxSDiMuOpmode : MxBead3Bits<0b111>; 515def MxUDiMuOpmode : MxBead3Bits<0b011>; 516 517/// Word operation: 518/// ---------------------------------------------------- 519/// F E D C | B A 9 | 8 7 6 | 5 4 3 | 2 1 0 520/// ---------------------------------------------------- 521/// | | | EFFECTIVE ADDRESS 522/// x x x x | REG | OP MODE | MODE | REG 523/// ---------------------------------------------------- 524class MxDiMuEncoding<MxBead4Bits CMD, MxBead3Bits OPMODE, MxEncEA EA, MxEncExt EXT> 525 : MxEncoding<EA.Reg, EA.DA, EA.Mode, OPMODE, MxBeadDReg<0>, CMD, 526 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>; 527 528let Defs = [CCR] in { 529let Constraints = "$src = $dst" in { 530// $reg <- $reg op $reg 531class MxDiMuOp_DD<string MN, bits<4> CMD, MxBead3Bits OPMODE, 532 MxOperand DST, MxOperand OPD> 533 : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", [], 534 MxDiMuEncoding<MxBead4Bits<CMD>, OPMODE, MxEncEAd_2, MxExtEmpty>>; 535 536// $reg <- $reg op $imm 537class MxDiMuOp_DI<string MN, bits<4> CMD, MxBead3Bits OPMODE, 538 MxOperand DST, MxOperand OPD> 539 : MxInst<(outs DST:$dst), (ins DST:$src, OPD:$opd), MN#"\t$opd, $dst", [], 540 MxDiMuEncoding<MxBead4Bits<CMD>, OPMODE, MxEncEAi, MxExtI16_2>>; 541} // let Constraints 542} // Defs = [CCR] 543 544multiclass MxDiMuOp<string MN, bits<4> CMD, bit isComm = 0> { 545 546 let isCommutable = isComm in { 547 def "S"#NAME#"d32d16" : MxDiMuOp_DD<MN#"s", CMD, MxSDiMuOpmode, MxDRD32, 548 MxDRD16>; 549 def "U"#NAME#"d32d16" : MxDiMuOp_DD<MN#"u", CMD, MxUDiMuOpmode, MxDRD32, 550 MxDRD16>; 551 } 552 553 def "S"#NAME#"d32i16" : MxDiMuOp_DI<MN#"s", CMD, MxSDiMuOpmode, MxDRD32, 554 Mxi16imm>; 555 def "U"#NAME#"d32i16" : MxDiMuOp_DI<MN#"u", CMD, MxUDiMuOpmode, MxDRD32, 556 Mxi16imm>; 557 558} 559 560defm DIV : MxDiMuOp<"div", 0x8>; 561 562// This is used to cast immediates to 16-bits for operations which don't 563// support smaller immediate sizes. 564def as_i16imm : SDNodeXForm<imm, [{ 565 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16); 566}]>; 567 568// RR i8 569def : Pat<(sdiv i8:$dst, i8:$opd), 570 (EXTRACT_SUBREG 571 (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)), 572 MxSubRegIndex8Lo)>; 573 574def : Pat<(udiv i8:$dst, i8:$opd), 575 (EXTRACT_SUBREG 576 (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)), 577 MxSubRegIndex8Lo)>; 578 579def : Pat<(srem i8:$dst, i8:$opd), 580 (EXTRACT_SUBREG 581 (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d8 $dst), (MOVSXd16d8 $opd)), 8), 8), 582 MxSubRegIndex8Lo)>; 583 584def : Pat<(urem i8:$dst, i8:$opd), 585 (EXTRACT_SUBREG 586 (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d8 $dst), (MOVZXd16d8 $opd)), 8), 8), 587 MxSubRegIndex8Lo)>; 588 589// RR i16 590def : Pat<(sdiv i16:$dst, i16:$opd), 591 (EXTRACT_SUBREG 592 (SDIVd32d16 (MOVSXd32d16 $dst), $opd), 593 MxSubRegIndex16Lo)>; 594 595def : Pat<(udiv i16:$dst, i16:$opd), 596 (EXTRACT_SUBREG 597 (UDIVd32d16 (MOVZXd32d16 $dst), $opd), 598 MxSubRegIndex16Lo)>; 599 600def : Pat<(srem i16:$dst, i16:$opd), 601 (EXTRACT_SUBREG 602 (ASR32di (ASR32di (SDIVd32d16 (MOVSXd32d16 $dst), $opd), 8), 8), 603 MxSubRegIndex16Lo)>; 604 605def : Pat<(urem i16:$dst, i16:$opd), 606 (EXTRACT_SUBREG 607 (LSR32di (LSR32di (UDIVd32d16 (MOVZXd32d16 $dst), $opd), 8), 8), 608 MxSubRegIndex16Lo)>; 609 610 611// RI i8 612def : Pat<(sdiv i8:$dst, MximmSExt8:$opd), 613 (EXTRACT_SUBREG 614 (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)), 615 MxSubRegIndex8Lo)>; 616 617def : Pat<(udiv i8:$dst, MximmSExt8:$opd), 618 (EXTRACT_SUBREG 619 (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)), 620 MxSubRegIndex8Lo)>; 621 622def : Pat<(srem i8:$dst, MximmSExt8:$opd), 623 (EXTRACT_SUBREG 624 (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d8 $dst), (as_i16imm $opd)), 8), 8), 625 MxSubRegIndex8Lo)>; 626 627def : Pat<(urem i8:$dst, MximmSExt8:$opd), 628 (EXTRACT_SUBREG 629 (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d8 $dst), (as_i16imm $opd)), 8), 8), 630 MxSubRegIndex8Lo)>; 631 632// RI i16 633def : Pat<(sdiv i16:$dst, MximmSExt16:$opd), 634 (EXTRACT_SUBREG 635 (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd), 636 MxSubRegIndex16Lo)>; 637 638def : Pat<(udiv i16:$dst, MximmSExt16:$opd), 639 (EXTRACT_SUBREG 640 (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd), 641 MxSubRegIndex16Lo)>; 642 643def : Pat<(srem i16:$dst, MximmSExt16:$opd), 644 (EXTRACT_SUBREG 645 (ASR32di (ASR32di (SDIVd32i16 (MOVSXd32d16 $dst), imm:$opd), 8), 8), 646 MxSubRegIndex16Lo)>; 647 648def : Pat<(urem i16:$dst, MximmSExt16:$opd), 649 (EXTRACT_SUBREG 650 (LSR32di (LSR32di (UDIVd32i16 (MOVZXd32d16 $dst), imm:$opd), 8), 8), 651 MxSubRegIndex16Lo)>; 652 653 654defm MUL : MxDiMuOp<"mul", 0xC, 1>; 655 656// RR 657def : Pat<(mul i16:$dst, i16:$opd), 658 (EXTRACT_SUBREG 659 (SMULd32d16 (MOVXd32d16 $dst), $opd), 660 MxSubRegIndex16Lo)>; 661 662def : Pat<(mulhs i16:$dst, i16:$opd), 663 (EXTRACT_SUBREG 664 (ASR32di (ASR32di (SMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8), 665 MxSubRegIndex16Lo)>; 666 667def : Pat<(mulhu i16:$dst, i16:$opd), 668 (EXTRACT_SUBREG 669 (LSR32di (LSR32di (UMULd32d16 (MOVXd32d16 $dst), $opd), 8), 8), 670 MxSubRegIndex16Lo)>; 671 672 673// RI 674def : Pat<(mul i16:$dst, MximmSExt16:$opd), 675 (EXTRACT_SUBREG 676 (SMULd32i16 (MOVXd32d16 $dst), imm:$opd), 677 MxSubRegIndex16Lo)>; 678 679def : Pat<(mulhs i16:$dst, MximmSExt16:$opd), 680 (EXTRACT_SUBREG 681 (ASR32di (ASR32di (SMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8), 682 MxSubRegIndex16Lo)>; 683 684def : Pat<(mulhu i16:$dst, MximmSExt16:$opd), 685 (EXTRACT_SUBREG 686 (LSR32di (LSR32di (UMULd32i16 (MOVXd32d16 $dst), imm:$opd), 8), 8), 687 MxSubRegIndex16Lo)>; 688 689 690//===----------------------------------------------------------------------===// 691// NEG/NEGX 692//===----------------------------------------------------------------------===// 693 694/// ------------+------------+------+---------+--------- 695/// F E D C | B A 9 8 | 7 6 | 5 4 3 | 2 1 0 696/// ------------+------------+------+------------------- 697/// | | | EFFECTIVE ADDRESS 698/// 0 1 0 0 | x x x x | SIZE | MODE | REG 699/// ------------+------------+------+---------+--------- 700class MxNEGEncoding<MxBead4Bits CMD, MxEncSize SIZE, MxEncEA EA, MxEncExt EXT> 701 : MxEncoding<EA.Reg, EA.DA, EA.Mode, SIZE, CMD, MxBead4Bits<0b0100>, 702 EXT.Imm, EXT.B8, EXT.Scale, EXT.WL, EXT.DAReg>; 703 704let Defs = [CCR] in { 705let Constraints = "$src = $dst" in { 706 707class MxNeg_D<MxType TYPE> 708 : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src), 709 "neg."#TYPE.Prefix#"\t$dst", 710 [(set TYPE.VT:$dst, (ineg TYPE.VT:$src))], 711 MxNEGEncoding<MxBead4Bits<0x4>, 712 !cast<MxEncSize>("MxEncSize"#TYPE.Size), 713 MxEncEAd_0, MxExtEmpty>>; 714 715let Uses = [CCR] in { 716class MxNegX_D<MxType TYPE> 717 : MxInst<(outs TYPE.ROp:$dst), (ins TYPE.ROp:$src), 718 "negx."#TYPE.Prefix#"\t$dst", 719 [(set TYPE.VT:$dst, (MxSubX 0, TYPE.VT:$src, CCR))], 720 MxNEGEncoding<MxBead4Bits<0x0>, 721 !cast<MxEncSize>("MxEncSize"#TYPE.Size), 722 MxEncEAd_0, MxExtEmpty>>; 723} 724 725} // let Constraints 726} // let Defs = [CCR] 727 728foreach S = [8, 16, 32] in { 729 def NEG#S#d : MxNeg_D<!cast<MxType>("MxType"#S#"d")>; 730 def NEGX#S#d : MxNegX_D<!cast<MxType>("MxType"#S#"d")>; 731} 732 733def : Pat<(MxSub 0, i8 :$src), (NEG8d MxDRD8 :$src)>; 734def : Pat<(MxSub 0, i16:$src), (NEG16d MxDRD16:$src)>; 735def : Pat<(MxSub 0, i32:$src), (NEG32d MxDRD32:$src)>; 736 737//===----------------------------------------------------------------------===// 738// no-CCR Patterns 739//===----------------------------------------------------------------------===// 740 741/// Basically the reason for this stuff is that add and addc share the same 742/// operand types constraints for whatever reasons and I had to define a common 743/// MxAdd and MxSub instructions that produce CCR and then pattern-map add and addc 744/// to it. 745/// NOTE On the other hand I see no reason why I cannot just drop explicit CCR 746/// result. Anyway works for now, hopefully I will better understand how this stuff 747/// is designed later 748foreach N = ["add", "addc"] in { 749 750 // add reg, reg 751 def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd), 752 (ADD8dd MxDRD8 :$src, MxDRD8 :$opd)>; 753 def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd), 754 (ADD16dr MxXRD16:$src, MxDRD16:$opd)>; 755 def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd), 756 (ADD32dr MxXRD32:$src, MxDRD32:$opd)>; 757 758 // add (An), reg 759 def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)), 760 (ADD8dj MxDRD8:$src, MxType8.JOp:$opd)>; 761 def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)), 762 (ADD16dj MxDRD16:$src, MxType16.JOp:$opd)>; 763 def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)), 764 (ADD32dj MxDRD32:$src, MxType32.JOp:$opd)>; 765 766 // add (i,An), reg 767 def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)), 768 (ADD8dp MxDRD8:$src, MxType8.POp:$opd)>; 769 def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)), 770 (ADD16dp MxDRD16:$src, MxType16.POp:$opd)>; 771 def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)), 772 (ADD32dp MxDRD32:$src, MxType32.POp:$opd)>; 773 774 // add (i,An,Xn), reg 775 def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)), 776 (ADD8df MxDRD8:$src, MxType8.FOp:$opd)>; 777 def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)), 778 (ADD16df MxDRD16:$src, MxType16.FOp:$opd)>; 779 def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)), 780 (ADD32df MxDRD32:$src, MxType32.FOp:$opd)>; 781 782 // add reg, imm 783 def : Pat<(!cast<SDNode>(N) i8: $src, MximmSExt8:$opd), 784 (ADD8di MxDRD8 :$src, imm:$opd)>; 785 def : Pat<(!cast<SDNode>(N) i16:$src, MximmSExt16:$opd), 786 (ADD16di MxDRD16:$src, imm:$opd)>; 787 788 // LEAp is more complex and thus will be selected over normal ADD32ri but it cannot 789 // be used with data registers, here by adding complexity to a simple ADD32ri insts 790 // we make sure it will be selected over LEAp 791 let AddedComplexity = 15 in { 792 def : Pat<(!cast<SDNode>(N) i32:$src, MximmSExt32:$opd), 793 (ADD32di MxDRD32:$src, imm:$opd)>; 794 } // AddedComplexity = 15 795 796 // add imm, (An) 797 def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd), 798 MxType8.JPat:$dst), 799 (ADD8ji MxType8.JOp:$dst, imm:$opd)>; 800 def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd), 801 MxType16.JPat:$dst), 802 (ADD16ji MxType16.JOp:$dst, imm:$opd)>; 803 def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd), 804 MxType32.JPat:$dst), 805 (ADD32ji MxType32.JOp:$dst, imm:$opd)>; 806 807} // foreach add, addc 808 809def : Pat<(adde i8 :$src, i8 :$opd), (ADDX8dd MxDRD8 :$src, MxDRD8 :$opd)>; 810def : Pat<(adde i16:$src, i16:$opd), (ADDX16dd MxDRD16:$src, MxDRD16:$opd)>; 811def : Pat<(adde i32:$src, i32:$opd), (ADDX32dd MxDRD32:$src, MxDRD32:$opd)>; 812 813 814 815foreach N = ["sub", "subc"] in { 816 817 // sub reg, reg 818 def : Pat<(!cast<SDNode>(N) i8 :$src, i8 :$opd), 819 (SUB8dd MxDRD8 :$src, MxDRD8 :$opd)>; 820 def : Pat<(!cast<SDNode>(N) i16:$src, i16:$opd), 821 (SUB16dd MxDRD16:$src, MxDRD16:$opd)>; 822 def : Pat<(!cast<SDNode>(N) i32:$src, i32:$opd), 823 (SUB32dd MxDRD32:$src, MxDRD32:$opd)>; 824 825 826 // sub (An), reg 827 def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.JPat:$opd)), 828 (SUB8dj MxDRD8:$src, MxType8.JOp:$opd)>; 829 def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.JPat:$opd)), 830 (SUB16dj MxDRD16:$src, MxType16.JOp:$opd)>; 831 def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.JPat:$opd)), 832 (SUB32dj MxDRD32:$src, MxType32.JOp:$opd)>; 833 834 // sub (i,An), reg 835 def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.PPat:$opd)), 836 (SUB8dp MxDRD8:$src, MxType8.POp:$opd)>; 837 def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.PPat:$opd)), 838 (SUB16dp MxDRD16:$src, MxType16.POp:$opd)>; 839 def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.PPat:$opd)), 840 (SUB32dp MxDRD32:$src, MxType32.POp:$opd)>; 841 842 // sub (i,An,Xn), reg 843 def : Pat<(!cast<SDNode>(N) MxType8.VT:$src, (Mxloadi8 MxType8.FPat:$opd)), 844 (SUB8df MxDRD8:$src, MxType8.FOp:$opd)>; 845 def : Pat<(!cast<SDNode>(N) MxType16.VT:$src, (Mxloadi16 MxType16.FPat:$opd)), 846 (SUB16df MxDRD16:$src, MxType16.FOp:$opd)>; 847 def : Pat<(!cast<SDNode>(N) MxType32.VT:$src, (Mxloadi32 MxType32.FPat:$opd)), 848 (SUB32df MxDRD32:$src, MxType32.FOp:$opd)>; 849 850 // sub reg, imm 851 def : Pat<(!cast<SDNode>(N) i8 :$src, MximmSExt8 :$opd), 852 (SUB8di MxDRD8 :$src, imm:$opd)>; 853 def : Pat<(!cast<SDNode>(N) i16:$src, MximmSExt16:$opd), 854 (SUB16di MxDRD16:$src, imm:$opd)>; 855 def : Pat<(!cast<SDNode>(N) i32:$src, MximmSExt32:$opd), 856 (SUB32di MxDRD32:$src, imm:$opd)>; 857 858 // sub imm, (An) 859 def : Pat<(store (!cast<SDNode>(N) (load MxType8.JPat:$dst), MxType8.IPat:$opd), 860 MxType8.JPat:$dst), 861 (SUB8ji MxType8.JOp:$dst, imm:$opd)>; 862 def : Pat<(store (!cast<SDNode>(N) (load MxType16.JPat:$dst), MxType16.IPat:$opd), 863 MxType16.JPat:$dst), 864 (SUB16ji MxType16.JOp:$dst, imm:$opd)>; 865 def : Pat<(store (!cast<SDNode>(N) (load MxType32.JPat:$dst), MxType32.IPat:$opd), 866 MxType32.JPat:$dst), 867 (SUB32ji MxType32.JOp:$dst, imm:$opd)>; 868 869} // foreach sub, subx 870 871def : Pat<(sube i8 :$src, i8 :$opd), (SUBX8dd MxDRD8 :$src, MxDRD8 :$opd)>; 872def : Pat<(sube i16:$src, i16:$opd), (SUBX16dd MxDRD16:$src, MxDRD16:$opd)>; 873def : Pat<(sube i32:$src, i32:$opd), (SUBX32dd MxDRD32:$src, MxDRD32:$opd)>; 874 875multiclass BitwisePat<string INST, SDNode OP> { 876 // op reg, reg 877 def : Pat<(OP i8 :$src, i8 :$opd), 878 (!cast<MxInst>(INST#"8dd") MxDRD8 :$src, MxDRD8 :$opd)>; 879 def : Pat<(OP i16:$src, i16:$opd), 880 (!cast<MxInst>(INST#"16dd") MxDRD16:$src, MxDRD16:$opd)>; 881 def : Pat<(OP i32:$src, i32:$opd), 882 (!cast<MxInst>(INST#"32dd") MxDRD32:$src, MxDRD32:$opd)>; 883 // op reg, imm 884 def : Pat<(OP i8: $src, MximmSExt8 :$opd), 885 (!cast<MxInst>(INST#"8di") MxDRD8 :$src, imm:$opd)>; 886 def : Pat<(OP i16:$src, MximmSExt16:$opd), 887 (!cast<MxInst>(INST#"16di") MxDRD16:$src, imm:$opd)>; 888 def : Pat<(OP i32:$src, MximmSExt32:$opd), 889 (!cast<MxInst>(INST#"32di") MxDRD32:$src, imm:$opd)>; 890} 891 892defm : BitwisePat<"AND", and>; 893defm : BitwisePat<"OR", or>; 894defm : BitwisePat<"XOR", xor>; 895