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();)