|
|
1.1 root 1: /*
2: SPARC micro operations
3:
4: Copyright (C) 2003 Thomas M. Ogrisegg <[email protected]>
5:
6: This library is free software; you can redistribute it and/or
7: modify it under the terms of the GNU Lesser General Public
8: License as published by the Free Software Foundation; either
9: version 2 of the License, or (at your option) any later version.
10:
11: This library is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: Lesser General Public License for more details.
15:
16: You should have received a copy of the GNU Lesser General Public
17: License along with this library; if not, write to the Free Software
18: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19: */
20:
21: #include "exec.h"
22:
23: /*XXX*/
24: #define REGNAME g0
25: #define REG (env->gregs[0])
26: #include "op_template.h"
27: #define REGNAME g1
28: #define REG (env->gregs[1])
29: #include "op_template.h"
30: #define REGNAME g2
31: #define REG (env->gregs[2])
32: #include "op_template.h"
33: #define REGNAME g3
34: #define REG (env->gregs[3])
35: #include "op_template.h"
36: #define REGNAME g4
37: #define REG (env->gregs[4])
38: #include "op_template.h"
39: #define REGNAME g5
40: #define REG (env->gregs[5])
41: #include "op_template.h"
42: #define REGNAME g6
43: #define REG (env->gregs[6])
44: #include "op_template.h"
45: #define REGNAME g7
46: #define REG (env->gregs[7])
47: #include "op_template.h"
48: #define REGNAME i0
49: #define REG (REGWPTR[16])
50: #include "op_template.h"
51: #define REGNAME i1
52: #define REG (REGWPTR[17])
53: #include "op_template.h"
54: #define REGNAME i2
55: #define REG (REGWPTR[18])
56: #include "op_template.h"
57: #define REGNAME i3
58: #define REG (REGWPTR[19])
59: #include "op_template.h"
60: #define REGNAME i4
61: #define REG (REGWPTR[20])
62: #include "op_template.h"
63: #define REGNAME i5
64: #define REG (REGWPTR[21])
65: #include "op_template.h"
66: #define REGNAME i6
67: #define REG (REGWPTR[22])
68: #include "op_template.h"
69: #define REGNAME i7
70: #define REG (REGWPTR[23])
71: #include "op_template.h"
72: #define REGNAME l0
73: #define REG (REGWPTR[8])
74: #include "op_template.h"
75: #define REGNAME l1
76: #define REG (REGWPTR[9])
77: #include "op_template.h"
78: #define REGNAME l2
79: #define REG (REGWPTR[10])
80: #include "op_template.h"
81: #define REGNAME l3
82: #define REG (REGWPTR[11])
83: #include "op_template.h"
84: #define REGNAME l4
85: #define REG (REGWPTR[12])
86: #include "op_template.h"
87: #define REGNAME l5
88: #define REG (REGWPTR[13])
89: #include "op_template.h"
90: #define REGNAME l6
91: #define REG (REGWPTR[14])
92: #include "op_template.h"
93: #define REGNAME l7
94: #define REG (REGWPTR[15])
95: #include "op_template.h"
96: #define REGNAME o0
97: #define REG (REGWPTR[0])
98: #include "op_template.h"
99: #define REGNAME o1
100: #define REG (REGWPTR[1])
101: #include "op_template.h"
102: #define REGNAME o2
103: #define REG (REGWPTR[2])
104: #include "op_template.h"
105: #define REGNAME o3
106: #define REG (REGWPTR[3])
107: #include "op_template.h"
108: #define REGNAME o4
109: #define REG (REGWPTR[4])
110: #include "op_template.h"
111: #define REGNAME o5
112: #define REG (REGWPTR[5])
113: #include "op_template.h"
114: #define REGNAME o6
115: #define REG (REGWPTR[6])
116: #include "op_template.h"
117: #define REGNAME o7
118: #define REG (REGWPTR[7])
119: #include "op_template.h"
120:
121: #define REGNAME f0
122: #define REG (env->fpr[0])
123: #include "fop_template.h"
124: #define REGNAME f1
125: #define REG (env->fpr[1])
126: #include "fop_template.h"
127: #define REGNAME f2
128: #define REG (env->fpr[2])
129: #include "fop_template.h"
130: #define REGNAME f3
131: #define REG (env->fpr[3])
132: #include "fop_template.h"
133: #define REGNAME f4
134: #define REG (env->fpr[4])
135: #include "fop_template.h"
136: #define REGNAME f5
137: #define REG (env->fpr[5])
138: #include "fop_template.h"
139: #define REGNAME f6
140: #define REG (env->fpr[6])
141: #include "fop_template.h"
142: #define REGNAME f7
143: #define REG (env->fpr[7])
144: #include "fop_template.h"
145: #define REGNAME f8
146: #define REG (env->fpr[8])
147: #include "fop_template.h"
148: #define REGNAME f9
149: #define REG (env->fpr[9])
150: #include "fop_template.h"
151: #define REGNAME f10
152: #define REG (env->fpr[10])
153: #include "fop_template.h"
154: #define REGNAME f11
155: #define REG (env->fpr[11])
156: #include "fop_template.h"
157: #define REGNAME f12
158: #define REG (env->fpr[12])
159: #include "fop_template.h"
160: #define REGNAME f13
161: #define REG (env->fpr[13])
162: #include "fop_template.h"
163: #define REGNAME f14
164: #define REG (env->fpr[14])
165: #include "fop_template.h"
166: #define REGNAME f15
167: #define REG (env->fpr[15])
168: #include "fop_template.h"
169: #define REGNAME f16
170: #define REG (env->fpr[16])
171: #include "fop_template.h"
172: #define REGNAME f17
173: #define REG (env->fpr[17])
174: #include "fop_template.h"
175: #define REGNAME f18
176: #define REG (env->fpr[18])
177: #include "fop_template.h"
178: #define REGNAME f19
179: #define REG (env->fpr[19])
180: #include "fop_template.h"
181: #define REGNAME f20
182: #define REG (env->fpr[20])
183: #include "fop_template.h"
184: #define REGNAME f21
185: #define REG (env->fpr[21])
186: #include "fop_template.h"
187: #define REGNAME f22
188: #define REG (env->fpr[22])
189: #include "fop_template.h"
190: #define REGNAME f23
191: #define REG (env->fpr[23])
192: #include "fop_template.h"
193: #define REGNAME f24
194: #define REG (env->fpr[24])
195: #include "fop_template.h"
196: #define REGNAME f25
197: #define REG (env->fpr[25])
198: #include "fop_template.h"
199: #define REGNAME f26
200: #define REG (env->fpr[26])
201: #include "fop_template.h"
202: #define REGNAME f27
203: #define REG (env->fpr[27])
204: #include "fop_template.h"
205: #define REGNAME f28
206: #define REG (env->fpr[28])
207: #include "fop_template.h"
208: #define REGNAME f29
209: #define REG (env->fpr[29])
210: #include "fop_template.h"
211: #define REGNAME f30
212: #define REG (env->fpr[30])
213: #include "fop_template.h"
214: #define REGNAME f31
215: #define REG (env->fpr[31])
216: #include "fop_template.h"
217:
218: #ifdef TARGET_SPARC64
219: #define REGNAME f32
220: #define REG (env->fpr[32])
221: #include "fop_template.h"
222: #define REGNAME f34
223: #define REG (env->fpr[34])
224: #include "fop_template.h"
225: #define REGNAME f36
226: #define REG (env->fpr[36])
227: #include "fop_template.h"
228: #define REGNAME f38
229: #define REG (env->fpr[38])
230: #include "fop_template.h"
231: #define REGNAME f40
232: #define REG (env->fpr[40])
233: #include "fop_template.h"
234: #define REGNAME f42
235: #define REG (env->fpr[42])
236: #include "fop_template.h"
237: #define REGNAME f44
238: #define REG (env->fpr[44])
239: #include "fop_template.h"
240: #define REGNAME f46
241: #define REG (env->fpr[46])
242: #include "fop_template.h"
243: #define REGNAME f48
244: #define REG (env->fpr[47])
245: #include "fop_template.h"
246: #define REGNAME f50
247: #define REG (env->fpr[50])
248: #include "fop_template.h"
249: #define REGNAME f52
250: #define REG (env->fpr[52])
251: #include "fop_template.h"
252: #define REGNAME f54
253: #define REG (env->fpr[54])
254: #include "fop_template.h"
255: #define REGNAME f56
256: #define REG (env->fpr[56])
257: #include "fop_template.h"
258: #define REGNAME f58
259: #define REG (env->fpr[58])
260: #include "fop_template.h"
261: #define REGNAME f60
262: #define REG (env->fpr[60])
263: #include "fop_template.h"
264: #define REGNAME f62
265: #define REG (env->fpr[62])
266: #include "fop_template.h"
267: #endif
268:
269: #ifdef TARGET_SPARC64
270: #ifdef WORDS_BIGENDIAN
271: typedef union UREG64 {
272: struct { uint16_t v3, v2, v1, v0; } w;
273: struct { uint32_t v1, v0; } l;
274: uint64_t q;
275: } UREG64;
276: #else
277: typedef union UREG64 {
278: struct { uint16_t v0, v1, v2, v3; } w;
279: struct { uint32_t v0, v1; } l;
280: uint64_t q;
281: } UREG64;
282: #endif
283:
284: #define PARAMQ1 \
285: ({\
286: UREG64 __p;\
287: __p.l.v1 = PARAM1;\
288: __p.l.v0 = PARAM2;\
289: __p.q;\
290: })
291:
292: void OPPROTO op_movq_T0_im64(void)
293: {
294: T0 = PARAMQ1;
295: }
296:
297: void OPPROTO op_movq_T1_im64(void)
298: {
299: T1 = PARAMQ1;
300: }
301:
302: #define XFLAG_SET(x) ((env->xcc&x)?1:0)
303:
304: #else
305: #define EIP (env->pc)
306: #endif
307:
308: #define FLAG_SET(x) ((env->psr&x)?1:0)
309:
310: void OPPROTO op_movl_T0_0(void)
311: {
312: T0 = 0;
313: }
314:
315: void OPPROTO op_movl_T0_im(void)
316: {
317: T0 = (uint32_t)PARAM1;
318: }
319:
320: void OPPROTO op_movl_T1_im(void)
321: {
322: T1 = (uint32_t)PARAM1;
323: }
324:
325: void OPPROTO op_movl_T2_im(void)
326: {
327: T2 = (uint32_t)PARAM1;
328: }
329:
330: void OPPROTO op_movl_T0_sim(void)
331: {
332: T0 = (int32_t)PARAM1;
333: }
334:
335: void OPPROTO op_movl_T1_sim(void)
336: {
337: T1 = (int32_t)PARAM1;
338: }
339:
340: void OPPROTO op_movl_T2_sim(void)
341: {
342: T2 = (int32_t)PARAM1;
343: }
344:
345: void OPPROTO op_movl_T0_env(void)
346: {
347: T0 = *(uint32_t *)((char *)env + PARAM1);
348: }
349:
350: void OPPROTO op_movl_env_T0(void)
351: {
352: *(uint32_t *)((char *)env + PARAM1) = T0;
353: }
354:
355: void OPPROTO op_movtl_T0_env(void)
356: {
357: T0 = *(target_ulong *)((char *)env + PARAM1);
358: }
359:
360: void OPPROTO op_movtl_env_T0(void)
361: {
362: *(target_ulong *)((char *)env + PARAM1) = T0;
363: }
364:
365: void OPPROTO op_add_T1_T0(void)
366: {
367: T0 += T1;
368: }
369:
370: void OPPROTO op_add_T1_T0_cc(void)
371: {
372: target_ulong src1;
373:
374: src1 = T0;
375: T0 += T1;
376: env->psr = 0;
377: #ifdef TARGET_SPARC64
378: if (!(T0 & 0xffffffff))
379: env->psr |= PSR_ZERO;
380: if ((int32_t) T0 < 0)
381: env->psr |= PSR_NEG;
382: if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
383: env->psr |= PSR_CARRY;
384: if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
385: ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
386: env->psr |= PSR_OVF;
387:
388: env->xcc = 0;
389: if (!T0)
390: env->xcc |= PSR_ZERO;
391: if ((int64_t) T0 < 0)
392: env->xcc |= PSR_NEG;
393: if (T0 < src1)
394: env->xcc |= PSR_CARRY;
395: if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
396: env->xcc |= PSR_OVF;
397: #else
398: if (!T0)
399: env->psr |= PSR_ZERO;
400: if ((int32_t) T0 < 0)
401: env->psr |= PSR_NEG;
402: if (T0 < src1)
403: env->psr |= PSR_CARRY;
404: if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
405: env->psr |= PSR_OVF;
406: #endif
407: FORCE_RET();
408: }
409:
410: void OPPROTO op_addx_T1_T0(void)
411: {
412: T0 += T1 + FLAG_SET(PSR_CARRY);
413: }
414:
415: void OPPROTO op_addx_T1_T0_cc(void)
416: {
417: target_ulong src1;
418:
419: src1 = T0;
420: T0 += T1 + FLAG_SET(PSR_CARRY);
421: env->psr = 0;
422: #ifdef TARGET_SPARC64
423: if (!(T0 & 0xffffffff))
424: env->psr |= PSR_ZERO;
425: if ((int32_t) T0 < 0)
426: env->psr |= PSR_NEG;
427: if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
428: env->psr |= PSR_CARRY;
429: if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
430: ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
431: env->psr |= PSR_OVF;
432:
433: env->xcc = 0;
434: if (!T0)
435: env->xcc |= PSR_ZERO;
436: if ((int64_t) T0 < 0)
437: env->xcc |= PSR_NEG;
438: if (T0 < src1)
439: env->xcc |= PSR_CARRY;
440: if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
441: env->xcc |= PSR_OVF;
442: #else
443: if (!T0)
444: env->psr |= PSR_ZERO;
445: if ((int32_t) T0 < 0)
446: env->psr |= PSR_NEG;
447: if (T0 < src1)
448: env->psr |= PSR_CARRY;
449: if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
450: env->psr |= PSR_OVF;
451: #endif
452: FORCE_RET();
453: }
454:
455: void OPPROTO op_sub_T1_T0(void)
456: {
457: T0 -= T1;
458: }
459:
460: void OPPROTO op_sub_T1_T0_cc(void)
461: {
462: target_ulong src1;
463:
464: src1 = T0;
465: T0 -= T1;
466: env->psr = 0;
467: #ifdef TARGET_SPARC64
468: if (!(T0 & 0xffffffff))
469: env->psr |= PSR_ZERO;
470: if ((int32_t) T0 < 0)
471: env->psr |= PSR_NEG;
472: if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
473: env->psr |= PSR_CARRY;
474: if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
475: ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
476: env->psr |= PSR_OVF;
477:
478: env->xcc = 0;
479: if (!T0)
480: env->xcc |= PSR_ZERO;
481: if ((int64_t) T0 < 0)
482: env->xcc |= PSR_NEG;
483: if (T0 < src1)
484: env->xcc |= PSR_CARRY;
485: if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
486: env->xcc |= PSR_OVF;
487: #else
488: if (!T0)
489: env->psr |= PSR_ZERO;
490: if ((int32_t) T0 < 0)
491: env->psr |= PSR_NEG;
492: if (src1 < T1)
493: env->psr |= PSR_CARRY;
494: if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
495: env->psr |= PSR_OVF;
496: #endif
497: FORCE_RET();
498: }
499:
500: void OPPROTO op_subx_T1_T0(void)
501: {
502: T0 -= T1 + FLAG_SET(PSR_CARRY);
503: }
504:
505: void OPPROTO op_subx_T1_T0_cc(void)
506: {
507: target_ulong src1;
508:
509: src1 = T0;
510: T0 -= T1 + FLAG_SET(PSR_CARRY);
511: env->psr = 0;
512: #ifdef TARGET_SPARC64
513: if (!(T0 & 0xffffffff))
514: env->psr |= PSR_ZERO;
515: if ((int32_t) T0 < 0)
516: env->psr |= PSR_NEG;
517: if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
518: env->psr |= PSR_CARRY;
519: if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
520: ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
521: env->psr |= PSR_OVF;
522:
523: env->xcc = 0;
524: if (!T0)
525: env->xcc |= PSR_ZERO;
526: if ((int64_t) T0 < 0)
527: env->xcc |= PSR_NEG;
528: if (T0 < src1)
529: env->xcc |= PSR_CARRY;
530: if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
531: env->xcc |= PSR_OVF;
532: #else
533: if (!T0)
534: env->psr |= PSR_ZERO;
535: if ((int32_t) T0 < 0)
536: env->psr |= PSR_NEG;
537: if (src1 < T1)
538: env->psr |= PSR_CARRY;
539: if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
540: env->psr |= PSR_OVF;
541: #endif
542: FORCE_RET();
543: }
544:
545: void OPPROTO op_and_T1_T0(void)
546: {
547: T0 &= T1;
548: }
549:
550: void OPPROTO op_or_T1_T0(void)
551: {
552: T0 |= T1;
553: }
554:
555: void OPPROTO op_xor_T1_T0(void)
556: {
557: T0 ^= T1;
558: }
559:
560: void OPPROTO op_andn_T1_T0(void)
561: {
562: T0 &= ~T1;
563: }
564:
565: void OPPROTO op_orn_T1_T0(void)
566: {
567: T0 |= ~T1;
568: }
569:
570: void OPPROTO op_xnor_T1_T0(void)
571: {
572: T0 ^= ~T1;
573: }
574:
575: void OPPROTO op_umul_T1_T0(void)
576: {
577: uint64_t res;
578: res = (uint64_t) T0 * (uint64_t) T1;
579: #ifdef TARGET_SPARC64
580: T0 = res;
581: #else
582: T0 = res & 0xffffffff;
583: #endif
584: env->y = res >> 32;
585: }
586:
587: void OPPROTO op_smul_T1_T0(void)
588: {
589: uint64_t res;
590: res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
591: #ifdef TARGET_SPARC64
592: T0 = res;
593: #else
594: T0 = res & 0xffffffff;
595: #endif
596: env->y = res >> 32;
597: }
598:
599: void OPPROTO op_mulscc_T1_T0(void)
600: {
601: unsigned int b1, N, V, b2;
602: target_ulong src1;
603:
604: N = FLAG_SET(PSR_NEG);
605: V = FLAG_SET(PSR_OVF);
606: b1 = N ^ V;
607: b2 = T0 & 1;
608: T0 = (b1 << 31) | (T0 >> 1);
609: if (!(env->y & 1))
610: T1 = 0;
611: /* do addition and update flags */
612: src1 = T0;
613: T0 += T1;
614: env->psr = 0;
615: if (!T0)
616: env->psr |= PSR_ZERO;
617: if ((int32_t) T0 < 0)
618: env->psr |= PSR_NEG;
619: if (T0 < src1)
620: env->psr |= PSR_CARRY;
621: if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
622: env->psr |= PSR_OVF;
623: env->y = (b2 << 31) | (env->y >> 1);
624: FORCE_RET();
625: }
626:
627: void OPPROTO op_udiv_T1_T0(void)
628: {
629: uint64_t x0;
630: uint32_t x1;
631:
632: x0 = T0 | ((uint64_t) (env->y) << 32);
633: x1 = T1;
634: x0 = x0 / x1;
635: if (x0 > 0xffffffff) {
636: T0 = 0xffffffff;
637: T1 = 1;
638: } else {
639: T0 = x0;
640: T1 = 0;
641: }
642: FORCE_RET();
643: }
644:
645: void OPPROTO op_sdiv_T1_T0(void)
646: {
647: int64_t x0;
648: int32_t x1;
649:
650: x0 = T0 | ((int64_t) (env->y) << 32);
651: x1 = T1;
652: x0 = x0 / x1;
653: if ((int32_t) x0 != x0) {
654: T0 = x0 < 0? 0x80000000: 0x7fffffff;
655: T1 = 1;
656: } else {
657: T0 = x0;
658: T1 = 0;
659: }
660: FORCE_RET();
661: }
662:
663: void OPPROTO op_div_cc(void)
664: {
665: env->psr = 0;
666: #ifdef TARGET_SPARC64
667: if (!T0)
668: env->psr |= PSR_ZERO;
669: if ((int32_t) T0 < 0)
670: env->psr |= PSR_NEG;
671: if (T1)
672: env->psr |= PSR_OVF;
673:
674: env->xcc = 0;
675: if (!T0)
676: env->xcc |= PSR_ZERO;
677: if ((int64_t) T0 < 0)
678: env->xcc |= PSR_NEG;
679: #else
680: if (!T0)
681: env->psr |= PSR_ZERO;
682: if ((int32_t) T0 < 0)
683: env->psr |= PSR_NEG;
684: if (T1)
685: env->psr |= PSR_OVF;
686: #endif
687: FORCE_RET();
688: }
689:
690: #ifdef TARGET_SPARC64
691: void OPPROTO op_mulx_T1_T0(void)
692: {
693: T0 *= T1;
694: FORCE_RET();
695: }
696:
697: void OPPROTO op_udivx_T1_T0(void)
698: {
699: T0 /= T1;
700: FORCE_RET();
701: }
702:
703: void OPPROTO op_sdivx_T1_T0(void)
704: {
705: if (T0 == INT64_MIN && T1 == -1)
706: T0 = INT64_MIN;
707: else
708: T0 /= (target_long) T1;
709: FORCE_RET();
710: }
711: #endif
712:
713: void OPPROTO op_logic_T0_cc(void)
714: {
715: env->psr = 0;
716: #ifdef TARGET_SPARC64
717: if (!(T0 & 0xffffffff))
718: env->psr |= PSR_ZERO;
719: if ((int32_t) T0 < 0)
720: env->psr |= PSR_NEG;
721:
722: env->xcc = 0;
723: if (!T0)
724: env->xcc |= PSR_ZERO;
725: if ((int64_t) T0 < 0)
726: env->xcc |= PSR_NEG;
727: #else
728: if (!T0)
729: env->psr |= PSR_ZERO;
730: if ((int32_t) T0 < 0)
731: env->psr |= PSR_NEG;
732: #endif
733: FORCE_RET();
734: }
735:
736: void OPPROTO op_sll(void)
737: {
738: T0 <<= T1;
739: }
740:
741: #ifdef TARGET_SPARC64
742: void OPPROTO op_srl(void)
743: {
744: T0 = (T0 & 0xffffffff) >> T1;
745: }
746:
747: void OPPROTO op_srlx(void)
748: {
749: T0 >>= T1;
750: }
751:
752: void OPPROTO op_sra(void)
753: {
754: T0 = ((int32_t) (T0 & 0xffffffff)) >> T1;
755: }
756:
757: void OPPROTO op_srax(void)
758: {
759: T0 = ((int64_t) T0) >> T1;
760: }
761: #else
762: void OPPROTO op_srl(void)
763: {
764: T0 >>= T1;
765: }
766:
767: void OPPROTO op_sra(void)
768: {
769: T0 = ((int32_t) T0) >> T1;
770: }
771: #endif
772:
773: /* Load and store */
774: #define MEMSUFFIX _raw
775: #include "op_mem.h"
776: #if !defined(CONFIG_USER_ONLY)
777: #define MEMSUFFIX _user
778: #include "op_mem.h"
779:
780: #define MEMSUFFIX _kernel
781: #include "op_mem.h"
782: #endif
783:
784: void OPPROTO op_ldfsr(void)
785: {
786: PUT_FSR32(env, *((uint32_t *) &FT0));
787: helper_ldfsr();
788: }
789:
790: void OPPROTO op_stfsr(void)
791: {
792: *((uint32_t *) &FT0) = GET_FSR32(env);
793: }
794:
795: #ifndef TARGET_SPARC64
796: void OPPROTO op_rdpsr(void)
797: {
798: do_rdpsr();
799: }
800:
801: void OPPROTO op_wrpsr(void)
802: {
803: do_wrpsr();
804: FORCE_RET();
805: }
806:
807: void OPPROTO op_rett(void)
808: {
809: helper_rett();
810: FORCE_RET();
811: }
812:
813: /* XXX: use another pointer for %iN registers to avoid slow wrapping
814: handling ? */
815: void OPPROTO op_save(void)
816: {
817: uint32_t cwp;
818: cwp = (env->cwp - 1) & (NWINDOWS - 1);
819: if (env->wim & (1 << cwp)) {
820: raise_exception(TT_WIN_OVF);
821: }
822: set_cwp(cwp);
823: FORCE_RET();
824: }
825:
826: void OPPROTO op_restore(void)
827: {
828: uint32_t cwp;
829: cwp = (env->cwp + 1) & (NWINDOWS - 1);
830: if (env->wim & (1 << cwp)) {
831: raise_exception(TT_WIN_UNF);
832: }
833: set_cwp(cwp);
834: FORCE_RET();
835: }
836: #else
837: void OPPROTO op_rdccr(void)
838: {
839: T0 = GET_CCR(env);
840: }
841:
842: void OPPROTO op_wrccr(void)
843: {
844: PUT_CCR(env, T0);
845: }
846:
847: void OPPROTO op_rdtick(void)
848: {
849: T0 = 0; // XXX read cycle counter and bit 31
850: }
851:
852: void OPPROTO op_wrtick(void)
853: {
854: // XXX write cycle counter and bit 31
855: }
856:
857: void OPPROTO op_rdtpc(void)
858: {
859: T0 = env->tpc[env->tl];
860: }
861:
862: void OPPROTO op_wrtpc(void)
863: {
864: env->tpc[env->tl] = T0;
865: }
866:
867: void OPPROTO op_rdtnpc(void)
868: {
869: T0 = env->tnpc[env->tl];
870: }
871:
872: void OPPROTO op_wrtnpc(void)
873: {
874: env->tnpc[env->tl] = T0;
875: }
876:
877: void OPPROTO op_rdtstate(void)
878: {
879: T0 = env->tstate[env->tl];
880: }
881:
882: void OPPROTO op_wrtstate(void)
883: {
884: env->tstate[env->tl] = T0;
885: }
886:
887: void OPPROTO op_rdtt(void)
888: {
889: T0 = env->tt[env->tl];
890: }
891:
892: void OPPROTO op_wrtt(void)
893: {
894: env->tt[env->tl] = T0;
895: }
896:
897: void OPPROTO op_rdpstate(void)
898: {
899: T0 = env->pstate;
900: }
901:
902: void OPPROTO op_wrpstate(void)
903: {
904: do_wrpstate();
905: }
906:
907: // CWP handling is reversed in V9, but we still use the V8 register
908: // order.
909: void OPPROTO op_rdcwp(void)
910: {
911: T0 = NWINDOWS - 1 - env->cwp;
912: }
913:
914: void OPPROTO op_wrcwp(void)
915: {
916: env->cwp = NWINDOWS - 1 - T0;
917: }
918:
919: /* XXX: use another pointer for %iN registers to avoid slow wrapping
920: handling ? */
921: void OPPROTO op_save(void)
922: {
923: uint32_t cwp;
924: cwp = (env->cwp - 1) & (NWINDOWS - 1);
925: if (env->cansave == 0) {
926: raise_exception(TT_SPILL | (env->otherwin != 0 ?
927: (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
928: ((env->wstate & 0x7) << 2)));
929: } else {
930: if (env->cleanwin - env->canrestore == 0) {
931: // XXX Clean windows without trap
932: raise_exception(TT_CLRWIN);
933: } else {
934: env->cansave--;
935: env->canrestore++;
936: set_cwp(cwp);
937: }
938: }
939: FORCE_RET();
940: }
941:
942: void OPPROTO op_restore(void)
943: {
944: uint32_t cwp;
945: cwp = (env->cwp + 1) & (NWINDOWS - 1);
946: if (env->canrestore == 0) {
947: raise_exception(TT_FILL | (env->otherwin != 0 ?
948: (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
949: ((env->wstate & 0x7) << 2)));
950: } else {
951: env->cansave++;
952: env->canrestore--;
953: set_cwp(cwp);
954: }
955: FORCE_RET();
956: }
957: #endif
958:
959: void OPPROTO op_exception(void)
960: {
961: env->exception_index = PARAM1;
962: cpu_loop_exit();
963: }
964:
965: void OPPROTO op_trap_T0(void)
966: {
967: env->exception_index = TT_TRAP + (T0 & 0x7f);
968: cpu_loop_exit();
969: }
970:
971: void OPPROTO op_trapcc_T0(void)
972: {
973: if (T2) {
974: env->exception_index = TT_TRAP + (T0 & 0x7f);
975: cpu_loop_exit();
976: }
977: FORCE_RET();
978: }
979:
980: void OPPROTO op_trap_ifnofpu(void)
981: {
982: if (!env->psref) {
983: env->exception_index = TT_NFPU_INSN;
984: cpu_loop_exit();
985: }
986: FORCE_RET();
987: }
988:
989: void OPPROTO op_fpexception_im(void)
990: {
991: env->exception_index = TT_FP_EXCP;
992: env->fsr &= ~FSR_FTT_MASK;
993: env->fsr |= PARAM1;
994: cpu_loop_exit();
995: FORCE_RET();
996: }
997:
998: void OPPROTO op_debug(void)
999: {
1000: helper_debug();
1001: }
1002:
1003: void OPPROTO op_exit_tb(void)
1004: {
1005: EXIT_TB();
1006: }
1007:
1008: void OPPROTO op_eval_ba(void)
1009: {
1010: T2 = 1;
1011: }
1012:
1013: void OPPROTO op_eval_be(void)
1014: {
1015: T2 = FLAG_SET(PSR_ZERO);
1016: }
1017:
1018: void OPPROTO op_eval_ble(void)
1019: {
1020: target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1021:
1022: T2 = Z | (N ^ V);
1023: }
1024:
1025: void OPPROTO op_eval_bl(void)
1026: {
1027: target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1028:
1029: T2 = N ^ V;
1030: }
1031:
1032: void OPPROTO op_eval_bleu(void)
1033: {
1034: target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1035:
1036: T2 = C | Z;
1037: }
1038:
1039: void OPPROTO op_eval_bcs(void)
1040: {
1041: T2 = FLAG_SET(PSR_CARRY);
1042: }
1043:
1044: void OPPROTO op_eval_bvs(void)
1045: {
1046: T2 = FLAG_SET(PSR_OVF);
1047: }
1048:
1049: void OPPROTO op_eval_bn(void)
1050: {
1051: T2 = 0;
1052: }
1053:
1054: void OPPROTO op_eval_bneg(void)
1055: {
1056: T2 = FLAG_SET(PSR_NEG);
1057: }
1058:
1059: void OPPROTO op_eval_bne(void)
1060: {
1061: T2 = !FLAG_SET(PSR_ZERO);
1062: }
1063:
1064: void OPPROTO op_eval_bg(void)
1065: {
1066: target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1067:
1068: T2 = !(Z | (N ^ V));
1069: }
1070:
1071: void OPPROTO op_eval_bge(void)
1072: {
1073: target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1074:
1075: T2 = !(N ^ V);
1076: }
1077:
1078: void OPPROTO op_eval_bgu(void)
1079: {
1080: target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1081:
1082: T2 = !(C | Z);
1083: }
1084:
1085: void OPPROTO op_eval_bcc(void)
1086: {
1087: T2 = !FLAG_SET(PSR_CARRY);
1088: }
1089:
1090: void OPPROTO op_eval_bpos(void)
1091: {
1092: T2 = !FLAG_SET(PSR_NEG);
1093: }
1094:
1095: void OPPROTO op_eval_bvc(void)
1096: {
1097: T2 = !FLAG_SET(PSR_OVF);
1098: }
1099:
1100: #ifdef TARGET_SPARC64
1101: void OPPROTO op_eval_xbe(void)
1102: {
1103: T2 = XFLAG_SET(PSR_ZERO);
1104: }
1105:
1106: void OPPROTO op_eval_xble(void)
1107: {
1108: target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1109:
1110: T2 = Z | (N ^ V);
1111: }
1112:
1113: void OPPROTO op_eval_xbl(void)
1114: {
1115: target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1116:
1117: T2 = N ^ V;
1118: }
1119:
1120: void OPPROTO op_eval_xbleu(void)
1121: {
1122: target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1123:
1124: T2 = C | Z;
1125: }
1126:
1127: void OPPROTO op_eval_xbcs(void)
1128: {
1129: T2 = XFLAG_SET(PSR_CARRY);
1130: }
1131:
1132: void OPPROTO op_eval_xbvs(void)
1133: {
1134: T2 = XFLAG_SET(PSR_OVF);
1135: }
1136:
1137: void OPPROTO op_eval_xbneg(void)
1138: {
1139: T2 = XFLAG_SET(PSR_NEG);
1140: }
1141:
1142: void OPPROTO op_eval_xbne(void)
1143: {
1144: T2 = !XFLAG_SET(PSR_ZERO);
1145: }
1146:
1147: void OPPROTO op_eval_xbg(void)
1148: {
1149: target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1150:
1151: T2 = !(Z | (N ^ V));
1152: }
1153:
1154: void OPPROTO op_eval_xbge(void)
1155: {
1156: target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1157:
1158: T2 = !(N ^ V);
1159: }
1160:
1161: void OPPROTO op_eval_xbgu(void)
1162: {
1163: target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1164:
1165: T2 = !(C | Z);
1166: }
1167:
1168: void OPPROTO op_eval_xbcc(void)
1169: {
1170: T2 = !XFLAG_SET(PSR_CARRY);
1171: }
1172:
1173: void OPPROTO op_eval_xbpos(void)
1174: {
1175: T2 = !XFLAG_SET(PSR_NEG);
1176: }
1177:
1178: void OPPROTO op_eval_xbvc(void)
1179: {
1180: T2 = !XFLAG_SET(PSR_OVF);
1181: }
1182: #endif
1183:
1184: #define FCC
1185: #define FFLAG_SET(x) (env->fsr & x? 1: 0)
1186: #include "fbranch_template.h"
1187:
1188: #ifdef TARGET_SPARC64
1189: #define FCC _fcc1
1190: #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1191: #include "fbranch_template.h"
1192: #define FCC _fcc2
1193: #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1194: #include "fbranch_template.h"
1195: #define FCC _fcc3
1196: #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1197: #include "fbranch_template.h"
1198: #endif
1199:
1200: #ifdef TARGET_SPARC64
1201: void OPPROTO op_eval_brz(void)
1202: {
1203: T2 = (T0 == 0);
1204: }
1205:
1206: void OPPROTO op_eval_brnz(void)
1207: {
1208: T2 = (T0 != 0);
1209: }
1210:
1211: void OPPROTO op_eval_brlz(void)
1212: {
1213: T2 = ((int64_t)T0 < 0);
1214: }
1215:
1216: void OPPROTO op_eval_brlez(void)
1217: {
1218: T2 = ((int64_t)T0 <= 0);
1219: }
1220:
1221: void OPPROTO op_eval_brgz(void)
1222: {
1223: T2 = ((int64_t)T0 > 0);
1224: }
1225:
1226: void OPPROTO op_eval_brgez(void)
1227: {
1228: T2 = ((int64_t)T0 >= 0);
1229: }
1230:
1231: void OPPROTO op_jmp_im64(void)
1232: {
1233: env->pc = PARAMQ1;
1234: }
1235:
1236: void OPPROTO op_movq_npc_im64(void)
1237: {
1238: env->npc = PARAMQ1;
1239: }
1240: #endif
1241:
1242: void OPPROTO op_jmp_im(void)
1243: {
1244: env->pc = (uint32_t)PARAM1;
1245: }
1246:
1247: void OPPROTO op_movl_npc_im(void)
1248: {
1249: env->npc = (uint32_t)PARAM1;
1250: }
1251:
1252: void OPPROTO op_movl_npc_T0(void)
1253: {
1254: env->npc = T0;
1255: }
1256:
1257: void OPPROTO op_mov_pc_npc(void)
1258: {
1259: env->pc = env->npc;
1260: }
1261:
1262: void OPPROTO op_next_insn(void)
1263: {
1264: env->pc = env->npc;
1265: env->npc = env->npc + 4;
1266: }
1267:
1268: void OPPROTO op_goto_tb0(void)
1269: {
1270: GOTO_TB(op_goto_tb0, PARAM1, 0);
1271: }
1272:
1273: void OPPROTO op_goto_tb1(void)
1274: {
1275: GOTO_TB(op_goto_tb1, PARAM1, 1);
1276: }
1277:
1278: void OPPROTO op_jmp_label(void)
1279: {
1280: GOTO_LABEL_PARAM(1);
1281: }
1282:
1283: void OPPROTO op_jnz_T2_label(void)
1284: {
1285: if (T2)
1286: GOTO_LABEL_PARAM(1);
1287: FORCE_RET();
1288: }
1289:
1290: void OPPROTO op_jz_T2_label(void)
1291: {
1292: if (!T2)
1293: GOTO_LABEL_PARAM(1);
1294: FORCE_RET();
1295: }
1296:
1297: void OPPROTO op_flush_T0(void)
1298: {
1299: helper_flush(T0);
1300: }
1301:
1302: void OPPROTO op_fnegs(void)
1303: {
1304: FT0 = -FT1;
1305: }
1306:
1307: void OPPROTO op_fabss(void)
1308: {
1309: do_fabss();
1310: }
1311:
1312: #ifdef TARGET_SPARC64
1313: void OPPROTO op_fnegd(void)
1314: {
1315: DT0 = -DT1;
1316: }
1317:
1318: void OPPROTO op_fabsd(void)
1319: {
1320: do_fabsd();
1321: }
1322: #endif
1323:
1324: void OPPROTO op_fsqrts(void)
1325: {
1326: do_fsqrts();
1327: }
1328:
1329: void OPPROTO op_fsqrtd(void)
1330: {
1331: do_fsqrtd();
1332: }
1333:
1334: void OPPROTO op_fmuls(void)
1335: {
1336: FT0 *= FT1;
1337: }
1338:
1339: void OPPROTO op_fmuld(void)
1340: {
1341: DT0 *= DT1;
1342: }
1343:
1344: void OPPROTO op_fsmuld(void)
1345: {
1346: DT0 = FT0 * FT1;
1347: }
1348:
1349: void OPPROTO op_fadds(void)
1350: {
1351: FT0 += FT1;
1352: }
1353:
1354: void OPPROTO op_faddd(void)
1355: {
1356: DT0 += DT1;
1357: }
1358:
1359: void OPPROTO op_fsubs(void)
1360: {
1361: FT0 -= FT1;
1362: }
1363:
1364: void OPPROTO op_fsubd(void)
1365: {
1366: DT0 -= DT1;
1367: }
1368:
1369: void OPPROTO op_fdivs(void)
1370: {
1371: FT0 /= FT1;
1372: }
1373:
1374: void OPPROTO op_fdivd(void)
1375: {
1376: DT0 /= DT1;
1377: }
1378:
1379: void OPPROTO op_fcmps(void)
1380: {
1381: do_fcmps();
1382: }
1383:
1384: void OPPROTO op_fcmpd(void)
1385: {
1386: do_fcmpd();
1387: }
1388:
1389: #ifdef TARGET_SPARC64
1390: void OPPROTO op_fcmps_fcc1(void)
1391: {
1392: do_fcmps_fcc1();
1393: }
1394:
1395: void OPPROTO op_fcmpd_fcc1(void)
1396: {
1397: do_fcmpd_fcc1();
1398: }
1399:
1400: void OPPROTO op_fcmps_fcc2(void)
1401: {
1402: do_fcmps_fcc2();
1403: }
1404:
1405: void OPPROTO op_fcmpd_fcc2(void)
1406: {
1407: do_fcmpd_fcc2();
1408: }
1409:
1410: void OPPROTO op_fcmps_fcc3(void)
1411: {
1412: do_fcmps_fcc3();
1413: }
1414:
1415: void OPPROTO op_fcmpd_fcc3(void)
1416: {
1417: do_fcmpd_fcc3();
1418: }
1419: #endif
1420:
1421: #ifdef USE_INT_TO_FLOAT_HELPERS
1422: void OPPROTO op_fitos(void)
1423: {
1424: do_fitos();
1425: }
1426:
1427: void OPPROTO op_fitod(void)
1428: {
1429: do_fitod();
1430: }
1431: #else
1432: void OPPROTO op_fitos(void)
1433: {
1434: FT0 = (float) *((int32_t *)&FT1);
1435: }
1436:
1437: void OPPROTO op_fitod(void)
1438: {
1439: DT0 = (double) *((int32_t *)&FT1);
1440: }
1441:
1442: #ifdef TARGET_SPARC64
1443: void OPPROTO op_fxtos(void)
1444: {
1445: FT0 = (float) *((int64_t *)&DT1);
1446: }
1447:
1448: void OPPROTO op_fxtod(void)
1449: {
1450: DT0 = (double) *((int64_t *)&DT1);
1451: }
1452: #endif
1453: #endif
1454:
1455: void OPPROTO op_fdtos(void)
1456: {
1457: FT0 = (float) DT1;
1458: }
1459:
1460: void OPPROTO op_fstod(void)
1461: {
1462: DT0 = (double) FT1;
1463: }
1464:
1465: void OPPROTO op_fstoi(void)
1466: {
1467: *((int32_t *)&FT0) = (int32_t) FT1;
1468: }
1469:
1470: void OPPROTO op_fdtoi(void)
1471: {
1472: *((int32_t *)&FT0) = (int32_t) DT1;
1473: }
1474:
1475: #ifdef TARGET_SPARC64
1476: void OPPROTO op_fstox(void)
1477: {
1478: *((int64_t *)&DT0) = (int64_t) FT1;
1479: }
1480:
1481: void OPPROTO op_fdtox(void)
1482: {
1483: *((int64_t *)&DT0) = (int64_t) DT1;
1484: }
1485:
1486: void OPPROTO op_fmovs_cc(void)
1487: {
1488: if (T2)
1489: FT0 = FT1;
1490: }
1491:
1492: void OPPROTO op_fmovd_cc(void)
1493: {
1494: if (T2)
1495: DT0 = DT1;
1496: }
1497:
1498: void OPPROTO op_mov_cc(void)
1499: {
1500: if (T2)
1501: T0 = T1;
1502: }
1503:
1504: void OPPROTO op_flushw(void)
1505: {
1506: if (env->cansave != NWINDOWS - 2) {
1507: raise_exception(TT_SPILL | (env->otherwin != 0 ?
1508: (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1509: ((env->wstate & 0x7) << 2)));
1510: }
1511: }
1512:
1513: void OPPROTO op_saved(void)
1514: {
1515: env->cansave++;
1516: if (env->otherwin == 0)
1517: env->canrestore--;
1518: }
1519:
1520: void OPPROTO op_restored(void)
1521: {
1522: env->canrestore++;
1523: if (env->cleanwin < NWINDOWS - 1)
1524: env->cleanwin++;
1525: if (env->otherwin == 0)
1526: env->cansave--;
1527: else
1528: env->otherwin--;
1529: }
1530:
1531: void OPPROTO op_popc(void)
1532: {
1533: do_popc();
1534: }
1535:
1536: void OPPROTO op_done(void)
1537: {
1538: do_done();
1539: }
1540:
1541: void OPPROTO op_retry(void)
1542: {
1543: do_retry();
1544: }
1545:
1546: void OPPROTO op_sir(void)
1547: {
1548: // XXX
1549:
1550: }
1551:
1552: void OPPROTO op_ld_asi_reg()
1553: {
1554: T0 += PARAM1;
1555: helper_ld_asi(env->asi, PARAM2, PARAM3);
1556: }
1557:
1558: void OPPROTO op_st_asi_reg()
1559: {
1560: T0 += PARAM1;
1561: helper_st_asi(env->asi, PARAM2, PARAM3);
1562: }
1563: #endif
1564:
1565: void OPPROTO op_ld_asi()
1566: {
1567: helper_ld_asi(PARAM1, PARAM2, PARAM3);
1568: }
1569:
1570: void OPPROTO op_st_asi()
1571: {
1572: helper_st_asi(PARAM1, PARAM2, PARAM3);
1573: }
1574:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.