fp.isa revision 7376:3b781776b2d9
1// -*- mode:c++ -*- 2 3// Copyright (c) 2010 ARM Limited 4// All rights reserved 5// 6// The license below extends only to copyright in the software and shall 7// not be construed as granting a license to any other intellectual 8// property including but not limited to intellectual property relating 9// to a hardware implementation of the functionality of the software 10// licensed hereunder. You may use the software subject to the license 11// terms below provided that you ensure that this notice is replicated 12// unmodified and in its entirety in all distributions of the software, 13// modified or unmodified, in source code or in binary form. 14// 15// Redistribution and use in source and binary forms, with or without 16// modification, are permitted provided that the following conditions are 17// met: redistributions of source code must retain the above copyright 18// notice, this list of conditions and the following disclaimer; 19// redistributions in binary form must reproduce the above copyright 20// notice, this list of conditions and the following disclaimer in the 21// documentation and/or other materials provided with the distribution; 22// neither the name of the copyright holders nor the names of its 23// contributors may be used to endorse or promote products derived from 24// this software without specific prior written permission. 25// 26// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 27// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 28// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 29// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 30// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 31// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 32// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 36// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37// 38// Authors: Gabe Black 39 40output header {{ 41 42template <class Micro> 43class VfpMacroRegRegOp : public VfpMacroOp 44{ 45 public: 46 VfpMacroRegRegOp(ExtMachInst _machInst, IntRegIndex _dest, 47 IntRegIndex _op1, bool _wide) : 48 VfpMacroOp("VfpMacroRegRegOp", _machInst, No_OpClass, _wide) 49 { 50 numMicroops = machInst.fpscrLen + 1; 51 assert(numMicroops > 1); 52 microOps = new StaticInstPtr[numMicroops]; 53 for (unsigned i = 0; i < numMicroops; i++) { 54 VfpMicroMode mode = VfpMicroop; 55 if (i == 0) 56 mode = VfpFirstMicroop; 57 else if (i == numMicroops - 1) 58 mode = VfpLastMicroop; 59 microOps[i] = new Micro(_machInst, _dest, _op1, mode); 60 nextIdxs(_dest, _op1); 61 } 62 } 63 64 %(BasicExecPanic)s 65}; 66 67template <class VfpOp> 68static StaticInstPtr 69decodeVfpRegRegOp(ExtMachInst machInst, 70 IntRegIndex dest, IntRegIndex op1, bool wide) 71{ 72 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) { 73 return new VfpOp(machInst, dest, op1); 74 } else { 75 return new VfpMacroRegRegOp<VfpOp>(machInst, dest, op1, wide); 76 } 77} 78 79template <class Micro> 80class VfpMacroRegImmOp : public VfpMacroOp 81{ 82 public: 83 VfpMacroRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, uint64_t _imm, 84 bool _wide) : 85 VfpMacroOp("VfpMacroRegImmOp", _machInst, No_OpClass, _wide) 86 { 87 numMicroops = machInst.fpscrLen + 1; 88 microOps = new StaticInstPtr[numMicroops]; 89 for (unsigned i = 0; i < numMicroops; i++) { 90 VfpMicroMode mode = VfpMicroop; 91 if (i == 0) 92 mode = VfpFirstMicroop; 93 else if (i == numMicroops - 1) 94 mode = VfpLastMicroop; 95 microOps[i] = new Micro(_machInst, _dest, _imm, mode); 96 nextIdxs(_dest); 97 } 98 } 99 100 %(BasicExecPanic)s 101}; 102 103template <class VfpOp> 104static StaticInstPtr 105decodeVfpRegImmOp(ExtMachInst machInst, 106 IntRegIndex dest, uint64_t imm, bool wide) 107{ 108 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) { 109 return new VfpOp(machInst, dest, imm); 110 } else { 111 return new VfpMacroRegImmOp<VfpOp>(machInst, dest, imm, wide); 112 } 113} 114 115template <class Micro> 116class VfpMacroRegRegImmOp : public VfpMacroOp 117{ 118 public: 119 VfpMacroRegRegImmOp(ExtMachInst _machInst, IntRegIndex _dest, 120 IntRegIndex _op1, uint64_t _imm, bool _wide) : 121 VfpMacroOp("VfpMacroRegRegImmOp", _machInst, No_OpClass, _wide) 122 { 123 numMicroops = machInst.fpscrLen + 1; 124 microOps = new StaticInstPtr[numMicroops]; 125 for (unsigned i = 0; i < numMicroops; i++) { 126 VfpMicroMode mode = VfpMicroop; 127 if (i == 0) 128 mode = VfpFirstMicroop; 129 else if (i == numMicroops - 1) 130 mode = VfpLastMicroop; 131 microOps[i] = new Micro(_machInst, _dest, _op1, _imm, mode); 132 nextIdxs(_dest, _op1); 133 } 134 } 135 136 %(BasicExecPanic)s 137}; 138 139template <class VfpOp> 140static StaticInstPtr 141decodeVfpRegRegImmOp(ExtMachInst machInst, IntRegIndex dest, 142 IntRegIndex op1, uint64_t imm, bool wide) 143{ 144 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) { 145 return new VfpOp(machInst, dest, op1, imm); 146 } else { 147 return new VfpMacroRegRegImmOp<VfpOp>(machInst, dest, op1, imm, wide); 148 } 149} 150 151template <class Micro> 152class VfpMacroRegRegRegOp : public VfpMacroOp 153{ 154 public: 155 VfpMacroRegRegRegOp(ExtMachInst _machInst, IntRegIndex _dest, 156 IntRegIndex _op1, IntRegIndex _op2, bool _wide) : 157 VfpMacroOp("VfpMacroRegRegRegOp", _machInst, No_OpClass, _wide) 158 { 159 numMicroops = machInst.fpscrLen + 1; 160 microOps = new StaticInstPtr[numMicroops]; 161 for (unsigned i = 0; i < numMicroops; i++) { 162 VfpMicroMode mode = VfpMicroop; 163 if (i == 0) 164 mode = VfpFirstMicroop; 165 else if (i == numMicroops - 1) 166 mode = VfpLastMicroop; 167 microOps[i] = new Micro(_machInst, _dest, _op1, _op2, mode); 168 nextIdxs(_dest, _op1, _op2); 169 } 170 } 171 172 %(BasicExecPanic)s 173}; 174 175template <class VfpOp> 176static StaticInstPtr 177decodeVfpRegRegRegOp(ExtMachInst machInst, IntRegIndex dest, 178 IntRegIndex op1, IntRegIndex op2, bool wide) 179{ 180 if (machInst.fpscrLen == 0 || VfpMacroOp::inScalarBank(dest)) { 181 return new VfpOp(machInst, dest, op1, op2); 182 } else { 183 return new VfpMacroRegRegRegOp<VfpOp>(machInst, dest, op1, op2, wide); 184 } 185} 186}}; 187 188let {{ 189 190 header_output = "" 191 decoder_output = "" 192 exec_output = "" 193 194 vmsrIop = InstObjParams("vmsr", "Vmsr", "VfpRegRegOp", 195 { "code": "MiscDest = Op1;", 196 "predicate_test": predicateTest }, []) 197 header_output += VfpRegRegOpDeclare.subst(vmsrIop); 198 decoder_output += VfpRegRegOpConstructor.subst(vmsrIop); 199 exec_output += PredOpExecute.subst(vmsrIop); 200 201 vmrsIop = InstObjParams("vmrs", "Vmrs", "VfpRegRegOp", 202 { "code": "Dest = MiscOp1;", 203 "predicate_test": predicateTest }, []) 204 header_output += VfpRegRegOpDeclare.subst(vmrsIop); 205 decoder_output += VfpRegRegOpConstructor.subst(vmrsIop); 206 exec_output += PredOpExecute.subst(vmrsIop); 207 208 vmovImmSCode = ''' 209 FpDest.uw = bits(imm, 31, 0); 210 ''' 211 vmovImmSIop = InstObjParams("vmov", "VmovImmS", "VfpRegImmOp", 212 { "code": vmovImmSCode, 213 "predicate_test": predicateTest }, []) 214 header_output += VfpRegImmOpDeclare.subst(vmovImmSIop); 215 decoder_output += VfpRegImmOpConstructor.subst(vmovImmSIop); 216 exec_output += PredOpExecute.subst(vmovImmSIop); 217 218 vmovImmDCode = ''' 219 FpDestP0.uw = bits(imm, 31, 0); 220 FpDestP1.uw = bits(imm, 63, 32); 221 ''' 222 vmovImmDIop = InstObjParams("vmov", "VmovImmD", "VfpRegImmOp", 223 { "code": vmovImmDCode, 224 "predicate_test": predicateTest }, []) 225 header_output += VfpRegImmOpDeclare.subst(vmovImmDIop); 226 decoder_output += VfpRegImmOpConstructor.subst(vmovImmDIop); 227 exec_output += PredOpExecute.subst(vmovImmDIop); 228 229 vmovImmQCode = ''' 230 FpDestP0.uw = bits(imm, 31, 0); 231 FpDestP1.uw = bits(imm, 63, 32); 232 FpDestP2.uw = bits(imm, 31, 0); 233 FpDestP3.uw = bits(imm, 63, 32); 234 ''' 235 vmovImmQIop = InstObjParams("vmov", "VmovImmQ", "VfpRegImmOp", 236 { "code": vmovImmQCode, 237 "predicate_test": predicateTest }, []) 238 header_output += VfpRegImmOpDeclare.subst(vmovImmQIop); 239 decoder_output += VfpRegImmOpConstructor.subst(vmovImmQIop); 240 exec_output += PredOpExecute.subst(vmovImmQIop); 241 242 vmovRegSCode = ''' 243 FpDest.uw = FpOp1.uw; 244 ''' 245 vmovRegSIop = InstObjParams("vmov", "VmovRegS", "VfpRegRegOp", 246 { "code": vmovRegSCode, 247 "predicate_test": predicateTest }, []) 248 header_output += VfpRegRegOpDeclare.subst(vmovRegSIop); 249 decoder_output += VfpRegRegOpConstructor.subst(vmovRegSIop); 250 exec_output += PredOpExecute.subst(vmovRegSIop); 251 252 vmovRegDCode = ''' 253 FpDestP0.uw = FpOp1P0.uw; 254 FpDestP1.uw = FpOp1P1.uw; 255 ''' 256 vmovRegDIop = InstObjParams("vmov", "VmovRegD", "VfpRegRegOp", 257 { "code": vmovRegDCode, 258 "predicate_test": predicateTest }, []) 259 header_output += VfpRegRegOpDeclare.subst(vmovRegDIop); 260 decoder_output += VfpRegRegOpConstructor.subst(vmovRegDIop); 261 exec_output += PredOpExecute.subst(vmovRegDIop); 262 263 vmovRegQCode = ''' 264 FpDestP0.uw = FpOp1P0.uw; 265 FpDestP1.uw = FpOp1P1.uw; 266 FpDestP2.uw = FpOp1P2.uw; 267 FpDestP3.uw = FpOp1P3.uw; 268 ''' 269 vmovRegQIop = InstObjParams("vmov", "VmovRegQ", "VfpRegRegOp", 270 { "code": vmovRegQCode, 271 "predicate_test": predicateTest }, []) 272 header_output += VfpRegRegOpDeclare.subst(vmovRegQIop); 273 decoder_output += VfpRegRegOpConstructor.subst(vmovRegQIop); 274 exec_output += PredOpExecute.subst(vmovRegQIop); 275 276 vmovCoreRegBCode = ''' 277 FpDest.uw = insertBits(FpDest.uw, imm * 8, imm * 8 + 7, Op1.ub); 278 ''' 279 vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "VfpRegRegImmOp", 280 { "code": vmovCoreRegBCode, 281 "predicate_test": predicateTest }, []) 282 header_output += VfpRegRegImmOpDeclare.subst(vmovCoreRegBIop); 283 decoder_output += VfpRegRegImmOpConstructor.subst(vmovCoreRegBIop); 284 exec_output += PredOpExecute.subst(vmovCoreRegBIop); 285 286 vmovCoreRegHCode = ''' 287 FpDest.uw = insertBits(FpDest.uw, imm * 16, imm * 16 + 15, Op1.uh); 288 ''' 289 vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "VfpRegRegImmOp", 290 { "code": vmovCoreRegHCode, 291 "predicate_test": predicateTest }, []) 292 header_output += VfpRegRegImmOpDeclare.subst(vmovCoreRegHIop); 293 decoder_output += VfpRegRegImmOpConstructor.subst(vmovCoreRegHIop); 294 exec_output += PredOpExecute.subst(vmovCoreRegHIop); 295 296 vmovCoreRegWCode = ''' 297 FpDest.uw = Op1.uw; 298 ''' 299 vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "VfpRegRegOp", 300 { "code": vmovCoreRegWCode, 301 "predicate_test": predicateTest }, []) 302 header_output += VfpRegRegOpDeclare.subst(vmovCoreRegWIop); 303 decoder_output += VfpRegRegOpConstructor.subst(vmovCoreRegWIop); 304 exec_output += PredOpExecute.subst(vmovCoreRegWIop); 305 306 vmovRegCoreUBCode = ''' 307 Dest = bits(FpOp1.uw, imm * 8, imm * 8 + 7); 308 ''' 309 vmovRegCoreUBIop = InstObjParams("vmov", "VmovRegCoreUB", "VfpRegRegImmOp", 310 { "code": vmovRegCoreUBCode, 311 "predicate_test": predicateTest }, []) 312 header_output += VfpRegRegImmOpDeclare.subst(vmovRegCoreUBIop); 313 decoder_output += VfpRegRegImmOpConstructor.subst(vmovRegCoreUBIop); 314 exec_output += PredOpExecute.subst(vmovRegCoreUBIop); 315 316 vmovRegCoreUHCode = ''' 317 Dest = bits(FpOp1.uw, imm * 16, imm * 16 + 15); 318 ''' 319 vmovRegCoreUHIop = InstObjParams("vmov", "VmovRegCoreUH", "VfpRegRegImmOp", 320 { "code": vmovRegCoreUHCode, 321 "predicate_test": predicateTest }, []) 322 header_output += VfpRegRegImmOpDeclare.subst(vmovRegCoreUHIop); 323 decoder_output += VfpRegRegImmOpConstructor.subst(vmovRegCoreUHIop); 324 exec_output += PredOpExecute.subst(vmovRegCoreUHIop); 325 326 vmovRegCoreSBCode = ''' 327 Dest = sext<8>(bits(FpOp1.uw, imm * 8, imm * 8 + 7)); 328 ''' 329 vmovRegCoreSBIop = InstObjParams("vmov", "VmovRegCoreSB", "VfpRegRegImmOp", 330 { "code": vmovRegCoreSBCode, 331 "predicate_test": predicateTest }, []) 332 header_output += VfpRegRegImmOpDeclare.subst(vmovRegCoreSBIop); 333 decoder_output += VfpRegRegImmOpConstructor.subst(vmovRegCoreSBIop); 334 exec_output += PredOpExecute.subst(vmovRegCoreSBIop); 335 336 vmovRegCoreSHCode = ''' 337 Dest = sext<16>(bits(FpOp1.uw, imm * 16, imm * 16 + 15)); 338 ''' 339 vmovRegCoreSHIop = InstObjParams("vmov", "VmovRegCoreSH", "VfpRegRegImmOp", 340 { "code": vmovRegCoreSHCode, 341 "predicate_test": predicateTest }, []) 342 header_output += VfpRegRegImmOpDeclare.subst(vmovRegCoreSHIop); 343 decoder_output += VfpRegRegImmOpConstructor.subst(vmovRegCoreSHIop); 344 exec_output += PredOpExecute.subst(vmovRegCoreSHIop); 345 346 vmovRegCoreWCode = ''' 347 Dest = FpOp1.uw; 348 ''' 349 vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "VfpRegRegOp", 350 { "code": vmovRegCoreWCode, 351 "predicate_test": predicateTest }, []) 352 header_output += VfpRegRegOpDeclare.subst(vmovRegCoreWIop); 353 decoder_output += VfpRegRegOpConstructor.subst(vmovRegCoreWIop); 354 exec_output += PredOpExecute.subst(vmovRegCoreWIop); 355 356 vmov2Reg2CoreCode = ''' 357 FpDestP0.uw = Op1.uw; 358 FpDestP1.uw = Op2.uw; 359 ''' 360 vmov2Reg2CoreIop = InstObjParams("vmov", "Vmov2Reg2Core", "VfpRegRegRegOp", 361 { "code": vmov2Reg2CoreCode, 362 "predicate_test": predicateTest }, []) 363 header_output += VfpRegRegRegOpDeclare.subst(vmov2Reg2CoreIop); 364 decoder_output += VfpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop); 365 exec_output += PredOpExecute.subst(vmov2Reg2CoreIop); 366 367 vmov2Core2RegCode = ''' 368 Dest.uw = FpOp2P0.uw; 369 Op1.uw = FpOp2P1.uw; 370 ''' 371 vmov2Core2RegIop = InstObjParams("vmov", "Vmov2Core2Reg", "VfpRegRegRegOp", 372 { "code": vmov2Core2RegCode, 373 "predicate_test": predicateTest }, []) 374 header_output += VfpRegRegRegOpDeclare.subst(vmov2Core2RegIop); 375 decoder_output += VfpRegRegRegOpConstructor.subst(vmov2Core2RegIop); 376 exec_output += PredOpExecute.subst(vmov2Core2RegIop); 377 378 vmulSCode = ''' 379 FpDest = FpOp1 * FpOp2; 380 if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { 381 FpDest = NAN; 382 } 383 ''' 384 vmulSIop = InstObjParams("vmuls", "VmulS", "VfpRegRegRegOp", 385 { "code": vmulSCode, 386 "predicate_test": predicateTest }, []) 387 header_output += VfpRegRegRegOpDeclare.subst(vmulSIop); 388 decoder_output += VfpRegRegRegOpConstructor.subst(vmulSIop); 389 exec_output += PredOpExecute.subst(vmulSIop); 390 391 vmulDCode = ''' 392 IntDoubleUnion cOp1, cOp2, cDest; 393 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 394 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 395 cDest.fp = cOp1.fp * cOp2.fp; 396 if ((isinf(cOp1.fp) && cOp2.fp == 0) || 397 (isinf(cOp2.fp) && cOp1.fp == 0)) { 398 cDest.fp = NAN; 399 } 400 FpDestP0.uw = cDest.bits; 401 FpDestP1.uw = cDest.bits >> 32; 402 ''' 403 vmulDIop = InstObjParams("vmuld", "VmulD", "VfpRegRegRegOp", 404 { "code": vmulDCode, 405 "predicate_test": predicateTest }, []) 406 header_output += VfpRegRegRegOpDeclare.subst(vmulDIop); 407 decoder_output += VfpRegRegRegOpConstructor.subst(vmulDIop); 408 exec_output += PredOpExecute.subst(vmulDIop); 409 410 vnegSCode = ''' 411 FpDest = -FpOp1; 412 ''' 413 vnegSIop = InstObjParams("vnegs", "VnegS", "VfpRegRegOp", 414 { "code": vnegSCode, 415 "predicate_test": predicateTest }, []) 416 header_output += VfpRegRegOpDeclare.subst(vnegSIop); 417 decoder_output += VfpRegRegOpConstructor.subst(vnegSIop); 418 exec_output += PredOpExecute.subst(vnegSIop); 419 420 vnegDCode = ''' 421 IntDoubleUnion cOp1, cDest; 422 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 423 cDest.fp = -cOp1.fp; 424 FpDestP0.uw = cDest.bits; 425 FpDestP1.uw = cDest.bits >> 32; 426 ''' 427 vnegDIop = InstObjParams("vnegd", "VnegD", "VfpRegRegOp", 428 { "code": vnegDCode, 429 "predicate_test": predicateTest }, []) 430 header_output += VfpRegRegOpDeclare.subst(vnegDIop); 431 decoder_output += VfpRegRegOpConstructor.subst(vnegDIop); 432 exec_output += PredOpExecute.subst(vnegDIop); 433 434 vabsSCode = ''' 435 FpDest = fabsf(FpOp1); 436 ''' 437 vabsSIop = InstObjParams("vabss", "VabsS", "VfpRegRegOp", 438 { "code": vabsSCode, 439 "predicate_test": predicateTest }, []) 440 header_output += VfpRegRegOpDeclare.subst(vabsSIop); 441 decoder_output += VfpRegRegOpConstructor.subst(vabsSIop); 442 exec_output += PredOpExecute.subst(vabsSIop); 443 444 vabsDCode = ''' 445 IntDoubleUnion cOp1, cDest; 446 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 447 cDest.fp = fabs(cOp1.fp); 448 FpDestP0.uw = cDest.bits; 449 FpDestP1.uw = cDest.bits >> 32; 450 ''' 451 vabsDIop = InstObjParams("vabsd", "VabsD", "VfpRegRegOp", 452 { "code": vabsDCode, 453 "predicate_test": predicateTest }, []) 454 header_output += VfpRegRegOpDeclare.subst(vabsDIop); 455 decoder_output += VfpRegRegOpConstructor.subst(vabsDIop); 456 exec_output += PredOpExecute.subst(vabsDIop); 457 458 vaddSCode = ''' 459 FpDest = FpOp1 + FpOp2; 460 ''' 461 vaddSIop = InstObjParams("vadds", "VaddS", "VfpRegRegRegOp", 462 { "code": vaddSCode, 463 "predicate_test": predicateTest }, []) 464 header_output += VfpRegRegRegOpDeclare.subst(vaddSIop); 465 decoder_output += VfpRegRegRegOpConstructor.subst(vaddSIop); 466 exec_output += PredOpExecute.subst(vaddSIop); 467 468 vaddDCode = ''' 469 IntDoubleUnion cOp1, cOp2, cDest; 470 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 471 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 472 cDest.fp = cOp1.fp + cOp2.fp; 473 FpDestP0.uw = cDest.bits; 474 FpDestP1.uw = cDest.bits >> 32; 475 ''' 476 vaddDIop = InstObjParams("vaddd", "VaddD", "VfpRegRegRegOp", 477 { "code": vaddDCode, 478 "predicate_test": predicateTest }, []) 479 header_output += VfpRegRegRegOpDeclare.subst(vaddDIop); 480 decoder_output += VfpRegRegRegOpConstructor.subst(vaddDIop); 481 exec_output += PredOpExecute.subst(vaddDIop); 482 483 vsubSCode = ''' 484 FpDest = FpOp1 - FpOp2; 485 ''' 486 vsubSIop = InstObjParams("vsubs", "VsubS", "VfpRegRegRegOp", 487 { "code": vsubSCode, 488 "predicate_test": predicateTest }, []) 489 header_output += VfpRegRegRegOpDeclare.subst(vsubSIop); 490 decoder_output += VfpRegRegRegOpConstructor.subst(vsubSIop); 491 exec_output += PredOpExecute.subst(vsubSIop); 492 493 vsubDCode = ''' 494 IntDoubleUnion cOp1, cOp2, cDest; 495 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 496 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 497 cDest.fp = cOp1.fp - cOp2.fp; 498 FpDestP0.uw = cDest.bits; 499 FpDestP1.uw = cDest.bits >> 32; 500 ''' 501 vsubDIop = InstObjParams("vsubd", "VsubD", "VfpRegRegRegOp", 502 { "code": vsubDCode, 503 "predicate_test": predicateTest }, []) 504 header_output += VfpRegRegRegOpDeclare.subst(vsubDIop); 505 decoder_output += VfpRegRegRegOpConstructor.subst(vsubDIop); 506 exec_output += PredOpExecute.subst(vsubDIop); 507 508 vdivSCode = ''' 509 FpDest = FpOp1 / FpOp2; 510 ''' 511 vdivSIop = InstObjParams("vdivs", "VdivS", "VfpRegRegRegOp", 512 { "code": vdivSCode, 513 "predicate_test": predicateTest }, []) 514 header_output += VfpRegRegRegOpDeclare.subst(vdivSIop); 515 decoder_output += VfpRegRegRegOpConstructor.subst(vdivSIop); 516 exec_output += PredOpExecute.subst(vdivSIop); 517 518 vdivDCode = ''' 519 IntDoubleUnion cOp1, cOp2, cDest; 520 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 521 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 522 cDest.fp = cOp1.fp / cOp2.fp; 523 FpDestP0.uw = cDest.bits; 524 FpDestP1.uw = cDest.bits >> 32; 525 ''' 526 vdivDIop = InstObjParams("vdivd", "VdivD", "VfpRegRegRegOp", 527 { "code": vdivDCode, 528 "predicate_test": predicateTest }, []) 529 header_output += VfpRegRegRegOpDeclare.subst(vdivDIop); 530 decoder_output += VfpRegRegRegOpConstructor.subst(vdivDIop); 531 exec_output += PredOpExecute.subst(vdivDIop); 532 533 vsqrtSCode = ''' 534 FpDest = sqrtf(FpOp1); 535 if (FpOp1 < 0) { 536 FpDest = NAN; 537 } 538 ''' 539 vsqrtSIop = InstObjParams("vsqrts", "VsqrtS", "VfpRegRegOp", 540 { "code": vsqrtSCode, 541 "predicate_test": predicateTest }, []) 542 header_output += VfpRegRegOpDeclare.subst(vsqrtSIop); 543 decoder_output += VfpRegRegOpConstructor.subst(vsqrtSIop); 544 exec_output += PredOpExecute.subst(vsqrtSIop); 545 546 vsqrtDCode = ''' 547 IntDoubleUnion cOp1, cDest; 548 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 549 cDest.fp = sqrt(cOp1.fp); 550 if (cOp1.fp < 0) { 551 cDest.fp = NAN; 552 } 553 FpDestP0.uw = cDest.bits; 554 FpDestP1.uw = cDest.bits >> 32; 555 ''' 556 vsqrtDIop = InstObjParams("vsqrtd", "VsqrtD", "VfpRegRegOp", 557 { "code": vsqrtDCode, 558 "predicate_test": predicateTest }, []) 559 header_output += VfpRegRegOpDeclare.subst(vsqrtDIop); 560 decoder_output += VfpRegRegOpConstructor.subst(vsqrtDIop); 561 exec_output += PredOpExecute.subst(vsqrtDIop); 562 563 vmlaSCode = ''' 564 float mid = FpOp1 * FpOp2; 565 if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { 566 mid = NAN; 567 } 568 FpDest = FpDest + mid; 569 ''' 570 vmlaSIop = InstObjParams("vmlas", "VmlaS", "VfpRegRegRegOp", 571 { "code": vmlaSCode, 572 "predicate_test": predicateTest }, []) 573 header_output += VfpRegRegRegOpDeclare.subst(vmlaSIop); 574 decoder_output += VfpRegRegRegOpConstructor.subst(vmlaSIop); 575 exec_output += PredOpExecute.subst(vmlaSIop); 576 577 vmlaDCode = ''' 578 IntDoubleUnion cOp1, cOp2, cDest; 579 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 580 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 581 cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); 582 double mid = cOp1.fp * cOp2.fp; 583 if ((isinf(cOp1.fp) && cOp2.fp == 0) || 584 (isinf(cOp2.fp) && cOp1.fp == 0)) { 585 mid = NAN; 586 } 587 cDest.fp = cDest.fp + mid; 588 FpDestP0.uw = cDest.bits; 589 FpDestP1.uw = cDest.bits >> 32; 590 ''' 591 vmlaDIop = InstObjParams("vmlad", "VmlaD", "VfpRegRegRegOp", 592 { "code": vmlaDCode, 593 "predicate_test": predicateTest }, []) 594 header_output += VfpRegRegRegOpDeclare.subst(vmlaDIop); 595 decoder_output += VfpRegRegRegOpConstructor.subst(vmlaDIop); 596 exec_output += PredOpExecute.subst(vmlaDIop); 597 598 vmlsSCode = ''' 599 float mid = FpOp1 * FpOp2; 600 if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { 601 mid = NAN; 602 } 603 FpDest = FpDest - mid; 604 ''' 605 vmlsSIop = InstObjParams("vmlss", "VmlsS", "VfpRegRegRegOp", 606 { "code": vmlsSCode, 607 "predicate_test": predicateTest }, []) 608 header_output += VfpRegRegRegOpDeclare.subst(vmlsSIop); 609 decoder_output += VfpRegRegRegOpConstructor.subst(vmlsSIop); 610 exec_output += PredOpExecute.subst(vmlsSIop); 611 612 vmlsDCode = ''' 613 IntDoubleUnion cOp1, cOp2, cDest; 614 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 615 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 616 cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); 617 double mid = cOp1.fp * cOp2.fp; 618 if ((isinf(cOp1.fp) && cOp2.fp == 0) || 619 (isinf(cOp2.fp) && cOp1.fp == 0)) { 620 mid = NAN; 621 } 622 cDest.fp = cDest.fp - mid; 623 FpDestP0.uw = cDest.bits; 624 FpDestP1.uw = cDest.bits >> 32; 625 ''' 626 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "VfpRegRegRegOp", 627 { "code": vmlsDCode, 628 "predicate_test": predicateTest }, []) 629 header_output += VfpRegRegRegOpDeclare.subst(vmlsDIop); 630 decoder_output += VfpRegRegRegOpConstructor.subst(vmlsDIop); 631 exec_output += PredOpExecute.subst(vmlsDIop); 632 633 vnmlaSCode = ''' 634 float mid = FpOp1 * FpOp2; 635 if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { 636 mid = NAN; 637 } 638 FpDest = -FpDest - mid; 639 ''' 640 vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "VfpRegRegRegOp", 641 { "code": vnmlaSCode, 642 "predicate_test": predicateTest }, []) 643 header_output += VfpRegRegRegOpDeclare.subst(vnmlaSIop); 644 decoder_output += VfpRegRegRegOpConstructor.subst(vnmlaSIop); 645 exec_output += PredOpExecute.subst(vnmlaSIop); 646 647 vnmlaDCode = ''' 648 IntDoubleUnion cOp1, cOp2, cDest; 649 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 650 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 651 cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); 652 double mid = cOp1.fp * cOp2.fp; 653 if ((isinf(cOp1.fp) && cOp2.fp == 0) || 654 (isinf(cOp2.fp) && cOp1.fp == 0)) { 655 mid = NAN; 656 } 657 cDest.fp = -cDest.fp - mid; 658 FpDestP0.uw = cDest.bits; 659 FpDestP1.uw = cDest.bits >> 32; 660 ''' 661 vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "VfpRegRegRegOp", 662 { "code": vnmlaDCode, 663 "predicate_test": predicateTest }, []) 664 header_output += VfpRegRegRegOpDeclare.subst(vnmlaDIop); 665 decoder_output += VfpRegRegRegOpConstructor.subst(vnmlaDIop); 666 exec_output += PredOpExecute.subst(vnmlaDIop); 667 668 vnmlsSCode = ''' 669 float mid = FpOp1 * FpOp2; 670 if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { 671 mid = NAN; 672 } 673 FpDest = -FpDest + mid; 674 ''' 675 vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "VfpRegRegRegOp", 676 { "code": vnmlsSCode, 677 "predicate_test": predicateTest }, []) 678 header_output += VfpRegRegRegOpDeclare.subst(vnmlsSIop); 679 decoder_output += VfpRegRegRegOpConstructor.subst(vnmlsSIop); 680 exec_output += PredOpExecute.subst(vnmlsSIop); 681 682 vnmlsDCode = ''' 683 IntDoubleUnion cOp1, cOp2, cDest; 684 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 685 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 686 cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); 687 double mid = cOp1.fp * cOp2.fp; 688 if ((isinf(cOp1.fp) && cOp2.fp == 0) || 689 (isinf(cOp2.fp) && cOp1.fp == 0)) { 690 mid = NAN; 691 } 692 cDest.fp = -cDest.fp + mid; 693 FpDestP0.uw = cDest.bits; 694 FpDestP1.uw = cDest.bits >> 32; 695 ''' 696 vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "VfpRegRegRegOp", 697 { "code": vnmlsDCode, 698 "predicate_test": predicateTest }, []) 699 header_output += VfpRegRegRegOpDeclare.subst(vnmlsDIop); 700 decoder_output += VfpRegRegRegOpConstructor.subst(vnmlsDIop); 701 exec_output += PredOpExecute.subst(vnmlsDIop); 702 703 vnmulSCode = ''' 704 float mid = FpOp1 * FpOp2; 705 if ((isinf(FpOp1) && FpOp2 == 0) || (isinf(FpOp2) && FpOp1 == 0)) { 706 mid = NAN; 707 } 708 FpDest = -mid; 709 ''' 710 vnmulSIop = InstObjParams("vnmuls", "VnmulS", "VfpRegRegRegOp", 711 { "code": vnmulSCode, 712 "predicate_test": predicateTest }, []) 713 header_output += VfpRegRegRegOpDeclare.subst(vnmulSIop); 714 decoder_output += VfpRegRegRegOpConstructor.subst(vnmulSIop); 715 exec_output += PredOpExecute.subst(vnmulSIop); 716 717 vnmulDCode = ''' 718 IntDoubleUnion cOp1, cOp2, cDest; 719 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 720 cOp2.bits = ((uint64_t)FpOp2P0.uw | ((uint64_t)FpOp2P1.uw << 32)); 721 cDest.bits = ((uint64_t)FpDestP0.uw | ((uint64_t)FpDestP1.uw << 32)); 722 double mid = cOp1.fp * cOp2.fp; 723 if ((isinf(cOp1.fp) && cOp2.fp == 0) || 724 (isinf(cOp2.fp) && cOp1.fp == 0)) { 725 mid = NAN; 726 } 727 cDest.fp = -mid; 728 FpDestP0.uw = cDest.bits; 729 FpDestP1.uw = cDest.bits >> 32; 730 ''' 731 vnmulDIop = InstObjParams("vnmuld", "VnmulD", "VfpRegRegRegOp", 732 { "code": vnmulDCode, 733 "predicate_test": predicateTest }, []) 734 header_output += VfpRegRegRegOpDeclare.subst(vnmulDIop); 735 decoder_output += VfpRegRegRegOpConstructor.subst(vnmulDIop); 736 exec_output += PredOpExecute.subst(vnmulDIop); 737 738 vcvtUIntFpSCode = ''' 739 FpDest = FpOp1.uw; 740 ''' 741 vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "VfpRegRegOp", 742 { "code": vcvtUIntFpSCode, 743 "predicate_test": predicateTest }, []) 744 header_output += VfpRegRegOpDeclare.subst(vcvtUIntFpSIop); 745 decoder_output += VfpRegRegOpConstructor.subst(vcvtUIntFpSIop); 746 exec_output += PredOpExecute.subst(vcvtUIntFpSIop); 747 748 vcvtUIntFpDCode = ''' 749 IntDoubleUnion cDest; 750 cDest.fp = (uint64_t)FpOp1P0.uw; 751 FpDestP0.uw = cDest.bits; 752 FpDestP1.uw = cDest.bits >> 32; 753 ''' 754 vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "VfpRegRegOp", 755 { "code": vcvtUIntFpDCode, 756 "predicate_test": predicateTest }, []) 757 header_output += VfpRegRegOpDeclare.subst(vcvtUIntFpDIop); 758 decoder_output += VfpRegRegOpConstructor.subst(vcvtUIntFpDIop); 759 exec_output += PredOpExecute.subst(vcvtUIntFpDIop); 760 761 vcvtSIntFpSCode = ''' 762 FpDest = FpOp1.sw; 763 ''' 764 vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "VfpRegRegOp", 765 { "code": vcvtSIntFpSCode, 766 "predicate_test": predicateTest }, []) 767 header_output += VfpRegRegOpDeclare.subst(vcvtSIntFpSIop); 768 decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpSIop); 769 exec_output += PredOpExecute.subst(vcvtSIntFpSIop); 770 771 vcvtSIntFpDCode = ''' 772 IntDoubleUnion cDest; 773 cDest.fp = FpOp1P0.sw; 774 FpDestP0.uw = cDest.bits; 775 FpDestP1.uw = cDest.bits >> 32; 776 ''' 777 vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "VfpRegRegOp", 778 { "code": vcvtSIntFpDCode, 779 "predicate_test": predicateTest }, []) 780 header_output += VfpRegRegOpDeclare.subst(vcvtSIntFpDIop); 781 decoder_output += VfpRegRegOpConstructor.subst(vcvtSIntFpDIop); 782 exec_output += PredOpExecute.subst(vcvtSIntFpDIop); 783 784 vcvtFpUIntSCode = ''' 785 FpDest.uw = FpOp1; 786 ''' 787 vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "VfpRegRegOp", 788 { "code": vcvtFpUIntSCode, 789 "predicate_test": predicateTest }, []) 790 header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntSIop); 791 decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntSIop); 792 exec_output += PredOpExecute.subst(vcvtFpUIntSIop); 793 794 vcvtFpUIntDCode = ''' 795 IntDoubleUnion cOp1; 796 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 797 uint64_t result = cOp1.fp; 798 FpDestP0.uw = result; 799 ''' 800 vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "VfpRegRegOp", 801 { "code": vcvtFpUIntDCode, 802 "predicate_test": predicateTest }, []) 803 header_output += VfpRegRegOpDeclare.subst(vcvtFpUIntDIop); 804 decoder_output += VfpRegRegOpConstructor.subst(vcvtFpUIntDIop); 805 exec_output += PredOpExecute.subst(vcvtFpUIntDIop); 806 807 vcvtFpSIntSCode = ''' 808 FpDest.sw = FpOp1; 809 ''' 810 vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "VfpRegRegOp", 811 { "code": vcvtFpSIntSCode, 812 "predicate_test": predicateTest }, []) 813 header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntSIop); 814 decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntSIop); 815 exec_output += PredOpExecute.subst(vcvtFpSIntSIop); 816 817 vcvtFpSIntDCode = ''' 818 IntDoubleUnion cOp1; 819 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 820 int64_t result = cOp1.fp; 821 FpDestP0.uw = result; 822 ''' 823 vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "VfpRegRegOp", 824 { "code": vcvtFpSIntDCode, 825 "predicate_test": predicateTest }, []) 826 header_output += VfpRegRegOpDeclare.subst(vcvtFpSIntDIop); 827 decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSIntDIop); 828 exec_output += PredOpExecute.subst(vcvtFpSIntDIop); 829 830 vcvtFpSFpDCode = ''' 831 IntDoubleUnion cDest; 832 cDest.fp = FpOp1; 833 FpDestP0.uw = cDest.bits; 834 FpDestP1.uw = cDest.bits >> 32; 835 ''' 836 vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "VfpRegRegOp", 837 { "code": vcvtFpSFpDCode, 838 "predicate_test": predicateTest }, []) 839 header_output += VfpRegRegOpDeclare.subst(vcvtFpSFpDIop); 840 decoder_output += VfpRegRegOpConstructor.subst(vcvtFpSFpDIop); 841 exec_output += PredOpExecute.subst(vcvtFpSFpDIop); 842 843 vcvtFpDFpSCode = ''' 844 IntDoubleUnion cOp1; 845 cOp1.bits = ((uint64_t)FpOp1P0.uw | ((uint64_t)FpOp1P1.uw << 32)); 846 FpDest = cOp1.fp; 847 ''' 848 vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "VfpRegRegOp", 849 { "code": vcvtFpDFpSCode, 850 "predicate_test": predicateTest }, []) 851 header_output += VfpRegRegOpDeclare.subst(vcvtFpDFpSIop); 852 decoder_output += VfpRegRegOpConstructor.subst(vcvtFpDFpSIop); 853 exec_output += PredOpExecute.subst(vcvtFpDFpSIop); 854}}; 855