Revision 3cc62370 target-ppc/translate.c
b/target-ppc/translate.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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; |
Also available in: Unified diff