1//===-- ARMInstrVFP.td - VFP support for ARM ---------------*- tablegen -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the ARM VFP instruction set. 11// 12//===----------------------------------------------------------------------===// 13 14def SDT_FTOI : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>; 15def SDT_ITOF : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; 16def SDT_CMPFP0 : SDTypeProfile<0, 1, [SDTCisFP<0>]>; 17def SDT_VMOVDRR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>, 18 SDTCisSameAs<1, 2>]>; 19 20def arm_ftoui : SDNode<"ARMISD::FTOUI", SDT_FTOI>; 21def arm_ftosi : SDNode<"ARMISD::FTOSI", SDT_FTOI>; 22def arm_sitof : SDNode<"ARMISD::SITOF", SDT_ITOF>; 23def arm_uitof : SDNode<"ARMISD::UITOF", SDT_ITOF>; 24def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInGlue, SDNPOutGlue]>; 25def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutGlue]>; 26def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutGlue]>; 27def arm_fmdrr : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>; 28 29 30//===----------------------------------------------------------------------===// 31// Operand Definitions. 32// 33 34// 8-bit floating-point immediate encodings. 35def FPImmOperand : AsmOperandClass { 36 let Name = "FPImm"; 37 let ParserMethod = "parseFPImm"; 38} 39 40def vfp_f32imm : Operand<f32>, 41 PatLeaf<(f32 fpimm), [{ 42 return ARM_AM::getFP32Imm(N->getValueAPF()) != -1; 43 }], SDNodeXForm<fpimm, [{ 44 APFloat InVal = N->getValueAPF(); 45 uint32_t enc = ARM_AM::getFP32Imm(InVal); 46 return CurDAG->getTargetConstant(enc, MVT::i32); 47 }]>> { 48 let PrintMethod = "printFPImmOperand"; 49 let ParserMatchClass = FPImmOperand; 50} 51 52def vfp_f64imm : Operand<f64>, 53 PatLeaf<(f64 fpimm), [{ 54 return ARM_AM::getFP64Imm(N->getValueAPF()) != -1; 55 }], SDNodeXForm<fpimm, [{ 56 APFloat InVal = N->getValueAPF(); 57 uint32_t enc = ARM_AM::getFP64Imm(InVal); 58 return CurDAG->getTargetConstant(enc, MVT::i32); 59 }]>> { 60 let PrintMethod = "printFPImmOperand"; 61 let ParserMatchClass = FPImmOperand; 62} 63 64def alignedload32 : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 65 return cast<LoadSDNode>(N)->getAlignment() >= 4; 66}]>; 67 68def alignedstore32 : PatFrag<(ops node:$val, node:$ptr), 69 (store node:$val, node:$ptr), [{ 70 return cast<StoreSDNode>(N)->getAlignment() >= 4; 71}]>; 72 73// The VCVT to/from fixed-point instructions encode the 'fbits' operand 74// (the number of fixed bits) differently than it appears in the assembly 75// source. It's encoded as "Size - fbits" where Size is the size of the 76// fixed-point representation (32 or 16) and fbits is the value appearing 77// in the assembly source, an integer in [0,16] or (0,32], depending on size. 78def fbits32_asm_operand : AsmOperandClass { let Name = "FBits32"; } 79def fbits32 : Operand<i32> { 80 let PrintMethod = "printFBits32"; 81 let ParserMatchClass = fbits32_asm_operand; 82} 83 84def fbits16_asm_operand : AsmOperandClass { let Name = "FBits16"; } 85def fbits16 : Operand<i32> { 86 let PrintMethod = "printFBits16"; 87 let ParserMatchClass = fbits16_asm_operand; 88} 89 90//===----------------------------------------------------------------------===// 91// Load / store Instructions. 92// 93 94let canFoldAsLoad = 1, isReMaterializable = 1 in { 95 96def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr), 97 IIC_fpLoad64, "vldr", "\t$Dd, $addr", 98 [(set DPR:$Dd, (f64 (alignedload32 addrmode5:$addr)))]>; 99 100def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$Sd), (ins addrmode5:$addr), 101 IIC_fpLoad32, "vldr", "\t$Sd, $addr", 102 [(set SPR:$Sd, (load addrmode5:$addr))]> { 103 // Some single precision VFP instructions may be executed on both NEON and VFP 104 // pipelines. 105 let D = VFPNeonDomain; 106} 107 108} // End of 'let canFoldAsLoad = 1, isReMaterializable = 1 in' 109 110def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$Dd, addrmode5:$addr), 111 IIC_fpStore64, "vstr", "\t$Dd, $addr", 112 [(alignedstore32 (f64 DPR:$Dd), addrmode5:$addr)]>; 113 114def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$Sd, addrmode5:$addr), 115 IIC_fpStore32, "vstr", "\t$Sd, $addr", 116 [(store SPR:$Sd, addrmode5:$addr)]> { 117 // Some single precision VFP instructions may be executed on both NEON and VFP 118 // pipelines. 119 let D = VFPNeonDomain; 120} 121 122//===----------------------------------------------------------------------===// 123// Load / store multiple Instructions. 124// 125 126multiclass vfp_ldst_mult<string asm, bit L_bit, 127 InstrItinClass itin, InstrItinClass itin_upd> { 128 // Double Precision 129 def DIA : 130 AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), 131 IndexModeNone, itin, 132 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> { 133 let Inst{24-23} = 0b01; // Increment After 134 let Inst{21} = 0; // No writeback 135 let Inst{20} = L_bit; 136 } 137 def DIA_UPD : 138 AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, 139 variable_ops), 140 IndexModeUpd, itin_upd, 141 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 142 let Inst{24-23} = 0b01; // Increment After 143 let Inst{21} = 1; // Writeback 144 let Inst{20} = L_bit; 145 } 146 def DDB_UPD : 147 AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, 148 variable_ops), 149 IndexModeUpd, itin_upd, 150 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 151 let Inst{24-23} = 0b10; // Decrement Before 152 let Inst{21} = 1; // Writeback 153 let Inst{20} = L_bit; 154 } 155 156 // Single Precision 157 def SIA : 158 AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), 159 IndexModeNone, itin, 160 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> { 161 let Inst{24-23} = 0b01; // Increment After 162 let Inst{21} = 0; // No writeback 163 let Inst{20} = L_bit; 164 165 // Some single precision VFP instructions may be executed on both NEON and 166 // VFP pipelines. 167 let D = VFPNeonDomain; 168 } 169 def SIA_UPD : 170 AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, 171 variable_ops), 172 IndexModeUpd, itin_upd, 173 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 174 let Inst{24-23} = 0b01; // Increment After 175 let Inst{21} = 1; // Writeback 176 let Inst{20} = L_bit; 177 178 // Some single precision VFP instructions may be executed on both NEON and 179 // VFP pipelines. 180 let D = VFPNeonDomain; 181 } 182 def SDB_UPD : 183 AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, 184 variable_ops), 185 IndexModeUpd, itin_upd, 186 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 187 let Inst{24-23} = 0b10; // Decrement Before 188 let Inst{21} = 1; // Writeback 189 let Inst{20} = L_bit; 190 191 // Some single precision VFP instructions may be executed on both NEON and 192 // VFP pipelines. 193 let D = VFPNeonDomain; 194 } 195} 196 197let neverHasSideEffects = 1 in { 198 199let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 200defm VLDM : vfp_ldst_mult<"vldm", 1, IIC_fpLoad_m, IIC_fpLoad_mu>; 201 202let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 203defm VSTM : vfp_ldst_mult<"vstm", 0, IIC_fpLoad_m, IIC_fpLoad_mu>; 204 205} // neverHasSideEffects 206 207def : MnemonicAlias<"vldm", "vldmia">; 208def : MnemonicAlias<"vstm", "vstmia">; 209 210def : InstAlias<"vpush${p} $r", (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r)>, 211 Requires<[HasVFP2]>; 212def : InstAlias<"vpush${p} $r", (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r)>, 213 Requires<[HasVFP2]>; 214def : InstAlias<"vpop${p} $r", (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r)>, 215 Requires<[HasVFP2]>; 216def : InstAlias<"vpop${p} $r", (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r)>, 217 Requires<[HasVFP2]>; 218defm : VFPDTAnyInstAlias<"vpush${p}", "$r", 219 (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r)>; 220defm : VFPDTAnyInstAlias<"vpush${p}", "$r", 221 (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r)>; 222defm : VFPDTAnyInstAlias<"vpop${p}", "$r", 223 (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r)>; 224defm : VFPDTAnyInstAlias<"vpop${p}", "$r", 225 (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r)>; 226 227// FLDMX, FSTMX - Load and store multiple unknown precision registers for 228// pre-armv6 cores. 229// These instruction are deprecated so we don't want them to get selected. 230multiclass vfp_ldstx_mult<string asm, bit L_bit> { 231 // Unknown precision 232 def XIA : 233 AXXI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), 234 IndexModeNone, !strconcat(asm, "iax${p}\t$Rn, $regs"), "", []> { 235 let Inst{24-23} = 0b01; // Increment After 236 let Inst{21} = 0; // No writeback 237 let Inst{20} = L_bit; 238 } 239 def XIA_UPD : 240 AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), 241 IndexModeUpd, !strconcat(asm, "iax${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 242 let Inst{24-23} = 0b01; // Increment After 243 let Inst{21} = 1; // Writeback 244 let Inst{20} = L_bit; 245 } 246 def XDB_UPD : 247 AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), 248 IndexModeUpd, !strconcat(asm, "dbx${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 249 let Inst{24-23} = 0b10; // Decrement Before 250 let Inst{21} = 1; 251 let Inst{20} = L_bit; 252 } 253} 254 255defm FLDM : vfp_ldstx_mult<"fldm", 1>; 256defm FSTM : vfp_ldstx_mult<"fstm", 0>; 257 258//===----------------------------------------------------------------------===// 259// FP Binary Operations. 260// 261 262let TwoOperandAliasConstraint = "$Dn = $Dd" in 263def VADDD : ADbI<0b11100, 0b11, 0, 0, 264 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 265 IIC_fpALU64, "vadd", ".f64\t$Dd, $Dn, $Dm", 266 [(set DPR:$Dd, (fadd DPR:$Dn, (f64 DPR:$Dm)))]>; 267 268let TwoOperandAliasConstraint = "$Sn = $Sd" in 269def VADDS : ASbIn<0b11100, 0b11, 0, 0, 270 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 271 IIC_fpALU32, "vadd", ".f32\t$Sd, $Sn, $Sm", 272 [(set SPR:$Sd, (fadd SPR:$Sn, SPR:$Sm))]> { 273 // Some single precision VFP instructions may be executed on both NEON and 274 // VFP pipelines on A8. 275 let D = VFPNeonA8Domain; 276} 277 278let TwoOperandAliasConstraint = "$Dn = $Dd" in 279def VSUBD : ADbI<0b11100, 0b11, 1, 0, 280 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 281 IIC_fpALU64, "vsub", ".f64\t$Dd, $Dn, $Dm", 282 [(set DPR:$Dd, (fsub DPR:$Dn, (f64 DPR:$Dm)))]>; 283 284let TwoOperandAliasConstraint = "$Sn = $Sd" in 285def VSUBS : ASbIn<0b11100, 0b11, 1, 0, 286 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 287 IIC_fpALU32, "vsub", ".f32\t$Sd, $Sn, $Sm", 288 [(set SPR:$Sd, (fsub SPR:$Sn, SPR:$Sm))]> { 289 // Some single precision VFP instructions may be executed on both NEON and 290 // VFP pipelines on A8. 291 let D = VFPNeonA8Domain; 292} 293 294let TwoOperandAliasConstraint = "$Dn = $Dd" in 295def VDIVD : ADbI<0b11101, 0b00, 0, 0, 296 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 297 IIC_fpDIV64, "vdiv", ".f64\t$Dd, $Dn, $Dm", 298 [(set DPR:$Dd, (fdiv DPR:$Dn, (f64 DPR:$Dm)))]>; 299 300let TwoOperandAliasConstraint = "$Sn = $Sd" in 301def VDIVS : ASbI<0b11101, 0b00, 0, 0, 302 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 303 IIC_fpDIV32, "vdiv", ".f32\t$Sd, $Sn, $Sm", 304 [(set SPR:$Sd, (fdiv SPR:$Sn, SPR:$Sm))]>; 305 306let TwoOperandAliasConstraint = "$Dn = $Dd" in 307def VMULD : ADbI<0b11100, 0b10, 0, 0, 308 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 309 IIC_fpMUL64, "vmul", ".f64\t$Dd, $Dn, $Dm", 310 [(set DPR:$Dd, (fmul DPR:$Dn, (f64 DPR:$Dm)))]>; 311 312let TwoOperandAliasConstraint = "$Sn = $Sd" in 313def VMULS : ASbIn<0b11100, 0b10, 0, 0, 314 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 315 IIC_fpMUL32, "vmul", ".f32\t$Sd, $Sn, $Sm", 316 [(set SPR:$Sd, (fmul SPR:$Sn, SPR:$Sm))]> { 317 // Some single precision VFP instructions may be executed on both NEON and 318 // VFP pipelines on A8. 319 let D = VFPNeonA8Domain; 320} 321 322def VNMULD : ADbI<0b11100, 0b10, 1, 0, 323 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 324 IIC_fpMUL64, "vnmul", ".f64\t$Dd, $Dn, $Dm", 325 [(set DPR:$Dd, (fneg (fmul DPR:$Dn, (f64 DPR:$Dm))))]>; 326 327def VNMULS : ASbI<0b11100, 0b10, 1, 0, 328 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 329 IIC_fpMUL32, "vnmul", ".f32\t$Sd, $Sn, $Sm", 330 [(set SPR:$Sd, (fneg (fmul SPR:$Sn, SPR:$Sm)))]> { 331 // Some single precision VFP instructions may be executed on both NEON and 332 // VFP pipelines on A8. 333 let D = VFPNeonA8Domain; 334} 335 336multiclass vsel_inst<string op, bits<2> opc, int CC> { 337 let DecoderNamespace = "VFPV8", PostEncoderMethod = "", 338 Uses = [CPSR], AddedComplexity = 4 in { 339 def S : ASbInp<0b11100, opc, 0, 340 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 341 NoItinerary, !strconcat("vsel", op, ".f32\t$Sd, $Sn, $Sm"), 342 [(set SPR:$Sd, (ARMcmov SPR:$Sm, SPR:$Sn, CC))]>, 343 Requires<[HasFPARMv8]>; 344 345 def D : ADbInp<0b11100, opc, 0, 346 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 347 NoItinerary, !strconcat("vsel", op, ".f64\t$Dd, $Dn, $Dm"), 348 [(set DPR:$Dd, (ARMcmov (f64 DPR:$Dm), (f64 DPR:$Dn), CC))]>, 349 Requires<[HasFPARMv8, HasDPVFP]>; 350 } 351} 352 353// The CC constants here match ARMCC::CondCodes. 354defm VSELGT : vsel_inst<"gt", 0b11, 12>; 355defm VSELGE : vsel_inst<"ge", 0b10, 10>; 356defm VSELEQ : vsel_inst<"eq", 0b00, 0>; 357defm VSELVS : vsel_inst<"vs", 0b01, 6>; 358 359multiclass vmaxmin_inst<string op, bit opc, SDNode SD> { 360 let DecoderNamespace = "VFPV8", PostEncoderMethod = "" in { 361 def S : ASbInp<0b11101, 0b00, opc, 362 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 363 NoItinerary, !strconcat(op, ".f32\t$Sd, $Sn, $Sm"), 364 [(set SPR:$Sd, (SD SPR:$Sn, SPR:$Sm))]>, 365 Requires<[HasFPARMv8]>; 366 367 def D : ADbInp<0b11101, 0b00, opc, 368 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 369 NoItinerary, !strconcat(op, ".f64\t$Dd, $Dn, $Dm"), 370 [(set DPR:$Dd, (f64 (SD (f64 DPR:$Dn), (f64 DPR:$Dm))))]>, 371 Requires<[HasFPARMv8, HasDPVFP]>; 372 } 373} 374 375defm VMAXNM : vmaxmin_inst<"vmaxnm", 0, ARMvmaxnm>; 376defm VMINNM : vmaxmin_inst<"vminnm", 1, ARMvminnm>; 377 378// Match reassociated forms only if not sign dependent rounding. 379def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)), 380 (VNMULD DPR:$a, DPR:$b)>, 381 Requires<[NoHonorSignDependentRounding,HasDPVFP]>; 382def : Pat<(fmul (fneg SPR:$a), SPR:$b), 383 (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>; 384 385// These are encoded as unary instructions. 386let Defs = [FPSCR_NZCV] in { 387def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0, 388 (outs), (ins DPR:$Dd, DPR:$Dm), 389 IIC_fpCMP64, "vcmpe", ".f64\t$Dd, $Dm", 390 [(arm_cmpfp DPR:$Dd, (f64 DPR:$Dm))]>; 391 392def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0, 393 (outs), (ins SPR:$Sd, SPR:$Sm), 394 IIC_fpCMP32, "vcmpe", ".f32\t$Sd, $Sm", 395 [(arm_cmpfp SPR:$Sd, SPR:$Sm)]> { 396 // Some single precision VFP instructions may be executed on both NEON and 397 // VFP pipelines on A8. 398 let D = VFPNeonA8Domain; 399} 400 401// FIXME: Verify encoding after integrated assembler is working. 402def VCMPD : ADuI<0b11101, 0b11, 0b0100, 0b01, 0, 403 (outs), (ins DPR:$Dd, DPR:$Dm), 404 IIC_fpCMP64, "vcmp", ".f64\t$Dd, $Dm", 405 [/* For disassembly only; pattern left blank */]>; 406 407def VCMPS : ASuI<0b11101, 0b11, 0b0100, 0b01, 0, 408 (outs), (ins SPR:$Sd, SPR:$Sm), 409 IIC_fpCMP32, "vcmp", ".f32\t$Sd, $Sm", 410 [/* For disassembly only; pattern left blank */]> { 411 // Some single precision VFP instructions may be executed on both NEON and 412 // VFP pipelines on A8. 413 let D = VFPNeonA8Domain; 414} 415} // Defs = [FPSCR_NZCV] 416 417//===----------------------------------------------------------------------===// 418// FP Unary Operations. 419// 420 421def VABSD : ADuI<0b11101, 0b11, 0b0000, 0b11, 0, 422 (outs DPR:$Dd), (ins DPR:$Dm), 423 IIC_fpUNA64, "vabs", ".f64\t$Dd, $Dm", 424 [(set DPR:$Dd, (fabs (f64 DPR:$Dm)))]>; 425 426def VABSS : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0, 427 (outs SPR:$Sd), (ins SPR:$Sm), 428 IIC_fpUNA32, "vabs", ".f32\t$Sd, $Sm", 429 [(set SPR:$Sd, (fabs SPR:$Sm))]> { 430 // Some single precision VFP instructions may be executed on both NEON and 431 // VFP pipelines on A8. 432 let D = VFPNeonA8Domain; 433} 434 435let Defs = [FPSCR_NZCV] in { 436def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0, 437 (outs), (ins DPR:$Dd), 438 IIC_fpCMP64, "vcmpe", ".f64\t$Dd, #0", 439 [(arm_cmpfp0 (f64 DPR:$Dd))]> { 440 let Inst{3-0} = 0b0000; 441 let Inst{5} = 0; 442} 443 444def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0, 445 (outs), (ins SPR:$Sd), 446 IIC_fpCMP32, "vcmpe", ".f32\t$Sd, #0", 447 [(arm_cmpfp0 SPR:$Sd)]> { 448 let Inst{3-0} = 0b0000; 449 let Inst{5} = 0; 450 451 // Some single precision VFP instructions may be executed on both NEON and 452 // VFP pipelines on A8. 453 let D = VFPNeonA8Domain; 454} 455 456// FIXME: Verify encoding after integrated assembler is working. 457def VCMPZD : ADuI<0b11101, 0b11, 0b0101, 0b01, 0, 458 (outs), (ins DPR:$Dd), 459 IIC_fpCMP64, "vcmp", ".f64\t$Dd, #0", 460 [/* For disassembly only; pattern left blank */]> { 461 let Inst{3-0} = 0b0000; 462 let Inst{5} = 0; 463} 464 465def VCMPZS : ASuI<0b11101, 0b11, 0b0101, 0b01, 0, 466 (outs), (ins SPR:$Sd), 467 IIC_fpCMP32, "vcmp", ".f32\t$Sd, #0", 468 [/* For disassembly only; pattern left blank */]> { 469 let Inst{3-0} = 0b0000; 470 let Inst{5} = 0; 471 472 // Some single precision VFP instructions may be executed on both NEON and 473 // VFP pipelines on A8. 474 let D = VFPNeonA8Domain; 475} 476} // Defs = [FPSCR_NZCV] 477 478def VCVTDS : ASuI<0b11101, 0b11, 0b0111, 0b11, 0, 479 (outs DPR:$Dd), (ins SPR:$Sm), 480 IIC_fpCVTDS, "vcvt", ".f64.f32\t$Dd, $Sm", 481 [(set DPR:$Dd, (fextend SPR:$Sm))]> { 482 // Instruction operands. 483 bits<5> Dd; 484 bits<5> Sm; 485 486 // Encode instruction operands. 487 let Inst{3-0} = Sm{4-1}; 488 let Inst{5} = Sm{0}; 489 let Inst{15-12} = Dd{3-0}; 490 let Inst{22} = Dd{4}; 491} 492 493// Special case encoding: bits 11-8 is 0b1011. 494def VCVTSD : VFPAI<(outs SPR:$Sd), (ins DPR:$Dm), VFPUnaryFrm, 495 IIC_fpCVTSD, "vcvt", ".f32.f64\t$Sd, $Dm", 496 [(set SPR:$Sd, (fround DPR:$Dm))]> { 497 // Instruction operands. 498 bits<5> Sd; 499 bits<5> Dm; 500 501 // Encode instruction operands. 502 let Inst{3-0} = Dm{3-0}; 503 let Inst{5} = Dm{4}; 504 let Inst{15-12} = Sd{4-1}; 505 let Inst{22} = Sd{0}; 506 507 let Inst{27-23} = 0b11101; 508 let Inst{21-16} = 0b110111; 509 let Inst{11-8} = 0b1011; 510 let Inst{7-6} = 0b11; 511 let Inst{4} = 0; 512 513 let Predicates = [HasVFP2, HasDPVFP]; 514} 515 516// Between half, single and double-precision. For disassembly only. 517 518// FIXME: Verify encoding after integrated assembler is working. 519def VCVTBHS: ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$Sd), (ins SPR:$Sm), 520 /* FIXME */ IIC_fpCVTSH, "vcvtb", ".f32.f16\t$Sd, $Sm", 521 [/* For disassembly only; pattern left blank */]>; 522 523def VCVTBSH: ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$Sd), (ins SPR:$Sm), 524 /* FIXME */ IIC_fpCVTHS, "vcvtb", ".f16.f32\t$Sd, $Sm", 525 [/* For disassembly only; pattern left blank */]>; 526 527def : Pat<(f32_to_f16 SPR:$a), 528 (i32 (COPY_TO_REGCLASS (VCVTBSH SPR:$a), GPR))>; 529 530def : Pat<(f16_to_f32 GPR:$a), 531 (VCVTBHS (COPY_TO_REGCLASS GPR:$a, SPR))>; 532 533def VCVTTHS: ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sm), 534 /* FIXME */ IIC_fpCVTSH, "vcvtt", ".f32.f16\t$Sd, $Sm", 535 [/* For disassembly only; pattern left blank */]>; 536 537def VCVTTSH: ASuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sm), 538 /* FIXME */ IIC_fpCVTHS, "vcvtt", ".f16.f32\t$Sd, $Sm", 539 [/* For disassembly only; pattern left blank */]>; 540 541def VCVTBHD : ADuI<0b11101, 0b11, 0b0010, 0b01, 0, 542 (outs DPR:$Dd), (ins SPR:$Sm), 543 NoItinerary, "vcvtb", ".f64.f16\t$Dd, $Sm", 544 []>, Requires<[HasFPARMv8, HasDPVFP]> { 545 // Instruction operands. 546 bits<5> Sm; 547 548 // Encode instruction operands. 549 let Inst{3-0} = Sm{4-1}; 550 let Inst{5} = Sm{0}; 551} 552 553def VCVTBDH : ADuI<0b11101, 0b11, 0b0011, 0b01, 0, 554 (outs SPR:$Sd), (ins DPR:$Dm), 555 NoItinerary, "vcvtb", ".f16.f64\t$Sd, $Dm", 556 []>, Requires<[HasFPARMv8, HasDPVFP]> { 557 // Instruction operands. 558 bits<5> Sd; 559 bits<5> Dm; 560 561 // Encode instruction operands. 562 let Inst{3-0} = Dm{3-0}; 563 let Inst{5} = Dm{4}; 564 let Inst{15-12} = Sd{4-1}; 565 let Inst{22} = Sd{0}; 566} 567 568def VCVTTHD : ADuI<0b11101, 0b11, 0b0010, 0b11, 0, 569 (outs DPR:$Dd), (ins SPR:$Sm), 570 NoItinerary, "vcvtt", ".f64.f16\t$Dd, $Sm", 571 []>, Requires<[HasFPARMv8, HasDPVFP]> { 572 // Instruction operands. 573 bits<5> Sm; 574 575 // Encode instruction operands. 576 let Inst{3-0} = Sm{4-1}; 577 let Inst{5} = Sm{0}; 578} 579 580def VCVTTDH : ADuI<0b11101, 0b11, 0b0011, 0b11, 0, 581 (outs SPR:$Sd), (ins DPR:$Dm), 582 NoItinerary, "vcvtt", ".f16.f64\t$Sd, $Dm", 583 []>, Requires<[HasFPARMv8, HasDPVFP]> { 584 // Instruction operands. 585 bits<5> Sd; 586 bits<5> Dm; 587 588 // Encode instruction operands. 589 let Inst{15-12} = Sd{4-1}; 590 let Inst{22} = Sd{0}; 591 let Inst{3-0} = Dm{3-0}; 592 let Inst{5} = Dm{4}; 593} 594 595multiclass vcvt_inst<string opc, bits<2> rm> { 596 let PostEncoderMethod = "", DecoderNamespace = "VFPV8" in { 597 def SS : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0, 598 (outs SPR:$Sd), (ins SPR:$Sm), 599 NoItinerary, !strconcat("vcvt", opc, ".s32.f32\t$Sd, $Sm"), 600 []>, Requires<[HasFPARMv8]> { 601 let Inst{17-16} = rm; 602 } 603 604 def US : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0, 605 (outs SPR:$Sd), (ins SPR:$Sm), 606 NoItinerary, !strconcat("vcvt", opc, ".u32.f32\t$Sd, $Sm"), 607 []>, Requires<[HasFPARMv8]> { 608 let Inst{17-16} = rm; 609 } 610 611 def SD : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0, 612 (outs SPR:$Sd), (ins DPR:$Dm), 613 NoItinerary, !strconcat("vcvt", opc, ".s32.f64\t$Sd, $Dm"), 614 []>, Requires<[HasFPARMv8, HasDPVFP]> { 615 bits<5> Dm; 616 617 let Inst{17-16} = rm; 618 619 // Encode instruction operands 620 let Inst{3-0} = Dm{3-0}; 621 let Inst{5} = Dm{4}; 622 let Inst{8} = 1; 623 } 624 625 def UD : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0, 626 (outs SPR:$Sd), (ins DPR:$Dm), 627 NoItinerary, !strconcat("vcvt", opc, ".u32.f64\t$Sd, $Dm"), 628 []>, Requires<[HasFPARMv8, HasDPVFP]> { 629 bits<5> Dm; 630 631 let Inst{17-16} = rm; 632 633 // Encode instruction operands 634 let Inst{3-0} = Dm{3-0}; 635 let Inst{5} = Dm{4}; 636 let Inst{8} = 1; 637 } 638 } 639} 640 641defm VCVTA : vcvt_inst<"a", 0b00>; 642defm VCVTN : vcvt_inst<"n", 0b01>; 643defm VCVTP : vcvt_inst<"p", 0b10>; 644defm VCVTM : vcvt_inst<"m", 0b11>; 645 646def VNEGD : ADuI<0b11101, 0b11, 0b0001, 0b01, 0, 647 (outs DPR:$Dd), (ins DPR:$Dm), 648 IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm", 649 [(set DPR:$Dd, (fneg (f64 DPR:$Dm)))]>; 650 651def VNEGS : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0, 652 (outs SPR:$Sd), (ins SPR:$Sm), 653 IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm", 654 [(set SPR:$Sd, (fneg SPR:$Sm))]> { 655 // Some single precision VFP instructions may be executed on both NEON and 656 // VFP pipelines on A8. 657 let D = VFPNeonA8Domain; 658} 659 660multiclass vrint_inst_zrx<string opc, bit op, bit op2> { 661 def S : ASuI<0b11101, 0b11, 0b0110, 0b11, 0, 662 (outs SPR:$Sd), (ins SPR:$Sm), 663 NoItinerary, !strconcat("vrint", opc), ".f32\t$Sd, $Sm", 664 []>, Requires<[HasFPARMv8]> { 665 let Inst{7} = op2; 666 let Inst{16} = op; 667 } 668 def D : ADuI<0b11101, 0b11, 0b0110, 0b11, 0, 669 (outs DPR:$Dd), (ins DPR:$Dm), 670 NoItinerary, !strconcat("vrint", opc), ".f64\t$Dd, $Dm", 671 []>, Requires<[HasFPARMv8, HasDPVFP]> { 672 let Inst{7} = op2; 673 let Inst{16} = op; 674 } 675 676 def : InstAlias<!strconcat("vrint", opc, "$p.f32.f32\t$Sd, $Sm"), 677 (!cast<Instruction>(NAME#"S") SPR:$Sd, SPR:$Sm, pred:$p)>, 678 Requires<[HasFPARMv8]>; 679 def : InstAlias<!strconcat("vrint", opc, "$p.f64.f64\t$Dd, $Dm"), 680 (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm, pred:$p)>, 681 Requires<[HasFPARMv8,HasDPVFP]>; 682} 683 684defm VRINTZ : vrint_inst_zrx<"z", 0, 1>; 685defm VRINTR : vrint_inst_zrx<"r", 0, 0>; 686defm VRINTX : vrint_inst_zrx<"x", 1, 0>; 687 688multiclass vrint_inst_anpm<string opc, bits<2> rm> { 689 let PostEncoderMethod = "", DecoderNamespace = "VFPV8" in { 690 def S : ASuInp<0b11101, 0b11, 0b1000, 0b01, 0, 691 (outs SPR:$Sd), (ins SPR:$Sm), 692 NoItinerary, !strconcat("vrint", opc, ".f32\t$Sd, $Sm"), 693 []>, Requires<[HasFPARMv8]> { 694 let Inst{17-16} = rm; 695 } 696 def D : ADuInp<0b11101, 0b11, 0b1000, 0b01, 0, 697 (outs DPR:$Dd), (ins DPR:$Dm), 698 NoItinerary, !strconcat("vrint", opc, ".f64\t$Dd, $Dm"), 699 []>, Requires<[HasFPARMv8, HasDPVFP]> { 700 let Inst{17-16} = rm; 701 } 702 } 703 704 def : InstAlias<!strconcat("vrint", opc, ".f32.f32\t$Sd, $Sm"), 705 (!cast<Instruction>(NAME#"S") SPR:$Sd, SPR:$Sm)>, 706 Requires<[HasFPARMv8]>; 707 def : InstAlias<!strconcat("vrint", opc, ".f64.f64\t$Dd, $Dm"), 708 (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm)>, 709 Requires<[HasFPARMv8,HasDPVFP]>; 710} 711 712defm VRINTA : vrint_inst_anpm<"a", 0b00>; 713defm VRINTN : vrint_inst_anpm<"n", 0b01>; 714defm VRINTP : vrint_inst_anpm<"p", 0b10>; 715defm VRINTM : vrint_inst_anpm<"m", 0b11>; 716 717def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0, 718 (outs DPR:$Dd), (ins DPR:$Dm), 719 IIC_fpSQRT64, "vsqrt", ".f64\t$Dd, $Dm", 720 [(set DPR:$Dd, (fsqrt (f64 DPR:$Dm)))]>; 721 722def VSQRTS : ASuI<0b11101, 0b11, 0b0001, 0b11, 0, 723 (outs SPR:$Sd), (ins SPR:$Sm), 724 IIC_fpSQRT32, "vsqrt", ".f32\t$Sd, $Sm", 725 [(set SPR:$Sd, (fsqrt SPR:$Sm))]>; 726 727let neverHasSideEffects = 1 in { 728def VMOVD : ADuI<0b11101, 0b11, 0b0000, 0b01, 0, 729 (outs DPR:$Dd), (ins DPR:$Dm), 730 IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm", []>; 731 732def VMOVS : ASuI<0b11101, 0b11, 0b0000, 0b01, 0, 733 (outs SPR:$Sd), (ins SPR:$Sm), 734 IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm", []>; 735} // neverHasSideEffects 736 737//===----------------------------------------------------------------------===// 738// FP <-> GPR Copies. Int <-> FP Conversions. 739// 740 741def VMOVRS : AVConv2I<0b11100001, 0b1010, 742 (outs GPR:$Rt), (ins SPR:$Sn), 743 IIC_fpMOVSI, "vmov", "\t$Rt, $Sn", 744 [(set GPR:$Rt, (bitconvert SPR:$Sn))]> { 745 // Instruction operands. 746 bits<4> Rt; 747 bits<5> Sn; 748 749 // Encode instruction operands. 750 let Inst{19-16} = Sn{4-1}; 751 let Inst{7} = Sn{0}; 752 let Inst{15-12} = Rt; 753 754 let Inst{6-5} = 0b00; 755 let Inst{3-0} = 0b0000; 756 757 // Some single precision VFP instructions may be executed on both NEON and VFP 758 // pipelines. 759 let D = VFPNeonDomain; 760} 761 762// Bitcast i32 -> f32. NEON prefers to use VMOVDRR. 763def VMOVSR : AVConv4I<0b11100000, 0b1010, 764 (outs SPR:$Sn), (ins GPR:$Rt), 765 IIC_fpMOVIS, "vmov", "\t$Sn, $Rt", 766 [(set SPR:$Sn, (bitconvert GPR:$Rt))]>, 767 Requires<[HasVFP2, UseVMOVSR]> { 768 // Instruction operands. 769 bits<5> Sn; 770 bits<4> Rt; 771 772 // Encode instruction operands. 773 let Inst{19-16} = Sn{4-1}; 774 let Inst{7} = Sn{0}; 775 let Inst{15-12} = Rt; 776 777 let Inst{6-5} = 0b00; 778 let Inst{3-0} = 0b0000; 779 780 // Some single precision VFP instructions may be executed on both NEON and VFP 781 // pipelines. 782 let D = VFPNeonDomain; 783} 784 785let neverHasSideEffects = 1 in { 786def VMOVRRD : AVConv3I<0b11000101, 0b1011, 787 (outs GPR:$Rt, GPR:$Rt2), (ins DPR:$Dm), 788 IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $Dm", 789 [/* FIXME: Can't write pattern for multiple result instr*/]> { 790 // Instruction operands. 791 bits<5> Dm; 792 bits<4> Rt; 793 bits<4> Rt2; 794 795 // Encode instruction operands. 796 let Inst{3-0} = Dm{3-0}; 797 let Inst{5} = Dm{4}; 798 let Inst{15-12} = Rt; 799 let Inst{19-16} = Rt2; 800 801 let Inst{7-6} = 0b00; 802 803 // Some single precision VFP instructions may be executed on both NEON and VFP 804 // pipelines. 805 let D = VFPNeonDomain; 806} 807 808def VMOVRRS : AVConv3I<0b11000101, 0b1010, 809 (outs GPR:$Rt, GPR:$Rt2), (ins SPR:$src1, SPR:$src2), 810 IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $src1, $src2", 811 [/* For disassembly only; pattern left blank */]> { 812 bits<5> src1; 813 bits<4> Rt; 814 bits<4> Rt2; 815 816 // Encode instruction operands. 817 let Inst{3-0} = src1{4-1}; 818 let Inst{5} = src1{0}; 819 let Inst{15-12} = Rt; 820 let Inst{19-16} = Rt2; 821 822 let Inst{7-6} = 0b00; 823 824 // Some single precision VFP instructions may be executed on both NEON and VFP 825 // pipelines. 826 let D = VFPNeonDomain; 827 let DecoderMethod = "DecodeVMOVRRS"; 828} 829} // neverHasSideEffects 830 831// FMDHR: GPR -> SPR 832// FMDLR: GPR -> SPR 833 834def VMOVDRR : AVConv5I<0b11000100, 0b1011, 835 (outs DPR:$Dm), (ins GPR:$Rt, GPR:$Rt2), 836 IIC_fpMOVID, "vmov", "\t$Dm, $Rt, $Rt2", 837 [(set DPR:$Dm, (arm_fmdrr GPR:$Rt, GPR:$Rt2))]> { 838 // Instruction operands. 839 bits<5> Dm; 840 bits<4> Rt; 841 bits<4> Rt2; 842 843 // Encode instruction operands. 844 let Inst{3-0} = Dm{3-0}; 845 let Inst{5} = Dm{4}; 846 let Inst{15-12} = Rt; 847 let Inst{19-16} = Rt2; 848 849 let Inst{7-6} = 0b00; 850 851 // Some single precision VFP instructions may be executed on both NEON and VFP 852 // pipelines. 853 let D = VFPNeonDomain; 854} 855 856let neverHasSideEffects = 1 in 857def VMOVSRR : AVConv5I<0b11000100, 0b1010, 858 (outs SPR:$dst1, SPR:$dst2), (ins GPR:$src1, GPR:$src2), 859 IIC_fpMOVID, "vmov", "\t$dst1, $dst2, $src1, $src2", 860 [/* For disassembly only; pattern left blank */]> { 861 // Instruction operands. 862 bits<5> dst1; 863 bits<4> src1; 864 bits<4> src2; 865 866 // Encode instruction operands. 867 let Inst{3-0} = dst1{4-1}; 868 let Inst{5} = dst1{0}; 869 let Inst{15-12} = src1; 870 let Inst{19-16} = src2; 871 872 let Inst{7-6} = 0b00; 873 874 // Some single precision VFP instructions may be executed on both NEON and VFP 875 // pipelines. 876 let D = VFPNeonDomain; 877 878 let DecoderMethod = "DecodeVMOVSRR"; 879} 880 881// FMRDH: SPR -> GPR 882// FMRDL: SPR -> GPR 883// FMRRS: SPR -> GPR 884// FMRX: SPR system reg -> GPR 885// FMSRR: GPR -> SPR 886// FMXR: GPR -> VFP system reg 887 888 889// Int -> FP: 890 891class AVConv1IDs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 892 bits<4> opcod4, dag oops, dag iops, 893 InstrItinClass itin, string opc, string asm, 894 list<dag> pattern> 895 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 896 pattern> { 897 // Instruction operands. 898 bits<5> Dd; 899 bits<5> Sm; 900 901 // Encode instruction operands. 902 let Inst{3-0} = Sm{4-1}; 903 let Inst{5} = Sm{0}; 904 let Inst{15-12} = Dd{3-0}; 905 let Inst{22} = Dd{4}; 906 907 let Predicates = [HasVFP2, HasDPVFP]; 908} 909 910class AVConv1InSs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 911 bits<4> opcod4, dag oops, dag iops,InstrItinClass itin, 912 string opc, string asm, list<dag> pattern> 913 : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 914 pattern> { 915 // Instruction operands. 916 bits<5> Sd; 917 bits<5> Sm; 918 919 // Encode instruction operands. 920 let Inst{3-0} = Sm{4-1}; 921 let Inst{5} = Sm{0}; 922 let Inst{15-12} = Sd{4-1}; 923 let Inst{22} = Sd{0}; 924} 925 926def VSITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011, 927 (outs DPR:$Dd), (ins SPR:$Sm), 928 IIC_fpCVTID, "vcvt", ".f64.s32\t$Dd, $Sm", 929 [(set DPR:$Dd, (f64 (arm_sitof SPR:$Sm)))]> { 930 let Inst{7} = 1; // s32 931} 932 933def VSITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010, 934 (outs SPR:$Sd),(ins SPR:$Sm), 935 IIC_fpCVTIS, "vcvt", ".f32.s32\t$Sd, $Sm", 936 [(set SPR:$Sd, (arm_sitof SPR:$Sm))]> { 937 let Inst{7} = 1; // s32 938 939 // Some single precision VFP instructions may be executed on both NEON and 940 // VFP pipelines on A8. 941 let D = VFPNeonA8Domain; 942} 943 944def VUITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011, 945 (outs DPR:$Dd), (ins SPR:$Sm), 946 IIC_fpCVTID, "vcvt", ".f64.u32\t$Dd, $Sm", 947 [(set DPR:$Dd, (f64 (arm_uitof SPR:$Sm)))]> { 948 let Inst{7} = 0; // u32 949} 950 951def VUITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010, 952 (outs SPR:$Sd), (ins SPR:$Sm), 953 IIC_fpCVTIS, "vcvt", ".f32.u32\t$Sd, $Sm", 954 [(set SPR:$Sd, (arm_uitof SPR:$Sm))]> { 955 let Inst{7} = 0; // u32 956 957 // Some single precision VFP instructions may be executed on both NEON and 958 // VFP pipelines on A8. 959 let D = VFPNeonA8Domain; 960} 961 962// FP -> Int: 963 964class AVConv1IsD_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 965 bits<4> opcod4, dag oops, dag iops, 966 InstrItinClass itin, string opc, string asm, 967 list<dag> pattern> 968 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 969 pattern> { 970 // Instruction operands. 971 bits<5> Sd; 972 bits<5> Dm; 973 974 // Encode instruction operands. 975 let Inst{3-0} = Dm{3-0}; 976 let Inst{5} = Dm{4}; 977 let Inst{15-12} = Sd{4-1}; 978 let Inst{22} = Sd{0}; 979 980 let Predicates = [HasVFP2, HasDPVFP]; 981} 982 983class AVConv1InsS_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 984 bits<4> opcod4, dag oops, dag iops, 985 InstrItinClass itin, string opc, string asm, 986 list<dag> pattern> 987 : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 988 pattern> { 989 // Instruction operands. 990 bits<5> Sd; 991 bits<5> Sm; 992 993 // Encode instruction operands. 994 let Inst{3-0} = Sm{4-1}; 995 let Inst{5} = Sm{0}; 996 let Inst{15-12} = Sd{4-1}; 997 let Inst{22} = Sd{0}; 998} 999 1000// Always set Z bit in the instruction, i.e. "round towards zero" variants. 1001def VTOSIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011, 1002 (outs SPR:$Sd), (ins DPR:$Dm), 1003 IIC_fpCVTDI, "vcvt", ".s32.f64\t$Sd, $Dm", 1004 [(set SPR:$Sd, (arm_ftosi (f64 DPR:$Dm)))]> { 1005 let Inst{7} = 1; // Z bit 1006} 1007 1008def VTOSIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010, 1009 (outs SPR:$Sd), (ins SPR:$Sm), 1010 IIC_fpCVTSI, "vcvt", ".s32.f32\t$Sd, $Sm", 1011 [(set SPR:$Sd, (arm_ftosi SPR:$Sm))]> { 1012 let Inst{7} = 1; // Z bit 1013 1014 // Some single precision VFP instructions may be executed on both NEON and 1015 // VFP pipelines on A8. 1016 let D = VFPNeonA8Domain; 1017} 1018 1019def VTOUIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011, 1020 (outs SPR:$Sd), (ins DPR:$Dm), 1021 IIC_fpCVTDI, "vcvt", ".u32.f64\t$Sd, $Dm", 1022 [(set SPR:$Sd, (arm_ftoui (f64 DPR:$Dm)))]> { 1023 let Inst{7} = 1; // Z bit 1024} 1025 1026def VTOUIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010, 1027 (outs SPR:$Sd), (ins SPR:$Sm), 1028 IIC_fpCVTSI, "vcvt", ".u32.f32\t$Sd, $Sm", 1029 [(set SPR:$Sd, (arm_ftoui SPR:$Sm))]> { 1030 let Inst{7} = 1; // Z bit 1031 1032 // Some single precision VFP instructions may be executed on both NEON and 1033 // VFP pipelines on A8. 1034 let D = VFPNeonA8Domain; 1035} 1036 1037// And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR. 1038let Uses = [FPSCR] in { 1039// FIXME: Verify encoding after integrated assembler is working. 1040def VTOSIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011, 1041 (outs SPR:$Sd), (ins DPR:$Dm), 1042 IIC_fpCVTDI, "vcvtr", ".s32.f64\t$Sd, $Dm", 1043 [(set SPR:$Sd, (int_arm_vcvtr (f64 DPR:$Dm)))]>{ 1044 let Inst{7} = 0; // Z bit 1045} 1046 1047def VTOSIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010, 1048 (outs SPR:$Sd), (ins SPR:$Sm), 1049 IIC_fpCVTSI, "vcvtr", ".s32.f32\t$Sd, $Sm", 1050 [(set SPR:$Sd, (int_arm_vcvtr SPR:$Sm))]> { 1051 let Inst{7} = 0; // Z bit 1052} 1053 1054def VTOUIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011, 1055 (outs SPR:$Sd), (ins DPR:$Dm), 1056 IIC_fpCVTDI, "vcvtr", ".u32.f64\t$Sd, $Dm", 1057 [(set SPR:$Sd, (int_arm_vcvtru(f64 DPR:$Dm)))]>{ 1058 let Inst{7} = 0; // Z bit 1059} 1060 1061def VTOUIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010, 1062 (outs SPR:$Sd), (ins SPR:$Sm), 1063 IIC_fpCVTSI, "vcvtr", ".u32.f32\t$Sd, $Sm", 1064 [(set SPR:$Sd, (int_arm_vcvtru SPR:$Sm))]> { 1065 let Inst{7} = 0; // Z bit 1066} 1067} 1068 1069// Convert between floating-point and fixed-point 1070// Data type for fixed-point naming convention: 1071// S16 (U=0, sx=0) -> SH 1072// U16 (U=1, sx=0) -> UH 1073// S32 (U=0, sx=1) -> SL 1074// U32 (U=1, sx=1) -> UL 1075 1076let Constraints = "$a = $dst" in { 1077 1078// FP to Fixed-Point: 1079 1080// Single Precision register 1081class AVConv1XInsS_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, 1082 bit op5, dag oops, dag iops, InstrItinClass itin, 1083 string opc, string asm, list<dag> pattern> 1084 : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern>, 1085 Sched<[WriteCvtFP]> { 1086 bits<5> dst; 1087 // if dp_operation then UInt(D:Vd) else UInt(Vd:D); 1088 let Inst{22} = dst{0}; 1089 let Inst{15-12} = dst{4-1}; 1090} 1091 1092// Double Precision register 1093class AVConv1XInsD_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, 1094 bit op5, dag oops, dag iops, InstrItinClass itin, 1095 string opc, string asm, list<dag> pattern> 1096 : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern>, 1097 Sched<[WriteCvtFP]> { 1098 bits<5> dst; 1099 // if dp_operation then UInt(D:Vd) else UInt(Vd:D); 1100 let Inst{22} = dst{4}; 1101 let Inst{15-12} = dst{3-0}; 1102 1103 let Predicates = [HasVFP2, HasDPVFP]; 1104} 1105 1106def VTOSHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 0, 1107 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1108 IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits", []> { 1109 // Some single precision VFP instructions may be executed on both NEON and 1110 // VFP pipelines on A8. 1111 let D = VFPNeonA8Domain; 1112} 1113 1114def VTOUHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 0, 1115 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1116 IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits", []> { 1117 // Some single precision VFP instructions may be executed on both NEON and 1118 // VFP pipelines on A8. 1119 let D = VFPNeonA8Domain; 1120} 1121 1122def VTOSLS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 1, 1123 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1124 IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits", []> { 1125 // Some single precision VFP instructions may be executed on both NEON and 1126 // VFP pipelines on A8. 1127 let D = VFPNeonA8Domain; 1128} 1129 1130def VTOULS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 1, 1131 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1132 IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits", []> { 1133 // Some single precision VFP instructions may be executed on both NEON and 1134 // VFP pipelines on A8. 1135 let D = VFPNeonA8Domain; 1136} 1137 1138def VTOSHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 0, 1139 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1140 IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits", []>; 1141 1142def VTOUHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 0, 1143 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1144 IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits", []>; 1145 1146def VTOSLD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 1, 1147 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1148 IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits", []>; 1149 1150def VTOULD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 1, 1151 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1152 IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits", []>; 1153 1154// Fixed-Point to FP: 1155 1156def VSHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 0, 1157 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1158 IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits", []> { 1159 // Some single precision VFP instructions may be executed on both NEON and 1160 // VFP pipelines on A8. 1161 let D = VFPNeonA8Domain; 1162} 1163 1164def VUHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 0, 1165 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1166 IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits", []> { 1167 // Some single precision VFP instructions may be executed on both NEON and 1168 // VFP pipelines on A8. 1169 let D = VFPNeonA8Domain; 1170} 1171 1172def VSLTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 1, 1173 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1174 IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits", []> { 1175 // Some single precision VFP instructions may be executed on both NEON and 1176 // VFP pipelines on A8. 1177 let D = VFPNeonA8Domain; 1178} 1179 1180def VULTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 1, 1181 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1182 IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits", []> { 1183 // Some single precision VFP instructions may be executed on both NEON and 1184 // VFP pipelines on A8. 1185 let D = VFPNeonA8Domain; 1186} 1187 1188def VSHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 0, 1189 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1190 IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits", []>; 1191 1192def VUHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 0, 1193 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1194 IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits", []>; 1195 1196def VSLTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 1, 1197 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1198 IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits", []>; 1199 1200def VULTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 1, 1201 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1202 IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits", []>; 1203 1204} // End of 'let Constraints = "$a = $dst" in' 1205 1206//===----------------------------------------------------------------------===// 1207// FP Multiply-Accumulate Operations. 1208// 1209 1210def VMLAD : ADbI<0b11100, 0b00, 0, 0, 1211 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1212 IIC_fpMAC64, "vmla", ".f64\t$Dd, $Dn, $Dm", 1213 [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm), 1214 (f64 DPR:$Ddin)))]>, 1215 RegConstraint<"$Ddin = $Dd">, 1216 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; 1217 1218def VMLAS : ASbIn<0b11100, 0b00, 0, 0, 1219 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1220 IIC_fpMAC32, "vmla", ".f32\t$Sd, $Sn, $Sm", 1221 [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm), 1222 SPR:$Sdin))]>, 1223 RegConstraint<"$Sdin = $Sd">, 1224 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]> { 1225 // Some single precision VFP instructions may be executed on both NEON and 1226 // VFP pipelines on A8. 1227 let D = VFPNeonA8Domain; 1228} 1229 1230def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 1231 (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>, 1232 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; 1233def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 1234 (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>, 1235 Requires<[HasVFP2,DontUseNEONForFP, UseFPVMLx,DontUseFusedMAC]>; 1236 1237def VMLSD : ADbI<0b11100, 0b00, 1, 0, 1238 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1239 IIC_fpMAC64, "vmls", ".f64\t$Dd, $Dn, $Dm", 1240 [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 1241 (f64 DPR:$Ddin)))]>, 1242 RegConstraint<"$Ddin = $Dd">, 1243 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; 1244 1245def VMLSS : ASbIn<0b11100, 0b00, 1, 0, 1246 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1247 IIC_fpMAC32, "vmls", ".f32\t$Sd, $Sn, $Sm", 1248 [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 1249 SPR:$Sdin))]>, 1250 RegConstraint<"$Sdin = $Sd">, 1251 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]> { 1252 // Some single precision VFP instructions may be executed on both NEON and 1253 // VFP pipelines on A8. 1254 let D = VFPNeonA8Domain; 1255} 1256 1257def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 1258 (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, 1259 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; 1260def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 1261 (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, 1262 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>; 1263 1264def VNMLAD : ADbI<0b11100, 0b01, 1, 0, 1265 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1266 IIC_fpMAC64, "vnmla", ".f64\t$Dd, $Dn, $Dm", 1267 [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 1268 (f64 DPR:$Ddin)))]>, 1269 RegConstraint<"$Ddin = $Dd">, 1270 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; 1271 1272def VNMLAS : ASbI<0b11100, 0b01, 1, 0, 1273 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1274 IIC_fpMAC32, "vnmla", ".f32\t$Sd, $Sn, $Sm", 1275 [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 1276 SPR:$Sdin))]>, 1277 RegConstraint<"$Sdin = $Sd">, 1278 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]> { 1279 // Some single precision VFP instructions may be executed on both NEON and 1280 // VFP pipelines on A8. 1281 let D = VFPNeonA8Domain; 1282} 1283 1284def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin), 1285 (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>, 1286 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; 1287def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), 1288 (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>, 1289 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>; 1290 1291def VNMLSD : ADbI<0b11100, 0b01, 0, 0, 1292 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1293 IIC_fpMAC64, "vnmls", ".f64\t$Dd, $Dn, $Dm", 1294 [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm), 1295 (f64 DPR:$Ddin)))]>, 1296 RegConstraint<"$Ddin = $Dd">, 1297 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; 1298 1299def VNMLSS : ASbI<0b11100, 0b01, 0, 0, 1300 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1301 IIC_fpMAC32, "vnmls", ".f32\t$Sd, $Sn, $Sm", 1302 [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>, 1303 RegConstraint<"$Sdin = $Sd">, 1304 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]> { 1305 // Some single precision VFP instructions may be executed on both NEON and 1306 // VFP pipelines on A8. 1307 let D = VFPNeonA8Domain; 1308} 1309 1310def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin), 1311 (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>, 1312 Requires<[HasVFP2,HasDPVFP,UseFPVMLx,DontUseFusedMAC]>; 1313def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), 1314 (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>, 1315 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx,DontUseFusedMAC]>; 1316 1317//===----------------------------------------------------------------------===// 1318// Fused FP Multiply-Accumulate Operations. 1319// 1320def VFMAD : ADbI<0b11101, 0b10, 0, 0, 1321 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1322 IIC_fpFMAC64, "vfma", ".f64\t$Dd, $Dn, $Dm", 1323 [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm), 1324 (f64 DPR:$Ddin)))]>, 1325 RegConstraint<"$Ddin = $Dd">, 1326 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 1327 1328def VFMAS : ASbIn<0b11101, 0b10, 0, 0, 1329 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1330 IIC_fpFMAC32, "vfma", ".f32\t$Sd, $Sn, $Sm", 1331 [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm), 1332 SPR:$Sdin))]>, 1333 RegConstraint<"$Sdin = $Sd">, 1334 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]> { 1335 // Some single precision VFP instructions may be executed on both NEON and 1336 // VFP pipelines. 1337} 1338 1339def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 1340 (VFMAD DPR:$dstin, DPR:$a, DPR:$b)>, 1341 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 1342def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 1343 (VFMAS SPR:$dstin, SPR:$a, SPR:$b)>, 1344 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 1345 1346// Match @llvm.fma.* intrinsics 1347// (fma x, y, z) -> (vfms z, x, y) 1348def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, DPR:$Ddin)), 1349 (VFMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 1350 Requires<[HasVFP4,HasDPVFP]>; 1351def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, SPR:$Sdin)), 1352 (VFMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 1353 Requires<[HasVFP4]>; 1354 1355def VFMSD : ADbI<0b11101, 0b10, 1, 0, 1356 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1357 IIC_fpFMAC64, "vfms", ".f64\t$Dd, $Dn, $Dm", 1358 [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 1359 (f64 DPR:$Ddin)))]>, 1360 RegConstraint<"$Ddin = $Dd">, 1361 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 1362 1363def VFMSS : ASbIn<0b11101, 0b10, 1, 0, 1364 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1365 IIC_fpFMAC32, "vfms", ".f32\t$Sd, $Sn, $Sm", 1366 [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 1367 SPR:$Sdin))]>, 1368 RegConstraint<"$Sdin = $Sd">, 1369 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]> { 1370 // Some single precision VFP instructions may be executed on both NEON and 1371 // VFP pipelines. 1372} 1373 1374def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 1375 (VFMSD DPR:$dstin, DPR:$a, DPR:$b)>, 1376 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 1377def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 1378 (VFMSS SPR:$dstin, SPR:$a, SPR:$b)>, 1379 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 1380 1381// Match @llvm.fma.* intrinsics 1382// (fma (fneg x), y, z) -> (vfms z, x, y) 1383def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin)), 1384 (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 1385 Requires<[HasVFP4,HasDPVFP]>; 1386def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin)), 1387 (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 1388 Requires<[HasVFP4]>; 1389// (fma x, (fneg y), z) -> (vfms z, x, y) 1390def : Pat<(f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin)), 1391 (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 1392 Requires<[HasVFP4,HasDPVFP]>; 1393def : Pat<(f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin)), 1394 (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 1395 Requires<[HasVFP4]>; 1396 1397def VFNMAD : ADbI<0b11101, 0b01, 1, 0, 1398 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1399 IIC_fpFMAC64, "vfnma", ".f64\t$Dd, $Dn, $Dm", 1400 [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 1401 (f64 DPR:$Ddin)))]>, 1402 RegConstraint<"$Ddin = $Dd">, 1403 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 1404 1405def VFNMAS : ASbI<0b11101, 0b01, 1, 0, 1406 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1407 IIC_fpFMAC32, "vfnma", ".f32\t$Sd, $Sn, $Sm", 1408 [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 1409 SPR:$Sdin))]>, 1410 RegConstraint<"$Sdin = $Sd">, 1411 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]> { 1412 // Some single precision VFP instructions may be executed on both NEON and 1413 // VFP pipelines. 1414} 1415 1416def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin), 1417 (VFNMAD DPR:$dstin, DPR:$a, DPR:$b)>, 1418 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 1419def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), 1420 (VFNMAS SPR:$dstin, SPR:$a, SPR:$b)>, 1421 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 1422 1423// Match @llvm.fma.* intrinsics 1424// (fneg (fma x, y, z)) -> (vfnma z, x, y) 1425def : Pat<(fneg (fma (f64 DPR:$Dn), (f64 DPR:$Dm), (f64 DPR:$Ddin))), 1426 (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 1427 Requires<[HasVFP4,HasDPVFP]>; 1428def : Pat<(fneg (fma (f32 SPR:$Sn), (f32 SPR:$Sm), (f32 SPR:$Sdin))), 1429 (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 1430 Requires<[HasVFP4]>; 1431// (fma (fneg x), y, (fneg z)) -> (vfnma z, x, y) 1432def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, (fneg DPR:$Ddin))), 1433 (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 1434 Requires<[HasVFP4,HasDPVFP]>; 1435def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, (fneg SPR:$Sdin))), 1436 (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 1437 Requires<[HasVFP4]>; 1438 1439def VFNMSD : ADbI<0b11101, 0b01, 0, 0, 1440 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1441 IIC_fpFMAC64, "vfnms", ".f64\t$Dd, $Dn, $Dm", 1442 [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm), 1443 (f64 DPR:$Ddin)))]>, 1444 RegConstraint<"$Ddin = $Dd">, 1445 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 1446 1447def VFNMSS : ASbI<0b11101, 0b01, 0, 0, 1448 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1449 IIC_fpFMAC32, "vfnms", ".f32\t$Sd, $Sn, $Sm", 1450 [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>, 1451 RegConstraint<"$Sdin = $Sd">, 1452 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]> { 1453 // Some single precision VFP instructions may be executed on both NEON and 1454 // VFP pipelines. 1455} 1456 1457def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin), 1458 (VFNMSD DPR:$dstin, DPR:$a, DPR:$b)>, 1459 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 1460def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), 1461 (VFNMSS SPR:$dstin, SPR:$a, SPR:$b)>, 1462 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 1463 1464// Match @llvm.fma.* intrinsics 1465 1466// (fma x, y, (fneg z)) -> (vfnms z, x, y)) 1467def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, (fneg DPR:$Ddin))), 1468 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 1469 Requires<[HasVFP4,HasDPVFP]>; 1470def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, (fneg SPR:$Sdin))), 1471 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 1472 Requires<[HasVFP4]>; 1473// (fneg (fma (fneg x), y, z)) -> (vfnms z, x, y) 1474def : Pat<(fneg (f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin))), 1475 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 1476 Requires<[HasVFP4,HasDPVFP]>; 1477def : Pat<(fneg (f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin))), 1478 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 1479 Requires<[HasVFP4]>; 1480// (fneg (fma x, (fneg y), z) -> (vfnms z, x, y) 1481def : Pat<(fneg (f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin))), 1482 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 1483 Requires<[HasVFP4,HasDPVFP]>; 1484def : Pat<(fneg (f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin))), 1485 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 1486 Requires<[HasVFP4]>; 1487 1488//===----------------------------------------------------------------------===// 1489// FP Conditional moves. 1490// 1491 1492let neverHasSideEffects = 1 in { 1493def VMOVDcc : PseudoInst<(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm, cmovpred:$p), 1494 IIC_fpUNA64, 1495 [(set (f64 DPR:$Dd), 1496 (ARMcmov DPR:$Dn, DPR:$Dm, cmovpred:$p))]>, 1497 RegConstraint<"$Dn = $Dd">, Requires<[HasVFP2,HasDPVFP]>; 1498 1499def VMOVScc : PseudoInst<(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm, cmovpred:$p), 1500 IIC_fpUNA32, 1501 [(set (f32 SPR:$Sd), 1502 (ARMcmov SPR:$Sn, SPR:$Sm, cmovpred:$p))]>, 1503 RegConstraint<"$Sn = $Sd">, Requires<[HasVFP2]>; 1504} // neverHasSideEffects 1505 1506//===----------------------------------------------------------------------===// 1507// Move from VFP System Register to ARM core register. 1508// 1509 1510class MovFromVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm, 1511 list<dag> pattern>: 1512 VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> { 1513 1514 // Instruction operand. 1515 bits<4> Rt; 1516 1517 let Inst{27-20} = 0b11101111; 1518 let Inst{19-16} = opc19_16; 1519 let Inst{15-12} = Rt; 1520 let Inst{11-8} = 0b1010; 1521 let Inst{7} = 0; 1522 let Inst{6-5} = 0b00; 1523 let Inst{4} = 1; 1524 let Inst{3-0} = 0b0000; 1525} 1526 1527// APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags 1528// to APSR. 1529let Defs = [CPSR], Uses = [FPSCR_NZCV], Rt = 0b1111 /* apsr_nzcv */ in 1530def FMSTAT : MovFromVFP<0b0001 /* fpscr */, (outs), (ins), 1531 "vmrs", "\tAPSR_nzcv, fpscr", [(arm_fmstat)]>; 1532 1533// Application level FPSCR -> GPR 1534let hasSideEffects = 1, Uses = [FPSCR] in 1535def VMRS : MovFromVFP<0b0001 /* fpscr */, (outs GPR:$Rt), (ins), 1536 "vmrs", "\t$Rt, fpscr", 1537 [(set GPR:$Rt, (int_arm_get_fpscr))]>; 1538 1539// System level FPEXC, FPSID -> GPR 1540let Uses = [FPSCR] in { 1541 def VMRS_FPEXC : MovFromVFP<0b1000 /* fpexc */, (outs GPR:$Rt), (ins), 1542 "vmrs", "\t$Rt, fpexc", []>; 1543 def VMRS_FPSID : MovFromVFP<0b0000 /* fpsid */, (outs GPR:$Rt), (ins), 1544 "vmrs", "\t$Rt, fpsid", []>; 1545 def VMRS_MVFR0 : MovFromVFP<0b0111 /* mvfr0 */, (outs GPR:$Rt), (ins), 1546 "vmrs", "\t$Rt, mvfr0", []>; 1547 def VMRS_MVFR1 : MovFromVFP<0b0110 /* mvfr1 */, (outs GPR:$Rt), (ins), 1548 "vmrs", "\t$Rt, mvfr1", []>; 1549 def VMRS_MVFR2 : MovFromVFP<0b0101 /* mvfr2 */, (outs GPR:$Rt), (ins), 1550 "vmrs", "\t$Rt, mvfr2", []>, Requires<[HasFPARMv8]>; 1551 def VMRS_FPINST : MovFromVFP<0b1001 /* fpinst */, (outs GPR:$Rt), (ins), 1552 "vmrs", "\t$Rt, fpinst", []>; 1553 def VMRS_FPINST2 : MovFromVFP<0b1010 /* fpinst2 */, (outs GPR:$Rt), (ins), 1554 "vmrs", "\t$Rt, fpinst2", []>; 1555} 1556 1557//===----------------------------------------------------------------------===// 1558// Move from ARM core register to VFP System Register. 1559// 1560 1561class MovToVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm, 1562 list<dag> pattern>: 1563 VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> { 1564 1565 // Instruction operand. 1566 bits<4> src; 1567 1568 // Encode instruction operand. 1569 let Inst{15-12} = src; 1570 1571 let Inst{27-20} = 0b11101110; 1572 let Inst{19-16} = opc19_16; 1573 let Inst{11-8} = 0b1010; 1574 let Inst{7} = 0; 1575 let Inst{4} = 1; 1576} 1577 1578let Defs = [FPSCR] in { 1579 // Application level GPR -> FPSCR 1580 def VMSR : MovToVFP<0b0001 /* fpscr */, (outs), (ins GPR:$src), 1581 "vmsr", "\tfpscr, $src", [(int_arm_set_fpscr GPR:$src)]>; 1582 // System level GPR -> FPEXC 1583 def VMSR_FPEXC : MovToVFP<0b1000 /* fpexc */, (outs), (ins GPR:$src), 1584 "vmsr", "\tfpexc, $src", []>; 1585 // System level GPR -> FPSID 1586 def VMSR_FPSID : MovToVFP<0b0000 /* fpsid */, (outs), (ins GPR:$src), 1587 "vmsr", "\tfpsid, $src", []>; 1588 1589 def VMSR_FPINST : MovToVFP<0b1001 /* fpinst */, (outs), (ins GPR:$src), 1590 "vmsr", "\tfpinst, $src", []>; 1591 def VMSR_FPINST2 : MovToVFP<0b1010 /* fpinst2 */, (outs), (ins GPR:$src), 1592 "vmsr", "\tfpinst2, $src", []>; 1593} 1594 1595//===----------------------------------------------------------------------===// 1596// Misc. 1597// 1598 1599// Materialize FP immediates. VFP3 only. 1600let isReMaterializable = 1 in { 1601def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm), 1602 VFPMiscFrm, IIC_fpUNA64, 1603 "vmov", ".f64\t$Dd, $imm", 1604 [(set DPR:$Dd, vfp_f64imm:$imm)]>, 1605 Requires<[HasVFP3,HasDPVFP]> { 1606 bits<5> Dd; 1607 bits<8> imm; 1608 1609 let Inst{27-23} = 0b11101; 1610 let Inst{22} = Dd{4}; 1611 let Inst{21-20} = 0b11; 1612 let Inst{19-16} = imm{7-4}; 1613 let Inst{15-12} = Dd{3-0}; 1614 let Inst{11-9} = 0b101; 1615 let Inst{8} = 1; // Double precision. 1616 let Inst{7-4} = 0b0000; 1617 let Inst{3-0} = imm{3-0}; 1618} 1619 1620def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm), 1621 VFPMiscFrm, IIC_fpUNA32, 1622 "vmov", ".f32\t$Sd, $imm", 1623 [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> { 1624 bits<5> Sd; 1625 bits<8> imm; 1626 1627 let Inst{27-23} = 0b11101; 1628 let Inst{22} = Sd{0}; 1629 let Inst{21-20} = 0b11; 1630 let Inst{19-16} = imm{7-4}; 1631 let Inst{15-12} = Sd{4-1}; 1632 let Inst{11-9} = 0b101; 1633 let Inst{8} = 0; // Single precision. 1634 let Inst{7-4} = 0b0000; 1635 let Inst{3-0} = imm{3-0}; 1636} 1637} 1638 1639//===----------------------------------------------------------------------===// 1640// Assembler aliases. 1641// 1642// A few mnemnoic aliases for pre-unifixed syntax. We don't guarantee to 1643// support them all, but supporting at least some of the basics is 1644// good to be friendly. 1645def : VFP2MnemonicAlias<"flds", "vldr">; 1646def : VFP2MnemonicAlias<"fldd", "vldr">; 1647def : VFP2MnemonicAlias<"fmrs", "vmov">; 1648def : VFP2MnemonicAlias<"fmsr", "vmov">; 1649def : VFP2MnemonicAlias<"fsqrts", "vsqrt">; 1650def : VFP2MnemonicAlias<"fsqrtd", "vsqrt">; 1651def : VFP2MnemonicAlias<"fadds", "vadd.f32">; 1652def : VFP2MnemonicAlias<"faddd", "vadd.f64">; 1653def : VFP2MnemonicAlias<"fmrdd", "vmov">; 1654def : VFP2MnemonicAlias<"fmrds", "vmov">; 1655def : VFP2MnemonicAlias<"fmrrd", "vmov">; 1656def : VFP2MnemonicAlias<"fmdrr", "vmov">; 1657def : VFP2MnemonicAlias<"fmuls", "vmul.f32">; 1658def : VFP2MnemonicAlias<"fmuld", "vmul.f64">; 1659def : VFP2MnemonicAlias<"fnegs", "vneg.f32">; 1660def : VFP2MnemonicAlias<"fnegd", "vneg.f64">; 1661def : VFP2MnemonicAlias<"ftosizd", "vcvt.s32.f64">; 1662def : VFP2MnemonicAlias<"ftosid", "vcvtr.s32.f64">; 1663def : VFP2MnemonicAlias<"ftosizs", "vcvt.s32.f32">; 1664def : VFP2MnemonicAlias<"ftosis", "vcvtr.s32.f32">; 1665def : VFP2MnemonicAlias<"ftouizd", "vcvt.u32.f64">; 1666def : VFP2MnemonicAlias<"ftouid", "vcvtr.u32.f64">; 1667def : VFP2MnemonicAlias<"ftouizs", "vcvt.u32.f32">; 1668def : VFP2MnemonicAlias<"ftouis", "vcvtr.u32.f32">; 1669def : VFP2MnemonicAlias<"fsitod", "vcvt.f64.s32">; 1670def : VFP2MnemonicAlias<"fsitos", "vcvt.f32.s32">; 1671def : VFP2MnemonicAlias<"fuitod", "vcvt.f64.u32">; 1672def : VFP2MnemonicAlias<"fuitos", "vcvt.f32.u32">; 1673def : VFP2MnemonicAlias<"fsts", "vstr">; 1674def : VFP2MnemonicAlias<"fstd", "vstr">; 1675def : VFP2MnemonicAlias<"fmacd", "vmla.f64">; 1676def : VFP2MnemonicAlias<"fmacs", "vmla.f32">; 1677def : VFP2MnemonicAlias<"fcpys", "vmov.f32">; 1678def : VFP2MnemonicAlias<"fcpyd", "vmov.f64">; 1679def : VFP2MnemonicAlias<"fcmps", "vcmp.f32">; 1680def : VFP2MnemonicAlias<"fcmpd", "vcmp.f64">; 1681def : VFP2MnemonicAlias<"fdivs", "vdiv.f32">; 1682def : VFP2MnemonicAlias<"fdivd", "vdiv.f64">; 1683def : VFP2MnemonicAlias<"fmrx", "vmrs">; 1684def : VFP2MnemonicAlias<"fmxr", "vmsr">; 1685 1686// Be friendly and accept the old form of zero-compare 1687def : VFP2DPInstAlias<"fcmpzd${p} $val", (VCMPZD DPR:$val, pred:$p)>; 1688def : VFP2InstAlias<"fcmpzs${p} $val", (VCMPZS SPR:$val, pred:$p)>; 1689 1690 1691def : VFP2InstAlias<"fmstat${p}", (FMSTAT pred:$p)>; 1692def : VFP2InstAlias<"fadds${p} $Sd, $Sn, $Sm", 1693 (VADDS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>; 1694def : VFP2DPInstAlias<"faddd${p} $Dd, $Dn, $Dm", 1695 (VADDD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; 1696def : VFP2InstAlias<"fsubs${p} $Sd, $Sn, $Sm", 1697 (VSUBS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>; 1698def : VFP2DPInstAlias<"fsubd${p} $Dd, $Dn, $Dm", 1699 (VSUBD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; 1700 1701// No need for the size suffix on VSQRT. It's implied by the register classes. 1702def : VFP2InstAlias<"vsqrt${p} $Sd, $Sm", (VSQRTS SPR:$Sd, SPR:$Sm, pred:$p)>; 1703def : VFP2DPInstAlias<"vsqrt${p} $Dd, $Dm", (VSQRTD DPR:$Dd, DPR:$Dm, pred:$p)>; 1704 1705// VLDR/VSTR accept an optional type suffix. 1706def : VFP2InstAlias<"vldr${p}.32 $Sd, $addr", 1707 (VLDRS SPR:$Sd, addrmode5:$addr, pred:$p)>; 1708def : VFP2InstAlias<"vstr${p}.32 $Sd, $addr", 1709 (VSTRS SPR:$Sd, addrmode5:$addr, pred:$p)>; 1710def : VFP2InstAlias<"vldr${p}.64 $Dd, $addr", 1711 (VLDRD DPR:$Dd, addrmode5:$addr, pred:$p)>; 1712def : VFP2InstAlias<"vstr${p}.64 $Dd, $addr", 1713 (VSTRD DPR:$Dd, addrmode5:$addr, pred:$p)>; 1714 1715// VMOV can accept optional 32-bit or less data type suffix suffix. 1716def : VFP2InstAlias<"vmov${p}.8 $Rt, $Sn", 1717 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 1718def : VFP2InstAlias<"vmov${p}.16 $Rt, $Sn", 1719 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 1720def : VFP2InstAlias<"vmov${p}.32 $Rt, $Sn", 1721 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 1722def : VFP2InstAlias<"vmov${p}.8 $Sn, $Rt", 1723 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 1724def : VFP2InstAlias<"vmov${p}.16 $Sn, $Rt", 1725 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 1726def : VFP2InstAlias<"vmov${p}.32 $Sn, $Rt", 1727 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 1728 1729def : VFP2InstAlias<"vmov${p}.f64 $Rt, $Rt2, $Dn", 1730 (VMOVRRD GPR:$Rt, GPR:$Rt2, DPR:$Dn, pred:$p)>; 1731def : VFP2InstAlias<"vmov${p}.f64 $Dn, $Rt, $Rt2", 1732 (VMOVDRR DPR:$Dn, GPR:$Rt, GPR:$Rt2, pred:$p)>; 1733 1734// VMOVS doesn't need the .f32 to disambiguate from the NEON encoding the way 1735// VMOVD does. 1736def : VFP2InstAlias<"vmov${p} $Sd, $Sm", 1737 (VMOVS SPR:$Sd, SPR:$Sm, pred:$p)>; 1738