|
|
1.1 root 1: /* automatically generated by sparc-fpu-auto.sh, do not edit! */
2: _TME_RCSID("$Id: sparc-fpu-auto.sh,v 1.4 2007/01/14 16:40:12 fredette Exp $");
3:
4: /* this sets the floating-point condition codes after a
5: single-precision operation: */
6: static void inline
7: _tme_sparc_fpu_fcc_single(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
8: {
9: tme_uint32_t fcc;
10:
11: /* set fcc: */
12: fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
13: ? TME_SPARC_FSR_FCC_UN
14: : tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
15: ? TME_SPARC_FSR_FCC_EQ
16: : tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
17: ? TME_SPARC_FSR_FCC_LT
18: : TME_SPARC_FSR_FCC_GT);
19:
20: /* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
21: if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
22: _tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
23: }
24:
25: /* set the floating-point condition codes: */
26: ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
27: }
28:
29: /* if the most significant bit of the NaN fraction is zero,
30: this is a signaling NaN: */
31: #define _TME_SPARC_FPU_IS_SNAN_SINGLE(a) (((*(a)) & ((0x007f0000 | (0x007f0000 >> 1)) ^ (0x007f0000 >> 1))) != 0)
32: static tme_int8_t
33: _tme_sparc_fpu_is_snan_single(tme_uint32_t *value)
34: {
35: return (_TME_SPARC_FPU_IS_SNAN_SINGLE(value));
36: }
37:
38: /* single-precision NaN propagation: */
39: static void
40: _tme_sparc_fpu_nan_from_nans_single(struct tme_ieee754_ctl *ctl,
41: const tme_uint32_t *a,
42: const tme_uint32_t *b,
43: tme_uint32_t *z)
44: {
45: struct tme_sparc *ic;
46: int a_is_snan;
47: int b_is_snan;
48:
49: /* recover our data structure : */
50: ic = ctl->tme_ieee754_ctl_private;
51:
52: /* see if any of the NaNs are signaling NaNs: */
53: a_is_snan = _TME_SPARC_FPU_IS_SNAN_SINGLE(a);
54: b_is_snan = _TME_SPARC_FPU_IS_SNAN_SINGLE(b);
55:
56: /* if either operand is a signaling NaN: */
57: if (a_is_snan || b_is_snan) {
58:
59: /* signal the signaling NaN: */
60: _tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
61: }
62:
63: /* if and only if a (corresponding to f[rs1]) is a signaling NaN, do
64: we return a. at all other times we return b (corresponding to f[rs2]): */
65: if (a_is_snan) {
66: b = a;
67: }
68:
69: /* return the NaN, but make sure it's nonsignaling: */
70: *z = *b;
71: (*(z)) |= ((0x007f0000 | (0x007f0000 >> 1)) ^ (0x007f0000 >> 1));
72: }
73:
74:
75: /* this sets the floating-point condition codes after a
76: double-precision operation: */
77: static void inline
78: _tme_sparc_fpu_fcc_double(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
79: {
80: tme_uint32_t fcc;
81:
82: /* set fcc: */
83: fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
84: ? TME_SPARC_FSR_FCC_UN
85: : tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
86: ? TME_SPARC_FSR_FCC_EQ
87: : tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
88: ? TME_SPARC_FSR_FCC_LT
89: : TME_SPARC_FSR_FCC_GT);
90:
91: /* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
92: if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
93: _tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
94: }
95:
96: /* set the floating-point condition codes: */
97: ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
98: }
99:
100: /* if the most significant bit of the NaN fraction is zero,
101: this is a signaling NaN: */
102: #define _TME_SPARC_FPU_IS_SNAN_DOUBLE(a) (((*(a)).tme_value64_uint32_hi & ((0x000f0000 | (0x000f0000 >> 1)) ^ (0x000f0000 >> 1))) != 0)
103: static tme_int8_t
104: _tme_sparc_fpu_is_snan_double(union tme_value64 *value)
105: {
106: return (_TME_SPARC_FPU_IS_SNAN_DOUBLE(value));
107: }
108:
109: /* double-precision NaN propagation: */
110: static void
111: _tme_sparc_fpu_nan_from_nans_double(struct tme_ieee754_ctl *ctl,
112: const union tme_value64 *a,
113: const union tme_value64 *b,
114: union tme_value64 *z)
115: {
116: struct tme_sparc *ic;
117: int a_is_snan;
118: int b_is_snan;
119:
120: /* recover our data structure : */
121: ic = ctl->tme_ieee754_ctl_private;
122:
123: /* see if any of the NaNs are signaling NaNs: */
124: a_is_snan = _TME_SPARC_FPU_IS_SNAN_DOUBLE(a);
125: b_is_snan = _TME_SPARC_FPU_IS_SNAN_DOUBLE(b);
126:
127: /* if either operand is a signaling NaN: */
128: if (a_is_snan || b_is_snan) {
129:
130: /* signal the signaling NaN: */
131: _tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
132: }
133:
134: /* if and only if a (corresponding to f[rs1]) is a signaling NaN, do
135: we return a. at all other times we return b (corresponding to f[rs2]): */
136: if (a_is_snan) {
137: b = a;
138: }
139:
140: /* return the NaN, but make sure it's nonsignaling: */
141: *z = *b;
142: (*(z)).tme_value64_uint32_hi |= ((0x000f0000 | (0x000f0000 >> 1)) ^ (0x000f0000 >> 1));
143: }
144:
145:
146: /* this sets the floating-point condition codes after a
147: quad-precision operation: */
148: static void inline
149: _tme_sparc_fpu_fcc_quad(struct tme_sparc *ic, const struct tme_float *dst, int trap_on_nan)
150: {
151: tme_uint32_t fcc;
152:
153: /* set fcc: */
154: fcc = (tme_float_is_nan(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
155: ? TME_SPARC_FSR_FCC_UN
156: : tme_float_is_zero(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
157: ? TME_SPARC_FSR_FCC_EQ
158: : tme_float_is_negative(dst, (TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
159: ? TME_SPARC_FSR_FCC_LT
160: : TME_SPARC_FSR_FCC_GT);
161:
162: /* if this is an FCMPE and this is a NaN, we always cause an invalid exception: */
163: if (trap_on_nan && fcc == TME_SPARC_FSR_FCC_UN) {
164: _tme_sparc_fpu_exception_ieee754(&ic->tme_sparc_fpu_ieee754_ctl, TME_FLOAT_EXCEPTION_INVALID);
165: }
166:
167: /* set the floating-point condition codes: */
168: ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & ~TME_SPARC_FSR_FCC) | fcc;
169: }
170:
171: /* if the most significant bit of the NaN fraction is zero,
172: this is a signaling NaN: */
173: #define _TME_SPARC_FPU_IS_SNAN_QUAD(a) (((*(a)).tme_float_ieee754_quad_hi.tme_value64_uint32_hi & ((0x0000ffff | (0x0000ffff >> 1)) ^ (0x0000ffff >> 1))) != 0)
174: static tme_int8_t
175: _tme_sparc_fpu_is_snan_quad(struct tme_float_ieee754_quad *value)
176: {
177: return (_TME_SPARC_FPU_IS_SNAN_QUAD(value));
178: }
179:
180: /* quad-precision NaN propagation: */
181: static void
182: _tme_sparc_fpu_nan_from_nans_quad(struct tme_ieee754_ctl *ctl,
183: const struct tme_float_ieee754_quad *a,
184: const struct tme_float_ieee754_quad *b,
185: struct tme_float_ieee754_quad *z)
186: {
187: struct tme_sparc *ic;
188: int a_is_snan;
189: int b_is_snan;
190:
191: /* recover our data structure : */
192: ic = ctl->tme_ieee754_ctl_private;
193:
194: /* see if any of the NaNs are signaling NaNs: */
195: a_is_snan = _TME_SPARC_FPU_IS_SNAN_QUAD(a);
196: b_is_snan = _TME_SPARC_FPU_IS_SNAN_QUAD(b);
197:
198: /* if either operand is a signaling NaN: */
199: if (a_is_snan || b_is_snan) {
200:
201: /* signal the signaling NaN: */
202: _tme_sparc_fpu_exception_ieee754(ctl, TME_FLOAT_EXCEPTION_INVALID);
203: }
204:
205: /* if and only if a (corresponding to f[rs1]) is a signaling NaN, do
206: we return a. at all other times we return b (corresponding to f[rs2]): */
207: if (a_is_snan) {
208: b = a;
209: }
210:
211: /* return the NaN, but make sure it's nonsignaling: */
212: *z = *b;
213: (*(z)).tme_float_ieee754_quad_hi.tme_value64_uint32_hi |= ((0x0000ffff | (0x0000ffff >> 1)) ^ (0x0000ffff >> 1));
214: }
215:
216: #define _TME_SPARC_FPU_UNIMPL tme_sparc_fpu_exception(ic, TME_SPARC_FSR_FTT_unimplemented_FPop)
217: #define _TME_SPARC_FPU_UNIMPL_IF(flags) do { if ((ic->tme_sparc_fpu_flags & (flags)) != 0) { _TME_SPARC_FPU_UNIMPL; } } while (/* CONSTCOND */ 0)
218:
219: void
220: tme_sparc_fpu_fpop1(struct tme_sparc *ic)
221: {
222: tme_uint8_t rounding_mode;
223: unsigned int opf;
224: unsigned int fpreg_rd_number;
225: const struct tme_float *fpreg_rs1;
226: const struct tme_float *fpreg_rs2;
227: struct tme_float fpreg_rs1_buffer;
228: struct tme_float fpreg_rs2_buffer;
229: struct tme_float fpreg_rd;
230: unsigned int fpreg_rd_format;
231:
232: /* set the rounding mode: */
233: switch (ic->tme_sparc_fpu_fsr & TME_SPARC_FSR_RND) {
234: default: assert(FALSE);
235: case TME_SPARC_FSR_RND_RN: rounding_mode = TME_FLOAT_ROUND_NEAREST_EVEN; break;
236: case TME_SPARC_FSR_RND_RZ: rounding_mode = TME_FLOAT_ROUND_TO_ZERO; break;
237: case TME_SPARC_FSR_RND_RM: rounding_mode = TME_FLOAT_ROUND_DOWN; break;
238: case TME_SPARC_FSR_RND_RP: rounding_mode = TME_FLOAT_ROUND_UP; break;
239: }
240: ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = rounding_mode;
241:
242: /* decode the rd and opf fields: */
243: fpreg_rd_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
244: opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
245:
246: /* dispatch on the opf field: */
247: switch (opf) {
248: #define _TME_SPARC_FPU_FORMAT_RS1(format) fpreg_rs1 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS1, (format))
249: #define _TME_SPARC_FPU_FORMAT_RS2(format) fpreg_rs2 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS2, (format))
250: #define _TME_SPARC_FPU_FORMAT_RD(format) do { fpreg_rd_format = (format) | TME_IEEE754_FPREG_FORMAT_BUILTIN; tme_sparc_fpu_fpreg_aligned(ic, fpreg_rd_number, fpreg_rd_format); } while (/* CONSTCOND */ 0)
251:
252: case 1: /* 000000001 FMOVs: */
253: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
254: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
255: _TME_SPARC_FPU_BEGIN;
256: fpreg_rd = *fpreg_rs2;
257: break;
258:
259: case 5: /* 000000101 FNEGs: */
260: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
261: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
262: _TME_SPARC_FPU_BEGIN;
263: fpreg_rd = *fpreg_rs2;
264: fpreg_rd.tme_float_value_ieee754_single ^= 0x80000000;
265: break;
266:
267: case 9: /* 000001001 FABSs: */
268: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
269: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
270: _TME_SPARC_FPU_BEGIN;
271: fpreg_rd = *fpreg_rs2;
272: fpreg_rd.tme_float_value_ieee754_single &= ~0x80000000;
273: break;
274:
275: case 41: /* 000101001 FSQRTs: */
276: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT);
277: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
278: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
279: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_sqrt,
280: fpreg_rs2, &fpreg_rd);
281: break;
282:
283: case 42: /* 000101010 FSQRTd: */
284: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT);
285: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
286: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
287: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_sqrt,
288: fpreg_rs2, &fpreg_rd);
289: break;
290:
291: case 43: /* 000101011 FSQRTq: */
292: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FSQRT | TME_SPARC_FPU_FLAG_NO_QUAD);
293: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
294: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
295: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_sqrt,
296: fpreg_rs2, &fpreg_rd);
297: break;
298:
299: case 65: /* 001000001 FADDs: */
300: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
301: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
302: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
303: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_add,
304: fpreg_rs1, fpreg_rs2, &fpreg_rd);
305: break;
306:
307: case 66: /* 001000010 FADDd: */
308: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
309: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
310: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
311: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_add,
312: fpreg_rs1, fpreg_rs2, &fpreg_rd);
313: break;
314:
315: case 67: /* 001000011 FADDq: */
316: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
317: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
318: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
319: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
320: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_add,
321: fpreg_rs1, fpreg_rs2, &fpreg_rd);
322: break;
323:
324: case 69: /* 001000101 FSUBs: */
325: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
326: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
327: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
328: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
329: fpreg_rs1, fpreg_rs2, &fpreg_rd);
330: break;
331:
332: case 70: /* 001000110 FSUBd: */
333: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
334: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
335: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
336: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
337: fpreg_rs1, fpreg_rs2, &fpreg_rd);
338: break;
339:
340: case 71: /* 001000111 FSUBq: */
341: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
342: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
343: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
344: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
345: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
346: fpreg_rs1, fpreg_rs2, &fpreg_rd);
347: break;
348:
349: case 73: /* 001001001 FMULs: */
350: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
351: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
352: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
353: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_mul,
354: fpreg_rs1, fpreg_rs2, &fpreg_rd);
355: break;
356:
357: case 74: /* 001001010 FMULd: */
358: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
359: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
360: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
361: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_mul,
362: fpreg_rs1, fpreg_rs2, &fpreg_rd);
363: break;
364:
365: case 75: /* 001001011 FMULq: */
366: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
367: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
368: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
369: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
370: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_mul,
371: fpreg_rs1, fpreg_rs2, &fpreg_rd);
372: break;
373:
374: case 77: /* 001001101 FDIVs: */
375: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
376: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
377: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
378: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_div,
379: fpreg_rs1, fpreg_rs2, &fpreg_rd);
380: break;
381:
382: case 78: /* 001001110 FDIVd: */
383: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
384: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
385: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
386: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_div,
387: fpreg_rs1, fpreg_rs2, &fpreg_rd);
388: break;
389:
390: case 79: /* 001001111 FDIVq: */
391: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
392: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
393: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
394: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
395: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_div,
396: fpreg_rs1, fpreg_rs2, &fpreg_rd);
397: break;
398:
399: case 105: /* 001101001 FsMULd: */
400: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FMUL_WIDER);
401: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
402: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
403: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
404: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
405: fpreg_rs1, &fpreg_rs1_buffer);
406: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
407: fpreg_rs2, &fpreg_rs2_buffer);
408: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_mul,
409: &fpreg_rs1_buffer, &fpreg_rs2_buffer, &fpreg_rd);
410: break;
411:
412: case 110: /* 001101110 FdMULq: */
413: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_FMUL_WIDER | TME_SPARC_FPU_FLAG_NO_QUAD);
414: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
415: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
416: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
417: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
418: fpreg_rs1, &fpreg_rs1_buffer);
419: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
420: fpreg_rs2, &fpreg_rs2_buffer);
421: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_mul,
422: &fpreg_rs1_buffer, &fpreg_rs2_buffer, &fpreg_rd);
423: break;
424:
425: case 196: /* 011000100 FiTOs: */
426: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
427: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
428: _TME_SPARC_FPU_BEGIN;
429: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_int32,
430: fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
431: break;
432:
433: case 198: /* 011000110 FdTOs: */
434: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
435: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
436: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_double,
437: fpreg_rs2, &fpreg_rd);
438: break;
439:
440: case 199: /* 011000111 FqTOs: */
441: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
442: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
443: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
444: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_from_quad,
445: fpreg_rs2, &fpreg_rd);
446: break;
447:
448: case 200: /* 011001000 FiTOd: */
449: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
450: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
451: _TME_SPARC_FPU_BEGIN;
452: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_int32,
453: fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
454: break;
455:
456: case 201: /* 011001001 FsTOd: */
457: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
458: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
459: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_single,
460: fpreg_rs2, &fpreg_rd);
461: break;
462:
463: case 203: /* 011001011 FqTOd: */
464: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
465: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
466: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
467: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_from_quad,
468: fpreg_rs2, &fpreg_rd);
469: break;
470:
471: case 204: /* 011001100 FiTOq: */
472: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
473: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
474: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
475: _TME_SPARC_FPU_BEGIN;
476: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_int32,
477: fpreg_rs2->tme_float_value_ieee754_single, &fpreg_rd);
478: break;
479:
480: case 205: /* 011001101 FsTOq: */
481: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
482: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
483: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
484: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_single,
485: fpreg_rs2, &fpreg_rd);
486: break;
487:
488: case 206: /* 011001110 FdTOq: */
489: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
490: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_QUAD);
491: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_from_double,
492: fpreg_rs2, &fpreg_rd);
493: break;
494:
495: case 209: /* 011010001 FsTOi: */
496: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
497: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
498: _TME_SPARC_FPU_BEGIN;
499: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
500: ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
501: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_single_to_int32,
502: fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
503: break;
504:
505: case 210: /* 011010010 FdTOi: */
506: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
507: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
508: _TME_SPARC_FPU_BEGIN;
509: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
510: ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
511: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_double_to_int32,
512: fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
513: break;
514:
515: case 211: /* 011010011 FqTOi: */
516: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
517: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
518: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
519: _TME_SPARC_FPU_BEGIN;
520: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
521: ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
522: _TME_SPARC_FPU_OP_MONADIC(tme_ieee754_ops_quad_to_int32,
523: fpreg_rs2, (tme_int32_t *) &fpreg_rd.tme_float_value_ieee754_single);
524: break;
525:
526: default: _TME_SPARC_FPU_UNIMPL; fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL; break;
527:
528: #undef _TME_SPARC_FPU_FORMAT_RS1
529: #undef _TME_SPARC_FPU_FORMAT_RS2
530: #undef _TME_SPARC_FPU_FORMAT_RD
531: }
532:
533: /* store any destination: */
534: if (fpreg_rd_format != TME_IEEE754_FPREG_FORMAT_NULL) {
535: tme_sparc_fpu_fpreg_format(ic, fpreg_rd_number, fpreg_rd_format);
536: ic->tme_sparc_fpu_fpregs[fpreg_rd_number] = fpreg_rd;
537: }
538:
539: }
540:
541: void
542: tme_sparc_fpu_fpop2(struct tme_sparc *ic)
543: {
544: tme_uint8_t rounding_mode;
545: unsigned int opf;
546: unsigned int fpreg_rd_number;
547: const struct tme_float *fpreg_rs1;
548: const struct tme_float *fpreg_rs2;
549: struct tme_float fpreg_rd;
550: unsigned int fpreg_rd_format;
551:
552: /* set the rounding mode: */
553: switch (ic->tme_sparc_fpu_fsr & TME_SPARC_FSR_RND) {
554: default: assert(FALSE);
555: case TME_SPARC_FSR_RND_RN: rounding_mode = TME_FLOAT_ROUND_NEAREST_EVEN; break;
556: case TME_SPARC_FSR_RND_RZ: rounding_mode = TME_FLOAT_ROUND_TO_ZERO; break;
557: case TME_SPARC_FSR_RND_RM: rounding_mode = TME_FLOAT_ROUND_DOWN; break;
558: case TME_SPARC_FSR_RND_RP: rounding_mode = TME_FLOAT_ROUND_UP; break;
559: }
560: ic->tme_sparc_fpu_ieee754_ctl.tme_ieee754_ctl_rounding_mode = rounding_mode;
561:
562: /* decode the rd and opf fields: */
563: fpreg_rd_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
564: opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
565:
566: /* dispatch on the opf field: */
567: switch (opf) {
568: #define _TME_SPARC_FPU_FORMAT_RS1(format) fpreg_rs1 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS1, (format))
569: #define _TME_SPARC_FPU_FORMAT_RS2(format) fpreg_rs2 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS2, (format))
570: #define _TME_SPARC_FPU_FORMAT_RD(format) do { fpreg_rd_format = (format) | TME_IEEE754_FPREG_FORMAT_BUILTIN; tme_sparc_fpu_fpreg_aligned(ic, fpreg_rd_number, fpreg_rd_format); } while (/* CONSTCOND */ 0)
571:
572: case 81: /* 001010001 FCMPs: */
573: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
574: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
575: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
576: fpreg_rs1, fpreg_rs2, &fpreg_rd);
577: _tme_sparc_fpu_fcc_single(ic, &fpreg_rd, FALSE);
578: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
579: break;
580:
581: case 82: /* 001010010 FCMPd: */
582: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
583: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
584: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
585: fpreg_rs1, fpreg_rs2, &fpreg_rd);
586: _tme_sparc_fpu_fcc_double(ic, &fpreg_rd, FALSE);
587: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
588: break;
589:
590: case 83: /* 001010011 FCMPq: */
591: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
592: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
593: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
594: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
595: fpreg_rs1, fpreg_rs2, &fpreg_rd);
596: _tme_sparc_fpu_fcc_quad(ic, &fpreg_rd, FALSE);
597: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
598: break;
599:
600: case 85: /* 001010101 FCMPEs: */
601: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
602: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
603: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_single_sub,
604: fpreg_rs1, fpreg_rs2, &fpreg_rd);
605: _tme_sparc_fpu_fcc_single(ic, &fpreg_rd, TRUE);
606: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
607: break;
608:
609: case 86: /* 001010110 FCMPEd: */
610: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
611: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
612: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_double_sub,
613: fpreg_rs1, fpreg_rs2, &fpreg_rd);
614: _tme_sparc_fpu_fcc_double(ic, &fpreg_rd, TRUE);
615: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
616: break;
617:
618: case 87: /* 001010111 FCMPEq: */
619: _TME_SPARC_FPU_UNIMPL_IF(TME_SPARC_FPU_FLAG_NO_QUAD);
620: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
621: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_QUAD | TME_IEEE754_FPREG_FORMAT_BUILTIN);
622: _TME_SPARC_FPU_OP_DYADIC(tme_ieee754_ops_quad_sub,
623: fpreg_rs1, fpreg_rs2, &fpreg_rd);
624: _tme_sparc_fpu_fcc_quad(ic, &fpreg_rd, TRUE);
625: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
626: break;
627:
628: default: _TME_SPARC_FPU_UNIMPL; fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL; break;
629:
630: #undef _TME_SPARC_FPU_FORMAT_RS1
631: #undef _TME_SPARC_FPU_FORMAT_RS2
632: #undef _TME_SPARC_FPU_FORMAT_RD
633: }
634:
635: /* store any destination: */
636: if (fpreg_rd_format != TME_IEEE754_FPREG_FORMAT_NULL) {
637: tme_sparc_fpu_fpreg_format(ic, fpreg_rd_number, fpreg_rd_format);
638: ic->tme_sparc_fpu_fpregs[fpreg_rd_number] = fpreg_rd;
639: }
640:
641: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.