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,9 +181,6 @@ Current QEMU limitations:
181 181
182 @itemize 182 @itemize
183 183
184 -@item Tagged add/subtract instructions are not supported, but they are  
185 -probably not used.  
186 -  
187 @item IPC syscalls are missing. 184 @item IPC syscalls are missing.
188 185
189 @item 128-bit floating point operations are not supported, though none of the 186 @item 128-bit floating point operations are not supported, though none of the
target-sparc/cpu.h
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 #define TT_WIN_UNF 0x06 37 #define TT_WIN_UNF 0x06
38 #define TT_FP_EXCP 0x08 38 #define TT_FP_EXCP 0x08
39 #define TT_DFAULT 0x09 39 #define TT_DFAULT 0x09
  40 +#define TT_TOVF 0x0a
40 #define TT_EXTINT 0x10 41 #define TT_EXTINT 0x10
41 #define TT_DIV_ZERO 0x2a 42 #define TT_DIV_ZERO 0x2a
42 #define TT_TRAP 0x80 43 #define TT_TRAP 0x80
@@ -47,6 +48,7 @@ @@ -47,6 +48,7 @@
47 #define TT_PRIV_INSN 0x11 48 #define TT_PRIV_INSN 0x11
48 #define TT_NFPU_INSN 0x20 49 #define TT_NFPU_INSN 0x20
49 #define TT_FP_EXCP 0x21 50 #define TT_FP_EXCP 0x21
  51 +#define TT_TOVF 0x23
50 #define TT_CLRWIN 0x24 52 #define TT_CLRWIN 0x24
51 #define TT_DIV_ZERO 0x28 53 #define TT_DIV_ZERO 0x28
52 #define TT_DFAULT 0x30 54 #define TT_DFAULT 0x30
target-sparc/op.c
@@ -472,6 +472,96 @@ void OPPROTO op_addx_T1_T0_cc(void) @@ -472,6 +472,96 @@ void OPPROTO op_addx_T1_T0_cc(void)
472 FORCE_RET(); 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 void OPPROTO op_sub_T1_T0(void) 565 void OPPROTO op_sub_T1_T0(void)
476 { 566 {
477 T0 -= T1; 567 T0 -= T1;
@@ -582,6 +672,96 @@ void OPPROTO op_subx_T1_T0_cc(void) @@ -582,6 +672,96 @@ void OPPROTO op_subx_T1_T0_cc(void)
582 FORCE_RET(); 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 void OPPROTO op_and_T1_T0(void) 765 void OPPROTO op_and_T1_T0(void)
586 { 766 {
587 T0 &= T1; 767 T0 &= T1;
target-sparc/translate.c
@@ -27,7 +27,6 @@ @@ -27,7 +27,6 @@
27 Optimize synthetic instructions 27 Optimize synthetic instructions
28 Optional alignment check 28 Optional alignment check
29 128-bit float 29 128-bit float
30 - Tagged add/sub  
31 */ 30 */
32 31
33 #include <stdarg.h> 32 #include <stdarg.h>
@@ -1833,10 +1832,21 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1833,10 +1832,21 @@ static void disas_sparc_insn(DisasContext * dc)
1833 } else { 1832 } else {
1834 switch (xop) { 1833 switch (xop) {
1835 case 0x20: /* taddcc */ 1834 case 0x20: /* taddcc */
  1835 + gen_op_tadd_T1_T0_cc();
  1836 + gen_movl_T0_reg(rd);
  1837 + break;
1836 case 0x21: /* tsubcc */ 1838 case 0x21: /* tsubcc */
  1839 + gen_op_tsub_T1_T0_cc();
  1840 + gen_movl_T0_reg(rd);
  1841 + break;
1837 case 0x22: /* taddcctv */ 1842 case 0x22: /* taddcctv */
  1843 + gen_op_tadd_T1_T0_ccTV();
  1844 + gen_movl_T0_reg(rd);
  1845 + break;
1838 case 0x23: /* tsubcctv */ 1846 case 0x23: /* tsubcctv */
1839 - goto illegal_insn; 1847 + gen_op_tsub_T1_T0_ccTV();
  1848 + gen_movl_T0_reg(rd);
  1849 + break;
1840 case 0x24: /* mulscc */ 1850 case 0x24: /* mulscc */
1841 gen_op_mulscc_T1_T0(); 1851 gen_op_mulscc_T1_T0();
1842 gen_movl_T0_reg(rd); 1852 gen_movl_T0_reg(rd);