1//===- ARMInstrVFP.td - VFP support for ARM -------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file describes the ARM VFP instruction set. 11// 12//===----------------------------------------------------------------------===// 13 14def SDT_FTOI : 15SDTypeProfile<1, 1, [SDTCisVT<0, f32>, SDTCisFP<1>]>; 16def SDT_ITOF : 17SDTypeProfile<1, 1, [SDTCisFP<0>, SDTCisVT<1, f32>]>; 18def SDT_CMPFP0 : 19SDTypeProfile<0, 1, [SDTCisFP<0>]>; 20def SDT_FMDRR : 21SDTypeProfile<1, 2, [SDTCisVT<0, f64>, SDTCisVT<1, i32>, 22 SDTCisSameAs<1, 2>]>; 23 24def arm_ftoui : SDNode<"ARMISD::FTOUI", SDT_FTOI>; 25def arm_ftosi : SDNode<"ARMISD::FTOSI", SDT_FTOI>; 26def arm_sitof : SDNode<"ARMISD::SITOF", SDT_ITOF>; 27def arm_uitof : SDNode<"ARMISD::UITOF", SDT_ITOF>; 28def arm_fmstat : SDNode<"ARMISD::FMSTAT", SDTNone, [SDNPInFlag,SDNPOutFlag]>; 29def arm_cmpfp : SDNode<"ARMISD::CMPFP", SDT_ARMCmp, [SDNPOutFlag]>; 30def arm_cmpfp0 : SDNode<"ARMISD::CMPFPw0",SDT_CMPFP0, [SDNPOutFlag]>; 31def arm_fmdrr : SDNode<"ARMISD::FMDRR", SDT_FMDRR>; 32 33//===----------------------------------------------------------------------===// 34// Load / store Instructions. 35// 36 37let canFoldAsLoad = 1 in { 38def FLDD : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr), 39 "fldd", " $dst, $addr", 40 [(set DPR:$dst, (load addrmode5:$addr))]>; 41 42def FLDS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr), 43 "flds", " $dst, $addr", 44 [(set SPR:$dst, (load addrmode5:$addr))]>; 45} // canFoldAsLoad 46 47def FSTD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr), 48 "fstd", " $src, $addr", 49 [(store DPR:$src, addrmode5:$addr)]>; 50 51def FSTS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr), 52 "fsts", " $src, $addr", 53 [(store SPR:$src, addrmode5:$addr)]>; 54 55//===----------------------------------------------------------------------===// 56// Load / store multiple Instructions. 57// 58 59let mayLoad = 1 in { 60def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1, 61 variable_ops), 62 "fldm${addr:submode}d${p} ${addr:base}, $dst1", 63 []> { 64 let Inst{20} = 1; 65} 66 67def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1, 68 variable_ops), 69 "fldm${addr:submode}s${p} ${addr:base}, $dst1", 70 []> { 71 let Inst{20} = 1; 72} 73} 74 75let mayStore = 1 in { 76def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1, 77 variable_ops), 78 "fstm${addr:submode}d${p} ${addr:base}, $src1", 79 []> { 80 let Inst{20} = 0; 81} 82 83def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1, 84 variable_ops), 85 "fstm${addr:submode}s${p} ${addr:base}, $src1", 86 []> { 87 let Inst{20} = 0; 88} 89} // mayStore 90 91// FLDMX, FSTMX - mixing S/D registers for pre-armv6 cores 92 93//===----------------------------------------------------------------------===// 94// FP Binary Operations. 95// 96 97def FADDD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b), 98 "faddd", " $dst, $a, $b", 99 [(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>; 100 101def FADDS : ASbI<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b), 102 "fadds", " $dst, $a, $b", 103 [(set SPR:$dst, (fadd SPR:$a, SPR:$b))]>; 104 105// These are encoded as unary instructions. 106let Defs = [FPSCR] in { 107def FCMPED : ADuI<0b11101011, 0b0100, 0b1100, (outs), (ins DPR:$a, DPR:$b), 108 "fcmped", " $a, $b", 109 [(arm_cmpfp DPR:$a, DPR:$b)]>; 110 111def FCMPES : ASuI<0b11101011, 0b0100, 0b1100, (outs), (ins SPR:$a, SPR:$b), 112 "fcmpes", " $a, $b", 113 [(arm_cmpfp SPR:$a, SPR:$b)]>; 114} 115 116def FDIVD : ADbI<0b11101000, (outs DPR:$dst), (ins DPR:$a, DPR:$b), 117 "fdivd", " $dst, $a, $b", 118 [(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>; 119 120def FDIVS : ASbI<0b11101000, (outs SPR:$dst), (ins SPR:$a, SPR:$b), 121 "fdivs", " $dst, $a, $b", 122 [(set SPR:$dst, (fdiv SPR:$a, SPR:$b))]>; 123 124def FMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b), 125 "fmuld", " $dst, $a, $b", 126 [(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>; 127 128def FMULS : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b), 129 "fmuls", " $dst, $a, $b", 130 [(set SPR:$dst, (fmul SPR:$a, SPR:$b))]>; 131 132def FNMULD : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b), 133 "fnmuld", " $dst, $a, $b", 134 [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]> { 135 let Inst{6} = 1; 136} 137 138def FNMULS : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b), 139 "fnmuls", " $dst, $a, $b", 140 [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]> { 141 let Inst{6} = 1; 142} 143 144// Match reassociated forms only if not sign dependent rounding. 145def : Pat<(fmul (fneg DPR:$a), DPR:$b), 146 (FNMULD DPR:$a, DPR:$b)>, Requires<[NoHonorSignDependentRounding]>; 147def : Pat<(fmul (fneg SPR:$a), SPR:$b), 148 (FNMULS SPR:$a, SPR:$b)>, Requires<[NoHonorSignDependentRounding]>; 149 150 151def FSUBD : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b), 152 "fsubd", " $dst, $a, $b", 153 [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]> { 154 let Inst{6} = 1; 155} 156 157def FSUBS : ASbI<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b), 158 "fsubs", " $dst, $a, $b", 159 [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]> { 160 let Inst{6} = 1; 161} 162 163//===----------------------------------------------------------------------===// 164// FP Unary Operations. 165// 166 167def FABSD : ADuI<0b11101011, 0b0000, 0b1100, (outs DPR:$dst), (ins DPR:$a), 168 "fabsd", " $dst, $a", 169 [(set DPR:$dst, (fabs DPR:$a))]>; 170 171def FABSS : ASuI<0b11101011, 0b0000, 0b1100, (outs SPR:$dst), (ins SPR:$a), 172 "fabss", " $dst, $a", 173 [(set SPR:$dst, (fabs SPR:$a))]>; 174 175let Defs = [FPSCR] in { 176def FCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a), 177 "fcmpezd", " $a", 178 [(arm_cmpfp0 DPR:$a)]>; 179 180def FCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a), 181 "fcmpezs", " $a", 182 [(arm_cmpfp0 SPR:$a)]>; 183} 184 185def FCVTDS : ASuI<0b11101011, 0b0111, 0b1100, (outs DPR:$dst), (ins SPR:$a), 186 "fcvtds", " $dst, $a", 187 [(set DPR:$dst, (fextend SPR:$a))]>; 188 189// Special case encoding: bits 11-8 is 0b1011. 190def FCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm, 191 "fcvtsd", " $dst, $a", 192 [(set SPR:$dst, (fround DPR:$a))]> { 193 let Inst{27-23} = 0b11101; 194 let Inst{21-16} = 0b110111; 195 let Inst{11-8} = 0b1011; 196 let Inst{7-4} = 0b1100; 197} 198 199let neverHasSideEffects = 1 in { 200def FCPYD : ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins DPR:$a), 201 "fcpyd", " $dst, $a", []>; 202 203def FCPYS : ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins SPR:$a), 204 "fcpys", " $dst, $a", []>; 205} // neverHasSideEffects 206 207def FNEGD : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins DPR:$a), 208 "fnegd", " $dst, $a", 209 [(set DPR:$dst, (fneg DPR:$a))]>; 210 211def FNEGS : ASuI<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins SPR:$a), 212 "fnegs", " $dst, $a", 213 [(set SPR:$dst, (fneg SPR:$a))]>; 214 215def FSQRTD : ADuI<0b11101011, 0b0001, 0b1100, (outs DPR:$dst), (ins DPR:$a), 216 "fsqrtd", " $dst, $a", 217 [(set DPR:$dst, (fsqrt DPR:$a))]>; 218 219def FSQRTS : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins SPR:$a), 220 "fsqrts", " $dst, $a", 221 [(set SPR:$dst, (fsqrt SPR:$a))]>; 222 223//===----------------------------------------------------------------------===// 224// FP <-> GPR Copies. Int <-> FP Conversions. 225// 226 227def FMRS : AVConv2I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src), 228 "fmrs", " $dst, $src", 229 [(set GPR:$dst, (bitconvert SPR:$src))]>; 230 231def FMSR : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src), 232 "fmsr", " $dst, $src", 233 [(set SPR:$dst, (bitconvert GPR:$src))]>; 234 235def FMRRD : AVConv3I<0b11000101, 0b1011, 236 (outs GPR:$dst1, GPR:$dst2), (ins DPR:$src), 237 "fmrrd", " $dst1, $dst2, $src", 238 [/* FIXME: Can't write pattern for multiple result instr*/]>; 239 240// FMDHR: GPR -> SPR 241// FMDLR: GPR -> SPR 242 243def FMDRR : AVConv5I<0b11000100, 0b1011, 244 (outs DPR:$dst), (ins GPR:$src1, GPR:$src2), 245 "fmdrr", " $dst, $src1, $src2", 246 [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>; 247 248// FMRDH: SPR -> GPR 249// FMRDL: SPR -> GPR 250// FMRRS: SPR -> GPR 251// FMRX : SPR system reg -> GPR 252 253// FMSRR: GPR -> SPR 254 255// FMXR: GPR -> VFP Sstem reg 256 257 258// Int to FP: 259 260def FSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a), 261 "fsitod", " $dst, $a", 262 [(set DPR:$dst, (arm_sitof SPR:$a))]> { 263 let Inst{7} = 1; 264} 265 266def FSITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a), 267 "fsitos", " $dst, $a", 268 [(set SPR:$dst, (arm_sitof SPR:$a))]> { 269 let Inst{7} = 1; 270} 271 272def FUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a), 273 "fuitod", " $dst, $a", 274 [(set DPR:$dst, (arm_uitof SPR:$a))]>; 275 276def FUITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a), 277 "fuitos", " $dst, $a", 278 [(set SPR:$dst, (arm_uitof SPR:$a))]>; 279 280// FP to Int: 281// Always set Z bit in the instruction, i.e. "round towards zero" variants. 282 283def FTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011, 284 (outs SPR:$dst), (ins DPR:$a), 285 "ftosizd", " $dst, $a", 286 [(set SPR:$dst, (arm_ftosi DPR:$a))]> { 287 let Inst{7} = 1; // Z bit 288} 289 290def FTOSIZS : AVConv1I<0b11101011, 0b1101, 0b1010, 291 (outs SPR:$dst), (ins SPR:$a), 292 "ftosizs", " $dst, $a", 293 [(set SPR:$dst, (arm_ftosi SPR:$a))]> { 294 let Inst{7} = 1; // Z bit 295} 296 297def FTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011, 298 (outs SPR:$dst), (ins DPR:$a), 299 "ftouizd", " $dst, $a", 300 [(set SPR:$dst, (arm_ftoui DPR:$a))]> { 301 let Inst{7} = 1; // Z bit 302} 303 304def FTOUIZS : AVConv1I<0b11101011, 0b1100, 0b1010, 305 (outs SPR:$dst), (ins SPR:$a), 306 "ftouizs", " $dst, $a", 307 [(set SPR:$dst, (arm_ftoui SPR:$a))]> { 308 let Inst{7} = 1; // Z bit 309} 310 311//===----------------------------------------------------------------------===// 312// FP FMA Operations. 313// 314 315def FMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), 316 "fmacd", " $dst, $a, $b", 317 [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>, 318 RegConstraint<"$dstin = $dst">; 319 320def FMACS : ASbI<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), 321 "fmacs", " $dst, $a, $b", 322 [(set SPR:$dst, (fadd (fmul SPR:$a, SPR:$b), SPR:$dstin))]>, 323 RegConstraint<"$dstin = $dst">; 324 325def FMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), 326 "fmscd", " $dst, $a, $b", 327 [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>, 328 RegConstraint<"$dstin = $dst">; 329 330def FMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), 331 "fmscs", " $dst, $a, $b", 332 [(set SPR:$dst, (fsub (fmul SPR:$a, SPR:$b), SPR:$dstin))]>, 333 RegConstraint<"$dstin = $dst">; 334 335def FNMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), 336 "fnmacd", " $dst, $a, $b", 337 [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>, 338 RegConstraint<"$dstin = $dst"> { 339 let Inst{6} = 1; 340} 341 342def FNMACS : ASbI<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), 343 "fnmacs", " $dst, $a, $b", 344 [(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>, 345 RegConstraint<"$dstin = $dst"> { 346 let Inst{6} = 1; 347} 348 349def FNMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b), 350 "fnmscd", " $dst, $a, $b", 351 [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>, 352 RegConstraint<"$dstin = $dst"> { 353 let Inst{6} = 1; 354} 355 356def FNMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b), 357 "fnmscs", " $dst, $a, $b", 358 [(set SPR:$dst, (fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>, 359 RegConstraint<"$dstin = $dst"> { 360 let Inst{6} = 1; 361} 362 363//===----------------------------------------------------------------------===// 364// FP Conditional moves. 365// 366 367def FCPYDcc : ADuI<0b11101011, 0b0000, 0b0100, 368 (outs DPR:$dst), (ins DPR:$false, DPR:$true), 369 "fcpyd", " $dst, $true", 370 [/*(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, imm:$cc))*/]>, 371 RegConstraint<"$false = $dst">; 372 373def FCPYScc : ASuI<0b11101011, 0b0000, 0b0100, 374 (outs SPR:$dst), (ins SPR:$false, SPR:$true), 375 "fcpys", " $dst, $true", 376 [/*(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, imm:$cc))*/]>, 377 RegConstraint<"$false = $dst">; 378 379def FNEGDcc : ADuI<0b11101011, 0b0001, 0b0100, 380 (outs DPR:$dst), (ins DPR:$false, DPR:$true), 381 "fnegd", " $dst, $true", 382 [/*(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, imm:$cc))*/]>, 383 RegConstraint<"$false = $dst">; 384 385def FNEGScc : ASuI<0b11101011, 0b0001, 0b0100, 386 (outs SPR:$dst), (ins SPR:$false, SPR:$true), 387 "fnegs", " $dst, $true", 388 [/*(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, imm:$cc))*/]>, 389 RegConstraint<"$false = $dst">; 390 391 392//===----------------------------------------------------------------------===// 393// Misc. 394// 395 396let Defs = [CPSR], Uses = [FPSCR] in 397def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, "fmstat", "", [(arm_fmstat)]> { 398 let Inst{27-20} = 0b11101111; 399 let Inst{19-16} = 0b0001; 400 let Inst{15-12} = 0b1111; 401 let Inst{11-8} = 0b1010; 402 let Inst{7} = 0; 403 let Inst{4} = 1; 404} 405