master
idef 344 lines 11.5 KB
Raw
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();)