Commit e32f879d1b5cbde3c996d6db5e15e487ae3064a5
1 parent
426613db
Sparc tagged operations (Aurelien Jarno)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2531 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
194 additions
and
5 deletions
qemu-tech.texi
... | ... | @@ -181,9 +181,6 @@ Current QEMU limitations: |
181 | 181 | |
182 | 182 | @itemize |
183 | 183 | |
184 | -@item Tagged add/subtract instructions are not supported, but they are | |
185 | -probably not used. | |
186 | - | |
187 | 184 | @item IPC syscalls are missing. |
188 | 185 | |
189 | 186 | @item 128-bit floating point operations are not supported, though none of the | ... | ... |
target-sparc/cpu.h
... | ... | @@ -37,6 +37,7 @@ |
37 | 37 | #define TT_WIN_UNF 0x06 |
38 | 38 | #define TT_FP_EXCP 0x08 |
39 | 39 | #define TT_DFAULT 0x09 |
40 | +#define TT_TOVF 0x0a | |
40 | 41 | #define TT_EXTINT 0x10 |
41 | 42 | #define TT_DIV_ZERO 0x2a |
42 | 43 | #define TT_TRAP 0x80 |
... | ... | @@ -47,6 +48,7 @@ |
47 | 48 | #define TT_PRIV_INSN 0x11 |
48 | 49 | #define TT_NFPU_INSN 0x20 |
49 | 50 | #define TT_FP_EXCP 0x21 |
51 | +#define TT_TOVF 0x23 | |
50 | 52 | #define TT_CLRWIN 0x24 |
51 | 53 | #define TT_DIV_ZERO 0x28 |
52 | 54 | #define TT_DFAULT 0x30 | ... | ... |
target-sparc/op.c
... | ... | @@ -472,6 +472,96 @@ void OPPROTO op_addx_T1_T0_cc(void) |
472 | 472 | FORCE_RET(); |
473 | 473 | } |
474 | 474 | |
475 | +void OPPROTO op_tadd_T1_T0_cc(void) | |
476 | +{ | |
477 | + target_ulong src1; | |
478 | + | |
479 | + src1 = T0; | |
480 | + T0 += T1; | |
481 | + env->psr = 0; | |
482 | +#ifdef TARGET_SPARC64 | |
483 | + if (!(T0 & 0xffffffff)) | |
484 | + env->psr |= PSR_ZERO; | |
485 | + if ((int32_t) T0 < 0) | |
486 | + env->psr |= PSR_NEG; | |
487 | + if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) | |
488 | + env->psr |= PSR_CARRY; | |
489 | + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) & | |
490 | + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) | |
491 | + env->psr |= PSR_OVF; | |
492 | + if ((src1 & 0x03) || (T1 & 0x03)) | |
493 | + env->psr |= PSR_OVF; | |
494 | + | |
495 | + env->xcc = 0; | |
496 | + if (!T0) | |
497 | + env->xcc |= PSR_ZERO; | |
498 | + if ((int64_t) T0 < 0) | |
499 | + env->xcc |= PSR_NEG; | |
500 | + if (T0 < src1) | |
501 | + env->xcc |= PSR_CARRY; | |
502 | + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63)) | |
503 | + env->xcc |= PSR_OVF; | |
504 | +#else | |
505 | + if (!T0) | |
506 | + env->psr |= PSR_ZERO; | |
507 | + if ((int32_t) T0 < 0) | |
508 | + env->psr |= PSR_NEG; | |
509 | + if (T0 < src1) | |
510 | + env->psr |= PSR_CARRY; | |
511 | + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) | |
512 | + env->psr |= PSR_OVF; | |
513 | + if ((src1 & 0x03) || (T1 & 0x03)) | |
514 | + env->psr |= PSR_OVF; | |
515 | +#endif | |
516 | + FORCE_RET(); | |
517 | +} | |
518 | + | |
519 | +void OPPROTO op_tadd_T1_T0_ccTV(void) | |
520 | +{ | |
521 | + target_ulong src1; | |
522 | + | |
523 | + if ((T0 & 0x03) || (T1 & 0x03)) | |
524 | + raise_exception(TT_TOVF); | |
525 | + | |
526 | + src1 = T0; | |
527 | + T0 += T1; | |
528 | + | |
529 | +#ifdef TARGET_SPARC64 | |
530 | + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) & | |
531 | + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) | |
532 | + raise_exception(TT_TOVF); | |
533 | +#else | |
534 | + if ((src1 & 0x03) || (T1 & 0x03)) | |
535 | + raise_exception(TT_TOVF); | |
536 | +#endif | |
537 | + | |
538 | + env->psr = 0; | |
539 | +#ifdef TARGET_SPARC64 | |
540 | + if (!(T0 & 0xffffffff)) | |
541 | + env->psr |= PSR_ZERO; | |
542 | + if ((int32_t) T0 < 0) | |
543 | + env->psr |= PSR_NEG; | |
544 | + if ((T0 & 0xffffffff) < (src1 & 0xffffffff)) | |
545 | + env->psr |= PSR_CARRY; | |
546 | + | |
547 | + env->xcc = 0; | |
548 | + if (!T0) | |
549 | + env->xcc |= PSR_ZERO; | |
550 | + if ((int64_t) T0 < 0) | |
551 | + env->xcc |= PSR_NEG; | |
552 | + if (T0 < src1) | |
553 | + env->xcc |= PSR_CARRY; | |
554 | +#else | |
555 | + if (!T0) | |
556 | + env->psr |= PSR_ZERO; | |
557 | + if ((int32_t) T0 < 0) | |
558 | + env->psr |= PSR_NEG; | |
559 | + if (T0 < src1) | |
560 | + env->psr |= PSR_CARRY; | |
561 | +#endif | |
562 | + FORCE_RET(); | |
563 | +} | |
564 | + | |
475 | 565 | void OPPROTO op_sub_T1_T0(void) |
476 | 566 | { |
477 | 567 | T0 -= T1; |
... | ... | @@ -582,6 +672,96 @@ void OPPROTO op_subx_T1_T0_cc(void) |
582 | 672 | FORCE_RET(); |
583 | 673 | } |
584 | 674 | |
675 | +void OPPROTO op_tsub_T1_T0_cc(void) | |
676 | +{ | |
677 | + target_ulong src1; | |
678 | + | |
679 | + src1 = T0; | |
680 | + T0 -= T1; | |
681 | + env->psr = 0; | |
682 | +#ifdef TARGET_SPARC64 | |
683 | + if (!(T0 & 0xffffffff)) | |
684 | + env->psr |= PSR_ZERO; | |
685 | + if ((int32_t) T0 < 0) | |
686 | + env->psr |= PSR_NEG; | |
687 | + if ((src1 & 0xffffffff) < (T1 & 0xffffffff)) | |
688 | + env->psr |= PSR_CARRY; | |
689 | + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & | |
690 | + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) | |
691 | + env->psr |= PSR_OVF; | |
692 | + if ((src1 & 0x03) || (T1 & 0x03)) | |
693 | + env->psr |= PSR_OVF; | |
694 | + | |
695 | + env->xcc = 0; | |
696 | + if (!T0) | |
697 | + env->xcc |= PSR_ZERO; | |
698 | + if ((int64_t) T0 < 0) | |
699 | + env->xcc |= PSR_NEG; | |
700 | + if (src1 < T1) | |
701 | + env->xcc |= PSR_CARRY; | |
702 | + if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63)) | |
703 | + env->xcc |= PSR_OVF; | |
704 | +#else | |
705 | + if (!T0) | |
706 | + env->psr |= PSR_ZERO; | |
707 | + if ((int32_t) T0 < 0) | |
708 | + env->psr |= PSR_NEG; | |
709 | + if (src1 < T1) | |
710 | + env->psr |= PSR_CARRY; | |
711 | + if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) | |
712 | + env->psr |= PSR_OVF; | |
713 | + if ((src1 & 0x03) || (T1 & 0x03)) | |
714 | + env->psr |= PSR_OVF; | |
715 | +#endif | |
716 | + FORCE_RET(); | |
717 | +} | |
718 | + | |
719 | +void OPPROTO op_tsub_T1_T0_ccTV(void) | |
720 | +{ | |
721 | + target_ulong src1; | |
722 | + | |
723 | + if ((T0 & 0x03) || (T1 & 0x03)) | |
724 | + raise_exception(TT_TOVF); | |
725 | + | |
726 | + src1 = T0; | |
727 | + T0 -= T1; | |
728 | + | |
729 | +#ifdef TARGET_SPARC64 | |
730 | + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) & | |
731 | + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31)) | |
732 | + raise_exception(TT_TOVF); | |
733 | +#else | |
734 | + if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) | |
735 | + raise_exception(TT_TOVF); | |
736 | +#endif | |
737 | + | |
738 | + env->psr = 0; | |
739 | +#ifdef TARGET_SPARC64 | |
740 | + if (!(T0 & 0xffffffff)) | |
741 | + env->psr |= PSR_ZERO; | |
742 | + if ((int32_t) T0 < 0) | |
743 | + env->psr |= PSR_NEG; | |
744 | + if ((src1 & 0xffffffff) < (T1 & 0xffffffff)) | |
745 | + env->psr |= PSR_CARRY; | |
746 | + | |
747 | + env->xcc = 0; | |
748 | + if (!T0) | |
749 | + env->xcc |= PSR_ZERO; | |
750 | + if ((int64_t) T0 < 0) | |
751 | + env->xcc |= PSR_NEG; | |
752 | + if (src1 < T1) | |
753 | + env->xcc |= PSR_CARRY; | |
754 | +#else | |
755 | + if (!T0) | |
756 | + env->psr |= PSR_ZERO; | |
757 | + if ((int32_t) T0 < 0) | |
758 | + env->psr |= PSR_NEG; | |
759 | + if (src1 < T1) | |
760 | + env->psr |= PSR_CARRY; | |
761 | +#endif | |
762 | + FORCE_RET(); | |
763 | +} | |
764 | + | |
585 | 765 | void OPPROTO op_and_T1_T0(void) |
586 | 766 | { |
587 | 767 | T0 &= T1; | ... | ... |
target-sparc/translate.c
... | ... | @@ -27,7 +27,6 @@ |
27 | 27 | Optimize synthetic instructions |
28 | 28 | Optional alignment check |
29 | 29 | 128-bit float |
30 | - Tagged add/sub | |
31 | 30 | */ |
32 | 31 | |
33 | 32 | #include <stdarg.h> |
... | ... | @@ -1833,10 +1832,21 @@ static void disas_sparc_insn(DisasContext * dc) |
1833 | 1832 | } else { |
1834 | 1833 | switch (xop) { |
1835 | 1834 | case 0x20: /* taddcc */ |
1835 | + gen_op_tadd_T1_T0_cc(); | |
1836 | + gen_movl_T0_reg(rd); | |
1837 | + break; | |
1836 | 1838 | case 0x21: /* tsubcc */ |
1839 | + gen_op_tsub_T1_T0_cc(); | |
1840 | + gen_movl_T0_reg(rd); | |
1841 | + break; | |
1837 | 1842 | case 0x22: /* taddcctv */ |
1843 | + gen_op_tadd_T1_T0_ccTV(); | |
1844 | + gen_movl_T0_reg(rd); | |
1845 | + break; | |
1838 | 1846 | case 0x23: /* tsubcctv */ |
1839 | - goto illegal_insn; | |
1847 | + gen_op_tsub_T1_T0_ccTV(); | |
1848 | + gen_movl_T0_reg(rd); | |
1849 | + break; | |
1840 | 1850 | case 0x24: /* mulscc */ |
1841 | 1851 | gen_op_mulscc_T1_T0(); |
1842 | 1852 | gen_movl_T0_reg(rd); | ... | ... |