|
|
1.1 root 1: /* automatically generated by sparc-vis-auto.sh, do not edit! */
2: _TME_RCSID("$Id: sparc-vis-auto.sh,v 1.4 2010/02/20 22:01:40 fredette Exp $");
3:
4: /* this handles VIS instructions: */
5: void
6: tme_sparc_vis(struct tme_sparc *ic)
7: {
8: unsigned int opf;
9: unsigned int fpreg_rd_number_encoded;
10: const struct tme_float *fpreg_rs1;
11: const struct tme_float *fpreg_rs2;
12: unsigned int fpreg_rd_format;
13: unsigned int fpreg_rd_number;
14: struct tme_float fpreg_rd;
15: tme_uint64_t value_fpreg_rs1;
16: tme_uint64_t value_fpreg_rs2;
17: unsigned int compare_result;
18: unsigned int reg_rd;
19: unsigned int alignaddr_off;
20:
21: TME_SPARC_INSN_FPU;
22:
23: /* extract the opf field: */
24: opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
25:
26: /* extract the encoded rd: */
27: fpreg_rd_number_encoded = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
28:
29: #ifdef _TME_SPARC_RECODE_VERIFY
30: /* clear the rd buffer: */
31: memset(&fpreg_rd, 0, sizeof(fpreg_rd));
32: #endif /* _TME_SPARC_RECODE_VERIFY */
33:
34: /* dispatch on the opf field: */
35: switch (opf) {
36: #define _TME_SPARC_FPU_FORMAT_RS1(format) fpreg_rs1 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS1, (format))
37: #define _TME_SPARC_FPU_FORMAT_RS2(format) fpreg_rs2 = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RS2, (format))
38: #define _TME_SPARC_FPU_FORMAT_RD(format) do { fpreg_rd_format = (format) | TME_IEEE754_FPREG_FORMAT_BUILTIN; fpreg_rd_number = tme_sparc_fpu_fpreg_decode(ic, fpreg_rd_number_encoded, fpreg_rd_format); } while (/* CONSTCOND */ 0)
39:
40: case 32: /* 000100000 FCMPLE16: */
41: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
42: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
43: value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
44: value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
45: compare_result = 0;
46: if (((tme_uint16_t) value_fpreg_rs1)
47: <= (tme_uint16_t) value_fpreg_rs2) {
48: compare_result += (1 << (0 / 16));
49: }
50: value_fpreg_rs1 >>= 16;
51: value_fpreg_rs2 >>= 16;
52: if (((tme_uint16_t) value_fpreg_rs1)
53: <= (tme_uint16_t) value_fpreg_rs2) {
54: compare_result += (1 << (16 / 16));
55: }
56: value_fpreg_rs1 >>= 16;
57: value_fpreg_rs2 >>= 16;
58: if (((tme_uint16_t) value_fpreg_rs1)
59: <= (tme_uint16_t) value_fpreg_rs2) {
60: compare_result += (1 << (32 / 16));
61: }
62: value_fpreg_rs1 >>= 16;
63: value_fpreg_rs2 >>= 16;
64: if (((tme_uint16_t) value_fpreg_rs1)
65: <= (tme_uint16_t) value_fpreg_rs2) {
66: compare_result += (1 << (48 / 16));
67: }
68: value_fpreg_rs1 >>= 16;
69: value_fpreg_rs2 >>= 16;
70: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
71: TME_SPARC_REG_INDEX(ic, reg_rd);
72: ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
73: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
74: fpreg_rd_number = 0;
75: break;
76:
77: case 34: /* 000100010 FCMPNE16: */
78: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
79: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
80: value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
81: value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
82: compare_result = 0;
83: if (((tme_uint16_t) value_fpreg_rs1)
84: != (tme_uint16_t) value_fpreg_rs2) {
85: compare_result += (1 << (0 / 16));
86: }
87: value_fpreg_rs1 >>= 16;
88: value_fpreg_rs2 >>= 16;
89: if (((tme_uint16_t) value_fpreg_rs1)
90: != (tme_uint16_t) value_fpreg_rs2) {
91: compare_result += (1 << (16 / 16));
92: }
93: value_fpreg_rs1 >>= 16;
94: value_fpreg_rs2 >>= 16;
95: if (((tme_uint16_t) value_fpreg_rs1)
96: != (tme_uint16_t) value_fpreg_rs2) {
97: compare_result += (1 << (32 / 16));
98: }
99: value_fpreg_rs1 >>= 16;
100: value_fpreg_rs2 >>= 16;
101: if (((tme_uint16_t) value_fpreg_rs1)
102: != (tme_uint16_t) value_fpreg_rs2) {
103: compare_result += (1 << (48 / 16));
104: }
105: value_fpreg_rs1 >>= 16;
106: value_fpreg_rs2 >>= 16;
107: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
108: TME_SPARC_REG_INDEX(ic, reg_rd);
109: ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
110: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
111: fpreg_rd_number = 0;
112: break;
113:
114: case 36: /* 000100100 FCMPLE32: */
115: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
116: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
117: value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
118: value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
119: compare_result = 0;
120: if (((tme_uint32_t) value_fpreg_rs1)
121: <= (tme_uint32_t) value_fpreg_rs2) {
122: compare_result += (1 << (0 / 32));
123: }
124: value_fpreg_rs1 >>= 32;
125: value_fpreg_rs2 >>= 32;
126: if (((tme_uint32_t) value_fpreg_rs1)
127: <= (tme_uint32_t) value_fpreg_rs2) {
128: compare_result += (1 << (32 / 32));
129: }
130: value_fpreg_rs1 >>= 32;
131: value_fpreg_rs2 >>= 32;
132: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
133: TME_SPARC_REG_INDEX(ic, reg_rd);
134: ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
135: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
136: fpreg_rd_number = 0;
137: break;
138:
139: case 38: /* 000100110 FCMPNE32: */
140: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
141: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
142: value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
143: value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
144: compare_result = 0;
145: if (((tme_uint32_t) value_fpreg_rs1)
146: != (tme_uint32_t) value_fpreg_rs2) {
147: compare_result += (1 << (0 / 32));
148: }
149: value_fpreg_rs1 >>= 32;
150: value_fpreg_rs2 >>= 32;
151: if (((tme_uint32_t) value_fpreg_rs1)
152: != (tme_uint32_t) value_fpreg_rs2) {
153: compare_result += (1 << (32 / 32));
154: }
155: value_fpreg_rs1 >>= 32;
156: value_fpreg_rs2 >>= 32;
157: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
158: TME_SPARC_REG_INDEX(ic, reg_rd);
159: ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
160: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
161: fpreg_rd_number = 0;
162: break;
163:
164: case 40: /* 000101000 FCMPGT16: */
165: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
166: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
167: value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
168: value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
169: compare_result = 0;
170: if (((tme_uint16_t) value_fpreg_rs1)
171: > (tme_uint16_t) value_fpreg_rs2) {
172: compare_result += (1 << (0 / 16));
173: }
174: value_fpreg_rs1 >>= 16;
175: value_fpreg_rs2 >>= 16;
176: if (((tme_uint16_t) value_fpreg_rs1)
177: > (tme_uint16_t) value_fpreg_rs2) {
178: compare_result += (1 << (16 / 16));
179: }
180: value_fpreg_rs1 >>= 16;
181: value_fpreg_rs2 >>= 16;
182: if (((tme_uint16_t) value_fpreg_rs1)
183: > (tme_uint16_t) value_fpreg_rs2) {
184: compare_result += (1 << (32 / 16));
185: }
186: value_fpreg_rs1 >>= 16;
187: value_fpreg_rs2 >>= 16;
188: if (((tme_uint16_t) value_fpreg_rs1)
189: > (tme_uint16_t) value_fpreg_rs2) {
190: compare_result += (1 << (48 / 16));
191: }
192: value_fpreg_rs1 >>= 16;
193: value_fpreg_rs2 >>= 16;
194: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
195: TME_SPARC_REG_INDEX(ic, reg_rd);
196: ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
197: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
198: fpreg_rd_number = 0;
199: break;
200:
201: case 42: /* 000101010 FCMPEQ16: */
202: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
203: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
204: value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
205: value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
206: compare_result = 0;
207: if (((tme_uint16_t) value_fpreg_rs1)
208: == (tme_uint16_t) value_fpreg_rs2) {
209: compare_result += (1 << (0 / 16));
210: }
211: value_fpreg_rs1 >>= 16;
212: value_fpreg_rs2 >>= 16;
213: if (((tme_uint16_t) value_fpreg_rs1)
214: == (tme_uint16_t) value_fpreg_rs2) {
215: compare_result += (1 << (16 / 16));
216: }
217: value_fpreg_rs1 >>= 16;
218: value_fpreg_rs2 >>= 16;
219: if (((tme_uint16_t) value_fpreg_rs1)
220: == (tme_uint16_t) value_fpreg_rs2) {
221: compare_result += (1 << (32 / 16));
222: }
223: value_fpreg_rs1 >>= 16;
224: value_fpreg_rs2 >>= 16;
225: if (((tme_uint16_t) value_fpreg_rs1)
226: == (tme_uint16_t) value_fpreg_rs2) {
227: compare_result += (1 << (48 / 16));
228: }
229: value_fpreg_rs1 >>= 16;
230: value_fpreg_rs2 >>= 16;
231: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
232: TME_SPARC_REG_INDEX(ic, reg_rd);
233: ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
234: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
235: fpreg_rd_number = 0;
236: break;
237:
238: case 44: /* 000101100 FCMPGT32: */
239: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
240: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
241: value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
242: value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
243: compare_result = 0;
244: if (((tme_uint32_t) value_fpreg_rs1)
245: > (tme_uint32_t) value_fpreg_rs2) {
246: compare_result += (1 << (0 / 32));
247: }
248: value_fpreg_rs1 >>= 32;
249: value_fpreg_rs2 >>= 32;
250: if (((tme_uint32_t) value_fpreg_rs1)
251: > (tme_uint32_t) value_fpreg_rs2) {
252: compare_result += (1 << (32 / 32));
253: }
254: value_fpreg_rs1 >>= 32;
255: value_fpreg_rs2 >>= 32;
256: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
257: TME_SPARC_REG_INDEX(ic, reg_rd);
258: ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
259: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
260: fpreg_rd_number = 0;
261: break;
262:
263: case 46: /* 000101110 FCMPEQ32: */
264: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
265: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
266: value_fpreg_rs1 = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
267: value_fpreg_rs2 = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
268: compare_result = 0;
269: if (((tme_uint32_t) value_fpreg_rs1)
270: == (tme_uint32_t) value_fpreg_rs2) {
271: compare_result += (1 << (0 / 32));
272: }
273: value_fpreg_rs1 >>= 32;
274: value_fpreg_rs2 >>= 32;
275: if (((tme_uint32_t) value_fpreg_rs1)
276: == (tme_uint32_t) value_fpreg_rs2) {
277: compare_result += (1 << (32 / 32));
278: }
279: value_fpreg_rs1 >>= 32;
280: value_fpreg_rs2 >>= 32;
281: reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
282: TME_SPARC_REG_INDEX(ic, reg_rd);
283: ic->tme_sparc_ireg_uint64(reg_rd) = compare_result;
284: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
285: fpreg_rd_number = 0;
286: break;
287:
288: case 72: /* 001001000 FALIGNDATA: */
289: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
290: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
291: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
292: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
293: fpreg_rd.tme_float_value_ieee754_double = fpreg_rs1->tme_float_value_ieee754_double;
294: alignaddr_off = TME_FIELD_MASK_EXTRACTU(ic->tme_sparc_vis_gsr, TME_SPARC_VIS_GSR_ALIGNADDR_OFF);
295: if (alignaddr_off) {
296: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint
297: = ((fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint
298: << (8 * alignaddr_off))
299: + (fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint
300: >> (64 - (8 * alignaddr_off))));
301: }
302: break;
303:
304: case 96: /* 001100000 (0000) FZERO: */
305: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
306: _TME_SPARC_FPU_BEGIN;
307: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
308: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = 0;
309: break;
310:
311: case 97: /* 001100001 (0000) FZEROS: */
312: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
313: _TME_SPARC_FPU_BEGIN;
314: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
315: fpreg_rd.tme_float_value_ieee754_single = 0;
316: break;
317:
318: case 98: /* 001100010 (0001) FNOR: */
319: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
320: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
321: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
322: _TME_SPARC_FPU_BEGIN;
323: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
324: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~(fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint | fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
325: break;
326:
327: case 99: /* 001100011 (0001) FNORS: */
328: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
329: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
330: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
331: _TME_SPARC_FPU_BEGIN;
332: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
333: fpreg_rd.tme_float_value_ieee754_single = ~(fpreg_rs1->tme_float_value_ieee754_single | fpreg_rs2->tme_float_value_ieee754_single);
334: break;
335:
336: case 100: /* 001100100 (0010) FANDNOT2: */
337: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
338: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
339: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
340: _TME_SPARC_FPU_BEGIN;
341: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
342: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint & ~fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
343: break;
344:
345: case 101: /* 001100101 (0010) FANDNOT2S: */
346: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
347: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
348: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
349: _TME_SPARC_FPU_BEGIN;
350: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
351: fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single & ~fpreg_rs2->tme_float_value_ieee754_single);
352: break;
353:
354: case 102: /* 001100110 (0011) FNOT2: */
355: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
356: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
357: _TME_SPARC_FPU_BEGIN;
358: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
359: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
360: break;
361:
362: case 103: /* 001100111 (0011) FNOT2S: */
363: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
364: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
365: _TME_SPARC_FPU_BEGIN;
366: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
367: fpreg_rd.tme_float_value_ieee754_single = ~fpreg_rs2->tme_float_value_ieee754_single;
368: break;
369:
370: case 104: /* 001101000 (0100) FANDNOT1: */
371: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
372: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
373: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
374: _TME_SPARC_FPU_BEGIN;
375: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
376: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint & ~fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint);
377: break;
378:
379: case 105: /* 001101001 (0100) FANDNOT1S: */
380: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
381: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
382: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
383: _TME_SPARC_FPU_BEGIN;
384: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
385: fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs2->tme_float_value_ieee754_single & ~fpreg_rs1->tme_float_value_ieee754_single);
386: break;
387:
388: case 106: /* 001101010 (0101) FNOT1: */
389: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
390: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
391: _TME_SPARC_FPU_BEGIN;
392: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
393: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
394: break;
395:
396: case 107: /* 001101011 (0101) FNOT1S: */
397: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
398: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
399: _TME_SPARC_FPU_BEGIN;
400: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
401: fpreg_rd.tme_float_value_ieee754_single = ~fpreg_rs1->tme_float_value_ieee754_single;
402: break;
403:
404: case 108: /* 001101100 (0110) FXOR: */
405: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
406: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
407: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
408: _TME_SPARC_FPU_BEGIN;
409: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
410: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint ^ fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
411: break;
412:
413: case 109: /* 001101101 (0110) FXORS: */
414: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
415: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
416: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
417: _TME_SPARC_FPU_BEGIN;
418: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
419: fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single ^ fpreg_rs2->tme_float_value_ieee754_single);
420: break;
421:
422: case 110: /* 001101110 (0111) FNAND: */
423: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
424: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
425: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
426: _TME_SPARC_FPU_BEGIN;
427: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
428: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~(fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint & fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
429: break;
430:
431: case 111: /* 001101111 (0111) FNANDS: */
432: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
433: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
434: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
435: _TME_SPARC_FPU_BEGIN;
436: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
437: fpreg_rd.tme_float_value_ieee754_single = ~(fpreg_rs1->tme_float_value_ieee754_single & fpreg_rs2->tme_float_value_ieee754_single);
438: break;
439:
440: case 112: /* 001110000 (1000) FAND: */
441: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
442: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
443: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
444: _TME_SPARC_FPU_BEGIN;
445: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
446: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint & fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
447: break;
448:
449: case 113: /* 001110001 (1000) FANDS: */
450: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
451: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
452: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
453: _TME_SPARC_FPU_BEGIN;
454: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
455: fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single & fpreg_rs2->tme_float_value_ieee754_single);
456: break;
457:
458: case 114: /* 001110010 (1001) FXNOR: */
459: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
460: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
461: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
462: _TME_SPARC_FPU_BEGIN;
463: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
464: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = ~(fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint ^ fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
465: break;
466:
467: case 115: /* 001110011 (1001) FXNORS: */
468: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
469: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
470: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
471: _TME_SPARC_FPU_BEGIN;
472: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
473: fpreg_rd.tme_float_value_ieee754_single = ~(fpreg_rs1->tme_float_value_ieee754_single ^ fpreg_rs2->tme_float_value_ieee754_single);
474: break;
475:
476: case 116: /* 001110100 (1010) FSRC1: */
477: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
478: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
479: _TME_SPARC_FPU_BEGIN;
480: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
481: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint;
482: break;
483:
484: case 117: /* 001110101 (1010) FSRC1S: */
485: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
486: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
487: _TME_SPARC_FPU_BEGIN;
488: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
489: fpreg_rd.tme_float_value_ieee754_single = fpreg_rs1->tme_float_value_ieee754_single;
490: break;
491:
492: case 118: /* 001110110 (1011) FORNOT2: */
493: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
494: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
495: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
496: _TME_SPARC_FPU_BEGIN;
497: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
498: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint | ~fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
499: break;
500:
501: case 119: /* 001110111 (1011) FORNOT2S: */
502: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
503: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
504: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
505: _TME_SPARC_FPU_BEGIN;
506: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
507: fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single | ~fpreg_rs2->tme_float_value_ieee754_single);
508: break;
509:
510: case 120: /* 001111000 (1100) FSRC2: */
511: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
512: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
513: _TME_SPARC_FPU_BEGIN;
514: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
515: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint;
516: break;
517:
518: case 121: /* 001111001 (1100) FSRC2S: */
519: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
520: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
521: _TME_SPARC_FPU_BEGIN;
522: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
523: fpreg_rd.tme_float_value_ieee754_single = fpreg_rs2->tme_float_value_ieee754_single;
524: break;
525:
526: case 122: /* 001111010 (1101) FORNOT1: */
527: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
528: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
529: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
530: _TME_SPARC_FPU_BEGIN;
531: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
532: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint | ~fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint);
533: break;
534:
535: case 123: /* 001111011 (1101) FORNOT1S: */
536: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
537: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
538: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
539: _TME_SPARC_FPU_BEGIN;
540: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
541: fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs2->tme_float_value_ieee754_single | ~fpreg_rs1->tme_float_value_ieee754_single);
542: break;
543:
544: case 124: /* 001111100 (1110) FOR: */
545: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_DOUBLE);
546: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_DOUBLE);
547: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
548: _TME_SPARC_FPU_BEGIN;
549: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
550: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (fpreg_rs1->tme_float_value_ieee754_double.tme_value64_uint | fpreg_rs2->tme_float_value_ieee754_double.tme_value64_uint);
551: break;
552:
553: case 125: /* 001111101 (1110) FORS: */
554: _TME_SPARC_FPU_FORMAT_RS1(TME_IEEE754_FPREG_FORMAT_SINGLE);
555: _TME_SPARC_FPU_FORMAT_RS2(TME_IEEE754_FPREG_FORMAT_SINGLE);
556: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
557: _TME_SPARC_FPU_BEGIN;
558: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
559: fpreg_rd.tme_float_value_ieee754_single = (fpreg_rs1->tme_float_value_ieee754_single | fpreg_rs2->tme_float_value_ieee754_single);
560: break;
561:
562: case 126: /* 001111110 (1111) FONE: */
563: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_DOUBLE);
564: _TME_SPARC_FPU_BEGIN;
565: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
566: fpreg_rd.tme_float_value_ieee754_double.tme_value64_uint = (0 - (tme_uint64_t) 1);
567: break;
568:
569: case 127: /* 001111111 (1111) FONES: */
570: _TME_SPARC_FPU_FORMAT_RD(TME_IEEE754_FPREG_FORMAT_SINGLE);
571: _TME_SPARC_FPU_BEGIN;
572: fpreg_rd.tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
573: fpreg_rd.tme_float_value_ieee754_single = (0 - (tme_uint32_t) 1);
574: break;
575:
576: default:
577: _TME_SPARC_FPU_UNIMPL;
578: fpreg_rd_format = TME_IEEE754_FPREG_FORMAT_NULL;
579: fpreg_rd_number = 0;
580: break;
581:
582: #undef _TME_SPARC_FPU_FORMAT_RS1
583: #undef _TME_SPARC_FPU_FORMAT_RS2
584: #undef _TME_SPARC_FPU_FORMAT_RD
585: }
586:
587: /* store any destination: */
588: if (fpreg_rd_format != TME_IEEE754_FPREG_FORMAT_NULL) {
589: tme_sparc_fpu_fpreg_format(ic, fpreg_rd_number, fpreg_rd_format);
590: ic->tme_sparc_fpu_fpregs[fpreg_rd_number] = fpreg_rd;
591: TME_SPARC_FPU_DIRTY(ic, fpreg_rd_number);
592: }
593:
594: }
595:
596: /* the sparc64 cycle handler for stdfa ASI_PST*: */
597: static void
598: _tme_sparc64_vis_ls_cycle_pstd(struct tme_sparc *ic, struct tme_sparc_ls *ls)
599: {
600: unsigned int reg_rs2;
601: tme_uint32_t mask_raw;
602: unsigned int asi;
603: tme_uint32_t mask_0_31;
604: tme_uint32_t mask_32_63;
605: tme_uint64_t mask;
606: const struct tme_float *fpreg_rd;
607: tme_uint64_t value_written;
608: const struct tme_sparc_tlb *tlb;
609: tme_uint64_t address;
610: tme_shared tme_uint8_t *emulator_off;
611: tme_shared tme_uint64_t *memory;
612: tme_uint64_t value_read;
613: tme_uint64_t value_cmp;
614:
615: /* decode rs2: */
616: reg_rs2 = TME_FIELD_MASK_EXTRACTU(ic->_tme_sparc_insn, TME_SPARC_FORMAT3_MASK_RS2);
617: TME_SPARC_REG_INDEX(ic, reg_rs2);
618:
619: /* get the raw mask: */
620: mask_raw = ic->tme_sparc_ireg_uint64(reg_rs2);
621:
622: /* get the ASI: */
623: asi
624: = (TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask)
625: & ~(TME_SPARC64_ASI_FLAG_SECONDARY
626: | TME_SPARC64_ASI_FLAG_LITTLE));
627:
628: /* assume that this is ASI_PST32*: */
629: mask_0_31 = 0 - (mask_raw & TME_BIT(0));
630: mask_raw >>= 1;
631: mask_32_63 = 0 - (mask_raw & TME_BIT(0));
632: mask_raw >>= 1;
633:
634: /* if this is ASI_PST16*: */
635: if (asi == TME_SPARC_VIS_ASI_PST16) {
636:
637: /* convert the ASI_PST32* mask into bits 0..31 of the ASI_PST16* mask: */
638: mask_0_31
639: = ((mask_0_31 & (((tme_uint32_t) 0xffff) << 0))
640: + (mask_32_63 & (((tme_uint32_t) 0xffff) << 16)));
641:
642: /* make bits 32..63 of the ASI_PST16* mask: */
643: mask_32_63
644: = (((0 - (mask_raw & TME_BIT(0))) & (((tme_uint32_t) 0xffff) << 0))
645: + ((0 - (mask_raw & TME_BIT(1))) & (((tme_uint32_t) 0xffff) << 16)));
646: }
647:
648: /* otherwise, if this is ASI_PST8*: */
649: else if (asi == TME_SPARC_VIS_ASI_PST8) {
650:
651: /* convert the ASI_PST32* mask into bits 0..15 of the ASI_PST8*
652: mask, and make bits 16..31: */
653: mask_0_31
654: = ((mask_0_31 & (((tme_uint32_t) 0xff) << 0))
655: + (mask_32_63 & (((tme_uint32_t) 0xff) << 8))
656: + ((0 - (mask_raw & TME_BIT(0))) & (((tme_uint32_t) 0xff) << 16))
657: + ((0 - (mask_raw & TME_BIT(1))) & (((tme_uint32_t) 0xff) << 24)));
658:
659: /* make bits 32..63 of the ASI_PST8* mask: */
660: mask_raw >>= 2;
661: mask_32_63
662: = (((0 - (mask_raw & TME_BIT(0))) & (((tme_uint32_t) 0xff) << 0))
663: + ((0 - (mask_raw & TME_BIT(1))) & (((tme_uint32_t) 0xff) << 8))
664: + ((0 - (mask_raw & TME_BIT(2))) & (((tme_uint32_t) 0xff) << 16))
665: + ((0 - (mask_raw & TME_BIT(3))) & (((tme_uint32_t) 0xff) << 24)));
666: }
667:
668: /* make the full mask: */
669: mask = 0;
670: mask |= (((tme_uint64_t) mask_32_63) << 32);
671: mask |= mask_0_31;
672:
673: /* get the value to store from the double-precision fp register: */
674: fpreg_rd = tme_sparc_fpu_fpreg_read(ic, TME_SPARC_FORMAT3_MASK_RD, TME_IEEE754_FPREG_FORMAT_DOUBLE);
675: value_written = fpreg_rd->tme_float_value_ieee754_double.tme_value64_uint;
676:
677: /* get the TLB entry: */
678: tlb = ls->tme_sparc_ls_tlb;
679:
680: /* swap the mask and the value to store: */
681: if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_ENDIAN_LITTLE) {
682: value_written = tme_htole_u64(value_written);
683: mask = tme_htole_u64(mask);
684: }
685: else {
686: value_written = tme_htobe_u64(value_written);
687: mask = tme_htobe_u64(mask);
688: }
689:
690: /* get the current address: */
691: address = ls->tme_sparc_ls_address64;
692:
693: /* if this is the first transfer, and the TLB entry allows fast
694: transfer of all of the addresses: */
695: emulator_off = tlb->tme_sparc_tlb_emulator_off_write;
696: if (__tme_predict_true(ls->tme_sparc_ls_state == 0
697: && ((tme_bus_addr64_t) tlb->tme_sparc_tlb_addr_last) >= (address + sizeof(tme_uint64_t) - 1)
698: && emulator_off != TME_EMULATOR_OFF_UNDEF
699: && emulator_off == tlb->tme_sparc_tlb_emulator_off_read)) {
700:
701: /* make the pointer to the memory to store: */
702: memory = (tme_shared tme_uint64_t *) (emulator_off + address);
703:
704: /* loop until we can do the atomic partial store: */
705: value_read = tme_memory_bus_read64(memory,
706: tlb->tme_sparc_tlb_bus_rwlock,
707: sizeof(tme_uint64_t),
708: sizeof(tme_uint64_t));
709: do {
710:
711: /* make the value to write: */
712: value_written
713: = ((value_written & mask)
714: + (value_read & ~mask));
715:
716: /* try an atomic compare-and-exchange: */
717: value_cmp = value_read;
718: value_read
719: = tme_memory_atomic_cx64(memory,
720: value_cmp,
721: value_written,
722: tlb->tme_sparc_tlb_bus_rwlock,
723: sizeof(tme_uint64_t));
724:
725: /* loop while the atomic compare-and-exchange failed: */
726: } while (value_read != value_cmp);
727:
728: /* we finished this transfer: */
729: ls->tme_sparc_ls_size = 0;
730: return;
731: }
732:
733: /* otherwise, we have to do a slow transfer: */
734: ls->tme_sparc_ls_buffer_offset = 0;
735: /* XXX WRITEME: */
736: abort();
737: }
738:
739: /* the sparc64 ASI handler for ASI_PST*: */
740: void
741: tme_sparc64_vis_ls_asi_pst(struct tme_sparc *ic, struct tme_sparc_ls *ls)
742: {
743: tme_uint32_t insn;
744: unsigned int reg_rs1;
745: tme_uint64_t address_first;
746:
747: /* NB: this checks for various traps in priority order: */
748:
749: /* the only faults that may have been set so far are an alignment
750: fault, which is probably wrong because the address checked was
751: (rs1 + rs2), instead of just rs1, and any ldd/std rd-odd fault.
752: we will override both faults: */
753: assert ((ls->tme_sparc_ls_faults
754: | TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED
755: | TME_SPARC_LS_FAULT_LDD_STD_RD_ODD)
756: == (TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED
757: | TME_SPARC_LS_FAULT_LDD_STD_RD_ODD));
758:
759: /* we need to do the complete transfer: */
760: ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_NONE;
761: ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_SLOW_CYCLES;
762: ls->tme_sparc_ls_state = 0;
763:
764: /* get the instruction: */
765: insn = ic->_tme_sparc_insn;
766:
767: /* NB: the exception for a non-stdfa opcode appears to be explicitly
768: prioritized above an illegal_instruction trap for an immediate
769: instruction: */
770:
771: /* if this is an stdfa: */
772: if (__tme_predict_true((insn
773: & (0x3f << 19))
774: == (0x37 << 19))) {
775:
776: /* set the slow cycle function: */
777: assert (ls->tme_sparc_ls_size == sizeof(tme_uint64_t));
778: ls->tme_sparc_ls_cycle = _tme_sparc64_vis_ls_cycle_pstd;
779: }
780:
781: /* any other instruction is illegal: */
782: else {
783: ls->tme_sparc_ls_faults = ic->tme_sparc_vis_ls_fault_illegal;
784: return;
785: }
786:
787: /* immediate instruction forms are illegal: */
788: if (__tme_predict_false(insn & TME_BIT(13))) {
789: tme_sparc_tlb_unbusy(ls->tme_sparc_ls_tlb);
790: TME_SPARC_INSN_ILL(ic);
791: }
792:
793: /* the stdfa instruction handler must have already checked that the
794: FPU is enabled: */
795: assert (!TME_SPARC_FPU_IS_DISABLED(ic));
796:
797: /* decode rs1: */
798: reg_rs1 = TME_FIELD_MASK_EXTRACTU(insn, TME_SPARC_FORMAT3_MASK_RS1);
799: TME_SPARC_REG_INDEX(ic, reg_rs1);
800:
801: /* get the address: */
802: address_first = ic->tme_sparc_ireg_uint64(reg_rs1);
803: ls->tme_sparc_ls_address64 = address_first;
804:
805: /* the address must be aligned: */
806: if (__tme_predict_false((((tme_uint32_t) address_first)
807: & (ls->tme_sparc_ls_size - 1)) != 0)) {
808: ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED;
809: return;
810: }
811:
812: /* the stdfa instruction handler must have already checked that the
813: FPU mode is not exception_pending: */
814: assert (ic->tme_sparc_fpu_mode != TME_SPARC_FPU_MODE_EXCEPTION_PENDING);
815: }
816:
817: /* the sparc64 cycle handler for lddfa and stdfa ASI_FL*: */
818: static void
819: _tme_sparc64_vis_ls_cycle_fld(struct tme_sparc *ic, struct tme_sparc_ls *ls)
820: {
821: tme_uint64_t value;
822: unsigned int buffer_offset;
823:
824: /* if this is an stdfa: */
825: if (ic->_tme_sparc_insn & (4 << 19)) {
826:
827: /* the actual store cycles will be done directly: */
828: ls->tme_sparc_ls_cycle = tme_sparc64_store;
829:
830: /* initialize the memory buffer with the value to store: */
831: value = *ls->tme_sparc_ls_rd64;
832: }
833:
834: /* otherwise, this is an lddfa: */
835: else {
836:
837: /* the actual load cycles will be done directly: */
838: ls->tme_sparc_ls_cycle = tme_sparc64_load;
839:
840: /* initialize the memory buffer with zero: */
841: value = 0;
842: }
843:
844: /* initialize the memory buffer: */
845: if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_ENDIAN_LITTLE) {
846: value = tme_htole_u64(value);
847: buffer_offset = 0;
848: }
849: else {
850: value = tme_htobe_u64(value);
851: buffer_offset = sizeof(value) - ls->tme_sparc_ls_size;
852: }
853: ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer64s[0] = value;
854: ls->tme_sparc_ls_buffer_offset = buffer_offset;
855:
856: /* do the (first) actual cycle: */
857: (*ls->tme_sparc_ls_cycle)(ic, ls);
858: }
859:
860: /* the sparc64 ASI handler for ASI_FL*: */
861: void
862: tme_sparc64_vis_ls_asi_fl(struct tme_sparc *ic, struct tme_sparc_ls *ls)
863: {
864: tme_uint32_t insn;
865:
866: /* NB: this checks for various traps in priority order: */
867:
868: /* the only faults that may have been set so far are an alignment
869: fault, which is probably wrong because the size used for the
870: alignment check was wrong, and any ldd/std rd-odd fault. we will
871: override both faults: */
872: assert ((ls->tme_sparc_ls_faults
873: | TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED
874: | TME_SPARC_LS_FAULT_LDD_STD_RD_ODD)
875: == (TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED
876: | TME_SPARC_LS_FAULT_LDD_STD_RD_ODD));
877:
878: /* get the instruction: */
879: insn = ic->_tme_sparc_insn;
880:
881: /* we need to do the complete transfer: */
882: ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_NONE;
883: ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_SLOW_CYCLES;
884: ls->tme_sparc_ls_state = 0;
885:
886: /* set the cycle size: */
887: #if (TME_SPARC_VIS_ASI_FL16 & (TME_SPARC_VIS_ASI_FL16 - 1)) != TME_SPARC_VIS_ASI_FL8
888: #error "TME_SPARC_VIS_ASI_FL values changed"
889: #endif
890: ls->tme_sparc_ls_size
891: = (sizeof(tme_uint8_t)
892: + ((TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask)
893: / (TME_SPARC_VIS_ASI_FL16
894: ^ TME_SPARC_VIS_ASI_FL8))
895: & 1));
896:
897: /* if this is an stdfa or an lddfa: */
898: if (__tme_predict_true((insn
899: & (0x3b << 19))
900: == (0x33 << 19))) {
901:
902: /* set the slow cycle function: */
903: ls->tme_sparc_ls_cycle = _tme_sparc64_vis_ls_cycle_fld;
904:
905: /* the stdfa or lddfa instruction handler must have already
906: checked that the FPU is enabled: */
907: assert (!TME_SPARC_FPU_IS_DISABLED(ic));
908: }
909:
910: /* any other instruction is illegal: */
911: /* XXX FIXME - is this correct? the UltraSPARC User's Manual
912: doesn't document data_access_exception for an illegal opcode: */
913: else {
914: ls->tme_sparc_ls_faults = ic->tme_sparc_vis_ls_fault_illegal;
915: return;
916: }
917:
918: /* the address must be aligned: */
919: if (__tme_predict_false((((tme_uint32_t) ls->tme_sparc_ls_address64)
920: & (ls->tme_sparc_ls_size - 1)) != 0)) {
921: ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED;
922: return;
923: }
924:
925: /* the stdfa or lddfa instruction handler must have already checked
926: that the FPU mode is execute: */
927: assert (ic->tme_sparc_fpu_mode == TME_SPARC_FPU_MODE_EXECUTE);
928: }
929:
930: /* the sparc64 VIS alternate ASI misalignment function: */
931: tme_uint32_t
932: tme_sparc64_vis_ls_asi_misaligned(struct tme_sparc *ic,
933: tme_uint32_t misaligned)
934: {
935: tme_uint32_t insn;
936: tme_uint32_t asi;
937: tme_uint32_t asi_base;
938: unsigned int reg_rs1;
939:
940: /* get the instruction: */
941: insn = TME_SPARC_INSN;
942:
943: /* get the ASI, assuming that the i bit is zero: */
944: asi = TME_FIELD_MASK_EXTRACTU(insn, (0xff << 5));
945:
946: /* if the i bit is one, use the ASI register: */
947: if (insn & TME_BIT(13)) {
948: asi = ic->tme_sparc64_ireg_asi;
949: }
950:
951: /* make a base version of the ASI, with the secondary and
952: little-endian flags cleared: */
953: asi_base = (asi & ~(TME_SPARC64_ASI_FLAG_SECONDARY | TME_SPARC64_ASI_FLAG_LITTLE));
954:
955: /* ASI_FL8* requires 8-bit alignment: */
956: if (asi_base == TME_SPARC_VIS_ASI_FL8) {
957: misaligned %= sizeof(tme_uint8_t);
958: }
959:
960: /* ASI_FL16* requires 16-bit alignment: */
961: else if (asi_base == TME_SPARC_VIS_ASI_FL16) {
962: misaligned %= sizeof(tme_uint16_t);
963: }
964:
965: /* if this is an ASI_PST*: */
966: else if (asi_base == TME_SPARC_VIS_ASI_PST8
967: || asi_base == TME_SPARC_VIS_ASI_PST16
968: || asi_base == TME_SPARC_VIS_ASI_PST32) {
969:
970: /* decode rs1: */
971: reg_rs1 = TME_FIELD_MASK_EXTRACTU(insn, TME_SPARC_FORMAT3_MASK_RS1);
972: TME_SPARC_REG_INDEX(ic, reg_rs1);
973:
974: /* if this is not a register mode stdfa: */
975: if (__tme_predict_false((insn
976: & ((0x3f << 19)
977: + TME_BIT(13)))
978: != (0x37 << 19))) {
979:
980: /* start a slow load/store, which will call the ASI handler,
981: which will cause the appropriate fault: */
982: tme_sparc64_ls(ic,
983: ic->tme_sparc_ireg_uint64(reg_rs1),
984: (tme_uint64_t *) NULL, /* _rd */
985: (TME_SPARC_LSINFO_SIZE(1)
986: | TME_SPARC_LSINFO_ASI(asi)
987: | TME_SPARC_LSINFO_A));
988: assert(FALSE);
989: }
990:
991: /* get the least-significant 32 bits of the address: */
992: misaligned = ic->tme_sparc_ireg_uint64(reg_rs1);
993:
994: /* ASI_PST* require 64-bit alignment, which the stdfa instruction
995: handler is already checking: */
996: }
997:
998: /* return a possibly updated misalignment: */
999: return (misaligned);
1000: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.