Commit 1579a72ec5957297786ba5928e60571f4ab2f844
1 parent
f7cfb2a1
Fix RDHWR handling. Code formatting. Don't use *_direct versions to raise
exceptions. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2611 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
131 additions
and
92 deletions
target-mips/op.c
@@ -336,7 +336,7 @@ void op_addo (void) | @@ -336,7 +336,7 @@ void op_addo (void) | ||
336 | T0 = (int32_t)T0 + (int32_t)T1; | 336 | T0 = (int32_t)T0 + (int32_t)T1; |
337 | if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) { | 337 | if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) { |
338 | /* operands of same sign, result different sign */ | 338 | /* operands of same sign, result different sign */ |
339 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); | 339 | + CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW); |
340 | } | 340 | } |
341 | T0 = (int32_t)T0; | 341 | T0 = (int32_t)T0; |
342 | RETURN(); | 342 | RETURN(); |
@@ -356,7 +356,7 @@ void op_subo (void) | @@ -356,7 +356,7 @@ void op_subo (void) | ||
356 | T0 = (int32_t)T0 - (int32_t)T1; | 356 | T0 = (int32_t)T0 - (int32_t)T1; |
357 | if (((tmp ^ T1) & (tmp ^ T0)) >> 31) { | 357 | if (((tmp ^ T1) & (tmp ^ T0)) >> 31) { |
358 | /* operands of different sign, first operand and result different sign */ | 358 | /* operands of different sign, first operand and result different sign */ |
359 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); | 359 | + CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW); |
360 | } | 360 | } |
361 | T0 = (int32_t)T0; | 361 | T0 = (int32_t)T0; |
362 | RETURN(); | 362 | RETURN(); |
@@ -402,7 +402,7 @@ void op_daddo (void) | @@ -402,7 +402,7 @@ void op_daddo (void) | ||
402 | T0 += T1; | 402 | T0 += T1; |
403 | if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) { | 403 | if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) { |
404 | /* operands of same sign, result different sign */ | 404 | /* operands of same sign, result different sign */ |
405 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); | 405 | + CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW); |
406 | } | 406 | } |
407 | RETURN(); | 407 | RETURN(); |
408 | } | 408 | } |
@@ -421,7 +421,7 @@ void op_dsubo (void) | @@ -421,7 +421,7 @@ void op_dsubo (void) | ||
421 | T0 = (int64_t)T0 - (int64_t)T1; | 421 | T0 = (int64_t)T0 - (int64_t)T1; |
422 | if (((tmp ^ T1) & (tmp ^ T0)) >> 63) { | 422 | if (((tmp ^ T1) & (tmp ^ T0)) >> 63) { |
423 | /* operands of different sign, first operand and result different sign */ | 423 | /* operands of different sign, first operand and result different sign */ |
424 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_OVERFLOW); | 424 | + CALL_FROM_TB1(do_raise_exception, EXCP_OVERFLOW); |
425 | } | 425 | } |
426 | RETURN(); | 426 | RETURN(); |
427 | } | 427 | } |
@@ -1650,7 +1650,7 @@ void op_cp0_enabled(void) | @@ -1650,7 +1650,7 @@ void op_cp0_enabled(void) | ||
1650 | { | 1650 | { |
1651 | if (!(env->CP0_Status & (1 << CP0St_CU0)) && | 1651 | if (!(env->CP0_Status & (1 << CP0St_CU0)) && |
1652 | (env->hflags & MIPS_HFLAG_UM)) { | 1652 | (env->hflags & MIPS_HFLAG_UM)) { |
1653 | - CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 0); | 1653 | + CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 0); |
1654 | } | 1654 | } |
1655 | RETURN(); | 1655 | RETURN(); |
1656 | } | 1656 | } |
@@ -1658,7 +1658,7 @@ void op_cp0_enabled(void) | @@ -1658,7 +1658,7 @@ void op_cp0_enabled(void) | ||
1658 | void op_cp1_enabled(void) | 1658 | void op_cp1_enabled(void) |
1659 | { | 1659 | { |
1660 | if (!(env->CP0_Status & (1 << CP0St_CU1))) { | 1660 | if (!(env->CP0_Status & (1 << CP0St_CU1))) { |
1661 | - CALL_FROM_TB2(do_raise_exception_direct_err, EXCP_CpU, 1); | 1661 | + CALL_FROM_TB2(do_raise_exception_err, EXCP_CpU, 1); |
1662 | } | 1662 | } |
1663 | RETURN(); | 1663 | RETURN(); |
1664 | } | 1664 | } |
@@ -2063,7 +2063,7 @@ void op_ei (void) | @@ -2063,7 +2063,7 @@ void op_ei (void) | ||
2063 | void op_trap (void) | 2063 | void op_trap (void) |
2064 | { | 2064 | { |
2065 | if (T0) { | 2065 | if (T0) { |
2066 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_TRAP); | 2066 | + CALL_FROM_TB1(do_raise_exception, EXCP_TRAP); |
2067 | } | 2067 | } |
2068 | RETURN(); | 2068 | RETURN(); |
2069 | } | 2069 | } |
@@ -2116,37 +2116,67 @@ void op_deret (void) | @@ -2116,37 +2116,67 @@ void op_deret (void) | ||
2116 | 2116 | ||
2117 | void op_rdhwr_cpunum(void) | 2117 | void op_rdhwr_cpunum(void) |
2118 | { | 2118 | { |
2119 | - if (env->CP0_HWREna & (1 << 0)) | ||
2120 | - T0 = env->CP0_EBase & 0x2ff; | 2119 | + if (!(env->hflags & MIPS_HFLAG_UM) || |
2120 | + (env->CP0_HWREna & (1 << 0)) || | ||
2121 | + (env->CP0_Status & (1 << CP0St_CU0))) | ||
2122 | + T0 = env->CP0_EBase & 0x3ff; | ||
2121 | else | 2123 | else |
2122 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); | 2124 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); |
2123 | RETURN(); | 2125 | RETURN(); |
2124 | } | 2126 | } |
2125 | 2127 | ||
2126 | void op_rdhwr_synci_step(void) | 2128 | void op_rdhwr_synci_step(void) |
2127 | { | 2129 | { |
2128 | - if (env->CP0_HWREna & (1 << 1)) | ||
2129 | - T0 = env->SYNCI_Step; | 2130 | + if (!(env->hflags & MIPS_HFLAG_UM) || |
2131 | + (env->CP0_HWREna & (1 << 1)) || | ||
2132 | + (env->CP0_Status & (1 << CP0St_CU0))) | ||
2133 | + T0 = env->SYNCI_Step; | ||
2130 | else | 2134 | else |
2131 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); | 2135 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); |
2132 | RETURN(); | 2136 | RETURN(); |
2133 | } | 2137 | } |
2134 | 2138 | ||
2135 | void op_rdhwr_cc(void) | 2139 | void op_rdhwr_cc(void) |
2136 | { | 2140 | { |
2137 | - if (env->CP0_HWREna & (1 << 2)) | ||
2138 | - T0 = env->CP0_Count; | 2141 | + if (!(env->hflags & MIPS_HFLAG_UM) || |
2142 | + (env->CP0_HWREna & (1 << 2)) || | ||
2143 | + (env->CP0_Status & (1 << CP0St_CU0))) | ||
2144 | + T0 = env->CP0_Count; | ||
2139 | else | 2145 | else |
2140 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); | 2146 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); |
2141 | RETURN(); | 2147 | RETURN(); |
2142 | } | 2148 | } |
2143 | 2149 | ||
2144 | void op_rdhwr_ccres(void) | 2150 | void op_rdhwr_ccres(void) |
2145 | { | 2151 | { |
2146 | - if (env->CP0_HWREna & (1 << 3)) | ||
2147 | - T0 = env->CCRes; | 2152 | + if (!(env->hflags & MIPS_HFLAG_UM) || |
2153 | + (env->CP0_HWREna & (1 << 3)) || | ||
2154 | + (env->CP0_Status & (1 << CP0St_CU0))) | ||
2155 | + T0 = env->CCRes; | ||
2148 | else | 2156 | else |
2149 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); | 2157 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); |
2158 | + RETURN(); | ||
2159 | +} | ||
2160 | + | ||
2161 | +void op_rdhwr_unimpl30(void) | ||
2162 | +{ | ||
2163 | + if (!(env->hflags & MIPS_HFLAG_UM) || | ||
2164 | + (env->CP0_HWREna & (1 << 30)) || | ||
2165 | + (env->CP0_Status & (1 << CP0St_CU0))) | ||
2166 | + T0 = 0; | ||
2167 | + else | ||
2168 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); | ||
2169 | + RETURN(); | ||
2170 | +} | ||
2171 | + | ||
2172 | +void op_rdhwr_unimpl31(void) | ||
2173 | +{ | ||
2174 | + if (!(env->hflags & MIPS_HFLAG_UM) || | ||
2175 | + (env->CP0_HWREna & (1 << 31)) || | ||
2176 | + (env->CP0_Status & (1 << CP0St_CU0))) | ||
2177 | + T0 = 0; | ||
2178 | + else | ||
2179 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); | ||
2150 | RETURN(); | 2180 | RETURN(); |
2151 | } | 2181 | } |
2152 | 2182 |
target-mips/translate.c
@@ -1762,7 +1762,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -1762,7 +1762,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
1762 | break; | 1762 | break; |
1763 | default: | 1763 | default: |
1764 | goto die; | 1764 | goto die; |
1765 | - } | 1765 | + } |
1766 | break; | 1766 | break; |
1767 | case 4: | 1767 | case 4: |
1768 | switch (sel) { | 1768 | switch (sel) { |
@@ -1776,7 +1776,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -1776,7 +1776,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
1776 | // break; | 1776 | // break; |
1777 | default: | 1777 | default: |
1778 | goto die; | 1778 | goto die; |
1779 | - } | 1779 | + } |
1780 | break; | 1780 | break; |
1781 | case 5: | 1781 | case 5: |
1782 | switch (sel) { | 1782 | switch (sel) { |
@@ -1790,7 +1790,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -1790,7 +1790,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
1790 | break; | 1790 | break; |
1791 | default: | 1791 | default: |
1792 | goto die; | 1792 | goto die; |
1793 | - } | 1793 | + } |
1794 | break; | 1794 | break; |
1795 | case 6: | 1795 | case 6: |
1796 | switch (sel) { | 1796 | switch (sel) { |
@@ -1820,7 +1820,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -1820,7 +1820,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
1820 | // break; | 1820 | // break; |
1821 | default: | 1821 | default: |
1822 | goto die; | 1822 | goto die; |
1823 | - } | 1823 | + } |
1824 | break; | 1824 | break; |
1825 | case 7: | 1825 | case 7: |
1826 | switch (sel) { | 1826 | switch (sel) { |
@@ -1830,7 +1830,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -1830,7 +1830,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
1830 | break; | 1830 | break; |
1831 | default: | 1831 | default: |
1832 | goto die; | 1832 | goto die; |
1833 | - } | 1833 | + } |
1834 | break; | 1834 | break; |
1835 | case 8: | 1835 | case 8: |
1836 | switch (sel) { | 1836 | switch (sel) { |
@@ -1861,7 +1861,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -1861,7 +1861,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
1861 | break; | 1861 | break; |
1862 | default: | 1862 | default: |
1863 | goto die; | 1863 | goto die; |
1864 | - } | 1864 | + } |
1865 | break; | 1865 | break; |
1866 | case 11: | 1866 | case 11: |
1867 | switch (sel) { | 1867 | switch (sel) { |
@@ -1914,7 +1914,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | @@ -1914,7 +1914,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) | ||
1914 | break; | 1914 | break; |
1915 | default: | 1915 | default: |
1916 | goto die; | 1916 | goto die; |
1917 | - } | 1917 | + } |
1918 | break; | 1918 | break; |
1919 | case 15: | 1919 | case 15: |
1920 | switch (sel) { | 1920 | switch (sel) { |
@@ -2521,7 +2521,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | @@ -2521,7 +2521,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) | ||
2521 | break; | 2521 | break; |
2522 | default: | 2522 | default: |
2523 | goto die; | 2523 | goto die; |
2524 | - } | 2524 | + } |
2525 | break; | 2525 | break; |
2526 | case 16: | 2526 | case 16: |
2527 | switch (sel) { | 2527 | switch (sel) { |
@@ -2955,7 +2955,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | @@ -2955,7 +2955,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) | ||
2955 | break; | 2955 | break; |
2956 | default: | 2956 | default: |
2957 | goto die; | 2957 | goto die; |
2958 | - } | 2958 | + } |
2959 | break; | 2959 | break; |
2960 | case 4: | 2960 | case 4: |
2961 | switch (sel) { | 2961 | switch (sel) { |
@@ -4703,83 +4703,92 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | @@ -4703,83 +4703,92 @@ static void decode_opc (CPUState *env, DisasContext *ctx) | ||
4703 | } | 4703 | } |
4704 | break; | 4704 | break; |
4705 | case OPC_SPECIAL3: | 4705 | case OPC_SPECIAL3: |
4706 | - op1 = MASK_SPECIAL3(ctx->opcode); | ||
4707 | - switch (op1) { | ||
4708 | - case OPC_EXT: | ||
4709 | - case OPC_INS: | ||
4710 | - gen_bitops(ctx, op1, rt, rs, sa, rd); | 4706 | + op1 = MASK_SPECIAL3(ctx->opcode); |
4707 | + switch (op1) { | ||
4708 | + case OPC_EXT: | ||
4709 | + case OPC_INS: | ||
4710 | + gen_bitops(ctx, op1, rt, rs, sa, rd); | ||
4711 | + break; | ||
4712 | + case OPC_BSHFL: | ||
4713 | + op2 = MASK_BSHFL(ctx->opcode); | ||
4714 | + switch (op2) { | ||
4715 | + case OPC_WSBH: | ||
4716 | + GEN_LOAD_REG_TN(T1, rt); | ||
4717 | + gen_op_wsbh(); | ||
4718 | + break; | ||
4719 | + case OPC_SEB: | ||
4720 | + GEN_LOAD_REG_TN(T1, rt); | ||
4721 | + gen_op_seb(); | ||
4722 | + break; | ||
4723 | + case OPC_SEH: | ||
4724 | + GEN_LOAD_REG_TN(T1, rt); | ||
4725 | + gen_op_seh(); | ||
4726 | + break; | ||
4727 | + default: /* Invalid */ | ||
4728 | + MIPS_INVAL("bshfl"); | ||
4729 | + generate_exception(ctx, EXCP_RI); | ||
4730 | + break; | ||
4731 | + } | ||
4732 | + GEN_STORE_TN_REG(rd, T0); | ||
4711 | break; | 4733 | break; |
4712 | - case OPC_BSHFL: | ||
4713 | - op2 = MASK_BSHFL(ctx->opcode); | ||
4714 | - switch (op2) { | ||
4715 | - case OPC_WSBH: | ||
4716 | - GEN_LOAD_REG_TN(T1, rt); | ||
4717 | - gen_op_wsbh(); | 4734 | + case OPC_RDHWR: |
4735 | + switch (rd) { | ||
4736 | + case 0: | ||
4737 | + gen_op_rdhwr_cpunum(); | ||
4718 | break; | 4738 | break; |
4719 | - case OPC_SEB: | ||
4720 | - GEN_LOAD_REG_TN(T1, rt); | ||
4721 | - gen_op_seb(); | 4739 | + case 1: |
4740 | + gen_op_rdhwr_synci_step(); | ||
4722 | break; | 4741 | break; |
4723 | - case OPC_SEH: | ||
4724 | - GEN_LOAD_REG_TN(T1, rt); | ||
4725 | - gen_op_seh(); | 4742 | + case 2: |
4743 | + gen_op_rdhwr_cc(); | ||
4726 | break; | 4744 | break; |
4727 | - default: /* Invalid */ | ||
4728 | - MIPS_INVAL("bshfl"); | ||
4729 | - generate_exception(ctx, EXCP_RI); | 4745 | + case 3: |
4746 | + gen_op_rdhwr_ccres(); | ||
4730 | break; | 4747 | break; |
4731 | - } | ||
4732 | - GEN_STORE_TN_REG(rd, T0); | ||
4733 | - break; | ||
4734 | - case OPC_RDHWR: | ||
4735 | - switch (rd) { | ||
4736 | - case 0: | ||
4737 | - gen_op_rdhwr_cpunum(); | ||
4738 | - break; | ||
4739 | - case 1: | ||
4740 | - gen_op_rdhwr_synci_step(); | ||
4741 | - break; | ||
4742 | - case 2: | ||
4743 | - gen_op_rdhwr_cc(); | ||
4744 | - break; | ||
4745 | - case 3: | ||
4746 | - gen_op_rdhwr_ccres(); | ||
4747 | - break; | 4748 | + case 29: |
4748 | #if defined (CONFIG_USER_ONLY) | 4749 | #if defined (CONFIG_USER_ONLY) |
4749 | - case 29: | ||
4750 | - gen_op_tls_value (); | ||
4751 | - GEN_STORE_TN_REG(rt, T0); | ||
4752 | - break; | 4750 | + gen_op_tls_value (); |
4751 | +#else | ||
4752 | + generate_exception(ctx, EXCP_RI); | ||
4753 | #endif | 4753 | #endif |
4754 | - default: /* Invalid */ | ||
4755 | - MIPS_INVAL("rdhwr"); | ||
4756 | - generate_exception(ctx, EXCP_RI); | ||
4757 | - break; | ||
4758 | - } | ||
4759 | - GEN_STORE_TN_REG(rt, T0); | ||
4760 | - break; | 4754 | + break; |
4755 | + case 30: | ||
4756 | + /* Implementation dependent */; | ||
4757 | + gen_op_rdhwr_unimpl30(); | ||
4758 | + break; | ||
4759 | + case 31: | ||
4760 | + /* Implementation dependent */; | ||
4761 | + gen_op_rdhwr_unimpl31(); | ||
4762 | + break; | ||
4763 | + default: /* Invalid */ | ||
4764 | + MIPS_INVAL("rdhwr"); | ||
4765 | + generate_exception(ctx, EXCP_RI); | ||
4766 | + break; | ||
4767 | + } | ||
4768 | + GEN_STORE_TN_REG(rt, T0); | ||
4769 | + break; | ||
4761 | #ifdef TARGET_MIPS64 | 4770 | #ifdef TARGET_MIPS64 |
4762 | - case OPC_DEXTM ... OPC_DEXT: | ||
4763 | - case OPC_DINSM ... OPC_DINS: | ||
4764 | - gen_bitops(ctx, op1, rt, rs, sa, rd); | 4771 | + case OPC_DEXTM ... OPC_DEXT: |
4772 | + case OPC_DINSM ... OPC_DINS: | ||
4773 | + gen_bitops(ctx, op1, rt, rs, sa, rd); | ||
4765 | break; | 4774 | break; |
4766 | - case OPC_DBSHFL: | ||
4767 | - op2 = MASK_DBSHFL(ctx->opcode); | ||
4768 | - switch (op2) { | ||
4769 | - case OPC_DSBH: | ||
4770 | - GEN_LOAD_REG_TN(T1, rt); | ||
4771 | - gen_op_dsbh(); | ||
4772 | - break; | ||
4773 | - case OPC_DSHD: | ||
4774 | - GEN_LOAD_REG_TN(T1, rt); | ||
4775 | - gen_op_dshd(); | ||
4776 | - break; | 4775 | + case OPC_DBSHFL: |
4776 | + op2 = MASK_DBSHFL(ctx->opcode); | ||
4777 | + switch (op2) { | ||
4778 | + case OPC_DSBH: | ||
4779 | + GEN_LOAD_REG_TN(T1, rt); | ||
4780 | + gen_op_dsbh(); | ||
4781 | + break; | ||
4782 | + case OPC_DSHD: | ||
4783 | + GEN_LOAD_REG_TN(T1, rt); | ||
4784 | + gen_op_dshd(); | ||
4785 | + break; | ||
4777 | default: /* Invalid */ | 4786 | default: /* Invalid */ |
4778 | MIPS_INVAL("dbshfl"); | 4787 | MIPS_INVAL("dbshfl"); |
4779 | generate_exception(ctx, EXCP_RI); | 4788 | generate_exception(ctx, EXCP_RI); |
4780 | break; | 4789 | break; |
4781 | - } | ||
4782 | - GEN_STORE_TN_REG(rd, T0); | 4790 | + } |
4791 | + GEN_STORE_TN_REG(rd, T0); | ||
4783 | #endif | 4792 | #endif |
4784 | default: /* Invalid */ | 4793 | default: /* Invalid */ |
4785 | MIPS_INVAL("special3"); | 4794 | MIPS_INVAL("special3"); |