1//===-- ARMInstrVFP.td - VFP support for ARM ---------------*- 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// This file describes the ARM VFP instruction set. 10// 11//===----------------------------------------------------------------------===// 12 13def SDT_CMPFP0 : SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisVT<1, i32>]>; 14def SDT_VMOVDRR : SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>, 15 SDTCisSameAs<1, 2>]>; 16def SDT_VMOVRRD : SDTypeProfile<2, 1, [SDTCisVT<0, i32>, SDTCisSameAs<0, 1>, 17 SDTCisVT<2, f64>]>; 18 19def SDT_VMOVSR : SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisVT<1, i32>]>; 20 21def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInGlue, SDNPOutGlue]>; 22def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMFCmp, [SDNPOutGlue]>; 23def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0", SDT_CMPFP0, [SDNPOutGlue]>; 24def arm_fmdrr : SDNode<"ARMISD::VMOVDRR", SDT_VMOVDRR>; 25def arm_fmrrd : SDNode<"ARMISD::VMOVRRD", SDT_VMOVRRD>; 26def arm_vmovsr : SDNode<"ARMISD::VMOVSR", SDT_VMOVSR>; 27 28def SDT_VMOVhr : SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, i32>] >; 29def SDT_VMOVrh : SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisFP<1>] >; 30def arm_vmovhr : SDNode<"ARMISD::VMOVhr", SDT_VMOVhr>; 31def arm_vmovrh : SDNode<"ARMISD::VMOVrh", SDT_VMOVrh>; 32 33//===----------------------------------------------------------------------===// 34// Operand Definitions. 35// 36 37// 8-bit floating-point immediate encodings. 38def FPImmOperand : AsmOperandClass { 39 let Name = "FPImm"; 40 let ParserMethod = "parseFPImm"; 41} 42 43def vfp_f16imm : Operand<f16>, 44 PatLeaf<(f16 fpimm), [{ 45 return ARM_AM::getFP16Imm(N->getValueAPF()) != -1; 46 }], SDNodeXForm<fpimm, [{ 47 APFloat InVal = N->getValueAPF(); 48 uint32_t enc = ARM_AM::getFP16Imm(InVal); 49 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 50 }]>> { 51 let PrintMethod = "printFPImmOperand"; 52 let ParserMatchClass = FPImmOperand; 53} 54 55def vfp_f32imm_xform : SDNodeXForm<fpimm, [{ 56 APFloat InVal = N->getValueAPF(); 57 uint32_t enc = ARM_AM::getFP32Imm(InVal); 58 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 59 }]>; 60 61def gi_vfp_f32imm : GICustomOperandRenderer<"renderVFPF32Imm">, 62 GISDNodeXFormEquiv<vfp_f32imm_xform>; 63 64def vfp_f32imm : Operand<f32>, 65 PatLeaf<(f32 fpimm), [{ 66 return ARM_AM::getFP32Imm(N->getValueAPF()) != -1; 67 }], vfp_f32imm_xform> { 68 let PrintMethod = "printFPImmOperand"; 69 let ParserMatchClass = FPImmOperand; 70 let GISelPredicateCode = [{ 71 const auto &MO = MI.getOperand(1); 72 if (!MO.isFPImm()) 73 return false; 74 return ARM_AM::getFP32Imm(MO.getFPImm()->getValueAPF()) != -1; 75 }]; 76} 77 78def vfp_f64imm_xform : SDNodeXForm<fpimm, [{ 79 APFloat InVal = N->getValueAPF(); 80 uint32_t enc = ARM_AM::getFP64Imm(InVal); 81 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32); 82 }]>; 83 84def gi_vfp_f64imm : GICustomOperandRenderer<"renderVFPF64Imm">, 85 GISDNodeXFormEquiv<vfp_f64imm_xform>; 86 87def vfp_f64imm : Operand<f64>, 88 PatLeaf<(f64 fpimm), [{ 89 return ARM_AM::getFP64Imm(N->getValueAPF()) != -1; 90 }], vfp_f64imm_xform> { 91 let PrintMethod = "printFPImmOperand"; 92 let ParserMatchClass = FPImmOperand; 93 let GISelPredicateCode = [{ 94 const auto &MO = MI.getOperand(1); 95 if (!MO.isFPImm()) 96 return false; 97 return ARM_AM::getFP64Imm(MO.getFPImm()->getValueAPF()) != -1; 98 }]; 99} 100 101def alignedload16 : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 102 return cast<LoadSDNode>(N)->getAlignment() >= 2; 103}]>; 104 105def alignedload32 : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 106 return cast<LoadSDNode>(N)->getAlignment() >= 4; 107}]>; 108 109def alignedstore16 : PatFrag<(ops node:$val, node:$ptr), 110 (store node:$val, node:$ptr), [{ 111 return cast<StoreSDNode>(N)->getAlignment() >= 2; 112}]>; 113 114def alignedstore32 : PatFrag<(ops node:$val, node:$ptr), 115 (store node:$val, node:$ptr), [{ 116 return cast<StoreSDNode>(N)->getAlignment() >= 4; 117}]>; 118 119// The VCVT to/from fixed-point instructions encode the 'fbits' operand 120// (the number of fixed bits) differently than it appears in the assembly 121// source. It's encoded as "Size - fbits" where Size is the size of the 122// fixed-point representation (32 or 16) and fbits is the value appearing 123// in the assembly source, an integer in [0,16] or (0,32], depending on size. 124def fbits32_asm_operand : AsmOperandClass { let Name = "FBits32"; } 125def fbits32 : Operand<i32> { 126 let PrintMethod = "printFBits32"; 127 let ParserMatchClass = fbits32_asm_operand; 128} 129 130def fbits16_asm_operand : AsmOperandClass { let Name = "FBits16"; } 131def fbits16 : Operand<i32> { 132 let PrintMethod = "printFBits16"; 133 let ParserMatchClass = fbits16_asm_operand; 134} 135 136//===----------------------------------------------------------------------===// 137// Load / store Instructions. 138// 139 140let canFoldAsLoad = 1, isReMaterializable = 1 in { 141 142def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr), 143 IIC_fpLoad64, "vldr", "\t$Dd, $addr", 144 [(set DPR:$Dd, (f64 (alignedload32 addrmode5:$addr)))]>, 145 Requires<[HasFPRegs]>; 146 147def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$Sd), (ins addrmode5:$addr), 148 IIC_fpLoad32, "vldr", "\t$Sd, $addr", 149 [(set SPR:$Sd, (alignedload32 addrmode5:$addr))]>, 150 Requires<[HasFPRegs]> { 151 // Some single precision VFP instructions may be executed on both NEON and VFP 152 // pipelines. 153 let D = VFPNeonDomain; 154} 155 156let isUnpredicable = 1 in 157def VLDRH : AHI5<0b1101, 0b01, (outs HPR:$Sd), (ins addrmode5fp16:$addr), 158 IIC_fpLoad16, "vldr", ".16\t$Sd, $addr", 159 [(set HPR:$Sd, (alignedload16 addrmode5fp16:$addr))]>, 160 Requires<[HasFPRegs16]>; 161 162} // End of 'let canFoldAsLoad = 1, isReMaterializable = 1 in' 163 164def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$Dd, addrmode5:$addr), 165 IIC_fpStore64, "vstr", "\t$Dd, $addr", 166 [(alignedstore32 (f64 DPR:$Dd), addrmode5:$addr)]>, 167 Requires<[HasFPRegs]>; 168 169def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$Sd, addrmode5:$addr), 170 IIC_fpStore32, "vstr", "\t$Sd, $addr", 171 [(alignedstore32 SPR:$Sd, addrmode5:$addr)]>, 172 Requires<[HasFPRegs]> { 173 // Some single precision VFP instructions may be executed on both NEON and VFP 174 // pipelines. 175 let D = VFPNeonDomain; 176} 177 178let isUnpredicable = 1 in 179def VSTRH : AHI5<0b1101, 0b00, (outs), (ins HPR:$Sd, addrmode5fp16:$addr), 180 IIC_fpStore16, "vstr", ".16\t$Sd, $addr", 181 [(alignedstore16 HPR:$Sd, addrmode5fp16:$addr)]>, 182 Requires<[HasFPRegs16]>; 183 184//===----------------------------------------------------------------------===// 185// Load / store multiple Instructions. 186// 187 188multiclass vfp_ldst_mult<string asm, bit L_bit, 189 InstrItinClass itin, InstrItinClass itin_upd> { 190 let Predicates = [HasFPRegs] in { 191 // Double Precision 192 def DIA : 193 AXDI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), 194 IndexModeNone, itin, 195 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> { 196 let Inst{24-23} = 0b01; // Increment After 197 let Inst{21} = 0; // No writeback 198 let Inst{20} = L_bit; 199 } 200 def DIA_UPD : 201 AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, 202 variable_ops), 203 IndexModeUpd, itin_upd, 204 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 205 let Inst{24-23} = 0b01; // Increment After 206 let Inst{21} = 1; // Writeback 207 let Inst{20} = L_bit; 208 } 209 def DDB_UPD : 210 AXDI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, 211 variable_ops), 212 IndexModeUpd, itin_upd, 213 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 214 let Inst{24-23} = 0b10; // Decrement Before 215 let Inst{21} = 1; // Writeback 216 let Inst{20} = L_bit; 217 } 218 219 // Single Precision 220 def SIA : 221 AXSI4<(outs), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, variable_ops), 222 IndexModeNone, itin, 223 !strconcat(asm, "ia${p}\t$Rn, $regs"), "", []> { 224 let Inst{24-23} = 0b01; // Increment After 225 let Inst{21} = 0; // No writeback 226 let Inst{20} = L_bit; 227 228 // Some single precision VFP instructions may be executed on both NEON and 229 // VFP pipelines. 230 let D = VFPNeonDomain; 231 } 232 def SIA_UPD : 233 AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, 234 variable_ops), 235 IndexModeUpd, itin_upd, 236 !strconcat(asm, "ia${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 237 let Inst{24-23} = 0b01; // Increment After 238 let Inst{21} = 1; // Writeback 239 let Inst{20} = L_bit; 240 241 // Some single precision VFP instructions may be executed on both NEON and 242 // VFP pipelines. 243 let D = VFPNeonDomain; 244 } 245 def SDB_UPD : 246 AXSI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, spr_reglist:$regs, 247 variable_ops), 248 IndexModeUpd, itin_upd, 249 !strconcat(asm, "db${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 250 let Inst{24-23} = 0b10; // Decrement Before 251 let Inst{21} = 1; // Writeback 252 let Inst{20} = L_bit; 253 254 // Some single precision VFP instructions may be executed on both NEON and 255 // VFP pipelines. 256 let D = VFPNeonDomain; 257 } 258 } 259} 260 261let hasSideEffects = 0 in { 262 263let mayLoad = 1, hasExtraDefRegAllocReq = 1 in 264defm VLDM : vfp_ldst_mult<"vldm", 1, IIC_fpLoad_m, IIC_fpLoad_mu>; 265 266let mayStore = 1, hasExtraSrcRegAllocReq = 1 in 267defm VSTM : vfp_ldst_mult<"vstm", 0, IIC_fpStore_m, IIC_fpStore_mu>; 268 269} // hasSideEffects 270 271def : MnemonicAlias<"vldm", "vldmia">; 272def : MnemonicAlias<"vstm", "vstmia">; 273 274 275//===----------------------------------------------------------------------===// 276// Lazy load / store multiple Instructions 277// 278let mayLoad = 1 in 279def VLLDM : AXSI4<(outs), (ins GPRnopc:$Rn, pred:$p), IndexModeNone, 280 IIC_fpLoad_m, "vlldm${p}\t$Rn", "", []>, 281 Requires<[HasV8MMainline, Has8MSecExt]> { 282 let Inst{24-23} = 0b00; 283 let Inst{22} = 0; 284 let Inst{21} = 1; 285 let Inst{20} = 1; 286 let Inst{15-12} = 0; 287 let Inst{7-0} = 0; 288 let mayLoad = 1; 289} 290 291let mayStore = 1 in 292def VLSTM : AXSI4<(outs), (ins GPRnopc:$Rn, pred:$p), IndexModeNone, 293 IIC_fpStore_m, "vlstm${p}\t$Rn", "", []>, 294 Requires<[HasV8MMainline, Has8MSecExt]> { 295 let Inst{24-23} = 0b00; 296 let Inst{22} = 0; 297 let Inst{21} = 1; 298 let Inst{20} = 0; 299 let Inst{15-12} = 0; 300 let Inst{7-0} = 0; 301 let mayStore = 1; 302} 303 304def : InstAlias<"vpush${p} $r", (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r), 0>, 305 Requires<[HasFPRegs]>; 306def : InstAlias<"vpush${p} $r", (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r), 0>, 307 Requires<[HasFPRegs]>; 308def : InstAlias<"vpop${p} $r", (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r), 0>, 309 Requires<[HasFPRegs]>; 310def : InstAlias<"vpop${p} $r", (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r), 0>, 311 Requires<[HasFPRegs]>; 312defm : VFPDTAnyInstAlias<"vpush${p}", "$r", 313 (VSTMSDB_UPD SP, pred:$p, spr_reglist:$r)>; 314defm : VFPDTAnyInstAlias<"vpush${p}", "$r", 315 (VSTMDDB_UPD SP, pred:$p, dpr_reglist:$r)>; 316defm : VFPDTAnyInstAlias<"vpop${p}", "$r", 317 (VLDMSIA_UPD SP, pred:$p, spr_reglist:$r)>; 318defm : VFPDTAnyInstAlias<"vpop${p}", "$r", 319 (VLDMDIA_UPD SP, pred:$p, dpr_reglist:$r)>; 320 321// FLDMX, FSTMX - Load and store multiple unknown precision registers for 322// pre-armv6 cores. 323// These instruction are deprecated so we don't want them to get selected. 324// However, there is no UAL syntax for them, so we keep them around for 325// (dis)assembly only. 326multiclass vfp_ldstx_mult<string asm, bit L_bit> { 327 let Predicates = [HasFPRegs] in { 328 // Unknown precision 329 def XIA : 330 AXXI4<(outs), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), 331 IndexModeNone, !strconcat(asm, "iax${p}\t$Rn, $regs"), "", []> { 332 let Inst{24-23} = 0b01; // Increment After 333 let Inst{21} = 0; // No writeback 334 let Inst{20} = L_bit; 335 } 336 def XIA_UPD : 337 AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), 338 IndexModeUpd, !strconcat(asm, "iax${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 339 let Inst{24-23} = 0b01; // Increment After 340 let Inst{21} = 1; // Writeback 341 let Inst{20} = L_bit; 342 } 343 def XDB_UPD : 344 AXXI4<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, dpr_reglist:$regs, variable_ops), 345 IndexModeUpd, !strconcat(asm, "dbx${p}\t$Rn!, $regs"), "$Rn = $wb", []> { 346 let Inst{24-23} = 0b10; // Decrement Before 347 let Inst{21} = 1; // Writeback 348 let Inst{20} = L_bit; 349 } 350 } 351} 352 353defm FLDM : vfp_ldstx_mult<"fldm", 1>; 354defm FSTM : vfp_ldstx_mult<"fstm", 0>; 355 356def : VFP2MnemonicAlias<"fldmeax", "fldmdbx">; 357def : VFP2MnemonicAlias<"fldmfdx", "fldmiax">; 358 359def : VFP2MnemonicAlias<"fstmeax", "fstmiax">; 360def : VFP2MnemonicAlias<"fstmfdx", "fstmdbx">; 361 362//===----------------------------------------------------------------------===// 363// FP Binary Operations. 364// 365 366let TwoOperandAliasConstraint = "$Dn = $Dd" in 367def VADDD : ADbI<0b11100, 0b11, 0, 0, 368 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 369 IIC_fpALU64, "vadd", ".f64\t$Dd, $Dn, $Dm", 370 [(set DPR:$Dd, (fadd DPR:$Dn, (f64 DPR:$Dm)))]>, 371 Sched<[WriteFPALU64]>; 372 373let TwoOperandAliasConstraint = "$Sn = $Sd" in 374def VADDS : ASbIn<0b11100, 0b11, 0, 0, 375 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 376 IIC_fpALU32, "vadd", ".f32\t$Sd, $Sn, $Sm", 377 [(set SPR:$Sd, (fadd SPR:$Sn, SPR:$Sm))]>, 378 Sched<[WriteFPALU32]> { 379 // Some single precision VFP instructions may be executed on both NEON and 380 // VFP pipelines on A8. 381 let D = VFPNeonA8Domain; 382} 383 384let TwoOperandAliasConstraint = "$Sn = $Sd" in 385def VADDH : AHbI<0b11100, 0b11, 0, 0, 386 (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm), 387 IIC_fpALU16, "vadd", ".f16\t$Sd, $Sn, $Sm", 388 [(set HPR:$Sd, (fadd HPR:$Sn, HPR:$Sm))]>, 389 Sched<[WriteFPALU32]>; 390 391let TwoOperandAliasConstraint = "$Dn = $Dd" in 392def VSUBD : ADbI<0b11100, 0b11, 1, 0, 393 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 394 IIC_fpALU64, "vsub", ".f64\t$Dd, $Dn, $Dm", 395 [(set DPR:$Dd, (fsub DPR:$Dn, (f64 DPR:$Dm)))]>, 396 Sched<[WriteFPALU64]>; 397 398let TwoOperandAliasConstraint = "$Sn = $Sd" in 399def VSUBS : ASbIn<0b11100, 0b11, 1, 0, 400 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 401 IIC_fpALU32, "vsub", ".f32\t$Sd, $Sn, $Sm", 402 [(set SPR:$Sd, (fsub SPR:$Sn, SPR:$Sm))]>, 403 Sched<[WriteFPALU32]>{ 404 // Some single precision VFP instructions may be executed on both NEON and 405 // VFP pipelines on A8. 406 let D = VFPNeonA8Domain; 407} 408 409let TwoOperandAliasConstraint = "$Sn = $Sd" in 410def VSUBH : AHbI<0b11100, 0b11, 1, 0, 411 (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm), 412 IIC_fpALU16, "vsub", ".f16\t$Sd, $Sn, $Sm", 413 [(set HPR:$Sd, (fsub HPR:$Sn, HPR:$Sm))]>, 414 Sched<[WriteFPALU32]>; 415 416let TwoOperandAliasConstraint = "$Dn = $Dd" in 417def VDIVD : ADbI<0b11101, 0b00, 0, 0, 418 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 419 IIC_fpDIV64, "vdiv", ".f64\t$Dd, $Dn, $Dm", 420 [(set DPR:$Dd, (fdiv DPR:$Dn, (f64 DPR:$Dm)))]>, 421 Sched<[WriteFPDIV64]>; 422 423let TwoOperandAliasConstraint = "$Sn = $Sd" in 424def VDIVS : ASbI<0b11101, 0b00, 0, 0, 425 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 426 IIC_fpDIV32, "vdiv", ".f32\t$Sd, $Sn, $Sm", 427 [(set SPR:$Sd, (fdiv SPR:$Sn, SPR:$Sm))]>, 428 Sched<[WriteFPDIV32]>; 429 430let TwoOperandAliasConstraint = "$Sn = $Sd" in 431def VDIVH : AHbI<0b11101, 0b00, 0, 0, 432 (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm), 433 IIC_fpDIV16, "vdiv", ".f16\t$Sd, $Sn, $Sm", 434 [(set HPR:$Sd, (fdiv HPR:$Sn, HPR:$Sm))]>, 435 Sched<[WriteFPDIV32]>; 436 437let TwoOperandAliasConstraint = "$Dn = $Dd" in 438def VMULD : ADbI<0b11100, 0b10, 0, 0, 439 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 440 IIC_fpMUL64, "vmul", ".f64\t$Dd, $Dn, $Dm", 441 [(set DPR:$Dd, (fmul DPR:$Dn, (f64 DPR:$Dm)))]>, 442 Sched<[WriteFPMUL64, ReadFPMUL, ReadFPMUL]>; 443 444let TwoOperandAliasConstraint = "$Sn = $Sd" in 445def VMULS : ASbIn<0b11100, 0b10, 0, 0, 446 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 447 IIC_fpMUL32, "vmul", ".f32\t$Sd, $Sn, $Sm", 448 [(set SPR:$Sd, (fmul SPR:$Sn, SPR:$Sm))]>, 449 Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]> { 450 // Some single precision VFP instructions may be executed on both NEON and 451 // VFP pipelines on A8. 452 let D = VFPNeonA8Domain; 453} 454 455let TwoOperandAliasConstraint = "$Sn = $Sd" in 456def VMULH : AHbI<0b11100, 0b10, 0, 0, 457 (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm), 458 IIC_fpMUL16, "vmul", ".f16\t$Sd, $Sn, $Sm", 459 [(set HPR:$Sd, (fmul HPR:$Sn, HPR:$Sm))]>, 460 Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]>; 461 462def VNMULD : ADbI<0b11100, 0b10, 1, 0, 463 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 464 IIC_fpMUL64, "vnmul", ".f64\t$Dd, $Dn, $Dm", 465 [(set DPR:$Dd, (fneg (fmul DPR:$Dn, (f64 DPR:$Dm))))]>, 466 Sched<[WriteFPMUL64, ReadFPMUL, ReadFPMUL]>; 467 468def VNMULS : ASbI<0b11100, 0b10, 1, 0, 469 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 470 IIC_fpMUL32, "vnmul", ".f32\t$Sd, $Sn, $Sm", 471 [(set SPR:$Sd, (fneg (fmul SPR:$Sn, SPR:$Sm)))]>, 472 Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]> { 473 // Some single precision VFP instructions may be executed on both NEON and 474 // VFP pipelines on A8. 475 let D = VFPNeonA8Domain; 476} 477 478def VNMULH : AHbI<0b11100, 0b10, 1, 0, 479 (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm), 480 IIC_fpMUL16, "vnmul", ".f16\t$Sd, $Sn, $Sm", 481 [(set HPR:$Sd, (fneg (fmul HPR:$Sn, HPR:$Sm)))]>, 482 Sched<[WriteFPMUL32, ReadFPMUL, ReadFPMUL]>; 483 484multiclass vsel_inst<string op, bits<2> opc, int CC> { 485 let DecoderNamespace = "VFPV8", PostEncoderMethod = "", 486 Uses = [CPSR], AddedComplexity = 4, isUnpredicable = 1 in { 487 def H : AHbInp<0b11100, opc, 0, 488 (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm), 489 NoItinerary, !strconcat("vsel", op, ".f16\t$Sd, $Sn, $Sm"), 490 [(set HPR:$Sd, (ARMcmov HPR:$Sm, HPR:$Sn, CC))]>, 491 Requires<[HasFullFP16]>; 492 493 def S : ASbInp<0b11100, opc, 0, 494 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 495 NoItinerary, !strconcat("vsel", op, ".f32\t$Sd, $Sn, $Sm"), 496 [(set SPR:$Sd, (ARMcmov SPR:$Sm, SPR:$Sn, CC))]>, 497 Requires<[HasFPARMv8]>; 498 499 def D : ADbInp<0b11100, opc, 0, 500 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 501 NoItinerary, !strconcat("vsel", op, ".f64\t$Dd, $Dn, $Dm"), 502 [(set DPR:$Dd, (ARMcmov (f64 DPR:$Dm), (f64 DPR:$Dn), CC))]>, 503 Requires<[HasFPARMv8, HasDPVFP]>; 504 } 505} 506 507// The CC constants here match ARMCC::CondCodes. 508defm VSELGT : vsel_inst<"gt", 0b11, 12>; 509defm VSELGE : vsel_inst<"ge", 0b10, 10>; 510defm VSELEQ : vsel_inst<"eq", 0b00, 0>; 511defm VSELVS : vsel_inst<"vs", 0b01, 6>; 512 513multiclass vmaxmin_inst<string op, bit opc, SDNode SD> { 514 let DecoderNamespace = "VFPV8", PostEncoderMethod = "", 515 isUnpredicable = 1 in { 516 def H : AHbInp<0b11101, 0b00, opc, 517 (outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm), 518 NoItinerary, !strconcat(op, ".f16\t$Sd, $Sn, $Sm"), 519 [(set HPR:$Sd, (SD HPR:$Sn, HPR:$Sm))]>, 520 Requires<[HasFullFP16]>; 521 522 def S : ASbInp<0b11101, 0b00, opc, 523 (outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm), 524 NoItinerary, !strconcat(op, ".f32\t$Sd, $Sn, $Sm"), 525 [(set SPR:$Sd, (SD SPR:$Sn, SPR:$Sm))]>, 526 Requires<[HasFPARMv8]>; 527 528 def D : ADbInp<0b11101, 0b00, opc, 529 (outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm), 530 NoItinerary, !strconcat(op, ".f64\t$Dd, $Dn, $Dm"), 531 [(set DPR:$Dd, (f64 (SD (f64 DPR:$Dn), (f64 DPR:$Dm))))]>, 532 Requires<[HasFPARMv8, HasDPVFP]>; 533 } 534} 535 536defm VFP_VMAXNM : vmaxmin_inst<"vmaxnm", 0, fmaxnum>; 537defm VFP_VMINNM : vmaxmin_inst<"vminnm", 1, fminnum>; 538 539// Match reassociated forms only if not sign dependent rounding. 540def : Pat<(fmul (fneg DPR:$a), (f64 DPR:$b)), 541 (VNMULD DPR:$a, DPR:$b)>, 542 Requires<[NoHonorSignDependentRounding,HasDPVFP]>; 543def : Pat<(fmul (fneg SPR:$a), SPR:$b), 544 (VNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>; 545 546// These are encoded as unary instructions. 547let Defs = [FPSCR_NZCV] in { 548def VCMPED : ADuI<0b11101, 0b11, 0b0100, 0b11, 0, 549 (outs), (ins DPR:$Dd, DPR:$Dm), 550 IIC_fpCMP64, "vcmpe", ".f64\t$Dd, $Dm", 551 [(arm_cmpfp DPR:$Dd, (f64 DPR:$Dm), (i32 1))]>; 552 553def VCMPES : ASuI<0b11101, 0b11, 0b0100, 0b11, 0, 554 (outs), (ins SPR:$Sd, SPR:$Sm), 555 IIC_fpCMP32, "vcmpe", ".f32\t$Sd, $Sm", 556 [(arm_cmpfp SPR:$Sd, SPR:$Sm, (i32 1))]> { 557 // Some single precision VFP instructions may be executed on both NEON and 558 // VFP pipelines on A8. 559 let D = VFPNeonA8Domain; 560} 561 562def VCMPEH : AHuI<0b11101, 0b11, 0b0100, 0b11, 0, 563 (outs), (ins HPR:$Sd, HPR:$Sm), 564 IIC_fpCMP16, "vcmpe", ".f16\t$Sd, $Sm", 565 [(arm_cmpfp HPR:$Sd, HPR:$Sm, (i32 1))]>; 566 567def VCMPD : ADuI<0b11101, 0b11, 0b0100, 0b01, 0, 568 (outs), (ins DPR:$Dd, DPR:$Dm), 569 IIC_fpCMP64, "vcmp", ".f64\t$Dd, $Dm", 570 [(arm_cmpfp DPR:$Dd, (f64 DPR:$Dm), (i32 0))]>; 571 572def VCMPS : ASuI<0b11101, 0b11, 0b0100, 0b01, 0, 573 (outs), (ins SPR:$Sd, SPR:$Sm), 574 IIC_fpCMP32, "vcmp", ".f32\t$Sd, $Sm", 575 [(arm_cmpfp SPR:$Sd, SPR:$Sm, (i32 0))]> { 576 // Some single precision VFP instructions may be executed on both NEON and 577 // VFP pipelines on A8. 578 let D = VFPNeonA8Domain; 579} 580 581def VCMPH : AHuI<0b11101, 0b11, 0b0100, 0b01, 0, 582 (outs), (ins HPR:$Sd, HPR:$Sm), 583 IIC_fpCMP16, "vcmp", ".f16\t$Sd, $Sm", 584 [(arm_cmpfp HPR:$Sd, HPR:$Sm, (i32 0))]>; 585} // Defs = [FPSCR_NZCV] 586 587//===----------------------------------------------------------------------===// 588// FP Unary Operations. 589// 590 591def VABSD : ADuI<0b11101, 0b11, 0b0000, 0b11, 0, 592 (outs DPR:$Dd), (ins DPR:$Dm), 593 IIC_fpUNA64, "vabs", ".f64\t$Dd, $Dm", 594 [(set DPR:$Dd, (fabs (f64 DPR:$Dm)))]>; 595 596def VABSS : ASuIn<0b11101, 0b11, 0b0000, 0b11, 0, 597 (outs SPR:$Sd), (ins SPR:$Sm), 598 IIC_fpUNA32, "vabs", ".f32\t$Sd, $Sm", 599 [(set SPR:$Sd, (fabs SPR:$Sm))]> { 600 // Some single precision VFP instructions may be executed on both NEON and 601 // VFP pipelines on A8. 602 let D = VFPNeonA8Domain; 603} 604 605def VABSH : AHuI<0b11101, 0b11, 0b0000, 0b11, 0, 606 (outs HPR:$Sd), (ins HPR:$Sm), 607 IIC_fpUNA16, "vabs", ".f16\t$Sd, $Sm", 608 [(set HPR:$Sd, (fabs (f16 HPR:$Sm)))]>; 609 610let Defs = [FPSCR_NZCV] in { 611def VCMPEZD : ADuI<0b11101, 0b11, 0b0101, 0b11, 0, 612 (outs), (ins DPR:$Dd), 613 IIC_fpCMP64, "vcmpe", ".f64\t$Dd, #0", 614 [(arm_cmpfp0 (f64 DPR:$Dd), (i32 1))]> { 615 let Inst{3-0} = 0b0000; 616 let Inst{5} = 0; 617} 618 619def VCMPEZS : ASuI<0b11101, 0b11, 0b0101, 0b11, 0, 620 (outs), (ins SPR:$Sd), 621 IIC_fpCMP32, "vcmpe", ".f32\t$Sd, #0", 622 [(arm_cmpfp0 SPR:$Sd, (i32 1))]> { 623 let Inst{3-0} = 0b0000; 624 let Inst{5} = 0; 625 626 // Some single precision VFP instructions may be executed on both NEON and 627 // VFP pipelines on A8. 628 let D = VFPNeonA8Domain; 629} 630 631def VCMPEZH : AHuI<0b11101, 0b11, 0b0101, 0b11, 0, 632 (outs), (ins HPR:$Sd), 633 IIC_fpCMP16, "vcmpe", ".f16\t$Sd, #0", 634 [(arm_cmpfp0 HPR:$Sd, (i32 1))]> { 635 let Inst{3-0} = 0b0000; 636 let Inst{5} = 0; 637} 638 639def VCMPZD : ADuI<0b11101, 0b11, 0b0101, 0b01, 0, 640 (outs), (ins DPR:$Dd), 641 IIC_fpCMP64, "vcmp", ".f64\t$Dd, #0", 642 [(arm_cmpfp0 (f64 DPR:$Dd), (i32 0))]> { 643 let Inst{3-0} = 0b0000; 644 let Inst{5} = 0; 645} 646 647def VCMPZS : ASuI<0b11101, 0b11, 0b0101, 0b01, 0, 648 (outs), (ins SPR:$Sd), 649 IIC_fpCMP32, "vcmp", ".f32\t$Sd, #0", 650 [(arm_cmpfp0 SPR:$Sd, (i32 0))]> { 651 let Inst{3-0} = 0b0000; 652 let Inst{5} = 0; 653 654 // Some single precision VFP instructions may be executed on both NEON and 655 // VFP pipelines on A8. 656 let D = VFPNeonA8Domain; 657} 658 659def VCMPZH : AHuI<0b11101, 0b11, 0b0101, 0b01, 0, 660 (outs), (ins HPR:$Sd), 661 IIC_fpCMP16, "vcmp", ".f16\t$Sd, #0", 662 [(arm_cmpfp0 HPR:$Sd, (i32 0))]> { 663 let Inst{3-0} = 0b0000; 664 let Inst{5} = 0; 665} 666} // Defs = [FPSCR_NZCV] 667 668def VCVTDS : ASuI<0b11101, 0b11, 0b0111, 0b11, 0, 669 (outs DPR:$Dd), (ins SPR:$Sm), 670 IIC_fpCVTDS, "vcvt", ".f64.f32\t$Dd, $Sm", 671 [(set DPR:$Dd, (fpextend SPR:$Sm))]>, 672 Sched<[WriteFPCVT]> { 673 // Instruction operands. 674 bits<5> Dd; 675 bits<5> Sm; 676 677 // Encode instruction operands. 678 let Inst{3-0} = Sm{4-1}; 679 let Inst{5} = Sm{0}; 680 let Inst{15-12} = Dd{3-0}; 681 let Inst{22} = Dd{4}; 682 683 let Predicates = [HasVFP2, HasDPVFP]; 684} 685 686// Special case encoding: bits 11-8 is 0b1011. 687def VCVTSD : VFPAI<(outs SPR:$Sd), (ins DPR:$Dm), VFPUnaryFrm, 688 IIC_fpCVTSD, "vcvt", ".f32.f64\t$Sd, $Dm", 689 [(set SPR:$Sd, (fpround DPR:$Dm))]>, 690 Sched<[WriteFPCVT]> { 691 // Instruction operands. 692 bits<5> Sd; 693 bits<5> Dm; 694 695 // Encode instruction operands. 696 let Inst{3-0} = Dm{3-0}; 697 let Inst{5} = Dm{4}; 698 let Inst{15-12} = Sd{4-1}; 699 let Inst{22} = Sd{0}; 700 701 let Inst{27-23} = 0b11101; 702 let Inst{21-16} = 0b110111; 703 let Inst{11-8} = 0b1011; 704 let Inst{7-6} = 0b11; 705 let Inst{4} = 0; 706 707 let Predicates = [HasVFP2, HasDPVFP]; 708} 709 710// Between half, single and double-precision. 711def VCVTBHS: ASuI<0b11101, 0b11, 0b0010, 0b01, 0, (outs SPR:$Sd), (ins SPR:$Sm), 712 /* FIXME */ IIC_fpCVTSH, "vcvtb", ".f32.f16\t$Sd, $Sm", 713 [/* Intentionally left blank, see patterns below */]>, 714 Requires<[HasFP16]>, 715 Sched<[WriteFPCVT]>; 716 717def : FP16Pat<(f32 (fpextend HPR:$Sm)), 718 (VCVTBHS (COPY_TO_REGCLASS HPR:$Sm, SPR))>; 719def : FP16Pat<(f16_to_fp GPR:$a), 720 (VCVTBHS (COPY_TO_REGCLASS GPR:$a, SPR))>; 721 722def VCVTBSH: ASuI<0b11101, 0b11, 0b0011, 0b01, 0, (outs SPR:$Sd), (ins SPR:$Sm), 723 /* FIXME */ IIC_fpCVTHS, "vcvtb", ".f16.f32\t$Sd, $Sm", 724 [/* Intentionally left blank, see patterns below */]>, 725 Requires<[HasFP16]>, 726 Sched<[WriteFPCVT]>; 727 728def : FP16Pat<(f16 (fpround SPR:$Sm)), 729 (COPY_TO_REGCLASS (VCVTBSH SPR:$Sm), HPR)>; 730def : FP16Pat<(fp_to_f16 SPR:$a), 731 (i32 (COPY_TO_REGCLASS (VCVTBSH SPR:$a), GPR))>; 732 733def VCVTTHS: ASuI<0b11101, 0b11, 0b0010, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sm), 734 /* FIXME */ IIC_fpCVTSH, "vcvtt", ".f32.f16\t$Sd, $Sm", 735 [/* For disassembly only; pattern left blank */]>, 736 Requires<[HasFP16]>, 737 Sched<[WriteFPCVT]>; 738 739def VCVTTSH: ASuI<0b11101, 0b11, 0b0011, 0b11, 0, (outs SPR:$Sd), (ins SPR:$Sm), 740 /* FIXME */ IIC_fpCVTHS, "vcvtt", ".f16.f32\t$Sd, $Sm", 741 [/* For disassembly only; pattern left blank */]>, 742 Requires<[HasFP16]>, 743 Sched<[WriteFPCVT]>; 744 745def VCVTBHD : ADuI<0b11101, 0b11, 0b0010, 0b01, 0, 746 (outs DPR:$Dd), (ins SPR:$Sm), 747 NoItinerary, "vcvtb", ".f64.f16\t$Dd, $Sm", 748 [/* Intentionally left blank, see patterns below */]>, 749 Requires<[HasFPARMv8, HasDPVFP]>, 750 Sched<[WriteFPCVT]> { 751 // Instruction operands. 752 bits<5> Sm; 753 754 // Encode instruction operands. 755 let Inst{3-0} = Sm{4-1}; 756 let Inst{5} = Sm{0}; 757} 758 759def : FullFP16Pat<(f64 (fpextend HPR:$Sm)), 760 (VCVTBHD (COPY_TO_REGCLASS HPR:$Sm, SPR))>, 761 Requires<[HasFPARMv8, HasDPVFP]>; 762def : FP16Pat<(f64 (f16_to_fp GPR:$a)), 763 (VCVTBHD (COPY_TO_REGCLASS GPR:$a, SPR))>, 764 Requires<[HasFPARMv8, HasDPVFP]>; 765 766def VCVTBDH : ADuI<0b11101, 0b11, 0b0011, 0b01, 0, 767 (outs SPR:$Sd), (ins DPR:$Dm), 768 NoItinerary, "vcvtb", ".f16.f64\t$Sd, $Dm", 769 [/* Intentionally left blank, see patterns below */]>, 770 Requires<[HasFPARMv8, HasDPVFP]> { 771 // Instruction operands. 772 bits<5> Sd; 773 bits<5> Dm; 774 775 // Encode instruction operands. 776 let Inst{3-0} = Dm{3-0}; 777 let Inst{5} = Dm{4}; 778 let Inst{15-12} = Sd{4-1}; 779 let Inst{22} = Sd{0}; 780} 781 782def : FullFP16Pat<(f16 (fpround DPR:$Dm)), 783 (COPY_TO_REGCLASS (VCVTBDH DPR:$Dm), HPR)>, 784 Requires<[HasFPARMv8, HasDPVFP]>; 785def : FP16Pat<(fp_to_f16 (f64 DPR:$a)), 786 (i32 (COPY_TO_REGCLASS (VCVTBDH DPR:$a), GPR))>, 787 Requires<[HasFPARMv8, HasDPVFP]>; 788 789def VCVTTHD : ADuI<0b11101, 0b11, 0b0010, 0b11, 0, 790 (outs DPR:$Dd), (ins SPR:$Sm), 791 NoItinerary, "vcvtt", ".f64.f16\t$Dd, $Sm", 792 []>, Requires<[HasFPARMv8, HasDPVFP]> { 793 // Instruction operands. 794 bits<5> Sm; 795 796 // Encode instruction operands. 797 let Inst{3-0} = Sm{4-1}; 798 let Inst{5} = Sm{0}; 799} 800 801def VCVTTDH : ADuI<0b11101, 0b11, 0b0011, 0b11, 0, 802 (outs SPR:$Sd), (ins DPR:$Dm), 803 NoItinerary, "vcvtt", ".f16.f64\t$Sd, $Dm", 804 []>, Requires<[HasFPARMv8, HasDPVFP]> { 805 // Instruction operands. 806 bits<5> Sd; 807 bits<5> Dm; 808 809 // Encode instruction operands. 810 let Inst{15-12} = Sd{4-1}; 811 let Inst{22} = Sd{0}; 812 let Inst{3-0} = Dm{3-0}; 813 let Inst{5} = Dm{4}; 814} 815 816multiclass vcvt_inst<string opc, bits<2> rm, 817 SDPatternOperator node = null_frag> { 818 let PostEncoderMethod = "", DecoderNamespace = "VFPV8" in { 819 def SH : AHuInp<0b11101, 0b11, 0b1100, 0b11, 0, 820 (outs SPR:$Sd), (ins HPR:$Sm), 821 NoItinerary, !strconcat("vcvt", opc, ".s32.f16\t$Sd, $Sm"), 822 []>, 823 Requires<[HasFullFP16]> { 824 let Inst{17-16} = rm; 825 } 826 827 def UH : AHuInp<0b11101, 0b11, 0b1100, 0b01, 0, 828 (outs SPR:$Sd), (ins HPR:$Sm), 829 NoItinerary, !strconcat("vcvt", opc, ".u32.f16\t$Sd, $Sm"), 830 []>, 831 Requires<[HasFullFP16]> { 832 let Inst{17-16} = rm; 833 } 834 835 def SS : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0, 836 (outs SPR:$Sd), (ins SPR:$Sm), 837 NoItinerary, !strconcat("vcvt", opc, ".s32.f32\t$Sd, $Sm"), 838 []>, 839 Requires<[HasFPARMv8]> { 840 let Inst{17-16} = rm; 841 } 842 843 def US : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0, 844 (outs SPR:$Sd), (ins SPR:$Sm), 845 NoItinerary, !strconcat("vcvt", opc, ".u32.f32\t$Sd, $Sm"), 846 []>, 847 Requires<[HasFPARMv8]> { 848 let Inst{17-16} = rm; 849 } 850 851 def SD : ASuInp<0b11101, 0b11, 0b1100, 0b11, 0, 852 (outs SPR:$Sd), (ins DPR:$Dm), 853 NoItinerary, !strconcat("vcvt", opc, ".s32.f64\t$Sd, $Dm"), 854 []>, 855 Requires<[HasFPARMv8, HasDPVFP]> { 856 bits<5> Dm; 857 858 let Inst{17-16} = rm; 859 860 // Encode instruction operands. 861 let Inst{3-0} = Dm{3-0}; 862 let Inst{5} = Dm{4}; 863 let Inst{8} = 1; 864 } 865 866 def UD : ASuInp<0b11101, 0b11, 0b1100, 0b01, 0, 867 (outs SPR:$Sd), (ins DPR:$Dm), 868 NoItinerary, !strconcat("vcvt", opc, ".u32.f64\t$Sd, $Dm"), 869 []>, 870 Requires<[HasFPARMv8, HasDPVFP]> { 871 bits<5> Dm; 872 873 let Inst{17-16} = rm; 874 875 // Encode instruction operands 876 let Inst{3-0} = Dm{3-0}; 877 let Inst{5} = Dm{4}; 878 let Inst{8} = 1; 879 } 880 } 881 882 let Predicates = [HasFPARMv8] in { 883 let Predicates = [HasFullFP16] in { 884 def : Pat<(i32 (fp_to_sint (node HPR:$a))), 885 (COPY_TO_REGCLASS 886 (!cast<Instruction>(NAME#"SH") HPR:$a), 887 GPR)>; 888 889 def : Pat<(i32 (fp_to_uint (node HPR:$a))), 890 (COPY_TO_REGCLASS 891 (!cast<Instruction>(NAME#"UH") HPR:$a), 892 GPR)>; 893 } 894 def : Pat<(i32 (fp_to_sint (node SPR:$a))), 895 (COPY_TO_REGCLASS 896 (!cast<Instruction>(NAME#"SS") SPR:$a), 897 GPR)>; 898 def : Pat<(i32 (fp_to_uint (node SPR:$a))), 899 (COPY_TO_REGCLASS 900 (!cast<Instruction>(NAME#"US") SPR:$a), 901 GPR)>; 902 } 903 let Predicates = [HasFPARMv8, HasDPVFP] in { 904 def : Pat<(i32 (fp_to_sint (node (f64 DPR:$a)))), 905 (COPY_TO_REGCLASS 906 (!cast<Instruction>(NAME#"SD") DPR:$a), 907 GPR)>; 908 def : Pat<(i32 (fp_to_uint (node (f64 DPR:$a)))), 909 (COPY_TO_REGCLASS 910 (!cast<Instruction>(NAME#"UD") DPR:$a), 911 GPR)>; 912 } 913} 914 915defm VCVTA : vcvt_inst<"a", 0b00, fround>; 916defm VCVTN : vcvt_inst<"n", 0b01>; 917defm VCVTP : vcvt_inst<"p", 0b10, fceil>; 918defm VCVTM : vcvt_inst<"m", 0b11, ffloor>; 919 920def VNEGD : ADuI<0b11101, 0b11, 0b0001, 0b01, 0, 921 (outs DPR:$Dd), (ins DPR:$Dm), 922 IIC_fpUNA64, "vneg", ".f64\t$Dd, $Dm", 923 [(set DPR:$Dd, (fneg (f64 DPR:$Dm)))]>; 924 925def VNEGS : ASuIn<0b11101, 0b11, 0b0001, 0b01, 0, 926 (outs SPR:$Sd), (ins SPR:$Sm), 927 IIC_fpUNA32, "vneg", ".f32\t$Sd, $Sm", 928 [(set SPR:$Sd, (fneg SPR:$Sm))]> { 929 // Some single precision VFP instructions may be executed on both NEON and 930 // VFP pipelines on A8. 931 let D = VFPNeonA8Domain; 932} 933 934def VNEGH : AHuI<0b11101, 0b11, 0b0001, 0b01, 0, 935 (outs HPR:$Sd), (ins HPR:$Sm), 936 IIC_fpUNA16, "vneg", ".f16\t$Sd, $Sm", 937 [(set HPR:$Sd, (fneg HPR:$Sm))]>; 938 939multiclass vrint_inst_zrx<string opc, bit op, bit op2, SDPatternOperator node> { 940 def H : AHuI<0b11101, 0b11, 0b0110, 0b11, 0, 941 (outs HPR:$Sd), (ins HPR:$Sm), 942 NoItinerary, !strconcat("vrint", opc), ".f16\t$Sd, $Sm", 943 [(set (f16 HPR:$Sd), (node (f16 HPR:$Sm)))]>, 944 Requires<[HasFullFP16]> { 945 let Inst{7} = op2; 946 let Inst{16} = op; 947 } 948 949 def S : ASuI<0b11101, 0b11, 0b0110, 0b11, 0, 950 (outs SPR:$Sd), (ins SPR:$Sm), 951 NoItinerary, !strconcat("vrint", opc), ".f32\t$Sd, $Sm", 952 [(set (f32 SPR:$Sd), (node (f32 SPR:$Sm)))]>, 953 Requires<[HasFPARMv8]> { 954 let Inst{7} = op2; 955 let Inst{16} = op; 956 } 957 def D : ADuI<0b11101, 0b11, 0b0110, 0b11, 0, 958 (outs DPR:$Dd), (ins DPR:$Dm), 959 NoItinerary, !strconcat("vrint", opc), ".f64\t$Dd, $Dm", 960 [(set (f64 DPR:$Dd), (node (f64 DPR:$Dm)))]>, 961 Requires<[HasFPARMv8, HasDPVFP]> { 962 let Inst{7} = op2; 963 let Inst{16} = op; 964 } 965 966 def : InstAlias<!strconcat("vrint", opc, "$p.f16.f16\t$Sd, $Sm"), 967 (!cast<Instruction>(NAME#"H") SPR:$Sd, SPR:$Sm, pred:$p), 0>, 968 Requires<[HasFullFP16]>; 969 def : InstAlias<!strconcat("vrint", opc, "$p.f32.f32\t$Sd, $Sm"), 970 (!cast<Instruction>(NAME#"S") SPR:$Sd, SPR:$Sm, pred:$p), 0>, 971 Requires<[HasFPARMv8]>; 972 def : InstAlias<!strconcat("vrint", opc, "$p.f64.f64\t$Dd, $Dm"), 973 (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm, pred:$p), 0>, 974 Requires<[HasFPARMv8,HasDPVFP]>; 975} 976 977defm VRINTZ : vrint_inst_zrx<"z", 0, 1, ftrunc>; 978defm VRINTR : vrint_inst_zrx<"r", 0, 0, fnearbyint>; 979defm VRINTX : vrint_inst_zrx<"x", 1, 0, frint>; 980 981multiclass vrint_inst_anpm<string opc, bits<2> rm, 982 SDPatternOperator node = null_frag> { 983 let PostEncoderMethod = "", DecoderNamespace = "VFPV8", 984 isUnpredicable = 1 in { 985 def H : AHuInp<0b11101, 0b11, 0b1000, 0b01, 0, 986 (outs HPR:$Sd), (ins HPR:$Sm), 987 NoItinerary, !strconcat("vrint", opc, ".f16\t$Sd, $Sm"), 988 [(set (f16 HPR:$Sd), (node (f16 HPR:$Sm)))]>, 989 Requires<[HasFullFP16]> { 990 let Inst{17-16} = rm; 991 } 992 def S : ASuInp<0b11101, 0b11, 0b1000, 0b01, 0, 993 (outs SPR:$Sd), (ins SPR:$Sm), 994 NoItinerary, !strconcat("vrint", opc, ".f32\t$Sd, $Sm"), 995 [(set (f32 SPR:$Sd), (node (f32 SPR:$Sm)))]>, 996 Requires<[HasFPARMv8]> { 997 let Inst{17-16} = rm; 998 } 999 def D : ADuInp<0b11101, 0b11, 0b1000, 0b01, 0, 1000 (outs DPR:$Dd), (ins DPR:$Dm), 1001 NoItinerary, !strconcat("vrint", opc, ".f64\t$Dd, $Dm"), 1002 [(set (f64 DPR:$Dd), (node (f64 DPR:$Dm)))]>, 1003 Requires<[HasFPARMv8, HasDPVFP]> { 1004 let Inst{17-16} = rm; 1005 } 1006 } 1007 1008 def : InstAlias<!strconcat("vrint", opc, ".f32.f32\t$Sd, $Sm"), 1009 (!cast<Instruction>(NAME#"S") SPR:$Sd, SPR:$Sm), 0>, 1010 Requires<[HasFPARMv8]>; 1011 def : InstAlias<!strconcat("vrint", opc, ".f64.f64\t$Dd, $Dm"), 1012 (!cast<Instruction>(NAME#"D") DPR:$Dd, DPR:$Dm), 0>, 1013 Requires<[HasFPARMv8,HasDPVFP]>; 1014} 1015 1016defm VRINTA : vrint_inst_anpm<"a", 0b00, fround>; 1017defm VRINTN : vrint_inst_anpm<"n", 0b01, int_arm_neon_vrintn>; 1018defm VRINTP : vrint_inst_anpm<"p", 0b10, fceil>; 1019defm VRINTM : vrint_inst_anpm<"m", 0b11, ffloor>; 1020 1021def VSQRTD : ADuI<0b11101, 0b11, 0b0001, 0b11, 0, 1022 (outs DPR:$Dd), (ins DPR:$Dm), 1023 IIC_fpSQRT64, "vsqrt", ".f64\t$Dd, $Dm", 1024 [(set DPR:$Dd, (fsqrt (f64 DPR:$Dm)))]>, 1025 Sched<[WriteFPSQRT64]>; 1026 1027def VSQRTS : ASuI<0b11101, 0b11, 0b0001, 0b11, 0, 1028 (outs SPR:$Sd), (ins SPR:$Sm), 1029 IIC_fpSQRT32, "vsqrt", ".f32\t$Sd, $Sm", 1030 [(set SPR:$Sd, (fsqrt SPR:$Sm))]>, 1031 Sched<[WriteFPSQRT32]>; 1032 1033def VSQRTH : AHuI<0b11101, 0b11, 0b0001, 0b11, 0, 1034 (outs HPR:$Sd), (ins HPR:$Sm), 1035 IIC_fpSQRT16, "vsqrt", ".f16\t$Sd, $Sm", 1036 [(set HPR:$Sd, (fsqrt (f16 HPR:$Sm)))]>; 1037 1038let hasSideEffects = 0 in { 1039let isMoveReg = 1 in { 1040def VMOVD : ADuI<0b11101, 0b11, 0b0000, 0b01, 0, 1041 (outs DPR:$Dd), (ins DPR:$Dm), 1042 IIC_fpUNA64, "vmov", ".f64\t$Dd, $Dm", []>, 1043 Requires<[HasFPRegs64]>; 1044 1045def VMOVS : ASuI<0b11101, 0b11, 0b0000, 0b01, 0, 1046 (outs SPR:$Sd), (ins SPR:$Sm), 1047 IIC_fpUNA32, "vmov", ".f32\t$Sd, $Sm", []>, 1048 Requires<[HasFPRegs]>; 1049} // isMoveReg 1050 1051let PostEncoderMethod = "", DecoderNamespace = "VFPV8", isUnpredicable = 1 in { 1052def VMOVH : ASuInp<0b11101, 0b11, 0b0000, 0b01, 0, 1053 (outs SPR:$Sd), (ins SPR:$Sm), 1054 IIC_fpUNA16, "vmovx.f16\t$Sd, $Sm", []>, 1055 Requires<[HasFullFP16]>; 1056 1057def VINSH : ASuInp<0b11101, 0b11, 0b0000, 0b11, 0, 1058 (outs SPR:$Sd), (ins SPR:$Sm), 1059 IIC_fpUNA16, "vins.f16\t$Sd, $Sm", []>, 1060 Requires<[HasFullFP16]>; 1061} // PostEncoderMethod 1062} // hasSideEffects 1063 1064//===----------------------------------------------------------------------===// 1065// FP <-> GPR Copies. Int <-> FP Conversions. 1066// 1067 1068let isMoveReg = 1 in { 1069def VMOVRS : AVConv2I<0b11100001, 0b1010, 1070 (outs GPR:$Rt), (ins SPR:$Sn), 1071 IIC_fpMOVSI, "vmov", "\t$Rt, $Sn", 1072 [(set GPR:$Rt, (bitconvert SPR:$Sn))]>, 1073 Requires<[HasFPRegs]>, 1074 Sched<[WriteFPMOV]> { 1075 // Instruction operands. 1076 bits<4> Rt; 1077 bits<5> Sn; 1078 1079 // Encode instruction operands. 1080 let Inst{19-16} = Sn{4-1}; 1081 let Inst{7} = Sn{0}; 1082 let Inst{15-12} = Rt; 1083 1084 let Inst{6-5} = 0b00; 1085 let Inst{3-0} = 0b0000; 1086 1087 // Some single precision VFP instructions may be executed on both NEON and VFP 1088 // pipelines. 1089 let D = VFPNeonDomain; 1090} 1091 1092// Bitcast i32 -> f32. NEON prefers to use VMOVDRR. 1093def VMOVSR : AVConv4I<0b11100000, 0b1010, 1094 (outs SPR:$Sn), (ins GPR:$Rt), 1095 IIC_fpMOVIS, "vmov", "\t$Sn, $Rt", 1096 [(set SPR:$Sn, (bitconvert GPR:$Rt))]>, 1097 Requires<[HasFPRegs, UseVMOVSR]>, 1098 Sched<[WriteFPMOV]> { 1099 // Instruction operands. 1100 bits<5> Sn; 1101 bits<4> Rt; 1102 1103 // Encode instruction operands. 1104 let Inst{19-16} = Sn{4-1}; 1105 let Inst{7} = Sn{0}; 1106 let Inst{15-12} = Rt; 1107 1108 let Inst{6-5} = 0b00; 1109 let Inst{3-0} = 0b0000; 1110 1111 // Some single precision VFP instructions may be executed on both NEON and VFP 1112 // pipelines. 1113 let D = VFPNeonDomain; 1114} 1115} // isMoveReg 1116def : Pat<(arm_vmovsr GPR:$Rt), (VMOVSR GPR:$Rt)>, Requires<[HasVFP2, UseVMOVSR]>; 1117 1118let hasSideEffects = 0 in { 1119def VMOVRRD : AVConv3I<0b11000101, 0b1011, 1120 (outs GPR:$Rt, GPR:$Rt2), (ins DPR:$Dm), 1121 IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $Dm", 1122 [(set GPR:$Rt, GPR:$Rt2, (arm_fmrrd DPR:$Dm))]>, 1123 Requires<[HasFPRegs]>, 1124 Sched<[WriteFPMOV]> { 1125 // Instruction operands. 1126 bits<5> Dm; 1127 bits<4> Rt; 1128 bits<4> Rt2; 1129 1130 // Encode instruction operands. 1131 let Inst{3-0} = Dm{3-0}; 1132 let Inst{5} = Dm{4}; 1133 let Inst{15-12} = Rt; 1134 let Inst{19-16} = Rt2; 1135 1136 let Inst{7-6} = 0b00; 1137 1138 // Some single precision VFP instructions may be executed on both NEON and VFP 1139 // pipelines. 1140 let D = VFPNeonDomain; 1141 1142 // This instruction is equivalent to 1143 // $Rt = EXTRACT_SUBREG $Dm, ssub_0 1144 // $Rt2 = EXTRACT_SUBREG $Dm, ssub_1 1145 let isExtractSubreg = 1; 1146} 1147 1148def VMOVRRS : AVConv3I<0b11000101, 0b1010, 1149 (outs GPR:$Rt, GPR:$Rt2), (ins SPR:$src1, SPR:$src2), 1150 IIC_fpMOVDI, "vmov", "\t$Rt, $Rt2, $src1, $src2", 1151 [/* For disassembly only; pattern left blank */]>, 1152 Requires<[HasFPRegs]>, 1153 Sched<[WriteFPMOV]> { 1154 bits<5> src1; 1155 bits<4> Rt; 1156 bits<4> Rt2; 1157 1158 // Encode instruction operands. 1159 let Inst{3-0} = src1{4-1}; 1160 let Inst{5} = src1{0}; 1161 let Inst{15-12} = Rt; 1162 let Inst{19-16} = Rt2; 1163 1164 let Inst{7-6} = 0b00; 1165 1166 // Some single precision VFP instructions may be executed on both NEON and VFP 1167 // pipelines. 1168 let D = VFPNeonDomain; 1169 let DecoderMethod = "DecodeVMOVRRS"; 1170} 1171} // hasSideEffects 1172 1173// FMDHR: GPR -> SPR 1174// FMDLR: GPR -> SPR 1175 1176def VMOVDRR : AVConv5I<0b11000100, 0b1011, 1177 (outs DPR:$Dm), (ins GPR:$Rt, GPR:$Rt2), 1178 IIC_fpMOVID, "vmov", "\t$Dm, $Rt, $Rt2", 1179 [(set DPR:$Dm, (arm_fmdrr GPR:$Rt, GPR:$Rt2))]>, 1180 Requires<[HasFPRegs]>, 1181 Sched<[WriteFPMOV]> { 1182 // Instruction operands. 1183 bits<5> Dm; 1184 bits<4> Rt; 1185 bits<4> Rt2; 1186 1187 // Encode instruction operands. 1188 let Inst{3-0} = Dm{3-0}; 1189 let Inst{5} = Dm{4}; 1190 let Inst{15-12} = Rt; 1191 let Inst{19-16} = Rt2; 1192 1193 let Inst{7-6} = 0b00; 1194 1195 // Some single precision VFP instructions may be executed on both NEON and VFP 1196 // pipelines. 1197 let D = VFPNeonDomain; 1198 1199 // This instruction is equivalent to 1200 // $Dm = REG_SEQUENCE $Rt, ssub_0, $Rt2, ssub_1 1201 let isRegSequence = 1; 1202} 1203 1204// Hoist an fabs or a fneg of a value coming from integer registers 1205// and do the fabs/fneg on the integer value. This is never a lose 1206// and could enable the conversion to float to be removed completely. 1207def : Pat<(fabs (arm_fmdrr GPR:$Rl, GPR:$Rh)), 1208 (VMOVDRR GPR:$Rl, (BFC GPR:$Rh, (i32 0x7FFFFFFF)))>, 1209 Requires<[IsARM, HasV6T2]>; 1210def : Pat<(fabs (arm_fmdrr GPR:$Rl, GPR:$Rh)), 1211 (VMOVDRR GPR:$Rl, (t2BFC GPR:$Rh, (i32 0x7FFFFFFF)))>, 1212 Requires<[IsThumb2, HasV6T2]>; 1213def : Pat<(fneg (arm_fmdrr GPR:$Rl, GPR:$Rh)), 1214 (VMOVDRR GPR:$Rl, (EORri GPR:$Rh, (i32 0x80000000)))>, 1215 Requires<[IsARM]>; 1216def : Pat<(fneg (arm_fmdrr GPR:$Rl, GPR:$Rh)), 1217 (VMOVDRR GPR:$Rl, (t2EORri GPR:$Rh, (i32 0x80000000)))>, 1218 Requires<[IsThumb2]>; 1219 1220let hasSideEffects = 0 in 1221def VMOVSRR : AVConv5I<0b11000100, 0b1010, 1222 (outs SPR:$dst1, SPR:$dst2), (ins GPR:$src1, GPR:$src2), 1223 IIC_fpMOVID, "vmov", "\t$dst1, $dst2, $src1, $src2", 1224 [/* For disassembly only; pattern left blank */]>, 1225 Requires<[HasFPRegs]>, 1226 Sched<[WriteFPMOV]> { 1227 // Instruction operands. 1228 bits<5> dst1; 1229 bits<4> src1; 1230 bits<4> src2; 1231 1232 // Encode instruction operands. 1233 let Inst{3-0} = dst1{4-1}; 1234 let Inst{5} = dst1{0}; 1235 let Inst{15-12} = src1; 1236 let Inst{19-16} = src2; 1237 1238 let Inst{7-6} = 0b00; 1239 1240 // Some single precision VFP instructions may be executed on both NEON and VFP 1241 // pipelines. 1242 let D = VFPNeonDomain; 1243 1244 let DecoderMethod = "DecodeVMOVSRR"; 1245} 1246 1247// Move H->R, clearing top 16 bits 1248def VMOVRH : AVConv2I<0b11100001, 0b1001, 1249 (outs rGPR:$Rt), (ins HPR:$Sn), 1250 IIC_fpMOVSI, "vmov", ".f16\t$Rt, $Sn", 1251 [(set rGPR:$Rt, (arm_vmovrh HPR:$Sn))]>, 1252 Requires<[HasFPRegs16]>, 1253 Sched<[WriteFPMOV]> { 1254 // Instruction operands. 1255 bits<4> Rt; 1256 bits<5> Sn; 1257 1258 // Encode instruction operands. 1259 let Inst{19-16} = Sn{4-1}; 1260 let Inst{7} = Sn{0}; 1261 let Inst{15-12} = Rt; 1262 1263 let Inst{6-5} = 0b00; 1264 let Inst{3-0} = 0b0000; 1265 1266 let isUnpredicable = 1; 1267} 1268 1269// Move R->H, clearing top 16 bits 1270def VMOVHR : AVConv4I<0b11100000, 0b1001, 1271 (outs HPR:$Sn), (ins rGPR:$Rt), 1272 IIC_fpMOVIS, "vmov", ".f16\t$Sn, $Rt", 1273 [(set HPR:$Sn, (arm_vmovhr rGPR:$Rt))]>, 1274 Requires<[HasFPRegs16]>, 1275 Sched<[WriteFPMOV]> { 1276 // Instruction operands. 1277 bits<5> Sn; 1278 bits<4> Rt; 1279 1280 // Encode instruction operands. 1281 let Inst{19-16} = Sn{4-1}; 1282 let Inst{7} = Sn{0}; 1283 let Inst{15-12} = Rt; 1284 1285 let Inst{6-5} = 0b00; 1286 let Inst{3-0} = 0b0000; 1287 1288 let isUnpredicable = 1; 1289} 1290 1291// FMRDH: SPR -> GPR 1292// FMRDL: SPR -> GPR 1293// FMRRS: SPR -> GPR 1294// FMRX: SPR system reg -> GPR 1295// FMSRR: GPR -> SPR 1296// FMXR: GPR -> VFP system reg 1297 1298 1299// Int -> FP: 1300 1301class AVConv1IDs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 1302 bits<4> opcod4, dag oops, dag iops, 1303 InstrItinClass itin, string opc, string asm, 1304 list<dag> pattern> 1305 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1306 pattern> { 1307 // Instruction operands. 1308 bits<5> Dd; 1309 bits<5> Sm; 1310 1311 // Encode instruction operands. 1312 let Inst{3-0} = Sm{4-1}; 1313 let Inst{5} = Sm{0}; 1314 let Inst{15-12} = Dd{3-0}; 1315 let Inst{22} = Dd{4}; 1316 1317 let Predicates = [HasVFP2, HasDPVFP]; 1318} 1319 1320class AVConv1InSs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 1321 bits<4> opcod4, dag oops, dag iops,InstrItinClass itin, 1322 string opc, string asm, list<dag> pattern> 1323 : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1324 pattern> { 1325 // Instruction operands. 1326 bits<5> Sd; 1327 bits<5> Sm; 1328 1329 // Encode instruction operands. 1330 let Inst{3-0} = Sm{4-1}; 1331 let Inst{5} = Sm{0}; 1332 let Inst{15-12} = Sd{4-1}; 1333 let Inst{22} = Sd{0}; 1334} 1335 1336class AVConv1IHs_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 1337 bits<4> opcod4, dag oops, dag iops, 1338 InstrItinClass itin, string opc, string asm, 1339 list<dag> pattern> 1340 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1341 pattern> { 1342 // Instruction operands. 1343 bits<5> Sd; 1344 bits<5> Sm; 1345 1346 // Encode instruction operands. 1347 let Inst{3-0} = Sm{4-1}; 1348 let Inst{5} = Sm{0}; 1349 let Inst{15-12} = Sd{4-1}; 1350 let Inst{22} = Sd{0}; 1351 1352 let Predicates = [HasFullFP16]; 1353} 1354 1355def VSITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011, 1356 (outs DPR:$Dd), (ins SPR:$Sm), 1357 IIC_fpCVTID, "vcvt", ".f64.s32\t$Dd, $Sm", 1358 []>, 1359 Sched<[WriteFPCVT]> { 1360 let Inst{7} = 1; // s32 1361} 1362 1363let Predicates=[HasVFP2, HasDPVFP] in { 1364 def : VFPPat<(f64 (sint_to_fp GPR:$a)), 1365 (VSITOD (COPY_TO_REGCLASS GPR:$a, SPR))>; 1366 1367 def : VFPPat<(f64 (sint_to_fp (i32 (alignedload32 addrmode5:$a)))), 1368 (VSITOD (VLDRS addrmode5:$a))>; 1369} 1370 1371def VSITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010, 1372 (outs SPR:$Sd),(ins SPR:$Sm), 1373 IIC_fpCVTIS, "vcvt", ".f32.s32\t$Sd, $Sm", 1374 []>, 1375 Sched<[WriteFPCVT]> { 1376 let Inst{7} = 1; // s32 1377 1378 // Some single precision VFP instructions may be executed on both NEON and 1379 // VFP pipelines on A8. 1380 let D = VFPNeonA8Domain; 1381} 1382 1383def : VFPNoNEONPat<(f32 (sint_to_fp GPR:$a)), 1384 (VSITOS (COPY_TO_REGCLASS GPR:$a, SPR))>; 1385 1386def : VFPNoNEONPat<(f32 (sint_to_fp (i32 (alignedload32 addrmode5:$a)))), 1387 (VSITOS (VLDRS addrmode5:$a))>; 1388 1389def VSITOH : AVConv1IHs_Encode<0b11101, 0b11, 0b1000, 0b1001, 1390 (outs HPR:$Sd), (ins SPR:$Sm), 1391 IIC_fpCVTIH, "vcvt", ".f16.s32\t$Sd, $Sm", 1392 []>, 1393 Sched<[WriteFPCVT]> { 1394 let Inst{7} = 1; // s32 1395 let isUnpredicable = 1; 1396} 1397 1398def : VFPNoNEONPat<(f16 (sint_to_fp GPR:$a)), 1399 (VSITOH (COPY_TO_REGCLASS GPR:$a, SPR))>; 1400 1401def VUITOD : AVConv1IDs_Encode<0b11101, 0b11, 0b1000, 0b1011, 1402 (outs DPR:$Dd), (ins SPR:$Sm), 1403 IIC_fpCVTID, "vcvt", ".f64.u32\t$Dd, $Sm", 1404 []>, 1405 Sched<[WriteFPCVT]> { 1406 let Inst{7} = 0; // u32 1407} 1408 1409let Predicates=[HasVFP2, HasDPVFP] in { 1410 def : VFPPat<(f64 (uint_to_fp GPR:$a)), 1411 (VUITOD (COPY_TO_REGCLASS GPR:$a, SPR))>; 1412 1413 def : VFPPat<(f64 (uint_to_fp (i32 (alignedload32 addrmode5:$a)))), 1414 (VUITOD (VLDRS addrmode5:$a))>; 1415} 1416 1417def VUITOS : AVConv1InSs_Encode<0b11101, 0b11, 0b1000, 0b1010, 1418 (outs SPR:$Sd), (ins SPR:$Sm), 1419 IIC_fpCVTIS, "vcvt", ".f32.u32\t$Sd, $Sm", 1420 []>, 1421 Sched<[WriteFPCVT]> { 1422 let Inst{7} = 0; // u32 1423 1424 // Some single precision VFP instructions may be executed on both NEON and 1425 // VFP pipelines on A8. 1426 let D = VFPNeonA8Domain; 1427} 1428 1429def : VFPNoNEONPat<(f32 (uint_to_fp GPR:$a)), 1430 (VUITOS (COPY_TO_REGCLASS GPR:$a, SPR))>; 1431 1432def : VFPNoNEONPat<(f32 (uint_to_fp (i32 (alignedload32 addrmode5:$a)))), 1433 (VUITOS (VLDRS addrmode5:$a))>; 1434 1435def VUITOH : AVConv1IHs_Encode<0b11101, 0b11, 0b1000, 0b1001, 1436 (outs HPR:$Sd), (ins SPR:$Sm), 1437 IIC_fpCVTIH, "vcvt", ".f16.u32\t$Sd, $Sm", 1438 []>, 1439 Sched<[WriteFPCVT]> { 1440 let Inst{7} = 0; // u32 1441 let isUnpredicable = 1; 1442} 1443 1444def : VFPNoNEONPat<(f16 (uint_to_fp GPR:$a)), 1445 (VUITOH (COPY_TO_REGCLASS GPR:$a, SPR))>; 1446 1447// FP -> Int: 1448 1449class AVConv1IsD_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 1450 bits<4> opcod4, dag oops, dag iops, 1451 InstrItinClass itin, string opc, string asm, 1452 list<dag> pattern> 1453 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1454 pattern> { 1455 // Instruction operands. 1456 bits<5> Sd; 1457 bits<5> Dm; 1458 1459 // Encode instruction operands. 1460 let Inst{3-0} = Dm{3-0}; 1461 let Inst{5} = Dm{4}; 1462 let Inst{15-12} = Sd{4-1}; 1463 let Inst{22} = Sd{0}; 1464 1465 let Predicates = [HasVFP2, HasDPVFP]; 1466} 1467 1468class AVConv1InsS_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 1469 bits<4> opcod4, dag oops, dag iops, 1470 InstrItinClass itin, string opc, string asm, 1471 list<dag> pattern> 1472 : AVConv1In<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1473 pattern> { 1474 // Instruction operands. 1475 bits<5> Sd; 1476 bits<5> Sm; 1477 1478 // Encode instruction operands. 1479 let Inst{3-0} = Sm{4-1}; 1480 let Inst{5} = Sm{0}; 1481 let Inst{15-12} = Sd{4-1}; 1482 let Inst{22} = Sd{0}; 1483} 1484 1485class AVConv1IsH_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 1486 bits<4> opcod4, dag oops, dag iops, 1487 InstrItinClass itin, string opc, string asm, 1488 list<dag> pattern> 1489 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1490 pattern> { 1491 // Instruction operands. 1492 bits<5> Sd; 1493 bits<5> Sm; 1494 1495 // Encode instruction operands. 1496 let Inst{3-0} = Sm{4-1}; 1497 let Inst{5} = Sm{0}; 1498 let Inst{15-12} = Sd{4-1}; 1499 let Inst{22} = Sd{0}; 1500 1501 let Predicates = [HasFullFP16]; 1502} 1503 1504// Always set Z bit in the instruction, i.e. "round towards zero" variants. 1505def VTOSIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011, 1506 (outs SPR:$Sd), (ins DPR:$Dm), 1507 IIC_fpCVTDI, "vcvt", ".s32.f64\t$Sd, $Dm", 1508 []>, 1509 Sched<[WriteFPCVT]> { 1510 let Inst{7} = 1; // Z bit 1511} 1512 1513let Predicates=[HasVFP2, HasDPVFP] in { 1514 def : VFPPat<(i32 (fp_to_sint (f64 DPR:$a))), 1515 (COPY_TO_REGCLASS (VTOSIZD DPR:$a), GPR)>; 1516 1517 def : VFPPat<(alignedstore32 (i32 (fp_to_sint (f64 DPR:$a))), addrmode5:$ptr), 1518 (VSTRS (VTOSIZD DPR:$a), addrmode5:$ptr)>; 1519} 1520 1521def VTOSIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010, 1522 (outs SPR:$Sd), (ins SPR:$Sm), 1523 IIC_fpCVTSI, "vcvt", ".s32.f32\t$Sd, $Sm", 1524 []>, 1525 Sched<[WriteFPCVT]> { 1526 let Inst{7} = 1; // Z bit 1527 1528 // Some single precision VFP instructions may be executed on both NEON and 1529 // VFP pipelines on A8. 1530 let D = VFPNeonA8Domain; 1531} 1532 1533def : VFPNoNEONPat<(i32 (fp_to_sint SPR:$a)), 1534 (COPY_TO_REGCLASS (VTOSIZS SPR:$a), GPR)>; 1535 1536def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_sint (f32 SPR:$a))), 1537 addrmode5:$ptr), 1538 (VSTRS (VTOSIZS SPR:$a), addrmode5:$ptr)>; 1539 1540def VTOSIZH : AVConv1IsH_Encode<0b11101, 0b11, 0b1101, 0b1001, 1541 (outs SPR:$Sd), (ins HPR:$Sm), 1542 IIC_fpCVTHI, "vcvt", ".s32.f16\t$Sd, $Sm", 1543 []>, 1544 Sched<[WriteFPCVT]> { 1545 let Inst{7} = 1; // Z bit 1546 let isUnpredicable = 1; 1547} 1548 1549def : VFPNoNEONPat<(i32 (fp_to_sint HPR:$a)), 1550 (COPY_TO_REGCLASS (VTOSIZH HPR:$a), GPR)>; 1551 1552def VTOUIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011, 1553 (outs SPR:$Sd), (ins DPR:$Dm), 1554 IIC_fpCVTDI, "vcvt", ".u32.f64\t$Sd, $Dm", 1555 []>, 1556 Sched<[WriteFPCVT]> { 1557 let Inst{7} = 1; // Z bit 1558} 1559 1560let Predicates=[HasVFP2, HasDPVFP] in { 1561 def : VFPPat<(i32 (fp_to_uint (f64 DPR:$a))), 1562 (COPY_TO_REGCLASS (VTOUIZD DPR:$a), GPR)>; 1563 1564 def : VFPPat<(alignedstore32 (i32 (fp_to_uint (f64 DPR:$a))), addrmode5:$ptr), 1565 (VSTRS (VTOUIZD DPR:$a), addrmode5:$ptr)>; 1566} 1567 1568def VTOUIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010, 1569 (outs SPR:$Sd), (ins SPR:$Sm), 1570 IIC_fpCVTSI, "vcvt", ".u32.f32\t$Sd, $Sm", 1571 []>, 1572 Sched<[WriteFPCVT]> { 1573 let Inst{7} = 1; // Z bit 1574 1575 // Some single precision VFP instructions may be executed on both NEON and 1576 // VFP pipelines on A8. 1577 let D = VFPNeonA8Domain; 1578} 1579 1580def : VFPNoNEONPat<(i32 (fp_to_uint SPR:$a)), 1581 (COPY_TO_REGCLASS (VTOUIZS SPR:$a), GPR)>; 1582 1583def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_uint (f32 SPR:$a))), 1584 addrmode5:$ptr), 1585 (VSTRS (VTOUIZS SPR:$a), addrmode5:$ptr)>; 1586 1587def VTOUIZH : AVConv1IsH_Encode<0b11101, 0b11, 0b1100, 0b1001, 1588 (outs SPR:$Sd), (ins HPR:$Sm), 1589 IIC_fpCVTHI, "vcvt", ".u32.f16\t$Sd, $Sm", 1590 []>, 1591 Sched<[WriteFPCVT]> { 1592 let Inst{7} = 1; // Z bit 1593 let isUnpredicable = 1; 1594} 1595 1596def : VFPNoNEONPat<(i32 (fp_to_uint HPR:$a)), 1597 (COPY_TO_REGCLASS (VTOUIZH HPR:$a), GPR)>; 1598 1599// And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR. 1600let Uses = [FPSCR] in { 1601def VTOSIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011, 1602 (outs SPR:$Sd), (ins DPR:$Dm), 1603 IIC_fpCVTDI, "vcvtr", ".s32.f64\t$Sd, $Dm", 1604 [(set SPR:$Sd, (int_arm_vcvtr (f64 DPR:$Dm)))]>, 1605 Sched<[WriteFPCVT]> { 1606 let Inst{7} = 0; // Z bit 1607} 1608 1609def VTOSIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010, 1610 (outs SPR:$Sd), (ins SPR:$Sm), 1611 IIC_fpCVTSI, "vcvtr", ".s32.f32\t$Sd, $Sm", 1612 [(set SPR:$Sd, (int_arm_vcvtr SPR:$Sm))]>, 1613 Sched<[WriteFPCVT]> { 1614 let Inst{7} = 0; // Z bit 1615} 1616 1617def VTOSIRH : AVConv1IsH_Encode<0b11101, 0b11, 0b1101, 0b1001, 1618 (outs SPR:$Sd), (ins SPR:$Sm), 1619 IIC_fpCVTHI, "vcvtr", ".s32.f16\t$Sd, $Sm", 1620 []>, 1621 Sched<[WriteFPCVT]> { 1622 let Inst{7} = 0; // Z bit 1623 let isUnpredicable = 1; 1624} 1625 1626def VTOUIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011, 1627 (outs SPR:$Sd), (ins DPR:$Dm), 1628 IIC_fpCVTDI, "vcvtr", ".u32.f64\t$Sd, $Dm", 1629 [(set SPR:$Sd, (int_arm_vcvtru(f64 DPR:$Dm)))]>, 1630 Sched<[WriteFPCVT]> { 1631 let Inst{7} = 0; // Z bit 1632} 1633 1634def VTOUIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010, 1635 (outs SPR:$Sd), (ins SPR:$Sm), 1636 IIC_fpCVTSI, "vcvtr", ".u32.f32\t$Sd, $Sm", 1637 [(set SPR:$Sd, (int_arm_vcvtru SPR:$Sm))]>, 1638 Sched<[WriteFPCVT]> { 1639 let Inst{7} = 0; // Z bit 1640} 1641 1642def VTOUIRH : AVConv1IsH_Encode<0b11101, 0b11, 0b1100, 0b1001, 1643 (outs SPR:$Sd), (ins SPR:$Sm), 1644 IIC_fpCVTHI, "vcvtr", ".u32.f16\t$Sd, $Sm", 1645 []>, 1646 Sched<[WriteFPCVT]> { 1647 let Inst{7} = 0; // Z bit 1648 let isUnpredicable = 1; 1649} 1650} 1651 1652// v8.3-a Javascript Convert to Signed fixed-point 1653def VJCVT : AVConv1IsD_Encode<0b11101, 0b11, 0b1001, 0b1011, 1654 (outs SPR:$Sd), (ins DPR:$Dm), 1655 IIC_fpCVTDI, "vjcvt", ".s32.f64\t$Sd, $Dm", 1656 []>, 1657 Requires<[HasFPARMv8, HasV8_3a]> { 1658 let Inst{7} = 1; // Z bit 1659} 1660 1661// Convert between floating-point and fixed-point 1662// Data type for fixed-point naming convention: 1663// S16 (U=0, sx=0) -> SH 1664// U16 (U=1, sx=0) -> UH 1665// S32 (U=0, sx=1) -> SL 1666// U32 (U=1, sx=1) -> UL 1667 1668let Constraints = "$a = $dst" in { 1669 1670// FP to Fixed-Point: 1671 1672// Single Precision register 1673class AVConv1XInsS_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, 1674 bit op5, dag oops, dag iops, InstrItinClass itin, 1675 string opc, string asm, list<dag> pattern> 1676 : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern> { 1677 bits<5> dst; 1678 // if dp_operation then UInt(D:Vd) else UInt(Vd:D); 1679 let Inst{22} = dst{0}; 1680 let Inst{15-12} = dst{4-1}; 1681} 1682 1683// Double Precision register 1684class AVConv1XInsD_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, 1685 bit op5, dag oops, dag iops, InstrItinClass itin, 1686 string opc, string asm, list<dag> pattern> 1687 : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern> { 1688 bits<5> dst; 1689 // if dp_operation then UInt(D:Vd) else UInt(Vd:D); 1690 let Inst{22} = dst{4}; 1691 let Inst{15-12} = dst{3-0}; 1692 1693 let Predicates = [HasVFP2, HasDPVFP]; 1694} 1695 1696let isUnpredicable = 1 in { 1697 1698def VTOSHH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1001, 0, 1699 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1700 IIC_fpCVTHI, "vcvt", ".s16.f16\t$dst, $a, $fbits", []>, 1701 Requires<[HasFullFP16]>, 1702 Sched<[WriteFPCVT]>; 1703 1704def VTOUHH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1001, 0, 1705 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1706 IIC_fpCVTHI, "vcvt", ".u16.f16\t$dst, $a, $fbits", []>, 1707 Requires<[HasFullFP16]>, 1708 Sched<[WriteFPCVT]>; 1709 1710def VTOSLH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1001, 1, 1711 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1712 IIC_fpCVTHI, "vcvt", ".s32.f16\t$dst, $a, $fbits", []>, 1713 Requires<[HasFullFP16]>, 1714 Sched<[WriteFPCVT]>; 1715 1716def VTOULH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1001, 1, 1717 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1718 IIC_fpCVTHI, "vcvt", ".u32.f16\t$dst, $a, $fbits", []>, 1719 Requires<[HasFullFP16]>, 1720 Sched<[WriteFPCVT]>; 1721 1722} // End of 'let isUnpredicable = 1 in' 1723 1724def VTOSHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 0, 1725 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1726 IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits", []>, 1727 Sched<[WriteFPCVT]> { 1728 // Some single precision VFP instructions may be executed on both NEON and 1729 // VFP pipelines on A8. 1730 let D = VFPNeonA8Domain; 1731} 1732 1733def VTOUHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 0, 1734 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1735 IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits", []> { 1736 // Some single precision VFP instructions may be executed on both NEON and 1737 // VFP pipelines on A8. 1738 let D = VFPNeonA8Domain; 1739} 1740 1741def VTOSLS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 1, 1742 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1743 IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits", []> { 1744 // Some single precision VFP instructions may be executed on both NEON and 1745 // VFP pipelines on A8. 1746 let D = VFPNeonA8Domain; 1747} 1748 1749def VTOULS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 1, 1750 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1751 IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits", []> { 1752 // Some single precision VFP instructions may be executed on both NEON and 1753 // VFP pipelines on A8. 1754 let D = VFPNeonA8Domain; 1755} 1756 1757def VTOSHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 0, 1758 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1759 IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits", []>, 1760 Sched<[WriteFPCVT]>; 1761 1762def VTOUHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 0, 1763 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1764 IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits", []>, 1765 Sched<[WriteFPCVT]>; 1766 1767def VTOSLD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 1, 1768 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1769 IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits", []>, 1770 Sched<[WriteFPCVT]>; 1771 1772def VTOULD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 1, 1773 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1774 IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits", []>, 1775 Sched<[WriteFPCVT]>; 1776 1777// Fixed-Point to FP: 1778 1779let isUnpredicable = 1 in { 1780 1781def VSHTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1001, 0, 1782 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1783 IIC_fpCVTIH, "vcvt", ".f16.s16\t$dst, $a, $fbits", []>, 1784 Requires<[HasFullFP16]>, 1785 Sched<[WriteFPCVT]>; 1786 1787def VUHTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1001, 0, 1788 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1789 IIC_fpCVTIH, "vcvt", ".f16.u16\t$dst, $a, $fbits", []>, 1790 Requires<[HasFullFP16]>, 1791 Sched<[WriteFPCVT]>; 1792 1793def VSLTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1001, 1, 1794 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1795 IIC_fpCVTIH, "vcvt", ".f16.s32\t$dst, $a, $fbits", []>, 1796 Requires<[HasFullFP16]>, 1797 Sched<[WriteFPCVT]>; 1798 1799def VULTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1001, 1, 1800 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1801 IIC_fpCVTIH, "vcvt", ".f16.u32\t$dst, $a, $fbits", []>, 1802 Requires<[HasFullFP16]>, 1803 Sched<[WriteFPCVT]>; 1804 1805} // End of 'let isUnpredicable = 1 in' 1806 1807def VSHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 0, 1808 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1809 IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits", []>, 1810 Sched<[WriteFPCVT]> { 1811 // Some single precision VFP instructions may be executed on both NEON and 1812 // VFP pipelines on A8. 1813 let D = VFPNeonA8Domain; 1814} 1815 1816def VUHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 0, 1817 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1818 IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits", []>, 1819 Sched<[WriteFPCVT]> { 1820 // Some single precision VFP instructions may be executed on both NEON and 1821 // VFP pipelines on A8. 1822 let D = VFPNeonA8Domain; 1823} 1824 1825def VSLTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 1, 1826 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1827 IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits", []>, 1828 Sched<[WriteFPCVT]> { 1829 // Some single precision VFP instructions may be executed on both NEON and 1830 // VFP pipelines on A8. 1831 let D = VFPNeonA8Domain; 1832} 1833 1834def VULTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 1, 1835 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1836 IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits", []>, 1837 Sched<[WriteFPCVT]> { 1838 // Some single precision VFP instructions may be executed on both NEON and 1839 // VFP pipelines on A8. 1840 let D = VFPNeonA8Domain; 1841} 1842 1843def VSHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 0, 1844 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1845 IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits", []>, 1846 Sched<[WriteFPCVT]>; 1847 1848def VUHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 0, 1849 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1850 IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits", []>, 1851 Sched<[WriteFPCVT]>; 1852 1853def VSLTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 1, 1854 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1855 IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits", []>, 1856 Sched<[WriteFPCVT]>; 1857 1858def VULTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 1, 1859 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1860 IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits", []>, 1861 Sched<[WriteFPCVT]>; 1862 1863} // End of 'let Constraints = "$a = $dst" in' 1864 1865//===----------------------------------------------------------------------===// 1866// FP Multiply-Accumulate Operations. 1867// 1868 1869def VMLAD : ADbI<0b11100, 0b00, 0, 0, 1870 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1871 IIC_fpMAC64, "vmla", ".f64\t$Dd, $Dn, $Dm", 1872 [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm), 1873 (f64 DPR:$Ddin)))]>, 1874 RegConstraint<"$Ddin = $Dd">, 1875 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>, 1876 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 1877 1878def VMLAS : ASbIn<0b11100, 0b00, 0, 0, 1879 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1880 IIC_fpMAC32, "vmla", ".f32\t$Sd, $Sn, $Sm", 1881 [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm), 1882 SPR:$Sdin))]>, 1883 RegConstraint<"$Sdin = $Sd">, 1884 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>, 1885 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 1886 // Some single precision VFP instructions may be executed on both NEON and 1887 // VFP pipelines on A8. 1888 let D = VFPNeonA8Domain; 1889} 1890 1891def VMLAH : AHbI<0b11100, 0b00, 0, 0, 1892 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 1893 IIC_fpMAC16, "vmla", ".f16\t$Sd, $Sn, $Sm", 1894 [(set HPR:$Sd, (fadd_mlx (fmul_su HPR:$Sn, HPR:$Sm), 1895 HPR:$Sdin))]>, 1896 RegConstraint<"$Sdin = $Sd">, 1897 Requires<[HasFullFP16,UseFPVMLx]>; 1898 1899def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 1900 (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>, 1901 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 1902def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 1903 (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>, 1904 Requires<[HasVFP2,DontUseNEONForFP, UseFPVMLx]>; 1905def : Pat<(fadd_mlx HPR:$dstin, (fmul_su HPR:$a, HPR:$b)), 1906 (VMLAH HPR:$dstin, HPR:$a, HPR:$b)>, 1907 Requires<[HasFullFP16,DontUseNEONForFP, UseFPVMLx]>; 1908 1909 1910def VMLSD : ADbI<0b11100, 0b00, 1, 0, 1911 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1912 IIC_fpMAC64, "vmls", ".f64\t$Dd, $Dn, $Dm", 1913 [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 1914 (f64 DPR:$Ddin)))]>, 1915 RegConstraint<"$Ddin = $Dd">, 1916 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>, 1917 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 1918 1919def VMLSS : ASbIn<0b11100, 0b00, 1, 0, 1920 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1921 IIC_fpMAC32, "vmls", ".f32\t$Sd, $Sn, $Sm", 1922 [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 1923 SPR:$Sdin))]>, 1924 RegConstraint<"$Sdin = $Sd">, 1925 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>, 1926 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 1927 // Some single precision VFP instructions may be executed on both NEON and 1928 // VFP pipelines on A8. 1929 let D = VFPNeonA8Domain; 1930} 1931 1932def VMLSH : AHbI<0b11100, 0b00, 1, 0, 1933 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 1934 IIC_fpMAC16, "vmls", ".f16\t$Sd, $Sn, $Sm", 1935 [(set HPR:$Sd, (fadd_mlx (fneg (fmul_su HPR:$Sn, HPR:$Sm)), 1936 HPR:$Sdin))]>, 1937 RegConstraint<"$Sdin = $Sd">, 1938 Requires<[HasFullFP16,UseFPVMLx]>; 1939 1940def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 1941 (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, 1942 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 1943def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 1944 (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, 1945 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>; 1946def : Pat<(fsub_mlx HPR:$dstin, (fmul_su HPR:$a, HPR:$b)), 1947 (VMLSH HPR:$dstin, HPR:$a, HPR:$b)>, 1948 Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>; 1949 1950def VNMLAD : ADbI<0b11100, 0b01, 1, 0, 1951 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1952 IIC_fpMAC64, "vnmla", ".f64\t$Dd, $Dn, $Dm", 1953 [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 1954 (f64 DPR:$Ddin)))]>, 1955 RegConstraint<"$Ddin = $Dd">, 1956 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>, 1957 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 1958 1959def VNMLAS : ASbI<0b11100, 0b01, 1, 0, 1960 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1961 IIC_fpMAC32, "vnmla", ".f32\t$Sd, $Sn, $Sm", 1962 [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 1963 SPR:$Sdin))]>, 1964 RegConstraint<"$Sdin = $Sd">, 1965 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>, 1966 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 1967 // Some single precision VFP instructions may be executed on both NEON and 1968 // VFP pipelines on A8. 1969 let D = VFPNeonA8Domain; 1970} 1971 1972def VNMLAH : AHbI<0b11100, 0b01, 1, 0, 1973 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 1974 IIC_fpMAC16, "vnmla", ".f16\t$Sd, $Sn, $Sm", 1975 [(set HPR:$Sd, (fsub_mlx (fneg (fmul_su HPR:$Sn, HPR:$Sm)), 1976 HPR:$Sdin))]>, 1977 RegConstraint<"$Sdin = $Sd">, 1978 Requires<[HasFullFP16,UseFPVMLx]>; 1979 1980// (-(a * b) - dst) -> -(dst + (a * b)) 1981def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin), 1982 (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>, 1983 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 1984def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), 1985 (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>, 1986 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>; 1987def : Pat<(fsub_mlx (fneg (fmul_su HPR:$a, HPR:$b)), HPR:$dstin), 1988 (VNMLAH HPR:$dstin, HPR:$a, HPR:$b)>, 1989 Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>; 1990 1991// (-dst - (a * b)) -> -(dst + (a * b)) 1992def : Pat<(fsub_mlx (fneg DPR:$dstin), (fmul_su DPR:$a, (f64 DPR:$b))), 1993 (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>, 1994 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 1995def : Pat<(fsub_mlx (fneg SPR:$dstin), (fmul_su SPR:$a, SPR:$b)), 1996 (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>, 1997 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>; 1998def : Pat<(fsub_mlx (fneg HPR:$dstin), (fmul_su HPR:$a, HPR:$b)), 1999 (VNMLAH HPR:$dstin, HPR:$a, HPR:$b)>, 2000 Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>; 2001 2002def VNMLSD : ADbI<0b11100, 0b01, 0, 0, 2003 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2004 IIC_fpMAC64, "vnmls", ".f64\t$Dd, $Dn, $Dm", 2005 [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm), 2006 (f64 DPR:$Ddin)))]>, 2007 RegConstraint<"$Ddin = $Dd">, 2008 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>, 2009 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2010 2011def VNMLSS : ASbI<0b11100, 0b01, 0, 0, 2012 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2013 IIC_fpMAC32, "vnmls", ".f32\t$Sd, $Sn, $Sm", 2014 [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>, 2015 RegConstraint<"$Sdin = $Sd">, 2016 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>, 2017 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2018 // Some single precision VFP instructions may be executed on both NEON and 2019 // VFP pipelines on A8. 2020 let D = VFPNeonA8Domain; 2021} 2022 2023def VNMLSH : AHbI<0b11100, 0b01, 0, 0, 2024 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2025 IIC_fpMAC16, "vnmls", ".f16\t$Sd, $Sn, $Sm", 2026 [(set HPR:$Sd, (fsub_mlx (fmul_su HPR:$Sn, HPR:$Sm), HPR:$Sdin))]>, 2027 RegConstraint<"$Sdin = $Sd">, 2028 Requires<[HasFullFP16,UseFPVMLx]>; 2029 2030def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin), 2031 (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>, 2032 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 2033def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), 2034 (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>, 2035 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>; 2036def : Pat<(fsub_mlx (fmul_su HPR:$a, HPR:$b), HPR:$dstin), 2037 (VNMLSH HPR:$dstin, HPR:$a, HPR:$b)>, 2038 Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>; 2039 2040//===----------------------------------------------------------------------===// 2041// Fused FP Multiply-Accumulate Operations. 2042// 2043def VFMAD : ADbI<0b11101, 0b10, 0, 0, 2044 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2045 IIC_fpFMAC64, "vfma", ".f64\t$Dd, $Dn, $Dm", 2046 [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm), 2047 (f64 DPR:$Ddin)))]>, 2048 RegConstraint<"$Ddin = $Dd">, 2049 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>, 2050 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2051 2052def VFMAS : ASbIn<0b11101, 0b10, 0, 0, 2053 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2054 IIC_fpFMAC32, "vfma", ".f32\t$Sd, $Sn, $Sm", 2055 [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm), 2056 SPR:$Sdin))]>, 2057 RegConstraint<"$Sdin = $Sd">, 2058 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>, 2059 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2060 // Some single precision VFP instructions may be executed on both NEON and 2061 // VFP pipelines. 2062} 2063 2064def VFMAH : AHbI<0b11101, 0b10, 0, 0, 2065 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2066 IIC_fpFMAC16, "vfma", ".f16\t$Sd, $Sn, $Sm", 2067 [(set HPR:$Sd, (fadd_mlx (fmul_su HPR:$Sn, HPR:$Sm), 2068 HPR:$Sdin))]>, 2069 RegConstraint<"$Sdin = $Sd">, 2070 Requires<[HasFullFP16,UseFusedMAC]>, 2071 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2072 2073def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 2074 (VFMAD DPR:$dstin, DPR:$a, DPR:$b)>, 2075 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 2076def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 2077 (VFMAS SPR:$dstin, SPR:$a, SPR:$b)>, 2078 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 2079def : Pat<(fadd_mlx HPR:$dstin, (fmul_su HPR:$a, HPR:$b)), 2080 (VFMAH HPR:$dstin, HPR:$a, HPR:$b)>, 2081 Requires<[HasFullFP16,DontUseNEONForFP,UseFusedMAC]>; 2082 2083// Match @llvm.fma.* intrinsics 2084// (fma x, y, z) -> (vfms z, x, y) 2085def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, DPR:$Ddin)), 2086 (VFMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2087 Requires<[HasVFP4,HasDPVFP]>; 2088def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, SPR:$Sdin)), 2089 (VFMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2090 Requires<[HasVFP4]>; 2091def : Pat<(f16 (fma HPR:$Sn, HPR:$Sm, HPR:$Sdin)), 2092 (VFMAH HPR:$Sdin, HPR:$Sn, HPR:$Sm)>, 2093 Requires<[HasFullFP16]>; 2094 2095def VFMSD : ADbI<0b11101, 0b10, 1, 0, 2096 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2097 IIC_fpFMAC64, "vfms", ".f64\t$Dd, $Dn, $Dm", 2098 [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 2099 (f64 DPR:$Ddin)))]>, 2100 RegConstraint<"$Ddin = $Dd">, 2101 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>, 2102 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2103 2104def VFMSS : ASbIn<0b11101, 0b10, 1, 0, 2105 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2106 IIC_fpFMAC32, "vfms", ".f32\t$Sd, $Sn, $Sm", 2107 [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 2108 SPR:$Sdin))]>, 2109 RegConstraint<"$Sdin = $Sd">, 2110 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>, 2111 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2112 // Some single precision VFP instructions may be executed on both NEON and 2113 // VFP pipelines. 2114} 2115 2116def VFMSH : AHbI<0b11101, 0b10, 1, 0, 2117 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2118 IIC_fpFMAC16, "vfms", ".f16\t$Sd, $Sn, $Sm", 2119 [(set HPR:$Sd, (fadd_mlx (fneg (fmul_su HPR:$Sn, HPR:$Sm)), 2120 HPR:$Sdin))]>, 2121 RegConstraint<"$Sdin = $Sd">, 2122 Requires<[HasFullFP16,UseFusedMAC]>, 2123 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2124 2125def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 2126 (VFMSD DPR:$dstin, DPR:$a, DPR:$b)>, 2127 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 2128def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 2129 (VFMSS SPR:$dstin, SPR:$a, SPR:$b)>, 2130 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 2131def : Pat<(fsub_mlx HPR:$dstin, (fmul_su HPR:$a, HPR:$b)), 2132 (VFMSH HPR:$dstin, HPR:$a, HPR:$b)>, 2133 Requires<[HasFullFP16,DontUseNEONForFP,UseFusedMAC]>; 2134 2135// Match @llvm.fma.* intrinsics 2136// (fma (fneg x), y, z) -> (vfms z, x, y) 2137def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin)), 2138 (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2139 Requires<[HasVFP4,HasDPVFP]>; 2140def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin)), 2141 (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2142 Requires<[HasVFP4]>; 2143// (fma x, (fneg y), z) -> (vfms z, x, y) 2144def : Pat<(f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin)), 2145 (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2146 Requires<[HasVFP4,HasDPVFP]>; 2147def : Pat<(f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin)), 2148 (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2149 Requires<[HasVFP4]>; 2150 2151def VFNMAD : ADbI<0b11101, 0b01, 1, 0, 2152 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2153 IIC_fpFMAC64, "vfnma", ".f64\t$Dd, $Dn, $Dm", 2154 [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 2155 (f64 DPR:$Ddin)))]>, 2156 RegConstraint<"$Ddin = $Dd">, 2157 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>, 2158 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2159 2160def VFNMAS : ASbI<0b11101, 0b01, 1, 0, 2161 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2162 IIC_fpFMAC32, "vfnma", ".f32\t$Sd, $Sn, $Sm", 2163 [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 2164 SPR:$Sdin))]>, 2165 RegConstraint<"$Sdin = $Sd">, 2166 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>, 2167 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2168 // Some single precision VFP instructions may be executed on both NEON and 2169 // VFP pipelines. 2170} 2171 2172def VFNMAH : AHbI<0b11101, 0b01, 1, 0, 2173 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2174 IIC_fpFMAC16, "vfnma", ".f16\t$Sd, $Sn, $Sm", 2175 [(set HPR:$Sd, (fsub_mlx (fneg (fmul_su HPR:$Sn, HPR:$Sm)), 2176 HPR:$Sdin))]>, 2177 RegConstraint<"$Sdin = $Sd">, 2178 Requires<[HasFullFP16,UseFusedMAC]>, 2179 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2180 2181def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin), 2182 (VFNMAD DPR:$dstin, DPR:$a, DPR:$b)>, 2183 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 2184def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), 2185 (VFNMAS SPR:$dstin, SPR:$a, SPR:$b)>, 2186 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 2187 2188// Match @llvm.fma.* intrinsics 2189// (fneg (fma x, y, z)) -> (vfnma z, x, y) 2190def : Pat<(fneg (fma (f64 DPR:$Dn), (f64 DPR:$Dm), (f64 DPR:$Ddin))), 2191 (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2192 Requires<[HasVFP4,HasDPVFP]>; 2193def : Pat<(fneg (fma (f32 SPR:$Sn), (f32 SPR:$Sm), (f32 SPR:$Sdin))), 2194 (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2195 Requires<[HasVFP4]>; 2196// (fma (fneg x), y, (fneg z)) -> (vfnma z, x, y) 2197def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, (fneg DPR:$Ddin))), 2198 (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2199 Requires<[HasVFP4,HasDPVFP]>; 2200def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, (fneg SPR:$Sdin))), 2201 (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2202 Requires<[HasVFP4]>; 2203 2204def VFNMSD : ADbI<0b11101, 0b01, 0, 0, 2205 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2206 IIC_fpFMAC64, "vfnms", ".f64\t$Dd, $Dn, $Dm", 2207 [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm), 2208 (f64 DPR:$Ddin)))]>, 2209 RegConstraint<"$Ddin = $Dd">, 2210 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>, 2211 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2212 2213def VFNMSS : ASbI<0b11101, 0b01, 0, 0, 2214 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2215 IIC_fpFMAC32, "vfnms", ".f32\t$Sd, $Sn, $Sm", 2216 [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>, 2217 RegConstraint<"$Sdin = $Sd">, 2218 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>, 2219 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2220 // Some single precision VFP instructions may be executed on both NEON and 2221 // VFP pipelines. 2222} 2223 2224def VFNMSH : AHbI<0b11101, 0b01, 0, 0, 2225 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2226 IIC_fpFMAC16, "vfnms", ".f16\t$Sd, $Sn, $Sm", 2227 [(set HPR:$Sd, (fsub_mlx (fmul_su HPR:$Sn, HPR:$Sm), HPR:$Sdin))]>, 2228 RegConstraint<"$Sdin = $Sd">, 2229 Requires<[HasFullFP16,UseFusedMAC]>, 2230 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2231 2232def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin), 2233 (VFNMSD DPR:$dstin, DPR:$a, DPR:$b)>, 2234 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 2235def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), 2236 (VFNMSS SPR:$dstin, SPR:$a, SPR:$b)>, 2237 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 2238 2239// Match @llvm.fma.* intrinsics 2240 2241// (fma x, y, (fneg z)) -> (vfnms z, x, y)) 2242def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, (fneg DPR:$Ddin))), 2243 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2244 Requires<[HasVFP4,HasDPVFP]>; 2245def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, (fneg SPR:$Sdin))), 2246 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2247 Requires<[HasVFP4]>; 2248// (fneg (fma (fneg x), y, z)) -> (vfnms z, x, y) 2249def : Pat<(fneg (f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin))), 2250 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2251 Requires<[HasVFP4,HasDPVFP]>; 2252def : Pat<(fneg (f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin))), 2253 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2254 Requires<[HasVFP4]>; 2255// (fneg (fma x, (fneg y), z) -> (vfnms z, x, y) 2256def : Pat<(fneg (f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin))), 2257 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2258 Requires<[HasVFP4,HasDPVFP]>; 2259def : Pat<(fneg (f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin))), 2260 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2261 Requires<[HasVFP4]>; 2262 2263//===----------------------------------------------------------------------===// 2264// FP Conditional moves. 2265// 2266 2267let hasSideEffects = 0 in { 2268def VMOVDcc : PseudoInst<(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm, cmovpred:$p), 2269 IIC_fpUNA64, 2270 [(set (f64 DPR:$Dd), 2271 (ARMcmov DPR:$Dn, DPR:$Dm, cmovpred:$p))]>, 2272 RegConstraint<"$Dn = $Dd">, Requires<[HasFPRegs64]>; 2273 2274def VMOVScc : PseudoInst<(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm, cmovpred:$p), 2275 IIC_fpUNA32, 2276 [(set (f32 SPR:$Sd), 2277 (ARMcmov SPR:$Sn, SPR:$Sm, cmovpred:$p))]>, 2278 RegConstraint<"$Sn = $Sd">, Requires<[HasFPRegs]>; 2279} // hasSideEffects 2280 2281//===----------------------------------------------------------------------===// 2282// Move from VFP System Register to ARM core register. 2283// 2284 2285class MovFromVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm, 2286 list<dag> pattern>: 2287 VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> { 2288 2289 // Instruction operand. 2290 bits<4> Rt; 2291 2292 let Inst{27-20} = 0b11101111; 2293 let Inst{19-16} = opc19_16; 2294 let Inst{15-12} = Rt; 2295 let Inst{11-8} = 0b1010; 2296 let Inst{7} = 0; 2297 let Inst{6-5} = 0b00; 2298 let Inst{4} = 1; 2299 let Inst{3-0} = 0b0000; 2300} 2301 2302let DecoderMethod = "DecodeForVMRSandVMSR" in { 2303 // APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags 2304 // to APSR. 2305 let Defs = [CPSR], Uses = [FPSCR_NZCV], Predicates = [HasFPRegs], 2306 Rt = 0b1111 /* apsr_nzcv */ in 2307 def FMSTAT : MovFromVFP<0b0001 /* fpscr */, (outs), (ins), 2308 "vmrs", "\tAPSR_nzcv, fpscr", [(arm_fmstat)]>; 2309 2310 // Application level FPSCR -> GPR 2311 let hasSideEffects = 1, Uses = [FPSCR], Predicates = [HasFPRegs] in 2312 def VMRS : MovFromVFP<0b0001 /* fpscr */, (outs GPRnopc:$Rt), (ins), 2313 "vmrs", "\t$Rt, fpscr", 2314 [(set GPRnopc:$Rt, (int_arm_get_fpscr))]>; 2315 2316 // System level FPEXC, FPSID -> GPR 2317 let Uses = [FPSCR] in { 2318 def VMRS_FPEXC : MovFromVFP<0b1000 /* fpexc */, (outs GPRnopc:$Rt), (ins), 2319 "vmrs", "\t$Rt, fpexc", []>; 2320 def VMRS_FPSID : MovFromVFP<0b0000 /* fpsid */, (outs GPRnopc:$Rt), (ins), 2321 "vmrs", "\t$Rt, fpsid", []>; 2322 def VMRS_MVFR0 : MovFromVFP<0b0111 /* mvfr0 */, (outs GPRnopc:$Rt), (ins), 2323 "vmrs", "\t$Rt, mvfr0", []>; 2324 def VMRS_MVFR1 : MovFromVFP<0b0110 /* mvfr1 */, (outs GPRnopc:$Rt), (ins), 2325 "vmrs", "\t$Rt, mvfr1", []>; 2326 let Predicates = [HasFPARMv8] in { 2327 def VMRS_MVFR2 : MovFromVFP<0b0101 /* mvfr2 */, (outs GPRnopc:$Rt), (ins), 2328 "vmrs", "\t$Rt, mvfr2", []>; 2329 } 2330 def VMRS_FPINST : MovFromVFP<0b1001 /* fpinst */, (outs GPRnopc:$Rt), (ins), 2331 "vmrs", "\t$Rt, fpinst", []>; 2332 def VMRS_FPINST2 : MovFromVFP<0b1010 /* fpinst2 */, (outs GPRnopc:$Rt), 2333 (ins), "vmrs", "\t$Rt, fpinst2", []>; 2334 let Predicates = [HasV8_1MMainline, HasFPRegs] in { 2335 // System level FPSCR_NZCVQC -> GPR 2336 def VMRS_FPSCR_NZCVQC 2337 : MovFromVFP<0b0010 /* fpscr_nzcvqc */, 2338 (outs GPR:$Rt), (ins cl_FPSCR_NZCV:$fpscr_in), 2339 "vmrs", "\t$Rt, fpscr_nzcvqc", []>; 2340 } 2341 } 2342 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2343 // System level FPSCR -> GPR, with context saving for security extensions 2344 def VMRS_FPCXTNS : MovFromVFP<0b1110 /* fpcxtns */, (outs GPR:$Rt), (ins), 2345 "vmrs", "\t$Rt, fpcxtns", []>; 2346 } 2347 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2348 // System level FPSCR -> GPR, with context saving for security extensions 2349 def VMRS_FPCXTS : MovFromVFP<0b1111 /* fpcxts */, (outs GPR:$Rt), (ins), 2350 "vmrs", "\t$Rt, fpcxts", []>; 2351 } 2352 2353 let Predicates = [HasV8_1MMainline, HasMVEInt] in { 2354 // System level VPR/P0 -> GPR 2355 let Uses = [VPR] in 2356 def VMRS_VPR : MovFromVFP<0b1100 /* vpr */, (outs GPR:$Rt), (ins), 2357 "vmrs", "\t$Rt, vpr", []>; 2358 2359 def VMRS_P0 : MovFromVFP<0b1101 /* p0 */, (outs GPR:$Rt), (ins VCCR:$cond), 2360 "vmrs", "\t$Rt, p0", []>; 2361 } 2362} 2363 2364//===----------------------------------------------------------------------===// 2365// Move from ARM core register to VFP System Register. 2366// 2367 2368class MovToVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm, 2369 list<dag> pattern>: 2370 VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> { 2371 2372 // Instruction operand. 2373 bits<4> src; 2374 2375 // Encode instruction operand. 2376 let Inst{15-12} = src; 2377 2378 let Inst{27-20} = 0b11101110; 2379 let Inst{19-16} = opc19_16; 2380 let Inst{11-8} = 0b1010; 2381 let Inst{7} = 0; 2382 let Inst{4} = 1; 2383 let Predicates = [HasVFP2]; 2384} 2385 2386let DecoderMethod = "DecodeForVMRSandVMSR" in { 2387 let Defs = [FPSCR] in { 2388 let Predicates = [HasFPRegs] in 2389 // Application level GPR -> FPSCR 2390 def VMSR : MovToVFP<0b0001 /* fpscr */, (outs), (ins GPRnopc:$src), 2391 "vmsr", "\tfpscr, $src", 2392 [(int_arm_set_fpscr GPRnopc:$src)]>; 2393 // System level GPR -> FPEXC 2394 def VMSR_FPEXC : MovToVFP<0b1000 /* fpexc */, (outs), (ins GPRnopc:$src), 2395 "vmsr", "\tfpexc, $src", []>; 2396 // System level GPR -> FPSID 2397 def VMSR_FPSID : MovToVFP<0b0000 /* fpsid */, (outs), (ins GPRnopc:$src), 2398 "vmsr", "\tfpsid, $src", []>; 2399 def VMSR_FPINST : MovToVFP<0b1001 /* fpinst */, (outs), (ins GPRnopc:$src), 2400 "vmsr", "\tfpinst, $src", []>; 2401 def VMSR_FPINST2 : MovToVFP<0b1010 /* fpinst2 */, (outs), (ins GPRnopc:$src), 2402 "vmsr", "\tfpinst2, $src", []>; 2403 } 2404 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2405 // System level GPR -> FPSCR with context saving for security extensions 2406 def VMSR_FPCXTNS : MovToVFP<0b1110 /* fpcxtns */, (outs), (ins GPR:$src), 2407 "vmsr", "\tfpcxtns, $src", []>; 2408 } 2409 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2410 // System level GPR -> FPSCR with context saving for security extensions 2411 def VMSR_FPCXTS : MovToVFP<0b1111 /* fpcxts */, (outs), (ins GPR:$src), 2412 "vmsr", "\tfpcxts, $src", []>; 2413 } 2414 let Predicates = [HasV8_1MMainline, HasFPRegs] in { 2415 // System level GPR -> FPSCR_NZCVQC 2416 def VMSR_FPSCR_NZCVQC 2417 : MovToVFP<0b0010 /* fpscr_nzcvqc */, 2418 (outs cl_FPSCR_NZCV:$fpscr_out), (ins GPR:$src), 2419 "vmsr", "\tfpscr_nzcvqc, $src", []>; 2420 } 2421 2422 let Predicates = [HasV8_1MMainline, HasMVEInt] in { 2423 // System level GPR -> VPR/P0 2424 let Defs = [VPR] in 2425 def VMSR_VPR : MovToVFP<0b1100 /* vpr */, (outs), (ins GPR:$src), 2426 "vmsr", "\tvpr, $src", []>; 2427 2428 def VMSR_P0 : MovToVFP<0b1101 /* p0 */, (outs VCCR:$cond), (ins GPR:$src), 2429 "vmsr", "\tp0, $src", []>; 2430 } 2431} 2432 2433//===----------------------------------------------------------------------===// 2434// Misc. 2435// 2436 2437// Materialize FP immediates. VFP3 only. 2438let isReMaterializable = 1 in { 2439def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm), 2440 VFPMiscFrm, IIC_fpUNA64, 2441 "vmov", ".f64\t$Dd, $imm", 2442 [(set DPR:$Dd, vfp_f64imm:$imm)]>, 2443 Requires<[HasVFP3,HasDPVFP]> { 2444 bits<5> Dd; 2445 bits<8> imm; 2446 2447 let Inst{27-23} = 0b11101; 2448 let Inst{22} = Dd{4}; 2449 let Inst{21-20} = 0b11; 2450 let Inst{19-16} = imm{7-4}; 2451 let Inst{15-12} = Dd{3-0}; 2452 let Inst{11-9} = 0b101; 2453 let Inst{8} = 1; // Double precision. 2454 let Inst{7-4} = 0b0000; 2455 let Inst{3-0} = imm{3-0}; 2456} 2457 2458def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm), 2459 VFPMiscFrm, IIC_fpUNA32, 2460 "vmov", ".f32\t$Sd, $imm", 2461 [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> { 2462 bits<5> Sd; 2463 bits<8> imm; 2464 2465 let Inst{27-23} = 0b11101; 2466 let Inst{22} = Sd{0}; 2467 let Inst{21-20} = 0b11; 2468 let Inst{19-16} = imm{7-4}; 2469 let Inst{15-12} = Sd{4-1}; 2470 let Inst{11-9} = 0b101; 2471 let Inst{8} = 0; // Single precision. 2472 let Inst{7-4} = 0b0000; 2473 let Inst{3-0} = imm{3-0}; 2474} 2475 2476def FCONSTH : VFPAI<(outs HPR:$Sd), (ins vfp_f16imm:$imm), 2477 VFPMiscFrm, IIC_fpUNA16, 2478 "vmov", ".f16\t$Sd, $imm", 2479 [(set HPR:$Sd, vfp_f16imm:$imm)]>, 2480 Requires<[HasFullFP16]> { 2481 bits<5> Sd; 2482 bits<8> imm; 2483 2484 let Inst{27-23} = 0b11101; 2485 let Inst{22} = Sd{0}; 2486 let Inst{21-20} = 0b11; 2487 let Inst{19-16} = imm{7-4}; 2488 let Inst{15-12} = Sd{4-1}; 2489 let Inst{11-8} = 0b1001; // Half precision 2490 let Inst{7-4} = 0b0000; 2491 let Inst{3-0} = imm{3-0}; 2492 2493 let isUnpredicable = 1; 2494} 2495} 2496 2497//===----------------------------------------------------------------------===// 2498// Assembler aliases. 2499// 2500// A few mnemonic aliases for pre-unifixed syntax. We don't guarantee to 2501// support them all, but supporting at least some of the basics is 2502// good to be friendly. 2503def : VFP2MnemonicAlias<"flds", "vldr">; 2504def : VFP2MnemonicAlias<"fldd", "vldr">; 2505def : VFP2MnemonicAlias<"fmrs", "vmov">; 2506def : VFP2MnemonicAlias<"fmsr", "vmov">; 2507def : VFP2MnemonicAlias<"fsqrts", "vsqrt">; 2508def : VFP2MnemonicAlias<"fsqrtd", "vsqrt">; 2509def : VFP2MnemonicAlias<"fadds", "vadd.f32">; 2510def : VFP2MnemonicAlias<"faddd", "vadd.f64">; 2511def : VFP2MnemonicAlias<"fmrdd", "vmov">; 2512def : VFP2MnemonicAlias<"fmrds", "vmov">; 2513def : VFP2MnemonicAlias<"fmrrd", "vmov">; 2514def : VFP2MnemonicAlias<"fmdrr", "vmov">; 2515def : VFP2MnemonicAlias<"fmuls", "vmul.f32">; 2516def : VFP2MnemonicAlias<"fmuld", "vmul.f64">; 2517def : VFP2MnemonicAlias<"fnegs", "vneg.f32">; 2518def : VFP2MnemonicAlias<"fnegd", "vneg.f64">; 2519def : VFP2MnemonicAlias<"ftosizd", "vcvt.s32.f64">; 2520def : VFP2MnemonicAlias<"ftosid", "vcvtr.s32.f64">; 2521def : VFP2MnemonicAlias<"ftosizs", "vcvt.s32.f32">; 2522def : VFP2MnemonicAlias<"ftosis", "vcvtr.s32.f32">; 2523def : VFP2MnemonicAlias<"ftouizd", "vcvt.u32.f64">; 2524def : VFP2MnemonicAlias<"ftouid", "vcvtr.u32.f64">; 2525def : VFP2MnemonicAlias<"ftouizs", "vcvt.u32.f32">; 2526def : VFP2MnemonicAlias<"ftouis", "vcvtr.u32.f32">; 2527def : VFP2MnemonicAlias<"fsitod", "vcvt.f64.s32">; 2528def : VFP2MnemonicAlias<"fsitos", "vcvt.f32.s32">; 2529def : VFP2MnemonicAlias<"fuitod", "vcvt.f64.u32">; 2530def : VFP2MnemonicAlias<"fuitos", "vcvt.f32.u32">; 2531def : VFP2MnemonicAlias<"fsts", "vstr">; 2532def : VFP2MnemonicAlias<"fstd", "vstr">; 2533def : VFP2MnemonicAlias<"fmacd", "vmla.f64">; 2534def : VFP2MnemonicAlias<"fmacs", "vmla.f32">; 2535def : VFP2MnemonicAlias<"fcpys", "vmov.f32">; 2536def : VFP2MnemonicAlias<"fcpyd", "vmov.f64">; 2537def : VFP2MnemonicAlias<"fcmps", "vcmp.f32">; 2538def : VFP2MnemonicAlias<"fcmpd", "vcmp.f64">; 2539def : VFP2MnemonicAlias<"fdivs", "vdiv.f32">; 2540def : VFP2MnemonicAlias<"fdivd", "vdiv.f64">; 2541def : VFP2MnemonicAlias<"fmrx", "vmrs">; 2542def : VFP2MnemonicAlias<"fmxr", "vmsr">; 2543 2544// Be friendly and accept the old form of zero-compare 2545def : VFP2DPInstAlias<"fcmpzd${p} $val", (VCMPZD DPR:$val, pred:$p)>; 2546def : VFP2InstAlias<"fcmpzs${p} $val", (VCMPZS SPR:$val, pred:$p)>; 2547 2548 2549def : InstAlias<"fmstat${p}", (FMSTAT pred:$p), 0>, Requires<[HasFPRegs]>; 2550def : VFP2InstAlias<"fadds${p} $Sd, $Sn, $Sm", 2551 (VADDS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>; 2552def : VFP2DPInstAlias<"faddd${p} $Dd, $Dn, $Dm", 2553 (VADDD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; 2554def : VFP2InstAlias<"fsubs${p} $Sd, $Sn, $Sm", 2555 (VSUBS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>; 2556def : VFP2DPInstAlias<"fsubd${p} $Dd, $Dn, $Dm", 2557 (VSUBD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; 2558 2559// No need for the size suffix on VSQRT. It's implied by the register classes. 2560def : VFP2InstAlias<"vsqrt${p} $Sd, $Sm", (VSQRTS SPR:$Sd, SPR:$Sm, pred:$p)>; 2561def : VFP2DPInstAlias<"vsqrt${p} $Dd, $Dm", (VSQRTD DPR:$Dd, DPR:$Dm, pred:$p)>; 2562 2563// VLDR/VSTR accept an optional type suffix. 2564def : VFP2InstAlias<"vldr${p}.32 $Sd, $addr", 2565 (VLDRS SPR:$Sd, addrmode5:$addr, pred:$p)>; 2566def : VFP2InstAlias<"vstr${p}.32 $Sd, $addr", 2567 (VSTRS SPR:$Sd, addrmode5:$addr, pred:$p)>; 2568def : VFP2InstAlias<"vldr${p}.64 $Dd, $addr", 2569 (VLDRD DPR:$Dd, addrmode5:$addr, pred:$p)>; 2570def : VFP2InstAlias<"vstr${p}.64 $Dd, $addr", 2571 (VSTRD DPR:$Dd, addrmode5:$addr, pred:$p)>; 2572 2573// VMOV can accept optional 32-bit or less data type suffix suffix. 2574def : VFP2InstAlias<"vmov${p}.8 $Rt, $Sn", 2575 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 2576def : VFP2InstAlias<"vmov${p}.16 $Rt, $Sn", 2577 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 2578def : VFP2InstAlias<"vmov${p}.32 $Rt, $Sn", 2579 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 2580def : VFP2InstAlias<"vmov${p}.8 $Sn, $Rt", 2581 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 2582def : VFP2InstAlias<"vmov${p}.16 $Sn, $Rt", 2583 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 2584def : VFP2InstAlias<"vmov${p}.32 $Sn, $Rt", 2585 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 2586 2587def : VFP2InstAlias<"vmov${p}.f64 $Rt, $Rt2, $Dn", 2588 (VMOVRRD GPR:$Rt, GPR:$Rt2, DPR:$Dn, pred:$p)>; 2589def : VFP2InstAlias<"vmov${p}.f64 $Dn, $Rt, $Rt2", 2590 (VMOVDRR DPR:$Dn, GPR:$Rt, GPR:$Rt2, pred:$p)>; 2591 2592// VMOVS doesn't need the .f32 to disambiguate from the NEON encoding the way 2593// VMOVD does. 2594def : VFP2InstAlias<"vmov${p} $Sd, $Sm", 2595 (VMOVS SPR:$Sd, SPR:$Sm, pred:$p)>; 2596 2597// FCONSTD/FCONSTS alias for vmov.f64/vmov.f32 2598// These aliases provide added functionality over vmov.f instructions by 2599// allowing users to write assembly containing encoded floating point constants 2600// (e.g. #0x70 vs #1.0). Without these alises there is no way for the 2601// assembler to accept encoded fp constants (but the equivalent fp-literal is 2602// accepted directly by vmovf). 2603def : VFP3InstAlias<"fconstd${p} $Dd, $val", 2604 (FCONSTD DPR:$Dd, vfp_f64imm:$val, pred:$p)>; 2605def : VFP3InstAlias<"fconsts${p} $Sd, $val", 2606 (FCONSTS SPR:$Sd, vfp_f32imm:$val, pred:$p)>; 2607 2608def VSCCLRMD : VFPXI<(outs), (ins pred:$p, fp_dreglist_with_vpr:$regs, variable_ops), 2609 AddrModeNone, 4, IndexModeNone, VFPMiscFrm, NoItinerary, 2610 "vscclrm{$p}\t$regs", "", []>, Sched<[]> { 2611 bits<13> regs; 2612 let Inst{31-23} = 0b111011001; 2613 let Inst{22} = regs{12}; 2614 let Inst{21-16} = 0b011111; 2615 let Inst{15-12} = regs{11-8}; 2616 let Inst{11-8} = 0b1011; 2617 let Inst{7-0} = regs{7-0}; 2618 2619 let DecoderMethod = "DecodeVSCCLRM"; 2620 2621 list<Predicate> Predicates = [HasV8_1MMainline, Has8MSecExt]; 2622} 2623 2624def VSCCLRMS : VFPXI<(outs), (ins pred:$p, fp_sreglist_with_vpr:$regs, variable_ops), 2625 AddrModeNone, 4, IndexModeNone, VFPMiscFrm, NoItinerary, 2626 "vscclrm{$p}\t$regs", "", []>, Sched<[]> { 2627 bits<13> regs; 2628 let Inst{31-23} = 0b111011001; 2629 let Inst{22} = regs{8}; 2630 let Inst{21-16} = 0b011111; 2631 let Inst{15-12} = regs{12-9}; 2632 let Inst{11-8} = 0b1010; 2633 let Inst{7-0} = regs{7-0}; 2634 2635 let DecoderMethod = "DecodeVSCCLRM"; 2636 2637 list<Predicate> Predicates = [HasV8_1MMainline, Has8MSecExt]; 2638} 2639 2640//===----------------------------------------------------------------------===// 2641// Store VFP System Register to memory. 2642// 2643 2644class vfp_vstrldr<bit opc, bit P, bit W, bits<4> SysReg, string sysreg, 2645 dag oops, dag iops, IndexMode im, string Dest, string cstr> 2646 : VFPI<oops, iops, AddrModeT2_i7s4, 4, im, VFPLdStFrm, IIC_fpSTAT, 2647 !if(opc,"vldr","vstr"), !strconcat("\t", sysreg, ", ", Dest), cstr, []>, 2648 Sched<[]> { 2649 bits<12> addr; 2650 let Inst{27-25} = 0b110; 2651 let Inst{24} = P; 2652 let Inst{23} = addr{7}; 2653 let Inst{22} = SysReg{3}; 2654 let Inst{21} = W; 2655 let Inst{20} = opc; 2656 let Inst{19-16} = addr{11-8}; 2657 let Inst{15-13} = SysReg{2-0}; 2658 let Inst{12-7} = 0b011111; 2659 let Inst{6-0} = addr{6-0}; 2660 list<Predicate> Predicates = [HasFPRegs, HasV8_1MMainline]; 2661 let mayLoad = opc; 2662 let mayStore = !if(opc, 0b0, 0b1); 2663 let hasSideEffects = 1; 2664} 2665 2666multiclass vfp_vstrldr_sysreg<bit opc, bits<4> SysReg, string sysreg, 2667 dag oops=(outs), dag iops=(ins)> { 2668 def _off : 2669 vfp_vstrldr<opc, 1, 0, SysReg, sysreg, 2670 oops, !con(iops, (ins t2addrmode_imm7s4:$addr)), 2671 IndexModePost, "$addr", "" > { 2672 let DecoderMethod = "DecodeVSTRVLDR_SYSREG<false>"; 2673 } 2674 2675 def _pre : 2676 vfp_vstrldr<opc, 1, 1, SysReg, sysreg, 2677 !con(oops, (outs GPRnopc:$wb)), 2678 !con(iops, (ins t2addrmode_imm7s4_pre:$addr)), 2679 IndexModePre, "$addr!", "$addr.base = $wb"> { 2680 let DecoderMethod = "DecodeVSTRVLDR_SYSREG<true>"; 2681 } 2682 2683 def _post : 2684 vfp_vstrldr<opc, 0, 1, SysReg, sysreg, 2685 !con(oops, (outs GPRnopc:$wb)), 2686 !con(iops, (ins t2_addr_offset_none:$Rn, 2687 t2am_imm7s4_offset:$addr)), 2688 IndexModePost, "$Rn$addr", "$Rn.base = $wb"> { 2689 bits<4> Rn; 2690 let Inst{19-16} = Rn{3-0}; 2691 let DecoderMethod = "DecodeVSTRVLDR_SYSREG<true>"; 2692 } 2693} 2694 2695let Defs = [FPSCR] in { 2696 defm VSTR_FPSCR : vfp_vstrldr_sysreg<0b0,0b0001, "fpscr">; 2697 defm VSTR_FPSCR_NZCVQC : vfp_vstrldr_sysreg<0b0,0b0010, "fpscr_nzcvqc">; 2698 2699 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2700 defm VSTR_FPCXTNS : vfp_vstrldr_sysreg<0b0,0b1110, "fpcxtns">; 2701 defm VSTR_FPCXTS : vfp_vstrldr_sysreg<0b0,0b1111, "fpcxts">; 2702 } 2703} 2704 2705let Predicates = [HasV8_1MMainline, HasMVEInt] in { 2706 let Uses = [VPR] in { 2707 defm VSTR_VPR : vfp_vstrldr_sysreg<0b0,0b1100, "vpr">; 2708 } 2709 defm VSTR_P0 : vfp_vstrldr_sysreg<0b0,0b1101, "p0", 2710 (outs), (ins VCCR:$P0)>; 2711} 2712 2713let Uses = [FPSCR] in { 2714 defm VLDR_FPSCR : vfp_vstrldr_sysreg<0b1,0b0001, "fpscr">; 2715 defm VLDR_FPSCR_NZCVQC : vfp_vstrldr_sysreg<0b1,0b0010, "fpscr_nzcvqc">; 2716 2717 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2718 defm VLDR_FPCXTNS : vfp_vstrldr_sysreg<0b1,0b1110, "fpcxtns">; 2719 defm VLDR_FPCXTS : vfp_vstrldr_sysreg<0b1,0b1111, "fpcxts">; 2720 } 2721} 2722 2723let Predicates = [HasV8_1MMainline, HasMVEInt] in { 2724 let Defs = [VPR] in { 2725 defm VLDR_VPR : vfp_vstrldr_sysreg<0b1,0b1100, "vpr">; 2726 } 2727 defm VLDR_P0 : vfp_vstrldr_sysreg<0b1,0b1101, "p0", 2728 (outs VCCR:$P0), (ins)>; 2729} 2730