vfp.hh revision 7430
12SN/A/* 214045Snikos.nikoleris@arm.com * Copyright (c) 2010 ARM Limited 311932Ssascha.bischoff@arm.com * All rights reserved 411932Ssascha.bischoff@arm.com * 511932Ssascha.bischoff@arm.com * The license below extends only to copyright in the software and shall 611932Ssascha.bischoff@arm.com * not be construed as granting a license to any other intellectual 711932Ssascha.bischoff@arm.com * property including but not limited to intellectual property relating 811932Ssascha.bischoff@arm.com * to a hardware implementation of the functionality of the software 911932Ssascha.bischoff@arm.com * licensed hereunder. You may use the software subject to the license 1011932Ssascha.bischoff@arm.com * terms below provided that you ensure that this notice is replicated 1111932Ssascha.bischoff@arm.com * unmodified and in its entirety in all distributions of the software, 1211932Ssascha.bischoff@arm.com * modified or unmodified, in source code or in binary form. 1311932Ssascha.bischoff@arm.com * 141762SN/A * Redistribution and use in source and binary forms, with or without 152SN/A * modification, are permitted provided that the following conditions are 162SN/A * met: redistributions of source code must retain the above copyright 172SN/A * notice, this list of conditions and the following disclaimer; 182SN/A * redistributions in binary form must reproduce the above copyright 192SN/A * notice, this list of conditions and the following disclaimer in the 202SN/A * documentation and/or other materials provided with the distribution; 212SN/A * neither the name of the copyright holders nor the names of its 222SN/A * contributors may be used to endorse or promote products derived from 232SN/A * this software without specific prior written permission. 242SN/A * 252SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 322SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 332SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 352SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 362SN/A * 372SN/A * Authors: Gabe Black 382SN/A */ 392665Ssaidi@eecs.umich.edu 402665Ssaidi@eecs.umich.edu#ifndef __ARCH_ARM_INSTS_VFP_HH__ 412665Ssaidi@eecs.umich.edu#define __ARCH_ARM_INSTS_VFP_HH__ 4212226Sgiacomo.travaglini@arm.com 432SN/A#include "arch/arm/insts/misc.hh" 442SN/A#include "arch/arm/miscregs.hh" 451112SN/A#include <fenv.h> 461112SN/A#include <cmath> 472SN/A 4811800Sbrandon.potter@amd.comnamespace ArmISA 4912226Sgiacomo.travaglini@arm.com{ 5012226Sgiacomo.travaglini@arm.com 5112226Sgiacomo.travaglini@arm.comenum VfpMicroMode { 5212226Sgiacomo.travaglini@arm.com VfpNotAMicroop, 5312226Sgiacomo.travaglini@arm.com VfpMicroop, 5412226Sgiacomo.travaglini@arm.com VfpFirstMicroop, 552SN/A VfpLastMicroop 562SN/A}; 572SN/A 582SN/Atemplate<class T> 592SN/Astatic inline void 602SN/AsetVfpMicroFlags(VfpMicroMode mode, T &flags) 612SN/A{ 622SN/A switch (mode) { 632SN/A case VfpMicroop: 642SN/A flags[StaticInst::IsMicroop] = true; 652SN/A break; 662SN/A case VfpFirstMicroop: 672SN/A flags[StaticInst::IsMicroop] = 682SN/A flags[StaticInst::IsFirstMicroop] = true; 692SN/A break; 702SN/A case VfpLastMicroop: 712SN/A flags[StaticInst::IsMicroop] = 722SN/A flags[StaticInst::IsLastMicroop] = true; 732SN/A break; 742SN/A case VfpNotAMicroop: 752SN/A break; 762SN/A } 772SN/A if (mode == VfpMicroop || mode == VfpFirstMicroop) { 782SN/A flags[StaticInst::IsDelayedCommit] = true; 794661Sksewell@umich.edu } 804661Sksewell@umich.edu} 814661Sksewell@umich.edu 824661Sksewell@umich.eduenum FeExceptionBit 834661Sksewell@umich.edu{ 844661Sksewell@umich.edu FeDivByZero = FE_DIVBYZERO, 854661Sksewell@umich.edu FeInexact = FE_INEXACT, 864661Sksewell@umich.edu FeInvalid = FE_INVALID, 874661Sksewell@umich.edu FeOverflow = FE_OVERFLOW, 884661Sksewell@umich.edu FeUnderflow = FE_UNDERFLOW, 894661Sksewell@umich.edu FeAllExceptions = FE_ALL_EXCEPT 903814Ssaidi@eecs.umich.edu}; 913814Ssaidi@eecs.umich.edu 923814Ssaidi@eecs.umich.eduenum FeRoundingMode 933814Ssaidi@eecs.umich.edu{ 943814Ssaidi@eecs.umich.edu FeRoundDown = FE_DOWNWARD, 953814Ssaidi@eecs.umich.edu FeRoundNearest = FE_TONEAREST, 963814Ssaidi@eecs.umich.edu FeRoundZero = FE_TOWARDZERO, 973814Ssaidi@eecs.umich.edu FeRoundUpward = FE_UPWARD 983814Ssaidi@eecs.umich.edu}; 993814Ssaidi@eecs.umich.edu 1003814Ssaidi@eecs.umich.eduenum VfpRoundingMode 1014070Ssaidi@eecs.umich.edu{ 1024070Ssaidi@eecs.umich.edu VfpRoundNearest = 0, 1034070Ssaidi@eecs.umich.edu VfpRoundUpward = 1, 1044070Ssaidi@eecs.umich.edu VfpRoundDown = 2, 1054070Ssaidi@eecs.umich.edu VfpRoundZero = 3 1064070Ssaidi@eecs.umich.edu}; 1073814Ssaidi@eecs.umich.edu 1082SN/Atemplate <class fpType> 1092SN/Astatic inline bool 1102SN/AflushToZero(fpType &op) 1112SN/A{ 11210537Sandreas.hansson@arm.com fpType junk = 0.0; 1132SN/A if (std::fpclassify(op) == FP_SUBNORMAL) { 1142SN/A uint64_t bitMask = ULL(0x1) << (sizeof(fpType) * 8 - 1); 1152SN/A op = bitsToFp(fpToBits(op) & bitMask, junk); 1162SN/A return true; 1172SN/A } 1182SN/A return false; 1193422Sgblack@eecs.umich.edu} 1203422Sgblack@eecs.umich.edu 1213422Sgblack@eecs.umich.edutemplate <class fpType> 1223422Sgblack@eecs.umich.edustatic inline bool 1233422Sgblack@eecs.umich.eduflushToZero(fpType &op1, fpType &op2) 1243422Sgblack@eecs.umich.edu{ 1253422Sgblack@eecs.umich.edu bool flush1 = flushToZero(op1); 1263422Sgblack@eecs.umich.edu bool flush2 = flushToZero(op2); 1274425Ssaidi@eecs.umich.edu return flush1 || flush2; 1283422Sgblack@eecs.umich.edu} 1294425Ssaidi@eecs.umich.edu 1303422Sgblack@eecs.umich.edutemplate <class fpType> 1313422Sgblack@eecs.umich.edustatic inline void 1323422Sgblack@eecs.umich.eduvfpFlushToZero(FPSCR &fpscr, fpType &op) 1334661Sksewell@umich.edu{ 1344661Sksewell@umich.edu if (fpscr.fz == 1 && flushToZero(op)) { 1354661Sksewell@umich.edu fpscr.idc = 1; 1364661Sksewell@umich.edu } 1374661Sksewell@umich.edu} 1384661Sksewell@umich.edu 1394661Sksewell@umich.edutemplate <class fpType> 1404661Sksewell@umich.edustatic inline void 1414661Sksewell@umich.eduvfpFlushToZero(FPSCR &fpscr, fpType &op1, fpType &op2) 1424661Sksewell@umich.edu{ 1434661Sksewell@umich.edu vfpFlushToZero(fpscr, op1); 1443422Sgblack@eecs.umich.edu vfpFlushToZero(fpscr, op2); 1453422Sgblack@eecs.umich.edu} 1463422Sgblack@eecs.umich.edu 1473422Sgblack@eecs.umich.edustatic inline uint32_t 1483422Sgblack@eecs.umich.edufpToBits(float fp) 1493422Sgblack@eecs.umich.edu{ 1503422Sgblack@eecs.umich.edu union 1513422Sgblack@eecs.umich.edu { 1523422Sgblack@eecs.umich.edu float fp; 1533422Sgblack@eecs.umich.edu uint32_t bits; 1543422Sgblack@eecs.umich.edu } val; 1554661Sksewell@umich.edu val.fp = fp; 1564661Sksewell@umich.edu return val.bits; 1574661Sksewell@umich.edu} 1584661Sksewell@umich.edu 1594661Sksewell@umich.edustatic inline uint64_t 1604661Sksewell@umich.edufpToBits(double fp) 1614661Sksewell@umich.edu{ 1624661Sksewell@umich.edu union 16312226Sgiacomo.travaglini@arm.com { 16412226Sgiacomo.travaglini@arm.com double fp; 16512226Sgiacomo.travaglini@arm.com uint64_t bits; 16612226Sgiacomo.travaglini@arm.com } val; 16712226Sgiacomo.travaglini@arm.com val.fp = fp; 16812226Sgiacomo.travaglini@arm.com return val.bits; 16912226Sgiacomo.travaglini@arm.com} 17012226Sgiacomo.travaglini@arm.com 17112226Sgiacomo.travaglini@arm.comstatic inline float 17212226Sgiacomo.travaglini@arm.combitsToFp(uint64_t bits, float junk) 17312226Sgiacomo.travaglini@arm.com{ 17412226Sgiacomo.travaglini@arm.com union 17512226Sgiacomo.travaglini@arm.com { 17612226Sgiacomo.travaglini@arm.com float fp; 17712226Sgiacomo.travaglini@arm.com uint32_t bits; 17812226Sgiacomo.travaglini@arm.com } val; 17912226Sgiacomo.travaglini@arm.com val.bits = bits; 18012226Sgiacomo.travaglini@arm.com return val.fp; 18112226Sgiacomo.travaglini@arm.com} 18212226Sgiacomo.travaglini@arm.com 18312226Sgiacomo.travaglini@arm.comstatic inline double 18412226Sgiacomo.travaglini@arm.combitsToFp(uint64_t bits, double junk) 18513824SAndrea.Mondelli@ucf.edu{ 18612226Sgiacomo.travaglini@arm.com union 18712226Sgiacomo.travaglini@arm.com { 18812226Sgiacomo.travaglini@arm.com double fp; 18912226Sgiacomo.travaglini@arm.com uint64_t bits; 19012226Sgiacomo.travaglini@arm.com } val; 19112226Sgiacomo.travaglini@arm.com val.bits = bits; 1924103Ssaidi@eecs.umich.edu return val.fp; 1934103Ssaidi@eecs.umich.edu} 1944103Ssaidi@eecs.umich.edu 1954103Ssaidi@eecs.umich.edutypedef int VfpSavedState; 1964103Ssaidi@eecs.umich.edu 1974103Ssaidi@eecs.umich.eduVfpSavedState prepFpState(uint32_t rMode); 1984103Ssaidi@eecs.umich.eduvoid finishVfp(FPSCR &fpscr, VfpSavedState state); 1994103Ssaidi@eecs.umich.edu 2004103Ssaidi@eecs.umich.edutemplate <class fpType> 2014244Ssaidi@eecs.umich.edufpType fixDest(FPSCR fpscr, fpType val, fpType op1); 2024244Ssaidi@eecs.umich.edu 2034244Ssaidi@eecs.umich.edutemplate <class fpType> 2044244Ssaidi@eecs.umich.edufpType fixDest(FPSCR fpscr, fpType val, fpType op1, fpType op2); 2054244Ssaidi@eecs.umich.edu 2064244Ssaidi@eecs.umich.edutemplate <class fpType> 2074103Ssaidi@eecs.umich.edufpType fixDivDest(FPSCR fpscr, fpType val, fpType op1, fpType op2); 2084103Ssaidi@eecs.umich.edu 2094103Ssaidi@eecs.umich.edufloat fixFpDFpSDest(FPSCR fpscr, double val); 2106274Sgblack@eecs.umich.edudouble fixFpSFpDDest(FPSCR fpscr, float val); 2116274Sgblack@eecs.umich.edu 2126274Sgblack@eecs.umich.edufloat vcvtFpSFpH(FPSCR &fpscr, float op, float dest, bool top); 2136274Sgblack@eecs.umich.edufloat vcvtFpHFpS(FPSCR &fpscr, float op, bool top); 2146274Sgblack@eecs.umich.edu 2156274Sgblack@eecs.umich.edustatic inline double 2166274Sgblack@eecs.umich.edumakeDouble(uint32_t low, uint32_t high) 2176274Sgblack@eecs.umich.edu{ 2186274Sgblack@eecs.umich.edu double junk = 0.0; 2196274Sgblack@eecs.umich.edu return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk); 2206274Sgblack@eecs.umich.edu} 2216274Sgblack@eecs.umich.edu 2226274Sgblack@eecs.umich.edustatic inline uint32_t 2236274Sgblack@eecs.umich.edulowFromDouble(double val) 2246274Sgblack@eecs.umich.edu{ 2256274Sgblack@eecs.umich.edu return fpToBits(val); 2266274Sgblack@eecs.umich.edu} 22710400Sstephan.diestelhorst@arm.com 22810400Sstephan.diestelhorst@arm.comstatic inline uint32_t 22910400Sstephan.diestelhorst@arm.comhighFromDouble(double val) 23010400Sstephan.diestelhorst@arm.com{ 23110400Sstephan.diestelhorst@arm.com return fpToBits(val) >> 32; 23210400Sstephan.diestelhorst@arm.com} 23310400Sstephan.diestelhorst@arm.com 23410400Sstephan.diestelhorst@arm.comuint64_t vfpFpSToFixed(float val, bool isSigned, bool half, 23510400Sstephan.diestelhorst@arm.com uint8_t imm, bool rzero = true); 23610400Sstephan.diestelhorst@arm.comfloat vfpUFixedToFpS(FPSCR fpscr, uint32_t val, bool half, uint8_t imm); 23710400Sstephan.diestelhorst@arm.comfloat vfpSFixedToFpS(FPSCR fpscr, int32_t val, bool half, uint8_t imm); 23810400Sstephan.diestelhorst@arm.com 23910400Sstephan.diestelhorst@arm.comuint64_t vfpFpDToFixed(double val, bool isSigned, bool half, 24010400Sstephan.diestelhorst@arm.com uint8_t imm, bool rzero = true); 24110400Sstephan.diestelhorst@arm.comdouble vfpUFixedToFpD(FPSCR fpscr, uint32_t val, bool half, uint8_t imm); 24210400Sstephan.diestelhorst@arm.comdouble vfpSFixedToFpD(FPSCR fpscr, int32_t val, bool half, uint8_t imm); 24310400Sstephan.diestelhorst@arm.com 24410400Sstephan.diestelhorst@arm.comclass VfpMacroOp : public PredMacroOp 24510400Sstephan.diestelhorst@arm.com{ 24610400Sstephan.diestelhorst@arm.com public: 24710400Sstephan.diestelhorst@arm.com static bool 24810400Sstephan.diestelhorst@arm.com inScalarBank(IntRegIndex idx) 24910400Sstephan.diestelhorst@arm.com { 25010400Sstephan.diestelhorst@arm.com return (idx % 32) < 8; 25110400Sstephan.diestelhorst@arm.com } 25210400Sstephan.diestelhorst@arm.com 25310400Sstephan.diestelhorst@arm.com protected: 25410400Sstephan.diestelhorst@arm.com bool wide; 25510400Sstephan.diestelhorst@arm.com 25610400Sstephan.diestelhorst@arm.com VfpMacroOp(const char *mnem, ExtMachInst _machInst, 25710400Sstephan.diestelhorst@arm.com OpClass __opClass, bool _wide) : 25810400Sstephan.diestelhorst@arm.com PredMacroOp(mnem, _machInst, __opClass), wide(_wide) 25910400Sstephan.diestelhorst@arm.com {} 26011932Ssascha.bischoff@arm.com 26111932Ssascha.bischoff@arm.com IntRegIndex addStride(IntRegIndex idx, unsigned stride); 26211932Ssascha.bischoff@arm.com void nextIdxs(IntRegIndex &dest, IntRegIndex &op1, IntRegIndex &op2); 26311932Ssascha.bischoff@arm.com void nextIdxs(IntRegIndex &dest, IntRegIndex &op1); 26411932Ssascha.bischoff@arm.com void nextIdxs(IntRegIndex &dest); 26511932Ssascha.bischoff@arm.com}; 26611932Ssascha.bischoff@arm.com 26711932Ssascha.bischoff@arm.comstatic inline float 26811932Ssascha.bischoff@arm.comfpAddS(float a, float b) 26911932Ssascha.bischoff@arm.com{ 27011932Ssascha.bischoff@arm.com return a + b; 27111932Ssascha.bischoff@arm.com} 27211932Ssascha.bischoff@arm.com 27311932Ssascha.bischoff@arm.comstatic inline double 27411932Ssascha.bischoff@arm.comfpAddD(double a, double b) 27511932Ssascha.bischoff@arm.com{ 27611932Ssascha.bischoff@arm.com return a + b; 27711932Ssascha.bischoff@arm.com} 27811932Ssascha.bischoff@arm.com 27911932Ssascha.bischoff@arm.comstatic inline float 28011932Ssascha.bischoff@arm.comfpSubS(float a, float b) 28111932Ssascha.bischoff@arm.com{ 28211932Ssascha.bischoff@arm.com return a - b; 28311932Ssascha.bischoff@arm.com} 28411932Ssascha.bischoff@arm.com 28513531Sjairo.balart@metempsy.comstatic inline double 28613531Sjairo.balart@metempsy.comfpSubD(double a, double b) 28713531Sjairo.balart@metempsy.com{ 28813531Sjairo.balart@metempsy.com return a - b; 28913531Sjairo.balart@metempsy.com} 29013531Sjairo.balart@metempsy.com 29113531Sjairo.balart@metempsy.comstatic inline float 29213531Sjairo.balart@metempsy.comfpDivS(float a, float b) 29313531Sjairo.balart@metempsy.com{ 29413531Sjairo.balart@metempsy.com return a / b; 29513531Sjairo.balart@metempsy.com} 29614045Snikos.nikoleris@arm.com 29714045Snikos.nikoleris@arm.comstatic inline double 29814045Snikos.nikoleris@arm.comfpDivD(double a, double b) 29914045Snikos.nikoleris@arm.com{ 30014045Snikos.nikoleris@arm.com return a / b; 30114045Snikos.nikoleris@arm.com} 30214045Snikos.nikoleris@arm.com 30314045Snikos.nikoleris@arm.comstatic inline float 30414045Snikos.nikoleris@arm.comfpMulS(float a, float b) 30514045Snikos.nikoleris@arm.com{ 30614045Snikos.nikoleris@arm.com return a * b; 3071112SN/A} 308 309static inline double 310fpMulD(double a, double b) 311{ 312 return a * b; 313} 314 315class FpOp : public PredOp 316{ 317 protected: 318 FpOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : 319 PredOp(mnem, _machInst, __opClass) 320 {} 321 322 virtual float 323 doOp(float op1, float op2) const 324 { 325 panic("Unimplemented version of doOp called.\n"); 326 } 327 328 virtual float 329 doOp(float op1) const 330 { 331 panic("Unimplemented version of doOp called.\n"); 332 } 333 334 virtual double 335 doOp(double op1, double op2) const 336 { 337 panic("Unimplemented version of doOp called.\n"); 338 } 339 340 virtual double 341 doOp(double op1) const 342 { 343 panic("Unimplemented version of doOp called.\n"); 344 } 345 346 double 347 dbl(uint32_t low, uint32_t high) const 348 { 349 double junk = 0.0; 350 return bitsToFp((uint64_t)low | ((uint64_t)high << 32), junk); 351 } 352 353 uint32_t 354 dblLow(double val) const 355 { 356 return fpToBits(val); 357 } 358 359 uint32_t 360 dblHi(double val) const 361 { 362 return fpToBits(val) >> 32; 363 } 364 365 template <class fpType> 366 fpType 367 binaryOp(FPSCR &fpscr, fpType op1, fpType op2, 368 fpType (*func)(fpType, fpType), 369 bool flush, uint32_t rMode) const; 370 371 template <class fpType> 372 fpType 373 unaryOp(FPSCR &fpscr, fpType op1, 374 fpType (*func)(fpType), 375 bool flush, uint32_t rMode) const; 376}; 377 378class FpRegRegOp : public FpOp 379{ 380 protected: 381 IntRegIndex dest; 382 IntRegIndex op1; 383 384 FpRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 385 IntRegIndex _dest, IntRegIndex _op1, 386 VfpMicroMode mode = VfpNotAMicroop) : 387 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1) 388 { 389 setVfpMicroFlags(mode, flags); 390 } 391 392 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 393}; 394 395class FpRegImmOp : public FpOp 396{ 397 protected: 398 IntRegIndex dest; 399 uint64_t imm; 400 401 FpRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 402 IntRegIndex _dest, uint64_t _imm, 403 VfpMicroMode mode = VfpNotAMicroop) : 404 FpOp(mnem, _machInst, __opClass), dest(_dest), imm(_imm) 405 { 406 setVfpMicroFlags(mode, flags); 407 } 408 409 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 410}; 411 412class FpRegRegImmOp : public FpOp 413{ 414 protected: 415 IntRegIndex dest; 416 IntRegIndex op1; 417 uint64_t imm; 418 419 FpRegRegImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 420 IntRegIndex _dest, IntRegIndex _op1, 421 uint64_t _imm, VfpMicroMode mode = VfpNotAMicroop) : 422 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), imm(_imm) 423 { 424 setVfpMicroFlags(mode, flags); 425 } 426 427 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 428}; 429 430class FpRegRegRegOp : public FpOp 431{ 432 protected: 433 IntRegIndex dest; 434 IntRegIndex op1; 435 IntRegIndex op2; 436 437 FpRegRegRegOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass, 438 IntRegIndex _dest, IntRegIndex _op1, IntRegIndex _op2, 439 VfpMicroMode mode = VfpNotAMicroop) : 440 FpOp(mnem, _machInst, __opClass), dest(_dest), op1(_op1), op2(_op2) 441 { 442 setVfpMicroFlags(mode, flags); 443 } 444 445 std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; 446}; 447 448} 449 450#endif //__ARCH_ARM_INSTS_VFP_HH__ 451