Revision e06fcd75 target-ppc/translate.c
b/target-ppc/translate.c | ||
---|---|---|
264 | 264 |
tcg_gen_movi_tl(cpu_nip, (uint32_t)nip); |
265 | 265 |
} |
266 | 266 |
|
267 |
#define GEN_EXCP(ctx, excp, error) \ |
|
268 |
do { \ |
|
269 |
TCGv_i32 t0 = tcg_const_i32(excp); \ |
|
270 |
TCGv_i32 t1 = tcg_const_i32(error); \ |
|
271 |
if ((ctx)->exception == POWERPC_EXCP_NONE) { \ |
|
272 |
gen_update_nip(ctx, (ctx)->nip); \ |
|
273 |
} \ |
|
274 |
gen_helper_raise_exception_err(t0, t1); \ |
|
275 |
tcg_temp_free_i32(t0); \ |
|
276 |
tcg_temp_free_i32(t1); \ |
|
277 |
ctx->exception = (excp); \ |
|
278 |
} while (0) |
|
279 |
|
|
280 |
#define GEN_EXCP_INVAL(ctx) \ |
|
281 |
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \ |
|
282 |
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL) |
|
283 |
|
|
284 |
#define GEN_EXCP_PRIVOPC(ctx) \ |
|
285 |
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \ |
|
286 |
POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC) |
|
287 |
|
|
288 |
#define GEN_EXCP_PRIVREG(ctx) \ |
|
289 |
GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \ |
|
290 |
POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG) |
|
267 |
static always_inline void gen_exception_err (DisasContext *ctx, uint32_t excp, uint32_t error) |
|
268 |
{ |
|
269 |
TCGv_i32 t0, t1; |
|
270 |
if (ctx->exception == POWERPC_EXCP_NONE) { |
|
271 |
gen_update_nip(ctx, ctx->nip); |
|
272 |
} |
|
273 |
t0 = tcg_const_i32(excp); |
|
274 |
t1 = tcg_const_i32(error); |
|
275 |
gen_helper_raise_exception_err(t0, t1); |
|
276 |
tcg_temp_free_i32(t0); |
|
277 |
tcg_temp_free_i32(t1); |
|
278 |
ctx->exception = (excp); |
|
279 |
} |
|
291 | 280 |
|
292 |
#define GEN_EXCP_NO_FP(ctx) \ |
|
293 |
GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0) |
|
281 |
static always_inline void gen_exception (DisasContext *ctx, uint32_t excp) |
|
282 |
{ |
|
283 |
TCGv_i32 t0; |
|
284 |
if (ctx->exception == POWERPC_EXCP_NONE) { |
|
285 |
gen_update_nip(ctx, ctx->nip); |
|
286 |
} |
|
287 |
t0 = tcg_const_i32(excp); |
|
288 |
gen_helper_raise_exception(t0); |
|
289 |
tcg_temp_free_i32(t0); |
|
290 |
ctx->exception = (excp); |
|
291 |
} |
|
294 | 292 |
|
295 |
#define GEN_EXCP_NO_AP(ctx) \ |
|
296 |
GEN_EXCP(ctx, POWERPC_EXCP_APU, 0) |
|
293 |
static always_inline void gen_debug_exception (DisasContext *ctx) |
|
294 |
{ |
|
295 |
TCGv_i32 t0; |
|
296 |
gen_update_nip(ctx, ctx->nip); |
|
297 |
t0 = tcg_const_i32(EXCP_DEBUG); |
|
298 |
gen_helper_raise_exception(t0); |
|
299 |
tcg_temp_free_i32(t0); |
|
300 |
} |
|
297 | 301 |
|
298 |
#define GEN_EXCP_NO_VR(ctx) \ |
|
299 |
GEN_EXCP(ctx, POWERPC_EXCP_VPU, 0) |
|
302 |
static always_inline void gen_inval_exception (DisasContext *ctx, uint32_t error) |
|
303 |
{ |
|
304 |
gen_exception_err(ctx, POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | error); |
|
305 |
} |
|
300 | 306 |
|
301 | 307 |
/* Stop translation */ |
302 |
static always_inline void GEN_STOP (DisasContext *ctx)
|
|
308 |
static always_inline void gen_stop_exception (DisasContext *ctx)
|
|
303 | 309 |
{ |
304 | 310 |
gen_update_nip(ctx, ctx->nip); |
305 | 311 |
ctx->exception = POWERPC_EXCP_STOP; |
306 | 312 |
} |
307 | 313 |
|
308 | 314 |
/* No need to update nip here, as execution flow will change */ |
309 |
static always_inline void GEN_SYNC (DisasContext *ctx)
|
|
315 |
static always_inline void gen_sync_exception (DisasContext *ctx)
|
|
310 | 316 |
{ |
311 | 317 |
ctx->exception = POWERPC_EXCP_SYNC; |
312 | 318 |
} |
... | ... | |
689 | 695 |
/* Invalid instruction */ |
690 | 696 |
GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE) |
691 | 697 |
{ |
692 |
GEN_EXCP_INVAL(ctx);
|
|
698 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
693 | 699 |
} |
694 | 700 |
|
695 | 701 |
static opc_handler_t invalid_handler = { |
... | ... | |
2083 | 2089 |
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \ |
2084 | 2090 |
{ \ |
2085 | 2091 |
if (unlikely(!ctx->fpu_enabled)) { \ |
2086 |
GEN_EXCP_NO_FP(ctx); \
|
|
2092 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
2087 | 2093 |
return; \ |
2088 | 2094 |
} \ |
2089 | 2095 |
gen_reset_fpstatus(); \ |
... | ... | |
2104 | 2110 |
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \ |
2105 | 2111 |
{ \ |
2106 | 2112 |
if (unlikely(!ctx->fpu_enabled)) { \ |
2107 |
GEN_EXCP_NO_FP(ctx); \
|
|
2113 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
2108 | 2114 |
return; \ |
2109 | 2115 |
} \ |
2110 | 2116 |
gen_reset_fpstatus(); \ |
... | ... | |
2124 | 2130 |
GEN_HANDLER(f##name, op1, op2, 0xFF, inval, type) \ |
2125 | 2131 |
{ \ |
2126 | 2132 |
if (unlikely(!ctx->fpu_enabled)) { \ |
2127 |
GEN_EXCP_NO_FP(ctx); \
|
|
2133 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
2128 | 2134 |
return; \ |
2129 | 2135 |
} \ |
2130 | 2136 |
gen_reset_fpstatus(); \ |
... | ... | |
2144 | 2150 |
GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \ |
2145 | 2151 |
{ \ |
2146 | 2152 |
if (unlikely(!ctx->fpu_enabled)) { \ |
2147 |
GEN_EXCP_NO_FP(ctx); \
|
|
2153 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
2148 | 2154 |
return; \ |
2149 | 2155 |
} \ |
2150 | 2156 |
gen_reset_fpstatus(); \ |
... | ... | |
2157 | 2163 |
GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type) \ |
2158 | 2164 |
{ \ |
2159 | 2165 |
if (unlikely(!ctx->fpu_enabled)) { \ |
2160 |
GEN_EXCP_NO_FP(ctx); \
|
|
2166 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
2161 | 2167 |
return; \ |
2162 | 2168 |
} \ |
2163 | 2169 |
gen_reset_fpstatus(); \ |
... | ... | |
2186 | 2192 |
GEN_HANDLER(frsqrtes, 0x3B, 0x1A, 0xFF, 0x001F07C0, PPC_FLOAT_FRSQRTES) |
2187 | 2193 |
{ |
2188 | 2194 |
if (unlikely(!ctx->fpu_enabled)) { |
2189 |
GEN_EXCP_NO_FP(ctx);
|
|
2195 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2190 | 2196 |
return; |
2191 | 2197 |
} |
2192 | 2198 |
gen_reset_fpstatus(); |
... | ... | |
2204 | 2210 |
GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT) |
2205 | 2211 |
{ |
2206 | 2212 |
if (unlikely(!ctx->fpu_enabled)) { |
2207 |
GEN_EXCP_NO_FP(ctx);
|
|
2213 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2208 | 2214 |
return; |
2209 | 2215 |
} |
2210 | 2216 |
gen_reset_fpstatus(); |
... | ... | |
2215 | 2221 |
GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT) |
2216 | 2222 |
{ |
2217 | 2223 |
if (unlikely(!ctx->fpu_enabled)) { |
2218 |
GEN_EXCP_NO_FP(ctx);
|
|
2224 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2219 | 2225 |
return; |
2220 | 2226 |
} |
2221 | 2227 |
gen_reset_fpstatus(); |
... | ... | |
2264 | 2270 |
GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) |
2265 | 2271 |
{ |
2266 | 2272 |
if (unlikely(!ctx->fpu_enabled)) { |
2267 |
GEN_EXCP_NO_FP(ctx);
|
|
2273 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2268 | 2274 |
return; |
2269 | 2275 |
} |
2270 | 2276 |
gen_reset_fpstatus(); |
... | ... | |
2277 | 2283 |
GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) |
2278 | 2284 |
{ |
2279 | 2285 |
if (unlikely(!ctx->fpu_enabled)) { |
2280 |
GEN_EXCP_NO_FP(ctx);
|
|
2286 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2281 | 2287 |
return; |
2282 | 2288 |
} |
2283 | 2289 |
gen_reset_fpstatus(); |
... | ... | |
2296 | 2302 |
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT) |
2297 | 2303 |
{ |
2298 | 2304 |
if (unlikely(!ctx->fpu_enabled)) { |
2299 |
GEN_EXCP_NO_FP(ctx);
|
|
2305 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2300 | 2306 |
return; |
2301 | 2307 |
} |
2302 | 2308 |
tcg_gen_mov_i64(cpu_fpr[rD(ctx->opcode)], cpu_fpr[rB(ctx->opcode)]); |
... | ... | |
2317 | 2323 |
int bfa; |
2318 | 2324 |
|
2319 | 2325 |
if (unlikely(!ctx->fpu_enabled)) { |
2320 |
GEN_EXCP_NO_FP(ctx);
|
|
2326 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2321 | 2327 |
return; |
2322 | 2328 |
} |
2323 | 2329 |
gen_optimize_fprf(); |
... | ... | |
2331 | 2337 |
GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) |
2332 | 2338 |
{ |
2333 | 2339 |
if (unlikely(!ctx->fpu_enabled)) { |
2334 |
GEN_EXCP_NO_FP(ctx);
|
|
2340 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2335 | 2341 |
return; |
2336 | 2342 |
} |
2337 | 2343 |
gen_optimize_fprf(); |
... | ... | |
2346 | 2352 |
uint8_t crb; |
2347 | 2353 |
|
2348 | 2354 |
if (unlikely(!ctx->fpu_enabled)) { |
2349 |
GEN_EXCP_NO_FP(ctx);
|
|
2355 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2350 | 2356 |
return; |
2351 | 2357 |
} |
2352 | 2358 |
crb = 32 - (crbD(ctx->opcode) >> 2); |
... | ... | |
2365 | 2371 |
uint8_t crb; |
2366 | 2372 |
|
2367 | 2373 |
if (unlikely(!ctx->fpu_enabled)) { |
2368 |
GEN_EXCP_NO_FP(ctx);
|
|
2374 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2369 | 2375 |
return; |
2370 | 2376 |
} |
2371 | 2377 |
crb = 32 - (crbD(ctx->opcode) >> 2); |
... | ... | |
2390 | 2396 |
TCGv_i32 t0; |
2391 | 2397 |
|
2392 | 2398 |
if (unlikely(!ctx->fpu_enabled)) { |
2393 |
GEN_EXCP_NO_FP(ctx);
|
|
2399 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2394 | 2400 |
return; |
2395 | 2401 |
} |
2396 | 2402 |
gen_optimize_fprf(); |
... | ... | |
2413 | 2419 |
TCGv_i32 t1; |
2414 | 2420 |
|
2415 | 2421 |
if (unlikely(!ctx->fpu_enabled)) { |
2416 |
GEN_EXCP_NO_FP(ctx);
|
|
2422 |
gen_exception(ctx, POWERPC_EXCP_FPU);
|
|
2417 | 2423 |
return; |
2418 | 2424 |
} |
2419 | 2425 |
bf = crbD(ctx->opcode) >> 2; |
... | ... | |
2698 | 2704 |
TCGv EA; \ |
2699 | 2705 |
if (unlikely(rA(ctx->opcode) == 0 || \ |
2700 | 2706 |
rA(ctx->opcode) == rD(ctx->opcode))) { \ |
2701 |
GEN_EXCP_INVAL(ctx); \
|
|
2707 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
|
2702 | 2708 |
return; \ |
2703 | 2709 |
} \ |
2704 | 2710 |
gen_set_access_type(ctx, ACCESS_INT); \ |
... | ... | |
2718 | 2724 |
TCGv EA; \ |
2719 | 2725 |
if (unlikely(rA(ctx->opcode) == 0 || \ |
2720 | 2726 |
rA(ctx->opcode) == rD(ctx->opcode))) { \ |
2721 |
GEN_EXCP_INVAL(ctx); \
|
|
2727 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
|
2722 | 2728 |
return; \ |
2723 | 2729 |
} \ |
2724 | 2730 |
gen_set_access_type(ctx, ACCESS_INT); \ |
... | ... | |
2769 | 2775 |
if (Rc(ctx->opcode)) { |
2770 | 2776 |
if (unlikely(rA(ctx->opcode) == 0 || |
2771 | 2777 |
rA(ctx->opcode) == rD(ctx->opcode))) { |
2772 |
GEN_EXCP_INVAL(ctx);
|
|
2778 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
2773 | 2779 |
return; |
2774 | 2780 |
} |
2775 | 2781 |
} |
... | ... | |
2791 | 2797 |
GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX) |
2792 | 2798 |
{ |
2793 | 2799 |
#if defined(CONFIG_USER_ONLY) |
2794 |
GEN_EXCP_PRIVOPC(ctx);
|
|
2800 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
2795 | 2801 |
#else |
2796 | 2802 |
int ra, rd; |
2797 | 2803 |
TCGv EA; |
2798 | 2804 |
|
2799 | 2805 |
/* Restore CPU state */ |
2800 | 2806 |
if (unlikely(ctx->mem_idx == 0)) { |
2801 |
GEN_EXCP_PRIVOPC(ctx);
|
|
2807 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
2802 | 2808 |
return; |
2803 | 2809 |
} |
2804 | 2810 |
ra = rA(ctx->opcode); |
2805 | 2811 |
rd = rD(ctx->opcode); |
2806 | 2812 |
if (unlikely((rd & 1) || rd == ra)) { |
2807 |
GEN_EXCP_INVAL(ctx);
|
|
2813 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
2808 | 2814 |
return; |
2809 | 2815 |
} |
2810 | 2816 |
if (unlikely(ctx->le_mode)) { |
2811 | 2817 |
/* Little-endian mode is not handled */ |
2812 |
GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
|
|
2818 |
gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
|
|
2813 | 2819 |
return; |
2814 | 2820 |
} |
2815 | 2821 |
gen_set_access_type(ctx, ACCESS_INT); |
... | ... | |
2840 | 2846 |
{ \ |
2841 | 2847 |
TCGv EA; \ |
2842 | 2848 |
if (unlikely(rA(ctx->opcode) == 0)) { \ |
2843 |
GEN_EXCP_INVAL(ctx); \
|
|
2849 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
|
2844 | 2850 |
return; \ |
2845 | 2851 |
} \ |
2846 | 2852 |
gen_set_access_type(ctx, ACCESS_INT); \ |
... | ... | |
2859 | 2865 |
{ \ |
2860 | 2866 |
TCGv EA; \ |
2861 | 2867 |
if (unlikely(rA(ctx->opcode) == 0)) { \ |
2862 |
GEN_EXCP_INVAL(ctx); \
|
|
2868 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
|
2863 | 2869 |
return; \ |
2864 | 2870 |
} \ |
2865 | 2871 |
gen_set_access_type(ctx, ACCESS_INT); \ |
... | ... | |
2904 | 2910 |
rs = rS(ctx->opcode); |
2905 | 2911 |
if ((ctx->opcode & 0x3) == 0x2) { |
2906 | 2912 |
#if defined(CONFIG_USER_ONLY) |
2907 |
GEN_EXCP_PRIVOPC(ctx);
|
|
2913 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
2908 | 2914 |
#else |
2909 | 2915 |
/* stq */ |
2910 | 2916 |
if (unlikely(ctx->mem_idx == 0)) { |
2911 |
GEN_EXCP_PRIVOPC(ctx);
|
|
2917 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
2912 | 2918 |
return; |
2913 | 2919 |
} |
2914 | 2920 |
if (unlikely(rs & 1)) { |
2915 |
GEN_EXCP_INVAL(ctx);
|
|
2921 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
2916 | 2922 |
return; |
2917 | 2923 |
} |
2918 | 2924 |
if (unlikely(ctx->le_mode)) { |
2919 | 2925 |
/* Little-endian mode is not handled */ |
2920 |
GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
|
|
2926 |
gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
|
|
2921 | 2927 |
return; |
2922 | 2928 |
} |
2923 | 2929 |
gen_set_access_type(ctx, ACCESS_INT); |
... | ... | |
2932 | 2938 |
/* std / stdu */ |
2933 | 2939 |
if (Rc(ctx->opcode)) { |
2934 | 2940 |
if (unlikely(rA(ctx->opcode) == 0)) { |
2935 |
GEN_EXCP_INVAL(ctx);
|
|
2941 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
2936 | 2942 |
return; |
2937 | 2943 |
} |
2938 | 2944 |
} |
... | ... | |
3094 | 3100 |
if (unlikely(((start + nr) > 32 && |
3095 | 3101 |
start <= ra && (start + nr - 32) > ra) || |
3096 | 3102 |
((start + nr) <= 32 && start <= ra && (start + nr) > ra))) { |
3097 |
GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM, |
|
3098 |
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX); |
|
3103 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_LSWX); |
|
3099 | 3104 |
return; |
3100 | 3105 |
} |
3101 | 3106 |
gen_set_access_type(ctx, ACCESS_INT); |
... | ... | |
3181 | 3186 |
/* isync */ |
3182 | 3187 |
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM) |
3183 | 3188 |
{ |
3184 |
GEN_STOP(ctx);
|
|
3189 |
gen_stop_exception(ctx);
|
|
3185 | 3190 |
} |
3186 | 3191 |
|
3187 | 3192 |
/* lwarx */ |
... | ... | |
3266 | 3271 |
tcg_gen_st_i32(t0, cpu_env, offsetof(CPUState, halted)); |
3267 | 3272 |
tcg_temp_free_i32(t0); |
3268 | 3273 |
/* Stop translation, as the CPU is supposed to sleep from now */ |
3269 |
GEN_EXCP(ctx, EXCP_HLT, 1);
|
|
3274 |
gen_exception_err(ctx, EXCP_HLT, 1);
|
|
3270 | 3275 |
} |
3271 | 3276 |
|
3272 | 3277 |
/*** Floating-point load ***/ |
... | ... | |
3275 | 3280 |
{ \ |
3276 | 3281 |
TCGv EA; \ |
3277 | 3282 |
if (unlikely(!ctx->fpu_enabled)) { \ |
3278 |
GEN_EXCP_NO_FP(ctx); \
|
|
3283 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
3279 | 3284 |
return; \ |
3280 | 3285 |
} \ |
3281 | 3286 |
gen_set_access_type(ctx, ACCESS_FLOAT); \ |
... | ... | |
3290 | 3295 |
{ \ |
3291 | 3296 |
TCGv EA; \ |
3292 | 3297 |
if (unlikely(!ctx->fpu_enabled)) { \ |
3293 |
GEN_EXCP_NO_FP(ctx); \
|
|
3298 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
3294 | 3299 |
return; \ |
3295 | 3300 |
} \ |
3296 | 3301 |
if (unlikely(rA(ctx->opcode) == 0)) { \ |
3297 |
GEN_EXCP_INVAL(ctx); \
|
|
3302 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
|
3298 | 3303 |
return; \ |
3299 | 3304 |
} \ |
3300 | 3305 |
gen_set_access_type(ctx, ACCESS_FLOAT); \ |
... | ... | |
3310 | 3315 |
{ \ |
3311 | 3316 |
TCGv EA; \ |
3312 | 3317 |
if (unlikely(!ctx->fpu_enabled)) { \ |
3313 |
GEN_EXCP_NO_FP(ctx); \
|
|
3318 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
3314 | 3319 |
return; \ |
3315 | 3320 |
} \ |
3316 | 3321 |
if (unlikely(rA(ctx->opcode) == 0)) { \ |
3317 |
GEN_EXCP_INVAL(ctx); \
|
|
3322 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
|
3318 | 3323 |
return; \ |
3319 | 3324 |
} \ |
3320 | 3325 |
gen_set_access_type(ctx, ACCESS_FLOAT); \ |
... | ... | |
3330 | 3335 |
{ \ |
3331 | 3336 |
TCGv EA; \ |
3332 | 3337 |
if (unlikely(!ctx->fpu_enabled)) { \ |
3333 |
GEN_EXCP_NO_FP(ctx); \
|
|
3338 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
3334 | 3339 |
return; \ |
3335 | 3340 |
} \ |
3336 | 3341 |
gen_set_access_type(ctx, ACCESS_FLOAT); \ |
... | ... | |
3368 | 3373 |
{ \ |
3369 | 3374 |
TCGv EA; \ |
3370 | 3375 |
if (unlikely(!ctx->fpu_enabled)) { \ |
3371 |
GEN_EXCP_NO_FP(ctx); \
|
|
3376 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
3372 | 3377 |
return; \ |
3373 | 3378 |
} \ |
3374 | 3379 |
gen_set_access_type(ctx, ACCESS_FLOAT); \ |
... | ... | |
3383 | 3388 |
{ \ |
3384 | 3389 |
TCGv EA; \ |
3385 | 3390 |
if (unlikely(!ctx->fpu_enabled)) { \ |
3386 |
GEN_EXCP_NO_FP(ctx); \
|
|
3391 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
3387 | 3392 |
return; \ |
3388 | 3393 |
} \ |
3389 | 3394 |
if (unlikely(rA(ctx->opcode) == 0)) { \ |
3390 |
GEN_EXCP_INVAL(ctx); \
|
|
3395 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
|
3391 | 3396 |
return; \ |
3392 | 3397 |
} \ |
3393 | 3398 |
gen_set_access_type(ctx, ACCESS_FLOAT); \ |
... | ... | |
3403 | 3408 |
{ \ |
3404 | 3409 |
TCGv EA; \ |
3405 | 3410 |
if (unlikely(!ctx->fpu_enabled)) { \ |
3406 |
GEN_EXCP_NO_FP(ctx); \
|
|
3411 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
3407 | 3412 |
return; \ |
3408 | 3413 |
} \ |
3409 | 3414 |
if (unlikely(rA(ctx->opcode) == 0)) { \ |
3410 |
GEN_EXCP_INVAL(ctx); \
|
|
3415 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
|
3411 | 3416 |
return; \ |
3412 | 3417 |
} \ |
3413 | 3418 |
gen_set_access_type(ctx, ACCESS_FLOAT); \ |
... | ... | |
3423 | 3428 |
{ \ |
3424 | 3429 |
TCGv EA; \ |
3425 | 3430 |
if (unlikely(!ctx->fpu_enabled)) { \ |
3426 |
GEN_EXCP_NO_FP(ctx); \
|
|
3431 |
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
|
3427 | 3432 |
return; \ |
3428 | 3433 |
} \ |
3429 | 3434 |
gen_set_access_type(ctx, ACCESS_FLOAT); \ |
... | ... | |
3489 | 3494 |
ctx->exception == POWERPC_EXCP_BRANCH) { |
3490 | 3495 |
target_ulong tmp = ctx->nip; |
3491 | 3496 |
ctx->nip = dest; |
3492 |
GEN_EXCP(ctx, POWERPC_EXCP_TRACE, 0);
|
|
3497 |
gen_exception(ctx, POWERPC_EXCP_TRACE);
|
|
3493 | 3498 |
ctx->nip = tmp; |
3494 | 3499 |
} |
3495 | 3500 |
if (ctx->singlestep_enabled & GDBSTUB_SINGLE_STEP) { |
3496 |
gen_update_nip(ctx, dest); |
|
3497 |
gen_helper_raise_debug(); |
|
3501 |
gen_debug_exception(ctx); |
|
3498 | 3502 |
} |
3499 | 3503 |
} |
3500 | 3504 |
tcg_gen_exit_tb(0); |
... | ... | |
3558 | 3562 |
/* Decrement and test CTR */ |
3559 | 3563 |
TCGv temp = tcg_temp_new(); |
3560 | 3564 |
if (unlikely(type == BCOND_CTR)) { |
3561 |
GEN_EXCP_INVAL(ctx);
|
|
3565 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
3562 | 3566 |
return; |
3563 | 3567 |
} |
3564 | 3568 |
tcg_gen_subi_tl(cpu_ctr, cpu_ctr, 1); |
... | ... | |
3692 | 3696 |
GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW) |
3693 | 3697 |
{ |
3694 | 3698 |
#if defined(CONFIG_USER_ONLY) |
3695 |
GEN_EXCP_PRIVOPC(ctx);
|
|
3699 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
3696 | 3700 |
#else |
3697 | 3701 |
/* Restore CPU state */ |
3698 | 3702 |
if (unlikely(!ctx->mem_idx)) { |
3699 |
GEN_EXCP_PRIVOPC(ctx);
|
|
3703 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
3700 | 3704 |
return; |
3701 | 3705 |
} |
3702 | 3706 |
gen_helper_rfi(); |
3703 |
GEN_SYNC(ctx);
|
|
3707 |
gen_sync_exception(ctx);
|
|
3704 | 3708 |
#endif |
3705 | 3709 |
} |
3706 | 3710 |
|
... | ... | |
3708 | 3712 |
GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B) |
3709 | 3713 |
{ |
3710 | 3714 |
#if defined(CONFIG_USER_ONLY) |
3711 |
GEN_EXCP_PRIVOPC(ctx);
|
|
3715 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
3712 | 3716 |
#else |
3713 | 3717 |
/* Restore CPU state */ |
3714 | 3718 |
if (unlikely(!ctx->mem_idx)) { |
3715 |
GEN_EXCP_PRIVOPC(ctx);
|
|
3719 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
3716 | 3720 |
return; |
3717 | 3721 |
} |
3718 | 3722 |
gen_helper_rfid(); |
3719 |
GEN_SYNC(ctx);
|
|
3723 |
gen_sync_exception(ctx);
|
|
3720 | 3724 |
#endif |
3721 | 3725 |
} |
3722 | 3726 |
|
3723 | 3727 |
GEN_HANDLER(hrfid, 0x13, 0x12, 0x08, 0x03FF8001, PPC_64H) |
3724 | 3728 |
{ |
3725 | 3729 |
#if defined(CONFIG_USER_ONLY) |
3726 |
GEN_EXCP_PRIVOPC(ctx);
|
|
3730 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
3727 | 3731 |
#else |
3728 | 3732 |
/* Restore CPU state */ |
3729 | 3733 |
if (unlikely(ctx->mem_idx <= 1)) { |
3730 |
GEN_EXCP_PRIVOPC(ctx);
|
|
3734 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
3731 | 3735 |
return; |
3732 | 3736 |
} |
3733 | 3737 |
gen_helper_hrfid(); |
3734 |
GEN_SYNC(ctx);
|
|
3738 |
gen_sync_exception(ctx);
|
|
3735 | 3739 |
#endif |
3736 | 3740 |
} |
3737 | 3741 |
#endif |
... | ... | |
3747 | 3751 |
uint32_t lev; |
3748 | 3752 |
|
3749 | 3753 |
lev = (ctx->opcode >> 5) & 0x7F; |
3750 |
GEN_EXCP(ctx, POWERPC_SYSCALL, lev);
|
|
3754 |
gen_exception_err(ctx, POWERPC_SYSCALL, lev);
|
|
3751 | 3755 |
} |
3752 | 3756 |
|
3753 | 3757 |
/*** Trap ***/ |
... | ... | |
3826 | 3830 |
GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC) |
3827 | 3831 |
{ |
3828 | 3832 |
#if defined(CONFIG_USER_ONLY) |
3829 |
GEN_EXCP_PRIVREG(ctx);
|
|
3833 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
3830 | 3834 |
#else |
3831 | 3835 |
if (unlikely(!ctx->mem_idx)) { |
3832 |
GEN_EXCP_PRIVREG(ctx);
|
|
3836 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
3833 | 3837 |
return; |
3834 | 3838 |
} |
3835 | 3839 |
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_msr); |
... | ... | |
3878 | 3882 |
printf("Trying to read privileged spr %d %03x at " ADDRX "\n", |
3879 | 3883 |
sprn, sprn, ctx->nip); |
3880 | 3884 |
} |
3881 |
GEN_EXCP_PRIVREG(ctx);
|
|
3885 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
3882 | 3886 |
} |
3883 | 3887 |
} else { |
3884 | 3888 |
/* Not defined */ |
... | ... | |
3888 | 3892 |
} |
3889 | 3893 |
printf("Trying to read invalid spr %d %03x at " ADDRX "\n", |
3890 | 3894 |
sprn, sprn, ctx->nip); |
3891 |
GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM, |
|
3892 |
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR); |
|
3895 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR); |
|
3893 | 3896 |
} |
3894 | 3897 |
} |
3895 | 3898 |
|
... | ... | |
3929 | 3932 |
GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001EF801, PPC_64B) |
3930 | 3933 |
{ |
3931 | 3934 |
#if defined(CONFIG_USER_ONLY) |
3932 |
GEN_EXCP_PRIVREG(ctx);
|
|
3935 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
3933 | 3936 |
#else |
3934 | 3937 |
if (unlikely(!ctx->mem_idx)) { |
3935 |
GEN_EXCP_PRIVREG(ctx);
|
|
3938 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
3936 | 3939 |
return; |
3937 | 3940 |
} |
3938 | 3941 |
if (ctx->opcode & 0x00010000) { |
... | ... | |
3951 | 3954 |
gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); |
3952 | 3955 |
/* Must stop the translation as machine state (may have) changed */ |
3953 | 3956 |
/* Note that mtmsr is not always defined as context-synchronizing */ |
3954 |
ctx->exception = POWERPC_EXCP_STOP;
|
|
3957 |
gen_stop_exception(ctx);
|
|
3955 | 3958 |
} |
3956 | 3959 |
#endif |
3957 | 3960 |
} |
... | ... | |
3960 | 3963 |
GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) |
3961 | 3964 |
{ |
3962 | 3965 |
#if defined(CONFIG_USER_ONLY) |
3963 |
GEN_EXCP_PRIVREG(ctx);
|
|
3966 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
3964 | 3967 |
#else |
3965 | 3968 |
if (unlikely(!ctx->mem_idx)) { |
3966 |
GEN_EXCP_PRIVREG(ctx);
|
|
3969 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
3967 | 3970 |
return; |
3968 | 3971 |
} |
3969 | 3972 |
if (ctx->opcode & 0x00010000) { |
... | ... | |
3994 | 3997 |
gen_helper_store_msr(cpu_gpr[rS(ctx->opcode)]); |
3995 | 3998 |
/* Must stop the translation as machine state (may have) changed */ |
3996 | 3999 |
/* Note that mtmsr is not always defined as context-synchronizing */ |
3997 |
ctx->exception = POWERPC_EXCP_STOP;
|
|
4000 |
gen_stop_exception(ctx);
|
|
3998 | 4001 |
} |
3999 | 4002 |
#endif |
4000 | 4003 |
} |
... | ... | |
4024 | 4027 |
} |
4025 | 4028 |
printf("Trying to write privileged spr %d %03x at " ADDRX "\n", |
4026 | 4029 |
sprn, sprn, ctx->nip); |
4027 |
GEN_EXCP_PRIVREG(ctx);
|
|
4030 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4028 | 4031 |
} |
4029 | 4032 |
} else { |
4030 | 4033 |
/* Not defined */ |
... | ... | |
4034 | 4037 |
} |
4035 | 4038 |
printf("Trying to write invalid spr %d %03x at " ADDRX "\n", |
4036 | 4039 |
sprn, sprn, ctx->nip); |
4037 |
GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM, |
|
4038 |
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR); |
|
4040 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_SPR); |
|
4039 | 4041 |
} |
4040 | 4042 |
} |
4041 | 4043 |
|
... | ... | |
4056 | 4058 |
GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE) |
4057 | 4059 |
{ |
4058 | 4060 |
#if defined(CONFIG_USER_ONLY) |
4059 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4061 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4060 | 4062 |
#else |
4061 | 4063 |
TCGv EA, val; |
4062 | 4064 |
if (unlikely(!ctx->mem_idx)) { |
4063 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4065 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4064 | 4066 |
return; |
4065 | 4067 |
} |
4066 | 4068 |
EA = tcg_temp_new(); |
... | ... | |
4162 | 4164 |
GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT) |
4163 | 4165 |
{ |
4164 | 4166 |
#if defined(CONFIG_USER_ONLY) |
4165 |
GEN_EXCP_PRIVREG(ctx);
|
|
4167 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4166 | 4168 |
#else |
4167 | 4169 |
TCGv t0; |
4168 | 4170 |
if (unlikely(!ctx->mem_idx)) { |
4169 |
GEN_EXCP_PRIVREG(ctx);
|
|
4171 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4170 | 4172 |
return; |
4171 | 4173 |
} |
4172 | 4174 |
t0 = tcg_const_tl(SR(ctx->opcode)); |
... | ... | |
4179 | 4181 |
GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT) |
4180 | 4182 |
{ |
4181 | 4183 |
#if defined(CONFIG_USER_ONLY) |
4182 |
GEN_EXCP_PRIVREG(ctx);
|
|
4184 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4183 | 4185 |
#else |
4184 | 4186 |
TCGv t0; |
4185 | 4187 |
if (unlikely(!ctx->mem_idx)) { |
4186 |
GEN_EXCP_PRIVREG(ctx);
|
|
4188 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4187 | 4189 |
return; |
4188 | 4190 |
} |
4189 | 4191 |
t0 = tcg_temp_new(); |
... | ... | |
4198 | 4200 |
GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT) |
4199 | 4201 |
{ |
4200 | 4202 |
#if defined(CONFIG_USER_ONLY) |
4201 |
GEN_EXCP_PRIVREG(ctx);
|
|
4203 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4202 | 4204 |
#else |
4203 | 4205 |
TCGv t0; |
4204 | 4206 |
if (unlikely(!ctx->mem_idx)) { |
4205 |
GEN_EXCP_PRIVREG(ctx);
|
|
4207 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4206 | 4208 |
return; |
4207 | 4209 |
} |
4208 | 4210 |
t0 = tcg_const_tl(SR(ctx->opcode)); |
... | ... | |
4215 | 4217 |
GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) |
4216 | 4218 |
{ |
4217 | 4219 |
#if defined(CONFIG_USER_ONLY) |
4218 |
GEN_EXCP_PRIVREG(ctx);
|
|
4220 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4219 | 4221 |
#else |
4220 | 4222 |
TCGv t0; |
4221 | 4223 |
if (unlikely(!ctx->mem_idx)) { |
4222 |
GEN_EXCP_PRIVREG(ctx);
|
|
4224 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4223 | 4225 |
return; |
4224 | 4226 |
} |
4225 | 4227 |
t0 = tcg_temp_new(); |
... | ... | |
4236 | 4238 |
GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B) |
4237 | 4239 |
{ |
4238 | 4240 |
#if defined(CONFIG_USER_ONLY) |
4239 |
GEN_EXCP_PRIVREG(ctx);
|
|
4241 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4240 | 4242 |
#else |
4241 | 4243 |
TCGv t0; |
4242 | 4244 |
if (unlikely(!ctx->mem_idx)) { |
4243 |
GEN_EXCP_PRIVREG(ctx);
|
|
4245 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4244 | 4246 |
return; |
4245 | 4247 |
} |
4246 | 4248 |
t0 = tcg_const_tl(SR(ctx->opcode)); |
... | ... | |
4254 | 4256 |
PPC_SEGMENT_64B) |
4255 | 4257 |
{ |
4256 | 4258 |
#if defined(CONFIG_USER_ONLY) |
4257 |
GEN_EXCP_PRIVREG(ctx);
|
|
4259 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4258 | 4260 |
#else |
4259 | 4261 |
TCGv t0; |
4260 | 4262 |
if (unlikely(!ctx->mem_idx)) { |
4261 |
GEN_EXCP_PRIVREG(ctx);
|
|
4263 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4262 | 4264 |
return; |
4263 | 4265 |
} |
4264 | 4266 |
t0 = tcg_temp_new(); |
... | ... | |
4273 | 4275 |
GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B) |
4274 | 4276 |
{ |
4275 | 4277 |
#if defined(CONFIG_USER_ONLY) |
4276 |
GEN_EXCP_PRIVREG(ctx);
|
|
4278 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4277 | 4279 |
#else |
4278 | 4280 |
TCGv t0; |
4279 | 4281 |
if (unlikely(!ctx->mem_idx)) { |
4280 |
GEN_EXCP_PRIVREG(ctx);
|
|
4282 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4281 | 4283 |
return; |
4282 | 4284 |
} |
4283 | 4285 |
t0 = tcg_const_tl(SR(ctx->opcode)); |
... | ... | |
4291 | 4293 |
PPC_SEGMENT_64B) |
4292 | 4294 |
{ |
4293 | 4295 |
#if defined(CONFIG_USER_ONLY) |
4294 |
GEN_EXCP_PRIVREG(ctx);
|
|
4296 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4295 | 4297 |
#else |
4296 | 4298 |
TCGv t0; |
4297 | 4299 |
if (unlikely(!ctx->mem_idx)) { |
4298 |
GEN_EXCP_PRIVREG(ctx);
|
|
4300 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
4299 | 4301 |
return; |
4300 | 4302 |
} |
4301 | 4303 |
t0 = tcg_temp_new(); |
... | ... | |
4313 | 4315 |
GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA) |
4314 | 4316 |
{ |
4315 | 4317 |
#if defined(CONFIG_USER_ONLY) |
4316 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4318 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4317 | 4319 |
#else |
4318 | 4320 |
if (unlikely(!ctx->mem_idx)) { |
4319 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4321 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4320 | 4322 |
return; |
4321 | 4323 |
} |
4322 | 4324 |
gen_helper_tlbia(); |
... | ... | |
4327 | 4329 |
GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE) |
4328 | 4330 |
{ |
4329 | 4331 |
#if defined(CONFIG_USER_ONLY) |
4330 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4332 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4331 | 4333 |
#else |
4332 | 4334 |
if (unlikely(!ctx->mem_idx)) { |
4333 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4335 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4334 | 4336 |
return; |
4335 | 4337 |
} |
4336 | 4338 |
#if defined(TARGET_PPC64) |
... | ... | |
4349 | 4351 |
GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC) |
4350 | 4352 |
{ |
4351 | 4353 |
#if defined(CONFIG_USER_ONLY) |
4352 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4354 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4353 | 4355 |
#else |
4354 | 4356 |
if (unlikely(!ctx->mem_idx)) { |
4355 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4357 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4356 | 4358 |
return; |
4357 | 4359 |
} |
4358 | 4360 |
/* This has no effect: it should ensure that all previous |
4359 | 4361 |
* tlbie have completed |
4360 | 4362 |
*/ |
4361 |
GEN_STOP(ctx);
|
|
4363 |
gen_stop_exception(ctx);
|
|
4362 | 4364 |
#endif |
4363 | 4365 |
} |
4364 | 4366 |
|
... | ... | |
4367 | 4369 |
GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI) |
4368 | 4370 |
{ |
4369 | 4371 |
#if defined(CONFIG_USER_ONLY) |
4370 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4372 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4371 | 4373 |
#else |
4372 | 4374 |
if (unlikely(!ctx->mem_idx)) { |
4373 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4375 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4374 | 4376 |
return; |
4375 | 4377 |
} |
4376 | 4378 |
gen_helper_slbia(); |
... | ... | |
4381 | 4383 |
GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI) |
4382 | 4384 |
{ |
4383 | 4385 |
#if defined(CONFIG_USER_ONLY) |
4384 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4386 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4385 | 4387 |
#else |
4386 | 4388 |
if (unlikely(!ctx->mem_idx)) { |
4387 |
GEN_EXCP_PRIVOPC(ctx);
|
|
4389 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
4388 | 4390 |
return; |
4389 | 4391 |
} |
4390 | 4392 |
gen_helper_slbie(cpu_gpr[rB(ctx->opcode)]); |
... | ... | |
5065 | 5067 |
GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC) |
5066 | 5068 |
{ |
5067 | 5069 |
/* XXX: TODO */ |
5068 |
GEN_EXCP_INVAL(ctx);
|
|
5070 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
5069 | 5071 |
} |
5070 | 5072 |
|
5071 | 5073 |
/* esa */ |
5072 | 5074 |
GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC) |
5073 | 5075 |
{ |
5074 | 5076 |
/* XXX: TODO */ |
5075 |
GEN_EXCP_INVAL(ctx);
|
|
5077 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
5076 | 5078 |
} |
5077 | 5079 |
|
5078 | 5080 |
/* mfrom */ |
5079 | 5081 |
GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC) |
5080 | 5082 |
{ |
5081 | 5083 |
#if defined(CONFIG_USER_ONLY) |
5082 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5084 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5083 | 5085 |
#else |
5084 | 5086 |
if (unlikely(!ctx->mem_idx)) { |
5085 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5087 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5086 | 5088 |
return; |
5087 | 5089 |
} |
5088 | 5090 |
gen_helper_602_mfrom(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); |
... | ... | |
5094 | 5096 |
GEN_HANDLER2(tlbld_6xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB) |
5095 | 5097 |
{ |
5096 | 5098 |
#if defined(CONFIG_USER_ONLY) |
5097 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5099 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5098 | 5100 |
#else |
5099 | 5101 |
if (unlikely(!ctx->mem_idx)) { |
5100 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5102 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5101 | 5103 |
return; |
5102 | 5104 |
} |
5103 | 5105 |
gen_helper_6xx_tlbd(cpu_gpr[rB(ctx->opcode)]); |
... | ... | |
5108 | 5110 |
GEN_HANDLER2(tlbli_6xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB) |
5109 | 5111 |
{ |
5110 | 5112 |
#if defined(CONFIG_USER_ONLY) |
5111 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5113 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5112 | 5114 |
#else |
5113 | 5115 |
if (unlikely(!ctx->mem_idx)) { |
5114 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5116 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5115 | 5117 |
return; |
5116 | 5118 |
} |
5117 | 5119 |
gen_helper_6xx_tlbi(cpu_gpr[rB(ctx->opcode)]); |
... | ... | |
5123 | 5125 |
GEN_HANDLER2(tlbld_74xx, "tlbld", 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_74xx_TLB) |
5124 | 5126 |
{ |
5125 | 5127 |
#if defined(CONFIG_USER_ONLY) |
5126 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5128 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5127 | 5129 |
#else |
5128 | 5130 |
if (unlikely(!ctx->mem_idx)) { |
5129 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5131 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5130 | 5132 |
return; |
5131 | 5133 |
} |
5132 | 5134 |
gen_helper_74xx_tlbd(cpu_gpr[rB(ctx->opcode)]); |
... | ... | |
5137 | 5139 |
GEN_HANDLER2(tlbli_74xx, "tlbli", 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_74xx_TLB) |
5138 | 5140 |
{ |
5139 | 5141 |
#if defined(CONFIG_USER_ONLY) |
5140 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5142 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5141 | 5143 |
#else |
5142 | 5144 |
if (unlikely(!ctx->mem_idx)) { |
5143 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5145 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5144 | 5146 |
return; |
5145 | 5147 |
} |
5146 | 5148 |
gen_helper_74xx_tlbi(cpu_gpr[rB(ctx->opcode)]); |
... | ... | |
5159 | 5161 |
{ |
5160 | 5162 |
/* Cache line invalidate: privileged and treated as no-op */ |
5161 | 5163 |
#if defined(CONFIG_USER_ONLY) |
5162 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5164 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5163 | 5165 |
#else |
5164 | 5166 |
if (unlikely(!ctx->mem_idx)) { |
5165 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5167 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5166 | 5168 |
return; |
5167 | 5169 |
} |
5168 | 5170 |
#endif |
... | ... | |
5177 | 5179 |
GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER) |
5178 | 5180 |
{ |
5179 | 5181 |
#if defined(CONFIG_USER_ONLY) |
5180 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5182 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5181 | 5183 |
#else |
5182 | 5184 |
int ra = rA(ctx->opcode); |
5183 | 5185 |
int rd = rD(ctx->opcode); |
5184 | 5186 |
TCGv t0; |
5185 | 5187 |
if (unlikely(!ctx->mem_idx)) { |
5186 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5188 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5187 | 5189 |
return; |
5188 | 5190 |
} |
5189 | 5191 |
t0 = tcg_temp_new(); |
... | ... | |
5200 | 5202 |
GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER) |
5201 | 5203 |
{ |
5202 | 5204 |
#if defined(CONFIG_USER_ONLY) |
5203 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5205 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5204 | 5206 |
#else |
5205 | 5207 |
TCGv t0; |
5206 | 5208 |
if (unlikely(!ctx->mem_idx)) { |
5207 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5209 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5208 | 5210 |
return; |
5209 | 5211 |
} |
5210 | 5212 |
t0 = tcg_temp_new(); |
... | ... | |
5217 | 5219 |
GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER) |
5218 | 5220 |
{ |
5219 | 5221 |
#if defined(CONFIG_USER_ONLY) |
5220 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5222 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5221 | 5223 |
#else |
5222 | 5224 |
if (unlikely(!ctx->mem_idx)) { |
5223 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5225 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5224 | 5226 |
return; |
5225 | 5227 |
} |
5226 | 5228 |
gen_helper_rfsvc(); |
5227 |
GEN_SYNC(ctx);
|
|
5229 |
gen_sync_exception(ctx);
|
|
5228 | 5230 |
#endif |
5229 | 5231 |
} |
5230 | 5232 |
|
... | ... | |
5370 | 5372 |
GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_MFAPIDI) |
5371 | 5373 |
{ |
5372 | 5374 |
/* XXX: TODO */ |
5373 |
GEN_EXCP_INVAL(ctx);
|
|
5375 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
5374 | 5376 |
} |
5375 | 5377 |
|
5376 | 5378 |
/* XXX: not implemented on 440 ? */ |
5377 | 5379 |
GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_TLBIVA) |
5378 | 5380 |
{ |
5379 | 5381 |
#if defined(CONFIG_USER_ONLY) |
5380 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5382 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5381 | 5383 |
#else |
5382 | 5384 |
TCGv t0; |
5383 | 5385 |
if (unlikely(!ctx->mem_idx)) { |
5384 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5386 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5385 | 5387 |
return; |
5386 | 5388 |
} |
5387 | 5389 |
t0 = tcg_temp_new(); |
... | ... | |
5610 | 5612 |
GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_DCR) |
5611 | 5613 |
{ |
5612 | 5614 |
#if defined(CONFIG_USER_ONLY) |
5613 |
GEN_EXCP_PRIVREG(ctx);
|
|
5615 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
5614 | 5616 |
#else |
5615 | 5617 |
TCGv dcrn; |
5616 | 5618 |
if (unlikely(!ctx->mem_idx)) { |
5617 |
GEN_EXCP_PRIVREG(ctx);
|
|
5619 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
5618 | 5620 |
return; |
5619 | 5621 |
} |
5620 | 5622 |
/* NIP cannot be restored if the memory exception comes from an helper */ |
... | ... | |
5629 | 5631 |
GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_DCR) |
5630 | 5632 |
{ |
5631 | 5633 |
#if defined(CONFIG_USER_ONLY) |
5632 |
GEN_EXCP_PRIVREG(ctx);
|
|
5634 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
5633 | 5635 |
#else |
5634 | 5636 |
TCGv dcrn; |
5635 | 5637 |
if (unlikely(!ctx->mem_idx)) { |
5636 |
GEN_EXCP_PRIVREG(ctx);
|
|
5638 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
5637 | 5639 |
return; |
5638 | 5640 |
} |
5639 | 5641 |
/* NIP cannot be restored if the memory exception comes from an helper */ |
... | ... | |
5649 | 5651 |
GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_DCRX) |
5650 | 5652 |
{ |
5651 | 5653 |
#if defined(CONFIG_USER_ONLY) |
5652 |
GEN_EXCP_PRIVREG(ctx);
|
|
5654 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
5653 | 5655 |
#else |
5654 | 5656 |
if (unlikely(!ctx->mem_idx)) { |
5655 |
GEN_EXCP_PRIVREG(ctx);
|
|
5657 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
5656 | 5658 |
return; |
5657 | 5659 |
} |
5658 | 5660 |
/* NIP cannot be restored if the memory exception comes from an helper */ |
... | ... | |
5667 | 5669 |
GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_DCRX) |
5668 | 5670 |
{ |
5669 | 5671 |
#if defined(CONFIG_USER_ONLY) |
5670 |
GEN_EXCP_PRIVREG(ctx);
|
|
5672 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
5671 | 5673 |
#else |
5672 | 5674 |
if (unlikely(!ctx->mem_idx)) { |
5673 |
GEN_EXCP_PRIVREG(ctx);
|
|
5675 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
|
|
5674 | 5676 |
return; |
5675 | 5677 |
} |
5676 | 5678 |
/* NIP cannot be restored if the memory exception comes from an helper */ |
... | ... | |
5702 | 5704 |
GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON) |
5703 | 5705 |
{ |
5704 | 5706 |
#if defined(CONFIG_USER_ONLY) |
5705 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5707 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5706 | 5708 |
#else |
5707 | 5709 |
if (unlikely(!ctx->mem_idx)) { |
5708 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5710 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5709 | 5711 |
return; |
5710 | 5712 |
} |
5711 | 5713 |
/* interpreted as no-op */ |
... | ... | |
5716 | 5718 |
GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON) |
5717 | 5719 |
{ |
5718 | 5720 |
#if defined(CONFIG_USER_ONLY) |
5719 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5721 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5720 | 5722 |
#else |
5721 | 5723 |
TCGv EA, val; |
5722 | 5724 |
if (unlikely(!ctx->mem_idx)) { |
5723 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5725 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5724 | 5726 |
return; |
5725 | 5727 |
} |
5726 | 5728 |
gen_set_access_type(ctx, ACCESS_CACHE); |
... | ... | |
5747 | 5749 |
GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON) |
5748 | 5750 |
{ |
5749 | 5751 |
#if defined(CONFIG_USER_ONLY) |
5750 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5752 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5751 | 5753 |
#else |
5752 | 5754 |
if (unlikely(!ctx->mem_idx)) { |
5753 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5755 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5754 | 5756 |
return; |
5755 | 5757 |
} |
5756 | 5758 |
/* interpreted as no-op */ |
... | ... | |
5761 | 5763 |
GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON) |
5762 | 5764 |
{ |
5763 | 5765 |
#if defined(CONFIG_USER_ONLY) |
5764 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5766 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5765 | 5767 |
#else |
5766 | 5768 |
if (unlikely(!ctx->mem_idx)) { |
5767 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5769 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5768 | 5770 |
return; |
5769 | 5771 |
} |
5770 | 5772 |
/* interpreted as no-op */ |
... | ... | |
5775 | 5777 |
GEN_HANDLER2(rfci_40x, "rfci", 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP) |
5776 | 5778 |
{ |
5777 | 5779 |
#if defined(CONFIG_USER_ONLY) |
5778 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5780 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5779 | 5781 |
#else |
5780 | 5782 |
if (unlikely(!ctx->mem_idx)) { |
5781 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5783 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5782 | 5784 |
return; |
5783 | 5785 |
} |
5784 | 5786 |
/* Restore CPU state */ |
5785 | 5787 |
gen_helper_40x_rfci(); |
5786 |
GEN_SYNC(ctx);
|
|
5788 |
gen_sync_exception(ctx);
|
|
5787 | 5789 |
#endif |
5788 | 5790 |
} |
5789 | 5791 |
|
5790 | 5792 |
GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE) |
5791 | 5793 |
{ |
5792 | 5794 |
#if defined(CONFIG_USER_ONLY) |
5793 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5795 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5794 | 5796 |
#else |
5795 | 5797 |
if (unlikely(!ctx->mem_idx)) { |
5796 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5798 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5797 | 5799 |
return; |
5798 | 5800 |
} |
5799 | 5801 |
/* Restore CPU state */ |
5800 | 5802 |
gen_helper_rfci(); |
5801 |
GEN_SYNC(ctx);
|
|
5803 |
gen_sync_exception(ctx);
|
|
5802 | 5804 |
#endif |
5803 | 5805 |
} |
5804 | 5806 |
|
... | ... | |
5807 | 5809 |
GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_RFDI) |
5808 | 5810 |
{ |
5809 | 5811 |
#if defined(CONFIG_USER_ONLY) |
5810 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5812 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5811 | 5813 |
#else |
5812 | 5814 |
if (unlikely(!ctx->mem_idx)) { |
5813 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5815 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5814 | 5816 |
return; |
5815 | 5817 |
} |
5816 | 5818 |
/* Restore CPU state */ |
5817 | 5819 |
gen_helper_rfdi(); |
5818 |
GEN_SYNC(ctx);
|
|
5820 |
gen_sync_exception(ctx);
|
|
5819 | 5821 |
#endif |
5820 | 5822 |
} |
5821 | 5823 |
|
... | ... | |
5823 | 5825 |
GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI) |
5824 | 5826 |
{ |
5825 | 5827 |
#if defined(CONFIG_USER_ONLY) |
5826 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5828 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5827 | 5829 |
#else |
5828 | 5830 |
if (unlikely(!ctx->mem_idx)) { |
5829 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5831 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5830 | 5832 |
return; |
5831 | 5833 |
} |
5832 | 5834 |
/* Restore CPU state */ |
5833 | 5835 |
gen_helper_rfmci(); |
5834 |
GEN_SYNC(ctx);
|
|
5836 |
gen_sync_exception(ctx);
|
|
5835 | 5837 |
#endif |
5836 | 5838 |
} |
5837 | 5839 |
|
... | ... | |
5840 | 5842 |
GEN_HANDLER2(tlbre_40x, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB) |
5841 | 5843 |
{ |
5842 | 5844 |
#if defined(CONFIG_USER_ONLY) |
5843 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5845 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5844 | 5846 |
#else |
5845 | 5847 |
if (unlikely(!ctx->mem_idx)) { |
5846 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5848 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5847 | 5849 |
return; |
5848 | 5850 |
} |
5849 | 5851 |
switch (rB(ctx->opcode)) { |
... | ... | |
5854 | 5856 |
gen_helper_4xx_tlbre_lo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); |
5855 | 5857 |
break; |
5856 | 5858 |
default: |
5857 |
GEN_EXCP_INVAL(ctx);
|
|
5859 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
5858 | 5860 |
break; |
5859 | 5861 |
} |
5860 | 5862 |
#endif |
... | ... | |
5864 | 5866 |
GEN_HANDLER2(tlbsx_40x, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB) |
5865 | 5867 |
{ |
5866 | 5868 |
#if defined(CONFIG_USER_ONLY) |
5867 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5869 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5868 | 5870 |
#else |
5869 | 5871 |
TCGv t0; |
5870 | 5872 |
if (unlikely(!ctx->mem_idx)) { |
5871 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5873 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5872 | 5874 |
return; |
5873 | 5875 |
} |
5874 | 5876 |
t0 = tcg_temp_new(); |
... | ... | |
5891 | 5893 |
GEN_HANDLER2(tlbwe_40x, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB) |
5892 | 5894 |
{ |
5893 | 5895 |
#if defined(CONFIG_USER_ONLY) |
5894 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5896 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5895 | 5897 |
#else |
5896 | 5898 |
if (unlikely(!ctx->mem_idx)) { |
5897 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5899 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5898 | 5900 |
return; |
5899 | 5901 |
} |
5900 | 5902 |
switch (rB(ctx->opcode)) { |
... | ... | |
5905 | 5907 |
gen_helper_4xx_tlbwe_lo(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); |
5906 | 5908 |
break; |
5907 | 5909 |
default: |
5908 |
GEN_EXCP_INVAL(ctx);
|
|
5910 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
5909 | 5911 |
break; |
5910 | 5912 |
} |
5911 | 5913 |
#endif |
... | ... | |
5916 | 5918 |
GEN_HANDLER2(tlbre_440, "tlbre", 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) |
5917 | 5919 |
{ |
5918 | 5920 |
#if defined(CONFIG_USER_ONLY) |
5919 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5921 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5920 | 5922 |
#else |
5921 | 5923 |
if (unlikely(!ctx->mem_idx)) { |
5922 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5924 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5923 | 5925 |
return; |
5924 | 5926 |
} |
5925 | 5927 |
switch (rB(ctx->opcode)) { |
... | ... | |
5933 | 5935 |
} |
5934 | 5936 |
break; |
5935 | 5937 |
default: |
5936 |
GEN_EXCP_INVAL(ctx);
|
|
5938 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
5937 | 5939 |
break; |
5938 | 5940 |
} |
5939 | 5941 |
#endif |
... | ... | |
5943 | 5945 |
GEN_HANDLER2(tlbsx_440, "tlbsx", 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) |
5944 | 5946 |
{ |
5945 | 5947 |
#if defined(CONFIG_USER_ONLY) |
5946 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5948 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5947 | 5949 |
#else |
5948 | 5950 |
TCGv t0; |
5949 | 5951 |
if (unlikely(!ctx->mem_idx)) { |
5950 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5952 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5951 | 5953 |
return; |
5952 | 5954 |
} |
5953 | 5955 |
t0 = tcg_temp_new(); |
... | ... | |
5970 | 5972 |
GEN_HANDLER2(tlbwe_440, "tlbwe", 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) |
5971 | 5973 |
{ |
5972 | 5974 |
#if defined(CONFIG_USER_ONLY) |
5973 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5975 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5974 | 5976 |
#else |
5975 | 5977 |
if (unlikely(!ctx->mem_idx)) { |
5976 |
GEN_EXCP_PRIVOPC(ctx);
|
|
5978 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
5977 | 5979 |
return; |
5978 | 5980 |
} |
5979 | 5981 |
switch (rB(ctx->opcode)) { |
... | ... | |
5987 | 5989 |
} |
5988 | 5990 |
break; |
5989 | 5991 |
default: |
5990 |
GEN_EXCP_INVAL(ctx);
|
|
5992 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
5991 | 5993 |
break; |
5992 | 5994 |
} |
5993 | 5995 |
#endif |
... | ... | |
5997 | 5999 |
GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_WRTEE) |
5998 | 6000 |
{ |
5999 | 6001 |
#if defined(CONFIG_USER_ONLY) |
6000 |
GEN_EXCP_PRIVOPC(ctx);
|
|
6002 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
6001 | 6003 |
#else |
6002 | 6004 |
TCGv t0; |
6003 | 6005 |
if (unlikely(!ctx->mem_idx)) { |
6004 |
GEN_EXCP_PRIVOPC(ctx);
|
|
6006 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
6005 | 6007 |
return; |
6006 | 6008 |
} |
6007 | 6009 |
t0 = tcg_temp_new(); |
... | ... | |
6012 | 6014 |
/* Stop translation to have a chance to raise an exception |
6013 | 6015 |
* if we just set msr_ee to 1 |
6014 | 6016 |
*/ |
6015 |
GEN_STOP(ctx);
|
|
6017 |
gen_stop_exception(ctx);
|
|
6016 | 6018 |
#endif |
6017 | 6019 |
} |
6018 | 6020 |
|
... | ... | |
6020 | 6022 |
GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_WRTEE) |
6021 | 6023 |
{ |
6022 | 6024 |
#if defined(CONFIG_USER_ONLY) |
6023 |
GEN_EXCP_PRIVOPC(ctx);
|
|
6025 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
6024 | 6026 |
#else |
6025 | 6027 |
if (unlikely(!ctx->mem_idx)) { |
6026 |
GEN_EXCP_PRIVOPC(ctx);
|
|
6028 |
gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
|
|
6027 | 6029 |
return; |
6028 | 6030 |
} |
6029 | 6031 |
if (ctx->opcode & 0x00010000) { |
6030 | 6032 |
tcg_gen_ori_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); |
6031 | 6033 |
/* Stop translation to have a chance to raise an exception */ |
6032 |
GEN_STOP(ctx);
|
|
6034 |
gen_stop_exception(ctx);
|
|
6033 | 6035 |
} else { |
6034 | 6036 |
tcg_gen_andi_tl(cpu_msr, cpu_msr, (1 << MSR_EE)); |
6035 | 6037 |
} |
... | ... | |
6075 | 6077 |
{ \ |
6076 | 6078 |
TCGv EA; \ |
6077 | 6079 |
if (unlikely(!ctx->altivec_enabled)) { \ |
6078 |
GEN_EXCP_NO_VR(ctx); \
|
|
6080 |
gen_exception(ctx, POWERPC_EXCP_VPU); \
|
|
6079 | 6081 |
return; \ |
6080 | 6082 |
} \ |
6081 | 6083 |
gen_set_access_type(ctx, ACCESS_INT); \ |
... | ... | |
6099 | 6101 |
{ \ |
6100 | 6102 |
TCGv EA; \ |
6101 | 6103 |
if (unlikely(!ctx->altivec_enabled)) { \ |
6102 |
GEN_EXCP_NO_VR(ctx); \
|
|
6104 |
gen_exception(ctx, POWERPC_EXCP_VPU); \
|
|
6103 | 6105 |
return; \ |
6104 | 6106 |
} \ |
6105 | 6107 |
gen_set_access_type(ctx, ACCESS_INT); \ |
... | ... | |
6161 | 6163 |
/* Handler for undefined SPE opcodes */ |
6162 | 6164 |
static always_inline void gen_speundef (DisasContext *ctx) |
6163 | 6165 |
{ |
6164 |
GEN_EXCP_INVAL(ctx);
|
|
6166 |
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
|
|
6165 | 6167 |
} |
6166 | 6168 |
|
6167 | 6169 |
/* SPE logic */ |
... | ... | |
6170 | 6172 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6171 | 6173 |
{ \ |
6172 | 6174 |
if (unlikely(!ctx->spe_enabled)) { \ |
6173 |
GEN_EXCP_NO_AP(ctx); \
|
|
6175 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6174 | 6176 |
return; \ |
6175 | 6177 |
} \ |
6176 | 6178 |
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ |
... | ... | |
6181 | 6183 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6182 | 6184 |
{ \ |
6183 | 6185 |
if (unlikely(!ctx->spe_enabled)) { \ |
6184 |
GEN_EXCP_NO_AP(ctx); \
|
|
6186 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6185 | 6187 |
return; \ |
6186 | 6188 |
} \ |
6187 | 6189 |
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ |
... | ... | |
6206 | 6208 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6207 | 6209 |
{ \ |
6208 | 6210 |
if (unlikely(!ctx->spe_enabled)) { \ |
6209 |
GEN_EXCP_NO_AP(ctx); \
|
|
6211 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6210 | 6212 |
return; \ |
6211 | 6213 |
} \ |
6212 | 6214 |
TCGv_i32 t0 = tcg_temp_local_new_i32(); \ |
... | ... | |
6227 | 6229 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6228 | 6230 |
{ \ |
6229 | 6231 |
if (unlikely(!ctx->spe_enabled)) { \ |
6230 |
GEN_EXCP_NO_AP(ctx); \
|
|
6232 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6231 | 6233 |
return; \ |
6232 | 6234 |
} \ |
6233 | 6235 |
tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ |
... | ... | |
6247 | 6249 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6248 | 6250 |
{ \ |
6249 | 6251 |
if (unlikely(!ctx->spe_enabled)) { \ |
6250 |
GEN_EXCP_NO_AP(ctx); \
|
|
6252 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6251 | 6253 |
return; \ |
6252 | 6254 |
} \ |
6253 | 6255 |
TCGv_i32 t0 = tcg_temp_local_new_i32(); \ |
... | ... | |
6268 | 6270 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6269 | 6271 |
{ \ |
6270 | 6272 |
if (unlikely(!ctx->spe_enabled)) { \ |
6271 |
GEN_EXCP_NO_AP(ctx); \
|
|
6273 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6272 | 6274 |
return; \ |
6273 | 6275 |
} \ |
6274 | 6276 |
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \ |
... | ... | |
6306 | 6308 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6307 | 6309 |
{ \ |
6308 | 6310 |
if (unlikely(!ctx->spe_enabled)) { \ |
6309 |
GEN_EXCP_NO_AP(ctx); \
|
|
6311 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6310 | 6312 |
return; \ |
6311 | 6313 |
} \ |
6312 | 6314 |
TCGv_i32 t0 = tcg_temp_local_new_i32(); \ |
... | ... | |
6332 | 6334 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6333 | 6335 |
{ \ |
6334 | 6336 |
if (unlikely(!ctx->spe_enabled)) { \ |
6335 |
GEN_EXCP_NO_AP(ctx); \
|
|
6337 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6336 | 6338 |
return; \ |
6337 | 6339 |
} \ |
6338 | 6340 |
tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ |
... | ... | |
6410 | 6412 |
static always_inline void gen_evmergehi (DisasContext *ctx) |
6411 | 6413 |
{ |
6412 | 6414 |
if (unlikely(!ctx->spe_enabled)) { |
6413 |
GEN_EXCP_NO_AP(ctx);
|
|
6415 |
gen_exception(ctx, POWERPC_EXCP_APU);
|
|
6414 | 6416 |
return; |
6415 | 6417 |
} |
6416 | 6418 |
#if defined(TARGET_PPC64) |
... | ... | |
6439 | 6441 |
static always_inline void gen_##name (DisasContext *ctx) \ |
6440 | 6442 |
{ \ |
6441 | 6443 |
if (unlikely(!ctx->spe_enabled)) { \ |
6442 |
GEN_EXCP_NO_AP(ctx); \
|
|
6444 |
gen_exception(ctx, POWERPC_EXCP_APU); \
|
|
6443 | 6445 |
return; \ |
6444 | 6446 |
} \ |
6445 | 6447 |
TCGv_i32 t0 = tcg_temp_local_new_i32(); \ |
... | ... | |
6449 | 6451 |
tcg_op(t0, t0, rA(ctx->opcode)); \ |
Also available in: Unified diff