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