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