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