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