|
|
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;
1.1.1.2 root 382: if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
1.1 root 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: src1 = T0;
1.1.1.3 ! root 419: if (FLAG_SET(PSR_CARRY))
! 420: {
! 421: T0 += T1 + 1;
! 422: env->psr = 0;
! 423: #ifdef TARGET_SPARC64
! 424: if ((T0 & 0xffffffff) <= (src1 & 0xffffffff))
! 425: env->psr |= PSR_CARRY;
! 426: env->xcc = 0;
! 427: if (T0 <= src1)
! 428: env->xcc |= PSR_CARRY;
! 429: #else
! 430: if (T0 <= src1)
! 431: env->psr |= PSR_CARRY;
! 432: #endif
! 433: }
! 434: else
! 435: {
! 436: T0 += T1;
! 437: env->psr = 0;
! 438: #ifdef TARGET_SPARC64
! 439: if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
! 440: env->psr |= PSR_CARRY;
! 441: env->xcc = 0;
! 442: if (T0 < src1)
! 443: env->xcc |= PSR_CARRY;
! 444: #else
! 445: if (T0 < src1)
! 446: env->psr |= PSR_CARRY;
! 447: #endif
! 448: }
1.1 root 449: #ifdef TARGET_SPARC64
450: if (!(T0 & 0xffffffff))
451: env->psr |= PSR_ZERO;
452: if ((int32_t) T0 < 0)
453: env->psr |= PSR_NEG;
454: if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
455: ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
456: env->psr |= PSR_OVF;
457:
458: if (!T0)
459: env->xcc |= PSR_ZERO;
460: if ((int64_t) T0 < 0)
461: env->xcc |= PSR_NEG;
462: if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
463: env->xcc |= PSR_OVF;
464: #else
465: if (!T0)
466: env->psr |= PSR_ZERO;
467: if ((int32_t) T0 < 0)
468: env->psr |= PSR_NEG;
469: if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
470: env->psr |= PSR_OVF;
471: #endif
472: FORCE_RET();
473: }
474:
475: void OPPROTO op_sub_T1_T0(void)
476: {
477: T0 -= T1;
478: }
479:
480: void OPPROTO op_sub_T1_T0_cc(void)
481: {
482: target_ulong src1;
483:
484: src1 = T0;
485: T0 -= T1;
486: env->psr = 0;
487: #ifdef TARGET_SPARC64
488: if (!(T0 & 0xffffffff))
489: env->psr |= PSR_ZERO;
490: if ((int32_t) T0 < 0)
491: env->psr |= PSR_NEG;
492: if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
493: env->psr |= PSR_CARRY;
494: if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
495: ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
496: env->psr |= PSR_OVF;
497:
498: env->xcc = 0;
499: if (!T0)
500: env->xcc |= PSR_ZERO;
501: if ((int64_t) T0 < 0)
502: env->xcc |= PSR_NEG;
1.1.1.2 root 503: if (src1 < T1)
1.1 root 504: env->xcc |= PSR_CARRY;
505: if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
506: env->xcc |= PSR_OVF;
507: #else
508: if (!T0)
509: env->psr |= PSR_ZERO;
510: if ((int32_t) T0 < 0)
511: env->psr |= PSR_NEG;
512: if (src1 < T1)
513: env->psr |= PSR_CARRY;
514: if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
515: env->psr |= PSR_OVF;
516: #endif
517: FORCE_RET();
518: }
519:
520: void OPPROTO op_subx_T1_T0(void)
521: {
522: T0 -= T1 + FLAG_SET(PSR_CARRY);
523: }
524:
525: void OPPROTO op_subx_T1_T0_cc(void)
526: {
527: target_ulong src1;
528: src1 = T0;
1.1.1.3 ! root 529: if (FLAG_SET(PSR_CARRY))
! 530: {
! 531: T0 -= T1 + 1;
! 532: env->psr = 0;
! 533: #ifdef TARGET_SPARC64
! 534: if ((src1 & 0xffffffff) <= (T1 & 0xffffffff))
! 535: env->psr |= PSR_CARRY;
! 536: env->xcc = 0;
! 537: if (src1 <= T1)
! 538: env->xcc |= PSR_CARRY;
! 539: #else
! 540: if (src1 <= T1)
! 541: env->psr |= PSR_CARRY;
! 542: #endif
! 543: }
! 544: else
! 545: {
! 546: T0 -= T1;
! 547: env->psr = 0;
! 548: #ifdef TARGET_SPARC64
! 549: if ((src1 & 0xffffffff) < (T1 & 0xffffffff))
! 550: env->psr |= PSR_CARRY;
! 551: env->xcc = 0;
! 552: if (src1 < T1)
! 553: env->xcc |= PSR_CARRY;
! 554: #else
! 555: if (src1 < T1)
! 556: env->psr |= PSR_CARRY;
! 557: #endif
! 558: }
1.1 root 559: #ifdef TARGET_SPARC64
560: if (!(T0 & 0xffffffff))
561: env->psr |= PSR_ZERO;
562: if ((int32_t) T0 < 0)
563: env->psr |= PSR_NEG;
564: if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
565: ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
566: env->psr |= PSR_OVF;
567:
568: if (!T0)
569: env->xcc |= PSR_ZERO;
570: if ((int64_t) T0 < 0)
571: env->xcc |= PSR_NEG;
572: if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
573: env->xcc |= PSR_OVF;
574: #else
575: if (!T0)
576: env->psr |= PSR_ZERO;
577: if ((int32_t) T0 < 0)
578: env->psr |= PSR_NEG;
579: if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
580: env->psr |= PSR_OVF;
581: #endif
582: FORCE_RET();
583: }
584:
585: void OPPROTO op_and_T1_T0(void)
586: {
587: T0 &= T1;
588: }
589:
590: void OPPROTO op_or_T1_T0(void)
591: {
592: T0 |= T1;
593: }
594:
595: void OPPROTO op_xor_T1_T0(void)
596: {
597: T0 ^= T1;
598: }
599:
600: void OPPROTO op_andn_T1_T0(void)
601: {
602: T0 &= ~T1;
603: }
604:
605: void OPPROTO op_orn_T1_T0(void)
606: {
607: T0 |= ~T1;
608: }
609:
610: void OPPROTO op_xnor_T1_T0(void)
611: {
612: T0 ^= ~T1;
613: }
614:
615: void OPPROTO op_umul_T1_T0(void)
616: {
617: uint64_t res;
618: res = (uint64_t) T0 * (uint64_t) T1;
619: #ifdef TARGET_SPARC64
620: T0 = res;
621: #else
622: T0 = res & 0xffffffff;
623: #endif
624: env->y = res >> 32;
625: }
626:
627: void OPPROTO op_smul_T1_T0(void)
628: {
629: uint64_t res;
630: res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
631: #ifdef TARGET_SPARC64
632: T0 = res;
633: #else
634: T0 = res & 0xffffffff;
635: #endif
636: env->y = res >> 32;
637: }
638:
639: void OPPROTO op_mulscc_T1_T0(void)
640: {
641: unsigned int b1, N, V, b2;
642: target_ulong src1;
643:
644: N = FLAG_SET(PSR_NEG);
645: V = FLAG_SET(PSR_OVF);
646: b1 = N ^ V;
647: b2 = T0 & 1;
648: T0 = (b1 << 31) | (T0 >> 1);
649: if (!(env->y & 1))
650: T1 = 0;
651: /* do addition and update flags */
652: src1 = T0;
653: T0 += T1;
654: env->psr = 0;
655: if (!T0)
656: env->psr |= PSR_ZERO;
657: if ((int32_t) T0 < 0)
658: env->psr |= PSR_NEG;
659: if (T0 < src1)
660: env->psr |= PSR_CARRY;
661: if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
662: env->psr |= PSR_OVF;
663: env->y = (b2 << 31) | (env->y >> 1);
664: FORCE_RET();
665: }
666:
667: void OPPROTO op_udiv_T1_T0(void)
668: {
669: uint64_t x0;
670: uint32_t x1;
671:
672: x0 = T0 | ((uint64_t) (env->y) << 32);
673: x1 = T1;
674: x0 = x0 / x1;
675: if (x0 > 0xffffffff) {
676: T0 = 0xffffffff;
677: T1 = 1;
678: } else {
679: T0 = x0;
680: T1 = 0;
681: }
682: FORCE_RET();
683: }
684:
685: void OPPROTO op_sdiv_T1_T0(void)
686: {
687: int64_t x0;
688: int32_t x1;
689:
690: x0 = T0 | ((int64_t) (env->y) << 32);
691: x1 = T1;
692: x0 = x0 / x1;
693: if ((int32_t) x0 != x0) {
694: T0 = x0 < 0? 0x80000000: 0x7fffffff;
695: T1 = 1;
696: } else {
697: T0 = x0;
698: T1 = 0;
699: }
700: FORCE_RET();
701: }
702:
703: void OPPROTO op_div_cc(void)
704: {
705: env->psr = 0;
706: #ifdef TARGET_SPARC64
707: if (!T0)
708: env->psr |= PSR_ZERO;
709: if ((int32_t) T0 < 0)
710: env->psr |= PSR_NEG;
711: if (T1)
712: env->psr |= PSR_OVF;
713:
714: env->xcc = 0;
715: if (!T0)
716: env->xcc |= PSR_ZERO;
717: if ((int64_t) T0 < 0)
718: env->xcc |= PSR_NEG;
719: #else
720: if (!T0)
721: env->psr |= PSR_ZERO;
722: if ((int32_t) T0 < 0)
723: env->psr |= PSR_NEG;
724: if (T1)
725: env->psr |= PSR_OVF;
726: #endif
727: FORCE_RET();
728: }
729:
730: #ifdef TARGET_SPARC64
731: void OPPROTO op_mulx_T1_T0(void)
732: {
733: T0 *= T1;
734: FORCE_RET();
735: }
736:
737: void OPPROTO op_udivx_T1_T0(void)
738: {
739: T0 /= T1;
740: FORCE_RET();
741: }
742:
743: void OPPROTO op_sdivx_T1_T0(void)
744: {
745: if (T0 == INT64_MIN && T1 == -1)
746: T0 = INT64_MIN;
747: else
748: T0 /= (target_long) T1;
749: FORCE_RET();
750: }
751: #endif
752:
753: void OPPROTO op_logic_T0_cc(void)
754: {
755: env->psr = 0;
756: #ifdef TARGET_SPARC64
757: if (!(T0 & 0xffffffff))
758: env->psr |= PSR_ZERO;
759: if ((int32_t) T0 < 0)
760: env->psr |= PSR_NEG;
761:
762: env->xcc = 0;
763: if (!T0)
764: env->xcc |= PSR_ZERO;
765: if ((int64_t) T0 < 0)
766: env->xcc |= PSR_NEG;
767: #else
768: if (!T0)
769: env->psr |= PSR_ZERO;
770: if ((int32_t) T0 < 0)
771: env->psr |= PSR_NEG;
772: #endif
773: FORCE_RET();
774: }
775:
776: void OPPROTO op_sll(void)
777: {
778: T0 <<= T1;
779: }
780:
781: #ifdef TARGET_SPARC64
782: void OPPROTO op_srl(void)
783: {
784: T0 = (T0 & 0xffffffff) >> T1;
785: }
786:
787: void OPPROTO op_srlx(void)
788: {
789: T0 >>= T1;
790: }
791:
792: void OPPROTO op_sra(void)
793: {
794: T0 = ((int32_t) (T0 & 0xffffffff)) >> T1;
795: }
796:
797: void OPPROTO op_srax(void)
798: {
799: T0 = ((int64_t) T0) >> T1;
800: }
801: #else
802: void OPPROTO op_srl(void)
803: {
804: T0 >>= T1;
805: }
806:
807: void OPPROTO op_sra(void)
808: {
809: T0 = ((int32_t) T0) >> T1;
810: }
811: #endif
812:
813: /* Load and store */
814: #define MEMSUFFIX _raw
815: #include "op_mem.h"
816: #if !defined(CONFIG_USER_ONLY)
817: #define MEMSUFFIX _user
818: #include "op_mem.h"
819:
820: #define MEMSUFFIX _kernel
821: #include "op_mem.h"
822: #endif
823:
824: void OPPROTO op_ldfsr(void)
825: {
826: PUT_FSR32(env, *((uint32_t *) &FT0));
827: helper_ldfsr();
828: }
829:
830: void OPPROTO op_stfsr(void)
831: {
832: *((uint32_t *) &FT0) = GET_FSR32(env);
833: }
834:
835: #ifndef TARGET_SPARC64
836: void OPPROTO op_rdpsr(void)
837: {
838: do_rdpsr();
839: }
840:
841: void OPPROTO op_wrpsr(void)
842: {
843: do_wrpsr();
844: FORCE_RET();
845: }
846:
847: void OPPROTO op_rett(void)
848: {
849: helper_rett();
850: FORCE_RET();
851: }
852:
853: /* XXX: use another pointer for %iN registers to avoid slow wrapping
854: handling ? */
855: void OPPROTO op_save(void)
856: {
857: uint32_t cwp;
858: cwp = (env->cwp - 1) & (NWINDOWS - 1);
859: if (env->wim & (1 << cwp)) {
860: raise_exception(TT_WIN_OVF);
861: }
862: set_cwp(cwp);
863: FORCE_RET();
864: }
865:
866: void OPPROTO op_restore(void)
867: {
868: uint32_t cwp;
869: cwp = (env->cwp + 1) & (NWINDOWS - 1);
870: if (env->wim & (1 << cwp)) {
871: raise_exception(TT_WIN_UNF);
872: }
873: set_cwp(cwp);
874: FORCE_RET();
875: }
876: #else
877: void OPPROTO op_rdccr(void)
878: {
879: T0 = GET_CCR(env);
880: }
881:
882: void OPPROTO op_wrccr(void)
883: {
884: PUT_CCR(env, T0);
885: }
886:
887: void OPPROTO op_rdtick(void)
888: {
889: T0 = 0; // XXX read cycle counter and bit 31
890: }
891:
892: void OPPROTO op_wrtick(void)
893: {
894: // XXX write cycle counter and bit 31
895: }
896:
897: void OPPROTO op_rdtpc(void)
898: {
899: T0 = env->tpc[env->tl];
900: }
901:
902: void OPPROTO op_wrtpc(void)
903: {
904: env->tpc[env->tl] = T0;
905: }
906:
907: void OPPROTO op_rdtnpc(void)
908: {
909: T0 = env->tnpc[env->tl];
910: }
911:
912: void OPPROTO op_wrtnpc(void)
913: {
914: env->tnpc[env->tl] = T0;
915: }
916:
917: void OPPROTO op_rdtstate(void)
918: {
919: T0 = env->tstate[env->tl];
920: }
921:
922: void OPPROTO op_wrtstate(void)
923: {
924: env->tstate[env->tl] = T0;
925: }
926:
927: void OPPROTO op_rdtt(void)
928: {
929: T0 = env->tt[env->tl];
930: }
931:
932: void OPPROTO op_wrtt(void)
933: {
934: env->tt[env->tl] = T0;
935: }
936:
937: void OPPROTO op_rdpstate(void)
938: {
939: T0 = env->pstate;
940: }
941:
942: void OPPROTO op_wrpstate(void)
943: {
944: do_wrpstate();
945: }
946:
947: // CWP handling is reversed in V9, but we still use the V8 register
948: // order.
949: void OPPROTO op_rdcwp(void)
950: {
951: T0 = NWINDOWS - 1 - env->cwp;
952: }
953:
954: void OPPROTO op_wrcwp(void)
955: {
956: env->cwp = NWINDOWS - 1 - T0;
957: }
958:
959: /* XXX: use another pointer for %iN registers to avoid slow wrapping
960: handling ? */
961: void OPPROTO op_save(void)
962: {
963: uint32_t cwp;
964: cwp = (env->cwp - 1) & (NWINDOWS - 1);
965: if (env->cansave == 0) {
966: raise_exception(TT_SPILL | (env->otherwin != 0 ?
967: (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
968: ((env->wstate & 0x7) << 2)));
969: } else {
970: if (env->cleanwin - env->canrestore == 0) {
971: // XXX Clean windows without trap
972: raise_exception(TT_CLRWIN);
973: } else {
974: env->cansave--;
975: env->canrestore++;
976: set_cwp(cwp);
977: }
978: }
979: FORCE_RET();
980: }
981:
982: void OPPROTO op_restore(void)
983: {
984: uint32_t cwp;
985: cwp = (env->cwp + 1) & (NWINDOWS - 1);
986: if (env->canrestore == 0) {
987: raise_exception(TT_FILL | (env->otherwin != 0 ?
988: (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
989: ((env->wstate & 0x7) << 2)));
990: } else {
991: env->cansave++;
992: env->canrestore--;
993: set_cwp(cwp);
994: }
995: FORCE_RET();
996: }
997: #endif
998:
999: void OPPROTO op_exception(void)
1000: {
1001: env->exception_index = PARAM1;
1002: cpu_loop_exit();
1003: }
1004:
1005: void OPPROTO op_trap_T0(void)
1006: {
1007: env->exception_index = TT_TRAP + (T0 & 0x7f);
1008: cpu_loop_exit();
1009: }
1010:
1011: void OPPROTO op_trapcc_T0(void)
1012: {
1013: if (T2) {
1014: env->exception_index = TT_TRAP + (T0 & 0x7f);
1015: cpu_loop_exit();
1016: }
1017: FORCE_RET();
1018: }
1019:
1020: void OPPROTO op_trap_ifnofpu(void)
1021: {
1022: if (!env->psref) {
1023: env->exception_index = TT_NFPU_INSN;
1024: cpu_loop_exit();
1025: }
1026: FORCE_RET();
1027: }
1028:
1029: void OPPROTO op_fpexception_im(void)
1030: {
1031: env->exception_index = TT_FP_EXCP;
1032: env->fsr &= ~FSR_FTT_MASK;
1033: env->fsr |= PARAM1;
1034: cpu_loop_exit();
1035: FORCE_RET();
1036: }
1037:
1038: void OPPROTO op_debug(void)
1039: {
1040: helper_debug();
1041: }
1042:
1043: void OPPROTO op_exit_tb(void)
1044: {
1045: EXIT_TB();
1046: }
1047:
1048: void OPPROTO op_eval_ba(void)
1049: {
1050: T2 = 1;
1051: }
1052:
1053: void OPPROTO op_eval_be(void)
1054: {
1055: T2 = FLAG_SET(PSR_ZERO);
1056: }
1057:
1058: void OPPROTO op_eval_ble(void)
1059: {
1060: target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1061:
1062: T2 = Z | (N ^ V);
1063: }
1064:
1065: void OPPROTO op_eval_bl(void)
1066: {
1067: target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1068:
1069: T2 = N ^ V;
1070: }
1071:
1072: void OPPROTO op_eval_bleu(void)
1073: {
1074: target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1075:
1076: T2 = C | Z;
1077: }
1078:
1079: void OPPROTO op_eval_bcs(void)
1080: {
1081: T2 = FLAG_SET(PSR_CARRY);
1082: }
1083:
1084: void OPPROTO op_eval_bvs(void)
1085: {
1086: T2 = FLAG_SET(PSR_OVF);
1087: }
1088:
1089: void OPPROTO op_eval_bn(void)
1090: {
1091: T2 = 0;
1092: }
1093:
1094: void OPPROTO op_eval_bneg(void)
1095: {
1096: T2 = FLAG_SET(PSR_NEG);
1097: }
1098:
1099: void OPPROTO op_eval_bne(void)
1100: {
1101: T2 = !FLAG_SET(PSR_ZERO);
1102: }
1103:
1104: void OPPROTO op_eval_bg(void)
1105: {
1106: target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1107:
1108: T2 = !(Z | (N ^ V));
1109: }
1110:
1111: void OPPROTO op_eval_bge(void)
1112: {
1113: target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
1114:
1115: T2 = !(N ^ V);
1116: }
1117:
1118: void OPPROTO op_eval_bgu(void)
1119: {
1120: target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
1121:
1122: T2 = !(C | Z);
1123: }
1124:
1125: void OPPROTO op_eval_bcc(void)
1126: {
1127: T2 = !FLAG_SET(PSR_CARRY);
1128: }
1129:
1130: void OPPROTO op_eval_bpos(void)
1131: {
1132: T2 = !FLAG_SET(PSR_NEG);
1133: }
1134:
1135: void OPPROTO op_eval_bvc(void)
1136: {
1137: T2 = !FLAG_SET(PSR_OVF);
1138: }
1139:
1140: #ifdef TARGET_SPARC64
1141: void OPPROTO op_eval_xbe(void)
1142: {
1143: T2 = XFLAG_SET(PSR_ZERO);
1144: }
1145:
1146: void OPPROTO op_eval_xble(void)
1147: {
1148: target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1149:
1150: T2 = Z | (N ^ V);
1151: }
1152:
1153: void OPPROTO op_eval_xbl(void)
1154: {
1155: target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1156:
1157: T2 = N ^ V;
1158: }
1159:
1160: void OPPROTO op_eval_xbleu(void)
1161: {
1162: target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1163:
1164: T2 = C | Z;
1165: }
1166:
1167: void OPPROTO op_eval_xbcs(void)
1168: {
1169: T2 = XFLAG_SET(PSR_CARRY);
1170: }
1171:
1172: void OPPROTO op_eval_xbvs(void)
1173: {
1174: T2 = XFLAG_SET(PSR_OVF);
1175: }
1176:
1177: void OPPROTO op_eval_xbneg(void)
1178: {
1179: T2 = XFLAG_SET(PSR_NEG);
1180: }
1181:
1182: void OPPROTO op_eval_xbne(void)
1183: {
1184: T2 = !XFLAG_SET(PSR_ZERO);
1185: }
1186:
1187: void OPPROTO op_eval_xbg(void)
1188: {
1189: target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1190:
1191: T2 = !(Z | (N ^ V));
1192: }
1193:
1194: void OPPROTO op_eval_xbge(void)
1195: {
1196: target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
1197:
1198: T2 = !(N ^ V);
1199: }
1200:
1201: void OPPROTO op_eval_xbgu(void)
1202: {
1203: target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
1204:
1205: T2 = !(C | Z);
1206: }
1207:
1208: void OPPROTO op_eval_xbcc(void)
1209: {
1210: T2 = !XFLAG_SET(PSR_CARRY);
1211: }
1212:
1213: void OPPROTO op_eval_xbpos(void)
1214: {
1215: T2 = !XFLAG_SET(PSR_NEG);
1216: }
1217:
1218: void OPPROTO op_eval_xbvc(void)
1219: {
1220: T2 = !XFLAG_SET(PSR_OVF);
1221: }
1222: #endif
1223:
1224: #define FCC
1225: #define FFLAG_SET(x) (env->fsr & x? 1: 0)
1226: #include "fbranch_template.h"
1227:
1228: #ifdef TARGET_SPARC64
1229: #define FCC _fcc1
1230: #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
1231: #include "fbranch_template.h"
1232: #define FCC _fcc2
1233: #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
1234: #include "fbranch_template.h"
1235: #define FCC _fcc3
1236: #define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
1237: #include "fbranch_template.h"
1238: #endif
1239:
1240: #ifdef TARGET_SPARC64
1241: void OPPROTO op_eval_brz(void)
1242: {
1243: T2 = (T0 == 0);
1244: }
1245:
1246: void OPPROTO op_eval_brnz(void)
1247: {
1248: T2 = (T0 != 0);
1249: }
1250:
1251: void OPPROTO op_eval_brlz(void)
1252: {
1253: T2 = ((int64_t)T0 < 0);
1254: }
1255:
1256: void OPPROTO op_eval_brlez(void)
1257: {
1258: T2 = ((int64_t)T0 <= 0);
1259: }
1260:
1261: void OPPROTO op_eval_brgz(void)
1262: {
1263: T2 = ((int64_t)T0 > 0);
1264: }
1265:
1266: void OPPROTO op_eval_brgez(void)
1267: {
1268: T2 = ((int64_t)T0 >= 0);
1269: }
1270:
1271: void OPPROTO op_jmp_im64(void)
1272: {
1273: env->pc = PARAMQ1;
1274: }
1275:
1276: void OPPROTO op_movq_npc_im64(void)
1277: {
1278: env->npc = PARAMQ1;
1279: }
1280: #endif
1281:
1282: void OPPROTO op_jmp_im(void)
1283: {
1284: env->pc = (uint32_t)PARAM1;
1285: }
1286:
1287: void OPPROTO op_movl_npc_im(void)
1288: {
1289: env->npc = (uint32_t)PARAM1;
1290: }
1291:
1292: void OPPROTO op_movl_npc_T0(void)
1293: {
1294: env->npc = T0;
1295: }
1296:
1297: void OPPROTO op_mov_pc_npc(void)
1298: {
1299: env->pc = env->npc;
1300: }
1301:
1302: void OPPROTO op_next_insn(void)
1303: {
1304: env->pc = env->npc;
1305: env->npc = env->npc + 4;
1306: }
1307:
1308: void OPPROTO op_goto_tb0(void)
1309: {
1310: GOTO_TB(op_goto_tb0, PARAM1, 0);
1311: }
1312:
1313: void OPPROTO op_goto_tb1(void)
1314: {
1315: GOTO_TB(op_goto_tb1, PARAM1, 1);
1316: }
1317:
1318: void OPPROTO op_jmp_label(void)
1319: {
1320: GOTO_LABEL_PARAM(1);
1321: }
1322:
1323: void OPPROTO op_jnz_T2_label(void)
1324: {
1325: if (T2)
1326: GOTO_LABEL_PARAM(1);
1327: FORCE_RET();
1328: }
1329:
1330: void OPPROTO op_jz_T2_label(void)
1331: {
1332: if (!T2)
1333: GOTO_LABEL_PARAM(1);
1334: FORCE_RET();
1335: }
1336:
1337: void OPPROTO op_flush_T0(void)
1338: {
1339: helper_flush(T0);
1340: }
1341:
1342: void OPPROTO op_fnegs(void)
1343: {
1344: FT0 = -FT1;
1345: }
1346:
1347: void OPPROTO op_fabss(void)
1348: {
1349: do_fabss();
1350: }
1351:
1352: #ifdef TARGET_SPARC64
1353: void OPPROTO op_fnegd(void)
1354: {
1355: DT0 = -DT1;
1356: }
1357:
1358: void OPPROTO op_fabsd(void)
1359: {
1360: do_fabsd();
1361: }
1362: #endif
1363:
1364: void OPPROTO op_fsqrts(void)
1365: {
1366: do_fsqrts();
1367: }
1368:
1369: void OPPROTO op_fsqrtd(void)
1370: {
1371: do_fsqrtd();
1372: }
1373:
1374: void OPPROTO op_fmuls(void)
1375: {
1376: FT0 *= FT1;
1377: }
1378:
1379: void OPPROTO op_fmuld(void)
1380: {
1381: DT0 *= DT1;
1382: }
1383:
1384: void OPPROTO op_fsmuld(void)
1385: {
1386: DT0 = FT0 * FT1;
1387: }
1388:
1389: void OPPROTO op_fadds(void)
1390: {
1391: FT0 += FT1;
1392: }
1393:
1394: void OPPROTO op_faddd(void)
1395: {
1396: DT0 += DT1;
1397: }
1398:
1399: void OPPROTO op_fsubs(void)
1400: {
1401: FT0 -= FT1;
1402: }
1403:
1404: void OPPROTO op_fsubd(void)
1405: {
1406: DT0 -= DT1;
1407: }
1408:
1409: void OPPROTO op_fdivs(void)
1410: {
1411: FT0 /= FT1;
1412: }
1413:
1414: void OPPROTO op_fdivd(void)
1415: {
1416: DT0 /= DT1;
1417: }
1418:
1419: void OPPROTO op_fcmps(void)
1420: {
1421: do_fcmps();
1422: }
1423:
1424: void OPPROTO op_fcmpd(void)
1425: {
1426: do_fcmpd();
1427: }
1428:
1429: #ifdef TARGET_SPARC64
1430: void OPPROTO op_fcmps_fcc1(void)
1431: {
1432: do_fcmps_fcc1();
1433: }
1434:
1435: void OPPROTO op_fcmpd_fcc1(void)
1436: {
1437: do_fcmpd_fcc1();
1438: }
1439:
1440: void OPPROTO op_fcmps_fcc2(void)
1441: {
1442: do_fcmps_fcc2();
1443: }
1444:
1445: void OPPROTO op_fcmpd_fcc2(void)
1446: {
1447: do_fcmpd_fcc2();
1448: }
1449:
1450: void OPPROTO op_fcmps_fcc3(void)
1451: {
1452: do_fcmps_fcc3();
1453: }
1454:
1455: void OPPROTO op_fcmpd_fcc3(void)
1456: {
1457: do_fcmpd_fcc3();
1458: }
1459: #endif
1460:
1461: #ifdef USE_INT_TO_FLOAT_HELPERS
1462: void OPPROTO op_fitos(void)
1463: {
1464: do_fitos();
1465: }
1466:
1467: void OPPROTO op_fitod(void)
1468: {
1469: do_fitod();
1470: }
1471: #else
1472: void OPPROTO op_fitos(void)
1473: {
1474: FT0 = (float) *((int32_t *)&FT1);
1475: }
1476:
1477: void OPPROTO op_fitod(void)
1478: {
1479: DT0 = (double) *((int32_t *)&FT1);
1480: }
1481:
1482: #ifdef TARGET_SPARC64
1483: void OPPROTO op_fxtos(void)
1484: {
1485: FT0 = (float) *((int64_t *)&DT1);
1486: }
1487:
1488: void OPPROTO op_fxtod(void)
1489: {
1490: DT0 = (double) *((int64_t *)&DT1);
1491: }
1492: #endif
1493: #endif
1494:
1495: void OPPROTO op_fdtos(void)
1496: {
1497: FT0 = (float) DT1;
1498: }
1499:
1500: void OPPROTO op_fstod(void)
1501: {
1502: DT0 = (double) FT1;
1503: }
1504:
1505: void OPPROTO op_fstoi(void)
1506: {
1507: *((int32_t *)&FT0) = (int32_t) FT1;
1508: }
1509:
1510: void OPPROTO op_fdtoi(void)
1511: {
1512: *((int32_t *)&FT0) = (int32_t) DT1;
1513: }
1514:
1515: #ifdef TARGET_SPARC64
1516: void OPPROTO op_fstox(void)
1517: {
1518: *((int64_t *)&DT0) = (int64_t) FT1;
1519: }
1520:
1521: void OPPROTO op_fdtox(void)
1522: {
1523: *((int64_t *)&DT0) = (int64_t) DT1;
1524: }
1525:
1526: void OPPROTO op_fmovs_cc(void)
1527: {
1528: if (T2)
1529: FT0 = FT1;
1530: }
1531:
1532: void OPPROTO op_fmovd_cc(void)
1533: {
1534: if (T2)
1535: DT0 = DT1;
1536: }
1537:
1538: void OPPROTO op_mov_cc(void)
1539: {
1540: if (T2)
1541: T0 = T1;
1542: }
1543:
1544: void OPPROTO op_flushw(void)
1545: {
1546: if (env->cansave != NWINDOWS - 2) {
1547: raise_exception(TT_SPILL | (env->otherwin != 0 ?
1548: (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
1549: ((env->wstate & 0x7) << 2)));
1550: }
1551: }
1552:
1553: void OPPROTO op_saved(void)
1554: {
1555: env->cansave++;
1556: if (env->otherwin == 0)
1557: env->canrestore--;
1558: }
1559:
1560: void OPPROTO op_restored(void)
1561: {
1562: env->canrestore++;
1563: if (env->cleanwin < NWINDOWS - 1)
1564: env->cleanwin++;
1565: if (env->otherwin == 0)
1566: env->cansave--;
1567: else
1568: env->otherwin--;
1569: }
1570:
1571: void OPPROTO op_popc(void)
1572: {
1573: do_popc();
1574: }
1575:
1576: void OPPROTO op_done(void)
1577: {
1578: do_done();
1579: }
1580:
1581: void OPPROTO op_retry(void)
1582: {
1583: do_retry();
1584: }
1585:
1586: void OPPROTO op_sir(void)
1587: {
1588: // XXX
1589:
1590: }
1591:
1592: void OPPROTO op_ld_asi_reg()
1593: {
1594: T0 += PARAM1;
1595: helper_ld_asi(env->asi, PARAM2, PARAM3);
1596: }
1597:
1598: void OPPROTO op_st_asi_reg()
1599: {
1600: T0 += PARAM1;
1601: helper_st_asi(env->asi, PARAM2, PARAM3);
1602: }
1603: #endif
1604:
1605: void OPPROTO op_ld_asi()
1606: {
1607: helper_ld_asi(PARAM1, PARAM2, PARAM3);
1608: }
1609:
1610: void OPPROTO op_st_asi()
1611: {
1612: helper_st_asi(PARAM1, PARAM2, PARAM3);
1613: }
1614:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.