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 1556class AVConv1IsH_Encode<bits<5> opcod1, bits<2> opcod2, bits<4> opcod3, 1557 bits<4> opcod4, dag oops, dag iops, 1558 InstrItinClass itin, string opc, string asm, 1559 list<dag> pattern> 1560 : AVConv1I<opcod1, opcod2, opcod3, opcod4, oops, iops, itin, opc, asm, 1561 pattern> { 1562 // Instruction operands. 1563 bits<5> Sd; 1564 bits<5> Sm; 1565 1566 // Encode instruction operands. 1567 let Inst{3-0} = Sm{4-1}; 1568 let Inst{5} = Sm{0}; 1569 let Inst{15-12} = Sd{4-1}; 1570 let Inst{22} = Sd{0}; 1571 1572 let Predicates = [HasFullFP16]; 1573 let hasSideEffects = 0; 1574} 1575 1576// Always set Z bit in the instruction, i.e. "round towards zero" variants. 1577def VTOSIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011, 1578 (outs SPR:$Sd), (ins DPR:$Dm), 1579 IIC_fpCVTDI, "vcvt", ".s32.f64\t$Sd, $Dm", 1580 []>, 1581 Sched<[WriteFPCVT]> { 1582 let Inst{7} = 1; // Z bit 1583} 1584 1585let Predicates=[HasVFP2, HasDPVFP] in { 1586 def : VFPPat<(i32 (fp_to_sint (f64 DPR:$a))), 1587 (COPY_TO_REGCLASS (VTOSIZD DPR:$a), GPR)>; 1588 1589 def : VFPPat<(alignedstore32 (i32 (fp_to_sint (f64 DPR:$a))), addrmode5:$ptr), 1590 (VSTRS (VTOSIZD DPR:$a), addrmode5:$ptr)>; 1591} 1592 1593def VTOSIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010, 1594 (outs SPR:$Sd), (ins SPR:$Sm), 1595 IIC_fpCVTSI, "vcvt", ".s32.f32\t$Sd, $Sm", 1596 []>, 1597 Sched<[WriteFPCVT]> { 1598 let Inst{7} = 1; // Z bit 1599 1600 // Some single precision VFP instructions may be executed on both NEON and 1601 // VFP pipelines on A8. 1602 let D = VFPNeonA8Domain; 1603} 1604 1605def : VFPNoNEONPat<(i32 (fp_to_sint SPR:$a)), 1606 (COPY_TO_REGCLASS (VTOSIZS SPR:$a), GPR)>; 1607 1608def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_sint (f32 SPR:$a))), 1609 addrmode5:$ptr), 1610 (VSTRS (VTOSIZS SPR:$a), addrmode5:$ptr)>; 1611 1612def VTOSIZH : AVConv1IsH_Encode<0b11101, 0b11, 0b1101, 0b1001, 1613 (outs SPR:$Sd), (ins HPR:$Sm), 1614 IIC_fpCVTHI, "vcvt", ".s32.f16\t$Sd, $Sm", 1615 []>, 1616 Sched<[WriteFPCVT]> { 1617 let Inst{7} = 1; // Z bit 1618 let isUnpredicable = 1; 1619} 1620 1621def : VFPNoNEONPat<(i32 (fp_to_sint (f16 HPR:$a))), 1622 (COPY_TO_REGCLASS (VTOSIZH (f16 HPR:$a)), GPR)>; 1623 1624def VTOUIZD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011, 1625 (outs SPR:$Sd), (ins DPR:$Dm), 1626 IIC_fpCVTDI, "vcvt", ".u32.f64\t$Sd, $Dm", 1627 []>, 1628 Sched<[WriteFPCVT]> { 1629 let Inst{7} = 1; // Z bit 1630} 1631 1632let Predicates=[HasVFP2, HasDPVFP] in { 1633 def : VFPPat<(i32 (fp_to_uint (f64 DPR:$a))), 1634 (COPY_TO_REGCLASS (VTOUIZD DPR:$a), GPR)>; 1635 1636 def : VFPPat<(alignedstore32 (i32 (fp_to_uint (f64 DPR:$a))), addrmode5:$ptr), 1637 (VSTRS (VTOUIZD DPR:$a), addrmode5:$ptr)>; 1638} 1639 1640def VTOUIZS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010, 1641 (outs SPR:$Sd), (ins SPR:$Sm), 1642 IIC_fpCVTSI, "vcvt", ".u32.f32\t$Sd, $Sm", 1643 []>, 1644 Sched<[WriteFPCVT]> { 1645 let Inst{7} = 1; // Z bit 1646 1647 // Some single precision VFP instructions may be executed on both NEON and 1648 // VFP pipelines on A8. 1649 let D = VFPNeonA8Domain; 1650} 1651 1652def : VFPNoNEONPat<(i32 (fp_to_uint SPR:$a)), 1653 (COPY_TO_REGCLASS (VTOUIZS SPR:$a), GPR)>; 1654 1655def : VFPNoNEONPat<(alignedstore32 (i32 (fp_to_uint (f32 SPR:$a))), 1656 addrmode5:$ptr), 1657 (VSTRS (VTOUIZS SPR:$a), addrmode5:$ptr)>; 1658 1659def VTOUIZH : AVConv1IsH_Encode<0b11101, 0b11, 0b1100, 0b1001, 1660 (outs SPR:$Sd), (ins HPR:$Sm), 1661 IIC_fpCVTHI, "vcvt", ".u32.f16\t$Sd, $Sm", 1662 []>, 1663 Sched<[WriteFPCVT]> { 1664 let Inst{7} = 1; // Z bit 1665 let isUnpredicable = 1; 1666} 1667 1668def : VFPNoNEONPat<(i32 (fp_to_uint (f16 HPR:$a))), 1669 (COPY_TO_REGCLASS (VTOUIZH (f16 HPR:$a)), GPR)>; 1670 1671// And the Z bit '0' variants, i.e. use the rounding mode specified by FPSCR. 1672let Uses = [FPSCR] in { 1673def VTOSIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1101, 0b1011, 1674 (outs SPR:$Sd), (ins DPR:$Dm), 1675 IIC_fpCVTDI, "vcvtr", ".s32.f64\t$Sd, $Dm", 1676 [(set SPR:$Sd, (int_arm_vcvtr (f64 DPR:$Dm)))]>, 1677 Sched<[WriteFPCVT]> { 1678 let Inst{7} = 0; // Z bit 1679} 1680 1681def VTOSIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1101, 0b1010, 1682 (outs SPR:$Sd), (ins SPR:$Sm), 1683 IIC_fpCVTSI, "vcvtr", ".s32.f32\t$Sd, $Sm", 1684 [(set SPR:$Sd, (int_arm_vcvtr SPR:$Sm))]>, 1685 Sched<[WriteFPCVT]> { 1686 let Inst{7} = 0; // Z bit 1687} 1688 1689def VTOSIRH : AVConv1IsH_Encode<0b11101, 0b11, 0b1101, 0b1001, 1690 (outs SPR:$Sd), (ins SPR:$Sm), 1691 IIC_fpCVTHI, "vcvtr", ".s32.f16\t$Sd, $Sm", 1692 []>, 1693 Sched<[WriteFPCVT]> { 1694 let Inst{7} = 0; // Z bit 1695 let isUnpredicable = 1; 1696} 1697 1698def VTOUIRD : AVConv1IsD_Encode<0b11101, 0b11, 0b1100, 0b1011, 1699 (outs SPR:$Sd), (ins DPR:$Dm), 1700 IIC_fpCVTDI, "vcvtr", ".u32.f64\t$Sd, $Dm", 1701 [(set SPR:$Sd, (int_arm_vcvtru(f64 DPR:$Dm)))]>, 1702 Sched<[WriteFPCVT]> { 1703 let Inst{7} = 0; // Z bit 1704} 1705 1706def VTOUIRS : AVConv1InsS_Encode<0b11101, 0b11, 0b1100, 0b1010, 1707 (outs SPR:$Sd), (ins SPR:$Sm), 1708 IIC_fpCVTSI, "vcvtr", ".u32.f32\t$Sd, $Sm", 1709 [(set SPR:$Sd, (int_arm_vcvtru SPR:$Sm))]>, 1710 Sched<[WriteFPCVT]> { 1711 let Inst{7} = 0; // Z bit 1712} 1713 1714def VTOUIRH : AVConv1IsH_Encode<0b11101, 0b11, 0b1100, 0b1001, 1715 (outs SPR:$Sd), (ins SPR:$Sm), 1716 IIC_fpCVTHI, "vcvtr", ".u32.f16\t$Sd, $Sm", 1717 []>, 1718 Sched<[WriteFPCVT]> { 1719 let Inst{7} = 0; // Z bit 1720 let isUnpredicable = 1; 1721} 1722} 1723 1724// v8.3-a Javascript Convert to Signed fixed-point 1725def VJCVT : AVConv1IsD_Encode<0b11101, 0b11, 0b1001, 0b1011, 1726 (outs SPR:$Sd), (ins DPR:$Dm), 1727 IIC_fpCVTDI, "vjcvt", ".s32.f64\t$Sd, $Dm", 1728 []>, 1729 Requires<[HasFPARMv8, HasV8_3a]> { 1730 let Inst{7} = 1; // Z bit 1731} 1732 1733// Convert between floating-point and fixed-point 1734// Data type for fixed-point naming convention: 1735// S16 (U=0, sx=0) -> SH 1736// U16 (U=1, sx=0) -> UH 1737// S32 (U=0, sx=1) -> SL 1738// U32 (U=1, sx=1) -> UL 1739 1740let Constraints = "$a = $dst" in { 1741 1742// FP to Fixed-Point: 1743 1744// Single Precision register 1745class AVConv1XInsS_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, 1746 bit op5, dag oops, dag iops, InstrItinClass itin, 1747 string opc, string asm, list<dag> pattern> 1748 : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern> { 1749 bits<5> dst; 1750 // if dp_operation then UInt(D:Vd) else UInt(Vd:D); 1751 let Inst{22} = dst{0}; 1752 let Inst{15-12} = dst{4-1}; 1753 1754 let hasSideEffects = 0; 1755} 1756 1757// Double Precision register 1758class AVConv1XInsD_Encode<bits<5> op1, bits<2> op2, bits<4> op3, bits<4> op4, 1759 bit op5, dag oops, dag iops, InstrItinClass itin, 1760 string opc, string asm, list<dag> pattern> 1761 : AVConv1XI<op1, op2, op3, op4, op5, oops, iops, itin, opc, asm, pattern> { 1762 bits<5> dst; 1763 // if dp_operation then UInt(D:Vd) else UInt(Vd:D); 1764 let Inst{22} = dst{4}; 1765 let Inst{15-12} = dst{3-0}; 1766 1767 let hasSideEffects = 0; 1768 let Predicates = [HasVFP2, HasDPVFP]; 1769} 1770 1771let isUnpredicable = 1 in { 1772 1773def VTOSHH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1001, 0, 1774 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1775 IIC_fpCVTHI, "vcvt", ".s16.f16\t$dst, $a, $fbits", []>, 1776 Requires<[HasFullFP16]>, 1777 Sched<[WriteFPCVT]>; 1778 1779def VTOUHH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1001, 0, 1780 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1781 IIC_fpCVTHI, "vcvt", ".u16.f16\t$dst, $a, $fbits", []>, 1782 Requires<[HasFullFP16]>, 1783 Sched<[WriteFPCVT]>; 1784 1785def VTOSLH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1001, 1, 1786 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1787 IIC_fpCVTHI, "vcvt", ".s32.f16\t$dst, $a, $fbits", []>, 1788 Requires<[HasFullFP16]>, 1789 Sched<[WriteFPCVT]>; 1790 1791def VTOULH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1001, 1, 1792 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1793 IIC_fpCVTHI, "vcvt", ".u32.f16\t$dst, $a, $fbits", []>, 1794 Requires<[HasFullFP16]>, 1795 Sched<[WriteFPCVT]>; 1796 1797} // End of 'let isUnpredicable = 1 in' 1798 1799def VTOSHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 0, 1800 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1801 IIC_fpCVTSI, "vcvt", ".s16.f32\t$dst, $a, $fbits", []>, 1802 Sched<[WriteFPCVT]> { 1803 // Some single precision VFP instructions may be executed on both NEON and 1804 // VFP pipelines on A8. 1805 let D = VFPNeonA8Domain; 1806} 1807 1808def VTOUHS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 0, 1809 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1810 IIC_fpCVTSI, "vcvt", ".u16.f32\t$dst, $a, $fbits", []>, 1811 Sched<[WriteFPCVT]> { 1812 // Some single precision VFP instructions may be executed on both NEON and 1813 // VFP pipelines on A8. 1814 let D = VFPNeonA8Domain; 1815} 1816 1817def VTOSLS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1110, 0b1010, 1, 1818 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1819 IIC_fpCVTSI, "vcvt", ".s32.f32\t$dst, $a, $fbits", []>, 1820 Sched<[WriteFPCVT]> { 1821 // Some single precision VFP instructions may be executed on both NEON and 1822 // VFP pipelines on A8. 1823 let D = VFPNeonA8Domain; 1824} 1825 1826def VTOULS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1111, 0b1010, 1, 1827 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1828 IIC_fpCVTSI, "vcvt", ".u32.f32\t$dst, $a, $fbits", []>, 1829 Sched<[WriteFPCVT]> { 1830 // Some single precision VFP instructions may be executed on both NEON and 1831 // VFP pipelines on A8. 1832 let D = VFPNeonA8Domain; 1833} 1834 1835def VTOSHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 0, 1836 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1837 IIC_fpCVTDI, "vcvt", ".s16.f64\t$dst, $a, $fbits", []>, 1838 Sched<[WriteFPCVT]>; 1839 1840def VTOUHD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 0, 1841 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1842 IIC_fpCVTDI, "vcvt", ".u16.f64\t$dst, $a, $fbits", []>, 1843 Sched<[WriteFPCVT]>; 1844 1845def VTOSLD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1110, 0b1011, 1, 1846 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1847 IIC_fpCVTDI, "vcvt", ".s32.f64\t$dst, $a, $fbits", []>, 1848 Sched<[WriteFPCVT]>; 1849 1850def VTOULD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1111, 0b1011, 1, 1851 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1852 IIC_fpCVTDI, "vcvt", ".u32.f64\t$dst, $a, $fbits", []>, 1853 Sched<[WriteFPCVT]>; 1854 1855// Fixed-Point to FP: 1856 1857let isUnpredicable = 1 in { 1858 1859def VSHTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1001, 0, 1860 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1861 IIC_fpCVTIH, "vcvt", ".f16.s16\t$dst, $a, $fbits", []>, 1862 Requires<[HasFullFP16]>, 1863 Sched<[WriteFPCVT]>; 1864 1865def VUHTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1001, 0, 1866 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1867 IIC_fpCVTIH, "vcvt", ".f16.u16\t$dst, $a, $fbits", []>, 1868 Requires<[HasFullFP16]>, 1869 Sched<[WriteFPCVT]>; 1870 1871def VSLTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1001, 1, 1872 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1873 IIC_fpCVTIH, "vcvt", ".f16.s32\t$dst, $a, $fbits", []>, 1874 Requires<[HasFullFP16]>, 1875 Sched<[WriteFPCVT]>; 1876 1877def VULTOH : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1001, 1, 1878 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1879 IIC_fpCVTIH, "vcvt", ".f16.u32\t$dst, $a, $fbits", []>, 1880 Requires<[HasFullFP16]>, 1881 Sched<[WriteFPCVT]>; 1882 1883} // End of 'let isUnpredicable = 1 in' 1884 1885def VSHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 0, 1886 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1887 IIC_fpCVTIS, "vcvt", ".f32.s16\t$dst, $a, $fbits", []>, 1888 Sched<[WriteFPCVT]> { 1889 // Some single precision VFP instructions may be executed on both NEON and 1890 // VFP pipelines on A8. 1891 let D = VFPNeonA8Domain; 1892} 1893 1894def VUHTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 0, 1895 (outs SPR:$dst), (ins SPR:$a, fbits16:$fbits), 1896 IIC_fpCVTIS, "vcvt", ".f32.u16\t$dst, $a, $fbits", []>, 1897 Sched<[WriteFPCVT]> { 1898 // Some single precision VFP instructions may be executed on both NEON and 1899 // VFP pipelines on A8. 1900 let D = VFPNeonA8Domain; 1901} 1902 1903def VSLTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1010, 0b1010, 1, 1904 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1905 IIC_fpCVTIS, "vcvt", ".f32.s32\t$dst, $a, $fbits", []>, 1906 Sched<[WriteFPCVT]> { 1907 // Some single precision VFP instructions may be executed on both NEON and 1908 // VFP pipelines on A8. 1909 let D = VFPNeonA8Domain; 1910} 1911 1912def VULTOS : AVConv1XInsS_Encode<0b11101, 0b11, 0b1011, 0b1010, 1, 1913 (outs SPR:$dst), (ins SPR:$a, fbits32:$fbits), 1914 IIC_fpCVTIS, "vcvt", ".f32.u32\t$dst, $a, $fbits", []>, 1915 Sched<[WriteFPCVT]> { 1916 // Some single precision VFP instructions may be executed on both NEON and 1917 // VFP pipelines on A8. 1918 let D = VFPNeonA8Domain; 1919} 1920 1921def VSHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 0, 1922 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1923 IIC_fpCVTID, "vcvt", ".f64.s16\t$dst, $a, $fbits", []>, 1924 Sched<[WriteFPCVT]>; 1925 1926def VUHTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 0, 1927 (outs DPR:$dst), (ins DPR:$a, fbits16:$fbits), 1928 IIC_fpCVTID, "vcvt", ".f64.u16\t$dst, $a, $fbits", []>, 1929 Sched<[WriteFPCVT]>; 1930 1931def VSLTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1010, 0b1011, 1, 1932 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1933 IIC_fpCVTID, "vcvt", ".f64.s32\t$dst, $a, $fbits", []>, 1934 Sched<[WriteFPCVT]>; 1935 1936def VULTOD : AVConv1XInsD_Encode<0b11101, 0b11, 0b1011, 0b1011, 1, 1937 (outs DPR:$dst), (ins DPR:$a, fbits32:$fbits), 1938 IIC_fpCVTID, "vcvt", ".f64.u32\t$dst, $a, $fbits", []>, 1939 Sched<[WriteFPCVT]>; 1940 1941} // End of 'let Constraints = "$a = $dst" in' 1942 1943// BFloat16 - Single precision, unary, predicated 1944class BF16_VCVT<string opc, bits<2> op7_6> 1945 : VFPAI<(outs SPR:$Sd), (ins SPR:$dst, SPR:$Sm), 1946 VFPUnaryFrm, NoItinerary, 1947 opc, ".bf16.f32\t$Sd, $Sm", []>, 1948 RegConstraint<"$dst = $Sd">, 1949 Requires<[HasBF16]>, 1950 Sched<[]> { 1951 bits<5> Sd; 1952 bits<5> Sm; 1953 1954 // Encode instruction operands. 1955 let Inst{3-0} = Sm{4-1}; 1956 let Inst{5} = Sm{0}; 1957 let Inst{15-12} = Sd{4-1}; 1958 let Inst{22} = Sd{0}; 1959 1960 let Inst{27-23} = 0b11101; // opcode1 1961 let Inst{21-20} = 0b11; // opcode2 1962 let Inst{19-16} = 0b0011; // opcode3 1963 let Inst{11-8} = 0b1001; 1964 let Inst{7-6} = op7_6; 1965 let Inst{4} = 0; 1966 1967 let DecoderNamespace = "VFPV8"; 1968 let hasSideEffects = 0; 1969} 1970 1971def BF16_VCVTB : BF16_VCVT<"vcvtb", 0b01>; 1972def BF16_VCVTT : BF16_VCVT<"vcvtt", 0b11>; 1973 1974//===----------------------------------------------------------------------===// 1975// FP Multiply-Accumulate Operations. 1976// 1977 1978def VMLAD : ADbI<0b11100, 0b00, 0, 0, 1979 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 1980 IIC_fpMAC64, "vmla", ".f64\t$Dd, $Dn, $Dm", 1981 [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm), 1982 (f64 DPR:$Ddin)))]>, 1983 RegConstraint<"$Ddin = $Dd">, 1984 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>, 1985 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 1986 1987def VMLAS : ASbIn<0b11100, 0b00, 0, 0, 1988 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 1989 IIC_fpMAC32, "vmla", ".f32\t$Sd, $Sn, $Sm", 1990 [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm), 1991 SPR:$Sdin))]>, 1992 RegConstraint<"$Sdin = $Sd">, 1993 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>, 1994 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 1995 // Some single precision VFP instructions may be executed on both NEON and 1996 // VFP pipelines on A8. 1997 let D = VFPNeonA8Domain; 1998} 1999 2000def VMLAH : AHbI<0b11100, 0b00, 0, 0, 2001 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2002 IIC_fpMAC16, "vmla", ".f16\t$Sd, $Sn, $Sm", 2003 [(set (f16 HPR:$Sd), (fadd_mlx (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm)), 2004 (f16 HPR:$Sdin)))]>, 2005 RegConstraint<"$Sdin = $Sd">, 2006 Requires<[HasFullFP16,UseFPVMLx]>; 2007 2008def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 2009 (VMLAD DPR:$dstin, DPR:$a, DPR:$b)>, 2010 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 2011def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 2012 (VMLAS SPR:$dstin, SPR:$a, SPR:$b)>, 2013 Requires<[HasVFP2,DontUseNEONForFP, UseFPVMLx]>; 2014def : Pat<(fadd_mlx HPR:$dstin, (fmul_su (f16 HPR:$a), HPR:$b)), 2015 (VMLAH HPR:$dstin, (f16 HPR:$a), HPR:$b)>, 2016 Requires<[HasFullFP16,DontUseNEONForFP, UseFPVMLx]>; 2017 2018 2019def VMLSD : ADbI<0b11100, 0b00, 1, 0, 2020 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2021 IIC_fpMAC64, "vmls", ".f64\t$Dd, $Dn, $Dm", 2022 [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 2023 (f64 DPR:$Ddin)))]>, 2024 RegConstraint<"$Ddin = $Dd">, 2025 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>, 2026 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2027 2028def VMLSS : ASbIn<0b11100, 0b00, 1, 0, 2029 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2030 IIC_fpMAC32, "vmls", ".f32\t$Sd, $Sn, $Sm", 2031 [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 2032 SPR:$Sdin))]>, 2033 RegConstraint<"$Sdin = $Sd">, 2034 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>, 2035 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2036 // Some single precision VFP instructions may be executed on both NEON and 2037 // VFP pipelines on A8. 2038 let D = VFPNeonA8Domain; 2039} 2040 2041def VMLSH : AHbI<0b11100, 0b00, 1, 0, 2042 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2043 IIC_fpMAC16, "vmls", ".f16\t$Sd, $Sn, $Sm", 2044 [(set (f16 HPR:$Sd), (fadd_mlx (fneg (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm))), 2045 (f16 HPR:$Sdin)))]>, 2046 RegConstraint<"$Sdin = $Sd">, 2047 Requires<[HasFullFP16,UseFPVMLx]>; 2048 2049def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 2050 (VMLSD DPR:$dstin, DPR:$a, DPR:$b)>, 2051 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 2052def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 2053 (VMLSS SPR:$dstin, SPR:$a, SPR:$b)>, 2054 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>; 2055def : Pat<(fsub_mlx HPR:$dstin, (fmul_su (f16 HPR:$a), HPR:$b)), 2056 (VMLSH HPR:$dstin, (f16 HPR:$a), HPR:$b)>, 2057 Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>; 2058 2059def VNMLAD : ADbI<0b11100, 0b01, 1, 0, 2060 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2061 IIC_fpMAC64, "vnmla", ".f64\t$Dd, $Dn, $Dm", 2062 [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 2063 (f64 DPR:$Ddin)))]>, 2064 RegConstraint<"$Ddin = $Dd">, 2065 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>, 2066 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2067 2068def VNMLAS : ASbI<0b11100, 0b01, 1, 0, 2069 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2070 IIC_fpMAC32, "vnmla", ".f32\t$Sd, $Sn, $Sm", 2071 [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 2072 SPR:$Sdin))]>, 2073 RegConstraint<"$Sdin = $Sd">, 2074 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>, 2075 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2076 // Some single precision VFP instructions may be executed on both NEON and 2077 // VFP pipelines on A8. 2078 let D = VFPNeonA8Domain; 2079} 2080 2081def VNMLAH : AHbI<0b11100, 0b01, 1, 0, 2082 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2083 IIC_fpMAC16, "vnmla", ".f16\t$Sd, $Sn, $Sm", 2084 [(set (f16 HPR:$Sd), (fsub_mlx (fneg (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm))), 2085 (f16 HPR:$Sdin)))]>, 2086 RegConstraint<"$Sdin = $Sd">, 2087 Requires<[HasFullFP16,UseFPVMLx]>; 2088 2089// (-(a * b) - dst) -> -(dst + (a * b)) 2090def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin), 2091 (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>, 2092 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 2093def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), 2094 (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>, 2095 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>; 2096def : Pat<(fsub_mlx (fneg (fmul_su (f16 HPR:$a), HPR:$b)), HPR:$dstin), 2097 (VNMLAH HPR:$dstin, (f16 HPR:$a), HPR:$b)>, 2098 Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>; 2099 2100// (-dst - (a * b)) -> -(dst + (a * b)) 2101def : Pat<(fsub_mlx (fneg DPR:$dstin), (fmul_su DPR:$a, (f64 DPR:$b))), 2102 (VNMLAD DPR:$dstin, DPR:$a, DPR:$b)>, 2103 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 2104def : Pat<(fsub_mlx (fneg SPR:$dstin), (fmul_su SPR:$a, SPR:$b)), 2105 (VNMLAS SPR:$dstin, SPR:$a, SPR:$b)>, 2106 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>; 2107def : Pat<(fsub_mlx (fneg HPR:$dstin), (fmul_su (f16 HPR:$a), HPR:$b)), 2108 (VNMLAH HPR:$dstin, (f16 HPR:$a), HPR:$b)>, 2109 Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>; 2110 2111def VNMLSD : ADbI<0b11100, 0b01, 0, 0, 2112 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2113 IIC_fpMAC64, "vnmls", ".f64\t$Dd, $Dn, $Dm", 2114 [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm), 2115 (f64 DPR:$Ddin)))]>, 2116 RegConstraint<"$Ddin = $Dd">, 2117 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>, 2118 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2119 2120def VNMLSS : ASbI<0b11100, 0b01, 0, 0, 2121 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2122 IIC_fpMAC32, "vnmls", ".f32\t$Sd, $Sn, $Sm", 2123 [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>, 2124 RegConstraint<"$Sdin = $Sd">, 2125 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>, 2126 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2127 // Some single precision VFP instructions may be executed on both NEON and 2128 // VFP pipelines on A8. 2129 let D = VFPNeonA8Domain; 2130} 2131 2132def VNMLSH : AHbI<0b11100, 0b01, 0, 0, 2133 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2134 IIC_fpMAC16, "vnmls", ".f16\t$Sd, $Sn, $Sm", 2135 [(set (f16 HPR:$Sd), (fsub_mlx (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm)), (f16 HPR:$Sdin)))]>, 2136 RegConstraint<"$Sdin = $Sd">, 2137 Requires<[HasFullFP16,UseFPVMLx]>; 2138 2139def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin), 2140 (VNMLSD DPR:$dstin, DPR:$a, DPR:$b)>, 2141 Requires<[HasVFP2,HasDPVFP,UseFPVMLx]>; 2142def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), 2143 (VNMLSS SPR:$dstin, SPR:$a, SPR:$b)>, 2144 Requires<[HasVFP2,DontUseNEONForFP,UseFPVMLx]>; 2145def : Pat<(fsub_mlx (fmul_su (f16 HPR:$a), HPR:$b), HPR:$dstin), 2146 (VNMLSH HPR:$dstin, (f16 HPR:$a), HPR:$b)>, 2147 Requires<[HasFullFP16,DontUseNEONForFP,UseFPVMLx]>; 2148 2149//===----------------------------------------------------------------------===// 2150// Fused FP Multiply-Accumulate Operations. 2151// 2152def VFMAD : ADbI<0b11101, 0b10, 0, 0, 2153 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2154 IIC_fpFMAC64, "vfma", ".f64\t$Dd, $Dn, $Dm", 2155 [(set DPR:$Dd, (fadd_mlx (fmul_su DPR:$Dn, DPR:$Dm), 2156 (f64 DPR:$Ddin)))]>, 2157 RegConstraint<"$Ddin = $Dd">, 2158 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>, 2159 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2160 2161def VFMAS : ASbIn<0b11101, 0b10, 0, 0, 2162 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2163 IIC_fpFMAC32, "vfma", ".f32\t$Sd, $Sn, $Sm", 2164 [(set SPR:$Sd, (fadd_mlx (fmul_su SPR:$Sn, SPR:$Sm), 2165 SPR:$Sdin))]>, 2166 RegConstraint<"$Sdin = $Sd">, 2167 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>, 2168 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2169 // Some single precision VFP instructions may be executed on both NEON and 2170 // VFP pipelines. 2171} 2172 2173def VFMAH : AHbI<0b11101, 0b10, 0, 0, 2174 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2175 IIC_fpFMAC16, "vfma", ".f16\t$Sd, $Sn, $Sm", 2176 [(set (f16 HPR:$Sd), (fadd_mlx (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm)), 2177 (f16 HPR:$Sdin)))]>, 2178 RegConstraint<"$Sdin = $Sd">, 2179 Requires<[HasFullFP16,UseFusedMAC]>, 2180 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2181 2182def : Pat<(fadd_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 2183 (VFMAD DPR:$dstin, DPR:$a, DPR:$b)>, 2184 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 2185def : Pat<(fadd_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 2186 (VFMAS SPR:$dstin, SPR:$a, SPR:$b)>, 2187 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 2188def : Pat<(fadd_mlx HPR:$dstin, (fmul_su (f16 HPR:$a), HPR:$b)), 2189 (VFMAH HPR:$dstin, (f16 HPR:$a), HPR:$b)>, 2190 Requires<[HasFullFP16,DontUseNEONForFP,UseFusedMAC]>; 2191 2192// Match @llvm.fma.* intrinsics 2193// (fma x, y, z) -> (vfms z, x, y) 2194def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, DPR:$Ddin)), 2195 (VFMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2196 Requires<[HasVFP4,HasDPVFP]>; 2197def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, SPR:$Sdin)), 2198 (VFMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2199 Requires<[HasVFP4]>; 2200def : Pat<(f16 (fma HPR:$Sn, HPR:$Sm, (f16 HPR:$Sdin))), 2201 (VFMAH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>, 2202 Requires<[HasFullFP16]>; 2203 2204def VFMSD : ADbI<0b11101, 0b10, 1, 0, 2205 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2206 IIC_fpFMAC64, "vfms", ".f64\t$Dd, $Dn, $Dm", 2207 [(set DPR:$Dd, (fadd_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 2208 (f64 DPR:$Ddin)))]>, 2209 RegConstraint<"$Ddin = $Dd">, 2210 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>, 2211 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2212 2213def VFMSS : ASbIn<0b11101, 0b10, 1, 0, 2214 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2215 IIC_fpFMAC32, "vfms", ".f32\t$Sd, $Sn, $Sm", 2216 [(set SPR:$Sd, (fadd_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 2217 SPR:$Sdin))]>, 2218 RegConstraint<"$Sdin = $Sd">, 2219 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>, 2220 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2221 // Some single precision VFP instructions may be executed on both NEON and 2222 // VFP pipelines. 2223} 2224 2225def VFMSH : AHbI<0b11101, 0b10, 1, 0, 2226 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2227 IIC_fpFMAC16, "vfms", ".f16\t$Sd, $Sn, $Sm", 2228 [(set (f16 HPR:$Sd), (fadd_mlx (fneg (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm))), 2229 (f16 HPR:$Sdin)))]>, 2230 RegConstraint<"$Sdin = $Sd">, 2231 Requires<[HasFullFP16,UseFusedMAC]>, 2232 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2233 2234def : Pat<(fsub_mlx DPR:$dstin, (fmul_su DPR:$a, (f64 DPR:$b))), 2235 (VFMSD DPR:$dstin, DPR:$a, DPR:$b)>, 2236 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 2237def : Pat<(fsub_mlx SPR:$dstin, (fmul_su SPR:$a, SPR:$b)), 2238 (VFMSS SPR:$dstin, SPR:$a, SPR:$b)>, 2239 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 2240def : Pat<(fsub_mlx HPR:$dstin, (fmul_su (f16 HPR:$a), HPR:$b)), 2241 (VFMSH HPR:$dstin, (f16 HPR:$a), HPR:$b)>, 2242 Requires<[HasFullFP16,DontUseNEONForFP,UseFusedMAC]>; 2243 2244// Match @llvm.fma.* intrinsics 2245// (fma (fneg x), y, z) -> (vfms z, x, y) 2246def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin)), 2247 (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2248 Requires<[HasVFP4,HasDPVFP]>; 2249def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin)), 2250 (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2251 Requires<[HasVFP4]>; 2252def : Pat<(f16 (fma (fneg (f16 HPR:$Sn)), (f16 HPR:$Sm), (f16 HPR:$Sdin))), 2253 (VFMSH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>, 2254 Requires<[HasFullFP16]>; 2255// (fma x, (fneg y), z) -> (vfms z, x, y) 2256def : Pat<(f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin)), 2257 (VFMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2258 Requires<[HasVFP4,HasDPVFP]>; 2259def : Pat<(f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin)), 2260 (VFMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2261 Requires<[HasVFP4]>; 2262def : Pat<(f16 (fma (f16 HPR:$Sn), (fneg (f16 HPR:$Sm)), (f16 HPR:$Sdin))), 2263 (VFMSH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>, 2264 Requires<[HasFullFP16]>; 2265 2266def VFNMAD : ADbI<0b11101, 0b01, 1, 0, 2267 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2268 IIC_fpFMAC64, "vfnma", ".f64\t$Dd, $Dn, $Dm", 2269 [(set DPR:$Dd,(fsub_mlx (fneg (fmul_su DPR:$Dn,DPR:$Dm)), 2270 (f64 DPR:$Ddin)))]>, 2271 RegConstraint<"$Ddin = $Dd">, 2272 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>, 2273 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2274 2275def VFNMAS : ASbI<0b11101, 0b01, 1, 0, 2276 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2277 IIC_fpFMAC32, "vfnma", ".f32\t$Sd, $Sn, $Sm", 2278 [(set SPR:$Sd, (fsub_mlx (fneg (fmul_su SPR:$Sn, SPR:$Sm)), 2279 SPR:$Sdin))]>, 2280 RegConstraint<"$Sdin = $Sd">, 2281 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>, 2282 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2283 // Some single precision VFP instructions may be executed on both NEON and 2284 // VFP pipelines. 2285} 2286 2287def VFNMAH : AHbI<0b11101, 0b01, 1, 0, 2288 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2289 IIC_fpFMAC16, "vfnma", ".f16\t$Sd, $Sn, $Sm", 2290 [(set (f16 HPR:$Sd), (fsub_mlx (fneg (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm))), 2291 (f16 HPR:$Sdin)))]>, 2292 RegConstraint<"$Sdin = $Sd">, 2293 Requires<[HasFullFP16,UseFusedMAC]>, 2294 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2295 2296def : Pat<(fsub_mlx (fneg (fmul_su DPR:$a, (f64 DPR:$b))), DPR:$dstin), 2297 (VFNMAD DPR:$dstin, DPR:$a, DPR:$b)>, 2298 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 2299def : Pat<(fsub_mlx (fneg (fmul_su SPR:$a, SPR:$b)), SPR:$dstin), 2300 (VFNMAS SPR:$dstin, SPR:$a, SPR:$b)>, 2301 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 2302 2303// Match @llvm.fma.* intrinsics 2304// (fneg (fma x, y, z)) -> (vfnma z, x, y) 2305def : Pat<(fneg (fma (f64 DPR:$Dn), (f64 DPR:$Dm), (f64 DPR:$Ddin))), 2306 (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2307 Requires<[HasVFP4,HasDPVFP]>; 2308def : Pat<(fneg (fma (f32 SPR:$Sn), (f32 SPR:$Sm), (f32 SPR:$Sdin))), 2309 (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2310 Requires<[HasVFP4]>; 2311def : Pat<(fneg (fma (f16 HPR:$Sn), (f16 HPR:$Sm), (f16 (f16 HPR:$Sdin)))), 2312 (VFNMAH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>, 2313 Requires<[HasFullFP16]>; 2314// (fma (fneg x), y, (fneg z)) -> (vfnma z, x, y) 2315def : Pat<(f64 (fma (fneg DPR:$Dn), DPR:$Dm, (fneg DPR:$Ddin))), 2316 (VFNMAD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2317 Requires<[HasVFP4,HasDPVFP]>; 2318def : Pat<(f32 (fma (fneg SPR:$Sn), SPR:$Sm, (fneg SPR:$Sdin))), 2319 (VFNMAS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2320 Requires<[HasVFP4]>; 2321def : Pat<(f16 (fma (fneg (f16 HPR:$Sn)), (f16 HPR:$Sm), (fneg (f16 HPR:$Sdin)))), 2322 (VFNMAH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>, 2323 Requires<[HasFullFP16]>; 2324 2325def VFNMSD : ADbI<0b11101, 0b01, 0, 0, 2326 (outs DPR:$Dd), (ins DPR:$Ddin, DPR:$Dn, DPR:$Dm), 2327 IIC_fpFMAC64, "vfnms", ".f64\t$Dd, $Dn, $Dm", 2328 [(set DPR:$Dd, (fsub_mlx (fmul_su DPR:$Dn, DPR:$Dm), 2329 (f64 DPR:$Ddin)))]>, 2330 RegConstraint<"$Ddin = $Dd">, 2331 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>, 2332 Sched<[WriteFPMAC64, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2333 2334def VFNMSS : ASbI<0b11101, 0b01, 0, 0, 2335 (outs SPR:$Sd), (ins SPR:$Sdin, SPR:$Sn, SPR:$Sm), 2336 IIC_fpFMAC32, "vfnms", ".f32\t$Sd, $Sn, $Sm", 2337 [(set SPR:$Sd, (fsub_mlx (fmul_su SPR:$Sn, SPR:$Sm), SPR:$Sdin))]>, 2338 RegConstraint<"$Sdin = $Sd">, 2339 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>, 2340 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]> { 2341 // Some single precision VFP instructions may be executed on both NEON and 2342 // VFP pipelines. 2343} 2344 2345def VFNMSH : AHbI<0b11101, 0b01, 0, 0, 2346 (outs HPR:$Sd), (ins HPR:$Sdin, HPR:$Sn, HPR:$Sm), 2347 IIC_fpFMAC16, "vfnms", ".f16\t$Sd, $Sn, $Sm", 2348 [(set (f16 HPR:$Sd), (fsub_mlx (fmul_su (f16 HPR:$Sn), (f16 HPR:$Sm)), (f16 HPR:$Sdin)))]>, 2349 RegConstraint<"$Sdin = $Sd">, 2350 Requires<[HasFullFP16,UseFusedMAC]>, 2351 Sched<[WriteFPMAC32, ReadFPMAC, ReadFPMUL, ReadFPMUL]>; 2352 2353def : Pat<(fsub_mlx (fmul_su DPR:$a, (f64 DPR:$b)), DPR:$dstin), 2354 (VFNMSD DPR:$dstin, DPR:$a, DPR:$b)>, 2355 Requires<[HasVFP4,HasDPVFP,UseFusedMAC]>; 2356def : Pat<(fsub_mlx (fmul_su SPR:$a, SPR:$b), SPR:$dstin), 2357 (VFNMSS SPR:$dstin, SPR:$a, SPR:$b)>, 2358 Requires<[HasVFP4,DontUseNEONForFP,UseFusedMAC]>; 2359 2360// Match @llvm.fma.* intrinsics 2361 2362// (fma x, y, (fneg z)) -> (vfnms z, x, y)) 2363def : Pat<(f64 (fma DPR:$Dn, DPR:$Dm, (fneg DPR:$Ddin))), 2364 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2365 Requires<[HasVFP4,HasDPVFP]>; 2366def : Pat<(f32 (fma SPR:$Sn, SPR:$Sm, (fneg SPR:$Sdin))), 2367 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2368 Requires<[HasVFP4]>; 2369def : Pat<(f16 (fma (f16 HPR:$Sn), (f16 HPR:$Sm), (fneg (f16 HPR:$Sdin)))), 2370 (VFNMSH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>, 2371 Requires<[HasFullFP16]>; 2372// (fneg (fma (fneg x), y, z)) -> (vfnms z, x, y) 2373def : Pat<(fneg (f64 (fma (fneg DPR:$Dn), DPR:$Dm, DPR:$Ddin))), 2374 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2375 Requires<[HasVFP4,HasDPVFP]>; 2376def : Pat<(fneg (f32 (fma (fneg SPR:$Sn), SPR:$Sm, SPR:$Sdin))), 2377 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2378 Requires<[HasVFP4]>; 2379def : Pat<(fneg (f16 (fma (fneg (f16 HPR:$Sn)), (f16 HPR:$Sm), (f16 HPR:$Sdin)))), 2380 (VFNMSH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>, 2381 Requires<[HasFullFP16]>; 2382// (fneg (fma x, (fneg y), z) -> (vfnms z, x, y) 2383def : Pat<(fneg (f64 (fma DPR:$Dn, (fneg DPR:$Dm), DPR:$Ddin))), 2384 (VFNMSD DPR:$Ddin, DPR:$Dn, DPR:$Dm)>, 2385 Requires<[HasVFP4,HasDPVFP]>; 2386def : Pat<(fneg (f32 (fma SPR:$Sn, (fneg SPR:$Sm), SPR:$Sdin))), 2387 (VFNMSS SPR:$Sdin, SPR:$Sn, SPR:$Sm)>, 2388 Requires<[HasVFP4]>; 2389def : Pat<(fneg (f16 (fma (f16 HPR:$Sn), (fneg (f16 HPR:$Sm)), (f16 HPR:$Sdin)))), 2390 (VFNMSH (f16 HPR:$Sdin), (f16 HPR:$Sn), (f16 HPR:$Sm))>, 2391 Requires<[HasFullFP16]>; 2392 2393//===----------------------------------------------------------------------===// 2394// FP Conditional moves. 2395// 2396 2397let hasSideEffects = 0 in { 2398def VMOVDcc : PseudoInst<(outs DPR:$Dd), (ins DPR:$Dn, DPR:$Dm, cmovpred:$p), 2399 IIC_fpUNA64, 2400 [(set (f64 DPR:$Dd), 2401 (ARMcmov DPR:$Dn, DPR:$Dm, cmovpred:$p))]>, 2402 RegConstraint<"$Dn = $Dd">, Requires<[HasFPRegs64]>; 2403 2404def VMOVScc : PseudoInst<(outs SPR:$Sd), (ins SPR:$Sn, SPR:$Sm, cmovpred:$p), 2405 IIC_fpUNA32, 2406 [(set (f32 SPR:$Sd), 2407 (ARMcmov SPR:$Sn, SPR:$Sm, cmovpred:$p))]>, 2408 RegConstraint<"$Sn = $Sd">, Requires<[HasFPRegs]>; 2409 2410def VMOVHcc : PseudoInst<(outs HPR:$Sd), (ins HPR:$Sn, HPR:$Sm, cmovpred:$p), 2411 IIC_fpUNA16, 2412 [(set (f16 HPR:$Sd), 2413 (ARMcmov (f16 HPR:$Sn), (f16 HPR:$Sm), cmovpred:$p))]>, 2414 RegConstraint<"$Sd = $Sn">, Requires<[HasFPRegs]>; 2415} // hasSideEffects 2416 2417//===----------------------------------------------------------------------===// 2418// Move from VFP System Register to ARM core register. 2419// 2420 2421class MovFromVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm, 2422 list<dag> pattern>: 2423 VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> { 2424 2425 // Instruction operand. 2426 bits<4> Rt; 2427 2428 let Inst{27-20} = 0b11101111; 2429 let Inst{19-16} = opc19_16; 2430 let Inst{15-12} = Rt; 2431 let Inst{11-8} = 0b1010; 2432 let Inst{7} = 0; 2433 let Inst{6-5} = 0b00; 2434 let Inst{4} = 1; 2435 let Inst{3-0} = 0b0000; 2436 let Unpredictable{7-5} = 0b111; 2437 let Unpredictable{3-0} = 0b1111; 2438} 2439 2440let DecoderMethod = "DecodeForVMRSandVMSR" in { 2441 // APSR is the application level alias of CPSR. This FPSCR N, Z, C, V flags 2442 // to APSR. 2443 let Defs = [CPSR], Uses = [FPSCR_NZCV], Predicates = [HasFPRegs], 2444 Rt = 0b1111 /* apsr_nzcv */ in 2445 def FMSTAT : MovFromVFP<0b0001 /* fpscr */, (outs), (ins), 2446 "vmrs", "\tAPSR_nzcv, fpscr", [(arm_fmstat)]>; 2447 2448 // Application level FPSCR -> GPR 2449 let hasSideEffects = 1, Uses = [FPSCR], Predicates = [HasFPRegs] in 2450 def VMRS : MovFromVFP<0b0001 /* fpscr */, (outs GPRnopc:$Rt), (ins), 2451 "vmrs", "\t$Rt, fpscr", 2452 [(set GPRnopc:$Rt, (int_arm_get_fpscr))]>; 2453 2454 // System level FPEXC, FPSID -> GPR 2455 let Uses = [FPSCR] in { 2456 def VMRS_FPEXC : MovFromVFP<0b1000 /* fpexc */, (outs GPRnopc:$Rt), (ins), 2457 "vmrs", "\t$Rt, fpexc", []>; 2458 def VMRS_FPSID : MovFromVFP<0b0000 /* fpsid */, (outs GPRnopc:$Rt), (ins), 2459 "vmrs", "\t$Rt, fpsid", []>; 2460 def VMRS_MVFR0 : MovFromVFP<0b0111 /* mvfr0 */, (outs GPRnopc:$Rt), (ins), 2461 "vmrs", "\t$Rt, mvfr0", []>; 2462 def VMRS_MVFR1 : MovFromVFP<0b0110 /* mvfr1 */, (outs GPRnopc:$Rt), (ins), 2463 "vmrs", "\t$Rt, mvfr1", []>; 2464 let Predicates = [HasFPARMv8] in { 2465 def VMRS_MVFR2 : MovFromVFP<0b0101 /* mvfr2 */, (outs GPRnopc:$Rt), (ins), 2466 "vmrs", "\t$Rt, mvfr2", []>; 2467 } 2468 def VMRS_FPINST : MovFromVFP<0b1001 /* fpinst */, (outs GPRnopc:$Rt), (ins), 2469 "vmrs", "\t$Rt, fpinst", []>; 2470 def VMRS_FPINST2 : MovFromVFP<0b1010 /* fpinst2 */, (outs GPRnopc:$Rt), 2471 (ins), "vmrs", "\t$Rt, fpinst2", []>; 2472 let Predicates = [HasV8_1MMainline, HasFPRegs] in { 2473 // System level FPSCR_NZCVQC -> GPR 2474 def VMRS_FPSCR_NZCVQC 2475 : MovFromVFP<0b0010 /* fpscr_nzcvqc */, 2476 (outs GPR:$Rt), (ins cl_FPSCR_NZCV:$fpscr_in), 2477 "vmrs", "\t$Rt, fpscr_nzcvqc", []>; 2478 } 2479 } 2480 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2481 // System level FPSCR -> GPR, with context saving for security extensions 2482 def VMRS_FPCXTNS : MovFromVFP<0b1110 /* fpcxtns */, (outs GPR:$Rt), (ins), 2483 "vmrs", "\t$Rt, fpcxtns", []>; 2484 } 2485 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2486 // System level FPSCR -> GPR, with context saving for security extensions 2487 def VMRS_FPCXTS : MovFromVFP<0b1111 /* fpcxts */, (outs GPR:$Rt), (ins), 2488 "vmrs", "\t$Rt, fpcxts", []>; 2489 } 2490 2491 let Predicates = [HasV8_1MMainline, HasMVEInt] in { 2492 // System level VPR/P0 -> GPR 2493 let Uses = [VPR] in 2494 def VMRS_VPR : MovFromVFP<0b1100 /* vpr */, (outs GPR:$Rt), (ins), 2495 "vmrs", "\t$Rt, vpr", []>; 2496 2497 def VMRS_P0 : MovFromVFP<0b1101 /* p0 */, (outs GPR:$Rt), (ins VCCR:$cond), 2498 "vmrs", "\t$Rt, p0", []>; 2499 } 2500} 2501 2502//===----------------------------------------------------------------------===// 2503// Move from ARM core register to VFP System Register. 2504// 2505 2506class MovToVFP<bits<4> opc19_16, dag oops, dag iops, string opc, string asm, 2507 list<dag> pattern>: 2508 VFPAI<oops, iops, VFPMiscFrm, IIC_fpSTAT, opc, asm, pattern> { 2509 2510 // Instruction operand. 2511 bits<4> Rt; 2512 2513 let Inst{27-20} = 0b11101110; 2514 let Inst{19-16} = opc19_16; 2515 let Inst{15-12} = Rt; 2516 let Inst{11-8} = 0b1010; 2517 let Inst{7} = 0; 2518 let Inst{6-5} = 0b00; 2519 let Inst{4} = 1; 2520 let Inst{3-0} = 0b0000; 2521 let Predicates = [HasVFP2]; 2522 let Unpredictable{7-5} = 0b111; 2523 let Unpredictable{3-0} = 0b1111; 2524} 2525 2526let DecoderMethod = "DecodeForVMRSandVMSR" in { 2527 let Defs = [FPSCR] in { 2528 let Predicates = [HasFPRegs] in 2529 // Application level GPR -> FPSCR 2530 def VMSR : MovToVFP<0b0001 /* fpscr */, (outs), (ins GPRnopc:$Rt), 2531 "vmsr", "\tfpscr, $Rt", 2532 [(int_arm_set_fpscr GPRnopc:$Rt)]>; 2533 // System level GPR -> FPEXC 2534 def VMSR_FPEXC : MovToVFP<0b1000 /* fpexc */, (outs), (ins GPRnopc:$Rt), 2535 "vmsr", "\tfpexc, $Rt", []>; 2536 // System level GPR -> FPSID 2537 def VMSR_FPSID : MovToVFP<0b0000 /* fpsid */, (outs), (ins GPRnopc:$Rt), 2538 "vmsr", "\tfpsid, $Rt", []>; 2539 def VMSR_FPINST : MovToVFP<0b1001 /* fpinst */, (outs), (ins GPRnopc:$Rt), 2540 "vmsr", "\tfpinst, $Rt", []>; 2541 def VMSR_FPINST2 : MovToVFP<0b1010 /* fpinst2 */, (outs), (ins GPRnopc:$Rt), 2542 "vmsr", "\tfpinst2, $Rt", []>; 2543 } 2544 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2545 // System level GPR -> FPSCR with context saving for security extensions 2546 def VMSR_FPCXTNS : MovToVFP<0b1110 /* fpcxtns */, (outs), (ins GPR:$Rt), 2547 "vmsr", "\tfpcxtns, $Rt", []>; 2548 } 2549 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2550 // System level GPR -> FPSCR with context saving for security extensions 2551 def VMSR_FPCXTS : MovToVFP<0b1111 /* fpcxts */, (outs), (ins GPR:$Rt), 2552 "vmsr", "\tfpcxts, $Rt", []>; 2553 } 2554 let Predicates = [HasV8_1MMainline, HasFPRegs] in { 2555 // System level GPR -> FPSCR_NZCVQC 2556 def VMSR_FPSCR_NZCVQC 2557 : MovToVFP<0b0010 /* fpscr_nzcvqc */, 2558 (outs cl_FPSCR_NZCV:$fpscr_out), (ins GPR:$Rt), 2559 "vmsr", "\tfpscr_nzcvqc, $Rt", []>; 2560 } 2561 2562 let Predicates = [HasV8_1MMainline, HasMVEInt] in { 2563 // System level GPR -> VPR/P0 2564 let Defs = [VPR] in 2565 def VMSR_VPR : MovToVFP<0b1100 /* vpr */, (outs), (ins GPR:$Rt), 2566 "vmsr", "\tvpr, $Rt", []>; 2567 2568 def VMSR_P0 : MovToVFP<0b1101 /* p0 */, (outs VCCR:$cond), (ins GPR:$Rt), 2569 "vmsr", "\tp0, $Rt", []>; 2570 } 2571} 2572 2573//===----------------------------------------------------------------------===// 2574// Misc. 2575// 2576 2577// Materialize FP immediates. VFP3 only. 2578let isReMaterializable = 1 in { 2579def FCONSTD : VFPAI<(outs DPR:$Dd), (ins vfp_f64imm:$imm), 2580 VFPMiscFrm, IIC_fpUNA64, 2581 "vmov", ".f64\t$Dd, $imm", 2582 [(set DPR:$Dd, vfp_f64imm:$imm)]>, 2583 Requires<[HasVFP3,HasDPVFP]> { 2584 bits<5> Dd; 2585 bits<8> imm; 2586 2587 let Inst{27-23} = 0b11101; 2588 let Inst{22} = Dd{4}; 2589 let Inst{21-20} = 0b11; 2590 let Inst{19-16} = imm{7-4}; 2591 let Inst{15-12} = Dd{3-0}; 2592 let Inst{11-9} = 0b101; 2593 let Inst{8} = 1; // Double precision. 2594 let Inst{7-4} = 0b0000; 2595 let Inst{3-0} = imm{3-0}; 2596} 2597 2598def FCONSTS : VFPAI<(outs SPR:$Sd), (ins vfp_f32imm:$imm), 2599 VFPMiscFrm, IIC_fpUNA32, 2600 "vmov", ".f32\t$Sd, $imm", 2601 [(set SPR:$Sd, vfp_f32imm:$imm)]>, Requires<[HasVFP3]> { 2602 bits<5> Sd; 2603 bits<8> imm; 2604 2605 let Inst{27-23} = 0b11101; 2606 let Inst{22} = Sd{0}; 2607 let Inst{21-20} = 0b11; 2608 let Inst{19-16} = imm{7-4}; 2609 let Inst{15-12} = Sd{4-1}; 2610 let Inst{11-9} = 0b101; 2611 let Inst{8} = 0; // Single precision. 2612 let Inst{7-4} = 0b0000; 2613 let Inst{3-0} = imm{3-0}; 2614} 2615 2616def FCONSTH : VFPAI<(outs HPR:$Sd), (ins vfp_f16imm:$imm), 2617 VFPMiscFrm, IIC_fpUNA16, 2618 "vmov", ".f16\t$Sd, $imm", 2619 [(set (f16 HPR:$Sd), vfp_f16imm:$imm)]>, 2620 Requires<[HasFullFP16]> { 2621 bits<5> Sd; 2622 bits<8> imm; 2623 2624 let Inst{27-23} = 0b11101; 2625 let Inst{22} = Sd{0}; 2626 let Inst{21-20} = 0b11; 2627 let Inst{19-16} = imm{7-4}; 2628 let Inst{15-12} = Sd{4-1}; 2629 let Inst{11-8} = 0b1001; // Half precision 2630 let Inst{7-4} = 0b0000; 2631 let Inst{3-0} = imm{3-0}; 2632 2633 let isUnpredicable = 1; 2634} 2635} 2636 2637//===----------------------------------------------------------------------===// 2638// Assembler aliases. 2639// 2640// A few mnemonic aliases for pre-unifixed syntax. We don't guarantee to 2641// support them all, but supporting at least some of the basics is 2642// good to be friendly. 2643def : VFP2MnemonicAlias<"flds", "vldr">; 2644def : VFP2MnemonicAlias<"fldd", "vldr">; 2645def : VFP2MnemonicAlias<"fmrs", "vmov">; 2646def : VFP2MnemonicAlias<"fmsr", "vmov">; 2647def : VFP2MnemonicAlias<"fsqrts", "vsqrt">; 2648def : VFP2MnemonicAlias<"fsqrtd", "vsqrt">; 2649def : VFP2MnemonicAlias<"fadds", "vadd.f32">; 2650def : VFP2MnemonicAlias<"faddd", "vadd.f64">; 2651def : VFP2MnemonicAlias<"fmrdd", "vmov">; 2652def : VFP2MnemonicAlias<"fmrds", "vmov">; 2653def : VFP2MnemonicAlias<"fmrrd", "vmov">; 2654def : VFP2MnemonicAlias<"fmdrr", "vmov">; 2655def : VFP2MnemonicAlias<"fmuls", "vmul.f32">; 2656def : VFP2MnemonicAlias<"fmuld", "vmul.f64">; 2657def : VFP2MnemonicAlias<"fnegs", "vneg.f32">; 2658def : VFP2MnemonicAlias<"fnegd", "vneg.f64">; 2659def : VFP2MnemonicAlias<"ftosizd", "vcvt.s32.f64">; 2660def : VFP2MnemonicAlias<"ftosid", "vcvtr.s32.f64">; 2661def : VFP2MnemonicAlias<"ftosizs", "vcvt.s32.f32">; 2662def : VFP2MnemonicAlias<"ftosis", "vcvtr.s32.f32">; 2663def : VFP2MnemonicAlias<"ftouizd", "vcvt.u32.f64">; 2664def : VFP2MnemonicAlias<"ftouid", "vcvtr.u32.f64">; 2665def : VFP2MnemonicAlias<"ftouizs", "vcvt.u32.f32">; 2666def : VFP2MnemonicAlias<"ftouis", "vcvtr.u32.f32">; 2667def : VFP2MnemonicAlias<"fsitod", "vcvt.f64.s32">; 2668def : VFP2MnemonicAlias<"fsitos", "vcvt.f32.s32">; 2669def : VFP2MnemonicAlias<"fuitod", "vcvt.f64.u32">; 2670def : VFP2MnemonicAlias<"fuitos", "vcvt.f32.u32">; 2671def : VFP2MnemonicAlias<"fsts", "vstr">; 2672def : VFP2MnemonicAlias<"fstd", "vstr">; 2673def : VFP2MnemonicAlias<"fmacd", "vmla.f64">; 2674def : VFP2MnemonicAlias<"fmacs", "vmla.f32">; 2675def : VFP2MnemonicAlias<"fcpys", "vmov.f32">; 2676def : VFP2MnemonicAlias<"fcpyd", "vmov.f64">; 2677def : VFP2MnemonicAlias<"fcmps", "vcmp.f32">; 2678def : VFP2MnemonicAlias<"fcmpd", "vcmp.f64">; 2679def : VFP2MnemonicAlias<"fdivs", "vdiv.f32">; 2680def : VFP2MnemonicAlias<"fdivd", "vdiv.f64">; 2681def : VFP2MnemonicAlias<"fmrx", "vmrs">; 2682def : VFP2MnemonicAlias<"fmxr", "vmsr">; 2683 2684// Be friendly and accept the old form of zero-compare 2685def : VFP2DPInstAlias<"fcmpzd${p} $val", (VCMPZD DPR:$val, pred:$p)>; 2686def : VFP2InstAlias<"fcmpzs${p} $val", (VCMPZS SPR:$val, pred:$p)>; 2687 2688 2689def : InstAlias<"fmstat${p}", (FMSTAT pred:$p), 0>, Requires<[HasFPRegs]>; 2690def : VFP2InstAlias<"fadds${p} $Sd, $Sn, $Sm", 2691 (VADDS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>; 2692def : VFP2DPInstAlias<"faddd${p} $Dd, $Dn, $Dm", 2693 (VADDD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; 2694def : VFP2InstAlias<"fsubs${p} $Sd, $Sn, $Sm", 2695 (VSUBS SPR:$Sd, SPR:$Sn, SPR:$Sm, pred:$p)>; 2696def : VFP2DPInstAlias<"fsubd${p} $Dd, $Dn, $Dm", 2697 (VSUBD DPR:$Dd, DPR:$Dn, DPR:$Dm, pred:$p)>; 2698 2699// No need for the size suffix on VSQRT. It's implied by the register classes. 2700def : VFP2InstAlias<"vsqrt${p} $Sd, $Sm", (VSQRTS SPR:$Sd, SPR:$Sm, pred:$p)>; 2701def : VFP2DPInstAlias<"vsqrt${p} $Dd, $Dm", (VSQRTD DPR:$Dd, DPR:$Dm, pred:$p)>; 2702 2703// VLDR/VSTR accept an optional type suffix. 2704def : VFP2InstAlias<"vldr${p}.32 $Sd, $addr", 2705 (VLDRS SPR:$Sd, addrmode5:$addr, pred:$p)>; 2706def : VFP2InstAlias<"vstr${p}.32 $Sd, $addr", 2707 (VSTRS SPR:$Sd, addrmode5:$addr, pred:$p)>; 2708def : VFP2InstAlias<"vldr${p}.64 $Dd, $addr", 2709 (VLDRD DPR:$Dd, addrmode5:$addr, pred:$p)>; 2710def : VFP2InstAlias<"vstr${p}.64 $Dd, $addr", 2711 (VSTRD DPR:$Dd, addrmode5:$addr, pred:$p)>; 2712 2713// VMOV can accept optional 32-bit or less data type suffix suffix. 2714def : VFP2InstAlias<"vmov${p}.8 $Rt, $Sn", 2715 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 2716def : VFP2InstAlias<"vmov${p}.16 $Rt, $Sn", 2717 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 2718def : VFP2InstAlias<"vmov${p}.32 $Rt, $Sn", 2719 (VMOVRS GPR:$Rt, SPR:$Sn, pred:$p)>; 2720def : VFP2InstAlias<"vmov${p}.8 $Sn, $Rt", 2721 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 2722def : VFP2InstAlias<"vmov${p}.16 $Sn, $Rt", 2723 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 2724def : VFP2InstAlias<"vmov${p}.32 $Sn, $Rt", 2725 (VMOVSR SPR:$Sn, GPR:$Rt, pred:$p)>; 2726 2727def : VFP2InstAlias<"vmov${p}.f64 $Rt, $Rt2, $Dn", 2728 (VMOVRRD GPR:$Rt, GPR:$Rt2, DPR:$Dn, pred:$p)>; 2729def : VFP2InstAlias<"vmov${p}.f64 $Dn, $Rt, $Rt2", 2730 (VMOVDRR DPR:$Dn, GPR:$Rt, GPR:$Rt2, pred:$p)>; 2731 2732// VMOVS doesn't need the .f32 to disambiguate from the NEON encoding the way 2733// VMOVD does. 2734def : VFP2InstAlias<"vmov${p} $Sd, $Sm", 2735 (VMOVS SPR:$Sd, SPR:$Sm, pred:$p)>; 2736 2737// FCONSTD/FCONSTS alias for vmov.f64/vmov.f32 2738// These aliases provide added functionality over vmov.f instructions by 2739// allowing users to write assembly containing encoded floating point constants 2740// (e.g. #0x70 vs #1.0). Without these alises there is no way for the 2741// assembler to accept encoded fp constants (but the equivalent fp-literal is 2742// accepted directly by vmovf). 2743def : VFP3InstAlias<"fconstd${p} $Dd, $val", 2744 (FCONSTD DPR:$Dd, vfp_f64imm:$val, pred:$p)>; 2745def : VFP3InstAlias<"fconsts${p} $Sd, $val", 2746 (FCONSTS SPR:$Sd, vfp_f32imm:$val, pred:$p)>; 2747 2748def VSCCLRMD : VFPXI<(outs), (ins pred:$p, fp_dreglist_with_vpr:$regs, variable_ops), 2749 AddrModeNone, 4, IndexModeNone, VFPMiscFrm, NoItinerary, 2750 "vscclrm{$p}\t$regs", "", []>, Sched<[]> { 2751 bits<13> regs; 2752 let Inst{31-23} = 0b111011001; 2753 let Inst{22} = regs{12}; 2754 let Inst{21-16} = 0b011111; 2755 let Inst{15-12} = regs{11-8}; 2756 let Inst{11-8} = 0b1011; 2757 let Inst{7-1} = regs{7-1}; 2758 let Inst{0} = 0; 2759 2760 let DecoderMethod = "DecodeVSCCLRM"; 2761 2762 list<Predicate> Predicates = [HasV8_1MMainline, Has8MSecExt]; 2763} 2764 2765def VSCCLRMS : VFPXI<(outs), (ins pred:$p, fp_sreglist_with_vpr:$regs, variable_ops), 2766 AddrModeNone, 4, IndexModeNone, VFPMiscFrm, NoItinerary, 2767 "vscclrm{$p}\t$regs", "", []>, Sched<[]> { 2768 bits<13> regs; 2769 let Inst{31-23} = 0b111011001; 2770 let Inst{22} = regs{8}; 2771 let Inst{21-16} = 0b011111; 2772 let Inst{15-12} = regs{12-9}; 2773 let Inst{11-8} = 0b1010; 2774 let Inst{7-0} = regs{7-0}; 2775 2776 let DecoderMethod = "DecodeVSCCLRM"; 2777 2778 list<Predicate> Predicates = [HasV8_1MMainline, Has8MSecExt]; 2779} 2780 2781//===----------------------------------------------------------------------===// 2782// Store VFP System Register to memory. 2783// 2784 2785class vfp_vstrldr<bit opc, bit P, bit W, bits<4> SysReg, string sysreg, 2786 dag oops, dag iops, IndexMode im, string Dest, string cstr> 2787 : VFPI<oops, iops, AddrModeT2_i7s4, 4, im, VFPLdStFrm, IIC_fpSTAT, 2788 !if(opc,"vldr","vstr"), !strconcat("\t", sysreg, ", ", Dest), cstr, []>, 2789 Sched<[]> { 2790 bits<12> addr; 2791 let Inst{27-25} = 0b110; 2792 let Inst{24} = P; 2793 let Inst{23} = addr{7}; 2794 let Inst{22} = SysReg{3}; 2795 let Inst{21} = W; 2796 let Inst{20} = opc; 2797 let Inst{19-16} = addr{11-8}; 2798 let Inst{15-13} = SysReg{2-0}; 2799 let Inst{12-7} = 0b011111; 2800 let Inst{6-0} = addr{6-0}; 2801 list<Predicate> Predicates = [HasFPRegs, HasV8_1MMainline]; 2802 let mayLoad = opc; 2803 let mayStore = !if(opc, 0b0, 0b1); 2804 let hasSideEffects = 1; 2805} 2806 2807multiclass vfp_vstrldr_sysreg<bit opc, bits<4> SysReg, string sysreg, 2808 dag oops=(outs), dag iops=(ins)> { 2809 def _off : 2810 vfp_vstrldr<opc, 1, 0, SysReg, sysreg, 2811 oops, !con(iops, (ins t2addrmode_imm7s4:$addr)), 2812 IndexModePost, "$addr", "" > { 2813 let DecoderMethod = "DecodeVSTRVLDR_SYSREG<false>"; 2814 } 2815 2816 def _pre : 2817 vfp_vstrldr<opc, 1, 1, SysReg, sysreg, 2818 !con(oops, (outs GPRnopc:$wb)), 2819 !con(iops, (ins t2addrmode_imm7s4_pre:$addr)), 2820 IndexModePre, "$addr!", "$addr.base = $wb"> { 2821 let DecoderMethod = "DecodeVSTRVLDR_SYSREG<true>"; 2822 } 2823 2824 def _post : 2825 vfp_vstrldr<opc, 0, 1, SysReg, sysreg, 2826 !con(oops, (outs GPRnopc:$wb)), 2827 !con(iops, (ins t2_addr_offset_none:$Rn, 2828 t2am_imm7s4_offset:$addr)), 2829 IndexModePost, "$Rn$addr", "$Rn.base = $wb"> { 2830 bits<4> Rn; 2831 let Inst{19-16} = Rn{3-0}; 2832 let DecoderMethod = "DecodeVSTRVLDR_SYSREG<true>"; 2833 } 2834} 2835 2836let Defs = [FPSCR] in { 2837 defm VSTR_FPSCR : vfp_vstrldr_sysreg<0b0,0b0001, "fpscr">; 2838 defm VSTR_FPSCR_NZCVQC : vfp_vstrldr_sysreg<0b0,0b0010, "fpscr_nzcvqc">; 2839 2840 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2841 defm VSTR_FPCXTNS : vfp_vstrldr_sysreg<0b0,0b1110, "fpcxtns">; 2842 defm VSTR_FPCXTS : vfp_vstrldr_sysreg<0b0,0b1111, "fpcxts">; 2843 } 2844} 2845 2846let Predicates = [HasV8_1MMainline, HasMVEInt] in { 2847 let Uses = [VPR] in { 2848 defm VSTR_VPR : vfp_vstrldr_sysreg<0b0,0b1100, "vpr">; 2849 } 2850 defm VSTR_P0 : vfp_vstrldr_sysreg<0b0,0b1101, "p0", 2851 (outs), (ins VCCR:$P0)>; 2852} 2853 2854let Uses = [FPSCR] in { 2855 defm VLDR_FPSCR : vfp_vstrldr_sysreg<0b1,0b0001, "fpscr">; 2856 defm VLDR_FPSCR_NZCVQC : vfp_vstrldr_sysreg<0b1,0b0010, "fpscr_nzcvqc">; 2857 2858 let Predicates = [HasV8_1MMainline, Has8MSecExt] in { 2859 defm VLDR_FPCXTNS : vfp_vstrldr_sysreg<0b1,0b1110, "fpcxtns">; 2860 defm VLDR_FPCXTS : vfp_vstrldr_sysreg<0b1,0b1111, "fpcxts">; 2861 } 2862} 2863 2864let Predicates = [HasV8_1MMainline, HasMVEInt] in { 2865 let Defs = [VPR] in { 2866 defm VLDR_VPR : vfp_vstrldr_sysreg<0b1,0b1100, "vpr">; 2867 } 2868 defm VLDR_P0 : vfp_vstrldr_sysreg<0b1,0b1101, "p0", 2869 (outs VCCR:$P0), (ins)>; 2870} 2871