Commit e32f879d1b5cbde3c996d6db5e15e487ae3064a5

Authored by blueswir1
1 parent 426613db

Sparc tagged operations (Aurelien Jarno)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2531 c046a42c-6fe2-441c-8c8c-71466251a162
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);
... ...