|
|
1.1 root 1: /* automatically generated by sparc-insns-auto.sh, do not edit! */
2: _TME_RCSID("$Id: sparc-insns-auto.sh,v 1.5 2007/03/29 01:16:09 fredette Exp $");
3:
4: #include "sparc-impl.h"
5:
6: #undef TME_SPARC_VERSION
7: #define TME_SPARC_VERSION(ic) (8)
8: static tme_uint32_t
9: _tme_sparc32_alternate_asi_mask(struct tme_sparc *ic)
10: {
11: unsigned int asi_data;
12: tme_uint32_t asi_mask_data;
13:
14: /* get the ASI, assuming that the i bit is zero: */
15: asi_data = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0xff << 5));
16:
17: /* this is a privileged instruction: */
18: TME_SPARC_INSN_PRIV;
19:
20: /* if the i bit is one, this is an illegal instruction: */
21: if (__tme_predict_false(TME_SPARC_INSN & TME_BIT(13))) {
22: TME_SPARC_INSN_ILL;
23: }
24:
25: /* map the ASI into an ASI mask: */
26: switch (asi_data) {
27: case TME_SPARC32_ASI_UI: asi_mask_data = TME_SPARC32_ASI_MASK_UI; break;
28: case TME_SPARC32_ASI_UD: asi_mask_data = TME_SPARC32_ASI_MASK_UD; break;
29: case TME_SPARC32_ASI_SI: asi_mask_data = TME_SPARC32_ASI_MASK_SI; break;
30: case TME_SPARC32_ASI_SD: asi_mask_data = TME_SPARC32_ASI_MASK_SD; break;
31: default: asi_mask_data = TME_SPARC_ASI_MASK(asi_data); break;
32: }
33:
34: return (asi_mask_data);
35: }
36:
37: /* this does a sparc32 "add SRC1, SRC2, DST": */
38: TME_SPARC_FORMAT3(tme_sparc32_add, tme_uint32_t)
39: {
40: tme_uint32_t src1;
41: tme_uint32_t src2;
42: tme_uint32_t dst;
43:
44: /* get the operands: */
45: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
46: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
47:
48: /* perform the operation: */
49: dst = src1 + src2;
50:
51: /* store the destination: */
52: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
53:
54: TME_SPARC_INSN_OK;
55: }
56:
57: /* this does a sparc32 "addcc SRC1, SRC2, DST": */
58: TME_SPARC_FORMAT3(tme_sparc32_addcc, tme_uint32_t)
59: {
60: tme_uint32_t src1;
61: tme_uint32_t src2;
62: tme_uint32_t dst;
63: tme_uint32_t cc;
64:
65: /* get the operands: */
66: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
67: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
68:
69: /* perform the operation: */
70: dst = src1 + src2;
71:
72: /* store the destination: */
73: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
74:
75: /* set Z if the destination is zero: */
76: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
77:
78: /* set N if the destination is negative: */
79: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
80:
81: /* if the operands are the same sign, and the destination has
82: a different sign, set V: */
83: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V);
84:
85: /* if src1 and src2 both have the high bit set, or if dst does
86: not have the high bit set and either src1 or src2 does, set C: */
87: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C;
88:
89: /* set the condition codes: */
90: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
91:
92: TME_SPARC_INSN_OK;
93: }
94:
95: /* this does a sparc32 "sub SRC1, SRC2, DST": */
96: TME_SPARC_FORMAT3(tme_sparc32_sub, tme_uint32_t)
97: {
98: tme_uint32_t src1;
99: tme_uint32_t src2;
100: tme_uint32_t dst;
101:
102: /* get the operands: */
103: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
104: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
105:
106: /* perform the operation: */
107: dst = src1 - src2;
108:
109: /* store the destination: */
110: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
111:
112: TME_SPARC_INSN_OK;
113: }
114:
115: /* this does a sparc32 "subcc SRC1, SRC2, DST": */
116: TME_SPARC_FORMAT3(tme_sparc32_subcc, tme_uint32_t)
117: {
118: tme_uint32_t src1;
119: tme_uint32_t src2;
120: tme_uint32_t dst;
121: tme_uint32_t cc;
122:
123: /* get the operands: */
124: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
125: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
126:
127: /* perform the operation: */
128: dst = src1 - src2;
129:
130: /* store the destination: */
131: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
132:
133: /* set Z if the destination is zero: */
134: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
135:
136: /* set N if the destination is negative: */
137: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
138:
139: /* if the operands are different signs, and the destination has
140: a different sign from the first operand, set V: */
141: cc += ((((tme_int32_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC32_PSR_ICC_V);
142:
143: /* if src2 is greater than src1, set C: */
144: cc += ((((tme_uint32_t) src2) > ((tme_uint32_t) src1))) * TME_SPARC32_PSR_ICC_C;
145:
146: /* set the condition codes: */
147: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
148:
149: TME_SPARC_INSN_OK;
150: }
151:
152: /* this does a sparc32 "or SRC1, SRC2, DST": */
153: TME_SPARC_FORMAT3(tme_sparc32_or, tme_uint32_t)
154: {
155: tme_uint32_t src1;
156: tme_uint32_t src2;
157: tme_uint32_t dst;
158:
159: /* get the operands: */
160: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
161: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
162:
163: /* perform the operation: */
164: dst = src1 | src2;
165:
166: /* store the destination: */
167: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
168:
169: TME_SPARC_INSN_OK;
170: }
171:
172: /* this does a sparc32 "orcc SRC1, SRC2, DST": */
173: TME_SPARC_FORMAT3(tme_sparc32_orcc, tme_uint32_t)
174: {
175: tme_uint32_t src1;
176: tme_uint32_t src2;
177: tme_uint32_t dst;
178: tme_uint32_t cc;
179:
180: /* get the operands: */
181: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
182: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
183:
184: /* perform the operation: */
185: dst = src1 | src2;
186:
187: /* store the destination: */
188: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
189:
190: /* set Z if the destination is zero: */
191: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
192:
193: /* set N if the destination is negative: */
194: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
195:
196: /* set the condition codes: */
197: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
198:
199: TME_SPARC_INSN_OK;
200: }
201:
202: /* this does a sparc32 "orn SRC1, SRC2, DST": */
203: TME_SPARC_FORMAT3(tme_sparc32_orn, tme_uint32_t)
204: {
205: tme_uint32_t src1;
206: tme_uint32_t src2;
207: tme_uint32_t dst;
208:
209: /* get the operands: */
210: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
211: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
212:
213: /* perform the operation: */
214: dst = src1 | ~src2;
215:
216: /* store the destination: */
217: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
218:
219: TME_SPARC_INSN_OK;
220: }
221:
222: /* this does a sparc32 "orncc SRC1, SRC2, DST": */
223: TME_SPARC_FORMAT3(tme_sparc32_orncc, tme_uint32_t)
224: {
225: tme_uint32_t src1;
226: tme_uint32_t src2;
227: tme_uint32_t dst;
228: tme_uint32_t cc;
229:
230: /* get the operands: */
231: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
232: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
233:
234: /* perform the operation: */
235: dst = src1 | ~src2;
236:
237: /* store the destination: */
238: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
239:
240: /* set Z if the destination is zero: */
241: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
242:
243: /* set N if the destination is negative: */
244: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
245:
246: /* set the condition codes: */
247: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
248:
249: TME_SPARC_INSN_OK;
250: }
251:
252: /* this does a sparc32 "and SRC1, SRC2, DST": */
253: TME_SPARC_FORMAT3(tme_sparc32_and, tme_uint32_t)
254: {
255: tme_uint32_t src1;
256: tme_uint32_t src2;
257: tme_uint32_t dst;
258:
259: /* get the operands: */
260: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
261: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
262:
263: /* perform the operation: */
264: dst = src1 & src2;
265:
266: /* store the destination: */
267: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
268:
269: TME_SPARC_INSN_OK;
270: }
271:
272: /* this does a sparc32 "andcc SRC1, SRC2, DST": */
273: TME_SPARC_FORMAT3(tme_sparc32_andcc, tme_uint32_t)
274: {
275: tme_uint32_t src1;
276: tme_uint32_t src2;
277: tme_uint32_t dst;
278: tme_uint32_t cc;
279:
280: /* get the operands: */
281: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
282: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
283:
284: /* perform the operation: */
285: dst = src1 & src2;
286:
287: /* store the destination: */
288: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
289:
290: /* set Z if the destination is zero: */
291: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
292:
293: /* set N if the destination is negative: */
294: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
295:
296: /* set the condition codes: */
297: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
298:
299: TME_SPARC_INSN_OK;
300: }
301:
302: /* this does a sparc32 "andn SRC1, SRC2, DST": */
303: TME_SPARC_FORMAT3(tme_sparc32_andn, tme_uint32_t)
304: {
305: tme_uint32_t src1;
306: tme_uint32_t src2;
307: tme_uint32_t dst;
308:
309: /* get the operands: */
310: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
311: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
312:
313: /* perform the operation: */
314: dst = src1 & ~src2;
315:
316: /* store the destination: */
317: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
318:
319: TME_SPARC_INSN_OK;
320: }
321:
322: /* this does a sparc32 "andncc SRC1, SRC2, DST": */
323: TME_SPARC_FORMAT3(tme_sparc32_andncc, tme_uint32_t)
324: {
325: tme_uint32_t src1;
326: tme_uint32_t src2;
327: tme_uint32_t dst;
328: tme_uint32_t cc;
329:
330: /* get the operands: */
331: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
332: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
333:
334: /* perform the operation: */
335: dst = src1 & ~src2;
336:
337: /* store the destination: */
338: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
339:
340: /* set Z if the destination is zero: */
341: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
342:
343: /* set N if the destination is negative: */
344: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
345:
346: /* set the condition codes: */
347: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
348:
349: TME_SPARC_INSN_OK;
350: }
351:
352: /* this does a sparc32 "xor SRC1, SRC2, DST": */
353: TME_SPARC_FORMAT3(tme_sparc32_xor, tme_uint32_t)
354: {
355: tme_uint32_t src1;
356: tme_uint32_t src2;
357: tme_uint32_t dst;
358:
359: /* get the operands: */
360: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
361: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
362:
363: /* perform the operation: */
364: dst = src1 ^ src2;
365:
366: /* store the destination: */
367: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
368:
369: TME_SPARC_INSN_OK;
370: }
371:
372: /* this does a sparc32 "xorcc SRC1, SRC2, DST": */
373: TME_SPARC_FORMAT3(tme_sparc32_xorcc, tme_uint32_t)
374: {
375: tme_uint32_t src1;
376: tme_uint32_t src2;
377: tme_uint32_t dst;
378: tme_uint32_t cc;
379:
380: /* get the operands: */
381: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
382: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
383:
384: /* perform the operation: */
385: dst = src1 ^ src2;
386:
387: /* store the destination: */
388: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
389:
390: /* set Z if the destination is zero: */
391: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
392:
393: /* set N if the destination is negative: */
394: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
395:
396: /* set the condition codes: */
397: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
398:
399: TME_SPARC_INSN_OK;
400: }
401:
402: /* this does a sparc32 "xnor SRC1, SRC2, DST": */
403: TME_SPARC_FORMAT3(tme_sparc32_xnor, tme_uint32_t)
404: {
405: tme_uint32_t src1;
406: tme_uint32_t src2;
407: tme_uint32_t dst;
408:
409: /* get the operands: */
410: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
411: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
412:
413: /* perform the operation: */
414: dst = src1 ^ ~src2;
415:
416: /* store the destination: */
417: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
418:
419: TME_SPARC_INSN_OK;
420: }
421:
422: /* this does a sparc32 "xnorcc SRC1, SRC2, DST": */
423: TME_SPARC_FORMAT3(tme_sparc32_xnorcc, tme_uint32_t)
424: {
425: tme_uint32_t src1;
426: tme_uint32_t src2;
427: tme_uint32_t dst;
428: tme_uint32_t cc;
429:
430: /* get the operands: */
431: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
432: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
433:
434: /* perform the operation: */
435: dst = src1 ^ ~src2;
436:
437: /* store the destination: */
438: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
439:
440: /* set Z if the destination is zero: */
441: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
442:
443: /* set N if the destination is negative: */
444: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
445:
446: /* set the condition codes: */
447: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
448:
449: TME_SPARC_INSN_OK;
450: }
451:
452: /* this does a sparc32 "addx SRC1, SRC2, DST": */
453: TME_SPARC_FORMAT3(tme_sparc32_addx, tme_uint32_t)
454: {
455: tme_uint32_t src1;
456: tme_uint32_t src2;
457: tme_uint32_t dst;
458:
459: /* get the operands: */
460: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
461: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
462:
463: /* perform the operation: */
464: dst = src1 + src2;
465: dst += ((ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C) != 0);
466:
467: /* store the destination: */
468: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
469:
470: TME_SPARC_INSN_OK;
471: }
472:
473: /* this does a sparc32 "addxcc SRC1, SRC2, DST": */
474: TME_SPARC_FORMAT3(tme_sparc32_addxcc, tme_uint32_t)
475: {
476: tme_uint32_t src1;
477: tme_uint32_t src2;
478: tme_uint32_t dst;
479: tme_uint32_t cc;
480:
481: /* get the operands: */
482: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
483: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
484:
485: /* perform the operation: */
486: dst = src1 + src2;
487: dst += ((ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C) != 0);
488:
489: /* store the destination: */
490: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
491:
492: /* set Z if the destination is zero: */
493: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
494:
495: /* set N if the destination is negative: */
496: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
497:
498: /* if the operands are the same sign, and the destination has
499: a different sign, set V: */
500: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V);
501:
502: /* if src1 and src2 both have the high bit set, or if dst does
503: not have the high bit set and either src1 or src2 does, set C: */
504: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C;
505:
506: /* set the condition codes: */
507: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
508:
509: TME_SPARC_INSN_OK;
510: }
511:
512: /* this does a sparc32 "subx SRC1, SRC2, DST": */
513: TME_SPARC_FORMAT3(tme_sparc32_subx, tme_uint32_t)
514: {
515: tme_uint32_t src1;
516: tme_uint32_t src2;
517: tme_uint32_t dst;
518:
519: /* get the operands: */
520: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
521: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
522:
523: /* perform the operation: */
524: dst = src1 - src2;
525: dst -= ((ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C) != 0);
526:
527: /* store the destination: */
528: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
529:
530: TME_SPARC_INSN_OK;
531: }
532:
533: /* this does a sparc32 "subxcc SRC1, SRC2, DST": */
534: TME_SPARC_FORMAT3(tme_sparc32_subxcc, tme_uint32_t)
535: {
536: tme_uint32_t src1;
537: tme_uint32_t src2;
538: tme_uint32_t dst;
539: tme_uint32_t cc;
540:
541: /* get the operands: */
542: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
543: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
544:
545: /* perform the operation: */
546: dst = src1 - src2;
547: dst -= ((ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C) != 0);
548:
549: /* store the destination: */
550: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
551:
552: /* set Z if the destination is zero: */
553: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
554:
555: /* set N if the destination is negative: */
556: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
557:
558: /* if the operands are different signs, and the destination has
559: a different sign from the first operand, set V: */
560: cc += ((((tme_int32_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC32_PSR_ICC_V);
561:
562: /* if src2 is greater than src1, set C: */
563: cc += ((((tme_uint32_t) src2) > ((tme_uint32_t) src1)) || (((tme_uint32_t) src2) == ((tme_uint32_t) src1) && (ic->tme_sparc32_ireg_psr & TME_SPARC32_PSR_ICC_C))) * TME_SPARC32_PSR_ICC_C;
564:
565: /* set the condition codes: */
566: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
567:
568: TME_SPARC_INSN_OK;
569: }
570:
571: /* this does a sparc32 "taddcc SRC1, SRC2, DST": */
572: TME_SPARC_FORMAT3(tme_sparc32_taddcc, tme_uint32_t)
573: {
574: tme_uint32_t src1;
575: tme_uint32_t src2;
576: tme_uint32_t dst;
577: tme_uint32_t cc;
578:
579: /* get the operands: */
580: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
581: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
582:
583: /* perform the operation: */
584: dst = src1 + src2;
585:
586: /* store the destination: */
587: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
588:
589: /* set Z if the destination is zero: */
590: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
591:
592: /* set N if the destination is negative: */
593: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
594:
595: /* if the operands are the same sign, and the destination has
596: a different sign, set V: */
597: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V);
598:
599: /* if src1 and src2 both have the high bit set, or if dst does
600: not have the high bit set and either src1 or src2 does, set C: */
601: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C;
602:
603: /* set V if bits zero or one of src1 or src2 are set: */
604: cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC32_PSR_ICC_V);
605:
606: /* set the condition codes: */
607: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
608:
609: TME_SPARC_INSN_OK;
610: }
611:
612: /* this does a sparc32 "taddcctv SRC1, SRC2, DST": */
613: TME_SPARC_FORMAT3(tme_sparc32_taddcctv, tme_uint32_t)
614: {
615: tme_uint32_t src1;
616: tme_uint32_t src2;
617: tme_uint32_t dst;
618: tme_uint32_t cc;
619:
620: /* get the operands: */
621: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
622: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
623:
624: /* perform the operation: */
625: dst = src1 + src2;
626:
627: /* set Z if the destination is zero: */
628: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
629:
630: /* set N if the destination is negative: */
631: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
632:
633: /* if the operands are the same sign, and the destination has
634: a different sign, set V: */
635: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V);
636:
637: /* if src1 and src2 both have the high bit set, or if dst does
638: not have the high bit set and either src1 or src2 does, set C: */
639: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C;
640:
641: /* set V if bits zero or one of src1 or src2 are set: */
642: cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC32_PSR_ICC_V);
643:
644: /* trap on a tagged overflow: */
645: if (cc & TME_SPARC32_PSR_ICC_V) {
646: tme_sparc32_trap(ic, TME_SPARC_TRAP_tag_overflow);
647: }
648: /* store the destination: */
649: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
650:
651: /* set the condition codes: */
652: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
653:
654: TME_SPARC_INSN_OK;
655: }
656:
657: /* this does a sparc32 "tsubcc SRC1, SRC2, DST": */
658: TME_SPARC_FORMAT3(tme_sparc32_tsubcc, tme_uint32_t)
659: {
660: tme_uint32_t src1;
661: tme_uint32_t src2;
662: tme_uint32_t dst;
663: tme_uint32_t cc;
664:
665: /* get the operands: */
666: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
667: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
668:
669: /* perform the operation: */
670: dst = src1 - src2;
671:
672: /* store the destination: */
673: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
674:
675: /* set Z if the destination is zero: */
676: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
677:
678: /* set N if the destination is negative: */
679: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
680:
681: /* if the operands are different signs, and the destination has
682: a different sign from the first operand, set V: */
683: cc += ((((tme_int32_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC32_PSR_ICC_V);
684:
685: /* if src2 is greater than src1, set C: */
686: cc += ((((tme_uint32_t) src2) > ((tme_uint32_t) src1))) * TME_SPARC32_PSR_ICC_C;
687:
688: /* set V if bits zero or one of src1 or src2 are set: */
689: cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC32_PSR_ICC_V);
690:
691: /* set the condition codes: */
692: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
693:
694: TME_SPARC_INSN_OK;
695: }
696:
697: /* this does a sparc32 "tsubcctv SRC1, SRC2, DST": */
698: TME_SPARC_FORMAT3(tme_sparc32_tsubcctv, tme_uint32_t)
699: {
700: tme_uint32_t src1;
701: tme_uint32_t src2;
702: tme_uint32_t dst;
703: tme_uint32_t cc;
704:
705: /* get the operands: */
706: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
707: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
708:
709: /* perform the operation: */
710: dst = src1 - src2;
711:
712: /* set Z if the destination is zero: */
713: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
714:
715: /* set N if the destination is negative: */
716: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
717:
718: /* if the operands are different signs, and the destination has
719: a different sign from the first operand, set V: */
720: cc += ((((tme_int32_t) ((src1 ^ src2) & (src1 ^ dst))) < 0) * TME_SPARC32_PSR_ICC_V);
721:
722: /* if src2 is greater than src1, set C: */
723: cc += ((((tme_uint32_t) src2) > ((tme_uint32_t) src1))) * TME_SPARC32_PSR_ICC_C;
724:
725: /* set V if bits zero or one of src1 or src2 are set: */
726: cc |= ((((src1 | src2) & 3) != 0) * TME_SPARC32_PSR_ICC_V);
727:
728: /* trap on a tagged overflow: */
729: if (cc & TME_SPARC32_PSR_ICC_V) {
730: tme_sparc32_trap(ic, TME_SPARC_TRAP_tag_overflow);
731: }
732: /* store the destination: */
733: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
734:
735: /* set the condition codes: */
736: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
737:
738: TME_SPARC_INSN_OK;
739: }
740:
741: /* this does a sparc32 "umul SRC1, SRC2, DST": */
742: TME_SPARC_FORMAT3(tme_sparc32_umul, tme_uint32_t)
743: {
744: tme_uint32_t src1;
745: tme_uint32_t src2;
746: tme_uint32_t dst;
747: tme_uint64_t val64;
748:
749: /* get the operands: */
750: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
751: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
752:
753: /* perform the operation: */
754: val64 = (((tme_uint64_t) src1) * src2);
755: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = (((tme_uint64_t) val64) >> 32);
756: dst = ((tme_uint64_t) val64);
757:
758: /* store the destination: */
759: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
760:
761: TME_SPARC_INSN_OK;
762: }
763:
764: /* this does a sparc32 "umulcc SRC1, SRC2, DST": */
765: TME_SPARC_FORMAT3(tme_sparc32_umulcc, tme_uint32_t)
766: {
767: tme_uint32_t src1;
768: tme_uint32_t src2;
769: tme_uint32_t dst;
770: tme_uint64_t val64;
771: tme_uint32_t cc;
772:
773: /* get the operands: */
774: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
775: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
776:
777: /* perform the operation: */
778: val64 = (((tme_uint64_t) src1) * src2);
779: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = (((tme_uint64_t) val64) >> 32);
780: dst = ((tme_uint64_t) val64);
781:
782: /* store the destination: */
783: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
784:
785: /* set Z if the destination is zero: */
786: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
787:
788: /* set N if the destination is negative: */
789: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
790:
791: /* set the condition codes: */
792: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
793:
794: TME_SPARC_INSN_OK;
795: }
796:
797: /* this does a sparc32 "smul SRC1, SRC2, DST": */
798: TME_SPARC_FORMAT3(tme_sparc32_smul, tme_uint32_t)
799: {
800: tme_int32_t src1;
801: tme_int32_t src2;
802: tme_int32_t dst;
803: tme_int64_t val64;
804:
805: /* get the operands: */
806: src1 = (tme_int32_t) TME_SPARC_FORMAT3_RS1;
807: src2 = (tme_int32_t) TME_SPARC_FORMAT3_RS2;
808:
809: /* perform the operation: */
810: val64 = (((tme_int64_t) src1) * src2);
811: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = (((tme_uint64_t) val64) >> 32);
812: dst = ((tme_int64_t) val64);
813:
814: /* store the destination: */
815: TME_SPARC_FORMAT3_RD = (tme_int32_t) dst;
816:
817: TME_SPARC_INSN_OK;
818: }
819:
820: /* this does a sparc32 "smulcc SRC1, SRC2, DST": */
821: TME_SPARC_FORMAT3(tme_sparc32_smulcc, tme_uint32_t)
822: {
823: tme_int32_t src1;
824: tme_int32_t src2;
825: tme_int32_t dst;
826: tme_int64_t val64;
827: tme_uint32_t cc;
828:
829: /* get the operands: */
830: src1 = (tme_int32_t) TME_SPARC_FORMAT3_RS1;
831: src2 = (tme_int32_t) TME_SPARC_FORMAT3_RS2;
832:
833: /* perform the operation: */
834: val64 = (((tme_int64_t) src1) * src2);
835: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = (((tme_uint64_t) val64) >> 32);
836: dst = ((tme_int64_t) val64);
837:
838: /* store the destination: */
839: TME_SPARC_FORMAT3_RD = (tme_int32_t) dst;
840:
841: /* set Z if the destination is zero: */
842: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
843:
844: /* set N if the destination is negative: */
845: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
846:
847: /* set the condition codes: */
848: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
849:
850: TME_SPARC_INSN_OK;
851: }
852:
853: /* this does a sparc32 "udiv SRC1, SRC2, DST": */
854: TME_SPARC_FORMAT3(tme_sparc32_udiv, tme_uint32_t)
855: {
856: tme_uint32_t src1;
857: tme_uint32_t src2;
858: tme_uint32_t dst;
859: tme_uint64_t val64;
860:
861: /* get the operands: */
862: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
863: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
864:
865: /* perform the operation: */
866: val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y)) << 32) | ((tme_uint32_t) src1));
867: val64 /= src2;
868: /* XXX FIXME - overflow handling is missing here: */
869: dst = val64;
870:
871: /* store the destination: */
872: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
873:
874: TME_SPARC_INSN_OK;
875: }
876:
877: /* this does a sparc32 "udivcc SRC1, SRC2, DST": */
878: TME_SPARC_FORMAT3(tme_sparc32_udivcc, tme_uint32_t)
879: {
880: tme_uint32_t src1;
881: tme_uint32_t src2;
882: tme_uint32_t dst;
883: tme_uint64_t val64;
884: tme_uint32_t cc;
885:
886: /* get the operands: */
887: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
888: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
889:
890: /* perform the operation: */
891: val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y)) << 32) | ((tme_uint32_t) src1));
892: val64 /= src2;
893: /* XXX FIXME - overflow handling is missing here: */
894: dst = val64;
895:
896: /* store the destination: */
897: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
898:
899: /* set Z if the destination is zero: */
900: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
901:
902: /* set N if the destination is negative: */
903: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
904:
905: /* set the condition codes: */
906: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
907:
908: TME_SPARC_INSN_OK;
909: }
910:
911: /* this does a sparc32 "sdiv SRC1, SRC2, DST": */
912: TME_SPARC_FORMAT3(tme_sparc32_sdiv, tme_uint32_t)
913: {
914: tme_int32_t src1;
915: tme_int32_t src2;
916: tme_int32_t dst;
917: tme_int64_t val64;
918:
919: /* get the operands: */
920: src1 = (tme_int32_t) TME_SPARC_FORMAT3_RS1;
921: src2 = (tme_int32_t) TME_SPARC_FORMAT3_RS2;
922:
923: /* perform the operation: */
924: val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y)) << 32) | ((tme_uint32_t) src1));
925: val64 /= src2;
926: /* XXX FIXME - overflow handling is missing here: */
927: dst = val64;
928:
929: /* store the destination: */
930: TME_SPARC_FORMAT3_RD = (tme_int32_t) dst;
931:
932: TME_SPARC_INSN_OK;
933: }
934:
935: /* this does a sparc32 "sdivcc SRC1, SRC2, DST": */
936: TME_SPARC_FORMAT3(tme_sparc32_sdivcc, tme_uint32_t)
937: {
938: tme_int32_t src1;
939: tme_int32_t src2;
940: tme_int32_t dst;
941: tme_int64_t val64;
942: tme_uint32_t cc;
943:
944: /* get the operands: */
945: src1 = (tme_int32_t) TME_SPARC_FORMAT3_RS1;
946: src2 = (tme_int32_t) TME_SPARC_FORMAT3_RS2;
947:
948: /* perform the operation: */
949: val64 = ((((tme_uint64_t) ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y)) << 32) | ((tme_uint32_t) src1));
950: val64 /= src2;
951: /* XXX FIXME - overflow handling is missing here: */
952: dst = val64;
953:
954: /* store the destination: */
955: TME_SPARC_FORMAT3_RD = (tme_int32_t) dst;
956:
957: /* set Z if the destination is zero: */
958: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
959:
960: /* set N if the destination is negative: */
961: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
962:
963: /* set the condition codes: */
964: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
965:
966: TME_SPARC_INSN_OK;
967: }
968:
969: /* the sparc32 sll function: */
970: TME_SPARC_FORMAT3(tme_sparc32_sll, tme_uint32_t)
971: {
972: tme_uint32_t dst;
973: unsigned int count;
974:
975: /* get the value and the shift count: */
976: dst = TME_SPARC_FORMAT3_RS1;
977: count = TME_SPARC_FORMAT3_RS2;
978:
979: /* limit the count: */
980: count %= 32;
981:
982: /* do the shift: */
983: #if (SHIFTMAX_INT32_T < (32 - 1))
984: #error "cannot do full shifts of a tme_int32_t"
985: #endif /* (SHIFTMAX_INT32_T < (32 - 1)) */
986: dst <<= count;
987:
988: /* store the destination: */
989: TME_SPARC_FORMAT3_RD = dst;
990:
991: TME_SPARC_INSN_OK;
992: }
993:
994: /* the sparc32 srl function: */
995: TME_SPARC_FORMAT3(tme_sparc32_srl, tme_uint32_t)
996: {
997: tme_uint32_t dst;
998: unsigned int count;
999:
1000: /* get the value and the shift count: */
1001: dst = TME_SPARC_FORMAT3_RS1;
1002: count = TME_SPARC_FORMAT3_RS2;
1003:
1004: /* limit the count: */
1005: count %= 32;
1006:
1007: /* do the shift: */
1008: #if (SHIFTMAX_INT32_T < (32 - 1))
1009: #error "cannot do full shifts of a tme_int32_t"
1010: #endif /* (SHIFTMAX_INT32_T < (32 - 1)) */
1011: dst >>= count;
1012:
1013: /* store the destination: */
1014: TME_SPARC_FORMAT3_RD = dst;
1015:
1016: TME_SPARC_INSN_OK;
1017: }
1018:
1019: /* the sparc32 sra function: */
1020: TME_SPARC_FORMAT3(tme_sparc32_sra, tme_uint32_t)
1021: {
1022: tme_int32_t dst;
1023: unsigned int count;
1024:
1025: /* get the value and the shift count: */
1026: dst = TME_SPARC_FORMAT3_RS1;
1027: count = TME_SPARC_FORMAT3_RS2;
1028:
1029: /* limit the count: */
1030: count %= 32;
1031:
1032: /* do the shift: */
1033: #ifdef SHIFTSIGNED_INT32_T
1034: #if (SHIFTMAX_INT32_T < (32 - 1))
1035: #error "cannot do full shifts of a tme_int32_t"
1036: #endif /* (SHIFTMAX_INT32_T < (32 - 1)) */
1037: dst >>= count;
1038: #else /* !SHIFTSIGNED_INT32_T */
1039: for (; count-- > 0; ) {
1040: dst = (dst & ~((tme_int32_t) 1)) / 2;
1041: }
1042: #endif /* !SHIFTSIGNED_INT32_T */
1043:
1044: /* store the destination: */
1045: TME_SPARC_FORMAT3_RD = dst;
1046:
1047: TME_SPARC_INSN_OK;
1048: }
1049:
1050: /* this does a sparc32 ldb: */
1051: TME_SPARC_FORMAT3(tme_sparc32_ldb, tme_uint32_t)
1052: {
1053: tme_uint32_t address;
1054: struct tme_sparc_tlb *dtlb;
1055: const tme_shared tme_uint8_t *memory;
1056: tme_uint32_t value;
1057:
1058: /* get the address: */
1059: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1060:
1061: #ifdef _TME_SPARC_STATS
1062: /* track statistics: */
1063: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1064: #endif /* _TME_SPARC_STATS */
1065:
1066: /* get and busy the DTLB entry: */
1067: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1068: tme_sparc_tlb_busy(dtlb);
1069:
1070: /* assume that this DTLB applies and allows fast transfers: */
1071: memory = dtlb->tme_sparc_tlb_emulator_off_read;
1072:
1073: /* we must call the slow load function if: */
1074: if (__tme_predict_false(
1075:
1076: /* the DTLB entry is invalid: */
1077: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1078:
1079: /* the DTLB entry does not cover the needed addresses: */
1080: || (dtlb->tme_sparc_tlb_addr_first > address)
1081: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1)))
1082:
1083: /* the DTLB entry does not cover the needed address space: */
1084: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1085:
1086: /* the DTLB entry does not allow fast transfers: */
1087: || (memory == TME_EMULATOR_OFF_UNDEF)
1088:
1089: )) {
1090:
1091: /* call the slow load function: */
1092: memory = tme_sparc32_load(ic,
1093: address,
1094: ((8 / 8)));
1095: }
1096:
1097: /* do the fast transfer: */
1098: memory += address;
1099: value = tme_memory_bus_read8((const tme_shared tme_uint8_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
1100:
1101: /* unbusy the DTLB entry: */
1102: tme_sparc_tlb_unbusy(dtlb);
1103:
1104: /* possibly sign-extend the loaded value: */
1105: if (TME_SPARC_INSN & TME_BIT(22)) {
1106: value = (tme_uint32_t) (tme_int32_t) (tme_int8_t) value;
1107: }
1108:
1109: /* set the loaded value: */
1110: TME_SPARC_FORMAT3_RD = value;
1111:
1112: /* log the value loaded: */
1113: tme_sparc_verify_mem8(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
1114: tme_sparc_log(ic, 1000, TME_OK,
1115: (TME_SPARC_LOG_HANDLE(ic),
1116: _("ldb\t0x%02x:0x%08x:\t0x%08x"),
1117: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1118: address,
1119: TME_SPARC_FORMAT3_RD));
1120:
1121: TME_SPARC_INSN_OK;
1122: }
1123:
1124: /* this does a sparc32 stb: */
1125: TME_SPARC_FORMAT3(tme_sparc32_stb, tme_uint32_t)
1126: {
1127: tme_uint32_t address;
1128: struct tme_sparc_tlb *dtlb;
1129: tme_shared tme_uint8_t *memory;
1130: tme_uint32_t value;
1131:
1132: /* get the address: */
1133: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1134:
1135: #ifdef _TME_SPARC_STATS
1136: /* track statistics: */
1137: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1138: #endif /* _TME_SPARC_STATS */
1139:
1140: /* log the value stored: */
1141: tme_sparc_verify_mem8(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);
1142: tme_sparc_log(ic, 1000, TME_OK,
1143: (TME_SPARC_LOG_HANDLE(ic),
1144: _("stb\t0x%02x:0x%08x:\t0x%02x"),
1145: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1146: address,
1147: (tme_uint8_t) TME_SPARC_FORMAT3_RD));
1148:
1149: /* get and busy the DTLB entry: */
1150: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1151: tme_sparc_tlb_busy(dtlb);
1152:
1153: /* assume that this DTLB applies and allows fast transfers: */
1154: memory = dtlb->tme_sparc_tlb_emulator_off_write;
1155:
1156: /* we must call the slow store function if: */
1157: if (__tme_predict_false(
1158:
1159: /* the DTLB entry is invalid: */
1160: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1161:
1162: /* the DTLB entry does not cover the needed addresses: */
1163: || (dtlb->tme_sparc_tlb_addr_first > address)
1164: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1)))
1165:
1166: /* the DTLB entry does not cover the needed address space: */
1167: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1168:
1169: /* the DTLB entry does not allow fast transfers: */
1170: || (memory == TME_EMULATOR_OFF_UNDEF)
1171:
1172: )) {
1173:
1174: /* call the slow store function: */
1175: memory = tme_sparc32_store(ic,
1176: address,
1177: &TME_SPARC_FORMAT3_RD,
1178: ((8 / 8)));
1179:
1180: /* if the slow store function did the transfer, return now: */
1181: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
1182: tme_sparc_tlb_unbusy(dtlb);
1183: TME_SPARC_INSN_OK;
1184: }
1185: }
1186:
1187: /* do the fast transfer: */
1188: memory += address;
1189: value = (TME_SPARC_FORMAT3_RD);
1190: tme_memory_bus_write8((tme_shared tme_uint8_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
1191:
1192: /* unbusy the DTLB entry: */
1193: tme_sparc_tlb_unbusy(dtlb);
1194:
1195: TME_SPARC_INSN_OK;
1196: }
1197:
1198: /* this does a sparc32 ldh: */
1199: TME_SPARC_FORMAT3(tme_sparc32_ldh, tme_uint32_t)
1200: {
1201: tme_uint32_t address;
1202: struct tme_sparc_tlb *dtlb;
1203: const tme_shared tme_uint8_t *memory;
1204: tme_uint32_t value;
1205:
1206: /* get the address: */
1207: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1208:
1209: #ifdef _TME_SPARC_STATS
1210: /* track statistics: */
1211: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1212: #endif /* _TME_SPARC_STATS */
1213:
1214: /* get and busy the DTLB entry: */
1215: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1216: tme_sparc_tlb_busy(dtlb);
1217:
1218: /* assume that this DTLB applies and allows fast transfers: */
1219: memory = dtlb->tme_sparc_tlb_emulator_off_read;
1220:
1221: /* we must call the slow load function if: */
1222: if (__tme_predict_false(
1223:
1224: /* the DTLB entry is invalid: */
1225: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1226:
1227: /* the DTLB entry does not cover the needed addresses: */
1228: || (dtlb->tme_sparc_tlb_addr_first > address)
1229: || (dtlb->tme_sparc_tlb_addr_last < (address + ((16 / 8) - 1)))
1230:
1231: /* the DTLB entry does not cover the needed address space: */
1232: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1233:
1234: /* the DTLB entry does not allow fast transfers: */
1235: || (memory == TME_EMULATOR_OFF_UNDEF)
1236:
1237: /* the address is misaligned: */
1238: || ((address % (16 / 8)) != 0)
1239:
1240: )) {
1241:
1242: /* call the slow load function: */
1243: memory = tme_sparc32_load(ic,
1244: address,
1245: ((16 / 8)));
1246: }
1247:
1248: /* do the fast transfer: */
1249: memory += address;
1250: value = tme_memory_bus_read16((const tme_shared tme_uint16_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t));
1251: value = tme_betoh_u16(value);
1252:
1253: /* unbusy the DTLB entry: */
1254: tme_sparc_tlb_unbusy(dtlb);
1255:
1256: /* possibly sign-extend the loaded value: */
1257: if (TME_SPARC_INSN & TME_BIT(22)) {
1258: value = (tme_uint32_t) (tme_int32_t) (tme_int16_t) value;
1259: }
1260:
1261: /* set the loaded value: */
1262: TME_SPARC_FORMAT3_RD = value;
1263:
1264: /* log the value loaded: */
1265: tme_sparc_verify_mem16(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint16_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
1266: tme_sparc_log(ic, 1000, TME_OK,
1267: (TME_SPARC_LOG_HANDLE(ic),
1268: _("ldh\t0x%02x:0x%08x:\t0x%08x"),
1269: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1270: address,
1271: TME_SPARC_FORMAT3_RD));
1272:
1273: TME_SPARC_INSN_OK;
1274: }
1275:
1276: /* this does a sparc32 sth: */
1277: TME_SPARC_FORMAT3(tme_sparc32_sth, tme_uint32_t)
1278: {
1279: tme_uint32_t address;
1280: struct tme_sparc_tlb *dtlb;
1281: tme_shared tme_uint8_t *memory;
1282: tme_uint32_t value;
1283:
1284: /* get the address: */
1285: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1286:
1287: #ifdef _TME_SPARC_STATS
1288: /* track statistics: */
1289: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1290: #endif /* _TME_SPARC_STATS */
1291:
1292: /* log the value stored: */
1293: tme_sparc_verify_mem16(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint16_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);
1294: tme_sparc_log(ic, 1000, TME_OK,
1295: (TME_SPARC_LOG_HANDLE(ic),
1296: _("sth\t0x%02x:0x%08x:\t0x%04x"),
1297: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1298: address,
1299: (tme_uint16_t) TME_SPARC_FORMAT3_RD));
1300:
1301: /* get and busy the DTLB entry: */
1302: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1303: tme_sparc_tlb_busy(dtlb);
1304:
1305: /* assume that this DTLB applies and allows fast transfers: */
1306: memory = dtlb->tme_sparc_tlb_emulator_off_write;
1307:
1308: /* we must call the slow store function if: */
1309: if (__tme_predict_false(
1310:
1311: /* the DTLB entry is invalid: */
1312: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1313:
1314: /* the DTLB entry does not cover the needed addresses: */
1315: || (dtlb->tme_sparc_tlb_addr_first > address)
1316: || (dtlb->tme_sparc_tlb_addr_last < (address + ((16 / 8) - 1)))
1317:
1318: /* the DTLB entry does not cover the needed address space: */
1319: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1320:
1321: /* the DTLB entry does not allow fast transfers: */
1322: || (memory == TME_EMULATOR_OFF_UNDEF)
1323:
1324: /* the address is misaligned: */
1325: || ((address % (16 / 8)) != 0)
1326:
1327: )) {
1328:
1329: /* call the slow store function: */
1330: memory = tme_sparc32_store(ic,
1331: address,
1332: &TME_SPARC_FORMAT3_RD,
1333: ((16 / 8)));
1334:
1335: /* if the slow store function did the transfer, return now: */
1336: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
1337: tme_sparc_tlb_unbusy(dtlb);
1338: TME_SPARC_INSN_OK;
1339: }
1340: }
1341:
1342: /* do the fast transfer: */
1343: memory += address;
1344: value = tme_htobe_u16(TME_SPARC_FORMAT3_RD);
1345: tme_memory_bus_write16((tme_shared tme_uint16_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t));
1346:
1347: /* unbusy the DTLB entry: */
1348: tme_sparc_tlb_unbusy(dtlb);
1349:
1350: TME_SPARC_INSN_OK;
1351: }
1352:
1353: /* this does a sparc32 ld: */
1354: TME_SPARC_FORMAT3(tme_sparc32_ld, tme_uint32_t)
1355: {
1356: tme_uint32_t address;
1357: struct tme_sparc_tlb *dtlb;
1358: const tme_shared tme_uint8_t *memory;
1359: tme_uint32_t value;
1360:
1361: /* get the address: */
1362: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1363:
1364: #ifdef _TME_SPARC_STATS
1365: /* track statistics: */
1366: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1367: #endif /* _TME_SPARC_STATS */
1368:
1369: /* get and busy the DTLB entry: */
1370: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1371: tme_sparc_tlb_busy(dtlb);
1372:
1373: /* assume that this DTLB applies and allows fast transfers: */
1374: memory = dtlb->tme_sparc_tlb_emulator_off_read;
1375:
1376: /* we must call the slow load function if: */
1377: if (__tme_predict_false(
1378:
1379: /* the DTLB entry is invalid: */
1380: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1381:
1382: /* the DTLB entry does not cover the needed addresses: */
1383: || (dtlb->tme_sparc_tlb_addr_first > address)
1384: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1)))
1385:
1386: /* the DTLB entry does not cover the needed address space: */
1387: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1388:
1389: /* the DTLB entry does not allow fast transfers: */
1390: || (memory == TME_EMULATOR_OFF_UNDEF)
1391:
1392: /* the address is misaligned: */
1393: || ((address % (32 / 8)) != 0)
1394:
1395: )) {
1396:
1397: /* call the slow load function: */
1398: memory = tme_sparc32_load(ic,
1399: address,
1400: ((32 / 8)));
1401: }
1402:
1403: /* do the fast transfer: */
1404: memory += address;
1405: value = tme_memory_bus_read32((const tme_shared tme_uint32_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t));
1406: value = tme_betoh_u32(value);
1407:
1408: /* unbusy the DTLB entry: */
1409: tme_sparc_tlb_unbusy(dtlb);
1410:
1411: /* set the loaded value: */
1412: TME_SPARC_FORMAT3_RD = value;
1413:
1414: /* log the value loaded: */
1415: tme_sparc_verify_mem32(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
1416: tme_sparc_log(ic, 1000, TME_OK,
1417: (TME_SPARC_LOG_HANDLE(ic),
1418: _("ld\t0x%02x:0x%08x:\t0x%08x"),
1419: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1420: address,
1421: TME_SPARC_FORMAT3_RD));
1422:
1423: TME_SPARC_INSN_OK;
1424: }
1425:
1426: /* this does a sparc32 st: */
1427: TME_SPARC_FORMAT3(tme_sparc32_st, tme_uint32_t)
1428: {
1429: tme_uint32_t address;
1430: struct tme_sparc_tlb *dtlb;
1431: tme_shared tme_uint8_t *memory;
1432: tme_uint32_t value;
1433:
1434: /* get the address: */
1435: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1436:
1437: #ifdef _TME_SPARC_STATS
1438: /* track statistics: */
1439: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1440: #endif /* _TME_SPARC_STATS */
1441:
1442: /* log the value stored: */
1443: tme_sparc_verify_mem32(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);
1444: tme_sparc_log(ic, 1000, TME_OK,
1445: (TME_SPARC_LOG_HANDLE(ic),
1446: _("st\t0x%02x:0x%08x:\t0x%08x"),
1447: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1448: address,
1449: (tme_uint32_t) TME_SPARC_FORMAT3_RD));
1450:
1451: /* get and busy the DTLB entry: */
1452: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1453: tme_sparc_tlb_busy(dtlb);
1454:
1455: /* assume that this DTLB applies and allows fast transfers: */
1456: memory = dtlb->tme_sparc_tlb_emulator_off_write;
1457:
1458: /* we must call the slow store function if: */
1459: if (__tme_predict_false(
1460:
1461: /* the DTLB entry is invalid: */
1462: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1463:
1464: /* the DTLB entry does not cover the needed addresses: */
1465: || (dtlb->tme_sparc_tlb_addr_first > address)
1466: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1)))
1467:
1468: /* the DTLB entry does not cover the needed address space: */
1469: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1470:
1471: /* the DTLB entry does not allow fast transfers: */
1472: || (memory == TME_EMULATOR_OFF_UNDEF)
1473:
1474: /* the address is misaligned: */
1475: || ((address % (32 / 8)) != 0)
1476:
1477: )) {
1478:
1479: /* call the slow store function: */
1480: memory = tme_sparc32_store(ic,
1481: address,
1482: &TME_SPARC_FORMAT3_RD,
1483: ((32 / 8)));
1484:
1485: /* if the slow store function did the transfer, return now: */
1486: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
1487: tme_sparc_tlb_unbusy(dtlb);
1488: TME_SPARC_INSN_OK;
1489: }
1490: }
1491:
1492: /* do the fast transfer: */
1493: memory += address;
1494: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD);
1495: tme_memory_bus_write32((tme_shared tme_uint32_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t));
1496:
1497: /* unbusy the DTLB entry: */
1498: tme_sparc_tlb_unbusy(dtlb);
1499:
1500: TME_SPARC_INSN_OK;
1501: }
1502:
1503: /* this does a sparc32 ldd: */
1504: TME_SPARC_FORMAT3(tme_sparc32_ldd, tme_uint32_t)
1505: {
1506: tme_uint32_t address;
1507: struct tme_sparc_tlb *dtlb;
1508: const tme_shared tme_uint8_t *memory;
1509: tme_uint32_t value;
1510:
1511: /* get the address: */
1512: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1513:
1514: #ifdef _TME_SPARC_STATS
1515: /* track statistics: */
1516: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1517: #endif /* _TME_SPARC_STATS */
1518:
1519: /* get and busy the DTLB entry: */
1520: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1521: tme_sparc_tlb_busy(dtlb);
1522:
1523: /* assume that this DTLB applies and allows fast transfers: */
1524: memory = dtlb->tme_sparc_tlb_emulator_off_read;
1525:
1526: /* we must call the slow load function if: */
1527: if (__tme_predict_false(
1528:
1529: /* the DTLB entry is invalid: */
1530: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1531:
1532: /* the DTLB entry does not cover the needed addresses: */
1533: || (dtlb->tme_sparc_tlb_addr_first > address)
1534: || (dtlb->tme_sparc_tlb_addr_last < (address + ((64 / 8) - 1)))
1535:
1536: /* the DTLB entry does not cover the needed address space: */
1537: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1538:
1539: /* the DTLB entry does not allow fast transfers: */
1540: || (memory == TME_EMULATOR_OFF_UNDEF)
1541:
1542: /* the address is misaligned: */
1543: || ((address % (64 / 8)) != 0)
1544:
1545: /* the destination register number is odd: */
1546: || ((TME_SPARC_INSN & TME_BIT(25)) != 0)
1547:
1548: )) {
1549:
1550: /* call the slow load function: */
1551: memory = tme_sparc32_load(ic,
1552: address,
1553: ((64 / 8)));
1554: }
1555:
1556: /* do the fast transfer: */
1557: memory += address;
1558: value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 0, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint32_t));
1559: TME_SPARC_FORMAT3_RD = tme_betoh_u32(value);
1560: value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 1, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t));
1561: TME_SPARC_FORMAT3_RD_ODD = tme_betoh_u32(value);
1562:
1563: /* unbusy the DTLB entry: */
1564: tme_sparc_tlb_unbusy(dtlb);
1565:
1566: /* log the value loaded: */
1567: tme_sparc_log(ic, 1000, TME_OK,
1568: (TME_SPARC_LOG_HANDLE(ic),
1569: _("ldd\t0x%02x:0x%08x:\t0x%08x 0x%08x"),
1570: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1571: address,
1572: (tme_uint32_t) TME_SPARC_FORMAT3_RD,
1573: (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD));
1574:
1575: TME_SPARC_INSN_OK;
1576: }
1577:
1578: /* this does a sparc32 std: */
1579: TME_SPARC_FORMAT3(tme_sparc32_std, tme_uint32_t)
1580: {
1581: tme_uint32_t address;
1582: struct tme_sparc_tlb *dtlb;
1583: tme_shared tme_uint8_t *memory;
1584: tme_uint32_t value;
1585:
1586: /* get the address: */
1587: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1588:
1589: #ifdef _TME_SPARC_STATS
1590: /* track statistics: */
1591: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1592: #endif /* _TME_SPARC_STATS */
1593:
1594: /* log the values stored: */
1595: tme_sparc_log(ic, 1000, TME_OK,
1596: (TME_SPARC_LOG_HANDLE(ic),
1597: _("std\t0x%02x:0x%08x:\t0x%08x 0x%08x"),
1598: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1599: address,
1600: (tme_uint32_t) TME_SPARC_FORMAT3_RD,
1601: (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD));
1602:
1603: /* get and busy the DTLB entry: */
1604: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1605: tme_sparc_tlb_busy(dtlb);
1606:
1607: /* assume that this DTLB applies and allows fast transfers: */
1608: memory = dtlb->tme_sparc_tlb_emulator_off_write;
1609:
1610: /* we must call the slow store function if: */
1611: if (__tme_predict_false(
1612:
1613: /* the DTLB entry is invalid: */
1614: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1615:
1616: /* the DTLB entry does not cover the needed addresses: */
1617: || (dtlb->tme_sparc_tlb_addr_first > address)
1618: || (dtlb->tme_sparc_tlb_addr_last < (address + ((64 / 8) - 1)))
1619:
1620: /* the DTLB entry does not cover the needed address space: */
1621: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1622:
1623: /* the DTLB entry does not allow fast transfers: */
1624: || (memory == TME_EMULATOR_OFF_UNDEF)
1625:
1626: /* the address is misaligned: */
1627: || ((address % (64 / 8)) != 0)
1628:
1629: /* the destination register number is odd: */
1630: || ((TME_SPARC_INSN & TME_BIT(25)) != 0)
1631:
1632: )) {
1633:
1634: /* call the slow store function: */
1635: memory = tme_sparc32_store(ic,
1636: address,
1637: &TME_SPARC_FORMAT3_RD,
1638: ((64 / 8)));
1639:
1640: /* if the slow store function did the transfer, return now: */
1641: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
1642: tme_sparc_tlb_unbusy(dtlb);
1643: TME_SPARC_INSN_OK;
1644: }
1645: }
1646:
1647: /* do the fast transfer: */
1648: memory += address;
1649: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD);
1650: tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 0, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint32_t));
1651: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD_ODD);
1652: tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 1, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t));
1653:
1654: /* unbusy the DTLB entry: */
1655: tme_sparc_tlb_unbusy(dtlb);
1656:
1657: TME_SPARC_INSN_OK;
1658: }
1659:
1660: /* this does a sparc32 ldstub: */
1661: TME_SPARC_FORMAT3(tme_sparc32_ldstub, tme_uint32_t)
1662: {
1663: tme_uint32_t address;
1664: struct tme_sparc_tlb *dtlb;
1665: tme_shared tme_uint8_t *memory;
1666: tme_uint32_t value;
1667:
1668: /* get the address: */
1669: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1670:
1671: #ifdef _TME_SPARC_STATS
1672: /* track statistics: */
1673: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1674: #endif /* _TME_SPARC_STATS */
1675:
1676: /* get and busy the DTLB entry: */
1677: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1678: tme_sparc_tlb_busy(dtlb);
1679:
1680: /* assume that this DTLB applies and allows fast transfers: */
1681: memory = dtlb->tme_sparc_tlb_emulator_off_write;
1682:
1683: /* we must call the slow store function if: */
1684: if (__tme_predict_false(
1685:
1686: /* the DTLB entry is invalid: */
1687: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1688:
1689: /* the DTLB entry does not cover the needed addresses: */
1690: || (dtlb->tme_sparc_tlb_addr_first > address)
1691: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1)))
1692:
1693: /* the DTLB entry does not cover the needed address space: */
1694: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1695:
1696: /* the DTLB entry does not allow fast transfers: */
1697: || (memory != dtlb->tme_sparc_tlb_emulator_off_read)
1698: || (memory == TME_EMULATOR_OFF_UNDEF)
1699:
1700: )) {
1701:
1702: /* call the slow store function: */
1703: memory = tme_sparc32_store(ic,
1704: address,
1705: &TME_SPARC_FORMAT3_RD,
1706: (TME_SPARC_SLOW_FLAG_ATOMIC
1707: | (8 / 8)));
1708:
1709: /* if the slow store function did the transfer, return now: */
1710: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
1711: tme_sparc_tlb_unbusy(dtlb);
1712: TME_SPARC_INSN_OK;
1713: }
1714: }
1715:
1716: /* do the fast transfer: */
1717: memory += address;
1718: value = tme_memory_atomic_xchg8(memory, 0xff, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t));
1719:
1720: /* unbusy the DTLB entry: */
1721: tme_sparc_tlb_unbusy(dtlb);
1722:
1723: /* possibly sign-extend the loaded value: */
1724: if (TME_SPARC_INSN & TME_BIT(22)) {
1725: value = (tme_uint32_t) (tme_int32_t) (tme_int8_t) value;
1726: }
1727:
1728: /* set the loaded value: */
1729: TME_SPARC_FORMAT3_RD = value;
1730:
1731: /* log the value loaded: */
1732: tme_sparc_verify_mem8(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
1733: tme_sparc_log(ic, 1000, TME_OK,
1734: (TME_SPARC_LOG_HANDLE(ic),
1735: _("ldstub\t0x%02x:0x%08x:\t0x%08x"),
1736: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1737: address,
1738: TME_SPARC_FORMAT3_RD));
1739:
1740: TME_SPARC_INSN_OK;
1741: }
1742:
1743: /* this does a sparc32 ldstuba: */
1744: TME_SPARC_FORMAT3(tme_sparc32_ldstuba, tme_uint32_t)
1745: {
1746: tme_uint32_t asi_mask_data;
1747: tme_uint32_t address;
1748: struct tme_sparc_tlb *dtlb;
1749: tme_shared tme_uint8_t *memory;
1750: tme_uint32_t value;
1751:
1752: /* get the alternate ASI mask: */
1753: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
1754:
1755: /* get the address: */
1756: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1757:
1758: #ifdef _TME_SPARC_STATS
1759: /* track statistics: */
1760: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1761: #endif /* _TME_SPARC_STATS */
1762:
1763: /* get and busy the DTLB entry: */
1764: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1765: tme_sparc_tlb_busy(dtlb);
1766:
1767: /* assume that this DTLB applies and allows fast transfers: */
1768: memory = dtlb->tme_sparc_tlb_emulator_off_write;
1769:
1770: /* we must call the slow store function if: */
1771: if (__tme_predict_false(
1772:
1773: /* the DTLB entry is invalid: */
1774: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1775:
1776: /* the DTLB entry does not cover the needed addresses: */
1777: || (dtlb->tme_sparc_tlb_addr_first > address)
1778: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1)))
1779:
1780: /* the DTLB entry does not cover the needed address space: */
1781: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
1782:
1783: /* the DTLB entry does not allow fast transfers: */
1784: || (memory != dtlb->tme_sparc_tlb_emulator_off_read)
1785: || (memory == TME_EMULATOR_OFF_UNDEF)
1786:
1787: )) {
1788:
1789: /* call the slow store function: */
1790: memory = tme_sparc32_store(ic,
1791: address,
1792: &TME_SPARC_FORMAT3_RD,
1793: (TME_SPARC_SLOW_FLAG_ATOMIC
1794: | TME_SPARC_SLOW_FLAG_A
1795: | (8 / 8)));
1796:
1797: /* if the slow store function did the transfer, return now: */
1798: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
1799: tme_sparc_tlb_unbusy(dtlb);
1800: TME_SPARC_INSN_OK;
1801: }
1802: }
1803:
1804: /* do the fast transfer: */
1805: memory += address;
1806: value = tme_memory_atomic_xchg8(memory, 0xff, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t));
1807:
1808: /* unbusy the DTLB entry: */
1809: tme_sparc_tlb_unbusy(dtlb);
1810:
1811: /* possibly sign-extend the loaded value: */
1812: if (TME_SPARC_INSN & TME_BIT(22)) {
1813: value = (tme_uint32_t) (tme_int32_t) (tme_int8_t) value;
1814: }
1815:
1816: /* set the loaded value: */
1817: TME_SPARC_FORMAT3_RD = value;
1818:
1819: /* log the value loaded: */
1820: tme_sparc_verify_mem8(ic, asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
1821: tme_sparc_log(ic, 1000, TME_OK,
1822: (TME_SPARC_LOG_HANDLE(ic),
1823: _("ldstuba\t0x%02x:0x%08x:\t0x%08x"),
1824: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
1825: address,
1826: TME_SPARC_FORMAT3_RD));
1827:
1828: TME_SPARC_INSN_OK;
1829: }
1830:
1831: /* this does a sparc32 swap: */
1832: TME_SPARC_FORMAT3(tme_sparc32_swap, tme_uint32_t)
1833: {
1834: tme_uint32_t address;
1835: struct tme_sparc_tlb *dtlb;
1836: tme_shared tme_uint8_t *memory;
1837: tme_uint32_t value;
1838:
1839: /* get the address: */
1840: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1841:
1842: #ifdef _TME_SPARC_STATS
1843: /* track statistics: */
1844: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1845: #endif /* _TME_SPARC_STATS */
1846:
1847: /* log the value stored: */
1848: tme_sparc_verify_mem32(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);
1849: tme_sparc_log(ic, 1000, TME_OK,
1850: (TME_SPARC_LOG_HANDLE(ic),
1851: _("swap\t0x%02x:0x%08x:\t0x%08x"),
1852: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1853: address,
1854: (tme_uint32_t) TME_SPARC_FORMAT3_RD));
1855:
1856: /* get and busy the DTLB entry: */
1857: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1858: tme_sparc_tlb_busy(dtlb);
1859:
1860: /* assume that this DTLB applies and allows fast transfers: */
1861: memory = dtlb->tme_sparc_tlb_emulator_off_write;
1862:
1863: /* we must call the slow store function if: */
1864: if (__tme_predict_false(
1865:
1866: /* the DTLB entry is invalid: */
1867: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1868:
1869: /* the DTLB entry does not cover the needed addresses: */
1870: || (dtlb->tme_sparc_tlb_addr_first > address)
1871: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1)))
1872:
1873: /* the DTLB entry does not cover the needed address space: */
1874: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, ic->tme_sparc_asi_mask_data))
1875:
1876: /* the DTLB entry does not allow fast transfers: */
1877: || (memory != dtlb->tme_sparc_tlb_emulator_off_read)
1878: || (memory == TME_EMULATOR_OFF_UNDEF)
1879:
1880: /* the address is misaligned: */
1881: || ((address % (32 / 8)) != 0)
1882:
1883: )) {
1884:
1885: /* call the slow store function: */
1886: memory = tme_sparc32_store(ic,
1887: address,
1888: &TME_SPARC_FORMAT3_RD,
1889: (TME_SPARC_SLOW_FLAG_ATOMIC
1890: | (32 / 8)));
1891:
1892: /* if the slow store function did the transfer, return now: */
1893: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
1894: tme_sparc_tlb_unbusy(dtlb);
1895: TME_SPARC_INSN_OK;
1896: }
1897: }
1898:
1899: /* do the fast transfer: */
1900: memory += address;
1901: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD);
1902: value = tme_memory_atomic_xchg32((tme_shared tme_uint32_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t));
1903:
1904: /* unbusy the DTLB entry: */
1905: tme_sparc_tlb_unbusy(dtlb);
1906:
1907: /* set the loaded value: */
1908: TME_SPARC_FORMAT3_RD = value;
1909:
1910: /* log the value loaded: */
1911: tme_sparc_verify_mem32(ic, ic->tme_sparc_asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
1912: tme_sparc_log(ic, 1000, TME_OK,
1913: (TME_SPARC_LOG_HANDLE(ic),
1914: _("swap\t0x%02x:0x%08x:\t0x%08x"),
1915: TME_SPARC_ASI_MASK_WHICH(ic->tme_sparc_asi_mask_data),
1916: address,
1917: TME_SPARC_FORMAT3_RD));
1918:
1919: TME_SPARC_INSN_OK;
1920: }
1921:
1922: /* this does a sparc32 swapa: */
1923: TME_SPARC_FORMAT3(tme_sparc32_swapa, tme_uint32_t)
1924: {
1925: tme_uint32_t asi_mask_data;
1926: tme_uint32_t address;
1927: struct tme_sparc_tlb *dtlb;
1928: tme_shared tme_uint8_t *memory;
1929: tme_uint32_t value;
1930:
1931: /* get the alternate ASI mask: */
1932: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
1933:
1934: /* get the address: */
1935: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
1936:
1937: #ifdef _TME_SPARC_STATS
1938: /* track statistics: */
1939: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
1940: #endif /* _TME_SPARC_STATS */
1941:
1942: /* log the value stored: */
1943: tme_sparc_verify_mem32(ic, asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);
1944: tme_sparc_log(ic, 1000, TME_OK,
1945: (TME_SPARC_LOG_HANDLE(ic),
1946: _("swapa\t0x%02x:0x%08x:\t0x%08x"),
1947: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
1948: address,
1949: (tme_uint32_t) TME_SPARC_FORMAT3_RD));
1950:
1951: /* get and busy the DTLB entry: */
1952: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
1953: tme_sparc_tlb_busy(dtlb);
1954:
1955: /* assume that this DTLB applies and allows fast transfers: */
1956: memory = dtlb->tme_sparc_tlb_emulator_off_write;
1957:
1958: /* we must call the slow store function if: */
1959: if (__tme_predict_false(
1960:
1961: /* the DTLB entry is invalid: */
1962: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
1963:
1964: /* the DTLB entry does not cover the needed addresses: */
1965: || (dtlb->tme_sparc_tlb_addr_first > address)
1966: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1)))
1967:
1968: /* the DTLB entry does not cover the needed address space: */
1969: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
1970:
1971: /* the DTLB entry does not allow fast transfers: */
1972: || (memory != dtlb->tme_sparc_tlb_emulator_off_read)
1973: || (memory == TME_EMULATOR_OFF_UNDEF)
1974:
1975: /* the address is misaligned: */
1976: || ((address % (32 / 8)) != 0)
1977:
1978: )) {
1979:
1980: /* call the slow store function: */
1981: memory = tme_sparc32_store(ic,
1982: address,
1983: &TME_SPARC_FORMAT3_RD,
1984: (TME_SPARC_SLOW_FLAG_ATOMIC
1985: | TME_SPARC_SLOW_FLAG_A
1986: | (32 / 8)));
1987:
1988: /* if the slow store function did the transfer, return now: */
1989: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
1990: tme_sparc_tlb_unbusy(dtlb);
1991: TME_SPARC_INSN_OK;
1992: }
1993: }
1994:
1995: /* do the fast transfer: */
1996: memory += address;
1997: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD);
1998: value = tme_memory_atomic_xchg32((tme_shared tme_uint32_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t));
1999:
2000: /* unbusy the DTLB entry: */
2001: tme_sparc_tlb_unbusy(dtlb);
2002:
2003: /* set the loaded value: */
2004: TME_SPARC_FORMAT3_RD = value;
2005:
2006: /* log the value loaded: */
2007: tme_sparc_verify_mem32(ic, asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
2008: tme_sparc_log(ic, 1000, TME_OK,
2009: (TME_SPARC_LOG_HANDLE(ic),
2010: _("swapa\t0x%02x:0x%08x:\t0x%08x"),
2011: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2012: address,
2013: TME_SPARC_FORMAT3_RD));
2014:
2015: TME_SPARC_INSN_OK;
2016: }
2017:
2018: /* this does a sparc32 ldba: */
2019: TME_SPARC_FORMAT3(tme_sparc32_ldba, tme_uint32_t)
2020: {
2021: tme_uint32_t asi_mask_data;
2022: tme_uint32_t address;
2023: struct tme_sparc_tlb *dtlb;
2024: const tme_shared tme_uint8_t *memory;
2025: tme_uint32_t value;
2026:
2027: /* get the alternate ASI mask: */
2028: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2029:
2030: /* get the address: */
2031: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2032:
2033: #ifdef _TME_SPARC_STATS
2034: /* track statistics: */
2035: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
2036: #endif /* _TME_SPARC_STATS */
2037:
2038: /* get and busy the DTLB entry: */
2039: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2040: tme_sparc_tlb_busy(dtlb);
2041:
2042: /* assume that this DTLB applies and allows fast transfers: */
2043: memory = dtlb->tme_sparc_tlb_emulator_off_read;
2044:
2045: /* we must call the slow load function if: */
2046: if (__tme_predict_false(
2047:
2048: /* the DTLB entry is invalid: */
2049: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2050:
2051: /* the DTLB entry does not cover the needed addresses: */
2052: || (dtlb->tme_sparc_tlb_addr_first > address)
2053: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1)))
2054:
2055: /* the DTLB entry does not cover the needed address space: */
2056: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2057:
2058: /* the DTLB entry does not allow fast transfers: */
2059: || (memory == TME_EMULATOR_OFF_UNDEF)
2060:
2061: )) {
2062:
2063: /* call the slow load function: */
2064: memory = tme_sparc32_load(ic,
2065: address,
2066: (TME_SPARC_SLOW_FLAG_A
2067: | (8 / 8)));
2068: }
2069:
2070: /* do the fast transfer: */
2071: memory += address;
2072: value = tme_memory_bus_read8((const tme_shared tme_uint8_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
2073:
2074: /* unbusy the DTLB entry: */
2075: tme_sparc_tlb_unbusy(dtlb);
2076:
2077: /* possibly sign-extend the loaded value: */
2078: if (TME_SPARC_INSN & TME_BIT(22)) {
2079: value = (tme_uint32_t) (tme_int32_t) (tme_int8_t) value;
2080: }
2081:
2082: /* set the loaded value: */
2083: TME_SPARC_FORMAT3_RD = value;
2084:
2085: /* log the value loaded: */
2086: tme_sparc_verify_mem8(ic, asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
2087: tme_sparc_log(ic, 1000, TME_OK,
2088: (TME_SPARC_LOG_HANDLE(ic),
2089: _("ldba\t0x%02x:0x%08x:\t0x%08x"),
2090: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2091: address,
2092: TME_SPARC_FORMAT3_RD));
2093:
2094: TME_SPARC_INSN_OK;
2095: }
2096:
2097: /* this does a sparc32 stba: */
2098: TME_SPARC_FORMAT3(tme_sparc32_stba, tme_uint32_t)
2099: {
2100: tme_uint32_t asi_mask_data;
2101: tme_uint32_t address;
2102: struct tme_sparc_tlb *dtlb;
2103: tme_shared tme_uint8_t *memory;
2104: tme_uint32_t value;
2105:
2106: /* get the alternate ASI mask: */
2107: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2108:
2109: /* get the address: */
2110: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2111:
2112: #ifdef _TME_SPARC_STATS
2113: /* track statistics: */
2114: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
2115: #endif /* _TME_SPARC_STATS */
2116:
2117: /* log the value stored: */
2118: tme_sparc_verify_mem8(ic, asi_mask_data, address, (tme_uint8_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);
2119: tme_sparc_log(ic, 1000, TME_OK,
2120: (TME_SPARC_LOG_HANDLE(ic),
2121: _("stba\t0x%02x:0x%08x:\t0x%02x"),
2122: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2123: address,
2124: (tme_uint8_t) TME_SPARC_FORMAT3_RD));
2125:
2126: /* get and busy the DTLB entry: */
2127: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2128: tme_sparc_tlb_busy(dtlb);
2129:
2130: /* assume that this DTLB applies and allows fast transfers: */
2131: memory = dtlb->tme_sparc_tlb_emulator_off_write;
2132:
2133: /* we must call the slow store function if: */
2134: if (__tme_predict_false(
2135:
2136: /* the DTLB entry is invalid: */
2137: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2138:
2139: /* the DTLB entry does not cover the needed addresses: */
2140: || (dtlb->tme_sparc_tlb_addr_first > address)
2141: || (dtlb->tme_sparc_tlb_addr_last < (address + ((8 / 8) - 1)))
2142:
2143: /* the DTLB entry does not cover the needed address space: */
2144: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2145:
2146: /* the DTLB entry does not allow fast transfers: */
2147: || (memory == TME_EMULATOR_OFF_UNDEF)
2148:
2149: )) {
2150:
2151: /* call the slow store function: */
2152: memory = tme_sparc32_store(ic,
2153: address,
2154: &TME_SPARC_FORMAT3_RD,
2155: (TME_SPARC_SLOW_FLAG_A
2156: | (8 / 8)));
2157:
2158: /* if the slow store function did the transfer, return now: */
2159: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
2160: tme_sparc_tlb_unbusy(dtlb);
2161: TME_SPARC_INSN_OK;
2162: }
2163: }
2164:
2165: /* do the fast transfer: */
2166: memory += address;
2167: value = (TME_SPARC_FORMAT3_RD);
2168: tme_memory_bus_write8((tme_shared tme_uint8_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint8_t), sizeof(tme_uint32_t));
2169:
2170: /* unbusy the DTLB entry: */
2171: tme_sparc_tlb_unbusy(dtlb);
2172:
2173: TME_SPARC_INSN_OK;
2174: }
2175:
2176: /* this does a sparc32 ldha: */
2177: TME_SPARC_FORMAT3(tme_sparc32_ldha, tme_uint32_t)
2178: {
2179: tme_uint32_t asi_mask_data;
2180: tme_uint32_t address;
2181: struct tme_sparc_tlb *dtlb;
2182: const tme_shared tme_uint8_t *memory;
2183: tme_uint32_t value;
2184:
2185: /* get the alternate ASI mask: */
2186: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2187:
2188: /* get the address: */
2189: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2190:
2191: #ifdef _TME_SPARC_STATS
2192: /* track statistics: */
2193: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
2194: #endif /* _TME_SPARC_STATS */
2195:
2196: /* get and busy the DTLB entry: */
2197: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2198: tme_sparc_tlb_busy(dtlb);
2199:
2200: /* assume that this DTLB applies and allows fast transfers: */
2201: memory = dtlb->tme_sparc_tlb_emulator_off_read;
2202:
2203: /* we must call the slow load function if: */
2204: if (__tme_predict_false(
2205:
2206: /* the DTLB entry is invalid: */
2207: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2208:
2209: /* the DTLB entry does not cover the needed addresses: */
2210: || (dtlb->tme_sparc_tlb_addr_first > address)
2211: || (dtlb->tme_sparc_tlb_addr_last < (address + ((16 / 8) - 1)))
2212:
2213: /* the DTLB entry does not cover the needed address space: */
2214: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2215:
2216: /* the DTLB entry does not allow fast transfers: */
2217: || (memory == TME_EMULATOR_OFF_UNDEF)
2218:
2219: /* the address is misaligned: */
2220: || ((address % (16 / 8)) != 0)
2221:
2222: )) {
2223:
2224: /* call the slow load function: */
2225: memory = tme_sparc32_load(ic,
2226: address,
2227: (TME_SPARC_SLOW_FLAG_A
2228: | (16 / 8)));
2229: }
2230:
2231: /* do the fast transfer: */
2232: memory += address;
2233: value = tme_memory_bus_read16((const tme_shared tme_uint16_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t));
2234: value = tme_betoh_u16(value);
2235:
2236: /* unbusy the DTLB entry: */
2237: tme_sparc_tlb_unbusy(dtlb);
2238:
2239: /* possibly sign-extend the loaded value: */
2240: if (TME_SPARC_INSN & TME_BIT(22)) {
2241: value = (tme_uint32_t) (tme_int32_t) (tme_int16_t) value;
2242: }
2243:
2244: /* set the loaded value: */
2245: TME_SPARC_FORMAT3_RD = value;
2246:
2247: /* log the value loaded: */
2248: tme_sparc_verify_mem16(ic, asi_mask_data, address, (tme_uint16_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
2249: tme_sparc_log(ic, 1000, TME_OK,
2250: (TME_SPARC_LOG_HANDLE(ic),
2251: _("ldha\t0x%02x:0x%08x:\t0x%08x"),
2252: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2253: address,
2254: TME_SPARC_FORMAT3_RD));
2255:
2256: TME_SPARC_INSN_OK;
2257: }
2258:
2259: /* this does a sparc32 stha: */
2260: TME_SPARC_FORMAT3(tme_sparc32_stha, tme_uint32_t)
2261: {
2262: tme_uint32_t asi_mask_data;
2263: tme_uint32_t address;
2264: struct tme_sparc_tlb *dtlb;
2265: tme_shared tme_uint8_t *memory;
2266: tme_uint32_t value;
2267:
2268: /* get the alternate ASI mask: */
2269: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2270:
2271: /* get the address: */
2272: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2273:
2274: #ifdef _TME_SPARC_STATS
2275: /* track statistics: */
2276: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
2277: #endif /* _TME_SPARC_STATS */
2278:
2279: /* log the value stored: */
2280: tme_sparc_verify_mem16(ic, asi_mask_data, address, (tme_uint16_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);
2281: tme_sparc_log(ic, 1000, TME_OK,
2282: (TME_SPARC_LOG_HANDLE(ic),
2283: _("stha\t0x%02x:0x%08x:\t0x%04x"),
2284: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2285: address,
2286: (tme_uint16_t) TME_SPARC_FORMAT3_RD));
2287:
2288: /* get and busy the DTLB entry: */
2289: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2290: tme_sparc_tlb_busy(dtlb);
2291:
2292: /* assume that this DTLB applies and allows fast transfers: */
2293: memory = dtlb->tme_sparc_tlb_emulator_off_write;
2294:
2295: /* we must call the slow store function if: */
2296: if (__tme_predict_false(
2297:
2298: /* the DTLB entry is invalid: */
2299: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2300:
2301: /* the DTLB entry does not cover the needed addresses: */
2302: || (dtlb->tme_sparc_tlb_addr_first > address)
2303: || (dtlb->tme_sparc_tlb_addr_last < (address + ((16 / 8) - 1)))
2304:
2305: /* the DTLB entry does not cover the needed address space: */
2306: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2307:
2308: /* the DTLB entry does not allow fast transfers: */
2309: || (memory == TME_EMULATOR_OFF_UNDEF)
2310:
2311: /* the address is misaligned: */
2312: || ((address % (16 / 8)) != 0)
2313:
2314: )) {
2315:
2316: /* call the slow store function: */
2317: memory = tme_sparc32_store(ic,
2318: address,
2319: &TME_SPARC_FORMAT3_RD,
2320: (TME_SPARC_SLOW_FLAG_A
2321: | (16 / 8)));
2322:
2323: /* if the slow store function did the transfer, return now: */
2324: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
2325: tme_sparc_tlb_unbusy(dtlb);
2326: TME_SPARC_INSN_OK;
2327: }
2328: }
2329:
2330: /* do the fast transfer: */
2331: memory += address;
2332: value = tme_htobe_u16(TME_SPARC_FORMAT3_RD);
2333: tme_memory_bus_write16((tme_shared tme_uint16_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint16_t), sizeof(tme_uint32_t));
2334:
2335: /* unbusy the DTLB entry: */
2336: tme_sparc_tlb_unbusy(dtlb);
2337:
2338: TME_SPARC_INSN_OK;
2339: }
2340:
2341: /* this does a sparc32 lda: */
2342: TME_SPARC_FORMAT3(tme_sparc32_lda, tme_uint32_t)
2343: {
2344: tme_uint32_t asi_mask_data;
2345: tme_uint32_t address;
2346: struct tme_sparc_tlb *dtlb;
2347: const tme_shared tme_uint8_t *memory;
2348: tme_uint32_t value;
2349:
2350: /* get the alternate ASI mask: */
2351: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2352:
2353: /* get the address: */
2354: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2355:
2356: #ifdef _TME_SPARC_STATS
2357: /* track statistics: */
2358: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
2359: #endif /* _TME_SPARC_STATS */
2360:
2361: /* get and busy the DTLB entry: */
2362: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2363: tme_sparc_tlb_busy(dtlb);
2364:
2365: /* assume that this DTLB applies and allows fast transfers: */
2366: memory = dtlb->tme_sparc_tlb_emulator_off_read;
2367:
2368: /* we must call the slow load function if: */
2369: if (__tme_predict_false(
2370:
2371: /* the DTLB entry is invalid: */
2372: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2373:
2374: /* the DTLB entry does not cover the needed addresses: */
2375: || (dtlb->tme_sparc_tlb_addr_first > address)
2376: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1)))
2377:
2378: /* the DTLB entry does not cover the needed address space: */
2379: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2380:
2381: /* the DTLB entry does not allow fast transfers: */
2382: || (memory == TME_EMULATOR_OFF_UNDEF)
2383:
2384: /* the address is misaligned: */
2385: || ((address % (32 / 8)) != 0)
2386:
2387: )) {
2388:
2389: /* call the slow load function: */
2390: memory = tme_sparc32_load(ic,
2391: address,
2392: (TME_SPARC_SLOW_FLAG_A
2393: | (32 / 8)));
2394: }
2395:
2396: /* do the fast transfer: */
2397: memory += address;
2398: value = tme_memory_bus_read32((const tme_shared tme_uint32_t *) memory, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t));
2399: value = tme_betoh_u32(value);
2400:
2401: /* unbusy the DTLB entry: */
2402: tme_sparc_tlb_unbusy(dtlb);
2403:
2404: /* set the loaded value: */
2405: TME_SPARC_FORMAT3_RD = value;
2406:
2407: /* log the value loaded: */
2408: tme_sparc_verify_mem32(ic, asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_READ);
2409: tme_sparc_log(ic, 1000, TME_OK,
2410: (TME_SPARC_LOG_HANDLE(ic),
2411: _("lda\t0x%02x:0x%08x:\t0x%08x"),
2412: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2413: address,
2414: TME_SPARC_FORMAT3_RD));
2415:
2416: TME_SPARC_INSN_OK;
2417: }
2418:
2419: /* this does a sparc32 sta: */
2420: TME_SPARC_FORMAT3(tme_sparc32_sta, tme_uint32_t)
2421: {
2422: tme_uint32_t asi_mask_data;
2423: tme_uint32_t address;
2424: struct tme_sparc_tlb *dtlb;
2425: tme_shared tme_uint8_t *memory;
2426: tme_uint32_t value;
2427:
2428: /* get the alternate ASI mask: */
2429: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2430:
2431: /* get the address: */
2432: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2433:
2434: #ifdef _TME_SPARC_STATS
2435: /* track statistics: */
2436: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
2437: #endif /* _TME_SPARC_STATS */
2438:
2439: /* log the value stored: */
2440: tme_sparc_verify_mem32(ic, asi_mask_data, address, (tme_uint32_t) TME_SPARC_FORMAT3_RD, TME_BUS_CYCLE_WRITE);
2441: tme_sparc_log(ic, 1000, TME_OK,
2442: (TME_SPARC_LOG_HANDLE(ic),
2443: _("sta\t0x%02x:0x%08x:\t0x%08x"),
2444: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2445: address,
2446: (tme_uint32_t) TME_SPARC_FORMAT3_RD));
2447:
2448: /* get and busy the DTLB entry: */
2449: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2450: tme_sparc_tlb_busy(dtlb);
2451:
2452: /* assume that this DTLB applies and allows fast transfers: */
2453: memory = dtlb->tme_sparc_tlb_emulator_off_write;
2454:
2455: /* we must call the slow store function if: */
2456: if (__tme_predict_false(
2457:
2458: /* the DTLB entry is invalid: */
2459: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2460:
2461: /* the DTLB entry does not cover the needed addresses: */
2462: || (dtlb->tme_sparc_tlb_addr_first > address)
2463: || (dtlb->tme_sparc_tlb_addr_last < (address + ((32 / 8) - 1)))
2464:
2465: /* the DTLB entry does not cover the needed address space: */
2466: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2467:
2468: /* the DTLB entry does not allow fast transfers: */
2469: || (memory == TME_EMULATOR_OFF_UNDEF)
2470:
2471: /* the address is misaligned: */
2472: || ((address % (32 / 8)) != 0)
2473:
2474: )) {
2475:
2476: /* call the slow store function: */
2477: memory = tme_sparc32_store(ic,
2478: address,
2479: &TME_SPARC_FORMAT3_RD,
2480: (TME_SPARC_SLOW_FLAG_A
2481: | (32 / 8)));
2482:
2483: /* if the slow store function did the transfer, return now: */
2484: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
2485: tme_sparc_tlb_unbusy(dtlb);
2486: TME_SPARC_INSN_OK;
2487: }
2488: }
2489:
2490: /* do the fast transfer: */
2491: memory += address;
2492: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD);
2493: tme_memory_bus_write32((tme_shared tme_uint32_t *) memory, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t));
2494:
2495: /* unbusy the DTLB entry: */
2496: tme_sparc_tlb_unbusy(dtlb);
2497:
2498: TME_SPARC_INSN_OK;
2499: }
2500:
2501: /* this does a sparc32 ldda: */
2502: TME_SPARC_FORMAT3(tme_sparc32_ldda, tme_uint32_t)
2503: {
2504: tme_uint32_t asi_mask_data;
2505: tme_uint32_t address;
2506: struct tme_sparc_tlb *dtlb;
2507: const tme_shared tme_uint8_t *memory;
2508: tme_uint32_t value;
2509:
2510: /* get the alternate ASI mask: */
2511: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2512:
2513: /* get the address: */
2514: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2515:
2516: #ifdef _TME_SPARC_STATS
2517: /* track statistics: */
2518: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
2519: #endif /* _TME_SPARC_STATS */
2520:
2521: /* get and busy the DTLB entry: */
2522: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2523: tme_sparc_tlb_busy(dtlb);
2524:
2525: /* assume that this DTLB applies and allows fast transfers: */
2526: memory = dtlb->tme_sparc_tlb_emulator_off_read;
2527:
2528: /* we must call the slow load function if: */
2529: if (__tme_predict_false(
2530:
2531: /* the DTLB entry is invalid: */
2532: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2533:
2534: /* the DTLB entry does not cover the needed addresses: */
2535: || (dtlb->tme_sparc_tlb_addr_first > address)
2536: || (dtlb->tme_sparc_tlb_addr_last < (address + ((64 / 8) - 1)))
2537:
2538: /* the DTLB entry does not cover the needed address space: */
2539: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2540:
2541: /* the DTLB entry does not allow fast transfers: */
2542: || (memory == TME_EMULATOR_OFF_UNDEF)
2543:
2544: /* the address is misaligned: */
2545: || ((address % (64 / 8)) != 0)
2546:
2547: /* the destination register number is odd: */
2548: || ((TME_SPARC_INSN & TME_BIT(25)) != 0)
2549:
2550: )) {
2551:
2552: /* call the slow load function: */
2553: memory = tme_sparc32_load(ic,
2554: address,
2555: (TME_SPARC_SLOW_FLAG_A
2556: | (64 / 8)));
2557: }
2558:
2559: /* do the fast transfer: */
2560: memory += address;
2561: value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 0, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint32_t));
2562: TME_SPARC_FORMAT3_RD = tme_betoh_u32(value);
2563: value = tme_memory_bus_read32(((const tme_shared tme_uint32_t *) memory) + 1, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t));
2564: TME_SPARC_FORMAT3_RD_ODD = tme_betoh_u32(value);
2565:
2566: /* unbusy the DTLB entry: */
2567: tme_sparc_tlb_unbusy(dtlb);
2568:
2569: /* log the value loaded: */
2570: tme_sparc_log(ic, 1000, TME_OK,
2571: (TME_SPARC_LOG_HANDLE(ic),
2572: _("ldda\t0x%02x:0x%08x:\t0x%08x 0x%08x"),
2573: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2574: address,
2575: (tme_uint32_t) TME_SPARC_FORMAT3_RD,
2576: (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD));
2577:
2578: TME_SPARC_INSN_OK;
2579: }
2580:
2581: /* this does a sparc32 stda: */
2582: TME_SPARC_FORMAT3(tme_sparc32_stda, tme_uint32_t)
2583: {
2584: tme_uint32_t asi_mask_data;
2585: tme_uint32_t address;
2586: struct tme_sparc_tlb *dtlb;
2587: tme_shared tme_uint8_t *memory;
2588: tme_uint32_t value;
2589:
2590: /* get the alternate ASI mask: */
2591: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2592:
2593: /* get the address: */
2594: address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2595:
2596: #ifdef _TME_SPARC_STATS
2597: /* track statistics: */
2598: ic->tme_sparc_stats.tme_sparc_stats_memory_total++;
2599: #endif /* _TME_SPARC_STATS */
2600:
2601: /* log the values stored: */
2602: tme_sparc_log(ic, 1000, TME_OK,
2603: (TME_SPARC_LOG_HANDLE(ic),
2604: _("stda\t0x%02x:0x%08x:\t0x%08x 0x%08x"),
2605: TME_SPARC_ASI_MASK_WHICH(asi_mask_data),
2606: address,
2607: (tme_uint32_t) TME_SPARC_FORMAT3_RD,
2608: (tme_uint32_t) TME_SPARC_FORMAT3_RD_ODD));
2609:
2610: /* get and busy the DTLB entry: */
2611: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2612: tme_sparc_tlb_busy(dtlb);
2613:
2614: /* assume that this DTLB applies and allows fast transfers: */
2615: memory = dtlb->tme_sparc_tlb_emulator_off_write;
2616:
2617: /* we must call the slow store function if: */
2618: if (__tme_predict_false(
2619:
2620: /* the DTLB entry is invalid: */
2621: tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2622:
2623: /* the DTLB entry does not cover the needed addresses: */
2624: || (dtlb->tme_sparc_tlb_addr_first > address)
2625: || (dtlb->tme_sparc_tlb_addr_last < (address + ((64 / 8) - 1)))
2626:
2627: /* the DTLB entry does not cover the needed address space: */
2628: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2629:
2630: /* the DTLB entry does not allow fast transfers: */
2631: || (memory == TME_EMULATOR_OFF_UNDEF)
2632:
2633: /* the address is misaligned: */
2634: || ((address % (64 / 8)) != 0)
2635:
2636: /* the destination register number is odd: */
2637: || ((TME_SPARC_INSN & TME_BIT(25)) != 0)
2638:
2639: )) {
2640:
2641: /* call the slow store function: */
2642: memory = tme_sparc32_store(ic,
2643: address,
2644: &TME_SPARC_FORMAT3_RD,
2645: (TME_SPARC_SLOW_FLAG_A
2646: | (64 / 8)));
2647:
2648: /* if the slow store function did the transfer, return now: */
2649: if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
2650: tme_sparc_tlb_unbusy(dtlb);
2651: TME_SPARC_INSN_OK;
2652: }
2653: }
2654:
2655: /* do the fast transfer: */
2656: memory += address;
2657: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD);
2658: tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 0, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t) * 2, sizeof(tme_uint32_t));
2659: value = tme_htobe_u32(TME_SPARC_FORMAT3_RD_ODD);
2660: tme_memory_bus_write32(((tme_shared tme_uint32_t *) memory) + 1, value, dtlb->tme_sparc_tlb_bus_rwlock, sizeof(tme_uint32_t), sizeof(tme_uint32_t));
2661:
2662: /* unbusy the DTLB entry: */
2663: tme_sparc_tlb_unbusy(dtlb);
2664:
2665: TME_SPARC_INSN_OK;
2666: }
2667:
2668: /* this does a sparc32 jmpl: */
2669: TME_SPARC_FORMAT3(tme_sparc32_jmpl, tme_uint32_t)
2670: {
2671: tme_uint32_t pc_next_next;
2672:
2673: /* "The JMPL instruction causes a register-indirect delayed control
2674: transfer to the address given by r[rs1] + r[rs2] if the i field is
2675: zero, or r[rs1] + sign_ext(simm13) if the i field is one. The JMPL
2676: instruction copies the PC, which contains the address of the JMPL
2677: instruction, into register r[rd]. If either of the low-order two
2678: bits of the jump address is nonzero, a mem_address_not_aligned
2679: trap occurs." */
2680:
2681: pc_next_next = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
2682: if (__tme_predict_false((pc_next_next % sizeof(tme_uint32_t)) != 0)) {
2683: TME_SPARC_INSN_TRAP(TME_SPARC_TRAP_mem_address_not_aligned);
2684: }
2685:
2686: /* write the PC of the jmpl into r[rd]: */
2687: TME_SPARC_FORMAT3_RD = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC);
2688:
2689: /* log an indirect call instruction, which has 15 (%o7) for rd: */
2690: if (TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD) == 15) {
2691: tme_sparc_log(ic, 250, TME_OK,
2692: (TME_SPARC_LOG_HANDLE(ic),
2693: _("call 0x%08x"),
2694: pc_next_next));
2695: }
2696:
2697: /* log a ret or retl instruction, which has 0 (%g0) for rd,
2698: either 31 (%i7) or 15 (%o7) for rs1, and 8 for simm13: */
2699: else if ((TME_SPARC_INSN | (16 << 14))
2700: == ((tme_uint32_t) (0x2 << 30) | (0 << 25) | (0x38 << 19) | (31 << 14) | (0x1 << 13) | 8)) {
2701: tme_sparc_log(ic, 250, TME_OK,
2702: (TME_SPARC_LOG_HANDLE(ic),
2703: _("retl 0x%08x"),
2704: pc_next_next));
2705: }
2706:
2707: /* set the delayed control transfer: */
2708: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_PC_NEXT_NEXT) = pc_next_next;
2709:
2710: TME_SPARC_INSN_OK;
2711: }
2712:
2713: /* this does a sparc32 ldf: */
2714: TME_SPARC_FORMAT3(tme_sparc32_ldf, tme_uint32_t)
2715: {
2716: unsigned int fpreg_number;
2717:
2718: TME_SPARC_INSN_FPU;
2719:
2720: /* decode rd: */
2721: fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
2722:
2723: /* make sure this floating-point register is single-precision: */
2724: tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
2725:
2726: /* do the load: */
2727: tme_sparc32_ld(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX));
2728:
2729: /* set the floating-point register value: */
2730: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
2731: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_single
2732: = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX);
2733:
2734: TME_SPARC_INSN_OK;
2735: }
2736:
2737: /* this does a sparc32 lddf: */
2738: TME_SPARC_FORMAT3(tme_sparc32_lddf, tme_uint32_t)
2739: {
2740: unsigned int fpreg_number;
2741:
2742: TME_SPARC_INSN_FPU;
2743:
2744: /* decode rd: */
2745: fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
2746:
2747: /* make sure rd is aligned: */
2748: if (!tme_sparc_fpu_fpreg_aligned(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE)) {
2749: fpreg_number -= 1;
2750: }
2751:
2752: /* make sure that the double floating-point register is double-precision: */
2753: tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
2754:
2755: /* do the load: */
2756: tme_sparc32_ldd(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX));
2757:
2758: /* set the double floating-point register value: */
2759: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
2760: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint32_hi
2761: = ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX) + 0);
2762: ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint32_lo
2763: = ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX) + 1);
2764:
2765: TME_SPARC_INSN_OK;
2766: }
2767:
2768: /* this does a sparc32 ldfsr: */
2769: TME_SPARC_FORMAT3(tme_sparc32_ldfsr, tme_uint32_t)
2770: {
2771: tme_uint32_t fsr;
2772:
2773: TME_SPARC_INSN_FPU;
2774:
2775: /* do the load: */
2776: tme_sparc32_ld(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX));
2777:
2778: /* update the FSR: */
2779: fsr = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX);
2780: /* "An LDFSR instruction does not affect ftt." */
2781: /* "The LDFSR instruction does not affect qne." */
2782: fsr &= ~(TME_SPARC_FSR_VER | TME_SPARC_FSR_FTT | TME_SPARC_FSR_QNE);
2783: ic->tme_sparc_fpu_fsr = (ic->tme_sparc_fpu_fsr & (TME_SPARC_FSR_VER | TME_SPARC_FSR_FTT | TME_SPARC_FSR_QNE)) | fsr;
2784:
2785: TME_SPARC_INSN_OK;
2786: }
2787:
2788: /* this does a sparc32 stf: */
2789: TME_SPARC_FORMAT3(tme_sparc32_stf, tme_uint32_t)
2790: {
2791: unsigned int fpreg_number;
2792: const tme_uint32_t *value_single;
2793: tme_uint32_t value_single_buffer;
2794:
2795: TME_SPARC_INSN_FPU_STORE(sizeof(tme_uint32_t));
2796:
2797: /* decode rd: */
2798: fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
2799:
2800: /* make sure this floating-point register is single-precision: */
2801: tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_SINGLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
2802:
2803: /* get this single floating-point register in IEEE754 single-precision format: */
2804: value_single = tme_ieee754_single_value_get(&ic->tme_sparc_fpu_fpregs[fpreg_number], &value_single_buffer);
2805:
2806: /* set the floating-point register value: */
2807: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX) = *value_single;
2808:
2809: /* do the store: */
2810: tme_sparc32_st(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX));
2811:
2812: TME_SPARC_INSN_OK;
2813: }
2814:
2815: /* this does a sparc32 stdf: */
2816: TME_SPARC_FORMAT3(tme_sparc32_stdf, tme_uint32_t)
2817: {
2818: unsigned int fpreg_number;
2819: const union tme_value64 *value_double;
2820: union tme_value64 value_double_buffer;
2821:
2822: TME_SPARC_INSN_FPU_STORE(sizeof(tme_uint32_t) * 2);
2823:
2824: /* decode rd: */
2825: fpreg_number = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
2826:
2827: /* make sure rd is aligned: */
2828: if (!tme_sparc_fpu_fpreg_aligned(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE)) {
2829: fpreg_number -= 1;
2830: }
2831:
2832: /* make sure the double floating-point register is double-precision: */
2833: tme_sparc_fpu_fpreg_format(ic, fpreg_number, TME_IEEE754_FPREG_FORMAT_DOUBLE | TME_IEEE754_FPREG_FORMAT_BUILTIN);
2834:
2835: /* get this double floating-point register in IEEE754 double-precision format: */
2836: value_double = tme_ieee754_double_value_get(&ic->tme_sparc_fpu_fpregs[fpreg_number], &value_double_buffer);
2837:
2838: /* set the floating-point register value: */
2839: ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX) + 0)
2840: = value_double->tme_value64_uint32_hi;
2841: ic->tme_sparc_ireg_uint32((TME_SPARC_IREG_FPX) + 1)
2842: = value_double->tme_value64_uint32_lo;
2843:
2844: /* do the store: */
2845: tme_sparc32_std(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX));
2846:
2847: TME_SPARC_INSN_OK;
2848: }
2849:
2850: /* this does a sparc32 stfsr: */
2851: TME_SPARC_FORMAT3(tme_sparc32_stfsr, tme_uint32_t)
2852: {
2853:
2854: TME_SPARC_INSN_FPU_STORE(sizeof(ic->tme_sparc_fpu_fsr));
2855:
2856: /* set the FSR value to store: */
2857: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX) = ic->tme_sparc_fpu_fsr;
2858:
2859: /* do the store: */
2860: tme_sparc32_st(ic, _rs1, _rs2, &ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_FPX));
2861:
2862: TME_SPARC_INSN_OK;
2863: }
2864:
2865: /* this does a sparc32 "mulscc SRC1, SRC2, DST": */
2866: TME_SPARC_FORMAT3(tme_sparc32_mulscc, tme_uint32_t)
2867: {
2868: tme_uint32_t src1;
2869: tme_uint32_t src2;
2870: tme_uint32_t dst;
2871: tme_uint32_t y;
2872: tme_uint32_t cc;
2873:
2874: /* get the operands: */
2875: src1 = (tme_uint32_t) TME_SPARC_FORMAT3_RS1;
2876: src2 = (tme_uint32_t) TME_SPARC_FORMAT3_RS2;
2877:
2878: /* perform the operation: */
2879:
2880: /* "(1) The multiplier is established as r[rs2] if the i field is zero, or
2881: sign_ext(simm13) if the i field is one."
2882:
2883: "(3) If the least significant bit of the Y register = 1, the shifted
2884: value from step (2) is added to the multiplier. If the LSB of the
2885: Y register = 0, then 0 is added to the shifted value from step (2)." */
2886: y = ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y);
2887: if ((y & 1) == 0) {
2888: src2 = 0;
2889: }
2890:
2891: /* "(6) The Y register is shifted right by one bit, with the LSB of the
2892: unshifted r[rs1] replacing the MSB of Y." */
2893: y >>= 1;
2894: if (src1 & 1) {
2895: y += 0x80000000;
2896: }
2897: ic->tme_sparc_ireg_uint32(TME_SPARC_IREG_Y) = y;
2898:
2899: /* "(2) A 32-bit value is computed by shifting r[rs1] right by one
2900: bit with (N xor V) from the PSR replacing the high-order bit.
2901: (This is the proper sign for the previous partial product.)" */
2902: src1 >>= 1;
2903: if (((ic->tme_sparc32_ireg_psr ^ (ic->tme_sparc32_ireg_psr * (TME_SPARC32_PSR_ICC_N / TME_SPARC32_PSR_ICC_V))) & TME_SPARC32_PSR_ICC_N) != 0) {
2904: src1 += 0x80000000;
2905: }
2906:
2907: /* "(4) The sum from step (3) is written into r[rd]." */
2908: dst = src1 + src2;
2909:
2910: /* "(5) The integer condition codes, icc, are updated according to the
2911: addition performed in step (3)." */
2912:
2913: /* store the destination: */
2914: TME_SPARC_FORMAT3_RD = (tme_uint32_t) dst;
2915:
2916: /* set Z if the destination is zero: */
2917: cc = ((dst == 0) * (TME_SPARC32_PSR_ICC_Z));
2918:
2919: /* set N if the destination is negative: */
2920: cc += ((((tme_int32_t) dst) < 0) * TME_SPARC32_PSR_ICC_N);
2921:
2922: /* if the operands are the same sign, and the destination has
2923: a different sign, set V: */
2924: cc += ((((tme_int32_t) ((src2 ^ dst) & (src1 ^ (src2 ^ (((tme_uint32_t) 0) - 1))))) < 0) * TME_SPARC32_PSR_ICC_V);
2925:
2926: /* if src1 and src2 both have the high bit set, or if dst does
2927: not have the high bit set and either src1 or src2 does, set C: */
2928: cc += (((tme_int32_t) (((tme_uint32_t) (src1 & src2)) | ((((tme_uint32_t) dst) ^ (((tme_uint32_t) 0) - 1)) & ((tme_uint32_t) (src1 | src2))))) < 0) * TME_SPARC32_PSR_ICC_C;
2929:
2930: /* set the condition codes: */
2931: ic->tme_sparc32_ireg_psr = (ic->tme_sparc32_ireg_psr & ~TME_SPARC32_PSR_ICC) | cc;
2932:
2933: TME_SPARC_INSN_OK;
2934: }
2935:
2936: /* this does a slow load: */
2937: const tme_shared tme_uint8_t *
2938: tme_sparc32_load(struct tme_sparc *ic,
2939: tme_uint32_t address,
2940: const unsigned int flags)
2941: {
2942: unsigned int size;
2943: tme_uint32_t asi_mask_data;
2944: struct tme_sparc_tlb *dtlb;
2945: tme_bus_addr_t physical_address;
2946: int shift;
2947: struct tme_bus_cycle cycle;
2948: unsigned int transferred, resid, cycle_size;
2949: unsigned int trap;
2950: int err;
2951:
2952: /* get the transfer size. we can do at most a 64-bit transfer: */
2953: size = (flags % (sizeof(tme_uint64_t) * 2));
2954:
2955: /* get the DTLB entry. our caller has already busied it: */
2956: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
2957:
2958: /* if the address is not aligned: */
2959: if (__tme_predict_false((address & (size - 1)) != 0)) {
2960: tme_sparc_tlb_unbusy(dtlb);
2961: tme_sparc32_trap(ic, TME_SPARC_TRAP_mem_address_not_aligned);
2962: }
2963:
2964: /* if this is a ldd or a std (and not an lddf or an stdf)
2965: and the destination register address is odd: */
2966: /* NB: we detect lddf and stdf by testing bit 24 in the
2967: instruction word: */
2968: if (__tme_predict_false(size == (sizeof(tme_uint32_t) * 2)
2969: && (TME_SPARC_INSN & TME_BIT(25)) != 0
2970: && (TME_SPARC_INSN & TME_BIT(24)) == 0)) {
2971: tme_sparc_tlb_unbusy(dtlb);
2972: tme_sparc32_trap(ic, TME_SPARC_TRAP_illegal_instruction);
2973: }
2974:
2975: /* get the ASI and its mask: */
2976: asi_mask_data = ic->tme_sparc_asi_mask_data;
2977: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_INSN) != 0)) {
2978: asi_mask_data = ic->tme_sparc_asi_mask_insn;
2979: }
2980: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_A) != 0)) {
2981: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
2982: }
2983:
2984: /* loop until the load is completed: */
2985: trap = TME_SPARC_TRAP_none;
2986: transferred = 0;
2987: do {
2988:
2989: /* while the DTLB entry is invalid, or does not cover this address
2990: and address space, or if it does not allow for slow or fast reads: */
2991: for (; (tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
2992: || (dtlb->tme_sparc_tlb_addr_first > address)
2993: || (dtlb->tme_sparc_tlb_addr_last < address)
2994: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
2995: || (dtlb->tme_sparc_tlb_emulator_off_read == TME_EMULATOR_OFF_UNDEF
2996: && (dtlb->tme_sparc_tlb_cycles_ok & TME_BUS_CYCLE_READ) == 0)); ) {
2997:
2998: /* unbusy this DTLB entry for filling: */
2999: tme_bus_tlb_unbusy_fill(&dtlb->tme_sparc_tlb_bus_tlb);
3000:
3001: /* we never fill TLB entries on the stack because we never
3002: callout multiple fills at the same time, so the global TLB
3003: entry pointer always points back to the TLB entry. this
3004: also means that we do not have to call tme_bus_tlb_back()
3005: after the fill: */
3006: dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_global = &dtlb->tme_sparc_tlb_bus_tlb;
3007:
3008: /* reload the DTLB entry: */
3009: tme_sparc_callout_unlock(ic);
3010: #ifdef _TME_SPARC_STATS
3011: ic->tme_sparc_stats.tme_sparc_stats_dtlb_fill++;
3012: #endif /* _TME_SPARC_STATS */
3013: err = (*ic->_tme_sparc_bus_connection->tme_sparc_bus_tlb_fill)
3014: (ic->_tme_sparc_bus_connection,
3015: dtlb,
3016: asi_mask_data,
3017: address,
3018: TME_BUS_CYCLE_READ);
3019: assert (err == TME_OK);
3020: tme_sparc_callout_relock(ic);
3021:
3022: /* rebusy the DTLB entry: */
3023: tme_sparc_tlb_busy(dtlb);
3024: }
3025:
3026: /* if this DTLB entry allows fast reads: */
3027: if (__tme_predict_true(dtlb->tme_sparc_tlb_emulator_off_read != TME_EMULATOR_OFF_UNDEF)) {
3028:
3029: /* if we have not transferred anything yet, and this
3030: DTLB entry covers all of the addresses and allows
3031: fast transfers: */
3032: if (__tme_predict_true(transferred == 0
3033: && dtlb->tme_sparc_tlb_addr_last >= address + (size - 1)
3034: )) {
3035:
3036: /* return and let our caller do the transfer: */
3037: return (dtlb->tme_sparc_tlb_emulator_off_read);
3038: }
3039:
3040: /* calculate the cycle size: */
3041: cycle_size = (dtlb->tme_sparc_tlb_addr_last - address) + 1;
3042: cycle_size = TME_MIN(cycle_size, sizeof(tme_uint32_t) - (address % sizeof(tme_uint32_t)));
3043: cycle_size = TME_MIN(cycle_size, size - transferred);
3044: cycle.tme_bus_cycle_size = cycle_size;
3045:
3046: /* do a read: */
3047: tme_memory_bus_read_buffer((dtlb->tme_sparc_tlb_emulator_off_read + address),
3048: (&ic->tme_sparc_memory_buffer[0] + transferred),
3049: cycle_size,
3050: dtlb->tme_sparc_tlb_bus_rwlock,
3051: sizeof(tme_uint8_t),
3052: sizeof(tme_uint32_t));
3053: }
3054:
3055: /* otherwise, this DTLB entry does not allow fast reads: */
3056: else {
3057:
3058: /* make the bus cycle structure: */
3059: resid = size - transferred;
3060: cycle.tme_bus_cycle_type = TME_BUS_CYCLE_READ;
3061: cycle.tme_bus_cycle_buffer = (tme_uint8_t *) (&ic->tme_sparc_memory_buffer[0] + transferred);
3062: cycle.tme_bus_cycle_buffer_increment = 1;
3063: cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (address % sizeof(tme_uint32_t)));
3064: cycle.tme_bus_cycle_size = cycle_size;
3065: cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2);
3066: cycle.tme_bus_cycle_lane_routing =
3067: &tme_sparc32_router[TME_SPARC_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, address)];
3068:
3069: /* form the physical address for the bus cycle handler: */
3070: physical_address = dtlb->tme_sparc_tlb_addr_offset + address;
3071: shift = dtlb->tme_sparc_tlb_addr_shift;
3072: if (shift < 0) {
3073: physical_address <<= (0 - shift);
3074: }
3075: else if (shift > 0) {
3076: physical_address >>= shift;
3077: }
3078: cycle.tme_bus_cycle_address = physical_address;
3079:
3080: /* callout the bus cycle: */
3081: tme_sparc_tlb_unbusy(dtlb);
3082: tme_sparc_callout_unlock(ic);
3083: err = (*dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle)
3084: (dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle);
3085: tme_sparc_callout_relock(ic);
3086: tme_sparc_tlb_busy(dtlb);
3087:
3088: /* if the TLB entry was invalidated before the load: */
3089: if (err == EBADF
3090: && tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)) {
3091: cycle.tme_bus_cycle_size = 0;
3092: }
3093:
3094: /* otherwise, any other error might be a bus error: */
3095: else if (err != TME_OK) {
3096:
3097: /* if a real bus error may have happened, instead of
3098: some synchronous event: */
3099: if (err != TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {
3100:
3101: /* call the bus fault handlers: */
3102: err = tme_bus_tlb_fault(&dtlb->tme_sparc_tlb_bus_tlb, &cycle, err);
3103: }
3104:
3105: /* if some synchronous event has happened: */
3106: if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {
3107:
3108: /* after the currently executing instruction finishes, check
3109: for external resets, halts, or interrupts: */
3110: ic->_tme_sparc_instruction_burst_remaining = 0;
3111: }
3112:
3113: /* otherwise, if a real bus fault happened: */
3114: else if (err != TME_OK) {
3115: trap = (*ic->_tme_sparc_bus_fault)(ic, &cycle, flags, err);
3116: if (trap != TME_SPARC_TRAP_none) {
3117: break;
3118: }
3119: }
3120: }
3121: }
3122:
3123: /* update: */
3124: address += cycle.tme_bus_cycle_size;
3125: transferred += cycle.tme_bus_cycle_size;
3126: } while (transferred < size);
3127:
3128: /* if we faulted, start trap processing: */
3129: if (__tme_predict_false(trap != TME_SPARC_TRAP_none)) {
3130: tme_sparc_tlb_unbusy(dtlb);
3131: tme_sparc32_trap(ic, trap);
3132: }
3133:
3134: return (ic->tme_sparc_memory_buffer - (address - size));
3135: }
3136:
3137: /* this does a slow store: */
3138: tme_shared tme_uint8_t *
3139: tme_sparc32_store(struct tme_sparc *ic,
3140: tme_uint32_t address,
3141: const tme_uint32_t * const _rd,
3142: const unsigned int flags)
3143: {
3144: unsigned int size;
3145: tme_uint32_t asi_mask_data;
3146: struct tme_sparc_tlb *dtlb;
3147: tme_bus_addr_t physical_address;
3148: int shift;
3149: struct tme_bus_cycle cycle;
3150: unsigned int transferred, resid, cycle_size;
3151: unsigned int trap;
3152: int err;
3153: tme_uint32_t stored_registers[2];
3154: const tme_uint8_t *buffer;
3155:
3156: /* get the transfer size. we can do at most a 64-bit transfer: */
3157: size = (flags % (sizeof(tme_uint64_t) * 2));
3158:
3159: /* get the DTLB entry. our caller has already busied it: */
3160: dtlb = TME_SPARC_DTLB_ENTRY(ic, address);
3161:
3162: /* if the address is not aligned: */
3163: if (__tme_predict_false((address & (size - 1)) != 0)) {
3164: tme_sparc_tlb_unbusy(dtlb);
3165: tme_sparc32_trap(ic, TME_SPARC_TRAP_mem_address_not_aligned);
3166: }
3167:
3168: /* if this is a ldd or a std (and not an lddf or an stdf)
3169: and the destination register address is odd: */
3170: /* NB: we detect lddf and stdf by testing bit 24 in the
3171: instruction word: */
3172: if (__tme_predict_false(size == (sizeof(tme_uint32_t) * 2)
3173: && (TME_SPARC_INSN & TME_BIT(25)) != 0
3174: && (TME_SPARC_INSN & TME_BIT(24)) == 0)) {
3175: tme_sparc_tlb_unbusy(dtlb);
3176: tme_sparc32_trap(ic, TME_SPARC_TRAP_illegal_instruction);
3177: }
3178:
3179: /* get the ASI and its mask: */
3180: asi_mask_data = ic->tme_sparc_asi_mask_data;
3181: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_INSN) != 0)) {
3182: asi_mask_data = ic->tme_sparc_asi_mask_insn;
3183: }
3184: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_A) != 0)) {
3185: asi_mask_data = _tme_sparc32_alternate_asi_mask(ic);
3186: }
3187:
3188: /* store big-endian versions of the registers to store in
3189: a buffer. we always assume that this is a std and copy
3190: r[rd] and r[rd + 1] into the buffer: */
3191: stored_registers[0] = tme_htobe_u32(TME_SPARC_FORMAT3_RD);
3192: stored_registers[1] = tme_htobe_u32(TME_SPARC_FORMAT3_RD_ODD);
3193:
3194: /* make the initial pointer into the buffer: */
3195: buffer = (const tme_uint8_t *) stored_registers;
3196: if (size < sizeof(tme_uint32_t)) {
3197: buffer += sizeof(tme_uint32_t) - size;
3198: }
3199:
3200: /* loop until the store is completed: */
3201: trap = TME_SPARC_TRAP_none;
3202: transferred = 0;
3203: do {
3204:
3205: /* while the DTLB entry is invalid, or does not cover this address
3206: and address space, or if it does not allow for slow or fast writes: */
3207: for (; (tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)
3208: || (dtlb->tme_sparc_tlb_addr_first > address)
3209: || (dtlb->tme_sparc_tlb_addr_last < address)
3210: || (!TME_SPARC_TLB_ASI_MASK_OK(dtlb, asi_mask_data))
3211: || (dtlb->tme_sparc_tlb_emulator_off_write == TME_EMULATOR_OFF_UNDEF
3212: && (dtlb->tme_sparc_tlb_cycles_ok & TME_BUS_CYCLE_WRITE) == 0)); ) {
3213:
3214: /* unbusy this DTLB entry for filling: */
3215: tme_bus_tlb_unbusy_fill(&dtlb->tme_sparc_tlb_bus_tlb);
3216:
3217: /* we never fill TLB entries on the stack because we never
3218: callout multiple fills at the same time, so the global TLB
3219: entry pointer always points back to the TLB entry. this
3220: also means that we do not have to call tme_bus_tlb_back()
3221: after the fill: */
3222: dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_global = &dtlb->tme_sparc_tlb_bus_tlb;
3223:
3224: /* reload the DTLB entry: */
3225: tme_sparc_callout_unlock(ic);
3226: #ifdef _TME_SPARC_STATS
3227: ic->tme_sparc_stats.tme_sparc_stats_dtlb_fill++;
3228: #endif /* _TME_SPARC_STATS */
3229: err = (*ic->_tme_sparc_bus_connection->tme_sparc_bus_tlb_fill)
3230: (ic->_tme_sparc_bus_connection,
3231: dtlb,
3232: asi_mask_data,
3233: address,
3234: TME_BUS_CYCLE_WRITE);
3235: assert (err == TME_OK);
3236: tme_sparc_callout_relock(ic);
3237:
3238: /* rebusy the DTLB entry: */
3239: tme_sparc_tlb_busy(dtlb);
3240: }
3241:
3242: /* if this DTLB entry allows fast writes: */
3243: if (__tme_predict_true(dtlb->tme_sparc_tlb_emulator_off_write != TME_EMULATOR_OFF_UNDEF)) {
3244:
3245: /* if we have not transferred anything yet, and this
3246: DTLB entry covers all of the addresses and allows
3247: fast transfers: */
3248: if (__tme_predict_true(transferred == 0
3249: && dtlb->tme_sparc_tlb_addr_last >= address + (size - 1)
3250:
3251: && ((flags & TME_SPARC_SLOW_FLAG_ATOMIC) == 0
3252: || dtlb->tme_sparc_tlb_emulator_off_read == dtlb->tme_sparc_tlb_emulator_off_write))) {
3253:
3254: /* return and let our caller do the transfer: */
3255: return (dtlb->tme_sparc_tlb_emulator_off_write);
3256: }
3257:
3258: /* calculate the cycle size: */
3259: cycle_size = (dtlb->tme_sparc_tlb_addr_last - address) + 1;
3260: cycle_size = TME_MIN(cycle_size, sizeof(tme_uint32_t) - (address % sizeof(tme_uint32_t)));
3261: cycle_size = TME_MIN(cycle_size, size - transferred);
3262: cycle.tme_bus_cycle_size = cycle_size;
3263:
3264: /* do a write: */
3265: tme_memory_bus_write_buffer((dtlb->tme_sparc_tlb_emulator_off_write + address),
3266: (buffer + transferred),
3267: cycle_size,
3268: dtlb->tme_sparc_tlb_bus_rwlock,
3269: sizeof(tme_uint8_t),
3270: sizeof(tme_uint32_t));
3271: }
3272:
3273: /* otherwise, this DTLB entry does not allow fast writes: */
3274: else {
3275:
3276: /* make the bus cycle structure: */
3277: resid = size - transferred;
3278: cycle.tme_bus_cycle_type = TME_BUS_CYCLE_WRITE;
3279: cycle.tme_bus_cycle_buffer = (tme_uint8_t *) (buffer + transferred);
3280: cycle.tme_bus_cycle_buffer_increment = 1;
3281: cycle_size = TME_MIN(resid, sizeof(tme_uint32_t) - (address % sizeof(tme_uint32_t)));
3282: cycle.tme_bus_cycle_size = cycle_size;
3283: cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS32_LOG2);
3284: cycle.tme_bus_cycle_lane_routing =
3285: &tme_sparc32_router[TME_SPARC_BUS_ROUTER_INDEX(TME_BUS32_LOG2, cycle_size, address)];
3286:
3287: /* form the physical address for the bus cycle handler: */
3288: physical_address = dtlb->tme_sparc_tlb_addr_offset + address;
3289: shift = dtlb->tme_sparc_tlb_addr_shift;
3290: if (shift < 0) {
3291: physical_address <<= (0 - shift);
3292: }
3293: else if (shift > 0) {
3294: physical_address >>= shift;
3295: }
3296: cycle.tme_bus_cycle_address = physical_address;
3297:
3298: /* callout the bus cycle: */
3299: tme_sparc_tlb_unbusy(dtlb);
3300: tme_sparc_callout_unlock(ic);
3301: err = (*dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle)
3302: (dtlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycle_private, &cycle);
3303: tme_sparc_callout_relock(ic);
3304: tme_sparc_tlb_busy(dtlb);
3305:
3306: /* if the TLB entry was invalidated before the store: */
3307: if (err == EBADF
3308: && tme_bus_tlb_is_invalid(&dtlb->tme_sparc_tlb_bus_tlb)) {
3309: cycle.tme_bus_cycle_size = 0;
3310: }
3311:
3312: /* otherwise, any other error might be a bus error: */
3313: else if (err != TME_OK) {
3314:
3315: /* if a real bus error may have happened, instead of
3316: some synchronous event: */
3317: if (err != TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {
3318:
3319: /* call the bus fault handlers: */
3320: err = tme_bus_tlb_fault(&dtlb->tme_sparc_tlb_bus_tlb, &cycle, err);
3321: }
3322:
3323: /* if some synchronous event has happened: */
3324: if (err == TME_BUS_CYCLE_SYNCHRONOUS_EVENT) {
3325:
3326: /* after the currently executing instruction finishes, check
3327: for external resets, halts, or interrupts: */
3328: ic->_tme_sparc_instruction_burst_remaining = 0;
3329: }
3330:
3331: /* otherwise, if a real bus fault happened: */
3332: else if (err != TME_OK) {
3333: trap = (*ic->_tme_sparc_bus_fault)(ic, &cycle, flags, err);
3334: if (trap != TME_SPARC_TRAP_none) {
3335: break;
3336: }
3337: }
3338: }
3339:
3340: /* if this was an atomic operation, and data was transferred: */
3341: if (__tme_predict_false((flags & TME_SPARC_SLOW_FLAG_ATOMIC) != 0
3342: && cycle.tme_bus_cycle_size > 0)) {
3343:
3344: /* we do not support atomic operations in TLB entries that
3345: do not support both fast reads and fast writes. assuming
3346: that all atomic operations are to regular memory, we
3347: should always get fast read and fast write TLBs. when
3348: we do not, it should only be because the memory has been
3349: made read-only in the MMU. the write above was supposed
3350: to cause a fault (with the instruction rerun later with
3351: a fast read and fast write TLB entry), but instead it
3352: succeeded and transferred some data. we have modified
3353: memory and cannot recover: */
3354: abort();
3355: }
3356: }
3357:
3358: /* update: */
3359: address += cycle.tme_bus_cycle_size;
3360: transferred += cycle.tme_bus_cycle_size;
3361: } while (transferred < size);
3362:
3363: /* if we faulted, start trap processing: */
3364: if (__tme_predict_false(trap != TME_SPARC_TRAP_none)) {
3365: tme_sparc_tlb_unbusy(dtlb);
3366: tme_sparc32_trap(ic, trap);
3367: }
3368:
3369: return ((tme_uint8_t *) TME_EMULATOR_OFF_UNDEF);
3370: }
3371:
3372: #undef TME_SPARC_VERSION
3373: #define TME_SPARC_VERSION(ic) _TME_SPARC_VERSION(ic)
3374: /* automatically generated by sparc-misc-auto.sh, do not edit! */
3375:
3376: /* the icc->conditions mapping: */
3377: const tme_uint8_t _tme_sparc_conds_icc[16] = {
3378: 0,
3379: 0 | TME_BIT(4) | TME_BIT(5),
3380: 0 | TME_BIT(2) | TME_BIT(3) | TME_BIT(7),
3381: 0 | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(5) | TME_BIT(7),
3382: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(4),
3383: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(4) | TME_BIT(5),
3384: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(7),
3385: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(5) | TME_BIT(7),
3386: 0 | TME_BIT(2) | TME_BIT(3) | TME_BIT(6),
3387: 0 | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(5) | TME_BIT(6),
3388: 0 | TME_BIT(6) | TME_BIT(7),
3389: 0 | TME_BIT(4) | TME_BIT(5) | TME_BIT(6) | TME_BIT(7),
3390: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(6),
3391: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(3) | TME_BIT(4) | TME_BIT(5) | TME_BIT(6),
3392: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(4) | TME_BIT(6) | TME_BIT(7),
3393: 0 | TME_BIT(1) | TME_BIT(2) | TME_BIT(4) | TME_BIT(5) | TME_BIT(6) | TME_BIT(7),
3394: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.