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 | 336 | T0 = (int32_t)T0 + (int32_t)T1; |
| 337 | 337 | if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 31) { |
| 338 | 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 | 341 | T0 = (int32_t)T0; |
| 342 | 342 | RETURN(); |
| ... | ... | @@ -356,7 +356,7 @@ void op_subo (void) |
| 356 | 356 | T0 = (int32_t)T0 - (int32_t)T1; |
| 357 | 357 | if (((tmp ^ T1) & (tmp ^ T0)) >> 31) { |
| 358 | 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 | 361 | T0 = (int32_t)T0; |
| 362 | 362 | RETURN(); |
| ... | ... | @@ -402,7 +402,7 @@ void op_daddo (void) |
| 402 | 402 | T0 += T1; |
| 403 | 403 | if (((tmp ^ T1 ^ (-1)) & (T0 ^ T1)) >> 63) { |
| 404 | 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 | 407 | RETURN(); |
| 408 | 408 | } |
| ... | ... | @@ -421,7 +421,7 @@ void op_dsubo (void) |
| 421 | 421 | T0 = (int64_t)T0 - (int64_t)T1; |
| 422 | 422 | if (((tmp ^ T1) & (tmp ^ T0)) >> 63) { |
| 423 | 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 | 426 | RETURN(); |
| 427 | 427 | } |
| ... | ... | @@ -1650,7 +1650,7 @@ void op_cp0_enabled(void) |
| 1650 | 1650 | { |
| 1651 | 1651 | if (!(env->CP0_Status & (1 << CP0St_CU0)) && |
| 1652 | 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 | 1655 | RETURN(); |
| 1656 | 1656 | } |
| ... | ... | @@ -1658,7 +1658,7 @@ void op_cp0_enabled(void) |
| 1658 | 1658 | void op_cp1_enabled(void) |
| 1659 | 1659 | { |
| 1660 | 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 | 1663 | RETURN(); |
| 1664 | 1664 | } |
| ... | ... | @@ -2063,7 +2063,7 @@ void op_ei (void) |
| 2063 | 2063 | void op_trap (void) |
| 2064 | 2064 | { |
| 2065 | 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 | 2068 | RETURN(); |
| 2069 | 2069 | } |
| ... | ... | @@ -2116,37 +2116,67 @@ void op_deret (void) |
| 2116 | 2116 | |
| 2117 | 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 | 2123 | else |
| 2122 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); | |
| 2124 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); | |
| 2123 | 2125 | RETURN(); |
| 2124 | 2126 | } |
| 2125 | 2127 | |
| 2126 | 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 | 2134 | else |
| 2131 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); | |
| 2135 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); | |
| 2132 | 2136 | RETURN(); |
| 2133 | 2137 | } |
| 2134 | 2138 | |
| 2135 | 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 | 2145 | else |
| 2140 | - CALL_FROM_TB1(do_raise_exception_direct, EXCP_RI); | |
| 2146 | + CALL_FROM_TB1(do_raise_exception, EXCP_RI); | |
| 2141 | 2147 | RETURN(); |
| 2142 | 2148 | } |
| 2143 | 2149 | |
| 2144 | 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 | 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 | 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 | 1762 | break; |
| 1763 | 1763 | default: |
| 1764 | 1764 | goto die; |
| 1765 | - } | |
| 1765 | + } | |
| 1766 | 1766 | break; |
| 1767 | 1767 | case 4: |
| 1768 | 1768 | switch (sel) { |
| ... | ... | @@ -1776,7 +1776,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) |
| 1776 | 1776 | // break; |
| 1777 | 1777 | default: |
| 1778 | 1778 | goto die; |
| 1779 | - } | |
| 1779 | + } | |
| 1780 | 1780 | break; |
| 1781 | 1781 | case 5: |
| 1782 | 1782 | switch (sel) { |
| ... | ... | @@ -1790,7 +1790,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) |
| 1790 | 1790 | break; |
| 1791 | 1791 | default: |
| 1792 | 1792 | goto die; |
| 1793 | - } | |
| 1793 | + } | |
| 1794 | 1794 | break; |
| 1795 | 1795 | case 6: |
| 1796 | 1796 | switch (sel) { |
| ... | ... | @@ -1820,7 +1820,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) |
| 1820 | 1820 | // break; |
| 1821 | 1821 | default: |
| 1822 | 1822 | goto die; |
| 1823 | - } | |
| 1823 | + } | |
| 1824 | 1824 | break; |
| 1825 | 1825 | case 7: |
| 1826 | 1826 | switch (sel) { |
| ... | ... | @@ -1830,7 +1830,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) |
| 1830 | 1830 | break; |
| 1831 | 1831 | default: |
| 1832 | 1832 | goto die; |
| 1833 | - } | |
| 1833 | + } | |
| 1834 | 1834 | break; |
| 1835 | 1835 | case 8: |
| 1836 | 1836 | switch (sel) { |
| ... | ... | @@ -1861,7 +1861,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) |
| 1861 | 1861 | break; |
| 1862 | 1862 | default: |
| 1863 | 1863 | goto die; |
| 1864 | - } | |
| 1864 | + } | |
| 1865 | 1865 | break; |
| 1866 | 1866 | case 11: |
| 1867 | 1867 | switch (sel) { |
| ... | ... | @@ -1914,7 +1914,7 @@ static void gen_mfc0 (DisasContext *ctx, int reg, int sel) |
| 1914 | 1914 | break; |
| 1915 | 1915 | default: |
| 1916 | 1916 | goto die; |
| 1917 | - } | |
| 1917 | + } | |
| 1918 | 1918 | break; |
| 1919 | 1919 | case 15: |
| 1920 | 1920 | switch (sel) { |
| ... | ... | @@ -2521,7 +2521,7 @@ static void gen_mtc0 (DisasContext *ctx, int reg, int sel) |
| 2521 | 2521 | break; |
| 2522 | 2522 | default: |
| 2523 | 2523 | goto die; |
| 2524 | - } | |
| 2524 | + } | |
| 2525 | 2525 | break; |
| 2526 | 2526 | case 16: |
| 2527 | 2527 | switch (sel) { |
| ... | ... | @@ -2955,7 +2955,7 @@ static void gen_dmfc0 (DisasContext *ctx, int reg, int sel) |
| 2955 | 2955 | break; |
| 2956 | 2956 | default: |
| 2957 | 2957 | goto die; |
| 2958 | - } | |
| 2958 | + } | |
| 2959 | 2959 | break; |
| 2960 | 2960 | case 4: |
| 2961 | 2961 | switch (sel) { |
| ... | ... | @@ -4703,83 +4703,92 @@ static void decode_opc (CPUState *env, DisasContext *ctx) |
| 4703 | 4703 | } |
| 4704 | 4704 | break; |
| 4705 | 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 | 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 | 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 | 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 | 4744 | break; |
| 4727 | - default: /* Invalid */ | |
| 4728 | - MIPS_INVAL("bshfl"); | |
| 4729 | - generate_exception(ctx, EXCP_RI); | |
| 4745 | + case 3: | |
| 4746 | + gen_op_rdhwr_ccres(); | |
| 4730 | 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 | 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 | 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 | 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 | 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 | 4786 | default: /* Invalid */ |
| 4778 | 4787 | MIPS_INVAL("dbshfl"); |
| 4779 | 4788 | generate_exception(ctx, EXCP_RI); |
| 4780 | 4789 | break; |
| 4781 | - } | |
| 4782 | - GEN_STORE_TN_REG(rd, T0); | |
| 4790 | + } | |
| 4791 | + GEN_STORE_TN_REG(rd, T0); | |
| 4783 | 4792 | #endif |
| 4784 | 4793 | default: /* Invalid */ |
| 4785 | 4794 | MIPS_INVAL("special3"); | ... | ... |