qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

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 /*************************************/
     25 Q6INSN(F2_sfadd,"Rd32=sfadd(Rs32,Rt32)",ATTRIBS(),
     26 "Floating-Point Add",
     27 { RdV=fUNFLOAT(fFLOAT(RsV)+fFLOAT(RtV));})
     28 
     29 Q6INSN(F2_sfsub,"Rd32=sfsub(Rs32,Rt32)",ATTRIBS(),
     30 "Floating-Point Subtract",
     31 { RdV=fUNFLOAT(fFLOAT(RsV)-fFLOAT(RtV));})
     32 
     33 Q6INSN(F2_sfmpy,"Rd32=sfmpy(Rs32,Rt32)",ATTRIBS(),
     34 "Floating-Point Multiply",
     35 { RdV=fUNFLOAT(fSFMPY(fFLOAT(RsV),fFLOAT(RtV)));})
     36 
     37 Q6INSN(F2_sffma,"Rx32+=sfmpy(Rs32,Rt32)",ATTRIBS(),
     38 "Floating-Point Fused Multiply Add",
     39 { RxV=fUNFLOAT(fFMAF(fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV)));})
     40 
     41 Q6INSN(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 
     50 Q6INSN(F2_sffms,"Rx32-=sfmpy(Rs32,Rt32)",ATTRIBS(),
     51 "Floating-Point Fused Multiply Add",
     52 { RxV=fUNFLOAT(fFMAF(-fFLOAT(RsV),fFLOAT(RtV),fFLOAT(RxV))); })
     53 
     54 Q6INSN(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 
     69 Q6INSN(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 
     85 Q6INSN(F2_sfcmpeq,"Pd4=sfcmp.eq(Rs32,Rt32)",ATTRIBS(),
     86 "Floating Point Compare for Equal",
     87 {PdV=f8BITSOF(fFLOAT(RsV)==fFLOAT(RtV));})
     88 
     89 Q6INSN(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 
     95 Q6INSN(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 
    101 Q6INSN(F2_sfcmpuo,"Pd4=sfcmp.uo(Rs32,Rt32)",ATTRIBS(),
    102 "Floating-Point Compare for Unordered",
    103 {PdV=f8BITSOF(isunordered(fFLOAT(RsV),fFLOAT(RtV)));})
    104 
    105 
    106 Q6INSN(F2_sfmax,"Rd32=sfmax(Rs32,Rt32)",ATTRIBS(),
    107 "Maximum of Floating-Point values",
    108 { RdV = fUNFLOAT(fSF_MAX(fFLOAT(RsV),fFLOAT(RtV))); })
    109 
    110 Q6INSN(F2_sfmin,"Rd32=sfmin(Rs32,Rt32)",ATTRIBS(),
    111 "Minimum of Floating-Point values",
    112 { RdV = fUNFLOAT(fSF_MIN(fFLOAT(RsV),fFLOAT(RtV))); })
    113 
    114 
    115 Q6INSN(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 
    133 Q6INSN(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 
    140 Q6INSN(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 
    149 Q6INSN(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 
    165 Q6INSN(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 
    173 Q6INSN(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 
    181 Q6INSN(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 
    197 Q6INSN(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 /*************************************/
    208 Q6INSN(F2_dfadd,"Rdd32=dfadd(Rss32,Rtt32)",ATTRIBS(),
    209 "Floating-Point Add",
    210 { RddV=fUNDOUBLE(fDOUBLE(RssV)+fDOUBLE(RttV));})
    211 
    212 Q6INSN(F2_dfsub,"Rdd32=dfsub(Rss32,Rtt32)",ATTRIBS(),
    213 "Floating-Point Subtract",
    214 { RddV=fUNDOUBLE(fDOUBLE(RssV)-fDOUBLE(RttV));})
    215 
    216 Q6INSN(F2_dfmax,"Rdd32=dfmax(Rss32,Rtt32)",ATTRIBS(),
    217 "Maximum of Floating-Point values",
    218 { RddV = fUNDOUBLE(fDF_MAX(fDOUBLE(RssV),fDOUBLE(RttV))); })
    219 
    220 Q6INSN(F2_dfmin,"Rdd32=dfmin(Rss32,Rtt32)",ATTRIBS(),
    221 "Minimum of Floating-Point values",
    222 { RddV = fUNDOUBLE(fDF_MIN(fDOUBLE(RssV),fDOUBLE(RttV))); })
    223 
    224 Q6INSN(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 
    232 Q6INSN(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 
    241 Q6INSN(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 
    247 Q6INSN(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 
    255 Q6INSN(F2_dfcmpeq,"Pd4=dfcmp.eq(Rss32,Rtt32)",ATTRIBS(),
    256 "Floating Point Compare for Equal",
    257 {PdV=f8BITSOF(fDOUBLE(RssV)==fDOUBLE(RttV));})
    258 
    259 Q6INSN(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 
    266 Q6INSN(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 
    272 Q6INSN(F2_dfcmpuo,"Pd4=dfcmp.uo(Rss32,Rtt32)",ATTRIBS(),
    273 "Floating-Point Compare for Unordered",
    274 {PdV=f8BITSOF(isunordered(fDOUBLE(RssV),fDOUBLE(RttV)));})
    275 
    276 
    277 Q6INSN(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 
    296 Q6INSN(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 
    303 Q6INSN(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 
    319 CONVERT(sf2df,Rdd32,RddV,Rs32,RsV,fUNDOUBLE,df,fFLOAT,sf,,,)
    320 CONVERT(df2sf,Rd32,RdV,Rss32,RssV,fUNFLOAT,sf,fDOUBLE,df,,,)
    321 
    322 #define ALLINTDST(TAGSTART,SRC,SRCV,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    323 CONVERT(TAGSTART##uw,Rd32,RdV,SRC,SRCV,fCAST4u,4u,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    324 CONVERT(TAGSTART##w,Rd32,RdV,SRC,SRCV,fCAST4s,4s,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    325 CONVERT(TAGSTART##ud,Rdd32,RddV,SRC,SRCV,fCAST8u,8u,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    326 CONVERT(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) \
    329 CONVERT(TAGSTART##sf,Rd32,RdV,SRC,SRCV,fUNFLOAT,sf,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH) \
    330 CONVERT(TAGSTART##df,Rdd32,RddV,SRC,SRCV,fUNDOUBLE,df,INCAST,INTYPE,MODETAG,MODESYN,MODEBEH)
    331 
    332 #define ALLINTSRC(GEN,MODETAG,MODESYN,MODEBEH) \
    333 GEN(uw##2,Rs32,RsV,fCAST4u,4u,MODETAG,MODESYN,MODEBEH) \
    334 GEN(w##2,Rs32,RsV,fCAST4s,4s,MODETAG,MODESYN,MODEBEH) \
    335 GEN(ud##2,Rss32,RssV,fCAST8u,8u,MODETAG,MODESYN,MODEBEH) \
    336 GEN(d##2,Rss32,RssV,fCAST8s,8s,MODETAG,MODESYN,MODEBEH)
    337 
    338 #define ALLFPSRC(GEN,MODETAG,MODESYN,MODEBEH) \
    339 GEN(sf##2,Rs32,RsV,fFLOAT,sf,MODETAG,MODESYN,MODEBEH) \
    340 GEN(df##2,Rss32,RssV,fDOUBLE,df,MODETAG,MODESYN,MODEBEH)
    341 
    342 ALLINTSRC(ALLFPDST,,,)
    343 ALLFPSRC(ALLINTDST,,,)
    344 ALLFPSRC(ALLINTDST,_chop,:chop,fFPSETROUND_CHOP();)