Commit 3cc6237083cd40247e060c1fcf403a2d9ccbaf92
1 parent
c4decf37
ppc fixes (Jocelyn Mayer)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1297 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
101 additions
and
67 deletions
target-ppc/cpu.h
target-ppc/helper.c
@@ -18,10 +18,6 @@ | @@ -18,10 +18,6 @@ | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #include "exec.h" | 20 | #include "exec.h" |
21 | -#if defined (USE_OPEN_FIRMWARE) | ||
22 | -#include <time.h> | ||
23 | -#include "of.h" | ||
24 | -#endif | ||
25 | 21 | ||
26 | //#define DEBUG_MMU | 22 | //#define DEBUG_MMU |
27 | //#define DEBUG_BATS | 23 | //#define DEBUG_BATS |
@@ -688,18 +684,6 @@ void do_interrupt (CPUState *env) | @@ -688,18 +684,6 @@ void do_interrupt (CPUState *env) | ||
688 | } | 684 | } |
689 | /* Generate informations in save/restore registers */ | 685 | /* Generate informations in save/restore registers */ |
690 | switch (excp) { | 686 | switch (excp) { |
691 | - case EXCP_OFCALL: | ||
692 | -#if defined (USE_OPEN_FIRMWARE) | ||
693 | - env->gpr[3] = OF_client_entry((void *)env->gpr[3]); | ||
694 | -#endif | ||
695 | - return; | ||
696 | - case EXCP_RTASCALL: | ||
697 | -#if defined (USE_OPEN_FIRMWARE) | ||
698 | - printf("RTAS call !\n"); | ||
699 | - env->gpr[3] = RTAS_entry((void *)env->gpr[3]); | ||
700 | - printf("RTAS call done\n"); | ||
701 | -#endif | ||
702 | - return; | ||
703 | case EXCP_NONE: | 687 | case EXCP_NONE: |
704 | /* Do nothing */ | 688 | /* Do nothing */ |
705 | #if defined (DEBUG_EXCEPTIONS) | 689 | #if defined (DEBUG_EXCEPTIONS) |
target-ppc/op.c
@@ -697,9 +697,9 @@ PPC_OP(addzeo) | @@ -697,9 +697,9 @@ PPC_OP(addzeo) | ||
697 | PPC_OP(divw) | 697 | PPC_OP(divw) |
698 | { | 698 | { |
699 | if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { | 699 | if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) { |
700 | - Ts0 = (-1) * (T0 >> 31); | 700 | + T0 = (int32_t)((-1) * (T0 >> 31)); |
701 | } else { | 701 | } else { |
702 | - Ts0 /= Ts1; | 702 | + T0 = (Ts0 / Ts1); |
703 | } | 703 | } |
704 | RETURN(); | 704 | RETURN(); |
705 | } | 705 | } |
@@ -712,7 +712,7 @@ PPC_OP(divwo) | @@ -712,7 +712,7 @@ PPC_OP(divwo) | ||
712 | T0 = (-1) * (T0 >> 31); | 712 | T0 = (-1) * (T0 >> 31); |
713 | } else { | 713 | } else { |
714 | xer_ov = 0; | 714 | xer_ov = 0; |
715 | - Ts0 /= Ts1; | 715 | + T0 = (Ts0 / Ts1); |
716 | } | 716 | } |
717 | RETURN(); | 717 | RETURN(); |
718 | } | 718 | } |
@@ -744,7 +744,7 @@ PPC_OP(divwuo) | @@ -744,7 +744,7 @@ PPC_OP(divwuo) | ||
744 | /* multiply high word */ | 744 | /* multiply high word */ |
745 | PPC_OP(mulhw) | 745 | PPC_OP(mulhw) |
746 | { | 746 | { |
747 | - Ts0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32; | 747 | + T0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32; |
748 | RETURN(); | 748 | RETURN(); |
749 | } | 749 | } |
750 | 750 | ||
@@ -758,7 +758,7 @@ PPC_OP(mulhwu) | @@ -758,7 +758,7 @@ PPC_OP(mulhwu) | ||
758 | /* multiply low immediate */ | 758 | /* multiply low immediate */ |
759 | PPC_OP(mulli) | 759 | PPC_OP(mulli) |
760 | { | 760 | { |
761 | - Ts0 *= SPARAM(1); | 761 | + T0 = (Ts0 * SPARAM(1)); |
762 | RETURN(); | 762 | RETURN(); |
763 | } | 763 | } |
764 | 764 | ||
@@ -779,7 +779,7 @@ PPC_OP(mullwo) | @@ -779,7 +779,7 @@ PPC_OP(mullwo) | ||
779 | } else { | 779 | } else { |
780 | xer_ov = 0; | 780 | xer_ov = 0; |
781 | } | 781 | } |
782 | - Ts0 = res; | 782 | + T0 = (int32_t)res; |
783 | RETURN(); | 783 | RETURN(); |
784 | } | 784 | } |
785 | 785 | ||
@@ -787,7 +787,7 @@ PPC_OP(mullwo) | @@ -787,7 +787,7 @@ PPC_OP(mullwo) | ||
787 | PPC_OP(neg) | 787 | PPC_OP(neg) |
788 | { | 788 | { |
789 | if (T0 != 0x80000000) { | 789 | if (T0 != 0x80000000) { |
790 | - Ts0 = -Ts0; | 790 | + T0 = -Ts0; |
791 | } | 791 | } |
792 | RETURN(); | 792 | RETURN(); |
793 | } | 793 | } |
@@ -799,7 +799,7 @@ PPC_OP(nego) | @@ -799,7 +799,7 @@ PPC_OP(nego) | ||
799 | xer_so = 1; | 799 | xer_so = 1; |
800 | } else { | 800 | } else { |
801 | xer_ov = 0; | 801 | xer_ov = 0; |
802 | - Ts0 = -Ts0; | 802 | + T0 = -Ts0; |
803 | } | 803 | } |
804 | RETURN(); | 804 | RETURN(); |
805 | } | 805 | } |
@@ -1047,14 +1047,14 @@ PPC_OP(eqv) | @@ -1047,14 +1047,14 @@ PPC_OP(eqv) | ||
1047 | /* extend sign byte */ | 1047 | /* extend sign byte */ |
1048 | PPC_OP(extsb) | 1048 | PPC_OP(extsb) |
1049 | { | 1049 | { |
1050 | - Ts0 = (int8_t)(Ts0); | 1050 | + T0 = (int32_t)((int8_t)(Ts0)); |
1051 | RETURN(); | 1051 | RETURN(); |
1052 | } | 1052 | } |
1053 | 1053 | ||
1054 | /* extend sign half word */ | 1054 | /* extend sign half word */ |
1055 | PPC_OP(extsh) | 1055 | PPC_OP(extsh) |
1056 | { | 1056 | { |
1057 | - Ts0 = (int16_t)(Ts0); | 1057 | + T0 = (int32_t)((int16_t)(Ts0)); |
1058 | RETURN(); | 1058 | RETURN(); |
1059 | } | 1059 | } |
1060 | 1060 | ||
@@ -1175,8 +1175,8 @@ PPC_OP(sraw) | @@ -1175,8 +1175,8 @@ PPC_OP(sraw) | ||
1175 | /* shift right algebraic word immediate */ | 1175 | /* shift right algebraic word immediate */ |
1176 | PPC_OP(srawi) | 1176 | PPC_OP(srawi) |
1177 | { | 1177 | { |
1178 | - Ts1 = Ts0; | ||
1179 | - Ts0 = Ts0 >> PARAM(1); | 1178 | + T1 = T0; |
1179 | + T0 = (Ts0 >> PARAM(1)); | ||
1180 | if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) { | 1180 | if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) { |
1181 | xer_ca = 1; | 1181 | xer_ca = 1; |
1182 | } else { | 1182 | } else { |
@@ -1207,7 +1207,7 @@ PPC_OP(fadd) | @@ -1207,7 +1207,7 @@ PPC_OP(fadd) | ||
1207 | /* fadds - fadds. */ | 1207 | /* fadds - fadds. */ |
1208 | PPC_OP(fadds) | 1208 | PPC_OP(fadds) |
1209 | { | 1209 | { |
1210 | - FTS0 += FTS1; | 1210 | + FT0 = FTS0 + FTS1; |
1211 | RETURN(); | 1211 | RETURN(); |
1212 | } | 1212 | } |
1213 | 1213 | ||
@@ -1221,7 +1221,7 @@ PPC_OP(fsub) | @@ -1221,7 +1221,7 @@ PPC_OP(fsub) | ||
1221 | /* fsubs - fsubs. */ | 1221 | /* fsubs - fsubs. */ |
1222 | PPC_OP(fsubs) | 1222 | PPC_OP(fsubs) |
1223 | { | 1223 | { |
1224 | - FTS0 -= FTS1; | 1224 | + FT0 = FTS0 - FTS1; |
1225 | RETURN(); | 1225 | RETURN(); |
1226 | } | 1226 | } |
1227 | 1227 | ||
@@ -1235,7 +1235,7 @@ PPC_OP(fmul) | @@ -1235,7 +1235,7 @@ PPC_OP(fmul) | ||
1235 | /* fmuls - fmuls. */ | 1235 | /* fmuls - fmuls. */ |
1236 | PPC_OP(fmuls) | 1236 | PPC_OP(fmuls) |
1237 | { | 1237 | { |
1238 | - FTS0 *= FTS1; | 1238 | + FT0 = FTS0 * FTS1; |
1239 | RETURN(); | 1239 | RETURN(); |
1240 | } | 1240 | } |
1241 | 1241 | ||
@@ -1249,7 +1249,7 @@ PPC_OP(fdiv) | @@ -1249,7 +1249,7 @@ PPC_OP(fdiv) | ||
1249 | /* fdivs - fdivs. */ | 1249 | /* fdivs - fdivs. */ |
1250 | PPC_OP(fdivs) | 1250 | PPC_OP(fdivs) |
1251 | { | 1251 | { |
1252 | - FTS0 /= FTS1; | 1252 | + FT0 = FTS0 / FTS1; |
1253 | RETURN(); | 1253 | RETURN(); |
1254 | } | 1254 | } |
1255 | 1255 | ||
@@ -1299,7 +1299,7 @@ PPC_OP(fmadd) | @@ -1299,7 +1299,7 @@ PPC_OP(fmadd) | ||
1299 | /* fmadds - fmadds. */ | 1299 | /* fmadds - fmadds. */ |
1300 | PPC_OP(fmadds) | 1300 | PPC_OP(fmadds) |
1301 | { | 1301 | { |
1302 | - FTS0 = (FTS0 * FTS1) + FTS2; | 1302 | + FT0 = (FTS0 * FTS1) + FTS2; |
1303 | RETURN(); | 1303 | RETURN(); |
1304 | } | 1304 | } |
1305 | 1305 | ||
@@ -1313,7 +1313,7 @@ PPC_OP(fmsub) | @@ -1313,7 +1313,7 @@ PPC_OP(fmsub) | ||
1313 | /* fmsubs - fmsubs. */ | 1313 | /* fmsubs - fmsubs. */ |
1314 | PPC_OP(fmsubs) | 1314 | PPC_OP(fmsubs) |
1315 | { | 1315 | { |
1316 | - FTS0 = (FTS0 * FTS1) - FTS2; | 1316 | + FT0 = (FTS0 * FTS1) - FTS2; |
1317 | RETURN(); | 1317 | RETURN(); |
1318 | } | 1318 | } |
1319 | 1319 | ||
@@ -1349,7 +1349,7 @@ PPC_OP(fnmsubs) | @@ -1349,7 +1349,7 @@ PPC_OP(fnmsubs) | ||
1349 | /* frsp - frsp. */ | 1349 | /* frsp - frsp. */ |
1350 | PPC_OP(frsp) | 1350 | PPC_OP(frsp) |
1351 | { | 1351 | { |
1352 | - FTS0 = FT0; | 1352 | + FT0 = (float)FT0; |
1353 | RETURN(); | 1353 | RETURN(); |
1354 | } | 1354 | } |
1355 | 1355 |
target-ppc/op_helper.c
@@ -188,10 +188,17 @@ void do_load_fpscr (void) | @@ -188,10 +188,17 @@ void do_load_fpscr (void) | ||
188 | } u; | 188 | } u; |
189 | int i; | 189 | int i; |
190 | 190 | ||
191 | - u.s.u[0] = 0; | ||
192 | - u.s.u[1] = 0; | 191 | +#ifdef WORDS_BIGENDIAN |
192 | +#define WORD0 0 | ||
193 | +#define WORD1 1 | ||
194 | +#else | ||
195 | +#define WORD0 1 | ||
196 | +#define WORD1 0 | ||
197 | +#endif | ||
198 | + u.s.u[WORD0] = 0; | ||
199 | + u.s.u[WORD1] = 0; | ||
193 | for (i = 0; i < 8; i++) | 200 | for (i = 0; i < 8; i++) |
194 | - u.s.u[1] |= env->fpscr[i] << (4 * i); | 201 | + u.s.u[WORD1] |= env->fpscr[i] << (4 * i); |
195 | FT0 = u.d; | 202 | FT0 = u.d; |
196 | } | 203 | } |
197 | 204 | ||
@@ -210,10 +217,10 @@ void do_store_fpscr (uint32_t mask) | @@ -210,10 +217,10 @@ void do_store_fpscr (uint32_t mask) | ||
210 | 217 | ||
211 | u.d = FT0; | 218 | u.d = FT0; |
212 | if (mask & 0x80) | 219 | if (mask & 0x80) |
213 | - env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[1] >> 28) & ~0x9); | 220 | + env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[WORD1] >> 28) & ~0x9); |
214 | for (i = 1; i < 7; i++) { | 221 | for (i = 1; i < 7; i++) { |
215 | if (mask & (1 << (7 - i))) | 222 | if (mask & (1 << (7 - i))) |
216 | - env->fpscr[i] = (u.s.u[1] >> (4 * (7 - i))) & 0xF; | 223 | + env->fpscr[i] = (u.s.u[WORD1] >> (4 * (7 - i))) & 0xF; |
217 | } | 224 | } |
218 | /* TODO: update FEX & VX */ | 225 | /* TODO: update FEX & VX */ |
219 | /* Set rounding mode */ | 226 | /* Set rounding mode */ |
target-ppc/translate.c
@@ -134,12 +134,13 @@ typedef struct DisasContext { | @@ -134,12 +134,13 @@ typedef struct DisasContext { | ||
134 | target_ulong nip; | 134 | target_ulong nip; |
135 | uint32_t opcode; | 135 | uint32_t opcode; |
136 | uint32_t exception; | 136 | uint32_t exception; |
137 | - /* Execution mode */ | 137 | + /* Routine used to access memory */ |
138 | + int mem_idx; | ||
139 | + /* Translation flags */ | ||
138 | #if !defined(CONFIG_USER_ONLY) | 140 | #if !defined(CONFIG_USER_ONLY) |
139 | int supervisor; | 141 | int supervisor; |
140 | #endif | 142 | #endif |
141 | - /* Routine used to access memory */ | ||
142 | - int mem_idx; | 143 | + int fpu_enabled; |
143 | } DisasContext; | 144 | } DisasContext; |
144 | 145 | ||
145 | typedef struct opc_handler_t { | 146 | typedef struct opc_handler_t { |
@@ -330,19 +331,6 @@ GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON) | @@ -330,19 +331,6 @@ GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON) | ||
330 | RET_EXCP(ctx, EXCP_HLT, 0); | 331 | RET_EXCP(ctx, EXCP_HLT, 0); |
331 | } | 332 | } |
332 | 333 | ||
333 | -/* Special opcode to call open-firmware */ | ||
334 | -GEN_HANDLER(of_enter, 0x06, 0x01, 0xFF, 0x03FFFFC1, PPC_COMMON) | ||
335 | -{ | ||
336 | - RET_EXCP(ctx, EXCP_OFCALL, 0); | ||
337 | -} | ||
338 | - | ||
339 | -/* Special opcode to call RTAS */ | ||
340 | -GEN_HANDLER(rtas_enter, 0x06, 0x02, 0xFF, 0x03FFFFC1, PPC_COMMON) | ||
341 | -{ | ||
342 | - printf("RTAS entry point !\n"); | ||
343 | - RET_EXCP(ctx, EXCP_RTASCALL, 0); | ||
344 | -} | ||
345 | - | ||
346 | static opc_handler_t invalid_handler = { | 334 | static opc_handler_t invalid_handler = { |
347 | .inval = 0xFFFFFFFF, | 335 | .inval = 0xFFFFFFFF, |
348 | .type = PPC_NONE, | 336 | .type = PPC_NONE, |
@@ -764,6 +752,10 @@ __GEN_LOGICAL2(srw, 0x18, 0x10); | @@ -764,6 +752,10 @@ __GEN_LOGICAL2(srw, 0x18, 0x10); | ||
764 | #define _GEN_FLOAT_ACB(name, op1, op2) \ | 752 | #define _GEN_FLOAT_ACB(name, op1, op2) \ |
765 | GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \ | 753 | GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, PPC_FLOAT) \ |
766 | { \ | 754 | { \ |
755 | + if (!ctx->fpu_enabled) { \ | ||
756 | + RET_EXCP(ctx, EXCP_NO_FP, 0); \ | ||
757 | + return; \ | ||
758 | + } \ | ||
767 | gen_op_reset_scrfx(); \ | 759 | gen_op_reset_scrfx(); \ |
768 | gen_op_load_fpr_FT0(rA(ctx->opcode)); \ | 760 | gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
769 | gen_op_load_fpr_FT1(rC(ctx->opcode)); \ | 761 | gen_op_load_fpr_FT1(rC(ctx->opcode)); \ |
@@ -781,6 +773,10 @@ _GEN_FLOAT_ACB(name##s, 0x3B, op2); | @@ -781,6 +773,10 @@ _GEN_FLOAT_ACB(name##s, 0x3B, op2); | ||
781 | #define _GEN_FLOAT_AB(name, op1, op2, inval) \ | 773 | #define _GEN_FLOAT_AB(name, op1, op2, inval) \ |
782 | GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ | 774 | GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ |
783 | { \ | 775 | { \ |
776 | + if (!ctx->fpu_enabled) { \ | ||
777 | + RET_EXCP(ctx, EXCP_NO_FP, 0); \ | ||
778 | + return; \ | ||
779 | + } \ | ||
784 | gen_op_reset_scrfx(); \ | 780 | gen_op_reset_scrfx(); \ |
785 | gen_op_load_fpr_FT0(rA(ctx->opcode)); \ | 781 | gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
786 | gen_op_load_fpr_FT1(rB(ctx->opcode)); \ | 782 | gen_op_load_fpr_FT1(rB(ctx->opcode)); \ |
@@ -796,6 +792,10 @@ _GEN_FLOAT_AB(name##s, 0x3B, op2, inval); | @@ -796,6 +792,10 @@ _GEN_FLOAT_AB(name##s, 0x3B, op2, inval); | ||
796 | #define _GEN_FLOAT_AC(name, op1, op2, inval) \ | 792 | #define _GEN_FLOAT_AC(name, op1, op2, inval) \ |
797 | GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ | 793 | GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ |
798 | { \ | 794 | { \ |
795 | + if (!ctx->fpu_enabled) { \ | ||
796 | + RET_EXCP(ctx, EXCP_NO_FP, 0); \ | ||
797 | + return; \ | ||
798 | + } \ | ||
799 | gen_op_reset_scrfx(); \ | 799 | gen_op_reset_scrfx(); \ |
800 | gen_op_load_fpr_FT0(rA(ctx->opcode)); \ | 800 | gen_op_load_fpr_FT0(rA(ctx->opcode)); \ |
801 | gen_op_load_fpr_FT1(rC(ctx->opcode)); \ | 801 | gen_op_load_fpr_FT1(rC(ctx->opcode)); \ |
@@ -811,6 +811,10 @@ _GEN_FLOAT_AC(name##s, 0x3B, op2, inval); | @@ -811,6 +811,10 @@ _GEN_FLOAT_AC(name##s, 0x3B, op2, inval); | ||
811 | #define GEN_FLOAT_B(name, op2, op3) \ | 811 | #define GEN_FLOAT_B(name, op2, op3) \ |
812 | GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \ | 812 | GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \ |
813 | { \ | 813 | { \ |
814 | + if (!ctx->fpu_enabled) { \ | ||
815 | + RET_EXCP(ctx, EXCP_NO_FP, 0); \ | ||
816 | + return; \ | ||
817 | + } \ | ||
814 | gen_op_reset_scrfx(); \ | 818 | gen_op_reset_scrfx(); \ |
815 | gen_op_load_fpr_FT0(rB(ctx->opcode)); \ | 819 | gen_op_load_fpr_FT0(rB(ctx->opcode)); \ |
816 | gen_op_f##name(); \ | 820 | gen_op_f##name(); \ |
@@ -822,6 +826,10 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \ | @@ -822,6 +826,10 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \ | ||
822 | #define GEN_FLOAT_BS(name, op2) \ | 826 | #define GEN_FLOAT_BS(name, op2) \ |
823 | GEN_HANDLER(f##name, 0x3F, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \ | 827 | GEN_HANDLER(f##name, 0x3F, op2, 0xFF, 0x001F07C0, PPC_FLOAT) \ |
824 | { \ | 828 | { \ |
829 | + if (!ctx->fpu_enabled) { \ | ||
830 | + RET_EXCP(ctx, EXCP_NO_FP, 0); \ | ||
831 | + return; \ | ||
832 | + } \ | ||
825 | gen_op_reset_scrfx(); \ | 833 | gen_op_reset_scrfx(); \ |
826 | gen_op_load_fpr_FT0(rB(ctx->opcode)); \ | 834 | gen_op_load_fpr_FT0(rB(ctx->opcode)); \ |
827 | gen_op_f##name(); \ | 835 | gen_op_f##name(); \ |
@@ -853,6 +861,10 @@ GEN_FLOAT_BS(sqrt, 0x16); | @@ -853,6 +861,10 @@ GEN_FLOAT_BS(sqrt, 0x16); | ||
853 | 861 | ||
854 | GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT) | 862 | GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_OPT) |
855 | { | 863 | { |
864 | + if (!ctx->fpu_enabled) { | ||
865 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
866 | + return; | ||
867 | + } | ||
856 | gen_op_reset_scrfx(); | 868 | gen_op_reset_scrfx(); |
857 | gen_op_load_fpr_FT0(rB(ctx->opcode)); | 869 | gen_op_load_fpr_FT0(rB(ctx->opcode)); |
858 | gen_op_fsqrts(); | 870 | gen_op_fsqrts(); |
@@ -883,6 +895,10 @@ GEN_FLOAT_B(rsp, 0x0C, 0x00); | @@ -883,6 +895,10 @@ GEN_FLOAT_B(rsp, 0x0C, 0x00); | ||
883 | /* fcmpo */ | 895 | /* fcmpo */ |
884 | GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) | 896 | GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) |
885 | { | 897 | { |
898 | + if (!ctx->fpu_enabled) { | ||
899 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
900 | + return; | ||
901 | + } | ||
886 | gen_op_reset_scrfx(); | 902 | gen_op_reset_scrfx(); |
887 | gen_op_load_fpr_FT0(rA(ctx->opcode)); | 903 | gen_op_load_fpr_FT0(rA(ctx->opcode)); |
888 | gen_op_load_fpr_FT1(rB(ctx->opcode)); | 904 | gen_op_load_fpr_FT1(rB(ctx->opcode)); |
@@ -893,6 +909,10 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) | @@ -893,6 +909,10 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) | ||
893 | /* fcmpu */ | 909 | /* fcmpu */ |
894 | GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) | 910 | GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) |
895 | { | 911 | { |
912 | + if (!ctx->fpu_enabled) { | ||
913 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
914 | + return; | ||
915 | + } | ||
896 | gen_op_reset_scrfx(); | 916 | gen_op_reset_scrfx(); |
897 | gen_op_load_fpr_FT0(rA(ctx->opcode)); | 917 | gen_op_load_fpr_FT0(rA(ctx->opcode)); |
898 | gen_op_load_fpr_FT1(rB(ctx->opcode)); | 918 | gen_op_load_fpr_FT1(rB(ctx->opcode)); |
@@ -907,6 +927,10 @@ GEN_FLOAT_B(abs, 0x08, 0x08); | @@ -907,6 +927,10 @@ GEN_FLOAT_B(abs, 0x08, 0x08); | ||
907 | /* fmr - fmr. */ | 927 | /* fmr - fmr. */ |
908 | GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT) | 928 | GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT) |
909 | { | 929 | { |
930 | + if (!ctx->fpu_enabled) { | ||
931 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
932 | + return; | ||
933 | + } | ||
910 | gen_op_reset_scrfx(); | 934 | gen_op_reset_scrfx(); |
911 | gen_op_load_fpr_FT0(rB(ctx->opcode)); | 935 | gen_op_load_fpr_FT0(rB(ctx->opcode)); |
912 | gen_op_store_FT0_fpr(rD(ctx->opcode)); | 936 | gen_op_store_FT0_fpr(rD(ctx->opcode)); |
@@ -923,6 +947,10 @@ GEN_FLOAT_B(neg, 0x08, 0x01); | @@ -923,6 +947,10 @@ GEN_FLOAT_B(neg, 0x08, 0x01); | ||
923 | /* mcrfs */ | 947 | /* mcrfs */ |
924 | GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) | 948 | GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) |
925 | { | 949 | { |
950 | + if (!ctx->fpu_enabled) { | ||
951 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
952 | + return; | ||
953 | + } | ||
926 | gen_op_load_fpscr_T0(crfS(ctx->opcode)); | 954 | gen_op_load_fpscr_T0(crfS(ctx->opcode)); |
927 | gen_op_store_T0_crf(crfD(ctx->opcode)); | 955 | gen_op_store_T0_crf(crfD(ctx->opcode)); |
928 | gen_op_clear_fpscr(crfS(ctx->opcode)); | 956 | gen_op_clear_fpscr(crfS(ctx->opcode)); |
@@ -931,6 +959,10 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) | @@ -931,6 +959,10 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) | ||
931 | /* mffs */ | 959 | /* mffs */ |
932 | GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) | 960 | GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) |
933 | { | 961 | { |
962 | + if (!ctx->fpu_enabled) { | ||
963 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
964 | + return; | ||
965 | + } | ||
934 | gen_op_load_fpscr(); | 966 | gen_op_load_fpscr(); |
935 | gen_op_store_FT0_fpr(rD(ctx->opcode)); | 967 | gen_op_store_FT0_fpr(rD(ctx->opcode)); |
936 | if (Rc(ctx->opcode)) | 968 | if (Rc(ctx->opcode)) |
@@ -942,6 +974,10 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) | @@ -942,6 +974,10 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) | ||
942 | { | 974 | { |
943 | uint8_t crb; | 975 | uint8_t crb; |
944 | 976 | ||
977 | + if (!ctx->fpu_enabled) { | ||
978 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
979 | + return; | ||
980 | + } | ||
945 | crb = crbD(ctx->opcode) >> 2; | 981 | crb = crbD(ctx->opcode) >> 2; |
946 | gen_op_load_fpscr_T0(crb); | 982 | gen_op_load_fpscr_T0(crb); |
947 | gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03))); | 983 | gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03))); |
@@ -955,6 +991,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) | @@ -955,6 +991,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) | ||
955 | { | 991 | { |
956 | uint8_t crb; | 992 | uint8_t crb; |
957 | 993 | ||
994 | + if (!ctx->fpu_enabled) { | ||
995 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
996 | + return; | ||
997 | + } | ||
958 | crb = crbD(ctx->opcode) >> 2; | 998 | crb = crbD(ctx->opcode) >> 2; |
959 | gen_op_load_fpscr_T0(crb); | 999 | gen_op_load_fpscr_T0(crb); |
960 | gen_op_ori(1 << (crbD(ctx->opcode) & 0x03)); | 1000 | gen_op_ori(1 << (crbD(ctx->opcode) & 0x03)); |
@@ -966,6 +1006,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) | @@ -966,6 +1006,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) | ||
966 | /* mtfsf */ | 1006 | /* mtfsf */ |
967 | GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) | 1007 | GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) |
968 | { | 1008 | { |
1009 | + if (!ctx->fpu_enabled) { | ||
1010 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
1011 | + return; | ||
1012 | + } | ||
969 | gen_op_load_fpr_FT0(rB(ctx->opcode)); | 1013 | gen_op_load_fpr_FT0(rB(ctx->opcode)); |
970 | gen_op_store_fpscr(FM(ctx->opcode)); | 1014 | gen_op_store_fpscr(FM(ctx->opcode)); |
971 | if (Rc(ctx->opcode)) | 1015 | if (Rc(ctx->opcode)) |
@@ -975,6 +1019,10 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) | @@ -975,6 +1019,10 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) | ||
975 | /* mtfsfi */ | 1019 | /* mtfsfi */ |
976 | GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) | 1020 | GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) |
977 | { | 1021 | { |
1022 | + if (!ctx->fpu_enabled) { | ||
1023 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
1024 | + return; | ||
1025 | + } | ||
978 | gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode)); | 1026 | gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode)); |
979 | if (Rc(ctx->opcode)) | 1027 | if (Rc(ctx->opcode)) |
980 | gen_op_set_Rc1(); | 1028 | gen_op_set_Rc1(); |
@@ -1525,6 +1573,10 @@ GEN_STFS(fs, 0x14); | @@ -1525,6 +1573,10 @@ GEN_STFS(fs, 0x14); | ||
1525 | /* stfiwx */ | 1573 | /* stfiwx */ |
1526 | GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT) | 1574 | GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT) |
1527 | { | 1575 | { |
1576 | + if (!ctx->fpu_enabled) { | ||
1577 | + RET_EXCP(ctx, EXCP_NO_FP, 0); | ||
1578 | + return; | ||
1579 | + } | ||
1528 | RET_INVAL(ctx); | 1580 | RET_INVAL(ctx); |
1529 | } | 1581 | } |
1530 | 1582 | ||
@@ -2978,10 +3030,6 @@ void cpu_dump_state(CPUState *env, FILE *f, | @@ -2978,10 +3030,6 @@ void cpu_dump_state(CPUState *env, FILE *f, | ||
2978 | cpu_fprintf(f, "reservation 0x%08x\n", env->reserve); | 3030 | cpu_fprintf(f, "reservation 0x%08x\n", env->reserve); |
2979 | } | 3031 | } |
2980 | 3032 | ||
2981 | -#if !defined(CONFIG_USER_ONLY) && defined (USE_OPENFIRMWARE) | ||
2982 | -int setup_machine (CPUPPCState *env, uint32_t mid); | ||
2983 | -#endif | ||
2984 | - | ||
2985 | CPUPPCState *cpu_ppc_init(void) | 3033 | CPUPPCState *cpu_ppc_init(void) |
2986 | { | 3034 | { |
2987 | CPUPPCState *env; | 3035 | CPUPPCState *env; |
@@ -2991,14 +3039,10 @@ CPUPPCState *cpu_ppc_init(void) | @@ -2991,14 +3039,10 @@ CPUPPCState *cpu_ppc_init(void) | ||
2991 | env = qemu_mallocz(sizeof(CPUPPCState)); | 3039 | env = qemu_mallocz(sizeof(CPUPPCState)); |
2992 | if (!env) | 3040 | if (!env) |
2993 | return NULL; | 3041 | return NULL; |
2994 | -#if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE) | ||
2995 | - setup_machine(env, 0); | ||
2996 | -#else | ||
2997 | // env->spr[PVR] = 0; /* Basic PPC */ | 3042 | // env->spr[PVR] = 0; /* Basic PPC */ |
2998 | env->spr[PVR] = 0x00080100; /* G3 CPU */ | 3043 | env->spr[PVR] = 0x00080100; /* G3 CPU */ |
2999 | // env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */ | 3044 | // env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */ |
3000 | // env->spr[PVR] = 0x00070100; /* IBM 750FX */ | 3045 | // env->spr[PVR] = 0x00070100; /* IBM 750FX */ |
3001 | -#endif | ||
3002 | tlb_flush(env, 1); | 3046 | tlb_flush(env, 1); |
3003 | #if defined (DO_SINGLE_STEP) | 3047 | #if defined (DO_SINGLE_STEP) |
3004 | /* Single step trace mode */ | 3048 | /* Single step trace mode */ |
@@ -3053,8 +3097,9 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | @@ -3053,8 +3097,9 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, | ||
3053 | ctx.mem_idx = 0; | 3097 | ctx.mem_idx = 0; |
3054 | #else | 3098 | #else |
3055 | ctx.supervisor = 1 - msr_pr; | 3099 | ctx.supervisor = 1 - msr_pr; |
3056 | - ctx.mem_idx = (1 - msr_pr); | 3100 | + ctx.mem_idx = 1 - msr_pr; |
3057 | #endif | 3101 | #endif |
3102 | + ctx.fpu_enabled = msr_fp; | ||
3058 | #if defined (DO_SINGLE_STEP) | 3103 | #if defined (DO_SINGLE_STEP) |
3059 | /* Single step trace mode */ | 3104 | /* Single step trace mode */ |
3060 | msr_se = 1; | 3105 | msr_se = 1; |