Commit 3cc6237083cd40247e060c1fcf403a2d9ccbaf92

Authored by bellard
1 parent c4decf37

ppc fixes (Jocelyn Mayer)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1297 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/cpu.h
... ... @@ -24,8 +24,6 @@
24 24  
25 25 #include "cpu-defs.h"
26 26  
27   -//#define USE_OPEN_FIRMWARE
28   -
29 27 #include "config.h"
30 28 #include <setjmp.h>
31 29  
... ...
target-ppc/helper.c
... ... @@ -18,10 +18,6 @@
18 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 19 */
20 20 #include "exec.h"
21   -#if defined (USE_OPEN_FIRMWARE)
22   -#include <time.h>
23   -#include "of.h"
24   -#endif
25 21  
26 22 //#define DEBUG_MMU
27 23 //#define DEBUG_BATS
... ... @@ -688,18 +684,6 @@ void do_interrupt (CPUState *env)
688 684 }
689 685 /* Generate informations in save/restore registers */
690 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 687 case EXCP_NONE:
704 688 /* Do nothing */
705 689 #if defined (DEBUG_EXCEPTIONS)
... ...
target-ppc/op.c
... ... @@ -697,9 +697,9 @@ PPC_OP(addzeo)
697 697 PPC_OP(divw)
698 698 {
699 699 if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
700   - Ts0 = (-1) * (T0 >> 31);
  700 + T0 = (int32_t)((-1) * (T0 >> 31));
701 701 } else {
702   - Ts0 /= Ts1;
  702 + T0 = (Ts0 / Ts1);
703 703 }
704 704 RETURN();
705 705 }
... ... @@ -712,7 +712,7 @@ PPC_OP(divwo)
712 712 T0 = (-1) * (T0 >> 31);
713 713 } else {
714 714 xer_ov = 0;
715   - Ts0 /= Ts1;
  715 + T0 = (Ts0 / Ts1);
716 716 }
717 717 RETURN();
718 718 }
... ... @@ -744,7 +744,7 @@ PPC_OP(divwuo)
744 744 /* multiply high word */
745 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 748 RETURN();
749 749 }
750 750  
... ... @@ -758,7 +758,7 @@ PPC_OP(mulhwu)
758 758 /* multiply low immediate */
759 759 PPC_OP(mulli)
760 760 {
761   - Ts0 *= SPARAM(1);
  761 + T0 = (Ts0 * SPARAM(1));
762 762 RETURN();
763 763 }
764 764  
... ... @@ -779,7 +779,7 @@ PPC_OP(mullwo)
779 779 } else {
780 780 xer_ov = 0;
781 781 }
782   - Ts0 = res;
  782 + T0 = (int32_t)res;
