cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

float.idef (11752B)


      1/*
      2 *  Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
      3 *
      4 *  This program is free software; you can redistribute it and/or modify
      5 *  it under the terms of the GNU General Public License as published by
      6 *  the Free Software Foundation; either version 2 of the License, or
      7 *  (at your option) any later version.
      8 *
      9 *  This program is distributed in the hope that it will be useful,
     10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 *  GNU General Public License for more details.
     13 *
     14 *  You should have received a copy of the GNU General Public License
     15 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
     16 */
     17
     18/*
     19 * Floating-Point Instructions
     20 */
     21
     22/*************************************/
     23/* Scalar FP                         */
     24/*************************************/
     25Q6INSN(F2_sfadd,"Rd32=sfadd(Rs32,Rt32)",ATTRIBS(),
     26"Floating-Point Add",
     27{ RdV=fUNFLOAT(fFLOAT(RsV)+fFLOAT(RtV));})
     28
     29Q6INSN(F2_sfsub,"Rd32=sfsub(Rs32,Rt32)",ATTRIBS(),
     30"Floating-Point Subtract",
     31{ RdV=fUNFLOAT(fFLOAT(RsV)-fFLOAT(RtV));})
     32
     33Q6INSN(F2_sfmpy,"Rd32=sfmpy(Rs32,Rt32)",ATTRIBS(),
     34"Floating-Point Multiply",
     35{ RdV=fUNFLOAT(fSFMPY(fFLOAT(RsV),fFLOAT(RtV)));})
     36
     37Q6INSN(F2_sffma,"Rx32+=sfmpy(Rs32,Rt32)",ATTRIBS(),
     38"Floating-Point Fused Multiply Add",
     39{ RxV=fUNFLOAT(fFMAF(fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV)));})
     40
     41Q6INSN(F2_sffma_sc,"Rx32+=sfmpy(Rs32,Rt32,Pu4):scale",ATTRIBS(),
     42"Floating-Point Fused Multiply Add w/ Additional Scaling (2**Pu)",
     43{
     44    fHIDE(size4s_t tmp;)
     45    fCHECKSFNAN3(RxV,RxV,RsV,RtV);
     46    tmp=fUNFLOAT(fFMAFX(fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV),PuV));
     47    if (!((fFLOAT(RxV) == 0.0) && fISZEROPROD(fFLOAT(RsV),fFLOAT(RtV)))) RxV = tmp;
     48})
     49
     50Q6INSN(F2_sffms,"Rx32-=sfmpy(Rs32,Rt32)",ATTRIBS(),
     51"Floating-Point Fused Multiply Add",
     52{ RxV=fUNFLOAT(fFMAF(-fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV))); })
     53
     54Q6INSN(F2_sffma_lib,"Rx32+=sfmpy(Rs32,Rt32):lib",ATTRIBS(),
     55"Floating-Point Fused Multiply Add for Library Routines",
     56{ fFPSETROUND_NEAREST(); fHIDE(int infinp; int infminusinf; size4s_t tmp;)
     57  infminusinf = ((isinf(fFLOAT(RxV))) &&
     58                 (fISINFPROD(fFLOAT(RsV),fFLOAT(RtV))) &&
     59                 (fGETBIT(31,RsV ^ RxV ^ RtV) != 0));
     60  infinp = (isinf(fFLOAT(RxV))) || (isinf(fFLOAT(RtV))) || (isinf(fFLOAT(RsV)));
     61  fCHECKSFNAN3(RxV,RxV,RsV,RtV);
     62  tmp=fUNFLOAT(fFMAF(fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV)));
     63  if (!((fFLOAT(RxV) == 0.0) && fISZEROPROD(fFLOAT(RsV),fFLOAT(RtV)))) RxV = tmp;
     64  fFPCANCELFLAGS();
     65  if (isinf(fFLOAT(RxV)) && !infinp) RxV = RxV - 1;
     66  if (infminusinf) RxV = 0;
     67})
     68
     69Q6INSN(F2_sffms_lib,"Rx32-=sfmpy(Rs32,Rt32):lib",ATTRIBS(),
     70"Floating-Point Fused Multiply Add for Library Routines",
     71{ fFPSETROUND_NEAREST(); fHIDE(int infinp; int infminusinf; size4s_t tmp;)
     72  infminusinf = ((isinf(fFLOAT(RxV))) &&
     73                 (fISINFPROD(fFLOAT(RsV),fFLOAT(RtV))) &&
     74                 (fGETBIT(31,RsV ^ RxV ^ RtV) == 0));
     75  infinp = (isinf(fFLOAT(RxV))) || (isinf(fFLOAT(RtV))) || (isinf(fFLOAT(RsV)));
     76  fCHECKSFNAN3(RxV,RxV,RsV,RtV);
     77  tmp=fUNFLOAT(fFMAF(-fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV)));
     78  if (!((fFLOAT(RxV) == 0.0) && fISZEROPROD(fFLOAT(RsV),fFLOAT(RtV)))) RxV = tmp;
     79  fFPCANCELFLAGS();
     80  if (isinf(fFLOAT(RxV)) && !infinp) RxV = RxV - 1;
     81  if (infminusinf) RxV = 0;
     82})
     83
     84
     85Q6INSN(F2_sfcmpeq,"Pd4=sfcmp.eq(Rs32,Rt32)",ATTRIBS(),
     86"Floating Point Compare for Equal",
     87{PdV=f8BITSOF(fFLOAT(RsV)==fFLOAT(RtV));})
     88
     89Q6INSN(F2_sfcmpgt,"Pd4=sfcmp.gt(Rs32,Rt32)",ATTRIBS(),
     90"Floating-Point Compare for Greater Than",
     91{PdV=f8BITSOF(fFLOAT(RsV)>fFLOAT(RtV));})
     92
     93/* cmpge is not the same as !cmpgt(swapops) in IEEE */
     94
     95Q6INSN(F2_sfcmpge,"Pd4=sfcmp.ge(Rs32,Rt32)",ATTRIBS(),
     96"Floating-Point Compare for Greater Than / Equal To",
     97{PdV=f8BITSOF(fFLOAT(RsV)>=fFLOAT(RtV));})
     98
     99/* Everyone seems to have this... */
    100
    101Q6INSN(F2_sfcmpuo,"Pd4=sfcmp.uo(Rs32,Rt32)",ATTRIBS(),
    102"Floating-Point Compare for Unordered",
    103{PdV=f8BITSOF(isunordered(fFLOAT(RsV),fFLOAT(RtV)));})
    104
    105
    106Q6INSN(F2_sfmax,"Rd32=sfmax(Rs32,Rt32)",ATTRIBS(),
    107"Maximum of Floating-Point values",
    108{ RdV = fUNFLOAT(fSF_MAX(fFLOAT(RsV),fFLOAT(RtV))); })
    109
    110Q6INSN(F2_sfmin,"Rd32=sfmin(Rs32,Rt32)",ATTRIBS(),
    111"Minimum of Floating-Point values",
    112{ RdV = fUNFLOAT(fSF_MIN(fFLOAT(RsV),fFLOAT(RtV))); })
    113
    114
    115Q6INSN(F2_sfclass,"Pd4=sfclass(Rs32,#u5)",ATTRIBS(),
    116"Classify Floating-Point Value",
    117{
    118    fHIDE(int class;)
    119    PdV = 0;
    120    class = fpclassify(fFLOAT(RsV));
    121    /* Is the value zero? */
    122    if (fGETBIT(0,uiV) && (class == FP_ZERO)) PdV = 0xff;
    123    if (fGETBIT(1,uiV) && (class == FP_NORMAL)) PdV = 0xff;
    124    if (fGETBIT(2,uiV) && (class == FP_SUBNORMAL)) PdV = 0xff;
    125    if (fGETBIT(3,uiV) && (class == FP_INFINITE)) PdV = 0xff;
    126    if (fGETBIT(4,uiV) && (class == FP_NAN)) PdV = 0xff;
    127    fFPCANCELFLAGS();
    128})
    129
    130/* Range: +/- (1.0 .. 1+(63/64)) * 2**(-6 .. +9) */
    131/* More immediate bits should probably be used for more precision? */
    132
    133Q6INSN(F2_sfimm_p,"Rd32=sfmake(#u10):pos",ATTRIBS(),
    134"Make Floating Point Value",
    135{
    136    RdV = (127 - 6) << 23;
    137    RdV += uiV << 17;
    138})
    139
    140Q6INSN(F2_sfimm_n,"Rd32=sfmake(#u10):neg",ATTRIBS(),
    141"Make Floating Point Value",
    142{
    143    RdV = (127 - 6) << 23;
    144    RdV += (uiV << 17);
    145    RdV |= (1 << 31);
    146})
    147
    148
    149Q6INSN(F2_sfrecipa,"Rd32,Pe4=sfrecipa(Rs32,Rt32)",ATTRIBS(),
    150"Reciprocal Approximation for Division",
    151{
    152    fHIDE(int idx;)
    153    fHIDE(int adjust;)
    154    fHIDE(int mant;)
    155    fHIDE(int exp;)
    156    if (fSF_RECIP_COMMON(RsV,RtV,RdV,adjust)) {
    157        PeV = adjust;
    158        idx = (RtV >> 16) & 0x7f;
    159        mant = (fSF_RECIP_LOOKUP(idx) << 15) | 1;
    160        exp = fSF_BIAS() - (fSF_GETEXP(RtV) - fSF_BIAS()) - 1;
    161        RdV = fMAKESF(fGETBIT(31,RtV),exp,mant);
    162    }
    163})
    164
    165Q6INSN(F2_sffixupn,"Rd32=sffixupn(Rs32,Rt32)",ATTRIBS(),
    166"Fix Up Numerator",
    167{
    168    fHIDE(int adjust;)
    169    fSF_RECIP_COMMON(RsV,RtV,RdV,adjust);
    170    RdV = RsV;
    171})
    172
    173Q6INSN(F2_sffixupd,"Rd32=sffixupd(Rs32,Rt32)",ATTRIBS(),
    174"Fix Up Denominator",
    175{
    176    fHIDE(int adjust;)
    177    fSF_RECIP_COMMON(RsV,RtV,RdV,adjust);
    178    RdV = RtV;
    179})
    180
    181Q6INSN(F2_sfinvsqrta,"Rd32,Pe4=sfinvsqrta(Rs32)",ATTRIBS(),
    182"Reciprocal Square Root Approximation",
    183{
    184    fHIDE(int idx;)
    185    fHIDE(int adjust;)
    186    fHIDE(int mant;)
    187    fHIDE(int exp;)
    188    if (fSF_INVSQRT_COMMON(RsV,RdV,adjust)) {
    189        PeV = adjust;
    190        idx = (RsV >> 17) & 0x7f;
    191        mant = (fSF_INVSQRT_LOOKUP(idx) << 15);
    192        exp = fSF_BIAS() - ((fSF_GETEXP(RsV) - fSF_BIAS()) >> 1) - 1;
    193        RdV = fMAKESF(fGETBIT(31,RsV),exp,mant);
    194    }
    195})
    196
    197Q6INSN(F2_sffixupr,"Rd32=sffixupr(Rs32)",ATTRIBS(),
    198"Fix Up Radicand",
    199{
    200    fHIDE(int adjust;)
    201    fSF_INVSQRT_COMMON(RsV,RdV,adjust);
    202    RdV = RsV;
    203})
    204
    205/*************************************/
    206/* Scalar DP                         */
    207/*************************************/
    208Q6INSN(F2_dfadd,"Rdd32=dfadd(Rss32,Rtt32)",ATTRIBS(),
    209"Floating-Point Add",
    210{ RddV=fUNDOUBLE(fDOUBLE(RssV)+fDOUBLE(RttV));})
    211
    212Q6INSN(F2_dfsub,"Rdd32=dfsub(Rss32,Rtt32)",ATTRIBS(),
    213"Floating-Point Subtract",
    214{ RddV=fUNDOUBLE(fDOUBLE(RssV)-fDOUBLE(RttV));})
    215
    216Q6INSN(F2_dfmax,"Rdd32=dfmax(Rss32,Rtt32)",ATTRIBS(),
    217"Maximum of Floating-Point values",
    218{ RddV = fUNDOUBLE(fDF_MAX(fDOUBLE(RssV),fDOUBLE(RttV))); })
    219
    220Q6INSN(F2_dfmin,"Rdd32=dfmin(Rss32,Rtt32)",ATTRIBS(),
    221"Minimum of Floating-Point values",
    222{ RddV = fUNDOUBLE(fDF_MIN(fDOUBLE(RssV),fDOUBLE(RttV))); })
    223
    224Q6INSN(F2_dfmpyfix,"Rdd32=dfmpyfix(Rss32,Rtt32)",ATTRIBS(),
    225"Fix Up Multiplicand for Multiplication",
    226{
    227    if (fDF_ISDENORM(RssV) && fDF_ISBIG(RttV) && fDF_ISNORMAL(RttV)) RddV = fUNDOUBLE(fDOUBLE(RssV) * 0x1.0p52);
    228    else if (fDF_ISDENORM(RttV) && fDF_ISBIG(RssV) && fDF_ISNORMAL(RssV)) RddV = fUNDOUBLE(fDOUBLE(RssV) * 0x1.0p-52);
    229    else RddV = RssV;
    230})
    231
    232Q6INSN(F2_dfmpyll,"Rdd32=dfmpyll(Rss32,Rtt32)",ATTRIBS(),
    233"Multiply low*low and shift off low 32 bits into sticky (in MSB)",
    234{
    235    fHIDE(size8u_t prod;)
    236    prod = fMPY32UU(fGETUWORD(0,RssV),fGETUWORD(0,RttV));
    237    RddV = (prod >> 32) << 1;
    238    if (fGETUWORD(0,prod) != 0) fSETBIT(0,RddV,1);
    239})
    240
    241Q6INSN(F2_dfmpylh,"Rxx32+=dfmpylh(Rss32,Rtt32)",ATTRIBS(),
    242"Multiply low*high and accumulate",
    243{
    244    RxxV += (fGETUWORD(0,RssV) * (0x00100000 | fZXTN(20,64,fGETUWORD(1,RttV)))) << 1;
    245})
    246
    247Q6INSN(F2_dfmpyhh,"Rxx32+=dfmpyhh(Rss32,Rtt32)",ATTRIBS(),
    248"Multiply high*high and accumulate with L*H value",
    249{
    250    RxxV = fUNDOUBLE(fDF_MPY_HH(fDOUBLE(RssV),fDOUBLE(RttV),RxxV));
    251})
    252
    253
    254
    255Q6INSN(F2_dfcmpeq,"Pd4=dfcmp.eq(Rss32,Rtt32)",ATTRIBS(),
    256"Floating Point Compare for Equal",
    257{PdV=f8BITSOF(fDOUBLE(RssV)==fDOUBLE(RttV));})
    258
    259Q6INSN(F2_dfcmpgt,"Pd4=dfcmp.gt(Rss32,Rtt32)",ATTRIBS(),
    260"Floating-Point Compare for Greater Than",
    261{PdV=f8BITSOF(fDOUBLE(RssV)>fDOUBLE(RttV));})
    262
    263
    264/* cmpge is not the same as !cmpgt(swapops) in IEEE */
    265
    266Q6INSN(F2_dfcmpge,"Pd4=dfcmp.ge(Rss32,Rtt32)",ATTRIBS(),
    267"Floating-Point Compare for Greater Than / Equal To",
    268{PdV=f8BITSOF(fDOUBLE(RssV)>=fDOUBLE(RttV));})
    269
    270/* Everyone seems to have this... */
    271
    272Q6INSN(F2_dfcmpuo,"Pd4=dfcmp.uo(Rss32,Rtt32)",ATTRIBS(),
    273"Floating-Point Compare for Unordered",
    274{PdV=f8BITSOF(isunordered(fDOUBLE(RssV),fDOUBLE(RttV)));})
    275
    276
    277Q6INSN(F2_dfclass,"Pd4=dfclass(Rss32,#u5)",ATTRIBS(),
    278"Classify Floating-Point Value",
    279{
    280    fHIDE(int class;)
    281    PdV = 0;
    282    class = fpclassify(fDOUBLE(RssV));
    283    /* Is the value zero? */
    284    if (fGETBIT(0,uiV) && (class == FP_ZERO)) PdV = 0xff;
    285    if (fGETBIT(1,uiV) && (class == FP_NORMAL)) PdV = 0xff;
    286    if (fGETBIT(2,uiV) && (class == FP_SUBNORMAL)) PdV = 0xff;
    287    if (fGETBIT(3,uiV) && (class == FP_INFINITE)) PdV = 0xff;
    288    if (fGETBIT(4,uiV) && (class == FP_NAN)) PdV = 0xff;
    289    fFPCANCELFLAGS();
    290})
    291
    292
    293/* Range: +/- (1.0 .. 1+(63/64)) * 2**(-6 .. +9) */
    294/* More immediate bits should probably be used for more precision? */
    295
    296Q6INSN(F2_dfimm_p,"Rdd32=dfmake(#u10):pos",ATTRIBS(),
    297"Make Floating Point Value",
    298{
    299    RddV = (1023ULL - 6) << 52;
    300    RddV += (fHIDE((size8u_t))uiV) << 46;
    301})
    302
    303Q6INSN(F2_dfimm_n,"Rdd32=dfmake(#u10):neg",ATTRIBS(),
    304"Make Floating Point Value",
    305{
    306    RddV = (1023ULL - 6) << 52;
    307    RddV += (fHIDE((size8u_t))uiV) << 46;
    308    RddV |= ((1ULL) << 63);
    309})
    310
    311
    312/* CONVERSION */
    313
    314#define CONVERT(TAG,DEST,DESTV,SRC,SRCV,OUTCAST,OUTTYPE,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    315    Q6INSN(F2_conv_##TAG##MODETAG,#DEST"=convert_"#TAG"("#SRC")"#MODESYN,ATTRIBS(), \
    316    "Floating point format conversion", \
    317    { MODEBEH DESTV = OUTCAST(conv_##INTYPE##_to_##OUTTYPE(INCAST(SRCV))); })
    318
    319CONVERT(sf2df,Rdd32,RddV,Rs32,RsV,fUNDOUBLE,df,fFLOAT,sf,,,)
    320CONVERT(df2sf,Rd32,RdV,Rss32,RssV,fUNFLOAT,sf,fDOUBLE,df,,,)
    321
    322#define ALLINTDST(TAGSTART,SRC,SRCV,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    323CONVERT(TAGSTART##uw,Rd32,RdV,SRC,SRCV,fCAST4u,4u,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    324CONVERT(TAGSTART##w,Rd32,RdV,SRC,SRCV,fCAST4s,4s,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    325CONVERT(TAGSTART##ud,Rdd32,RddV,SRC,SRCV,fCAST8u,8u,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    326CONVERT(TAGSTART##d,Rdd32,RddV,SRC,SRCV,fCAST8s,8s,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH)
    327
    328#define ALLFPDST(TAGSTART,SRC,SRCV,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    329CONVERT(TAGSTART##sf,Rd32,RdV,SRC,SRCV,fUNFLOAT,sf,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    330CONVERT(TAGSTART##df,Rdd32,RddV,SRC,SRCV,fUNDOUBLE,df,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH)
    331
    332#define ALLINTSRC(GEN,MODETAG,MODESYN,MODEBEH) \
    333GEN(uw##2,Rs32,RsV,fCAST4u,4u,MODETAG,MODESYN,MODEBEH) \
    334GEN(w##2,Rs32,RsV,fCAST4s,4s,MODETAG,MODESYN,MODEBEH) \
    335GEN(ud##2,Rss32,RssV,fCAST8u,8u,MODETAG,MODESYN,MODEBEH) \
    336GEN(d##2,Rss32,RssV,fCAST8s,8s,MODETAG,MODESYN,MODEBEH)
    337
    338#define ALLFPSRC(GEN,MODETAG,MODESYN,MODEBEH) \
    339GEN(sf##2,Rs32,RsV,fFLOAT,sf,MODETAG,MODESYN,MODEBEH) \
    340GEN(df##2,Rss32,RssV,fDOUBLE,df,MODETAG,MODESYN,MODEBEH)
    341
    342ALLINTSRC(ALLFPDST,,,)
    343ALLFPSRC(ALLINTDST,,,)
    344ALLFPSRC(ALLINTDST,_chop,:chop,fFPSETROUND_CHOP();)