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