783 783 RETURN();
784 784 }
785 785  
... ... @@ -787,7 +787,7 @@ PPC_OP(mullwo)
787 787 PPC_OP(neg)
788 788 {
789 789 if (T0 != 0x80000000) {
790   - Ts0 = -Ts0;
  790 + T0 = -Ts0;
791 791 }
792 792 RETURN();
793 793 }
... ... @@ -799,7 +799,7 @@ PPC_OP(nego)
799 799 xer_so = 1;
800 800 } else {
801 801 xer_ov = 0;
802   - Ts0 = -Ts0;
  802 + T0 = -Ts0;
803 803 }
804 804 RETURN();
805 805 }
... ... @@ -1047,14 +1047,14 @@ PPC_OP(eqv)
1047 1047 /* extend sign byte */
1048 1048 PPC_OP(extsb)
1049 1049 {
1050   - Ts0 = (int8_t)(Ts0);
  1050 + T0 = (int32_t)((int8_t)(Ts0));
1051 1051 RETURN();
1052 1052 }
1053 1053  
1054 1054 /* extend sign half word */
1055 1055 PPC_OP(extsh)
1056 1056 {
1057   - Ts0 = (int16_t)(Ts0);
  1057 + T0 = (int32_t)((int16_t)(Ts0));
1058 1058 RETURN();
1059 1059 }
1060 1060  
... ... @@ -1175,8 +1175,8 @@ PPC_OP(sraw)
1175 1175 /* shift right algebraic word immediate */
1176 1176 PPC_OP(srawi)
1177 1177 {
1178   - Ts1 = Ts0;
1179   - Ts0 = Ts0 >> PARAM(1);
  1178 + T1 = T0;
  1179 + T0 = (Ts0 >> PARAM(1));
1180 1180 if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) {
1181 1181 xer_ca = 1;
1182 1182 } else {
... ... @@ -1207,7 +1207,7 @@ PPC_OP(fadd)
1207 1207 /* fadds - fadds. */
1208 1208 PPC_OP(fadds)
1209 1209 {
1210   - FTS0 += FTS1;
  1210 + FT0 = FTS0 + FTS1;
1211 1211 RETURN();
1212 1212 }
1213 1213  
... ... @@ -1221,7 +1221,7 @@ PPC_OP(fsub)
1221 1221 /* fsubs - fsubs. */
1222 1222 PPC_OP(fsubs)
1223 1223 {
1224   - FTS0 -= FTS1;
  1224 + FT0 = FTS0 - FTS1;
1225 1225 RETURN();
1226 1226 }
1227 1227  
... ... @@ -1235,7 +1235,7 @@ PPC_OP(fmul)
1235 1235 /* fmuls - fmuls. */
1236 1236 PPC_OP(fmuls)
1237 1237 {
1238   - FTS0 *= FTS1;
  1238 + FT0 = FTS0 * FTS1;
1239 1239 RETURN();
1240 1240 }
1241 1241  
... ... @@ -1249,7 +1249,7 @@ PPC_OP(fdiv)
1249 1249 /* fdivs - fdivs. */
1250 1250 PPC_OP(fdivs)
1251 1251 {
1252   - FTS0 /= FTS1;
  1252 + FT0 = FTS0 / FTS1;
1253 1253 RETURN();
1254 1254 }
1255 1255  
... ... @@ -1299,7 +1299,7 @@ PPC_OP(fmadd)
1299 1299 /* fmadds - fmadds. */
1300 1300 PPC_OP(fmadds)
1301 1301 {
1302   - FTS0 = (FTS0 * FTS1) + FTS2;
  1302 + FT0 = (FTS0 * FTS1) + FTS2;
1303 1303 RETURN();
1304 1304 }
1305 1305  
... ... @@ -1313,7 +1313,7 @@ PPC_OP(fmsub)
1313 1313 /* fmsubs - fmsubs. */
1314 1314 PPC_OP(fmsubs)
1315 1315 {
1316   - FTS0 = (FTS0 * FTS1) - FTS2;
  1316 + FT0 = (FTS0 * FTS1) - FTS2;
1317 1317 RETURN();
1318 1318 }
1319 1319  
... ... @@ -1349,7 +1349,7 @@ PPC_OP(fnmsubs)
1349 1349 /* frsp - frsp. */
1350 1350 PPC_OP(frsp)
1351 1351 {
1352   - FTS0 = FT0;
  1352 + FT0 = (float)FT0;
1353 1353 RETURN();
1354 1354 }
1355 1355  
... ...
target-ppc/op_helper.c
... ... @@ -188,10 +188,17 @@ void do_load_fpscr (void)
188 188 } u;
189 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 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 202 FT0 = u.d;
196 203 }
197 204  
... ... @@ -210,10 +217,10 @@ void do_store_fpscr (uint32_t mask)
210 217  
211 218 u.d = FT0;
212 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 221 for (i = 1; i < 7; i++) {
215 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 225 /* TODO: update FEX & VX */
219 226 /* Set rounding mode */
... ...
target-ppc/translate.c
... ... @@ -134,12 +134,13 @@ typedef struct DisasContext {
134 134 target_ulong nip;
135 135 uint32_t opcode;
136 136 uint32_t exception;
137   - /* Execution mode */
  137 + /* Routine used to access memory */
  138 + int mem_idx;
  139 + /* Translation flags */
138 140 #if !defined(CONFIG_USER_ONLY)
139 141 int supervisor;
140 142 #endif
141   - /* Routine used to access memory */
142   - int mem_idx;
  143 + int fpu_enabled;
143 144 } DisasContext;
144 145  
145 146 typedef struct opc_handler_t {
... ... @@ -330,19 +331,6 @@ GEN_HANDLER(stop, 0x06, 0x00, 0xFF, 0x03FFFFC1, PPC_COMMON)
330 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 334 static opc_handler_t invalid_handler = {
347 335 .inval = 0xFFFFFFFF,
348 336 .type = PPC_NONE,
... ... @@ -764,6 +752,10 @@ __GEN_LOGICAL2(srw, 0x18, 0x10);
764 752 #define _GEN_FLOAT_ACB(name, op1, op2) \
765 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 759 gen_op_reset_scrfx(); \
768 760 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
769 761 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
... ... @@ -781,6 +773,10 @@ _GEN_FLOAT_ACB(name##s, 0x3B, op2);
781 773 #define _GEN_FLOAT_AB(name, op1, op2, inval) \
782 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 780 gen_op_reset_scrfx(); \
785 781 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
786 782 gen_op_load_fpr_FT1(rB(ctx->opcode)); \
... ... @@ -796,6 +792,10 @@ _GEN_FLOAT_AB(name##s, 0x3B, op2, inval);
796 792 #define _GEN_FLOAT_AC(name, op1, op2, inval) \
797 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 799 gen_op_reset_scrfx(); \
800 800 gen_op_load_fpr_FT0(rA(ctx->opcode)); \
801 801 gen_op_load_fpr_FT1(rC(ctx->opcode)); \
... ... @@ -811,6 +811,10 @@ _GEN_FLOAT_AC(name##s, 0x3B, op2, inval);
811 811 #define GEN_FLOAT_B(name, op2, op3) \
812 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 818 gen_op_reset_scrfx(); \
815 819 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
816 820 gen_op_f##name(); \
... ... @@ -822,6 +826,10 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, PPC_FLOAT) \
822 826 #define GEN_FLOAT_BS(name, op2) \
823 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 833 gen_op_reset_scrfx(); \
826 834 gen_op_load_fpr_FT0(rB(ctx->opcode)); \
827 835 gen_op_f##name(); \
... ... @@ -853,6 +861,10 @@ GEN_FLOAT_BS(sqrt, 0x16);
853 861  
854 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 868 gen_op_reset_scrfx();
857 869 gen_op_load_fpr_FT0(rB(ctx->opcode));
858 870 gen_op_fsqrts();
... ... @@ -883,6 +895,10 @@ GEN_FLOAT_B(rsp, 0x0C, 0x00);
883 895 /* fcmpo */
884 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 902 gen_op_reset_scrfx();
887 903 gen_op_load_fpr_FT0(rA(ctx->opcode));
888 904 gen_op_load_fpr_FT1(rB(ctx->opcode));
... ... @@ -893,6 +909,10 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
893 909 /* fcmpu */
894 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 916 gen_op_reset_scrfx();
897 917 gen_op_load_fpr_FT0(rA(ctx->opcode));
898 918 gen_op_load_fpr_FT1(rB(ctx->opcode));
... ... @@ -907,6 +927,10 @@ GEN_FLOAT_B(abs, 0x08, 0x08);
907 927 /* fmr - fmr. */
908 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 934 gen_op_reset_scrfx();
911 935 gen_op_load_fpr_FT0(rB(ctx->opcode));
912 936 gen_op_store_FT0_fpr(rD(ctx->opcode));
... ... @@ -923,6 +947,10 @@ GEN_FLOAT_B(neg, 0x08, 0x01);
923 947 /* mcrfs */
924 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 954 gen_op_load_fpscr_T0(crfS(ctx->opcode));
927 955 gen_op_store_T0_crf(crfD(ctx->opcode));
928 956 gen_op_clear_fpscr(crfS(ctx->opcode));
... ... @@ -931,6 +959,10 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
931 959 /* mffs */
932 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 966 gen_op_load_fpscr();
935 967 gen_op_store_FT0_fpr(rD(ctx->opcode));
936 968 if (Rc(ctx->opcode))
... ... @@ -942,6 +974,10 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
942 974 {
943 975 uint8_t crb;
944 976  
  977 + if (!ctx->fpu_enabled) {
  978 + RET_EXCP(ctx, EXCP_NO_FP, 0);
  979 + return;
  980 + }
945 981 crb = crbD(ctx->opcode) >> 2;
946 982 gen_op_load_fpscr_T0(crb);
947 983 gen_op_andi_(~(1 << (crbD(ctx->opcode) & 0x03)));
... ... @@ -955,6 +991,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
955 991 {
956 992 uint8_t crb;
957 993  
  994 + if (!ctx->fpu_enabled) {
  995 + RET_EXCP(ctx, EXCP_NO_FP, 0);
  996 + return;
  997 + }
958 998 crb = crbD(ctx->opcode) >> 2;
959 999 gen_op_load_fpscr_T0(crb);
960 1000 gen_op_ori(1 << (crbD(ctx->opcode) & 0x03));
... ... @@ -966,6 +1006,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
966 1006 /* mtfsf */
967 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 1013 gen_op_load_fpr_FT0(rB(ctx->opcode));
970 1014 gen_op_store_fpscr(FM(ctx->opcode));
971 1015 if (Rc(ctx->opcode))
... ... @@ -975,6 +1019,10 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
975 1019 /* mtfsfi */
976 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 1026 gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
979 1027 if (Rc(ctx->opcode))
980 1028 gen_op_set_Rc1();
... ... @@ -1525,6 +1573,10 @@ GEN_STFS(fs, 0x14);
1525 1573 /* stfiwx */
1526 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 1580 RET_INVAL(ctx);
1529 1581 }
1530 1582  
... ... @@ -2978,10 +3030,6 @@ void cpu_dump_state(CPUState *env, FILE *f,
2978 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 3033 CPUPPCState *cpu_ppc_init(void)
2986 3034 {
2987 3035 CPUPPCState *env;
... ... @@ -2991,14 +3039,10 @@ CPUPPCState *cpu_ppc_init(void)
2991 3039 env = qemu_mallocz(sizeof(CPUPPCState));
2992 3040 if (!env)
2993 3041 return NULL;
2994   -#if !defined(CONFIG_USER_ONLY) && defined (USE_OPEN_FIRMWARE)
2995   - setup_machine(env, 0);
2996   -#else
2997 3042 // env->spr[PVR] = 0; /* Basic PPC */
2998 3043 env->spr[PVR] = 0x00080100; /* G3 CPU */
2999 3044 // env->spr[PVR] = 0x00083100; /* MPC755 (G3 embedded) */
3000 3045 // env->spr[PVR] = 0x00070100; /* IBM 750FX */
3001   -#endif
3002 3046 tlb_flush(env, 1);
3003 3047 #if defined (DO_SINGLE_STEP)
3004 3048 /* Single step trace mode */
... ... @@ -3053,8 +3097,9 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3053 3097 ctx.mem_idx = 0;
3054 3098 #else
3055 3099 ctx.supervisor = 1 - msr_pr;
3056   - ctx.mem_idx = (1 - msr_pr);
  3100 + ctx.mem_idx = 1 - msr_pr;
3057 3101 #endif
  3102 + ctx.fpu_enabled = msr_fp;
3058 3103 #if defined (DO_SINGLE_STEP)
3059 3104 /* Single step trace mode */
3060 3105 msr_se = 1;
... ...