fp.isa revision 8588:ef28ed90449d
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", "FpRegRegOp", 195 { "code": vmsrEnabledCheckCode + \ 196 "MiscDest = Op1;", 197 "predicate_test": predicateTest, 198 "op_class": "SimdFloatMiscOp" }, 199 ["IsSerializeAfter","IsNonSpeculative"]) 200 header_output += FpRegRegOpDeclare.subst(vmsrIop); 201 decoder_output += FpRegRegOpConstructor.subst(vmsrIop); 202 exec_output += PredOpExecute.subst(vmsrIop); 203 204 vmsrFpscrCode = vmsrEnabledCheckCode + ''' 205 Fpscr = Op1 & ~FpCondCodesMask; 206 FpCondCodes = Op1 & FpCondCodesMask; 207 ''' 208 vmsrFpscrIop = InstObjParams("vmsr", "VmsrFpscr", "FpRegRegOp", 209 { "code": vmsrFpscrCode, 210 "predicate_test": predicateTest, 211 "op_class": "SimdFloatMiscOp" }, 212 ["IsSerializeAfter","IsNonSpeculative", 213 "IsSquashAfter"]) 214 header_output += FpRegRegOpDeclare.subst(vmsrFpscrIop); 215 decoder_output += FpRegRegOpConstructor.subst(vmsrFpscrIop); 216 exec_output += PredOpExecute.subst(vmsrFpscrIop); 217 218 vmrsIop = InstObjParams("vmrs", "Vmrs", "FpRegRegOp", 219 { "code": vmrsEnabledCheckCode + \ 220 "Dest = MiscOp1;", 221 "predicate_test": predicateTest, 222 "op_class": "SimdFloatMiscOp" }, 223 ["IsSerializeBefore"]) 224 header_output += FpRegRegOpDeclare.subst(vmrsIop); 225 decoder_output += FpRegRegOpConstructor.subst(vmrsIop); 226 exec_output += PredOpExecute.subst(vmrsIop); 227 228 vmrsFpscrIop = InstObjParams("vmrs", "VmrsFpscr", "FpRegRegOp", 229 { "code": vmrsEnabledCheckCode + \ 230 "Dest = Fpscr | FpCondCodes;", 231 "predicate_test": predicateTest, 232 "op_class": "SimdFloatMiscOp" }, 233 ["IsSerializeBefore"]) 234 header_output += FpRegRegOpDeclare.subst(vmrsFpscrIop); 235 decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop); 236 exec_output += PredOpExecute.subst(vmrsFpscrIop); 237 238 vmrsApsrFpscrCode = vmrsApsrEnabledCheckCode + ''' 239 FPSCR fpscr = FpCondCodes; 240 CondCodesNZ = (fpscr.n << 1) | fpscr.z; 241 CondCodesC = fpscr.c; 242 CondCodesV = fpscr.v; 243 ''' 244 vmrsApsrFpscrIop = InstObjParams("vmrs", "VmrsApsrFpscr", "PredOp", 245 { "code": vmrsApsrFpscrCode, 246 "predicate_test": predicateTest, 247 "op_class": "SimdFloatMiscOp" }) 248 header_output += BasicDeclare.subst(vmrsApsrFpscrIop); 249 decoder_output += BasicConstructor.subst(vmrsApsrFpscrIop); 250 exec_output += PredOpExecute.subst(vmrsApsrFpscrIop); 251 252 vmovImmSCode = vfpEnabledCheckCode + ''' 253 FpDest_uw = bits(imm, 31, 0); 254 ''' 255 vmovImmSIop = InstObjParams("vmov", "VmovImmS", "FpRegImmOp", 256 { "code": vmovImmSCode, 257 "predicate_test": predicateTest, 258 "op_class": "SimdFloatMiscOp" }, []) 259 header_output += FpRegImmOpDeclare.subst(vmovImmSIop); 260 decoder_output += FpRegImmOpConstructor.subst(vmovImmSIop); 261 exec_output += PredOpExecute.subst(vmovImmSIop); 262 263 vmovImmDCode = vfpEnabledCheckCode + ''' 264 FpDestP0_uw = bits(imm, 31, 0); 265 FpDestP1_uw = bits(imm, 63, 32); 266 ''' 267 vmovImmDIop = InstObjParams("vmov", "VmovImmD", "FpRegImmOp", 268 { "code": vmovImmDCode, 269 "predicate_test": predicateTest, 270 "op_class": "SimdFloatMiscOp" }, []) 271 header_output += FpRegImmOpDeclare.subst(vmovImmDIop); 272 decoder_output += FpRegImmOpConstructor.subst(vmovImmDIop); 273 exec_output += PredOpExecute.subst(vmovImmDIop); 274 275 vmovImmQCode = vfpEnabledCheckCode + ''' 276 FpDestP0_uw = bits(imm, 31, 0); 277 FpDestP1_uw = bits(imm, 63, 32); 278 FpDestP2_uw = bits(imm, 31, 0); 279 FpDestP3_uw = bits(imm, 63, 32); 280 ''' 281 vmovImmQIop = InstObjParams("vmov", "VmovImmQ", "FpRegImmOp", 282 { "code": vmovImmQCode, 283 "predicate_test": predicateTest, 284 "op_class": "SimdFloatMiscOp" }, []) 285 header_output += FpRegImmOpDeclare.subst(vmovImmQIop); 286 decoder_output += FpRegImmOpConstructor.subst(vmovImmQIop); 287 exec_output += PredOpExecute.subst(vmovImmQIop); 288 289 vmovRegSCode = vfpEnabledCheckCode + ''' 290 FpDest_uw = FpOp1_uw; 291 ''' 292 vmovRegSIop = InstObjParams("vmov", "VmovRegS", "FpRegRegOp", 293 { "code": vmovRegSCode, 294 "predicate_test": predicateTest, 295 "op_class": "SimdFloatMiscOp" }, []) 296 header_output += FpRegRegOpDeclare.subst(vmovRegSIop); 297 decoder_output += FpRegRegOpConstructor.subst(vmovRegSIop); 298 exec_output += PredOpExecute.subst(vmovRegSIop); 299 300 vmovRegDCode = vfpEnabledCheckCode + ''' 301 FpDestP0_uw = FpOp1P0_uw; 302 FpDestP1_uw = FpOp1P1_uw; 303 ''' 304 vmovRegDIop = InstObjParams("vmov", "VmovRegD", "FpRegRegOp", 305 { "code": vmovRegDCode, 306 "predicate_test": predicateTest, 307 "op_class": "SimdFloatMiscOp" }, []) 308 header_output += FpRegRegOpDeclare.subst(vmovRegDIop); 309 decoder_output += FpRegRegOpConstructor.subst(vmovRegDIop); 310 exec_output += PredOpExecute.subst(vmovRegDIop); 311 312 vmovRegQCode = vfpEnabledCheckCode + ''' 313 FpDestP0_uw = FpOp1P0_uw; 314 FpDestP1_uw = FpOp1P1_uw; 315 FpDestP2_uw = FpOp1P2_uw; 316 FpDestP3_uw = FpOp1P3_uw; 317 ''' 318 vmovRegQIop = InstObjParams("vmov", "VmovRegQ", "FpRegRegOp", 319 { "code": vmovRegQCode, 320 "predicate_test": predicateTest, 321 "op_class": "SimdFloatMiscOp" }, []) 322 header_output += FpRegRegOpDeclare.subst(vmovRegQIop); 323 decoder_output += FpRegRegOpConstructor.subst(vmovRegQIop); 324 exec_output += PredOpExecute.subst(vmovRegQIop); 325 326 vmovCoreRegBCode = vfpEnabledCheckCode + ''' 327 FpDest_uw = insertBits(FpDest_uw, imm * 8 + 7, imm * 8, Op1_ub); 328 ''' 329 vmovCoreRegBIop = InstObjParams("vmov", "VmovCoreRegB", "FpRegRegImmOp", 330 { "code": vmovCoreRegBCode, 331 "predicate_test": predicateTest, 332 "op_class": "SimdFloatMiscOp" }, []) 333 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegBIop); 334 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegBIop); 335 exec_output += PredOpExecute.subst(vmovCoreRegBIop); 336 337 vmovCoreRegHCode = vfpEnabledCheckCode + ''' 338 FpDest_uw = insertBits(FpDest_uw, imm * 16 + 15, imm * 16, Op1_uh); 339 ''' 340 vmovCoreRegHIop = InstObjParams("vmov", "VmovCoreRegH", "FpRegRegImmOp", 341 { "code": vmovCoreRegHCode, 342 "predicate_test": predicateTest, 343 "op_class": "SimdFloatMiscOp" }, []) 344 header_output += FpRegRegImmOpDeclare.subst(vmovCoreRegHIop); 345 decoder_output += FpRegRegImmOpConstructor.subst(vmovCoreRegHIop); 346 exec_output += PredOpExecute.subst(vmovCoreRegHIop); 347 348 vmovCoreRegWCode = vfpEnabledCheckCode + ''' 349 FpDest_uw = Op1_uw; 350 ''' 351 vmovCoreRegWIop = InstObjParams("vmov", "VmovCoreRegW", "FpRegRegOp", 352 { "code": vmovCoreRegWCode, 353 "predicate_test": predicateTest, 354 "op_class": "SimdFloatMiscOp" }, []) 355 header_output += FpRegRegOpDeclare.subst(vmovCoreRegWIop); 356 decoder_output += FpRegRegOpConstructor.subst(vmovCoreRegWIop); 357 exec_output += PredOpExecute.subst(vmovCoreRegWIop); 358 359 vmovRegCoreUBCode = vfpEnabledCheckCode + ''' 360 assert(imm < 4); 361 Dest = bits(FpOp1_uw, imm * 8 + 7, imm * 8); 362 ''' 363 vmovRegCoreUBIop = InstObjParams("vmov", "VmovRegCoreUB", "FpRegRegImmOp", 364 { "code": vmovRegCoreUBCode, 365 "predicate_test": predicateTest, 366 "op_class": "SimdFloatMiscOp" }, []) 367 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUBIop); 368 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUBIop); 369 exec_output += PredOpExecute.subst(vmovRegCoreUBIop); 370 371 vmovRegCoreUHCode = vfpEnabledCheckCode + ''' 372 assert(imm < 2); 373 Dest = bits(FpOp1_uw, imm * 16 + 15, imm * 16); 374 ''' 375 vmovRegCoreUHIop = InstObjParams("vmov", "VmovRegCoreUH", "FpRegRegImmOp", 376 { "code": vmovRegCoreUHCode, 377 "predicate_test": predicateTest, 378 "op_class": "SimdFloatMiscOp" }, []) 379 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreUHIop); 380 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreUHIop); 381 exec_output += PredOpExecute.subst(vmovRegCoreUHIop); 382 383 vmovRegCoreSBCode = vfpEnabledCheckCode + ''' 384 assert(imm < 4); 385 Dest = sext<8>(bits(FpOp1_uw, imm * 8 + 7, imm * 8)); 386 ''' 387 vmovRegCoreSBIop = InstObjParams("vmov", "VmovRegCoreSB", "FpRegRegImmOp", 388 { "code": vmovRegCoreSBCode, 389 "predicate_test": predicateTest, 390 "op_class": "SimdFloatMiscOp" }, []) 391 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSBIop); 392 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSBIop); 393 exec_output += PredOpExecute.subst(vmovRegCoreSBIop); 394 395 vmovRegCoreSHCode = vfpEnabledCheckCode + ''' 396 assert(imm < 2); 397 Dest = sext<16>(bits(FpOp1_uw, imm * 16 + 15, imm * 16)); 398 ''' 399 vmovRegCoreSHIop = InstObjParams("vmov", "VmovRegCoreSH", "FpRegRegImmOp", 400 { "code": vmovRegCoreSHCode, 401 "predicate_test": predicateTest, 402 "op_class": "SimdFloatMiscOp" }, []) 403 header_output += FpRegRegImmOpDeclare.subst(vmovRegCoreSHIop); 404 decoder_output += FpRegRegImmOpConstructor.subst(vmovRegCoreSHIop); 405 exec_output += PredOpExecute.subst(vmovRegCoreSHIop); 406 407 vmovRegCoreWCode = vfpEnabledCheckCode + ''' 408 Dest = FpOp1_uw; 409 ''' 410 vmovRegCoreWIop = InstObjParams("vmov", "VmovRegCoreW", "FpRegRegOp", 411 { "code": vmovRegCoreWCode, 412 "predicate_test": predicateTest, 413 "op_class": "SimdFloatMiscOp" }, []) 414 header_output += FpRegRegOpDeclare.subst(vmovRegCoreWIop); 415 decoder_output += FpRegRegOpConstructor.subst(vmovRegCoreWIop); 416 exec_output += PredOpExecute.subst(vmovRegCoreWIop); 417 418 vmov2Reg2CoreCode = vfpEnabledCheckCode + ''' 419 FpDestP0_uw = Op1_uw; 420 FpDestP1_uw = Op2_uw; 421 ''' 422 vmov2Reg2CoreIop = InstObjParams("vmov", "Vmov2Reg2Core", "FpRegRegRegOp", 423 { "code": vmov2Reg2CoreCode, 424 "predicate_test": predicateTest, 425 "op_class": "SimdFloatMiscOp" }, []) 426 header_output += FpRegRegRegOpDeclare.subst(vmov2Reg2CoreIop); 427 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Reg2CoreIop); 428 exec_output += PredOpExecute.subst(vmov2Reg2CoreIop); 429 430 vmov2Core2RegCode = vfpEnabledCheckCode + ''' 431 Dest_uw = FpOp2P0_uw; 432 Op1_uw = FpOp2P1_uw; 433 ''' 434 vmov2Core2RegIop = InstObjParams("vmov", "Vmov2Core2Reg", "FpRegRegRegOp", 435 { "code": vmov2Core2RegCode, 436 "predicate_test": predicateTest, 437 "op_class": "SimdFloatMiscOp" }, []) 438 header_output += FpRegRegRegOpDeclare.subst(vmov2Core2RegIop); 439 decoder_output += FpRegRegRegOpConstructor.subst(vmov2Core2RegIop); 440 exec_output += PredOpExecute.subst(vmov2Core2RegIop); 441}}; 442 443let {{ 444 445 header_output = "" 446 decoder_output = "" 447 exec_output = "" 448 449 singleSimpleCode = vfpEnabledCheckCode + ''' 450 FPSCR fpscr = (FPSCR) FpscrExc; 451 FpDest = %(op)s; 452 ''' 453 singleCode = singleSimpleCode + ''' 454 FpscrExc = fpscr; 455 ''' 456 singleBinOp = "binaryOp(fpscr, FpOp1, FpOp2," + \ 457 "%(func)s, fpscr.fz, fpscr.dn, fpscr.rMode)" 458 singleUnaryOp = "unaryOp(fpscr, FpOp1, %(func)s, fpscr.fz, fpscr.rMode)" 459 doubleCode = vfpEnabledCheckCode + ''' 460 FPSCR fpscr = (FPSCR) FpscrExc; 461 double dest = %(op)s; 462 FpDestP0_uw = dblLow(dest); 463 FpDestP1_uw = dblHi(dest); 464 FpscrExc = fpscr; 465 ''' 466 doubleBinOp = ''' 467 binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), 468 dbl(FpOp2P0_uw, FpOp2P1_uw), 469 %(func)s, fpscr.fz, fpscr.dn, fpscr.rMode); 470 ''' 471 doubleUnaryOp = ''' 472 unaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), %(func)s, 473 fpscr.fz, fpscr.rMode) 474 ''' 475 476 def buildBinFpOp(name, Name, base, opClass, singleOp, doubleOp): 477 global header_output, decoder_output, exec_output 478 479 code = singleCode % { "op": singleBinOp } 480 code = code % { "func": singleOp } 481 sIop = InstObjParams(name + "s", Name + "S", base, 482 { "code": code, 483 "predicate_test": predicateTest, 484 "op_class": opClass }, []) 485 code = doubleCode % { "op": doubleBinOp } 486 code = code % { "func": doubleOp } 487 dIop = InstObjParams(name + "d", Name + "D", base, 488 { "code": code, 489 "predicate_test": predicateTest, 490 "op_class": opClass }, []) 491 492 declareTempl = eval(base + "Declare"); 493 constructorTempl = eval(base + "Constructor"); 494 495 for iop in sIop, dIop: 496 header_output += declareTempl.subst(iop) 497 decoder_output += constructorTempl.subst(iop) 498 exec_output += PredOpExecute.subst(iop) 499 500 buildBinFpOp("vadd", "Vadd", "FpRegRegRegOp", "SimdFloatAddOp", "fpAddS", 501 "fpAddD") 502 buildBinFpOp("vsub", "Vsub", "FpRegRegRegOp", "SimdFloatAddOp", "fpSubS", 503 "fpSubD") 504 buildBinFpOp("vdiv", "Vdiv", "FpRegRegRegOp", "SimdFloatDivOp", "fpDivS", 505 "fpDivD") 506 buildBinFpOp("vmul", "Vmul", "FpRegRegRegOp", "SimdFloatMultOp", "fpMulS", 507 "fpMulD") 508 509 def buildUnaryFpOp(name, Name, base, opClass, singleOp, doubleOp = None): 510 if doubleOp is None: 511 doubleOp = singleOp 512 global header_output, decoder_output, exec_output 513 514 code = singleCode % { "op": singleUnaryOp } 515 code = code % { "func": singleOp } 516 sIop = InstObjParams(name + "s", Name + "S", base, 517 { "code": code, 518 "predicate_test": predicateTest, 519 "op_class": opClass }, []) 520 code = doubleCode % { "op": doubleUnaryOp } 521 code = code % { "func": doubleOp } 522 dIop = InstObjParams(name + "d", Name + "D", base, 523 { "code": code, 524 "predicate_test": predicateTest, 525 "op_class": opClass }, []) 526 527 declareTempl = eval(base + "Declare"); 528 constructorTempl = eval(base + "Constructor"); 529 530 for iop in sIop, dIop: 531 header_output += declareTempl.subst(iop) 532 decoder_output += constructorTempl.subst(iop) 533 exec_output += PredOpExecute.subst(iop) 534 535 buildUnaryFpOp("vsqrt", "Vsqrt", "FpRegRegOp", "SimdFloatSqrtOp", "sqrtf", 536 "sqrt") 537 538 def buildSimpleUnaryFpOp(name, Name, base, opClass, singleOp, 539 doubleOp = None): 540 if doubleOp is None: 541 doubleOp = singleOp 542 global header_output, decoder_output, exec_output 543 544 sIop = InstObjParams(name + "s", Name + "S", base, 545 { "code": singleSimpleCode % { "op": singleOp }, 546 "predicate_test": predicateTest, 547 "op_class": opClass }, []) 548 dIop = InstObjParams(name + "d", Name + "D", base, 549 { "code": doubleCode % { "op": doubleOp }, 550 "predicate_test": predicateTest, 551 "op_class": opClass }, []) 552 553 declareTempl = eval(base + "Declare"); 554 constructorTempl = eval(base + "Constructor"); 555 556 for iop in sIop, dIop: 557 header_output += declareTempl.subst(iop) 558 decoder_output += constructorTempl.subst(iop) 559 exec_output += PredOpExecute.subst(iop) 560 561 buildSimpleUnaryFpOp("vneg", "Vneg", "FpRegRegOp", "SimdFloatMiscOp", 562 "-FpOp1", "-dbl(FpOp1P0_uw, FpOp1P1_uw)") 563 buildSimpleUnaryFpOp("vabs", "Vabs", "FpRegRegOp", "SimdFloatMiscOp", 564 "fabsf(FpOp1)", "fabs(dbl(FpOp1P0_uw, FpOp1P1_uw))") 565}}; 566 567let {{ 568 569 header_output = "" 570 decoder_output = "" 571 exec_output = "" 572 573 vmlaSCode = vfpEnabledCheckCode + ''' 574 FPSCR fpscr = (FPSCR) FpscrExc; 575 float mid = binaryOp(fpscr, FpOp1, FpOp2, 576 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); 577 FpDest = binaryOp(fpscr, FpDest, mid, fpAddS, 578 fpscr.fz, fpscr.dn, fpscr.rMode); 579 FpscrExc = fpscr; 580 ''' 581 vmlaSIop = InstObjParams("vmlas", "VmlaS", "FpRegRegRegOp", 582 { "code": vmlaSCode, 583 "predicate_test": predicateTest, 584 "op_class": "SimdFloatMultAccOp" }, []) 585 header_output += FpRegRegRegOpDeclare.subst(vmlaSIop); 586 decoder_output += FpRegRegRegOpConstructor.subst(vmlaSIop); 587 exec_output += PredOpExecute.subst(vmlaSIop); 588 589 vmlaDCode = vfpEnabledCheckCode + ''' 590 FPSCR fpscr = (FPSCR) FpscrExc; 591 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), 592 dbl(FpOp2P0_uw, FpOp2P1_uw), 593 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode); 594 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw), 595 mid, fpAddD, fpscr.fz, 596 fpscr.dn, fpscr.rMode); 597 FpDestP0_uw = dblLow(dest); 598 FpDestP1_uw = dblHi(dest); 599 FpscrExc = fpscr; 600 ''' 601 vmlaDIop = InstObjParams("vmlad", "VmlaD", "FpRegRegRegOp", 602 { "code": vmlaDCode, 603 "predicate_test": predicateTest, 604 "op_class": "SimdFloatMultAccOp" }, []) 605 header_output += FpRegRegRegOpDeclare.subst(vmlaDIop); 606 decoder_output += FpRegRegRegOpConstructor.subst(vmlaDIop); 607 exec_output += PredOpExecute.subst(vmlaDIop); 608 609 vmlsSCode = vfpEnabledCheckCode + ''' 610 FPSCR fpscr = (FPSCR) FpscrExc; 611 float mid = binaryOp(fpscr, FpOp1, FpOp2, 612 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); 613 FpDest = binaryOp(fpscr, FpDest, -mid, fpAddS, 614 fpscr.fz, fpscr.dn, fpscr.rMode); 615 FpscrExc = fpscr; 616 ''' 617 vmlsSIop = InstObjParams("vmlss", "VmlsS", "FpRegRegRegOp", 618 { "code": vmlsSCode, 619 "predicate_test": predicateTest, 620 "op_class": "SimdFloatMultAccOp" }, []) 621 header_output += FpRegRegRegOpDeclare.subst(vmlsSIop); 622 decoder_output += FpRegRegRegOpConstructor.subst(vmlsSIop); 623 exec_output += PredOpExecute.subst(vmlsSIop); 624 625 vmlsDCode = vfpEnabledCheckCode + ''' 626 FPSCR fpscr = (FPSCR) FpscrExc; 627 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), 628 dbl(FpOp2P0_uw, FpOp2P1_uw), 629 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode); 630 double dest = binaryOp(fpscr, dbl(FpDestP0_uw, FpDestP1_uw), 631 -mid, fpAddD, fpscr.fz, 632 fpscr.dn, fpscr.rMode); 633 FpDestP0_uw = dblLow(dest); 634 FpDestP1_uw = dblHi(dest); 635 FpscrExc = fpscr; 636 ''' 637 vmlsDIop = InstObjParams("vmlsd", "VmlsD", "FpRegRegRegOp", 638 { "code": vmlsDCode, 639 "predicate_test": predicateTest, 640 "op_class": "SimdFloatMultAccOp" }, []) 641 header_output += FpRegRegRegOpDeclare.subst(vmlsDIop); 642 decoder_output += FpRegRegRegOpConstructor.subst(vmlsDIop); 643 exec_output += PredOpExecute.subst(vmlsDIop); 644 645 vnmlaSCode = vfpEnabledCheckCode + ''' 646 FPSCR fpscr = (FPSCR) FpscrExc; 647 float mid = binaryOp(fpscr, FpOp1, FpOp2, 648 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); 649 FpDest = binaryOp(fpscr, -FpDest, -mid, fpAddS, 650 fpscr.fz, fpscr.dn, fpscr.rMode); 651 FpscrExc = fpscr; 652 ''' 653 vnmlaSIop = InstObjParams("vnmlas", "VnmlaS", "FpRegRegRegOp", 654 { "code": vnmlaSCode, 655 "predicate_test": predicateTest, 656 "op_class": "SimdFloatMultAccOp" }, []) 657 header_output += FpRegRegRegOpDeclare.subst(vnmlaSIop); 658 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaSIop); 659 exec_output += PredOpExecute.subst(vnmlaSIop); 660 661 vnmlaDCode = vfpEnabledCheckCode + ''' 662 FPSCR fpscr = (FPSCR) FpscrExc; 663 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), 664 dbl(FpOp2P0_uw, FpOp2P1_uw), 665 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode); 666 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw), 667 -mid, fpAddD, fpscr.fz, 668 fpscr.dn, fpscr.rMode); 669 FpDestP0_uw = dblLow(dest); 670 FpDestP1_uw = dblHi(dest); 671 FpscrExc = fpscr; 672 ''' 673 vnmlaDIop = InstObjParams("vnmlad", "VnmlaD", "FpRegRegRegOp", 674 { "code": vnmlaDCode, 675 "predicate_test": predicateTest, 676 "op_class": "SimdFloatMultAccOp" }, []) 677 header_output += FpRegRegRegOpDeclare.subst(vnmlaDIop); 678 decoder_output += FpRegRegRegOpConstructor.subst(vnmlaDIop); 679 exec_output += PredOpExecute.subst(vnmlaDIop); 680 681 vnmlsSCode = vfpEnabledCheckCode + ''' 682 FPSCR fpscr = (FPSCR) FpscrExc; 683 float mid = binaryOp(fpscr, FpOp1, FpOp2, 684 fpMulS, fpscr.fz, fpscr.dn, fpscr.rMode); 685 FpDest = binaryOp(fpscr, -FpDest, mid, fpAddS, 686 fpscr.fz, fpscr.dn, fpscr.rMode); 687 FpscrExc = fpscr; 688 ''' 689 vnmlsSIop = InstObjParams("vnmlss", "VnmlsS", "FpRegRegRegOp", 690 { "code": vnmlsSCode, 691 "predicate_test": predicateTest, 692 "op_class": "SimdFloatMultAccOp" }, []) 693 header_output += FpRegRegRegOpDeclare.subst(vnmlsSIop); 694 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsSIop); 695 exec_output += PredOpExecute.subst(vnmlsSIop); 696 697 vnmlsDCode = vfpEnabledCheckCode + ''' 698 FPSCR fpscr = (FPSCR) FpscrExc; 699 double mid = binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), 700 dbl(FpOp2P0_uw, FpOp2P1_uw), 701 fpMulD, fpscr.fz, fpscr.dn, fpscr.rMode); 702 double dest = binaryOp(fpscr, -dbl(FpDestP0_uw, FpDestP1_uw), 703 mid, fpAddD, fpscr.fz, 704 fpscr.dn, fpscr.rMode); 705 FpDestP0_uw = dblLow(dest); 706 FpDestP1_uw = dblHi(dest); 707 FpscrExc = fpscr; 708 ''' 709 vnmlsDIop = InstObjParams("vnmlsd", "VnmlsD", "FpRegRegRegOp", 710 { "code": vnmlsDCode, 711 "predicate_test": predicateTest, 712 "op_class": "SimdFloatMultAccOp" }, []) 713 header_output += FpRegRegRegOpDeclare.subst(vnmlsDIop); 714 decoder_output += FpRegRegRegOpConstructor.subst(vnmlsDIop); 715 exec_output += PredOpExecute.subst(vnmlsDIop); 716 717 vnmulSCode = vfpEnabledCheckCode + ''' 718 FPSCR fpscr = (FPSCR) FpscrExc; 719 FpDest = -binaryOp(fpscr, FpOp1, FpOp2, fpMulS, 720 fpscr.fz, fpscr.dn, fpscr.rMode); 721 FpscrExc = fpscr; 722 ''' 723 vnmulSIop = InstObjParams("vnmuls", "VnmulS", "FpRegRegRegOp", 724 { "code": vnmulSCode, 725 "predicate_test": predicateTest, 726 "op_class": "SimdFloatMultOp" }, []) 727 header_output += FpRegRegRegOpDeclare.subst(vnmulSIop); 728 decoder_output += FpRegRegRegOpConstructor.subst(vnmulSIop); 729 exec_output += PredOpExecute.subst(vnmulSIop); 730 731 vnmulDCode = vfpEnabledCheckCode + ''' 732 FPSCR fpscr = (FPSCR) FpscrExc; 733 double dest = -binaryOp(fpscr, dbl(FpOp1P0_uw, FpOp1P1_uw), 734 dbl(FpOp2P0_uw, FpOp2P1_uw), 735 fpMulD, fpscr.fz, fpscr.dn, 736 fpscr.rMode); 737 FpDestP0_uw = dblLow(dest); 738 FpDestP1_uw = dblHi(dest); 739 FpscrExc = fpscr; 740 ''' 741 vnmulDIop = InstObjParams("vnmuld", "VnmulD", "FpRegRegRegOp", 742 { "code": vnmulDCode, 743 "predicate_test": predicateTest, 744 "op_class": "SimdFloatMultOp" }, []) 745 header_output += FpRegRegRegOpDeclare.subst(vnmulDIop); 746 decoder_output += FpRegRegRegOpConstructor.subst(vnmulDIop); 747 exec_output += PredOpExecute.subst(vnmulDIop); 748}}; 749 750let {{ 751 752 header_output = "" 753 decoder_output = "" 754 exec_output = "" 755 756 vcvtUIntFpSCode = vfpEnabledCheckCode + ''' 757 FPSCR fpscr = (FPSCR) FpscrExc; 758 VfpSavedState state = prepFpState(fpscr.rMode); 759 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw)); 760 FpDest = FpOp1_uw; 761 __asm__ __volatile__("" :: "m" (FpDest)); 762 finishVfp(fpscr, state, fpscr.fz); 763 FpscrExc = fpscr; 764 ''' 765 vcvtUIntFpSIop = InstObjParams("vcvt", "VcvtUIntFpS", "FpRegRegOp", 766 { "code": vcvtUIntFpSCode, 767 "predicate_test": predicateTest, 768 "op_class": "SimdFloatCvtOp" }, []) 769 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpSIop); 770 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpSIop); 771 exec_output += PredOpExecute.subst(vcvtUIntFpSIop); 772 773 vcvtUIntFpDCode = vfpEnabledCheckCode + ''' 774 FPSCR fpscr = (FPSCR) FpscrExc; 775 VfpSavedState state = prepFpState(fpscr.rMode); 776 __asm__ __volatile__("" : "=m" (FpOp1P0_uw) : "m" (FpOp1P0_uw)); 777 double cDest = (uint64_t)FpOp1P0_uw; 778 __asm__ __volatile__("" :: "m" (cDest)); 779 finishVfp(fpscr, state, fpscr.fz); 780 FpDestP0_uw = dblLow(cDest); 781 FpDestP1_uw = dblHi(cDest); 782 FpscrExc = fpscr; 783 ''' 784 vcvtUIntFpDIop = InstObjParams("vcvt", "VcvtUIntFpD", "FpRegRegOp", 785 { "code": vcvtUIntFpDCode, 786 "predicate_test": predicateTest, 787 "op_class": "SimdFloatCvtOp" }, []) 788 header_output += FpRegRegOpDeclare.subst(vcvtUIntFpDIop); 789 decoder_output += FpRegRegOpConstructor.subst(vcvtUIntFpDIop); 790 exec_output += PredOpExecute.subst(vcvtUIntFpDIop); 791 792 vcvtSIntFpSCode = vfpEnabledCheckCode + ''' 793 FPSCR fpscr = (FPSCR) FpscrExc; 794 VfpSavedState state = prepFpState(fpscr.rMode); 795 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw)); 796 FpDest = FpOp1_sw; 797 __asm__ __volatile__("" :: "m" (FpDest)); 798 finishVfp(fpscr, state, fpscr.fz); 799 FpscrExc = fpscr; 800 ''' 801 vcvtSIntFpSIop = InstObjParams("vcvt", "VcvtSIntFpS", "FpRegRegOp", 802 { "code": vcvtSIntFpSCode, 803 "predicate_test": predicateTest, 804 "op_class": "SimdFloatCvtOp" }, []) 805 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpSIop); 806 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpSIop); 807 exec_output += PredOpExecute.subst(vcvtSIntFpSIop); 808 809 vcvtSIntFpDCode = vfpEnabledCheckCode + ''' 810 FPSCR fpscr = (FPSCR) FpscrExc; 811 VfpSavedState state = prepFpState(fpscr.rMode); 812 __asm__ __volatile__("" : "=m" (FpOp1P0_sw) : "m" (FpOp1P0_sw)); 813 double cDest = FpOp1P0_sw; 814 __asm__ __volatile__("" :: "m" (cDest)); 815 finishVfp(fpscr, state, fpscr.fz); 816 FpDestP0_uw = dblLow(cDest); 817 FpDestP1_uw = dblHi(cDest); 818 FpscrExc = fpscr; 819 ''' 820 vcvtSIntFpDIop = InstObjParams("vcvt", "VcvtSIntFpD", "FpRegRegOp", 821 { "code": vcvtSIntFpDCode, 822 "predicate_test": predicateTest, 823 "op_class": "SimdFloatCvtOp" }, []) 824 header_output += FpRegRegOpDeclare.subst(vcvtSIntFpDIop); 825 decoder_output += FpRegRegOpConstructor.subst(vcvtSIntFpDIop); 826 exec_output += PredOpExecute.subst(vcvtSIntFpDIop); 827 828 vcvtFpUIntSRCode = vfpEnabledCheckCode + ''' 829 FPSCR fpscr = (FPSCR) FpscrExc; 830 VfpSavedState state = prepFpState(fpscr.rMode); 831 vfpFlushToZero(fpscr, FpOp1); 832 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 833 FpDest_uw = vfpFpSToFixed(FpOp1, false, false, 0, false); 834 __asm__ __volatile__("" :: "m" (FpDest_uw)); 835 finishVfp(fpscr, state, fpscr.fz); 836 FpscrExc = fpscr; 837 ''' 838 vcvtFpUIntSRIop = InstObjParams("vcvt", "VcvtFpUIntSR", "FpRegRegOp", 839 { "code": vcvtFpUIntSRCode, 840 "predicate_test": predicateTest, 841 "op_class": "SimdFloatCvtOp" }, []) 842 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSRIop); 843 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSRIop); 844 exec_output += PredOpExecute.subst(vcvtFpUIntSRIop); 845 846 vcvtFpUIntDRCode = vfpEnabledCheckCode + ''' 847 FPSCR fpscr = (FPSCR) FpscrExc; 848 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 849 vfpFlushToZero(fpscr, cOp1); 850 VfpSavedState state = prepFpState(fpscr.rMode); 851 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 852 uint64_t result = vfpFpDToFixed(cOp1, false, false, 0, false); 853 __asm__ __volatile__("" :: "m" (result)); 854 finishVfp(fpscr, state, fpscr.fz); 855 FpDestP0_uw = result; 856 FpscrExc = fpscr; 857 ''' 858 vcvtFpUIntDRIop = InstObjParams("vcvtr", "VcvtFpUIntDR", "FpRegRegOp", 859 { "code": vcvtFpUIntDRCode, 860 "predicate_test": predicateTest, 861 "op_class": "SimdFloatCvtOp" }, []) 862 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDRIop); 863 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDRIop); 864 exec_output += PredOpExecute.subst(vcvtFpUIntDRIop); 865 866 vcvtFpSIntSRCode = vfpEnabledCheckCode + ''' 867 FPSCR fpscr = (FPSCR) FpscrExc; 868 VfpSavedState state = prepFpState(fpscr.rMode); 869 vfpFlushToZero(fpscr, FpOp1); 870 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 871 FpDest_sw = vfpFpSToFixed(FpOp1, true, false, 0, false); 872 __asm__ __volatile__("" :: "m" (FpDest_sw)); 873 finishVfp(fpscr, state, fpscr.fz); 874 FpscrExc = fpscr; 875 ''' 876 vcvtFpSIntSRIop = InstObjParams("vcvtr", "VcvtFpSIntSR", "FpRegRegOp", 877 { "code": vcvtFpSIntSRCode, 878 "predicate_test": predicateTest, 879 "op_class": "SimdFloatCvtOp" }, []) 880 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSRIop); 881 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSRIop); 882 exec_output += PredOpExecute.subst(vcvtFpSIntSRIop); 883 884 vcvtFpSIntDRCode = vfpEnabledCheckCode + ''' 885 FPSCR fpscr = (FPSCR) FpscrExc; 886 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 887 vfpFlushToZero(fpscr, cOp1); 888 VfpSavedState state = prepFpState(fpscr.rMode); 889 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 890 int64_t result = vfpFpDToFixed(cOp1, true, false, 0, false); 891 __asm__ __volatile__("" :: "m" (result)); 892 finishVfp(fpscr, state, fpscr.fz); 893 FpDestP0_uw = result; 894 FpscrExc = fpscr; 895 ''' 896 vcvtFpSIntDRIop = InstObjParams("vcvtr", "VcvtFpSIntDR", "FpRegRegOp", 897 { "code": vcvtFpSIntDRCode, 898 "predicate_test": predicateTest, 899 "op_class": "SimdFloatCvtOp" }, []) 900 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDRIop); 901 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDRIop); 902 exec_output += PredOpExecute.subst(vcvtFpSIntDRIop); 903 904 vcvtFpUIntSCode = vfpEnabledCheckCode + ''' 905 FPSCR fpscr = (FPSCR) FpscrExc; 906 vfpFlushToZero(fpscr, FpOp1); 907 VfpSavedState state = prepFpState(fpscr.rMode); 908 fesetround(FeRoundZero); 909 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 910 FpDest_uw = vfpFpSToFixed(FpOp1, false, false, 0); 911 __asm__ __volatile__("" :: "m" (FpDest_uw)); 912 finishVfp(fpscr, state, fpscr.fz); 913 FpscrExc = fpscr; 914 ''' 915 vcvtFpUIntSIop = InstObjParams("vcvt", "VcvtFpUIntS", "FpRegRegOp", 916 { "code": vcvtFpUIntSCode, 917 "predicate_test": predicateTest, 918 "op_class": "SimdFloatCvtOp" }, []) 919 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntSIop); 920 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntSIop); 921 exec_output += PredOpExecute.subst(vcvtFpUIntSIop); 922 923 vcvtFpUIntDCode = vfpEnabledCheckCode + ''' 924 FPSCR fpscr = (FPSCR) FpscrExc; 925 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 926 vfpFlushToZero(fpscr, cOp1); 927 VfpSavedState state = prepFpState(fpscr.rMode); 928 fesetround(FeRoundZero); 929 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 930 uint64_t result = vfpFpDToFixed(cOp1, false, false, 0); 931 __asm__ __volatile__("" :: "m" (result)); 932 finishVfp(fpscr, state, fpscr.fz); 933 FpDestP0_uw = result; 934 FpscrExc = fpscr; 935 ''' 936 vcvtFpUIntDIop = InstObjParams("vcvt", "VcvtFpUIntD", "FpRegRegOp", 937 { "code": vcvtFpUIntDCode, 938 "predicate_test": predicateTest, 939 "op_class": "SimdFloatCvtOp" }, []) 940 header_output += FpRegRegOpDeclare.subst(vcvtFpUIntDIop); 941 decoder_output += FpRegRegOpConstructor.subst(vcvtFpUIntDIop); 942 exec_output += PredOpExecute.subst(vcvtFpUIntDIop); 943 944 vcvtFpSIntSCode = vfpEnabledCheckCode + ''' 945 FPSCR fpscr = (FPSCR) FpscrExc; 946 vfpFlushToZero(fpscr, FpOp1); 947 VfpSavedState state = prepFpState(fpscr.rMode); 948 fesetround(FeRoundZero); 949 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 950 FpDest_sw = vfpFpSToFixed(FpOp1, true, false, 0); 951 __asm__ __volatile__("" :: "m" (FpDest_sw)); 952 finishVfp(fpscr, state, fpscr.fz); 953 FpscrExc = fpscr; 954 ''' 955 vcvtFpSIntSIop = InstObjParams("vcvt", "VcvtFpSIntS", "FpRegRegOp", 956 { "code": vcvtFpSIntSCode, 957 "predicate_test": predicateTest, 958 "op_class": "SimdFloatCvtOp" }, []) 959 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntSIop); 960 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntSIop); 961 exec_output += PredOpExecute.subst(vcvtFpSIntSIop); 962 963 vcvtFpSIntDCode = vfpEnabledCheckCode + ''' 964 FPSCR fpscr = (FPSCR) FpscrExc; 965 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 966 vfpFlushToZero(fpscr, cOp1); 967 VfpSavedState state = prepFpState(fpscr.rMode); 968 fesetround(FeRoundZero); 969 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 970 int64_t result = vfpFpDToFixed(cOp1, true, false, 0); 971 __asm__ __volatile__("" :: "m" (result)); 972 finishVfp(fpscr, state, fpscr.fz); 973 FpDestP0_uw = result; 974 FpscrExc = fpscr; 975 ''' 976 vcvtFpSIntDIop = InstObjParams("vcvt", "VcvtFpSIntD", "FpRegRegOp", 977 { "code": vcvtFpSIntDCode, 978 "predicate_test": predicateTest, 979 "op_class": "SimdFloatCvtOp" }, []) 980 header_output += FpRegRegOpDeclare.subst(vcvtFpSIntDIop); 981 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSIntDIop); 982 exec_output += PredOpExecute.subst(vcvtFpSIntDIop); 983 984 vcvtFpSFpDCode = vfpEnabledCheckCode + ''' 985 FPSCR fpscr = (FPSCR) FpscrExc; 986 vfpFlushToZero(fpscr, FpOp1); 987 VfpSavedState state = prepFpState(fpscr.rMode); 988 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 989 double cDest = fixFpSFpDDest(FpscrExc, FpOp1); 990 __asm__ __volatile__("" :: "m" (cDest)); 991 finishVfp(fpscr, state, fpscr.fz); 992 FpDestP0_uw = dblLow(cDest); 993 FpDestP1_uw = dblHi(cDest); 994 FpscrExc = fpscr; 995 ''' 996 vcvtFpSFpDIop = InstObjParams("vcvt", "VcvtFpSFpD", "FpRegRegOp", 997 { "code": vcvtFpSFpDCode, 998 "predicate_test": predicateTest, 999 "op_class": "SimdFloatCvtOp" }, []) 1000 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpDIop); 1001 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpDIop); 1002 exec_output += PredOpExecute.subst(vcvtFpSFpDIop); 1003 1004 vcvtFpDFpSCode = vfpEnabledCheckCode + ''' 1005 FPSCR fpscr = (FPSCR) FpscrExc; 1006 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 1007 vfpFlushToZero(fpscr, cOp1); 1008 VfpSavedState state = prepFpState(fpscr.rMode); 1009 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 1010 FpDest = fixFpDFpSDest(FpscrExc, cOp1); 1011 __asm__ __volatile__("" :: "m" (FpDest)); 1012 finishVfp(fpscr, state, fpscr.fz); 1013 FpscrExc = fpscr; 1014 ''' 1015 vcvtFpDFpSIop = InstObjParams("vcvt", "VcvtFpDFpS", "FpRegRegOp", 1016 { "code": vcvtFpDFpSCode, 1017 "predicate_test": predicateTest, 1018 "op_class": "SimdFloatCvtOp" }, []) 1019 header_output += FpRegRegOpDeclare.subst(vcvtFpDFpSIop); 1020 decoder_output += FpRegRegOpConstructor.subst(vcvtFpDFpSIop); 1021 exec_output += PredOpExecute.subst(vcvtFpDFpSIop); 1022 1023 vcvtFpHTFpSCode = vfpEnabledCheckCode + ''' 1024 FPSCR fpscr = (FPSCR) FpscrExc; 1025 vfpFlushToZero(fpscr, FpOp1); 1026 VfpSavedState state = prepFpState(fpscr.rMode); 1027 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 1028 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp, 1029 bits(fpToBits(FpOp1), 31, 16)); 1030 __asm__ __volatile__("" :: "m" (FpDest)); 1031 finishVfp(fpscr, state, fpscr.fz); 1032 FpscrExc = fpscr; 1033 ''' 1034 vcvtFpHTFpSIop = InstObjParams("vcvtt", "VcvtFpHTFpS", "FpRegRegOp", 1035 { "code": vcvtFpHTFpSCode, 1036 "predicate_test": predicateTest, 1037 "op_class": "SimdFloatCvtOp" }, []) 1038 header_output += FpRegRegOpDeclare.subst(vcvtFpHTFpSIop); 1039 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHTFpSIop); 1040 exec_output += PredOpExecute.subst(vcvtFpHTFpSIop); 1041 1042 vcvtFpHBFpSCode = vfpEnabledCheckCode + ''' 1043 FPSCR fpscr = (FPSCR) FpscrExc; 1044 VfpSavedState state = prepFpState(fpscr.rMode); 1045 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 1046 FpDest = vcvtFpHFpS(fpscr, fpscr.dn, fpscr.ahp, 1047 bits(fpToBits(FpOp1), 15, 0)); 1048 __asm__ __volatile__("" :: "m" (FpDest)); 1049 finishVfp(fpscr, state, fpscr.fz); 1050 FpscrExc = fpscr; 1051 ''' 1052 vcvtFpHBFpSIop = InstObjParams("vcvtb", "VcvtFpHBFpS", "FpRegRegOp", 1053 { "code": vcvtFpHBFpSCode, 1054 "predicate_test": predicateTest, 1055 "op_class": "SimdFloatCvtOp" }, []) 1056 header_output += FpRegRegOpDeclare.subst(vcvtFpHBFpSIop); 1057 decoder_output += FpRegRegOpConstructor.subst(vcvtFpHBFpSIop); 1058 exec_output += PredOpExecute.subst(vcvtFpHBFpSIop); 1059 1060 vcvtFpSFpHTCode = vfpEnabledCheckCode + ''' 1061 FPSCR fpscr = (FPSCR) FpscrExc; 1062 vfpFlushToZero(fpscr, FpOp1); 1063 VfpSavedState state = prepFpState(fpscr.rMode); 1064 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw) 1065 : "m" (FpOp1), "m" (FpDest_uw)); 1066 FpDest_uw = insertBits(FpDest_uw, 31, 16,, 1067 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn, 1068 fpscr.rMode, fpscr.ahp, FpOp1)); 1069 __asm__ __volatile__("" :: "m" (FpDest_uw)); 1070 finishVfp(fpscr, state, fpscr.fz); 1071 FpscrExc = fpscr; 1072 ''' 1073 vcvtFpSFpHTIop = InstObjParams("vcvtt", "VcvtFpSFpHT", "FpRegRegOp", 1074 { "code": vcvtFpHTFpSCode, 1075 "predicate_test": predicateTest, 1076 "op_class": "SimdFloatCvtOp" }, []) 1077 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHTIop); 1078 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHTIop); 1079 exec_output += PredOpExecute.subst(vcvtFpSFpHTIop); 1080 1081 vcvtFpSFpHBCode = vfpEnabledCheckCode + ''' 1082 FPSCR fpscr = (FPSCR) FpscrExc; 1083 vfpFlushToZero(fpscr, FpOp1); 1084 VfpSavedState state = prepFpState(fpscr.rMode); 1085 __asm__ __volatile__("" : "=m" (FpOp1), "=m" (FpDest_uw) 1086 : "m" (FpOp1), "m" (FpDest_uw)); 1087 FpDest_uw = insertBits(FpDest_uw, 15, 0, 1088 vcvtFpSFpH(fpscr, fpscr.fz, fpscr.dn, 1089 fpscr.rMode, fpscr.ahp, FpOp1)); 1090 __asm__ __volatile__("" :: "m" (FpDest_uw)); 1091 finishVfp(fpscr, state, fpscr.fz); 1092 FpscrExc = fpscr; 1093 ''' 1094 vcvtFpSFpHBIop = InstObjParams("vcvtb", "VcvtFpSFpHB", "FpRegRegOp", 1095 { "code": vcvtFpSFpHBCode, 1096 "predicate_test": predicateTest, 1097 "op_class": "SimdFloatCvtOp" }, []) 1098 header_output += FpRegRegOpDeclare.subst(vcvtFpSFpHBIop); 1099 decoder_output += FpRegRegOpConstructor.subst(vcvtFpSFpHBIop); 1100 exec_output += PredOpExecute.subst(vcvtFpSFpHBIop); 1101 1102 vcmpSCode = vfpEnabledCheckCode + ''' 1103 FPSCR fpscr = (FPSCR) FpscrExc; 1104 vfpFlushToZero(fpscr, FpDest, FpOp1); 1105 if (FpDest == FpOp1) { 1106 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0; 1107 } else if (FpDest < FpOp1) { 1108 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0; 1109 } else if (FpDest > FpOp1) { 1110 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0; 1111 } else { 1112 const uint32_t qnan = 0x7fc00000; 1113 const bool nan1 = std::isnan(FpDest); 1114 const bool signal1 = nan1 && ((fpToBits(FpDest) & qnan) != qnan); 1115 const bool nan2 = std::isnan(FpOp1); 1116 const bool signal2 = nan2 && ((fpToBits(FpOp1) & qnan) != qnan); 1117 if (signal1 || signal2) 1118 fpscr.ioc = 1; 1119 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1; 1120 } 1121 FpCondCodes = fpscr & FpCondCodesMask; 1122 FpscrExc = fpscr; 1123 ''' 1124 vcmpSIop = InstObjParams("vcmps", "VcmpS", "FpRegRegOp", 1125 { "code": vcmpSCode, 1126 "predicate_test": predicateTest, 1127 "op_class": "SimdFloatCmpOp" }, []) 1128 header_output += FpRegRegOpDeclare.subst(vcmpSIop); 1129 decoder_output += FpRegRegOpConstructor.subst(vcmpSIop); 1130 exec_output += PredOpExecute.subst(vcmpSIop); 1131 1132 vcmpDCode = vfpEnabledCheckCode + ''' 1133 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 1134 double cDest = dbl(FpDestP0_uw, FpDestP1_uw); 1135 FPSCR fpscr = (FPSCR) FpscrExc; 1136 vfpFlushToZero(fpscr, cDest, cOp1); 1137 if (cDest == cOp1) { 1138 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0; 1139 } else if (cDest < cOp1) { 1140 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0; 1141 } else if (cDest > cOp1) { 1142 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0; 1143 } else { 1144 const uint64_t qnan = ULL(0x7ff8000000000000); 1145 const bool nan1 = std::isnan(cDest); 1146 const bool signal1 = nan1 && ((fpToBits(cDest) & qnan) != qnan); 1147 const bool nan2 = std::isnan(cOp1); 1148 const bool signal2 = nan2 && ((fpToBits(cOp1) & qnan) != qnan); 1149 if (signal1 || signal2) 1150 fpscr.ioc = 1; 1151 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1; 1152 } 1153 FpCondCodes = fpscr & FpCondCodesMask; 1154 FpscrExc = fpscr; 1155 ''' 1156 vcmpDIop = InstObjParams("vcmpd", "VcmpD", "FpRegRegOp", 1157 { "code": vcmpDCode, 1158 "predicate_test": predicateTest, 1159 "op_class": "SimdFloatCmpOp" }, []) 1160 header_output += FpRegRegOpDeclare.subst(vcmpDIop); 1161 decoder_output += FpRegRegOpConstructor.subst(vcmpDIop); 1162 exec_output += PredOpExecute.subst(vcmpDIop); 1163 1164 vcmpZeroSCode = vfpEnabledCheckCode + ''' 1165 FPSCR fpscr = (FPSCR) FpscrExc; 1166 vfpFlushToZero(fpscr, FpDest); 1167 // This only handles imm == 0 for now. 1168 assert(imm == 0); 1169 if (FpDest == imm) { 1170 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0; 1171 } else if (FpDest < imm) { 1172 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0; 1173 } else if (FpDest > imm) { 1174 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0; 1175 } else { 1176 const uint32_t qnan = 0x7fc00000; 1177 const bool nan = std::isnan(FpDest); 1178 const bool signal = nan && ((fpToBits(FpDest) & qnan) != qnan); 1179 if (signal) 1180 fpscr.ioc = 1; 1181 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1; 1182 } 1183 FpCondCodes = fpscr & FpCondCodesMask; 1184 FpscrExc = fpscr; 1185 ''' 1186 vcmpZeroSIop = InstObjParams("vcmpZeros", "VcmpZeroS", "FpRegImmOp", 1187 { "code": vcmpZeroSCode, 1188 "predicate_test": predicateTest, 1189 "op_class": "SimdFloatCmpOp" }, []) 1190 header_output += FpRegImmOpDeclare.subst(vcmpZeroSIop); 1191 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroSIop); 1192 exec_output += PredOpExecute.subst(vcmpZeroSIop); 1193 1194 vcmpZeroDCode = vfpEnabledCheckCode + ''' 1195 // This only handles imm == 0 for now. 1196 assert(imm == 0); 1197 double cDest = dbl(FpDestP0_uw, FpDestP1_uw); 1198 FPSCR fpscr = (FPSCR) FpscrExc; 1199 vfpFlushToZero(fpscr, cDest); 1200 if (cDest == imm) { 1201 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0; 1202 } else if (cDest < imm) { 1203 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0; 1204 } else if (cDest > imm) { 1205 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0; 1206 } else { 1207 const uint64_t qnan = ULL(0x7ff8000000000000); 1208 const bool nan = std::isnan(cDest); 1209 const bool signal = nan && ((fpToBits(cDest) & qnan) != qnan); 1210 if (signal) 1211 fpscr.ioc = 1; 1212 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1; 1213 } 1214 FpCondCodes = fpscr & FpCondCodesMask; 1215 FpscrExc = fpscr; 1216 ''' 1217 vcmpZeroDIop = InstObjParams("vcmpZerod", "VcmpZeroD", "FpRegImmOp", 1218 { "code": vcmpZeroDCode, 1219 "predicate_test": predicateTest, 1220 "op_class": "SimdFloatCmpOp" }, []) 1221 header_output += FpRegImmOpDeclare.subst(vcmpZeroDIop); 1222 decoder_output += FpRegImmOpConstructor.subst(vcmpZeroDIop); 1223 exec_output += PredOpExecute.subst(vcmpZeroDIop); 1224 1225 vcmpeSCode = vfpEnabledCheckCode + ''' 1226 FPSCR fpscr = (FPSCR) FpscrExc; 1227 vfpFlushToZero(fpscr, FpDest, FpOp1); 1228 if (FpDest == FpOp1) { 1229 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0; 1230 } else if (FpDest < FpOp1) { 1231 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0; 1232 } else if (FpDest > FpOp1) { 1233 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0; 1234 } else { 1235 fpscr.ioc = 1; 1236 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1; 1237 } 1238 FpCondCodes = fpscr & FpCondCodesMask; 1239 FpscrExc = fpscr; 1240 ''' 1241 vcmpeSIop = InstObjParams("vcmpes", "VcmpeS", "FpRegRegOp", 1242 { "code": vcmpeSCode, 1243 "predicate_test": predicateTest, 1244 "op_class": "SimdFloatCmpOp" }, []) 1245 header_output += FpRegRegOpDeclare.subst(vcmpeSIop); 1246 decoder_output += FpRegRegOpConstructor.subst(vcmpeSIop); 1247 exec_output += PredOpExecute.subst(vcmpeSIop); 1248 1249 vcmpeDCode = vfpEnabledCheckCode + ''' 1250 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 1251 double cDest = dbl(FpDestP0_uw, FpDestP1_uw); 1252 FPSCR fpscr = (FPSCR) FpscrExc; 1253 vfpFlushToZero(fpscr, cDest, cOp1); 1254 if (cDest == cOp1) { 1255 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0; 1256 } else if (cDest < cOp1) { 1257 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0; 1258 } else if (cDest > cOp1) { 1259 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0; 1260 } else { 1261 fpscr.ioc = 1; 1262 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1; 1263 } 1264 FpCondCodes = fpscr & FpCondCodesMask; 1265 FpscrExc = fpscr; 1266 ''' 1267 vcmpeDIop = InstObjParams("vcmped", "VcmpeD", "FpRegRegOp", 1268 { "code": vcmpeDCode, 1269 "predicate_test": predicateTest, 1270 "op_class": "SimdFloatCmpOp" }, []) 1271 header_output += FpRegRegOpDeclare.subst(vcmpeDIop); 1272 decoder_output += FpRegRegOpConstructor.subst(vcmpeDIop); 1273 exec_output += PredOpExecute.subst(vcmpeDIop); 1274 1275 vcmpeZeroSCode = vfpEnabledCheckCode + ''' 1276 FPSCR fpscr = (FPSCR) FpscrExc; 1277 vfpFlushToZero(fpscr, FpDest); 1278 if (FpDest == imm) { 1279 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0; 1280 } else if (FpDest < imm) { 1281 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0; 1282 } else if (FpDest > imm) { 1283 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0; 1284 } else { 1285 fpscr.ioc = 1; 1286 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1; 1287 } 1288 FpCondCodes = fpscr & FpCondCodesMask; 1289 FpscrExc = fpscr; 1290 ''' 1291 vcmpeZeroSIop = InstObjParams("vcmpeZeros", "VcmpeZeroS", "FpRegImmOp", 1292 { "code": vcmpeZeroSCode, 1293 "predicate_test": predicateTest, 1294 "op_class": "SimdFloatCmpOp" }, []) 1295 header_output += FpRegImmOpDeclare.subst(vcmpeZeroSIop); 1296 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroSIop); 1297 exec_output += PredOpExecute.subst(vcmpeZeroSIop); 1298 1299 vcmpeZeroDCode = vfpEnabledCheckCode + ''' 1300 double cDest = dbl(FpDestP0_uw, FpDestP1_uw); 1301 FPSCR fpscr = (FPSCR) FpscrExc; 1302 vfpFlushToZero(fpscr, cDest); 1303 if (cDest == imm) { 1304 fpscr.n = 0; fpscr.z = 1; fpscr.c = 1; fpscr.v = 0; 1305 } else if (cDest < imm) { 1306 fpscr.n = 1; fpscr.z = 0; fpscr.c = 0; fpscr.v = 0; 1307 } else if (cDest > imm) { 1308 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 0; 1309 } else { 1310 fpscr.ioc = 1; 1311 fpscr.n = 0; fpscr.z = 0; fpscr.c = 1; fpscr.v = 1; 1312 } 1313 FpCondCodes = fpscr & FpCondCodesMask; 1314 FpscrExc = fpscr; 1315 ''' 1316 vcmpeZeroDIop = InstObjParams("vcmpeZerod", "VcmpeZeroD", "FpRegImmOp", 1317 { "code": vcmpeZeroDCode, 1318 "predicate_test": predicateTest, 1319 "op_class": "SimdFloatCmpOp" }, []) 1320 header_output += FpRegImmOpDeclare.subst(vcmpeZeroDIop); 1321 decoder_output += FpRegImmOpConstructor.subst(vcmpeZeroDIop); 1322 exec_output += PredOpExecute.subst(vcmpeZeroDIop); 1323}}; 1324 1325let {{ 1326 1327 header_output = "" 1328 decoder_output = "" 1329 exec_output = "" 1330 1331 vcvtFpSFixedSCode = vfpEnabledCheckCode + ''' 1332 FPSCR fpscr = (FPSCR) FpscrExc; 1333 vfpFlushToZero(fpscr, FpOp1); 1334 VfpSavedState state = prepFpState(fpscr.rMode); 1335 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 1336 FpDest_sw = vfpFpSToFixed(FpOp1, true, false, imm); 1337 __asm__ __volatile__("" :: "m" (FpDest_sw)); 1338 finishVfp(fpscr, state, fpscr.fz); 1339 FpscrExc = fpscr; 1340 ''' 1341 vcvtFpSFixedSIop = InstObjParams("vcvt", "VcvtFpSFixedS", "FpRegRegImmOp", 1342 { "code": vcvtFpSFixedSCode, 1343 "predicate_test": predicateTest, 1344 "op_class": "SimdFloatCvtOp" }, []) 1345 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedSIop); 1346 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedSIop); 1347 exec_output += PredOpExecute.subst(vcvtFpSFixedSIop); 1348 1349 vcvtFpSFixedDCode = vfpEnabledCheckCode + ''' 1350 FPSCR fpscr = (FPSCR) FpscrExc; 1351 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 1352 vfpFlushToZero(fpscr, cOp1); 1353 VfpSavedState state = prepFpState(fpscr.rMode); 1354 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 1355 uint64_t mid = vfpFpDToFixed(cOp1, true, false, imm); 1356 __asm__ __volatile__("" :: "m" (mid)); 1357 finishVfp(fpscr, state, fpscr.fz); 1358 FpDestP0_uw = mid; 1359 FpDestP1_uw = mid >> 32; 1360 FpscrExc = fpscr; 1361 ''' 1362 vcvtFpSFixedDIop = InstObjParams("vcvt", "VcvtFpSFixedD", "FpRegRegImmOp", 1363 { "code": vcvtFpSFixedDCode, 1364 "predicate_test": predicateTest, 1365 "op_class": "SimdFloatCvtOp" }, []) 1366 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSFixedDIop); 1367 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSFixedDIop); 1368 exec_output += PredOpExecute.subst(vcvtFpSFixedDIop); 1369 1370 vcvtFpUFixedSCode = vfpEnabledCheckCode + ''' 1371 FPSCR fpscr = (FPSCR) FpscrExc; 1372 vfpFlushToZero(fpscr, FpOp1); 1373 VfpSavedState state = prepFpState(fpscr.rMode); 1374 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 1375 FpDest_uw = vfpFpSToFixed(FpOp1, false, false, imm); 1376 __asm__ __volatile__("" :: "m" (FpDest_uw)); 1377 finishVfp(fpscr, state, fpscr.fz); 1378 FpscrExc = fpscr; 1379 ''' 1380 vcvtFpUFixedSIop = InstObjParams("vcvt", "VcvtFpUFixedS", "FpRegRegImmOp", 1381 { "code": vcvtFpUFixedSCode, 1382 "predicate_test": predicateTest, 1383 "op_class": "SimdFloatCvtOp" }, []) 1384 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedSIop); 1385 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedSIop); 1386 exec_output += PredOpExecute.subst(vcvtFpUFixedSIop); 1387 1388 vcvtFpUFixedDCode = vfpEnabledCheckCode + ''' 1389 FPSCR fpscr = (FPSCR) FpscrExc; 1390 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 1391 vfpFlushToZero(fpscr, cOp1); 1392 VfpSavedState state = prepFpState(fpscr.rMode); 1393 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 1394 uint64_t mid = vfpFpDToFixed(cOp1, false, false, imm); 1395 __asm__ __volatile__("" :: "m" (mid)); 1396 finishVfp(fpscr, state, fpscr.fz); 1397 FpDestP0_uw = mid; 1398 FpDestP1_uw = mid >> 32; 1399 FpscrExc = fpscr; 1400 ''' 1401 vcvtFpUFixedDIop = InstObjParams("vcvt", "VcvtFpUFixedD", "FpRegRegImmOp", 1402 { "code": vcvtFpUFixedDCode, 1403 "predicate_test": predicateTest, 1404 "op_class": "SimdFloatCvtOp" }, []) 1405 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUFixedDIop); 1406 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUFixedDIop); 1407 exec_output += PredOpExecute.subst(vcvtFpUFixedDIop); 1408 1409 vcvtSFixedFpSCode = vfpEnabledCheckCode + ''' 1410 FPSCR fpscr = (FPSCR) FpscrExc; 1411 VfpSavedState state = prepFpState(fpscr.rMode); 1412 __asm__ __volatile__("" : "=m" (FpOp1_sw) : "m" (FpOp1_sw)); 1413 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sw, false, imm); 1414 __asm__ __volatile__("" :: "m" (FpDest)); 1415 finishVfp(fpscr, state, fpscr.fz); 1416 FpscrExc = fpscr; 1417 ''' 1418 vcvtSFixedFpSIop = InstObjParams("vcvt", "VcvtSFixedFpS", "FpRegRegImmOp", 1419 { "code": vcvtSFixedFpSCode, 1420 "predicate_test": predicateTest, 1421 "op_class": "SimdFloatCvtOp" }, []) 1422 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpSIop); 1423 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpSIop); 1424 exec_output += PredOpExecute.subst(vcvtSFixedFpSIop); 1425 1426 vcvtSFixedFpDCode = vfpEnabledCheckCode + ''' 1427 FPSCR fpscr = (FPSCR) FpscrExc; 1428 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32)); 1429 VfpSavedState state = prepFpState(fpscr.rMode); 1430 __asm__ __volatile__("" : "=m" (mid) : "m" (mid)); 1431 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, false, imm); 1432 __asm__ __volatile__("" :: "m" (cDest)); 1433 finishVfp(fpscr, state, fpscr.fz); 1434 FpDestP0_uw = dblLow(cDest); 1435 FpDestP1_uw = dblHi(cDest); 1436 FpscrExc = fpscr; 1437 ''' 1438 vcvtSFixedFpDIop = InstObjParams("vcvt", "VcvtSFixedFpD", "FpRegRegImmOp", 1439 { "code": vcvtSFixedFpDCode, 1440 "predicate_test": predicateTest, 1441 "op_class": "SimdFloatCvtOp" }, []) 1442 header_output += FpRegRegImmOpDeclare.subst(vcvtSFixedFpDIop); 1443 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSFixedFpDIop); 1444 exec_output += PredOpExecute.subst(vcvtSFixedFpDIop); 1445 1446 vcvtUFixedFpSCode = vfpEnabledCheckCode + ''' 1447 FPSCR fpscr = (FPSCR) FpscrExc; 1448 VfpSavedState state = prepFpState(fpscr.rMode); 1449 __asm__ __volatile__("" : "=m" (FpOp1_uw) : "m" (FpOp1_uw)); 1450 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uw, false, imm); 1451 __asm__ __volatile__("" :: "m" (FpDest)); 1452 finishVfp(fpscr, state, fpscr.fz); 1453 FpscrExc = fpscr; 1454 ''' 1455 vcvtUFixedFpSIop = InstObjParams("vcvt", "VcvtUFixedFpS", "FpRegRegImmOp", 1456 { "code": vcvtUFixedFpSCode, 1457 "predicate_test": predicateTest, 1458 "op_class": "SimdFloatCvtOp" }, []) 1459 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpSIop); 1460 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpSIop); 1461 exec_output += PredOpExecute.subst(vcvtUFixedFpSIop); 1462 1463 vcvtUFixedFpDCode = vfpEnabledCheckCode + ''' 1464 FPSCR fpscr = (FPSCR) FpscrExc; 1465 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32)); 1466 VfpSavedState state = prepFpState(fpscr.rMode); 1467 __asm__ __volatile__("" : "=m" (mid) : "m" (mid)); 1468 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, false, imm); 1469 __asm__ __volatile__("" :: "m" (cDest)); 1470 finishVfp(fpscr, state, fpscr.fz); 1471 FpDestP0_uw = dblLow(cDest); 1472 FpDestP1_uw = dblHi(cDest); 1473 FpscrExc = fpscr; 1474 ''' 1475 vcvtUFixedFpDIop = InstObjParams("vcvt", "VcvtUFixedFpD", "FpRegRegImmOp", 1476 { "code": vcvtUFixedFpDCode, 1477 "predicate_test": predicateTest, 1478 "op_class": "SimdFloatCvtOp" }, []) 1479 header_output += FpRegRegImmOpDeclare.subst(vcvtUFixedFpDIop); 1480 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUFixedFpDIop); 1481 exec_output += PredOpExecute.subst(vcvtUFixedFpDIop); 1482 1483 vcvtFpSHFixedSCode = vfpEnabledCheckCode + ''' 1484 FPSCR fpscr = (FPSCR) FpscrExc; 1485 vfpFlushToZero(fpscr, FpOp1); 1486 VfpSavedState state = prepFpState(fpscr.rMode); 1487 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 1488 FpDest_sh = vfpFpSToFixed(FpOp1, true, true, imm); 1489 __asm__ __volatile__("" :: "m" (FpDest_sh)); 1490 finishVfp(fpscr, state, fpscr.fz); 1491 FpscrExc = fpscr; 1492 ''' 1493 vcvtFpSHFixedSIop = InstObjParams("vcvt", "VcvtFpSHFixedS", 1494 "FpRegRegImmOp", 1495 { "code": vcvtFpSHFixedSCode, 1496 "predicate_test": predicateTest, 1497 "op_class": "SimdFloatCvtOp" }, []) 1498 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedSIop); 1499 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedSIop); 1500 exec_output += PredOpExecute.subst(vcvtFpSHFixedSIop); 1501 1502 vcvtFpSHFixedDCode = vfpEnabledCheckCode + ''' 1503 FPSCR fpscr = (FPSCR) FpscrExc; 1504 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 1505 vfpFlushToZero(fpscr, cOp1); 1506 VfpSavedState state = prepFpState(fpscr.rMode); 1507 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 1508 uint64_t result = vfpFpDToFixed(cOp1, true, true, imm); 1509 __asm__ __volatile__("" :: "m" (result)); 1510 finishVfp(fpscr, state, fpscr.fz); 1511 FpDestP0_uw = result; 1512 FpDestP1_uw = result >> 32; 1513 FpscrExc = fpscr; 1514 ''' 1515 vcvtFpSHFixedDIop = InstObjParams("vcvt", "VcvtFpSHFixedD", 1516 "FpRegRegImmOp", 1517 { "code": vcvtFpSHFixedDCode, 1518 "predicate_test": predicateTest, 1519 "op_class": "SimdFloatCvtOp" }, []) 1520 header_output += FpRegRegImmOpDeclare.subst(vcvtFpSHFixedDIop); 1521 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpSHFixedDIop); 1522 exec_output += PredOpExecute.subst(vcvtFpSHFixedDIop); 1523 1524 vcvtFpUHFixedSCode = vfpEnabledCheckCode + ''' 1525 FPSCR fpscr = (FPSCR) FpscrExc; 1526 vfpFlushToZero(fpscr, FpOp1); 1527 VfpSavedState state = prepFpState(fpscr.rMode); 1528 __asm__ __volatile__("" : "=m" (FpOp1) : "m" (FpOp1)); 1529 FpDest_uh = vfpFpSToFixed(FpOp1, false, true, imm); 1530 __asm__ __volatile__("" :: "m" (FpDest_uh)); 1531 finishVfp(fpscr, state, fpscr.fz); 1532 FpscrExc = fpscr; 1533 ''' 1534 vcvtFpUHFixedSIop = InstObjParams("vcvt", "VcvtFpUHFixedS", 1535 "FpRegRegImmOp", 1536 { "code": vcvtFpUHFixedSCode, 1537 "predicate_test": predicateTest, 1538 "op_class": "SimdFloatCvtOp" }, []) 1539 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedSIop); 1540 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedSIop); 1541 exec_output += PredOpExecute.subst(vcvtFpUHFixedSIop); 1542 1543 vcvtFpUHFixedDCode = vfpEnabledCheckCode + ''' 1544 FPSCR fpscr = (FPSCR) FpscrExc; 1545 double cOp1 = dbl(FpOp1P0_uw, FpOp1P1_uw); 1546 vfpFlushToZero(fpscr, cOp1); 1547 VfpSavedState state = prepFpState(fpscr.rMode); 1548 __asm__ __volatile__("" : "=m" (cOp1) : "m" (cOp1)); 1549 uint64_t mid = vfpFpDToFixed(cOp1, false, true, imm); 1550 __asm__ __volatile__("" :: "m" (mid)); 1551 finishVfp(fpscr, state, fpscr.fz); 1552 FpDestP0_uw = mid; 1553 FpDestP1_uw = mid >> 32; 1554 FpscrExc = fpscr; 1555 ''' 1556 vcvtFpUHFixedDIop = InstObjParams("vcvt", "VcvtFpUHFixedD", 1557 "FpRegRegImmOp", 1558 { "code": vcvtFpUHFixedDCode, 1559 "predicate_test": predicateTest, 1560 "op_class": "SimdFloatCvtOp" }, []) 1561 header_output += FpRegRegImmOpDeclare.subst(vcvtFpUHFixedDIop); 1562 decoder_output += FpRegRegImmOpConstructor.subst(vcvtFpUHFixedDIop); 1563 exec_output += PredOpExecute.subst(vcvtFpUHFixedDIop); 1564 1565 vcvtSHFixedFpSCode = vfpEnabledCheckCode + ''' 1566 FPSCR fpscr = (FPSCR) FpscrExc; 1567 VfpSavedState state = prepFpState(fpscr.rMode); 1568 __asm__ __volatile__("" : "=m" (FpOp1_sh) : "m" (FpOp1_sh)); 1569 FpDest = vfpSFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_sh, true, imm); 1570 __asm__ __volatile__("" :: "m" (FpDest)); 1571 finishVfp(fpscr, state, fpscr.fz); 1572 FpscrExc = fpscr; 1573 ''' 1574 vcvtSHFixedFpSIop = InstObjParams("vcvt", "VcvtSHFixedFpS", 1575 "FpRegRegImmOp", 1576 { "code": vcvtSHFixedFpSCode, 1577 "predicate_test": predicateTest, 1578 "op_class": "SimdFloatCvtOp" }, []) 1579 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpSIop); 1580 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpSIop); 1581 exec_output += PredOpExecute.subst(vcvtSHFixedFpSIop); 1582 1583 vcvtSHFixedFpDCode = vfpEnabledCheckCode + ''' 1584 FPSCR fpscr = (FPSCR) FpscrExc; 1585 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32)); 1586 VfpSavedState state = prepFpState(fpscr.rMode); 1587 __asm__ __volatile__("" : "=m" (mid) : "m" (mid)); 1588 double cDest = vfpSFixedToFpD(fpscr.fz, fpscr.dn, mid, true, imm); 1589 __asm__ __volatile__("" :: "m" (cDest)); 1590 finishVfp(fpscr, state, fpscr.fz); 1591 FpDestP0_uw = dblLow(cDest); 1592 FpDestP1_uw = dblHi(cDest); 1593 FpscrExc = fpscr; 1594 ''' 1595 vcvtSHFixedFpDIop = InstObjParams("vcvt", "VcvtSHFixedFpD", 1596 "FpRegRegImmOp", 1597 { "code": vcvtSHFixedFpDCode, 1598 "predicate_test": predicateTest, 1599 "op_class": "SimdFloatCvtOp" }, []) 1600 header_output += FpRegRegImmOpDeclare.subst(vcvtSHFixedFpDIop); 1601 decoder_output += FpRegRegImmOpConstructor.subst(vcvtSHFixedFpDIop); 1602 exec_output += PredOpExecute.subst(vcvtSHFixedFpDIop); 1603 1604 vcvtUHFixedFpSCode = vfpEnabledCheckCode + ''' 1605 FPSCR fpscr = (FPSCR) FpscrExc; 1606 VfpSavedState state = prepFpState(fpscr.rMode); 1607 __asm__ __volatile__("" : "=m" (FpOp1_uh) : "m" (FpOp1_uh)); 1608 FpDest = vfpUFixedToFpS(fpscr.fz, fpscr.dn, FpOp1_uh, true, imm); 1609 __asm__ __volatile__("" :: "m" (FpDest)); 1610 finishVfp(fpscr, state, fpscr.fz); 1611 FpscrExc = fpscr; 1612 ''' 1613 vcvtUHFixedFpSIop = InstObjParams("vcvt", "VcvtUHFixedFpS", 1614 "FpRegRegImmOp", 1615 { "code": vcvtUHFixedFpSCode, 1616 "predicate_test": predicateTest, 1617 "op_class": "SimdFloatCvtOp" }, []) 1618 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpSIop); 1619 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpSIop); 1620 exec_output += PredOpExecute.subst(vcvtUHFixedFpSIop); 1621 1622 vcvtUHFixedFpDCode = vfpEnabledCheckCode + ''' 1623 FPSCR fpscr = (FPSCR) FpscrExc; 1624 uint64_t mid = ((uint64_t)FpOp1P0_uw | ((uint64_t)FpOp1P1_uw << 32)); 1625 VfpSavedState state = prepFpState(fpscr.rMode); 1626 __asm__ __volatile__("" : "=m" (mid) : "m" (mid)); 1627 double cDest = vfpUFixedToFpD(fpscr.fz, fpscr.dn, mid, true, imm); 1628 __asm__ __volatile__("" :: "m" (cDest)); 1629 finishVfp(fpscr, state, fpscr.fz); 1630 FpDestP0_uw = dblLow(cDest); 1631 FpDestP1_uw = dblHi(cDest); 1632 FpscrExc = fpscr; 1633 ''' 1634 vcvtUHFixedFpDIop = InstObjParams("vcvt", "VcvtUHFixedFpD", 1635 "FpRegRegImmOp", 1636 { "code": vcvtUHFixedFpDCode, 1637 "predicate_test": predicateTest, 1638 "op_class": "SimdFloatCvtOp" }, []) 1639 header_output += FpRegRegImmOpDeclare.subst(vcvtUHFixedFpDIop); 1640 decoder_output += FpRegRegImmOpConstructor.subst(vcvtUHFixedFpDIop); 1641 exec_output += PredOpExecute.subst(vcvtUHFixedFpDIop); 1642}}; 1643