Commit e1833e1f96456fd8fc17463246fe0b2050e68efb

Authored by j_mayer
1 parent f9373291

Rework PowerPC exceptions model to make it more versatile:

* don't use exception vectors as the exception number.
  Use vectors numbers as defined in the PowerPC embedded specification instead
  and extend this model to cover all emulated PowerPC variants exceptions.
* add some missing exceptions definitions, from PowerPC 2.04 specification
  and actual PowerPC implementations.
* add code provision for hypervisor exceptions handling.
* define exception vectors and prefix in CPUPPCState to emulate BookE exception
  vectors without any hacks.
* define per CPU model valid exception vectors.
* handle all known exceptions in user-mode only emulations.
* fix hardware interrupts priorities in most cases.
* change RET_EXCP macros name into GEN_EXCP as they don't return.
* do not stop translation on most instructions that are not defined as
  context-synchronizing in PowerPC specification.
* fix PowerPC 64 jump targets and link register update when in 32 bits mode.
* Fix PowerPC 464 and 464F definitions.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3261 c046a42c-6fe2-441c-8c8c-71466251a162

Too many changes to show.

To preserve performance only 7 of 8 files are displayed.

darwin-user/main.c
@@ -139,17 +139,6 @@ void cpu_ppc_store_tbl (CPUState *env, uint32_t value) @@ -139,17 +139,6 @@ void cpu_ppc_store_tbl (CPUState *env, uint32_t value)
139 cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value); 139 cpu_ppc_store_tb(env, ((uint64_t)cpu_ppc_load_tbl(env) << 32) | value);
140 } 140 }
141 141
142 -uint32_t cpu_ppc_load_decr (CPUState *env)  
143 -{  
144 - /* TO FIX */  
145 - return -1;  
146 -}  
147 -  
148 -void cpu_ppc_store_decr (CPUState *env, uint32_t value)  
149 -{  
150 - /* TO FIX */  
151 -}  
152 -  
153 void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value) 142 void cpu_ppc601_store_rtcu (CPUState *env, uint32_t value)
154 { 143 {
155 cpu_ppc_store_tbu( env, value ); 144 cpu_ppc_store_tbu( env, value );
@@ -165,6 +154,27 @@ uint32_t cpu_ppc601_load_rtcl (CPUState *env) @@ -165,6 +154,27 @@ uint32_t cpu_ppc601_load_rtcl (CPUState *env)
165 return cpu_ppc_load_tbl(env) & 0x3FFFFF80; 154 return cpu_ppc_load_tbl(env) & 0x3FFFFF80;
166 } 155 }
167 156
  157 +/* XXX: to be fixed */
  158 +int ppc_dcr_read (ppc_dcr_t *dcr_env, int dcrn, target_ulong *valp)
  159 +{
  160 + return -1;
  161 +}
  162 +
  163 +int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
  164 +{
  165 + return -1;
  166 +}
  167 +
  168 +#define EXCP_DUMP(env, fmt, args...) \
  169 +do { \
  170 + fprintf(stderr, fmt , ##args); \
  171 + cpu_dump_state(env, stderr, fprintf, 0); \
  172 + if (loglevel != 0) { \
  173 + fprintf(logfile, fmt , ##args); \
  174 + cpu_dump_state(env, logfile, fprintf, 0); \
  175 + } \
  176 +} while (0)
  177 +
168 void cpu_loop(CPUPPCState *env) 178 void cpu_loop(CPUPPCState *env)
169 { 179 {
170 int trapnr; 180 int trapnr;
@@ -173,271 +183,365 @@ void cpu_loop(CPUPPCState *env) @@ -173,271 +183,365 @@ void cpu_loop(CPUPPCState *env)
173 183
174 for(;;) { 184 for(;;) {
175 trapnr = cpu_ppc_exec(env); 185 trapnr = cpu_ppc_exec(env);
176 - if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH &&  
177 - trapnr != EXCP_TRACE) {  
178 - if (loglevel > 0) {  
179 - cpu_dump_state(env, logfile, fprintf, 0);  
180 - }  
181 - }  
182 switch(trapnr) { 186 switch(trapnr) {
183 - case EXCP_NONE: 187 + case POWERPC_EXCP_NONE:
  188 + /* Just go on */
184 break; 189 break;
185 - case EXCP_SYSCALL_USER:  
186 - /* system call */  
187 - if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)  
188 - ret = do_unix_syscall(env, env->gpr[0]/*, env->gpr[3], env->gpr[4],  
189 - env->gpr[5], env->gpr[6], env->gpr[7],  
190 - env->gpr[8], env->gpr[9], env->gpr[10]*/);  
191 - else if(((int)env->gpr[0])<0)  
192 - ret = do_mach_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],  
193 - env->gpr[5], env->gpr[6], env->gpr[7],  
194 - env->gpr[8], env->gpr[9], env->gpr[10]);  
195 - else  
196 - ret = do_thread_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],  
197 - env->gpr[5], env->gpr[6], env->gpr[7],  
198 - env->gpr[8], env->gpr[9], env->gpr[10]);  
199 -  
200 - /* Unix syscall error signaling */  
201 - if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)  
202 - {  
203 - if( (int)ret < 0 )  
204 - env->nip += 0;  
205 - else  
206 - env->nip += 4;  
207 - }  
208 -  
209 - /* Return value */  
210 - env->gpr[3] = ret; 190 + case POWERPC_EXCP_CRITICAL: /* Critical input */
  191 + cpu_abort(env, "Critical interrupt while in user mode. "
  192 + "Aborting\n");
211 break; 193 break;
212 - case EXCP_RESET:  
213 - /* Should not happen ! */  
214 - fprintf(stderr, "RESET asked... Stop emulation\n");  
215 - if (loglevel)  
216 - fprintf(logfile, "RESET asked... Stop emulation\n");  
217 - abort();  
218 - case EXCP_MACHINE_CHECK:  
219 - fprintf(stderr, "Machine check exeption... Stop emulation\n");  
220 - if (loglevel)  
221 - fprintf(logfile, "RESET asked... Stop emulation\n");  
222 - info.si_signo = SIGBUS;  
223 - info.si_errno = 0;  
224 - info.si_code = BUS_OBJERR;  
225 - info.si_addr = (void*)(env->nip - 4);  
226 - queue_signal(info.si_signo, &info);  
227 - case EXCP_DSI: 194 + case POWERPC_EXCP_MCHECK: /* Machine check exception */
  195 + cpu_abort(env, "Machine check exception while in user mode. "
  196 + "Aborting\n");
  197 + break;
  198 + case POWERPC_EXCP_DSI: /* Data storage exception */
228 #ifndef DAR 199 #ifndef DAR
229 /* To deal with multiple qemu header version as host for the darwin-user code */ 200 /* To deal with multiple qemu header version as host for the darwin-user code */
230 # define DAR SPR_DAR 201 # define DAR SPR_DAR
231 #endif 202 #endif
232 - fprintf(stderr, "Invalid data memory access: 0x%08x\n", env->spr[DAR]);  
233 - if (loglevel) {  
234 - fprintf(logfile, "Invalid data memory access: 0x%08x\n",  
235 - env->spr[DAR]);  
236 - } 203 + EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n",
  204 + env->spr[SPR_DAR]);
237 /* Handle this via the gdb */ 205 /* Handle this via the gdb */
238 gdb_handlesig (env, SIGSEGV); 206 gdb_handlesig (env, SIGSEGV);
239 207
240 info.si_addr = (void*)env->nip; 208 info.si_addr = (void*)env->nip;
241 queue_signal(info.si_signo, &info); 209 queue_signal(info.si_signo, &info);
242 break; 210 break;
243 - case EXCP_ISI:  
244 - fprintf(stderr, "Invalid instruction fetch\n");  
245 - if (loglevel)  
246 - fprintf(logfile, "Invalid instruction fetch\n"); 211 + case POWERPC_EXCP_ISI: /* Instruction storage exception */
  212 + EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
  213 + env->spr[SPR_DAR]);
247 /* Handle this via the gdb */ 214 /* Handle this via the gdb */
248 gdb_handlesig (env, SIGSEGV); 215 gdb_handlesig (env, SIGSEGV);
249 216
250 info.si_addr = (void*)(env->nip - 4); 217 info.si_addr = (void*)(env->nip - 4);
251 queue_signal(info.si_signo, &info); 218 queue_signal(info.si_signo, &info);
252 break; 219 break;
253 - case EXCP_EXTERNAL:  
254 - /* Should not happen ! */  
255 - fprintf(stderr, "External interruption... Stop emulation\n");  
256 - if (loglevel)  
257 - fprintf(logfile, "External interruption... Stop emulation\n");  
258 - abort();  
259 - case EXCP_ALIGN:  
260 - fprintf(stderr, "Invalid unaligned memory access\n");  
261 - if (loglevel)  
262 - fprintf(logfile, "Invalid unaligned memory access\n");  
263 - info.si_signo = SIGBUS; 220 + case POWERPC_EXCP_EXTERNAL: /* External input */
  221 + cpu_abort(env, "External interrupt while in user mode. "
  222 + "Aborting\n");
  223 + break;
  224 + case POWERPC_EXCP_ALIGN: /* Alignment exception */
  225 + EXCP_DUMP(env, "Unaligned memory access\n");
264 info.si_errno = 0; 226 info.si_errno = 0;
265 info.si_code = BUS_ADRALN; 227 info.si_code = BUS_ADRALN;
266 info.si_addr = (void*)(env->nip - 4); 228 info.si_addr = (void*)(env->nip - 4);
267 queue_signal(info.si_signo, &info); 229 queue_signal(info.si_signo, &info);
268 break; 230 break;
269 - case EXCP_PROGRAM: 231 + case POWERPC_EXCP_PROGRAM: /* Program exception */
  232 + /* XXX: check this */
270 switch (env->error_code & ~0xF) { 233 switch (env->error_code & ~0xF) {
271 - case EXCP_FP:  
272 - fprintf(stderr, "Program exception\n");  
273 - if (loglevel)  
274 - fprintf(logfile, "Program exception\n");  
275 - /* Set FX */  
276 - env->fpscr[7] |= 0x8;  
277 - /* Finally, update FEX */  
278 - if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &  
279 - ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))  
280 - env->fpscr[7] |= 0x4;  
281 - info.si_signo = SIGFPE;  
282 - info.si_errno = 0;  
283 - switch (env->error_code & 0xF) {  
284 - case EXCP_FP_OX:  
285 - info.si_code = FPE_FLTOVF;  
286 - break;  
287 - case EXCP_FP_UX:  
288 - info.si_code = FPE_FLTUND;  
289 - break;  
290 - case EXCP_FP_ZX:  
291 - case EXCP_FP_VXZDZ:  
292 - info.si_code = FPE_FLTDIV;  
293 - break;  
294 - case EXCP_FP_XX:  
295 - info.si_code = FPE_FLTRES;  
296 - break;  
297 - case EXCP_FP_VXSOFT:  
298 - info.si_code = FPE_FLTINV;  
299 - break;  
300 - case EXCP_FP_VXNAN:  
301 - case EXCP_FP_VXISI:  
302 - case EXCP_FP_VXIDI:  
303 - case EXCP_FP_VXIMZ:  
304 - case EXCP_FP_VXVC:  
305 - case EXCP_FP_VXSQRT:  
306 - case EXCP_FP_VXCVI:  
307 - info.si_code = FPE_FLTSUB;  
308 - break;  
309 - default:  
310 - fprintf(stderr, "Unknown floating point exception "  
311 - "(%02x)\n", env->error_code);  
312 - if (loglevel) {  
313 - fprintf(logfile, "Unknown floating point exception "  
314 - "(%02x)\n", env->error_code & 0xF);  
315 - }  
316 - }  
317 - break;  
318 - case EXCP_INVAL:  
319 - fprintf(stderr, "Invalid instruction\n");  
320 - if (loglevel)  
321 - fprintf(logfile, "Invalid instruction\n");  
322 - info.si_signo = SIGILL;  
323 - info.si_errno = 0;  
324 - switch (env->error_code & 0xF) {  
325 - case EXCP_INVAL_INVAL:  
326 - info.si_code = ILL_ILLOPC;  
327 - break;  
328 - case EXCP_INVAL_LSWX:  
329 - info.si_code = ILL_ILLOPN;  
330 - break;  
331 - case EXCP_INVAL_SPR:  
332 - info.si_code = ILL_PRVREG;  
333 - break;  
334 - case EXCP_INVAL_FP:  
335 - info.si_code = ILL_COPROC;  
336 - break;  
337 - default:  
338 - fprintf(stderr, "Unknown invalid operation (%02x)\n",  
339 - env->error_code & 0xF);  
340 - if (loglevel) {  
341 - fprintf(logfile, "Unknown invalid operation (%02x)\n",  
342 - env->error_code & 0xF);  
343 - }  
344 - info.si_code = ILL_ILLADR;  
345 - break;  
346 - }  
347 - /* Handle this via the gdb */  
348 - gdb_handlesig (env, SIGSEGV); 234 + case POWERPC_EXCP_FP:
  235 + EXCP_DUMP(env, "Floating point program exception\n");
  236 + /* Set FX */
  237 + env->fpscr[7] |= 0x8;
  238 + /* Finally, update FEX */
  239 + if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
  240 + ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
  241 + env->fpscr[7] |= 0x4;
  242 + info.si_signo = SIGFPE;
  243 + info.si_errno = 0;
  244 + switch (env->error_code & 0xF) {
  245 + case POWERPC_EXCP_FP_OX:
  246 + info.si_code = FPE_FLTOVF;
  247 + break;
  248 + case POWERPC_EXCP_FP_UX:
  249 + info.si_code = FPE_FLTUND;
  250 + break;
  251 + case POWERPC_EXCP_FP_ZX:
  252 + case POWERPC_EXCP_FP_VXZDZ:
  253 + info.si_code = FPE_FLTDIV;
  254 + break;
  255 + case POWERPC_EXCP_FP_XX:
  256 + info.si_code = FPE_FLTRES;
  257 + break;
  258 + case POWERPC_EXCP_FP_VXSOFT:
  259 + info.si_code = FPE_FLTINV;
  260 + break;
  261 + case POWERPC_EXCP_FP_VXNAN:
  262 + case POWERPC_EXCP_FP_VXISI:
  263 + case POWERPC_EXCP_FP_VXIDI:
  264 + case POWERPC_EXCP_FP_VXIMZ:
  265 + case POWERPC_EXCP_FP_VXVC:
  266 + case POWERPC_EXCP_FP_VXSQRT:
  267 + case POWERPC_EXCP_FP_VXCVI:
  268 + info.si_code = FPE_FLTSUB;
  269 + break;
  270 + default:
  271 + EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
  272 + env->error_code);
  273 + break;
  274 + }
  275 + break;
  276 + case POWERPC_EXCP_INVAL:
  277 + EXCP_DUMP(env, "Invalid instruction\n");
  278 + info.si_signo = SIGILL;
  279 + info.si_errno = 0;
  280 + switch (env->error_code & 0xF) {
  281 + case POWERPC_EXCP_INVAL_INVAL:
  282 + info.si_code = ILL_ILLOPC;
  283 + break;
  284 + case POWERPC_EXCP_INVAL_LSWX:
  285 + info.si_code = ILL_ILLOPN;
  286 + break;
  287 + case POWERPC_EXCP_INVAL_SPR:
  288 + info.si_code = ILL_PRVREG;
  289 + break;
  290 + case POWERPC_EXCP_INVAL_FP:
  291 + info.si_code = ILL_COPROC;
  292 + break;
  293 + default:
  294 + EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
  295 + env->error_code & 0xF);
  296 + info.si_code = ILL_ILLADR;
  297 + break;
  298 + }
  299 + /* Handle this via the gdb */
  300 + gdb_handlesig (env, SIGSEGV);
  301 + break;
  302 + case POWERPC_EXCP_PRIV:
  303 + EXCP_DUMP(env, "Privilege violation\n");
  304 + info.si_signo = SIGILL;
  305 + info.si_errno = 0;
  306 + switch (env->error_code & 0xF) {
  307 + case POWERPC_EXCP_PRIV_OPC:
  308 + info.si_code = ILL_PRVOPC;
  309 + break;
  310 + case POWERPC_EXCP_PRIV_REG:
  311 + info.si_code = ILL_PRVREG;
349 break; 312 break;
350 - case EXCP_PRIV:  
351 - fprintf(stderr, "Privilege violation\n");  
352 - if (loglevel)  
353 - fprintf(logfile, "Privilege violation\n");  
354 - info.si_signo = SIGILL;  
355 - info.si_errno = 0;  
356 - switch (env->error_code & 0xF) {  
357 - case EXCP_PRIV_OPC:  
358 - info.si_code = ILL_PRVOPC;  
359 - break;  
360 - case EXCP_PRIV_REG:  
361 - info.si_code = ILL_PRVREG;  
362 - break;  
363 - default:  
364 - fprintf(stderr, "Unknown privilege violation (%02x)\n",  
365 - env->error_code & 0xF);  
366 - info.si_code = ILL_PRVOPC;  
367 - break;  
368 - }  
369 - break;  
370 - case EXCP_TRAP:  
371 - fprintf(stderr, "Tried to call a TRAP\n");  
372 - if (loglevel)  
373 - fprintf(logfile, "Tried to call a TRAP\n");  
374 - abort();  
375 default: 313 default:
376 - /* Should not happen ! */  
377 - fprintf(stderr, "Unknown program exception (%02x)\n",  
378 - env->error_code);  
379 - if (loglevel) {  
380 - fprintf(logfile, "Unknwon program exception (%02x)\n",  
381 - env->error_code);  
382 - }  
383 - abort(); 314 + EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
  315 + env->error_code & 0xF);
  316 + info.si_code = ILL_PRVOPC;
  317 + break;
  318 + }
  319 + break;
  320 + case POWERPC_EXCP_TRAP:
  321 + cpu_abort(env, "Tried to call a TRAP\n");
  322 + break;
  323 + default:
  324 + /* Should not happen ! */
  325 + cpu_abort(env, "Unknown program exception (%02x)\n",
  326 + env->error_code);
  327 + break;
384 } 328 }
385 info.si_addr = (void*)(env->nip - 4); 329 info.si_addr = (void*)(env->nip - 4);
386 queue_signal(info.si_signo, &info); 330 queue_signal(info.si_signo, &info);
387 break; 331 break;
388 - case EXCP_NO_FP:  
389 - fprintf(stderr, "No floating point allowed\n");  
390 - if (loglevel)  
391 - fprintf(logfile, "No floating point allowed\n");  
392 - info.si_signo = SIGILL; 332 + case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
  333 + EXCP_DUMP(env, "No floating point allowed\n");
  334 + info.si_signo = SIGILL;
393 info.si_errno = 0; 335 info.si_errno = 0;
394 info.si_code = ILL_COPROC; 336 info.si_code = ILL_COPROC;
395 info.si_addr = (void*)(env->nip - 4); 337 info.si_addr = (void*)(env->nip - 4);
396 queue_signal(info.si_signo, &info); 338 queue_signal(info.si_signo, &info);
397 break; 339 break;
398 - case EXCP_DECR:  
399 - /* Should not happen ! */  
400 - fprintf(stderr, "Decrementer exception\n");  
401 - if (loglevel)  
402 - fprintf(logfile, "Decrementer exception\n");  
403 - abort();  
404 - case EXCP_TRACE:  
405 - /* Pass to gdb: we use this to trace execution */  
406 - gdb_handlesig (env, SIGTRAP); 340 + case POWERPC_EXCP_SYSCALL: /* System call exception */
  341 + cpu_abort(env, "Syscall exception while in user mode. "
  342 + "Aborting\n");
407 break; 343 break;
408 - case EXCP_FP_ASSIST:  
409 - /* Should not happen ! */  
410 - fprintf(stderr, "Floating point assist exception\n");  
411 - if (loglevel)  
412 - fprintf(logfile, "Floating point assist exception\n");  
413 - abort();  
414 - case EXCP_MTMSR:  
415 - /* We reloaded the msr, just go on */  
416 - if (msr_pr == 0) {  
417 - fprintf(stderr, "Tried to go into supervisor mode !\n");  
418 - if (loglevel)  
419 - fprintf(logfile, "Tried to go into supervisor mode !\n");  
420 - abort();  
421 - } 344 + case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
  345 + EXCP_DUMP(env, "No APU instruction allowed\n");
  346 + info.si_signo = SIGILL;
  347 + info.si_errno = 0;
  348 + info.si_code = ILL_COPROC;
  349 + info.si_addr = (void*)(env->nip - 4);
  350 + queue_signal(info.si_signo, &info);
422 break; 351 break;
423 - case EXCP_BRANCH:  
424 - /* We stopped because of a jump... */ 352 + case POWERPC_EXCP_DECR: /* Decrementer exception */
  353 + cpu_abort(env, "Decrementer interrupt while in user mode. "
  354 + "Aborting\n");
425 break; 355 break;
426 - case EXCP_INTERRUPT:  
427 - /* Don't know why this should ever happen... */  
428 - fprintf(stderr, "EXCP_INTERRUPT\n"); 356 + case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
  357 + cpu_abort(env, "Fix interval timer interrupt while in user mode. "
  358 + "Aborting\n");
429 break; 359 break;
430 - case EXCP_DEBUG: 360 + case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
  361 + cpu_abort(env, "Watchdog timer interrupt while in user mode. "
  362 + "Aborting\n");
  363 + break;
  364 + case POWERPC_EXCP_DTLB: /* Data TLB error */
  365 + cpu_abort(env, "Data TLB exception while in user mode. "
  366 + "Aborting\n");
  367 + break;
  368 + case POWERPC_EXCP_ITLB: /* Instruction TLB error */
  369 + cpu_abort(env, "Instruction TLB exception while in user mode. "
  370 + "Aborting\n");
  371 + break;
  372 + case POWERPC_EXCP_DEBUG: /* Debug interrupt */
431 gdb_handlesig (env, SIGTRAP); 373 gdb_handlesig (env, SIGTRAP);
432 break; 374 break;
433 - default:  
434 - fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",  
435 - trapnr);  
436 - if (loglevel) {  
437 - fprintf(logfile, "qemu: unhandled CPU exception 0x%02x - "  
438 - "0x%02x - aborting\n", trapnr, env->error_code); 375 +#if defined(TARGET_PPCEMB)
  376 + case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
  377 + EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
  378 + info.si_signo = SIGILL;
  379 + info.si_errno = 0;
  380 + info.si_code = ILL_COPROC;
  381 + info.si_addr = (void*)(env->nip - 4);
  382 + queue_signal(info.si_signo, &info);
  383 + break;
  384 + case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
  385 + cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
  386 + break;
  387 + case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */
  388 + cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
  389 + break;
  390 + case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */
  391 + cpu_abort(env, "Performance monitor exception not handled\n");
  392 + break;
  393 + case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
  394 + cpu_abort(env, "Doorbell interrupt while in user mode. "
  395 + "Aborting\n");
  396 + break;
  397 + case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
  398 + cpu_abort(env, "Doorbell critical interrupt while in user mode. "
  399 + "Aborting\n");
  400 + break;
  401 +#endif /* defined(TARGET_PPCEMB) */
  402 + case POWERPC_EXCP_RESET: /* System reset exception */
  403 + cpu_abort(env, "Reset interrupt while in user mode. "
  404 + "Aborting\n");
  405 + break;
  406 +#if defined(TARGET_PPC64) /* PowerPC 64 */
  407 + case POWERPC_EXCP_DSEG: /* Data segment exception */
  408 + cpu_abort(env, "Data segment exception while in user mode. "
  409 + "Aborting\n");
  410 + break;
  411 + case POWERPC_EXCP_ISEG: /* Instruction segment exception */
  412 + cpu_abort(env, "Instruction segment exception "
  413 + "while in user mode. Aborting\n");
  414 + break;
  415 +#endif /* defined(TARGET_PPC64) */
  416 +#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
  417 + case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
  418 + cpu_abort(env, "Hypervisor decrementer interrupt "
  419 + "while in user mode. Aborting\n");
  420 + break;
  421 +#endif /* defined(TARGET_PPC64H) */
  422 + case POWERPC_EXCP_TRACE: /* Trace exception */
  423 + /* Nothing to do:
  424 + * we use this exception to emulate step-by-step execution mode.
  425 + */
  426 + break;
  427 +#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
  428 + case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
  429 + cpu_abort(env, "Hypervisor data storage exception "
  430 + "while in user mode. Aborting\n");
  431 + break;
  432 + case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */
  433 + cpu_abort(env, "Hypervisor instruction storage exception "
  434 + "while in user mode. Aborting\n");
  435 + break;
  436 + case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
  437 + cpu_abort(env, "Hypervisor data segment exception "
  438 + "while in user mode. Aborting\n");
  439 + break;
  440 + case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */
  441 + cpu_abort(env, "Hypervisor instruction segment exception "
  442 + "while in user mode. Aborting\n");
  443 + break;
  444 +#endif /* defined(TARGET_PPC64H) */
  445 + case POWERPC_EXCP_VPU: /* Vector unavailable exception */
  446 + EXCP_DUMP(env, "No Altivec instructions allowed\n");
  447 + info.si_signo = SIGILL;
  448 + info.si_errno = 0;
  449 + info.si_code = ILL_COPROC;
  450 + info.si_addr = (void*)(env->nip - 4);
  451 + queue_signal(info.si_signo, &info);
  452 + break;
  453 + case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
  454 + cpu_abort(env, "Programable interval timer interrupt "
  455 + "while in user mode. Aborting\n");
  456 + break;
  457 + case POWERPC_EXCP_IO: /* IO error exception */
  458 + cpu_abort(env, "IO error exception while in user mode. "
  459 + "Aborting\n");
  460 + break;
  461 + case POWERPC_EXCP_RUNM: /* Run mode exception */
  462 + cpu_abort(env, "Run mode exception while in user mode. "
  463 + "Aborting\n");
  464 + break;
  465 + case POWERPC_EXCP_EMUL: /* Emulation trap exception */
  466 + cpu_abort(env, "Emulation trap exception not handled\n");
  467 + break;
  468 + case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
  469 + cpu_abort(env, "Instruction fetch TLB exception "
  470 + "while in user-mode. Aborting");
  471 + break;
  472 + case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
  473 + cpu_abort(env, "Data load TLB exception while in user-mode. "
  474 + "Aborting");
  475 + break;
  476 + case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
  477 + cpu_abort(env, "Data store TLB exception while in user-mode. "
  478 + "Aborting");
  479 + break;
  480 + case POWERPC_EXCP_FPA: /* Floating-point assist exception */
  481 + cpu_abort(env, "Floating-point assist exception not handled\n");
  482 + break;
  483 + case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
  484 + cpu_abort(env, "Instruction address breakpoint exception "
  485 + "not handled\n");
  486 + break;
  487 + case POWERPC_EXCP_SMI: /* System management interrupt */
  488 + cpu_abort(env, "System management interrupt while in user mode. "
  489 + "Aborting\n");
  490 + break;
  491 + case POWERPC_EXCP_THERM: /* Thermal interrupt */
  492 + cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
  493 + "Aborting\n");
  494 + break;
  495 + case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */
  496 + cpu_abort(env, "Performance monitor exception not handled\n");
  497 + break;
  498 + case POWERPC_EXCP_VPUA: /* Vector assist exception */
  499 + cpu_abort(env, "Vector assist exception not handled\n");
  500 + break;
  501 + case POWERPC_EXCP_SOFTP: /* Soft patch exception */
  502 + cpu_abort(env, "Soft patch exception not handled\n");
  503 + break;
  504 + case POWERPC_EXCP_MAINT: /* Maintenance exception */
  505 + cpu_abort(env, "Maintenance exception while in user mode. "
  506 + "Aborting\n");
  507 + break;
  508 + case POWERPC_EXCP_STOP: /* stop translation */
  509 + /* We did invalidate the instruction cache. Go on */
  510 + break;
  511 + case POWERPC_EXCP_BRANCH: /* branch instruction: */
  512 + /* We just stopped because of a branch. Go on */
  513 + break;
  514 + case POWERPC_EXCP_SYSCALL_USER:
  515 + /* system call in user-mode emulation */
  516 + /* system call */
  517 + if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
  518 + ret = do_unix_syscall(env, env->gpr[0]/*, env->gpr[3], env->gpr[4],
  519 + env->gpr[5], env->gpr[6], env->gpr[7],
  520 + env->gpr[8], env->gpr[9], env->gpr[10]*/);
  521 + else if(((int)env->gpr[0])<0)
  522 + ret = do_mach_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
  523 + env->gpr[5], env->gpr[6], env->gpr[7],
  524 + env->gpr[8], env->gpr[9], env->gpr[10]);
  525 + else
  526 + ret = do_thread_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
  527 + env->gpr[5], env->gpr[6], env->gpr[7],
  528 + env->gpr[8], env->gpr[9], env->gpr[10]);
  529 +
  530 + /* Unix syscall error signaling */
  531 + if(((int)env->gpr[0]) <= SYS_MAXSYSCALL && ((int)env->gpr[0])>0)
  532 + {
  533 + if( (int)ret < 0 )
  534 + env->nip += 0;
  535 + else
  536 + env->nip += 4;
439 } 537 }
440 - abort(); 538 +
  539 + /* Return value */
  540 + env->gpr[3] = ret;
  541 + break;
  542 + default:
  543 + cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
  544 + break;
441 } 545 }
442 process_pending_signals(env); 546 process_pending_signals(env);
443 } 547 }
linux-user/main.c
@@ -723,6 +723,16 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val) @@ -723,6 +723,16 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val)
723 return -1; 723 return -1;
724 } 724 }
725 725
  726 +#define EXCP_DUMP(env, fmt, args...) \
  727 +do { \
  728 + fprintf(stderr, fmt , ##args); \
  729 + cpu_dump_state(env, stderr, fprintf, 0); \
  730 + if (loglevel != 0) { \
  731 + fprintf(logfile, fmt , ##args); \
  732 + cpu_dump_state(env, logfile, fprintf, 0); \
  733 + } \
  734 +} while (0)
  735 +
726 void cpu_loop(CPUPPCState *env) 736 void cpu_loop(CPUPPCState *env)
727 { 737 {
728 target_siginfo_t info; 738 target_siginfo_t info;
@@ -731,60 +741,22 @@ void cpu_loop(CPUPPCState *env) @@ -731,60 +741,22 @@ void cpu_loop(CPUPPCState *env)
731 741
732 for(;;) { 742 for(;;) {
733 trapnr = cpu_ppc_exec(env); 743 trapnr = cpu_ppc_exec(env);
734 - if (trapnr != EXCP_SYSCALL_USER && trapnr != EXCP_BRANCH &&  
735 - trapnr != EXCP_TRACE) {  
736 - if (loglevel > 0) {  
737 - cpu_dump_state(env, logfile, fprintf, 0);  
738 - }  
739 - }  
740 switch(trapnr) { 744 switch(trapnr) {
741 - case EXCP_NONE: 745 + case POWERPC_EXCP_NONE:
  746 + /* Just go on */
742 break; 747 break;
743 - case EXCP_SYSCALL_USER:  
744 - /* system call */  
745 - /* WARNING:  
746 - * PPC ABI uses overflow flag in cr0 to signal an error  
747 - * in syscalls.  
748 - */  
749 -#if 0  
750 - printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],  
751 - env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);  
752 -#endif  
753 - env->crf[0] &= ~0x1;  
754 - ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],  
755 - env->gpr[5], env->gpr[6], env->gpr[7],  
756 - env->gpr[8]);  
757 - if (ret > (uint32_t)(-515)) {  
758 - env->crf[0] |= 0x1;  
759 - ret = -ret;  
760 - }  
761 - env->gpr[3] = ret;  
762 -#if 0  
763 - printf("syscall returned 0x%08x (%d)\n", ret, ret);  
764 -#endif 748 + case POWERPC_EXCP_CRITICAL: /* Critical input */
  749 + cpu_abort(env, "Critical interrupt while in user mode. "
  750 + "Aborting\n");
765 break; 751 break;
766 - case EXCP_RESET:  
767 - /* Should not happen ! */  
768 - fprintf(stderr, "RESET asked... Stop emulation\n");  
769 - if (loglevel)  
770 - fprintf(logfile, "RESET asked... Stop emulation\n");  
771 - abort();  
772 - case EXCP_MACHINE_CHECK:  
773 - fprintf(stderr, "Machine check exeption... Stop emulation\n");  
774 - if (loglevel)  
775 - fprintf(logfile, "Machine check exception. Stop emulation\n");  
776 - info.si_signo = TARGET_SIGBUS;  
777 - info.si_errno = 0;  
778 - info.si_code = TARGET_BUS_OBJERR;  
779 - info._sifields._sigfault._addr = env->nip - 4;  
780 - queue_signal(info.si_signo, &info);  
781 - case EXCP_DSI:  
782 - fprintf(stderr, "Invalid data memory access: 0x" ADDRX "\n",  
783 - env->spr[SPR_DAR]);  
784 - if (loglevel) {  
785 - fprintf(logfile, "Invalid data memory access: 0x" ADDRX "\n",  
786 - env->spr[SPR_DAR]);  
787 - } 752 + case POWERPC_EXCP_MCHECK: /* Machine check exception */
  753 + cpu_abort(env, "Machine check exception while in user mode. "
  754 + "Aborting\n");
  755 + break;
  756 + case POWERPC_EXCP_DSI: /* Data storage exception */
  757 + EXCP_DUMP(env, "Invalid data memory access: 0x" ADDRX "\n",
  758 + env->spr[SPR_DAR]);
  759 + /* XXX: check this. Seems bugged */
788 switch (env->error_code & 0xFF000000) { 760 switch (env->error_code & 0xFF000000) {
789 case 0x40000000: 761 case 0x40000000:
790 info.si_signo = TARGET_SIGSEGV; 762 info.si_signo = TARGET_SIGSEGV;
@@ -803,12 +775,8 @@ void cpu_loop(CPUPPCState *env) @@ -803,12 +775,8 @@ void cpu_loop(CPUPPCState *env)
803 break; 775 break;
804 default: 776 default:
805 /* Let's send a regular segfault... */ 777 /* Let's send a regular segfault... */
806 - fprintf(stderr, "Invalid segfault errno (%02x)\n",  
807 - env->error_code);  
808 - if (loglevel) {  
809 - fprintf(logfile, "Invalid segfault errno (%02x)\n",  
810 - env->error_code);  
811 - } 778 + EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
  779 + env->error_code);
812 info.si_signo = TARGET_SIGSEGV; 780 info.si_signo = TARGET_SIGSEGV;
813 info.si_errno = 0; 781 info.si_errno = 0;
814 info.si_code = TARGET_SEGV_MAPERR; 782 info.si_code = TARGET_SEGV_MAPERR;
@@ -817,10 +785,10 @@ void cpu_loop(CPUPPCState *env) @@ -817,10 +785,10 @@ void cpu_loop(CPUPPCState *env)
817 info._sifields._sigfault._addr = env->nip; 785 info._sifields._sigfault._addr = env->nip;
818 queue_signal(info.si_signo, &info); 786 queue_signal(info.si_signo, &info);
819 break; 787 break;
820 - case EXCP_ISI:  
821 - fprintf(stderr, "Invalid instruction fetch\n");  
822 - if (loglevel)  
823 - fprintf(logfile, "Invalid instruction fetch\n"); 788 + case POWERPC_EXCP_ISI: /* Instruction storage exception */
  789 + EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" ADDRX "\n",
  790 + env->spr[SPR_DAR]);
  791 + /* XXX: check this */
824 switch (env->error_code & 0xFF000000) { 792 switch (env->error_code & 0xFF000000) {
825 case 0x40000000: 793 case 0x40000000:
826 info.si_signo = TARGET_SIGSEGV; 794 info.si_signo = TARGET_SIGSEGV;
@@ -835,12 +803,8 @@ void cpu_loop(CPUPPCState *env) @@ -835,12 +803,8 @@ void cpu_loop(CPUPPCState *env)
835 break; 803 break;
836 default: 804 default:
837 /* Let's send a regular segfault... */ 805 /* Let's send a regular segfault... */
838 - fprintf(stderr, "Invalid segfault errno (%02x)\n",  
839 - env->error_code);  
840 - if (loglevel) {  
841 - fprintf(logfile, "Invalid segfault errno (%02x)\n",  
842 - env->error_code);  
843 - } 806 + EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",
  807 + env->error_code);
844 info.si_signo = TARGET_SIGSEGV; 808 info.si_signo = TARGET_SIGSEGV;
845 info.si_errno = 0; 809 info.si_errno = 0;
846 info.si_code = TARGET_SEGV_MAPERR; 810 info.si_code = TARGET_SEGV_MAPERR;
@@ -849,28 +813,24 @@ void cpu_loop(CPUPPCState *env) @@ -849,28 +813,24 @@ void cpu_loop(CPUPPCState *env)
849 info._sifields._sigfault._addr = env->nip - 4; 813 info._sifields._sigfault._addr = env->nip - 4;
850 queue_signal(info.si_signo, &info); 814 queue_signal(info.si_signo, &info);
851 break; 815 break;
852 - case EXCP_EXTERNAL:  
853 - /* Should not happen ! */  
854 - fprintf(stderr, "External interruption... Stop emulation\n");  
855 - if (loglevel)  
856 - fprintf(logfile, "External interruption... Stop emulation\n");  
857 - abort();  
858 - case EXCP_ALIGN:  
859 - fprintf(stderr, "Invalid unaligned memory access\n");  
860 - if (loglevel)  
861 - fprintf(logfile, "Invalid unaligned memory access\n"); 816 + case POWERPC_EXCP_EXTERNAL: /* External input */
  817 + cpu_abort(env, "External interrupt while in user mode. "
  818 + "Aborting\n");
  819 + break;
  820 + case POWERPC_EXCP_ALIGN: /* Alignment exception */
  821 + EXCP_DUMP(env, "Unaligned memory access\n");
  822 + /* XXX: check this */
862 info.si_signo = TARGET_SIGBUS; 823 info.si_signo = TARGET_SIGBUS;
863 info.si_errno = 0; 824 info.si_errno = 0;
864 info.si_code = TARGET_BUS_ADRALN; 825 info.si_code = TARGET_BUS_ADRALN;
865 info._sifields._sigfault._addr = env->nip - 4; 826 info._sifields._sigfault._addr = env->nip - 4;
866 queue_signal(info.si_signo, &info); 827 queue_signal(info.si_signo, &info);
867 break; 828 break;
868 - case EXCP_PROGRAM: 829 + case POWERPC_EXCP_PROGRAM: /* Program exception */
  830 + /* XXX: check this */
869 switch (env->error_code & ~0xF) { 831 switch (env->error_code & ~0xF) {
870 - case EXCP_FP:  
871 - fprintf(stderr, "Program exception\n");  
872 - if (loglevel)  
873 - fprintf(logfile, "Program exception\n"); 832 + case POWERPC_EXCP_FP:
  833 + EXCP_DUMP(env, "Floating point program exception\n");
874 /* Set FX */ 834 /* Set FX */
875 env->fpscr[7] |= 0x8; 835 env->fpscr[7] |= 0x8;
876 /* Finally, update FEX */ 836 /* Finally, update FEX */
@@ -880,155 +840,138 @@ void cpu_loop(CPUPPCState *env) @@ -880,155 +840,138 @@ void cpu_loop(CPUPPCState *env)
880 info.si_signo = TARGET_SIGFPE; 840 info.si_signo = TARGET_SIGFPE;
881 info.si_errno = 0; 841 info.si_errno = 0;
882 switch (env->error_code & 0xF) { 842 switch (env->error_code & 0xF) {
883 - case EXCP_FP_OX: 843 + case POWERPC_EXCP_FP_OX:
884 info.si_code = TARGET_FPE_FLTOVF; 844 info.si_code = TARGET_FPE_FLTOVF;
885 break; 845 break;
886 - case EXCP_FP_UX: 846 + case POWERPC_EXCP_FP_UX:
887 info.si_code = TARGET_FPE_FLTUND; 847 info.si_code = TARGET_FPE_FLTUND;
888 break; 848 break;
889 - case EXCP_FP_ZX:  
890 - case EXCP_FP_VXZDZ: 849 + case POWERPC_EXCP_FP_ZX:
  850 + case POWERPC_EXCP_FP_VXZDZ:
891 info.si_code = TARGET_FPE_FLTDIV; 851 info.si_code = TARGET_FPE_FLTDIV;
892 break; 852 break;
893 - case EXCP_FP_XX: 853 + case POWERPC_EXCP_FP_XX:
894 info.si_code = TARGET_FPE_FLTRES; 854 info.si_code = TARGET_FPE_FLTRES;
895 break; 855 break;
896 - case EXCP_FP_VXSOFT: 856 + case POWERPC_EXCP_FP_VXSOFT:
897 info.si_code = TARGET_FPE_FLTINV; 857 info.si_code = TARGET_FPE_FLTINV;
898 break; 858 break;
899 - case EXCP_FP_VXNAN:  
900 - case EXCP_FP_VXISI:  
901 - case EXCP_FP_VXIDI:  
902 - case EXCP_FP_VXIMZ:  
903 - case EXCP_FP_VXVC:  
904 - case EXCP_FP_VXSQRT:  
905 - case EXCP_FP_VXCVI: 859 + case POWERPC_EXCP_FP_VXNAN:
  860 + case POWERPC_EXCP_FP_VXISI:
  861 + case POWERPC_EXCP_FP_VXIDI:
  862 + case POWERPC_EXCP_FP_VXIMZ:
  863 + case POWERPC_EXCP_FP_VXVC:
  864 + case POWERPC_EXCP_FP_VXSQRT:
  865 + case POWERPC_EXCP_FP_VXCVI:
906 info.si_code = TARGET_FPE_FLTSUB; 866 info.si_code = TARGET_FPE_FLTSUB;
907 break; 867 break;
908 default: 868 default:
909 - fprintf(stderr, "Unknown floating point exception "  
910 - "(%02x)\n", env->error_code);  
911 - if (loglevel) {  
912 - fprintf(logfile, "Unknown floating point exception "  
913 - "(%02x)\n", env->error_code & 0xF);  
914 - } 869 + EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",
  870 + env->error_code);
  871 + break;
915 } 872 }
916 - break;  
917 - case EXCP_INVAL:  
918 - fprintf(stderr, "Invalid instruction\n");  
919 - if (loglevel)  
920 - fprintf(logfile, "Invalid instruction\n"); 873 + break;
  874 + case POWERPC_EXCP_INVAL:
  875 + EXCP_DUMP(env, "Invalid instruction\n");
921 info.si_signo = TARGET_SIGILL; 876 info.si_signo = TARGET_SIGILL;
922 info.si_errno = 0; 877 info.si_errno = 0;
923 switch (env->error_code & 0xF) { 878 switch (env->error_code & 0xF) {
924 - case EXCP_INVAL_INVAL: 879 + case POWERPC_EXCP_INVAL_INVAL:
925 info.si_code = TARGET_ILL_ILLOPC; 880 info.si_code = TARGET_ILL_ILLOPC;
926 break; 881 break;
927 - case EXCP_INVAL_LSWX: 882 + case POWERPC_EXCP_INVAL_LSWX:
928 info.si_code = TARGET_ILL_ILLOPN; 883 info.si_code = TARGET_ILL_ILLOPN;
929 break; 884 break;
930 - case EXCP_INVAL_SPR: 885 + case POWERPC_EXCP_INVAL_SPR:
931 info.si_code = TARGET_ILL_PRVREG; 886 info.si_code = TARGET_ILL_PRVREG;
932 break; 887 break;
933 - case EXCP_INVAL_FP: 888 + case POWERPC_EXCP_INVAL_FP:
934 info.si_code = TARGET_ILL_COPROC; 889 info.si_code = TARGET_ILL_COPROC;
935 break; 890 break;
936 default: 891 default:
937 - fprintf(stderr, "Unknown invalid operation (%02x)\n",  
938 - env->error_code & 0xF);  
939 - if (loglevel) {  
940 - fprintf(logfile, "Unknown invalid operation (%02x)\n",  
941 - env->error_code & 0xF);  
942 - } 892 + EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",
  893 + env->error_code & 0xF);
943 info.si_code = TARGET_ILL_ILLADR; 894 info.si_code = TARGET_ILL_ILLADR;
944 break; 895 break;
945 } 896 }
946 break; 897 break;
947 - case EXCP_PRIV:  
948 - fprintf(stderr, "Privilege violation\n");  
949 - if (loglevel)  
950 - fprintf(logfile, "Privilege violation\n"); 898 + case POWERPC_EXCP_PRIV:
  899 + EXCP_DUMP(env, "Privilege violation\n");
951 info.si_signo = TARGET_SIGILL; 900 info.si_signo = TARGET_SIGILL;
952 info.si_errno = 0; 901 info.si_errno = 0;
953 switch (env->error_code & 0xF) { 902 switch (env->error_code & 0xF) {
954 - case EXCP_PRIV_OPC: 903 + case POWERPC_EXCP_PRIV_OPC:
955 info.si_code = TARGET_ILL_PRVOPC; 904 info.si_code = TARGET_ILL_PRVOPC;
956 break; 905 break;
957 - case EXCP_PRIV_REG: 906 + case POWERPC_EXCP_PRIV_REG:
958 info.si_code = TARGET_ILL_PRVREG; 907 info.si_code = TARGET_ILL_PRVREG;
959 - break; 908 + break;
960 default: 909 default:
961 - fprintf(stderr, "Unknown privilege violation (%02x)\n",  
962 - env->error_code & 0xF); 910 + EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",
  911 + env->error_code & 0xF);
963 info.si_code = TARGET_ILL_PRVOPC; 912 info.si_code = TARGET_ILL_PRVOPC;
964 break; 913 break;
965 } 914 }
966 break; 915 break;
967 - case EXCP_TRAP:  
968 - fprintf(stderr, "Tried to call a TRAP\n");  
969 - if (loglevel)  
970 - fprintf(logfile, "Tried to call a TRAP\n");  
971 - abort(); 916 + case POWERPC_EXCP_TRAP:
  917 + cpu_abort(env, "Tried to call a TRAP\n");
  918 + break;
972 default: 919 default:
973 /* Should not happen ! */ 920 /* Should not happen ! */
974 - fprintf(stderr, "Unknown program exception (%02x)\n",  
975 - env->error_code);  
976 - if (loglevel) {  
977 - fprintf(logfile, "Unknwon program exception (%02x)\n",  
978 - env->error_code);  
979 - }  
980 - abort(); 921 + cpu_abort(env, "Unknown program exception (%02x)\n",
  922 + env->error_code);
  923 + break;
981 } 924 }
982 info._sifields._sigfault._addr = env->nip - 4; 925 info._sifields._sigfault._addr = env->nip - 4;
983 queue_signal(info.si_signo, &info); 926 queue_signal(info.si_signo, &info);
984 break; 927 break;
985 - case EXCP_NO_FP:  
986 - fprintf(stderr, "No floating point allowed\n");  
987 - if (loglevel)  
988 - fprintf(logfile, "No floating point allowed\n"); 928 + case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
  929 + EXCP_DUMP(env, "No floating point allowed\n");
989 info.si_signo = TARGET_SIGILL; 930 info.si_signo = TARGET_SIGILL;
990 info.si_errno = 0; 931 info.si_errno = 0;
991 info.si_code = TARGET_ILL_COPROC; 932 info.si_code = TARGET_ILL_COPROC;
992 info._sifields._sigfault._addr = env->nip - 4; 933 info._sifields._sigfault._addr = env->nip - 4;
993 queue_signal(info.si_signo, &info); 934 queue_signal(info.si_signo, &info);
994 break; 935 break;
995 - case EXCP_DECR:  
996 - /* Should not happen ! */  
997 - fprintf(stderr, "Decrementer exception\n");  
998 - if (loglevel)  
999 - fprintf(logfile, "Decrementer exception\n");  
1000 - abort();  
1001 - case EXCP_TRACE:  
1002 - /* Do nothing: we use this to trace execution */  
1003 - break;  
1004 - case EXCP_FP_ASSIST:  
1005 - /* Should not happen ! */  
1006 - fprintf(stderr, "Floating point assist exception\n");  
1007 - if (loglevel)  
1008 - fprintf(logfile, "Floating point assist exception\n");  
1009 - abort();  
1010 - case EXCP_MTMSR:  
1011 - /* We reloaded the msr, just go on */  
1012 - if (msr_pr == 0) {  
1013 - fprintf(stderr, "Tried to go into supervisor mode !\n");  
1014 - if (loglevel)  
1015 - fprintf(logfile, "Tried to go into supervisor mode !\n");  
1016 - abort();  
1017 - } 936 + case POWERPC_EXCP_SYSCALL: /* System call exception */
  937 + cpu_abort(env, "Syscall exception while in user mode. "
  938 + "Aborting\n");
1018 break; 939 break;
1019 - case EXCP_BRANCH:  
1020 - /* We stopped because of a jump... */ 940 + case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
  941 + EXCP_DUMP(env, "No APU instruction allowed\n");
  942 + info.si_signo = TARGET_SIGILL;
  943 + info.si_errno = 0;
  944 + info.si_code = TARGET_ILL_COPROC;
  945 + info._sifields._sigfault._addr = env->nip - 4;
  946 + queue_signal(info.si_signo, &info);
1021 break; 947 break;
1022 - case EXCP_INTERRUPT:  
1023 - /* Don't know why this should ever happen... */ 948 + case POWERPC_EXCP_DECR: /* Decrementer exception */
  949 + cpu_abort(env, "Decrementer interrupt while in user mode. "
  950 + "Aborting\n");
1024 break; 951 break;
1025 - case EXCP_DEBUG: 952 + case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
  953 + cpu_abort(env, "Fix interval timer interrupt while in user mode. "
  954 + "Aborting\n");
  955 + break;
  956 + case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
  957 + cpu_abort(env, "Watchdog timer interrupt while in user mode. "
  958 + "Aborting\n");
  959 + break;
  960 + case POWERPC_EXCP_DTLB: /* Data TLB error */
  961 + cpu_abort(env, "Data TLB exception while in user mode. "
  962 + "Aborting\n");
  963 + break;
  964 + case POWERPC_EXCP_ITLB: /* Instruction TLB error */
  965 + cpu_abort(env, "Instruction TLB exception while in user mode. "
  966 + "Aborting\n");
  967 + break;
  968 + case POWERPC_EXCP_DEBUG: /* Debug interrupt */
  969 + /* XXX: check this */
1026 { 970 {
1027 int sig; 971 int sig;
1028 972
1029 - sig = gdb_handlesig (env, TARGET_SIGTRAP);  
1030 - if (sig)  
1031 - { 973 + sig = gdb_handlesig(env, TARGET_SIGTRAP);
  974 + if (sig) {
1032 info.si_signo = sig; 975 info.si_signo = sig;
1033 info.si_errno = 0; 976 info.si_errno = 0;
1034 info.si_code = TARGET_TRAP_BRKPT; 977 info.si_code = TARGET_TRAP_BRKPT;
@@ -1036,14 +979,171 @@ void cpu_loop(CPUPPCState *env) @@ -1036,14 +979,171 @@ void cpu_loop(CPUPPCState *env)
1036 } 979 }
1037 } 980 }
1038 break; 981 break;
1039 - default:  
1040 - fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",  
1041 - trapnr);  
1042 - if (loglevel) {  
1043 - fprintf(logfile, "qemu: unhandled CPU exception 0x%02x - "  
1044 - "0x%02x - aborting\n", trapnr, env->error_code); 982 +#if defined(TARGET_PPCEMB)
  983 + case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */
  984 + EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
  985 + info.si_signo = TARGET_SIGILL;
  986 + info.si_errno = 0;
  987 + info.si_code = TARGET_ILL_COPROC;
  988 + info._sifields._sigfault._addr = env->nip - 4;
  989 + queue_signal(info.si_signo, &info);
  990 + break;
  991 + case POWERPC_EXCP_EFPDI: /* Embedded floating-point data IRQ */
  992 + cpu_abort(env, "Embedded floating-point data IRQ not handled\n");
  993 + break;
  994 + case POWERPC_EXCP_EFPRI: /* Embedded floating-point round IRQ */
  995 + cpu_abort(env, "Embedded floating-point round IRQ not handled\n");
  996 + break;
  997 + case POWERPC_EXCP_EPERFM: /* Embedded performance monitor IRQ */
  998 + cpu_abort(env, "Performance monitor exception not handled\n");
  999 + break;
  1000 + case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
  1001 + cpu_abort(env, "Doorbell interrupt while in user mode. "
  1002 + "Aborting\n");
  1003 + break;
  1004 + case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
  1005 + cpu_abort(env, "Doorbell critical interrupt while in user mode. "
  1006 + "Aborting\n");
  1007 + break;
  1008 + case POWERPC_EXCP_RESET: /* System reset exception */
  1009 + cpu_abort(env, "Reset interrupt while in user mode. "
  1010 + "Aborting\n");
  1011 + break;
  1012 +#endif /* defined(TARGET_PPCEMB) */
  1013 +#if defined(TARGET_PPC64) /* PowerPC 64 */
  1014 + case POWERPC_EXCP_DSEG: /* Data segment exception */
  1015 + cpu_abort(env, "Data segment exception while in user mode. "
  1016 + "Aborting\n");
  1017 + break;
  1018 + case POWERPC_EXCP_ISEG: /* Instruction segment exception */
  1019 + cpu_abort(env, "Instruction segment exception "
  1020 + "while in user mode. Aborting\n");
  1021 + break;
  1022 +#endif /* defined(TARGET_PPC64) */
  1023 +#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
  1024 + case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
  1025 + cpu_abort(env, "Hypervisor decrementer interrupt "
  1026 + "while in user mode. Aborting\n");
  1027 + break;
  1028 +#endif /* defined(TARGET_PPC64H) */
  1029 + case POWERPC_EXCP_TRACE: /* Trace exception */
  1030 + /* Nothing to do:
  1031 + * we use this exception to emulate step-by-step execution mode.
  1032 + */
  1033 + break;
  1034 +#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
  1035 + case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
  1036 + cpu_abort(env, "Hypervisor data storage exception "
  1037 + "while in user mode. Aborting\n");
  1038 + break;
  1039 + case POWERPC_EXCP_HISI: /* Hypervisor instruction storage excp */
  1040 + cpu_abort(env, "Hypervisor instruction storage exception "
  1041 + "while in user mode. Aborting\n");
  1042 + break;
  1043 + case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
  1044 + cpu_abort(env, "Hypervisor data segment exception "
  1045 + "while in user mode. Aborting\n");
  1046 + break;
  1047 + case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment excp */
  1048 + cpu_abort(env, "Hypervisor instruction segment exception "
  1049 + "while in user mode. Aborting\n");
  1050 + break;
  1051 +#endif /* defined(TARGET_PPC64H) */
  1052 + case POWERPC_EXCP_VPU: /* Vector unavailable exception */
  1053 + EXCP_DUMP(env, "No Altivec instructions allowed\n");
  1054 + info.si_signo = TARGET_SIGILL;
  1055 + info.si_errno = 0;
  1056 + info.si_code = TARGET_ILL_COPROC;
  1057 + info._sifields._sigfault._addr = env->nip - 4;
  1058 + queue_signal(info.si_signo, &info);
  1059 + break;
  1060 + case POWERPC_EXCP_PIT: /* Programmable interval timer IRQ */
  1061 + cpu_abort(env, "Programable interval timer interrupt "
  1062 + "while in user mode. Aborting\n");
  1063 + break;
  1064 + case POWERPC_EXCP_IO: /* IO error exception */
  1065 + cpu_abort(env, "IO error exception while in user mode. "
  1066 + "Aborting\n");
  1067 + break;
  1068 + case POWERPC_EXCP_RUNM: /* Run mode exception */
  1069 + cpu_abort(env, "Run mode exception while in user mode. "
  1070 + "Aborting\n");
  1071 + break;
  1072 + case POWERPC_EXCP_EMUL: /* Emulation trap exception */
  1073 + cpu_abort(env, "Emulation trap exception not handled\n");
  1074 + break;
  1075 + case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
  1076 + cpu_abort(env, "Instruction fetch TLB exception "
  1077 + "while in user-mode. Aborting");
  1078 + break;
  1079 + case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
  1080 + cpu_abort(env, "Data load TLB exception while in user-mode. "
  1081 + "Aborting");
  1082 + break;
  1083 + case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
  1084 + cpu_abort(env, "Data store TLB exception while in user-mode. "
  1085 + "Aborting");
  1086 + break;
  1087 + case POWERPC_EXCP_FPA: /* Floating-point assist exception */
  1088 + cpu_abort(env, "Floating-point assist exception not handled\n");
  1089 + break;
  1090 + case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
  1091 + cpu_abort(env, "Instruction address breakpoint exception "
  1092 + "not handled\n");
  1093 + break;
  1094 + case POWERPC_EXCP_SMI: /* System management interrupt */
  1095 + cpu_abort(env, "System management interrupt while in user mode. "
  1096 + "Aborting\n");
  1097 + break;
  1098 + case POWERPC_EXCP_THERM: /* Thermal interrupt */
  1099 + cpu_abort(env, "Thermal interrupt interrupt while in user mode. "
  1100 + "Aborting\n");
  1101 + break;
  1102 + case POWERPC_EXCP_PERFM: /* Embedded performance monitor IRQ */
  1103 + cpu_abort(env, "Performance monitor exception not handled\n");
  1104 + break;
  1105 + case POWERPC_EXCP_VPUA: /* Vector assist exception */
  1106 + cpu_abort(env, "Vector assist exception not handled\n");
  1107 + break;
  1108 + case POWERPC_EXCP_SOFTP: /* Soft patch exception */
  1109 + cpu_abort(env, "Soft patch exception not handled\n");
  1110 + break;
  1111 + case POWERPC_EXCP_MAINT: /* Maintenance exception */
  1112 + cpu_abort(env, "Maintenance exception while in user mode. "
  1113 + "Aborting\n");
  1114 + break;
  1115 + case POWERPC_EXCP_STOP: /* stop translation */
  1116 + /* We did invalidate the instruction cache. Go on */
  1117 + break;
  1118 + case POWERPC_EXCP_BRANCH: /* branch instruction: */
  1119 + /* We just stopped because of a branch. Go on */
  1120 + break;
  1121 + case POWERPC_EXCP_SYSCALL_USER:
  1122 + /* system call in user-mode emulation */
  1123 + /* WARNING:
  1124 + * PPC ABI uses overflow flag in cr0 to signal an error
  1125 + * in syscalls.
  1126 + */
  1127 +#if 0
  1128 + printf("syscall %d 0x%08x 0x%08x 0x%08x 0x%08x\n", env->gpr[0],
  1129 + env->gpr[3], env->gpr[4], env->gpr[5], env->gpr[6]);
  1130 +#endif
  1131 + env->crf[0] &= ~0x1;
  1132 + ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
  1133 + env->gpr[5], env->gpr[6], env->gpr[7],
  1134 + env->gpr[8]);
  1135 + if (ret > (uint32_t)(-515)) {
  1136 + env->crf[0] |= 0x1;
  1137 + ret = -ret;
1045 } 1138 }
1046 - abort(); 1139 + env->gpr[3] = ret;
  1140 +#if 0
  1141 + printf("syscall returned 0x%08x (%d)\n", ret, ret);
  1142 +#endif
  1143 + break;
  1144 + default:
  1145 + cpu_abort(env, "Unknown exception 0x%d. Aborting\n", trapnr);
  1146 + break;
1047 } 1147 }
1048 process_pending_signals(env); 1148 process_pending_signals(env);
1049 } 1149 }
target-ppc/cpu.h
@@ -149,6 +149,127 @@ enum { @@ -149,6 +149,127 @@ enum {
149 }; 149 };
150 150
151 /*****************************************************************************/ 151 /*****************************************************************************/
  152 +/* Exception vectors definitions */
  153 +enum {
  154 + POWERPC_EXCP_NONE = -1,
  155 + /* The 64 first entries are used by the PowerPC embedded specification */
  156 + POWERPC_EXCP_CRITICAL = 0, /* Critical input */
  157 + POWERPC_EXCP_MCHECK = 1, /* Machine check exception */
  158 + POWERPC_EXCP_DSI = 2, /* Data storage exception */
  159 + POWERPC_EXCP_ISI = 3, /* Instruction storage exception */
  160 + POWERPC_EXCP_EXTERNAL = 4, /* External input */
  161 + POWERPC_EXCP_ALIGN = 5, /* Alignment exception */
  162 + POWERPC_EXCP_PROGRAM = 6, /* Program exception */
  163 + POWERPC_EXCP_FPU = 7, /* Floating-point unavailable exception */
  164 + POWERPC_EXCP_SYSCALL = 8, /* System call exception */
  165 + POWERPC_EXCP_APU = 9, /* Auxiliary processor unavailable */
  166 + POWERPC_EXCP_DECR = 10, /* Decrementer exception */
  167 + POWERPC_EXCP_FIT = 11, /* Fixed-interval timer interrupt */
  168 + POWERPC_EXCP_WDT = 12, /* Watchdog timer interrupt */
  169 + POWERPC_EXCP_DTLB = 13, /* Data TLB error */
  170 + POWERPC_EXCP_ITLB = 14, /* Instruction TLB error */
  171 + POWERPC_EXCP_DEBUG = 15, /* Debug interrupt */
  172 + /* Vectors 16 to 31 are reserved */
  173 +#if defined(TARGET_PPCEMB)
  174 + POWERPC_EXCP_SPEU = 32, /* SPE/embedded floating-point unavailable */
  175 + POWERPC_EXCP_EFPDI = 33, /* Embedded floating-point data interrupt */
  176 + POWERPC_EXCP_EFPRI = 34, /* Embedded floating-point round interrupt */
  177 + POWERPC_EXCP_EPERFM = 35, /* Embedded performance monitor interrupt */
  178 + POWERPC_EXCP_DOORI = 36, /* Embedded doorbell interrupt */
  179 + POWERPC_EXCP_DOORCI = 37, /* Embedded doorbell critical interrupt */
  180 +#endif /* defined(TARGET_PPCEMB) */
  181 + /* Vectors 38 to 63 are reserved */
  182 + /* Exceptions defined in the PowerPC server specification */
  183 + POWERPC_EXCP_RESET = 64, /* System reset exception */
  184 +#if defined(TARGET_PPC64) /* PowerPC 64 */
  185 + POWERPC_EXCP_DSEG = 65, /* Data segment exception */
  186 + POWERPC_EXCP_ISEG = 66, /* Instruction segment exception */
  187 +#endif /* defined(TARGET_PPC64) */
  188 +#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
  189 + POWERPC_EXCP_HDECR = 67, /* Hypervisor decrementer exception */
  190 +#endif /* defined(TARGET_PPC64H) */
  191 + POWERPC_EXCP_TRACE = 68, /* Trace exception */
  192 +#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
  193 + POWERPC_EXCP_HDSI = 69, /* Hypervisor data storage exception */
  194 + POWERPC_EXCP_HISI = 70, /* Hypervisor instruction storage exception */
  195 + POWERPC_EXCP_HDSEG = 71, /* Hypervisor data segment exception */
  196 + POWERPC_EXCP_HISEG = 72, /* Hypervisor instruction segment exception */
  197 +#endif /* defined(TARGET_PPC64H) */
  198 + POWERPC_EXCP_VPU = 73, /* Vector unavailable exception */
  199 + /* 40x specific exceptions */
  200 + POWERPC_EXCP_PIT = 74, /* Programmable interval timer interrupt */
  201 + /* 601 specific exceptions */
  202 + POWERPC_EXCP_IO = 75, /* IO error exception */
  203 + POWERPC_EXCP_RUNM = 76, /* Run mode exception */
  204 + /* 602 specific exceptions */
  205 + POWERPC_EXCP_EMUL = 77, /* Emulation trap exception */
  206 + /* 602/603 specific exceptions */
  207 + POWERPC_EXCP_IFTLB = 78, /* Instruction fetch TLB error */
  208 + POWERPC_EXCP_DLTLB = 79, /* Data load TLB miss */
  209 + POWERPC_EXCP_DSTLB = 80, /* Data store TLB miss */
  210 + /* Exceptions available on most PowerPC */
  211 + POWERPC_EXCP_FPA = 81, /* Floating-point assist exception */
  212 + POWERPC_EXCP_IABR = 82, /* Instruction address breakpoint */
  213 + POWERPC_EXCP_SMI = 83, /* System management interrupt */
  214 + POWERPC_EXCP_PERFM = 84, /* Embedded performance monitor interrupt */
  215 + /* 7xx/74xx specific exceptions */
  216 + POWERPC_EXCP_THERM = 85, /* Thermal interrupt */
  217 + /* 74xx specific exceptions */
  218 + POWERPC_EXCP_VPUA = 86, /* Vector assist exception */
  219 + /* 970FX specific exceptions */
  220 + POWERPC_EXCP_SOFTP = 87, /* Soft patch exception */
  221 + POWERPC_EXCP_MAINT = 88, /* Maintenance exception */
  222 + /* EOL */
  223 + POWERPC_EXCP_NB = 96,
  224 + /* Qemu exceptions: used internally during code translation */
  225 + POWERPC_EXCP_STOP = 0x200, /* stop translation */
  226 + POWERPC_EXCP_BRANCH = 0x201, /* branch instruction */
  227 + /* Qemu exceptions: special cases we want to stop translation */
  228 + POWERPC_EXCP_SYNC = 0x202, /* context synchronizing instruction */
  229 + POWERPC_EXCP_SYSCALL_USER = 0x203, /* System call in user mode only */
  230 +};
  231 +
  232 +
  233 +/* Exceptions error codes */
  234 +enum {
  235 + /* Exception subtypes for POWERPC_EXCP_ALIGN */
  236 + POWERPC_EXCP_ALIGN_FP = 0x01, /* FP alignment exception */
  237 + POWERPC_EXCP_ALIGN_LST = 0x02, /* Unaligned mult/extern load/store */
  238 + POWERPC_EXCP_ALIGN_LE = 0x03, /* Multiple little-endian access */
  239 + POWERPC_EXCP_ALIGN_PROT = 0x04, /* Access cross protection boundary */
  240 + POWERPC_EXCP_ALIGN_BAT = 0x05, /* Access cross a BAT/seg boundary */
  241 + POWERPC_EXCP_ALIGN_CACHE = 0x06, /* Impossible dcbz access */
  242 + /* Exception subtypes for POWERPC_EXCP_PROGRAM */
  243 + /* FP exceptions */
  244 + POWERPC_EXCP_FP = 0x10,
  245 + POWERPC_EXCP_FP_OX = 0x01, /* FP overflow */
  246 + POWERPC_EXCP_FP_UX = 0x02, /* FP underflow */
  247 + POWERPC_EXCP_FP_ZX = 0x03, /* FP divide by zero */
  248 + POWERPC_EXCP_FP_XX = 0x04, /* FP inexact */
  249 + POWERPC_EXCP_FP_VXNAN = 0x05, /* FP invalid SNaN op */
  250 + POWERPC_EXCP_FP_VXISI = 0x06, /* FP invalid infinite subtraction */
  251 + POWERPC_EXCP_FP_VXIDI = 0x07, /* FP invalid infinite divide */
  252 + POWERPC_EXCP_FP_VXZDZ = 0x08, /* FP invalid zero divide */
  253 + POWERPC_EXCP_FP_VXIMZ = 0x09, /* FP invalid infinite * zero */
  254 + POWERPC_EXCP_FP_VXVC = 0x0A, /* FP invalid compare */
  255 + POWERPC_EXCP_FP_VXSOFT = 0x0B, /* FP invalid operation */
  256 + POWERPC_EXCP_FP_VXSQRT = 0x0C, /* FP invalid square root */
  257 + POWERPC_EXCP_FP_VXCVI = 0x0D, /* FP invalid integer conversion */
  258 + /* Invalid instruction */
  259 + POWERPC_EXCP_INVAL = 0x20,
  260 + POWERPC_EXCP_INVAL_INVAL = 0x01, /* Invalid instruction */
  261 + POWERPC_EXCP_INVAL_LSWX = 0x02, /* Invalid lswx instruction */
  262 + POWERPC_EXCP_INVAL_SPR = 0x03, /* Invalid SPR access */
  263 + POWERPC_EXCP_INVAL_FP = 0x04, /* Unimplemented mandatory fp instr */
  264 + /* Privileged instruction */
  265 + POWERPC_EXCP_PRIV = 0x30,
  266 + POWERPC_EXCP_PRIV_OPC = 0x01, /* Privileged operation exception */
  267 + POWERPC_EXCP_PRIV_REG = 0x02, /* Privileged register exception */
  268 + /* Trap */
  269 + POWERPC_EXCP_TRAP = 0x40,
  270 +};
  271 +
  272 +/*****************************************************************************/
152 /* Input pins model */ 273 /* Input pins model */
153 enum { 274 enum {
154 PPC_FLAGS_INPUT_UNKNOWN = 0, 275 PPC_FLAGS_INPUT_UNKNOWN = 0,
@@ -411,6 +532,11 @@ struct CPUPPCState { @@ -411,6 +532,11 @@ struct CPUPPCState {
411 */ 532 */
412 uint32_t irq_input_state; 533 uint32_t irq_input_state;
413 void **irq_inputs; 534 void **irq_inputs;
  535 + /* Exception vectors */
  536 + target_ulong excp_vectors[POWERPC_EXCP_NB];
  537 + target_ulong excp_prefix;
  538 + target_ulong ivor_mask;
  539 + target_ulong ivpr_mask;
414 #endif 540 #endif
415 541
416 /* Those resources are used only during code translation */ 542 /* Those resources are used only during code translation */
@@ -634,9 +760,9 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val); @@ -634,9 +760,9 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, target_ulong val);
634 #define SPR_BOOKE_IAC1 (0x138) 760 #define SPR_BOOKE_IAC1 (0x138)
635 #define SPR_HRMOR (0x139) 761 #define SPR_HRMOR (0x139)
636 #define SPR_BOOKE_IAC2 (0x139) 762 #define SPR_BOOKE_IAC2 (0x139)
637 -#define SPR_HSSR0 (0x13A) 763 +#define SPR_HSRR0 (0x13A)
638 #define SPR_BOOKE_IAC3 (0x13A) 764 #define SPR_BOOKE_IAC3 (0x13A)
639 -#define SPR_HSSR1 (0x13B) 765 +#define SPR_HSRR1 (0x13B)
640 #define SPR_BOOKE_IAC4 (0x13B) 766 #define SPR_BOOKE_IAC4 (0x13B)
641 #define SPR_LPCR (0x13C) 767 #define SPR_LPCR (0x13C)
642 #define SPR_BOOKE_DAC1 (0x13C) 768 #define SPR_BOOKE_DAC1 (0x13C)
@@ -948,117 +1074,6 @@ enum { @@ -948,117 +1074,6 @@ enum {
948 ACCESS_CACHE = 0x60, /* Cache manipulation */ 1074 ACCESS_CACHE = 0x60, /* Cache manipulation */
949 }; 1075 };
950 1076
951 -/*****************************************************************************/  
952 -/* Exceptions */  
953 -#define EXCP_NONE -1  
954 -/* PowerPC hardware exceptions : exception vectors defined in PowerPC book 3 */  
955 -#define EXCP_RESET 0x0100 /* System reset */  
956 -#define EXCP_MACHINE_CHECK 0x0200 /* Machine check exception */  
957 -#define EXCP_DSI 0x0300 /* Data storage exception */  
958 -#define EXCP_DSEG 0x0380 /* Data segment exception */  
959 -#define EXCP_ISI 0x0400 /* Instruction storage exception */  
960 -#define EXCP_ISEG 0x0480 /* Instruction segment exception */  
961 -#define EXCP_EXTERNAL 0x0500 /* External interruption */  
962 -#define EXCP_ALIGN 0x0600 /* Alignment exception */  
963 -#define EXCP_PROGRAM 0x0700 /* Program exception */  
964 -#define EXCP_NO_FP 0x0800 /* Floating point unavailable exception */  
965 -#define EXCP_DECR 0x0900 /* Decrementer exception */  
966 -#define EXCP_HDECR 0x0980 /* Hypervisor decrementer exception */  
967 -#define EXCP_SYSCALL 0x0C00 /* System call */  
968 -#define EXCP_TRACE 0x0D00 /* Trace exception */  
969 -#define EXCP_PERF 0x0F00 /* Performance monitor exception */  
970 -/* Exceptions defined in PowerPC 32 bits programming environment manual */  
971 -#define EXCP_FP_ASSIST 0x0E00 /* Floating-point assist */  
972 -/* Implementation specific exceptions */  
973 -/* 40x exceptions */  
974 -#define EXCP_40x_PIT 0x1000 /* Programmable interval timer interrupt */  
975 -#define EXCP_40x_FIT 0x1010 /* Fixed interval timer interrupt */  
976 -#define EXCP_40x_WATCHDOG 0x1020 /* Watchdog timer exception */  
977 -#define EXCP_40x_DTLBMISS 0x1100 /* Data TLB miss exception */  
978 -#define EXCP_40x_ITLBMISS 0x1200 /* Instruction TLB miss exception */  
979 -#define EXCP_40x_DEBUG 0x2000 /* Debug exception */  
980 -/* 405 specific exceptions */  
981 -#define EXCP_405_APU 0x0F20 /* APU unavailable exception */  
982 -/* 440 specific exceptions */  
983 -#define EXCP_440_CRIT 0x0100 /* Critical interrupt */  
984 -#define EXCP_440_SPEU 0x1600 /* SPE unavailable exception */  
985 -#define EXCP_440_SPED 0x1700 /* SPE floating-point data exception */  
986 -#define EXCP_440_SPER 0x1800 /* SPE floating-point round exception */  
987 -/* TLB assist exceptions (602/603) */  
988 -#define EXCP_I_TLBMISS 0x1000 /* Instruction TLB miss */  
989 -#define EXCP_DL_TLBMISS 0x1100 /* Data load TLB miss */  
990 -#define EXCP_DS_TLBMISS 0x1200 /* Data store TLB miss */  
991 -/* Breakpoint exceptions (602/603/604/620/740/745/750/755...) */  
992 -#define EXCP_IABR 0x1300 /* Instruction address breakpoint */  
993 -#define EXCP_SMI 0x1400 /* System management interrupt */  
994 -/* Altivec related exceptions */  
995 -#define EXCP_VPU 0x0F20 /* VPU unavailable exception */  
996 -/* 601 specific exceptions */  
997 -#define EXCP_601_IO 0x0A00 /* IO error exception */  
998 -#define EXCP_601_RUNM 0x2000 /* Run mode exception */  
999 -/* 602 specific exceptions */  
1000 -#define EXCP_602_WATCHDOG 0x1500 /* Watchdog exception */  
1001 -#define EXCP_602_EMUL 0x1600 /* Emulation trap exception */  
1002 -/* G2 specific exceptions */  
1003 -#define EXCP_G2_CRIT 0x0A00 /* Critical interrupt */  
1004 -/* MPC740/745/750 & IBM 750 specific exceptions */  
1005 -#define EXCP_THRM 0x1700 /* Thermal management interrupt */  
1006 -/* 74xx specific exceptions */  
1007 -#define EXCP_74xx_VPUA 0x1600 /* VPU assist exception */  
1008 -/* 970FX specific exceptions */  
1009 -#define EXCP_970_SOFTP 0x1500 /* Soft patch exception */  
1010 -#define EXCP_970_MAINT 0x1600 /* Maintenance exception */  
1011 -#define EXCP_970_THRM 0x1800 /* Thermal exception */  
1012 -#define EXCP_970_VPUA 0x1700 /* VPU assist exception */  
1013 -/* SPE related exceptions */  
1014 -#define EXCP_NO_SPE 0x0F20 /* SPE unavailable exception */  
1015 -/* End of exception vectors area */  
1016 -#define EXCP_PPC_MAX 0x4000  
1017 -/* Qemu exceptions: special cases we want to stop translation */  
1018 -#define EXCP_MTMSR 0x11000 /* mtmsr instruction: */  
1019 - /* may change privilege level */  
1020 -#define EXCP_BRANCH 0x11001 /* branch instruction */  
1021 -#define EXCP_SYSCALL_USER 0x12000 /* System call in user mode only */  
1022 -  
1023 -/* Error codes */  
1024 -enum {  
1025 - /* Exception subtypes for EXCP_ALIGN */  
1026 - EXCP_ALIGN_FP = 0x01, /* FP alignment exception */  
1027 - EXCP_ALIGN_LST = 0x02, /* Unaligned mult/extern load/store */  
1028 - EXCP_ALIGN_LE = 0x03, /* Multiple little-endian access */  
1029 - EXCP_ALIGN_PROT = 0x04, /* Access cross protection boundary */  
1030 - EXCP_ALIGN_BAT = 0x05, /* Access cross a BAT/seg boundary */  
1031 - EXCP_ALIGN_CACHE = 0x06, /* Impossible dcbz access */  
1032 - /* Exception subtypes for EXCP_PROGRAM */  
1033 - /* FP exceptions */  
1034 - EXCP_FP = 0x10,  
1035 - EXCP_FP_OX = 0x01, /* FP overflow */  
1036 - EXCP_FP_UX = 0x02, /* FP underflow */  
1037 - EXCP_FP_ZX = 0x03, /* FP divide by zero */  
1038 - EXCP_FP_XX = 0x04, /* FP inexact */  
1039 - EXCP_FP_VXNAN = 0x05, /* FP invalid SNaN op */  
1040 - EXCP_FP_VXISI = 0x06, /* FP invalid infinite subtraction */  
1041 - EXCP_FP_VXIDI = 0x07, /* FP invalid infinite divide */  
1042 - EXCP_FP_VXZDZ = 0x08, /* FP invalid zero divide */  
1043 - EXCP_FP_VXIMZ = 0x09, /* FP invalid infinite * zero */  
1044 - EXCP_FP_VXVC = 0x0A, /* FP invalid compare */  
1045 - EXCP_FP_VXSOFT = 0x0B, /* FP invalid operation */  
1046 - EXCP_FP_VXSQRT = 0x0C, /* FP invalid square root */  
1047 - EXCP_FP_VXCVI = 0x0D, /* FP invalid integer conversion */  
1048 - /* Invalid instruction */  
1049 - EXCP_INVAL = 0x20,  
1050 - EXCP_INVAL_INVAL = 0x01, /* Invalid instruction */  
1051 - EXCP_INVAL_LSWX = 0x02, /* Invalid lswx instruction */  
1052 - EXCP_INVAL_SPR = 0x03, /* Invalid SPR access */  
1053 - EXCP_INVAL_FP = 0x04, /* Unimplemented mandatory fp instr */  
1054 - /* Privileged instruction */  
1055 - EXCP_PRIV = 0x30,  
1056 - EXCP_PRIV_OPC = 0x01, /* Privileged operation exception */  
1057 - EXCP_PRIV_REG = 0x02, /* Privileged register exception */  
1058 - /* Trap */  
1059 - EXCP_TRAP = 0x40,  
1060 -};  
1061 -  
1062 /* Hardware interruption sources: 1077 /* Hardware interruption sources:
1063 * all those exception can be raised simulteaneously 1078 * all those exception can be raised simulteaneously
1064 */ 1079 */
@@ -1130,19 +1145,22 @@ enum { @@ -1130,19 +1145,22 @@ enum {
1130 /* Hardware exceptions definitions */ 1145 /* Hardware exceptions definitions */
1131 enum { 1146 enum {
1132 /* External hardware exception sources */ 1147 /* External hardware exception sources */
1133 - PPC_INTERRUPT_RESET = 0, /* Reset exception */  
1134 - PPC_INTERRUPT_MCK = 1, /* Machine check exception */  
1135 - PPC_INTERRUPT_EXT = 2, /* External interrupt */  
1136 - PPC_INTERRUPT_SMI = 3, /* System management interrupt */  
1137 - PPC_INTERRUPT_CEXT = 4, /* Critical external interrupt */  
1138 - PPC_INTERRUPT_DEBUG = 5, /* External debug exception */  
1139 - PPC_INTERRUPT_THERM = 6, /* Thermal exception */ 1148 + PPC_INTERRUPT_RESET = 0, /* Reset exception */
  1149 + PPC_INTERRUPT_MCK = 1, /* Machine check exception */
  1150 + PPC_INTERRUPT_EXT = 2, /* External interrupt */
  1151 + PPC_INTERRUPT_SMI = 3, /* System management interrupt */
  1152 + PPC_INTERRUPT_CEXT = 4, /* Critical external interrupt */
  1153 + PPC_INTERRUPT_DEBUG = 5, /* External debug exception */
  1154 + PPC_INTERRUPT_THERM = 6, /* Thermal exception */
1140 /* Internal hardware exception sources */ 1155 /* Internal hardware exception sources */
1141 - PPC_INTERRUPT_DECR = 7, /* Decrementer exception */  
1142 - PPC_INTERRUPT_HDECR = 8, /* Hypervisor decrementer exception */  
1143 - PPC_INTERRUPT_PIT = 9, /* Programmable inteval timer interrupt */  
1144 - PPC_INTERRUPT_FIT = 10, /* Fixed interval timer interrupt */  
1145 - PPC_INTERRUPT_WDT = 11, /* Watchdog timer interrupt */ 1156 + PPC_INTERRUPT_DECR = 7, /* Decrementer exception */
  1157 + PPC_INTERRUPT_HDECR = 8, /* Hypervisor decrementer exception */
  1158 + PPC_INTERRUPT_PIT = 9, /* Programmable inteval timer interrupt */
  1159 + PPC_INTERRUPT_FIT = 10, /* Fixed interval timer interrupt */
  1160 + PPC_INTERRUPT_WDT = 11, /* Watchdog timer interrupt */
  1161 + PPC_INTERRUPT_CDOORBELL = 12, /* Critical doorbell interrupt */
  1162 + PPC_INTERRUPT_DOORBELL = 13, /* Doorbell interrupt */
  1163 + PPC_INTERRUPT_PERFM = 14, /* Performance monitor interrupt */
1146 }; 1164 };
1147 1165
1148 /*****************************************************************************/ 1166 /*****************************************************************************/
target-ppc/helper.c
@@ -44,10 +44,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -44,10 +44,10 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
44 int exception, error_code; 44 int exception, error_code;
45 45
46 if (rw == 2) { 46 if (rw == 2) {
47 - exception = EXCP_ISI; 47 + exception = POWERPC_EXCP_ISI;
48 error_code = 0; 48 error_code = 0;
49 } else { 49 } else {
50 - exception = EXCP_DSI; 50 + exception = POWERPC_EXCP_DSI;
51 error_code = 0; 51 error_code = 0;
52 if (rw) 52 if (rw)
53 error_code |= 0x02000000; 53 error_code |= 0x02000000;
@@ -1128,6 +1128,7 @@ static int check_physical (CPUState *env, mmu_ctx_t *ctx, @@ -1128,6 +1128,7 @@ static int check_physical (CPUState *env, mmu_ctx_t *ctx,
1128 ctx->prot |= PAGE_WRITE; 1128 ctx->prot |= PAGE_WRITE;
1129 } 1129 }
1130 } 1130 }
  1131 + break;
1131 case POWERPC_MMU_BOOKE: 1132 case POWERPC_MMU_BOOKE:
1132 ctx->prot |= PAGE_WRITE; 1133 ctx->prot |= PAGE_WRITE;
1133 break; 1134 break;
@@ -1250,20 +1251,20 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -1250,20 +1251,20 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1250 cpu_dump_state(env, logfile, fprintf, 0); 1251 cpu_dump_state(env, logfile, fprintf, 0);
1251 #endif 1252 #endif
1252 if (access_type == ACCESS_CODE) { 1253 if (access_type == ACCESS_CODE) {
1253 - exception = EXCP_ISI; 1254 + exception = POWERPC_EXCP_ISI;
1254 switch (ret) { 1255 switch (ret) {
1255 case -1: 1256 case -1:
1256 /* No matches in page tables or TLB */ 1257 /* No matches in page tables or TLB */
1257 switch (env->mmu_model) { 1258 switch (env->mmu_model) {
1258 case POWERPC_MMU_SOFT_6xx: 1259 case POWERPC_MMU_SOFT_6xx:
1259 - exception = EXCP_I_TLBMISS; 1260 + exception = POWERPC_EXCP_IFTLB;
1260 env->spr[SPR_IMISS] = address; 1261 env->spr[SPR_IMISS] = address;
1261 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; 1262 env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
1262 error_code = 1 << 18; 1263 error_code = 1 << 18;
1263 goto tlb_miss; 1264 goto tlb_miss;
1264 case POWERPC_MMU_SOFT_4xx: 1265 case POWERPC_MMU_SOFT_4xx:
1265 case POWERPC_MMU_SOFT_4xx_Z: 1266 case POWERPC_MMU_SOFT_4xx_Z:
1266 - exception = EXCP_40x_ITLBMISS; 1267 + exception = POWERPC_EXCP_ITLB;
1267 error_code = 0; 1268 error_code = 0;
1268 env->spr[SPR_40x_DEAR] = address; 1269 env->spr[SPR_40x_DEAR] = address;
1269 env->spr[SPR_40x_ESR] = 0x00000000; 1270 env->spr[SPR_40x_ESR] = 0x00000000;
@@ -1315,24 +1316,26 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -1315,24 +1316,26 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1315 /* No code fetch is allowed in direct-store areas */ 1316 /* No code fetch is allowed in direct-store areas */
1316 error_code = 0x10000000; 1317 error_code = 0x10000000;
1317 break; 1318 break;
  1319 +#if defined(TARGET_PPC64)
1318 case -5: 1320 case -5:
1319 /* No match in segment table */ 1321 /* No match in segment table */
1320 - exception = EXCP_ISEG; 1322 + exception = POWERPC_EXCP_ISEG;
1321 error_code = 0; 1323 error_code = 0;
1322 break; 1324 break;
  1325 +#endif
1323 } 1326 }
1324 } else { 1327 } else {
1325 - exception = EXCP_DSI; 1328 + exception = POWERPC_EXCP_DSI;
1326 switch (ret) { 1329 switch (ret) {
1327 case -1: 1330 case -1:
1328 /* No matches in page tables or TLB */ 1331 /* No matches in page tables or TLB */
1329 switch (env->mmu_model) { 1332 switch (env->mmu_model) {
1330 case POWERPC_MMU_SOFT_6xx: 1333 case POWERPC_MMU_SOFT_6xx:
1331 if (rw == 1) { 1334 if (rw == 1) {
1332 - exception = EXCP_DS_TLBMISS; 1335 + exception = POWERPC_EXCP_DSTLB;
1333 error_code = 1 << 16; 1336 error_code = 1 << 16;
1334 } else { 1337 } else {
1335 - exception = EXCP_DL_TLBMISS; 1338 + exception = POWERPC_EXCP_DLTLB;
1336 error_code = 0; 1339 error_code = 0;
1337 } 1340 }
1338 env->spr[SPR_DMISS] = address; 1341 env->spr[SPR_DMISS] = address;
@@ -1345,7 +1348,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -1345,7 +1348,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1345 goto out; 1348 goto out;
1346 case POWERPC_MMU_SOFT_4xx: 1349 case POWERPC_MMU_SOFT_4xx:
1347 case POWERPC_MMU_SOFT_4xx_Z: 1350 case POWERPC_MMU_SOFT_4xx_Z:
1348 - exception = EXCP_40x_DTLBMISS; 1351 + exception = POWERPC_EXCP_DTLB;
1349 error_code = 0; 1352 error_code = 0;
1350 env->spr[SPR_40x_DEAR] = address; 1353 env->spr[SPR_40x_DEAR] = address;
1351 if (rw) 1354 if (rw)
@@ -1396,8 +1399,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -1396,8 +1399,8 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1396 switch (access_type) { 1399 switch (access_type) {
1397 case ACCESS_FLOAT: 1400 case ACCESS_FLOAT:
1398 /* Floating point load/store */ 1401 /* Floating point load/store */
1399 - exception = EXCP_ALIGN;  
1400 - error_code = EXCP_ALIGN_FP; 1402 + exception = POWERPC_EXCP_ALIGN;
  1403 + error_code = POWERPC_EXCP_ALIGN_FP;
1401 break; 1404 break;
1402 case ACCESS_RES: 1405 case ACCESS_RES:
1403 /* lwarx, ldarx or srwcx. */ 1406 /* lwarx, ldarx or srwcx. */
@@ -1409,18 +1412,20 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -1409,18 +1412,20 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1409 break; 1412 break;
1410 default: 1413 default:
1411 printf("DSI: invalid exception (%d)\n", ret); 1414 printf("DSI: invalid exception (%d)\n", ret);
1412 - exception = EXCP_PROGRAM;  
1413 - error_code = EXCP_INVAL | EXCP_INVAL_INVAL; 1415 + exception = POWERPC_EXCP_PROGRAM;
  1416 + error_code = POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;
1414 break; 1417 break;
1415 } 1418 }
1416 break; 1419 break;
  1420 +#if defined(TARGET_PPC64)
1417 case -5: 1421 case -5:
1418 /* No match in segment table */ 1422 /* No match in segment table */
1419 - exception = EXCP_DSEG; 1423 + exception = POWERPC_EXCP_DSEG;
1420 error_code = 0; 1424 error_code = 0;
1421 break; 1425 break;
  1426 +#endif
1422 } 1427 }
1423 - if (exception == EXCP_DSI && rw == 1) 1428 + if (exception == POWERPC_EXCP_DSI && rw == 1)
1424 error_code |= 0x02000000; 1429 error_code |= 0x02000000;
1425 /* Store fault address */ 1430 /* Store fault address */
1426 env->spr[SPR_DAR] = address; 1431 env->spr[SPR_DAR] = address;
@@ -1830,12 +1835,14 @@ void do_compute_hflags (CPUPPCState *env) @@ -1830,12 +1835,14 @@ void do_compute_hflags (CPUPPCState *env)
1830 #if defined (CONFIG_USER_ONLY) 1835 #if defined (CONFIG_USER_ONLY)
1831 void do_interrupt (CPUState *env) 1836 void do_interrupt (CPUState *env)
1832 { 1837 {
1833 - env->exception_index = -1; 1838 + env->exception_index = POWERPC_EXCP_NONE;
  1839 + env->error_code = 0;
1834 } 1840 }
1835 1841
1836 void ppc_hw_interrupt (CPUState *env) 1842 void ppc_hw_interrupt (CPUState *env)
1837 { 1843 {
1838 - env->exception_index = -1; 1844 + env->exception_index = POWERPC_EXCP_NONE;
  1845 + env->error_code = 0;
1839 } 1846 }
1840 #else /* defined (CONFIG_USER_ONLY) */ 1847 #else /* defined (CONFIG_USER_ONLY) */
1841 static void dump_syscall (CPUState *env) 1848 static void dump_syscall (CPUState *env)
@@ -1846,126 +1853,122 @@ static void dump_syscall (CPUState *env) @@ -1846,126 +1853,122 @@ static void dump_syscall (CPUState *env)
1846 env->gpr[5], env->gpr[6], env->nip); 1853 env->gpr[5], env->gpr[6], env->nip);
1847 } 1854 }
1848 1855
1849 -void do_interrupt (CPUState *env) 1856 +/* Note that this function should be greatly optimized
  1857 + * when called with a constant excp, from ppc_hw_interrupt
  1858 + */
  1859 +static always_inline void powerpc_excp (CPUState *env,
  1860 + int excp_model, int excp)
1850 { 1861 {
1851 - target_ulong msr, *srr_0, *srr_1, *asrr_0, *asrr_1;  
1852 - int excp, idx; 1862 + target_ulong msr, vector;
  1863 + int srr0, srr1, asrr0, asrr1;
1853 1864
1854 - excp = env->exception_index;  
1855 - msr = do_load_msr(env);  
1856 - /* The default is to use SRR0 & SRR1 to save the exception context */  
1857 - srr_0 = &env->spr[SPR_SRR0];  
1858 - srr_1 = &env->spr[SPR_SRR1];  
1859 - asrr_0 = NULL;  
1860 - asrr_1 = NULL;  
1861 -#if defined (DEBUG_EXCEPTIONS)  
1862 - if ((excp == EXCP_PROGRAM || excp == EXCP_DSI) && msr_pr == 1) {  
1863 - if (loglevel != 0) {  
1864 - fprintf(logfile,  
1865 - "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",  
1866 - env->nip, excp, env->error_code);  
1867 - cpu_dump_state(env, logfile, fprintf, 0);  
1868 - }  
1869 - }  
1870 -#endif  
1871 if (loglevel & CPU_LOG_INT) { 1865 if (loglevel & CPU_LOG_INT) {
1872 fprintf(logfile, "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n", 1866 fprintf(logfile, "Raise exception at 0x" ADDRX " => 0x%08x (%02x)\n",
1873 env->nip, excp, env->error_code); 1867 env->nip, excp, env->error_code);
1874 } 1868 }
1875 - msr_pow = 0;  
1876 - idx = -1;  
1877 - /* Generate informations in save/restore registers */ 1869 + msr = do_load_msr(env);
  1870 + srr0 = SPR_SRR0;
  1871 + srr1 = SPR_SRR1;
  1872 + asrr0 = -1;
  1873 + asrr1 = -1;
  1874 + msr &= ~((target_ulong)0x783F0000);
1878 switch (excp) { 1875 switch (excp) {
1879 - /* Generic PowerPC exceptions */  
1880 - case EXCP_RESET: /* 0x0100 */  
1881 - switch (env->excp_model) { 1876 + case POWERPC_EXCP_NONE:
  1877 + /* Should never happen */
  1878 + return;
  1879 + case POWERPC_EXCP_CRITICAL: /* Critical input */
  1880 + msr_ri = 0; /* XXX: check this */
  1881 + switch (excp_model) {
1882 case POWERPC_EXCP_40x: 1882 case POWERPC_EXCP_40x:
1883 - srr_0 = &env->spr[SPR_40x_SRR2];  
1884 - srr_1 = &env->spr[SPR_40x_SRR3]; 1883 + srr0 = SPR_40x_SRR2;
  1884 + srr1 = SPR_40x_SRR3;
1885 break; 1885 break;
1886 case POWERPC_EXCP_BOOKE: 1886 case POWERPC_EXCP_BOOKE:
1887 - idx = 0;  
1888 - srr_0 = &env->spr[SPR_BOOKE_CSRR0];  
1889 - srr_1 = &env->spr[SPR_BOOKE_CSRR1]; 1887 + srr0 = SPR_BOOKE_CSRR0;
  1888 + srr1 = SPR_BOOKE_CSRR1;
1890 break; 1889 break;
1891 - default:  
1892 - if (msr_ip)  
1893 - excp += 0xFFC00;  
1894 - excp |= 0xFFC00000; 1890 + case POWERPC_EXCP_G2:
1895 break; 1891 break;
  1892 + default:
  1893 + goto excp_invalid;
1896 } 1894 }
1897 goto store_next; 1895 goto store_next;
1898 - case EXCP_MACHINE_CHECK: /* 0x0200 */  
1899 - switch (env->excp_model) { 1896 + case POWERPC_EXCP_MCHECK: /* Machine check exception */
  1897 + if (msr_me == 0) {
  1898 + /* Machine check exception is not enabled */
  1899 + /* XXX: we may just stop the processor here, to allow debugging */
  1900 + excp = POWERPC_EXCP_RESET;
  1901 + goto excp_reset;
  1902 + }
  1903 + msr_ri = 0;
  1904 + msr_me = 0;
  1905 +#if defined(TARGET_PPC64H)
  1906 + msr_hv = 1;
  1907 +#endif
  1908 + /* XXX: should also have something loaded in DAR / DSISR */
  1909 + switch (excp_model) {
1900 case POWERPC_EXCP_40x: 1910 case POWERPC_EXCP_40x:
1901 - srr_0 = &env->spr[SPR_40x_SRR2];  
1902 - srr_1 = &env->spr[SPR_40x_SRR3]; 1911 + srr0 = SPR_40x_SRR2;
  1912 + srr1 = SPR_40x_SRR3;
1903 break; 1913 break;
1904 case POWERPC_EXCP_BOOKE: 1914 case POWERPC_EXCP_BOOKE:
1905 - idx = 1;  
1906 - srr_0 = &env->spr[SPR_BOOKE_MCSRR0];  
1907 - srr_1 = &env->spr[SPR_BOOKE_MCSRR1];  
1908 - asrr_0 = &env->spr[SPR_BOOKE_CSRR0];  
1909 - asrr_1 = &env->spr[SPR_BOOKE_CSRR1];  
1910 - msr_ce = 0; 1915 + srr0 = SPR_BOOKE_MCSRR0;
  1916 + srr1 = SPR_BOOKE_MCSRR1;
  1917 + asrr0 = SPR_BOOKE_CSRR0;
  1918 + asrr1 = SPR_BOOKE_CSRR1;
1911 break; 1919 break;
1912 default: 1920 default:
1913 break; 1921 break;
1914 } 1922 }
1915 - msr_me = 0;  
1916 - break;  
1917 - case EXCP_DSI: /* 0x0300 */  
1918 - /* Store exception cause */  
1919 - /* data location address has been stored  
1920 - * when the fault has been detected  
1921 - */  
1922 - idx = 2;  
1923 - msr &= ~0xFFFF0000; 1923 + goto store_next;
  1924 + case POWERPC_EXCP_DSI: /* Data storage exception */
1924 #if defined (DEBUG_EXCEPTIONS) 1925 #if defined (DEBUG_EXCEPTIONS)
1925 if (loglevel != 0) { 1926 if (loglevel != 0) {
1926 fprintf(logfile, "DSI exception: DSISR=0x" ADDRX" DAR=0x" ADDRX 1927 fprintf(logfile, "DSI exception: DSISR=0x" ADDRX" DAR=0x" ADDRX
1927 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]); 1928 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);
1928 } 1929 }
1929 #endif 1930 #endif
  1931 + msr_ri = 0;
  1932 +#if defined(TARGET_PPC64H)
  1933 + if (lpes1 == 0)
  1934 + msr_hv = 1;
  1935 +#endif
1930 goto store_next; 1936 goto store_next;
1931 - case EXCP_ISI: /* 0x0400 */  
1932 - /* Store exception cause */  
1933 - idx = 3;  
1934 - msr &= ~0xFFFF0000;  
1935 - msr |= env->error_code; 1937 + case POWERPC_EXCP_ISI: /* Instruction storage exception */
1936 #if defined (DEBUG_EXCEPTIONS) 1938 #if defined (DEBUG_EXCEPTIONS)
1937 if (loglevel != 0) { 1939 if (loglevel != 0) {
1938 fprintf(logfile, "ISI exception: msr=0x" ADDRX ", nip=0x" ADDRX 1940 fprintf(logfile, "ISI exception: msr=0x" ADDRX ", nip=0x" ADDRX
1939 "\n", msr, env->nip); 1941 "\n", msr, env->nip);
1940 } 1942 }
1941 #endif 1943 #endif
  1944 + msr_ri = 0;
  1945 +#if defined(TARGET_PPC64H)
  1946 + if (lpes1 == 0)
  1947 + msr_hv = 1;
  1948 +#endif
  1949 + msr |= env->error_code;
1942 goto store_next; 1950 goto store_next;
1943 - case EXCP_EXTERNAL: /* 0x0500 */  
1944 - idx = 4; 1951 + case POWERPC_EXCP_EXTERNAL: /* External input */
  1952 + msr_ri = 0;
  1953 +#if defined(TARGET_PPC64H)
  1954 + if (lpes0 == 1)
  1955 + msr_hv = 1;
  1956 +#endif
1945 goto store_next; 1957 goto store_next;
1946 - case EXCP_ALIGN: /* 0x0600 */  
1947 - if (likely(env->excp_model != POWERPC_EXCP_601)) {  
1948 - /* Store exception cause */  
1949 - idx = 5;  
1950 - /* Get rS/rD and rA from faulting opcode */  
1951 - env->spr[SPR_DSISR] |=  
1952 - (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;  
1953 - /* data location address has been stored  
1954 - * when the fault has been detected  
1955 - */  
1956 - } else {  
1957 - /* IO error exception on PowerPC 601 */  
1958 - /* XXX: TODO */  
1959 - cpu_abort(env,  
1960 - "601 IO error exception is not implemented yet !\n");  
1961 - } 1958 + case POWERPC_EXCP_ALIGN: /* Alignment exception */
  1959 + msr_ri = 0;
  1960 +#if defined(TARGET_PPC64H)
  1961 + if (lpes1 == 0)
  1962 + msr_hv = 1;
  1963 +#endif
  1964 + /* XXX: this is false */
  1965 + /* Get rS/rD and rA from faulting opcode */
  1966 + env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;
1962 goto store_current; 1967 goto store_current;
1963 - case EXCP_PROGRAM: /* 0x0700 */  
1964 - idx = 6;  
1965 - msr &= ~0xFFFF0000; 1968 + case POWERPC_EXCP_PROGRAM: /* Program exception */
1966 switch (env->error_code & ~0xF) { 1969 switch (env->error_code & ~0xF) {
1967 - case EXCP_FP:  
1968 - if (msr_fe0 == 0 && msr_fe1 == 0) { 1970 + case POWERPC_EXCP_FP:
  1971 + if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {
1969 #if defined (DEBUG_EXCEPTIONS) 1972 #if defined (DEBUG_EXCEPTIONS)
1970 if (loglevel != 0) { 1973 if (loglevel != 0) {
1971 fprintf(logfile, "Ignore floating point exception\n"); 1974 fprintf(logfile, "Ignore floating point exception\n");
@@ -1973,6 +1976,11 @@ void do_interrupt (CPUState *env) @@ -1973,6 +1976,11 @@ void do_interrupt (CPUState *env)
1973 #endif 1976 #endif
1974 return; 1977 return;
1975 } 1978 }
  1979 + msr_ri = 0;
  1980 +#if defined(TARGET_PPC64H)
  1981 + if (lpes1 == 0)
  1982 + msr_hv = 1;
  1983 +#endif
1976 msr |= 0x00100000; 1984 msr |= 0x00100000;
1977 /* Set FX */ 1985 /* Set FX */
1978 env->fpscr[7] |= 0x8; 1986 env->fpscr[7] |= 0x8;
@@ -1980,39 +1988,59 @@ void do_interrupt (CPUState *env) @@ -1980,39 +1988,59 @@ void do_interrupt (CPUState *env)
1980 if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) & 1988 if ((((env->fpscr[7] & 0x3) << 3) | (env->fpscr[6] >> 1)) &
1981 ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3))) 1989 ((env->fpscr[1] << 1) | (env->fpscr[0] >> 3)))
1982 env->fpscr[7] |= 0x4; 1990 env->fpscr[7] |= 0x4;
  1991 + if (msr_fe0 != msr_fe1) {
  1992 + msr |= 0x00010000;
  1993 + goto store_current;
  1994 + }
1983 break; 1995 break;
1984 - case EXCP_INVAL: 1996 + case POWERPC_EXCP_INVAL:
1985 #if defined (DEBUG_EXCEPTIONS) 1997 #if defined (DEBUG_EXCEPTIONS)
1986 if (loglevel != 0) { 1998 if (loglevel != 0) {
1987 fprintf(logfile, "Invalid instruction at 0x" ADDRX "\n", 1999 fprintf(logfile, "Invalid instruction at 0x" ADDRX "\n",
1988 env->nip); 2000 env->nip);
1989 } 2001 }
1990 #endif 2002 #endif
  2003 + msr_ri = 0;
  2004 +#if defined(TARGET_PPC64H)
  2005 + if (lpes1 == 0)
  2006 + msr_hv = 1;
  2007 +#endif
1991 msr |= 0x00080000; 2008 msr |= 0x00080000;
1992 break; 2009 break;
1993 - case EXCP_PRIV: 2010 + case POWERPC_EXCP_PRIV:
  2011 + msr_ri = 0;
  2012 +#if defined(TARGET_PPC64H)
  2013 + if (lpes1 == 0)
  2014 + msr_hv = 1;
  2015 +#endif
1994 msr |= 0x00040000; 2016 msr |= 0x00040000;
1995 break; 2017 break;
1996 - case EXCP_TRAP:  
1997 - idx = 15; 2018 + case POWERPC_EXCP_TRAP:
  2019 + msr_ri = 0;
  2020 +#if defined(TARGET_PPC64H)
  2021 + if (lpes1 == 0)
  2022 + msr_hv = 1;
  2023 +#endif
1998 msr |= 0x00020000; 2024 msr |= 0x00020000;
1999 break; 2025 break;
2000 default: 2026 default:
2001 /* Should never occur */ 2027 /* Should never occur */
  2028 + cpu_abort(env, "Invalid program exception %d. Aborting\n",
  2029 + env->error_code);
2002 break; 2030 break;
2003 } 2031 }
2004 - msr |= 0x00010000;  
2005 - goto store_current;  
2006 - case EXCP_NO_FP: /* 0x0800 */  
2007 - idx = 7;  
2008 - msr &= ~0xFFFF0000;  
2009 - goto store_current;  
2010 - case EXCP_DECR:  
2011 goto store_next; 2032 goto store_next;
2012 - case EXCP_SYSCALL: /* 0x0C00 */  
2013 - idx = 8; 2033 + case POWERPC_EXCP_FPU: /* Floating-point unavailable exception */
  2034 + msr_ri = 0;
  2035 +#if defined(TARGET_PPC64H)
  2036 + if (lpes1 == 0)
  2037 + msr_hv = 1;
  2038 +#endif
  2039 + goto store_current;
  2040 + case POWERPC_EXCP_SYSCALL: /* System call exception */
2014 /* NOTE: this is a temporary hack to support graphics OSI 2041 /* NOTE: this is a temporary hack to support graphics OSI
2015 calls from the MOL driver */ 2042 calls from the MOL driver */
  2043 + /* XXX: To be removed */
2016 if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b && 2044 if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&
2017 env->osi_call) { 2045 env->osi_call) {
2018 if (env->osi_call(env) != 0) 2046 if (env->osi_call(env) != 0)
@@ -2021,166 +2049,254 @@ void do_interrupt (CPUState *env) @@ -2021,166 +2049,254 @@ void do_interrupt (CPUState *env)
2021 if (loglevel & CPU_LOG_INT) { 2049 if (loglevel & CPU_LOG_INT) {
2022 dump_syscall(env); 2050 dump_syscall(env);
2023 } 2051 }
  2052 + msr_ri = 0;
  2053 +#if defined(TARGET_PPC64H)
  2054 + if (lev == 1 || (lpes0 == 0 && lpes1 == 0))
  2055 + msr_hv = 1;
  2056 +#endif
  2057 + goto store_next;
  2058 + case POWERPC_EXCP_APU: /* Auxiliary processor unavailable */
  2059 + msr_ri = 0;
  2060 + goto store_current;
  2061 + case POWERPC_EXCP_DECR: /* Decrementer exception */
  2062 + msr_ri = 0;
  2063 +#if defined(TARGET_PPC64H)
  2064 + if (lpes1 == 0)
  2065 + msr_hv = 1;
  2066 +#endif
  2067 + goto store_next;
  2068 + case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
  2069 + /* FIT on 4xx */
  2070 +#if defined (DEBUG_EXCEPTIONS)
  2071 + if (loglevel != 0)
  2072 + fprintf(logfile, "FIT exception\n");
  2073 +#endif
  2074 + msr_ri = 0; /* XXX: check this */
2024 goto store_next; 2075 goto store_next;
2025 - case EXCP_TRACE: /* 0x0D00 */ 2076 + case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
  2077 +#if defined (DEBUG_EXCEPTIONS)
  2078 + if (loglevel != 0)
  2079 + fprintf(logfile, "WDT exception\n");
  2080 +#endif
  2081 + switch (excp_model) {
  2082 + case POWERPC_EXCP_BOOKE:
  2083 + srr0 = SPR_BOOKE_CSRR0;
  2084 + srr1 = SPR_BOOKE_CSRR1;
  2085 + break;
  2086 + default:
  2087 + break;
  2088 + }
  2089 + msr_ri = 0; /* XXX: check this */
2026 goto store_next; 2090 goto store_next;
2027 - case EXCP_PERF: /* 0x0F00 */ 2091 + case POWERPC_EXCP_DTLB: /* Data TLB error */
  2092 + msr_ri = 0; /* XXX: check this */
  2093 + goto store_next;
  2094 + case POWERPC_EXCP_ITLB: /* Instruction TLB error */
  2095 + msr_ri = 0; /* XXX: check this */
  2096 + goto store_next;
  2097 + case POWERPC_EXCP_DEBUG: /* Debug interrupt */
  2098 + switch (excp_model) {
  2099 + case POWERPC_EXCP_BOOKE:
  2100 + srr0 = SPR_BOOKE_DSRR0;
  2101 + srr1 = SPR_BOOKE_DSRR1;
  2102 + asrr0 = SPR_BOOKE_CSRR0;
  2103 + asrr1 = SPR_BOOKE_CSRR1;
  2104 + break;
  2105 + default:
  2106 + break;
  2107 + }
2028 /* XXX: TODO */ 2108 /* XXX: TODO */
2029 - cpu_abort(env,  
2030 - "Performance counter exception is not implemented yet !\n"); 2109 + cpu_abort(env, "Debug exception is not implemented yet !\n");
2031 goto store_next; 2110 goto store_next;
2032 - /* 32 bits PowerPC specific exceptions */  
2033 - case EXCP_FP_ASSIST: /* 0x0E00 */ 2111 +#if defined(TARGET_PPCEMB)
  2112 + case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */
  2113 + msr_ri = 0; /* XXX: check this */
  2114 + goto store_current;
  2115 + case POWERPC_EXCP_EFPDI: /* Embedded floating-point data interrupt */
2034 /* XXX: TODO */ 2116 /* XXX: TODO */
2035 - cpu_abort(env, "Floating point assist exception " 2117 + cpu_abort(env, "Embedded floating point data exception "
2036 "is not implemented yet !\n"); 2118 "is not implemented yet !\n");
2037 goto store_next; 2119 goto store_next;
2038 - /* 64 bits PowerPC exceptions */  
2039 - case EXCP_DSEG: /* 0x0380 */ 2120 + case POWERPC_EXCP_EFPRI: /* Embedded floating-point round interrupt */
2040 /* XXX: TODO */ 2121 /* XXX: TODO */
2041 - cpu_abort(env, "Data segment exception is not implemented yet !\n"); 2122 + cpu_abort(env, "Embedded floating point round exception "
  2123 + "is not implemented yet !\n");
2042 goto store_next; 2124 goto store_next;
2043 - case EXCP_ISEG: /* 0x0480 */ 2125 + case POWERPC_EXCP_EPERFM: /* Embedded performance monitor interrupt */
  2126 + msr_ri = 0;
2044 /* XXX: TODO */ 2127 /* XXX: TODO */
2045 cpu_abort(env, 2128 cpu_abort(env,
2046 - "Instruction segment exception is not implemented yet !\n"); 2129 + "Performance counter exception is not implemented yet !\n");
2047 goto store_next; 2130 goto store_next;
2048 - case EXCP_HDECR: /* 0x0980 */ 2131 + case POWERPC_EXCP_DOORI: /* Embedded doorbell interrupt */
2049 /* XXX: TODO */ 2132 /* XXX: TODO */
2050 - cpu_abort(env, "Hypervisor decrementer exception is not implemented "  
2051 - "yet !\n"); 2133 + cpu_abort(env,
  2134 + "Embedded doorbell interrupt is not implemented yet !\n");
2052 goto store_next; 2135 goto store_next;
2053 - /* Implementation specific exceptions */  
2054 - case 0x0A00:  
2055 - switch (env->excp_model) {  
2056 - case POWERPC_EXCP_G2:  
2057 - /* Critical interrupt on G2 */  
2058 - /* XXX: TODO */  
2059 - cpu_abort(env, "G2 critical interrupt is not implemented yet !\n");  
2060 - goto store_next;  
2061 - default:  
2062 - cpu_abort(env, "Invalid exception 0x0A00 !\n"); 2136 + case POWERPC_EXCP_DOORCI: /* Embedded doorbell critical interrupt */
  2137 + switch (excp_model) {
  2138 + case POWERPC_EXCP_BOOKE:
  2139 + srr0 = SPR_BOOKE_CSRR0;
  2140 + srr1 = SPR_BOOKE_CSRR1;
2063 break; 2141 break;
2064 - }  
2065 - return;  
2066 - case 0x0F20:  
2067 - idx = 9;  
2068 - switch (env->excp_model) {  
2069 - case POWERPC_EXCP_40x:  
2070 - /* APU unavailable on 405 */  
2071 - /* XXX: TODO */  
2072 - cpu_abort(env,  
2073 - "APU unavailable exception is not implemented yet !\n");  
2074 - goto store_next;  
2075 - case POWERPC_EXCP_74xx:  
2076 - /* Altivec unavailable */  
2077 - /* XXX: TODO */  
2078 - cpu_abort(env, "Altivec unavailable exception "  
2079 - "is not implemented yet !\n");  
2080 - goto store_next;  
2081 default: 2142 default:
2082 - cpu_abort(env, "Invalid exception 0x0F20 !\n");  
2083 break; 2143 break;
2084 } 2144 }
2085 - return;  
2086 - case 0x1000:  
2087 - idx = 10;  
2088 - switch (env->excp_model) {  
2089 - case POWERPC_EXCP_40x:  
2090 - /* PIT on 4xx */  
2091 - msr &= ~0xFFFF0000; 2145 + /* XXX: TODO */
  2146 + cpu_abort(env, "Embedded doorbell critical interrupt "
  2147 + "is not implemented yet !\n");
  2148 + goto store_next;
  2149 +#endif /* defined(TARGET_PPCEMB) */
  2150 + case POWERPC_EXCP_RESET: /* System reset exception */
  2151 + msr_ri = 0;
  2152 +#if defined(TARGET_PPC64H)
  2153 + msr_hv = 1;
  2154 +#endif
  2155 + excp_reset:
  2156 + goto store_next;
  2157 +#if defined(TARGET_PPC64)
  2158 + case POWERPC_EXCP_DSEG: /* Data segment exception */
  2159 + msr_ri = 0;
  2160 +#if defined(TARGET_PPC64H)
  2161 + if (lpes1 == 0)
  2162 + msr_hv = 1;
  2163 +#endif
  2164 + /* XXX: TODO */
  2165 + cpu_abort(env, "Data segment exception is not implemented yet !\n");
  2166 + goto store_next;
  2167 + case POWERPC_EXCP_ISEG: /* Instruction segment exception */
  2168 + msr_ri = 0;
  2169 +#if defined(TARGET_PPC64H)
  2170 + if (lpes1 == 0)
  2171 + msr_hv = 1;
  2172 +#endif
  2173 + /* XXX: TODO */
  2174 + cpu_abort(env,
  2175 + "Instruction segment exception is not implemented yet !\n");
  2176 + goto store_next;
  2177 +#endif /* defined(TARGET_PPC64) */
  2178 +#if defined(TARGET_PPC64H)
  2179 + case POWERPC_EXCP_HDECR: /* Hypervisor decrementer exception */
  2180 + srr0 = SPR_HSRR0;
  2181 + srr1 = SPR_HSSR1;
  2182 + msr_hv = 1;
  2183 + goto store_next;
  2184 +#endif
  2185 + case POWERPC_EXCP_TRACE: /* Trace exception */
  2186 + msr_ri = 0;
  2187 +#if defined(TARGET_PPC64H)
  2188 + if (lpes1 == 0)
  2189 + msr_hv = 1;
  2190 +#endif
  2191 + goto store_next;
  2192 +#if defined(TARGET_PPC64H)
  2193 + case POWERPC_EXCP_HDSI: /* Hypervisor data storage exception */
  2194 + srr0 = SPR_HSRR0;
  2195 + srr1 = SPR_HSSR1;
  2196 + msr_hv = 1;
  2197 + goto store_next;
  2198 + case POWERPC_EXCP_HISI: /* Hypervisor instruction storage exception */
  2199 + srr0 = SPR_HSRR0;
  2200 + srr1 = SPR_HSSR1;
  2201 + msr_hv = 1;
  2202 + /* XXX: TODO */
  2203 + cpu_abort(env, "Hypervisor instruction storage exception "
  2204 + "is not implemented yet !\n");
  2205 + goto store_next;
  2206 + case POWERPC_EXCP_HDSEG: /* Hypervisor data segment exception */
  2207 + srr0 = SPR_HSRR0;
  2208 + srr1 = SPR_HSSR1;
  2209 + msr_hv = 1;
  2210 + goto store_next;
  2211 + case POWERPC_EXCP_HISEG: /* Hypervisor instruction segment exception */
  2212 + srr0 = SPR_HSRR0;
  2213 + srr1 = SPR_HSSR1;
  2214 + msr_hv = 1;
  2215 + goto store_next;
  2216 +#endif /* defined(TARGET_PPC64H) */
  2217 + case POWERPC_EXCP_VPU: /* Vector unavailable exception */
  2218 + msr_ri = 0;
  2219 +#if defined(TARGET_PPC64H)
  2220 + if (lpes1 == 0)
  2221 + msr_hv = 1;
  2222 +#endif
  2223 + goto store_current;
  2224 + case POWERPC_EXCP_PIT: /* Programmable interval timer interrupt */
2092 #if defined (DEBUG_EXCEPTIONS) 2225 #if defined (DEBUG_EXCEPTIONS)
2093 - if (loglevel != 0)  
2094 - fprintf(logfile, "PIT exception\n"); 2226 + if (loglevel != 0)
  2227 + fprintf(logfile, "PIT exception\n");
  2228 +#endif
  2229 + msr_ri = 0; /* XXX: check this */
  2230 + goto store_next;
  2231 + case POWERPC_EXCP_IO: /* IO error exception */
  2232 + /* XXX: TODO */
  2233 + cpu_abort(env, "601 IO error exception is not implemented yet !\n");
  2234 + goto store_next;
  2235 + case POWERPC_EXCP_RUNM: /* Run mode exception */
  2236 + /* XXX: TODO */
  2237 + cpu_abort(env, "601 run mode exception is not implemented yet !\n");
  2238 + goto store_next;
  2239 + case POWERPC_EXCP_EMUL: /* Emulation trap exception */
  2240 + /* XXX: TODO */
  2241 + cpu_abort(env, "602 emulation trap exception "
  2242 + "is not implemented yet !\n");
  2243 + goto store_next;
  2244 + case POWERPC_EXCP_IFTLB: /* Instruction fetch TLB error */
  2245 + msr_ri = 0; /* XXX: check this */
  2246 +#if defined(TARGET_PPC64H) /* XXX: check this */
  2247 + if (lpes1 == 0)
  2248 + msr_hv = 1;
2095 #endif 2249 #endif
2096 - goto store_next; 2250 + switch (excp_model) {
2097 case POWERPC_EXCP_602: 2251 case POWERPC_EXCP_602:
2098 case POWERPC_EXCP_603: 2252 case POWERPC_EXCP_603:
2099 case POWERPC_EXCP_603E: 2253 case POWERPC_EXCP_603E:
2100 case POWERPC_EXCP_G2: 2254 case POWERPC_EXCP_G2:
2101 - /* ITLBMISS on 602/603 */  
2102 - goto store_gprs; 2255 + goto tlb_miss_tgpr;
2103 case POWERPC_EXCP_7x5: 2256 case POWERPC_EXCP_7x5:
2104 - /* ITLBMISS on 745/755 */  
2105 goto tlb_miss; 2257 goto tlb_miss;
2106 default: 2258 default:
2107 - cpu_abort(env, "Invalid exception 0x1000 !\n");  
2108 - break;  
2109 - }  
2110 - return;  
2111 - case 0x1010:  
2112 - idx = 11;  
2113 - switch (env->excp_model) {  
2114 - case POWERPC_EXCP_40x:  
2115 - /* FIT on 4xx */  
2116 - msr &= ~0xFFFF0000;  
2117 -#if defined (DEBUG_EXCEPTIONS)  
2118 - if (loglevel != 0)  
2119 - fprintf(logfile, "FIT exception\n");  
2120 -#endif  
2121 - goto store_next;  
2122 - default:  
2123 - cpu_abort(env, "Invalid exception 0x1010 !\n"); 2259 + cpu_abort(env, "Invalid instruction TLB miss exception\n");
2124 break; 2260 break;
2125 } 2261 }
2126 - return;  
2127 - case 0x1020:  
2128 - idx = 12;  
2129 - switch (env->excp_model) {  
2130 - case POWERPC_EXCP_40x:  
2131 - /* Watchdog on 4xx */  
2132 - msr &= ~0xFFFF0000;  
2133 -#if defined (DEBUG_EXCEPTIONS)  
2134 - if (loglevel != 0)  
2135 - fprintf(logfile, "WDT exception\n"); 2262 + break;
  2263 + case POWERPC_EXCP_DLTLB: /* Data load TLB miss */
  2264 + msr_ri = 0; /* XXX: check this */
  2265 +#if defined(TARGET_PPC64H) /* XXX: check this */
  2266 + if (lpes1 == 0)
  2267 + msr_hv = 1;
2136 #endif 2268 #endif
2137 - goto store_next;  
2138 - case POWERPC_EXCP_BOOKE:  
2139 - srr_0 = &env->spr[SPR_BOOKE_CSRR0];  
2140 - srr_1 = &env->spr[SPR_BOOKE_CSRR1];  
2141 - break;  
2142 - default:  
2143 - cpu_abort(env, "Invalid exception 0x1020 !\n");  
2144 - break;  
2145 - }  
2146 - return;  
2147 - case 0x1100:  
2148 - idx = 13;  
2149 - switch (env->excp_model) {  
2150 - case POWERPC_EXCP_40x:  
2151 - /* DTLBMISS on 4xx */  
2152 - msr &= ~0xFFFF0000;  
2153 - goto store_next; 2269 + switch (excp_model) {
2154 case POWERPC_EXCP_602: 2270 case POWERPC_EXCP_602:
2155 case POWERPC_EXCP_603: 2271 case POWERPC_EXCP_603:
2156 case POWERPC_EXCP_603E: 2272 case POWERPC_EXCP_603E:
2157 case POWERPC_EXCP_G2: 2273 case POWERPC_EXCP_G2:
2158 - /* DLTLBMISS on 602/603 */  
2159 - goto store_gprs; 2274 + goto tlb_miss_tgpr;
2160 case POWERPC_EXCP_7x5: 2275 case POWERPC_EXCP_7x5:
2161 - /* DLTLBMISS on 745/755 */  
2162 goto tlb_miss; 2276 goto tlb_miss;
2163 default: 2277 default:
2164 - cpu_abort(env, "Invalid exception 0x1100 !\n"); 2278 + cpu_abort(env, "Invalid data load TLB miss exception\n");
2165 break; 2279 break;
2166 } 2280 }
2167 - return;  
2168 - case 0x1200:  
2169 - idx = 14;  
2170 - switch (env->excp_model) {  
2171 - case POWERPC_EXCP_40x:  
2172 - /* ITLBMISS on 4xx */  
2173 - msr &= ~0xFFFF0000;  
2174 - goto store_next; 2281 + break;
  2282 + case POWERPC_EXCP_DSTLB: /* Data store TLB miss */
  2283 + msr_ri = 0; /* XXX: check this */
  2284 +#if defined(TARGET_PPC64H) /* XXX: check this */
  2285 + if (lpes1 == 0)
  2286 + msr_hv = 1;
  2287 +#endif
  2288 + switch (excp_model) {
2175 case POWERPC_EXCP_602: 2289 case POWERPC_EXCP_602:
2176 case POWERPC_EXCP_603: 2290 case POWERPC_EXCP_603:
2177 case POWERPC_EXCP_603E: 2291 case POWERPC_EXCP_603E:
2178 case POWERPC_EXCP_G2: 2292 case POWERPC_EXCP_G2:
2179 - /* DSTLBMISS on 602/603 */  
2180 - store_gprs: 2293 + tlb_miss_tgpr:
2181 /* Swap temporary saved registers with GPRs */ 2294 /* Swap temporary saved registers with GPRs */
2182 swap_gpr_tgpr(env); 2295 swap_gpr_tgpr(env);
2183 msr_tgpr = 1; 2296 msr_tgpr = 1;
  2297 + goto tlb_miss;
  2298 + case POWERPC_EXCP_7x5:
  2299 + tlb_miss:
2184 #if defined (DEBUG_SOFTWARE_TLB) 2300 #if defined (DEBUG_SOFTWARE_TLB)
2185 if (loglevel != 0) { 2301 if (loglevel != 0) {
2186 const unsigned char *es; 2302 const unsigned char *es;
@@ -2207,183 +2323,81 @@ void do_interrupt (CPUState *env) @@ -2207,183 +2323,81 @@ void do_interrupt (CPUState *env)
2207 env->error_code); 2323 env->error_code);
2208 } 2324 }
2209 #endif 2325 #endif
2210 - goto tlb_miss;  
2211 - case POWERPC_EXCP_7x5:  
2212 - /* DSTLBMISS on 745/755 */  
2213 - tlb_miss:  
2214 - msr &= ~0xF83F0000;  
2215 msr |= env->crf[0] << 28; 2326 msr |= env->crf[0] << 28;
2216 msr |= env->error_code; /* key, D/I, S/L bits */ 2327 msr |= env->error_code; /* key, D/I, S/L bits */
2217 /* Set way using a LRU mechanism */ 2328 /* Set way using a LRU mechanism */
2218 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17; 2329 msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;
2219 - goto store_next;  
2220 - default:  
2221 - cpu_abort(env, "Invalid exception 0x1200 !\n");  
2222 - break;  
2223 - }  
2224 - return;  
2225 - case 0x1300:  
2226 - switch (env->excp_model) {  
2227 - case POWERPC_EXCP_601:  
2228 - case POWERPC_EXCP_602:  
2229 - case POWERPC_EXCP_603:  
2230 - case POWERPC_EXCP_603E:  
2231 - case POWERPC_EXCP_G2:  
2232 - case POWERPC_EXCP_604:  
2233 - case POWERPC_EXCP_7x0:  
2234 - case POWERPC_EXCP_7x5:  
2235 - /* IABR on 6xx/7xx */  
2236 - /* XXX: TODO */  
2237 - cpu_abort(env, "IABR exception is not implemented yet !\n");  
2238 - goto store_next;  
2239 - default:  
2240 - cpu_abort(env, "Invalid exception 0x1300 !\n");  
2241 - break;  
2242 - }  
2243 - return;  
2244 - case 0x1400:  
2245 - switch (env->excp_model) {  
2246 - case POWERPC_EXCP_601:  
2247 - case POWERPC_EXCP_602:  
2248 - case POWERPC_EXCP_603:  
2249 - case POWERPC_EXCP_603E:  
2250 - case POWERPC_EXCP_G2:  
2251 - case POWERPC_EXCP_604:  
2252 - case POWERPC_EXCP_7x0:  
2253 - case POWERPC_EXCP_7x5:  
2254 - /* SMI on 6xx/7xx */  
2255 - /* XXX: TODO */  
2256 - cpu_abort(env, "SMI exception is not implemented yet !\n");  
2257 - goto store_next;  
2258 - default:  
2259 - cpu_abort(env, "Invalid exception 0x1400 !\n");  
2260 - break;  
2261 - }  
2262 - return;  
2263 - case 0x1500:  
2264 - switch (env->excp_model) {  
2265 - case POWERPC_EXCP_602:  
2266 - /* Watchdog on 602 */  
2267 - /* XXX: TODO */  
2268 - cpu_abort(env,  
2269 - "602 watchdog exception is not implemented yet !\n");  
2270 - goto store_next;  
2271 - case POWERPC_EXCP_970:  
2272 - /* Soft patch exception on 970 */  
2273 - /* XXX: TODO */  
2274 - cpu_abort(env,  
2275 - "970 soft-patch exception is not implemented yet !\n");  
2276 - goto store_next;  
2277 - case POWERPC_EXCP_74xx:  
2278 - /* VPU assist on 74xx */  
2279 - /* XXX: TODO */  
2280 - cpu_abort(env, "VPU assist exception is not implemented yet !\n");  
2281 - goto store_next;  
2282 - default:  
2283 - cpu_abort(env, "Invalid exception 0x1500 !\n");  
2284 - break;  
2285 - }  
2286 - return;  
2287 - case 0x1600:  
2288 - switch (env->excp_model) {  
2289 - case POWERPC_EXCP_602:  
2290 - /* Emulation trap on 602 */  
2291 - /* XXX: TODO */  
2292 - cpu_abort(env, "602 emulation trap exception "  
2293 - "is not implemented yet !\n");  
2294 - goto store_next;  
2295 - case POWERPC_EXCP_970:  
2296 - /* Maintenance exception on 970 */  
2297 - /* XXX: TODO */  
2298 - cpu_abort(env,  
2299 - "970 maintenance exception is not implemented yet !\n");  
2300 - goto store_next;  
2301 - default:  
2302 - cpu_abort(env, "Invalid exception 0x1600 !\n");  
2303 - break;  
2304 - }  
2305 - return;  
2306 - case 0x1700:  
2307 - switch (env->excp_model) {  
2308 - case POWERPC_EXCP_7x0:  
2309 - case POWERPC_EXCP_7x5:  
2310 - /* Thermal management interrupt on G3 */  
2311 - /* XXX: TODO */  
2312 - cpu_abort(env, "G3 thermal management exception "  
2313 - "is not implemented yet !\n");  
2314 - goto store_next;  
2315 - case POWERPC_EXCP_970:  
2316 - /* VPU assist on 970 */  
2317 - /* XXX: TODO */  
2318 - cpu_abort(env,  
2319 - "970 VPU assist exception is not implemented yet !\n");  
2320 - goto store_next;  
2321 - default:  
2322 - cpu_abort(env, "Invalid exception 0x1700 !\n");  
2323 - break;  
2324 - }  
2325 - return;  
2326 - case 0x1800:  
2327 - switch (env->excp_model) {  
2328 - case POWERPC_EXCP_970:  
2329 - /* Thermal exception on 970 */  
2330 - /* XXX: TODO */  
2331 - cpu_abort(env, "970 thermal management exception "  
2332 - "is not implemented yet !\n");  
2333 - goto store_next;  
2334 - default:  
2335 - cpu_abort(env, "Invalid exception 0x1800 !\n");  
2336 - break;  
2337 - }  
2338 - return;  
2339 - case 0x2000:  
2340 - switch (env->excp_model) {  
2341 - case POWERPC_EXCP_40x:  
2342 - /* DEBUG on 4xx */  
2343 - /* XXX: TODO */  
2344 - cpu_abort(env, "40x debug exception is not implemented yet !\n");  
2345 - goto store_next;  
2346 - case POWERPC_EXCP_601:  
2347 - /* Run mode exception on 601 */  
2348 - /* XXX: TODO */  
2349 - cpu_abort(env,  
2350 - "601 run mode exception is not implemented yet !\n");  
2351 - goto store_next;  
2352 - case POWERPC_EXCP_BOOKE:  
2353 - srr_0 = &env->spr[SPR_BOOKE_CSRR0];  
2354 - srr_1 = &env->spr[SPR_BOOKE_CSRR1];  
2355 break; 2330 break;
2356 default: 2331 default:
2357 - cpu_abort(env, "Invalid exception 0x1800 !\n"); 2332 + cpu_abort(env, "Invalid data store TLB miss exception\n");
2358 break; 2333 break;
2359 } 2334 }
2360 - return;  
2361 - /* Other exceptions */  
2362 - /* Qemu internal exceptions:  
2363 - * we should never come here with those values: abort execution  
2364 - */ 2335 + goto store_next;
  2336 + case POWERPC_EXCP_FPA: /* Floating-point assist exception */
  2337 + /* XXX: TODO */
  2338 + cpu_abort(env, "Floating point assist exception "
  2339 + "is not implemented yet !\n");
  2340 + goto store_next;
  2341 + case POWERPC_EXCP_IABR: /* Instruction address breakpoint */
  2342 + /* XXX: TODO */
  2343 + cpu_abort(env, "IABR exception is not implemented yet !\n");
  2344 + goto store_next;
  2345 + case POWERPC_EXCP_SMI: /* System management interrupt */
  2346 + /* XXX: TODO */
  2347 + cpu_abort(env, "SMI exception is not implemented yet !\n");
  2348 + goto store_next;
  2349 + case POWERPC_EXCP_THERM: /* Thermal interrupt */
  2350 + /* XXX: TODO */
  2351 + cpu_abort(env, "Thermal management exception "
  2352 + "is not implemented yet !\n");
  2353 + goto store_next;
  2354 + case POWERPC_EXCP_PERFM: /* Embedded performance monitor interrupt */
  2355 + msr_ri = 0;
  2356 +#if defined(TARGET_PPC64H)
  2357 + if (lpes1 == 0)
  2358 + msr_hv = 1;
  2359 +#endif
  2360 + /* XXX: TODO */
  2361 + cpu_abort(env,
  2362 + "Performance counter exception is not implemented yet !\n");
  2363 + goto store_next;
  2364 + case POWERPC_EXCP_VPUA: /* Vector assist exception */
  2365 + /* XXX: TODO */
  2366 + cpu_abort(env, "VPU assist exception is not implemented yet !\n");
  2367 + goto store_next;
  2368 + case POWERPC_EXCP_SOFTP: /* Soft patch exception */
  2369 + /* XXX: TODO */
  2370 + cpu_abort(env,
  2371 + "970 soft-patch exception is not implemented yet !\n");
  2372 + goto store_next;
  2373 + case POWERPC_EXCP_MAINT: /* Maintenance exception */
  2374 + /* XXX: TODO */
  2375 + cpu_abort(env,
  2376 + "970 maintenance exception is not implemented yet !\n");
  2377 + goto store_next;
2365 default: 2378 default:
2366 - cpu_abort(env, "Invalid exception: code %d (%04x)\n", excp, excp);  
2367 - return; 2379 + excp_invalid:
  2380 + cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);
  2381 + break;
2368 store_current: 2382 store_current:
2369 /* save current instruction location */ 2383 /* save current instruction location */
2370 - *srr_0 = env->nip - 4; 2384 + env->spr[srr0] = env->nip - 4;
2371 break; 2385 break;
2372 store_next: 2386 store_next:
2373 /* save next instruction location */ 2387 /* save next instruction location */
2374 - *srr_0 = env->nip; 2388 + env->spr[srr0] = env->nip;
2375 break; 2389 break;
2376 } 2390 }
2377 - /* Save msr */  
2378 - *srr_1 = msr;  
2379 - if (asrr_0 != NULL)  
2380 - *asrr_0 = *srr_0;  
2381 - if (asrr_1 != NULL)  
2382 - *asrr_1 = *srr_1; 2391 + /* Save MSR */
  2392 + env->spr[srr1] = msr;
  2393 + /* If any alternate SRR register are defined, duplicate saved values */
  2394 + if (asrr0 != -1)
  2395 + env->spr[asrr0] = env->spr[srr0];
  2396 + if (asrr1 != -1)
  2397 + env->spr[asrr1] = env->spr[srr1];
2383 /* If we disactivated any translation, flush TLBs */ 2398 /* If we disactivated any translation, flush TLBs */
2384 - if (msr_ir || msr_dr) { 2399 + if (msr_ir || msr_dr)
2385 tlb_flush(env, 1); 2400 tlb_flush(env, 1);
2386 - }  
2387 /* reload MSR with correct bits */ 2401 /* reload MSR with correct bits */
2388 msr_ee = 0; 2402 msr_ee = 0;
2389 msr_pr = 0; 2403 msr_pr = 0;
@@ -2394,37 +2408,42 @@ void do_interrupt (CPUState *env) @@ -2394,37 +2408,42 @@ void do_interrupt (CPUState *env)
2394 msr_fe1 = 0; 2408 msr_fe1 = 0;
2395 msr_ir = 0; 2409 msr_ir = 0;
2396 msr_dr = 0; 2410 msr_dr = 0;
2397 - msr_ri = 0; 2411 +#if 0 /* Fix this: not on all targets */
  2412 + msr_pmm = 0;
  2413 +#endif
2398 msr_le = msr_ile; 2414 msr_le = msr_ile;
2399 - if (env->excp_model == POWERPC_EXCP_BOOKE) {  
2400 - msr_cm = msr_icm;  
2401 - if (idx == -1 || (idx >= 16 && idx < 32)) {  
2402 - cpu_abort(env, "Invalid exception index for excp %d %08x idx %d\n",  
2403 - excp, excp, idx);  
2404 - } 2415 + do_compute_hflags(env);
  2416 + /* Jump to handler */
  2417 + vector = env->excp_vectors[excp];
  2418 + if (vector == (target_ulong)-1) {
  2419 + cpu_abort(env, "Raised an exception without defined vector %d\n",
  2420 + excp);
  2421 + }
  2422 + vector |= env->excp_prefix;
2405 #if defined(TARGET_PPC64) 2423 #if defined(TARGET_PPC64)
2406 - if (msr_cm)  
2407 - env->nip = (uint64_t)env->spr[SPR_BOOKE_IVPR];  
2408 - else  
2409 -#endif  
2410 - env->nip = (uint32_t)env->spr[SPR_BOOKE_IVPR];  
2411 - if (idx < 16)  
2412 - env->nip |= env->spr[SPR_BOOKE_IVOR0 + idx];  
2413 - else if (idx < 38)  
2414 - env->nip |= env->spr[SPR_BOOKE_IVOR32 + idx - 32]; 2424 + if (excp_model == POWERPC_EXCP_BOOKE) {
  2425 + msr_cm = msr_icm;
  2426 + if (!msr_cm)
  2427 + vector = (uint32_t)vector;
2415 } else { 2428 } else {
2416 msr_sf = msr_isf; 2429 msr_sf = msr_isf;
2417 - env->nip = excp; 2430 + if (!msr_sf)
  2431 + vector = (uint32_t)vector;
2418 } 2432 }
2419 - do_compute_hflags(env);  
2420 - /* Jump to handler */  
2421 - env->exception_index = EXCP_NONE; 2433 +#endif
  2434 + env->nip = vector;
  2435 + /* Reset exception state */
  2436 + env->exception_index = POWERPC_EXCP_NONE;
  2437 + env->error_code = 0;
2422 } 2438 }
2423 2439
2424 -void ppc_hw_interrupt (CPUPPCState *env) 2440 +void do_interrupt (CPUState *env)
2425 { 2441 {
2426 - int raised = 0; 2442 + powerpc_excp(env, env->excp_model, env->exception_index);
  2443 +}
2427 2444
  2445 +void ppc_hw_interrupt (CPUPPCState *env)
  2446 +{
2428 #if 1 2447 #if 1
2429 if (loglevel & CPU_LOG_INT) { 2448 if (loglevel & CPU_LOG_INT) {
2430 fprintf(logfile, "%s: %p pending %08x req %08x me %d ee %d\n", 2449 fprintf(logfile, "%s: %p pending %08x req %08x me %d ee %d\n",
@@ -2432,82 +2451,125 @@ void ppc_hw_interrupt (CPUPPCState *env) @@ -2432,82 +2451,125 @@ void ppc_hw_interrupt (CPUPPCState *env)
2432 env->interrupt_request, msr_me, msr_ee); 2451 env->interrupt_request, msr_me, msr_ee);
2433 } 2452 }
2434 #endif 2453 #endif
2435 - /* Raise it */ 2454 + /* External reset */
2436 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) { 2455 if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {
2437 - /* External reset / critical input */  
2438 - /* XXX: critical input should be handled another way.  
2439 - * This code is not correct !  
2440 - */  
2441 - env->exception_index = EXCP_RESET;  
2442 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET); 2456 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);
2443 - raised = 1;  
2444 - }  
2445 - if (raised == 0 && msr_me != 0) {  
2446 - /* Machine check exception */  
2447 - if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {  
2448 - env->exception_index = EXCP_MACHINE_CHECK;  
2449 - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);  
2450 - raised = 1;  
2451 - } 2457 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_RESET);
  2458 + return;
  2459 + }
  2460 + /* Machine check exception */
  2461 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {
  2462 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);
  2463 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_MCHECK);
  2464 + return;
2452 } 2465 }
2453 - if (raised == 0 && msr_ee != 0) {  
2454 -#if defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */ 2466 +#if 0 /* TODO */
  2467 + /* External debug exception */
  2468 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {
  2469 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);
  2470 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_DEBUG);
  2471 + return;
  2472 + }
  2473 +#endif
  2474 +#if defined(TARGET_PPC64H)
  2475 + if ((msr_ee != 0 || msr_hv == 0 || msr_pr == 1) & hdice != 0) {
2455 /* Hypervisor decrementer exception */ 2476 /* Hypervisor decrementer exception */
2456 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { 2477 if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {
2457 - env->exception_index = EXCP_HDECR;  
2458 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); 2478 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR);
2459 - raised = 1;  
2460 - } else 2479 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_HDECR);
  2480 + return;
  2481 + }
  2482 + }
  2483 +#endif
  2484 + if (msr_ce != 0) {
  2485 + /* External critical interrupt */
  2486 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {
  2487 + /* Taking a critical external interrupt does not clear the external
  2488 + * critical interrupt status
  2489 + */
  2490 +#if 0
  2491 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);
2461 #endif 2492 #endif
  2493 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_CRITICAL);
  2494 + return;
  2495 + }
  2496 + }
  2497 + if (msr_ee != 0) {
  2498 + /* Watchdog timer on embedded PowerPC */
  2499 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {
  2500 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);
  2501 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
  2502 + return;
  2503 + }
  2504 +#if defined(TARGET_PPCEMB)
  2505 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
  2506 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
  2507 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
  2508 + return;
  2509 + }
  2510 +#endif
  2511 +#if defined(TARGET_PPCEMB)
  2512 + /* External interrupt */
  2513 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
  2514 + /* Taking an external interrupt does not clear the external
  2515 + * interrupt status
  2516 + */
  2517 +#if 0
  2518 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
  2519 +#endif
  2520 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
  2521 + return;
  2522 + }
  2523 +#endif
  2524 + /* Fixed interval timer on embedded PowerPC */
  2525 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
  2526 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
  2527 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_FIT);
  2528 + return;
  2529 + }
  2530 + /* Programmable interval timer on embedded PowerPC */
  2531 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {
  2532 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);
  2533 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_PIT);
  2534 + return;
  2535 + }
2462 /* Decrementer exception */ 2536 /* Decrementer exception */
2463 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { 2537 if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {
2464 - env->exception_index = EXCP_DECR;  
2465 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); 2538 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);
2466 - raised = 1;  
2467 - /* Programmable interval timer on embedded PowerPC */  
2468 - } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {  
2469 - env->exception_index = EXCP_40x_PIT;  
2470 - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);  
2471 - raised = 1;  
2472 - /* Fixed interval timer on embedded PowerPC */  
2473 - } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {  
2474 - env->exception_index = EXCP_40x_FIT;  
2475 - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);  
2476 - raised = 1;  
2477 - /* Watchdog timer on embedded PowerPC */  
2478 - } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {  
2479 - env->exception_index = EXCP_40x_WATCHDOG;  
2480 - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);  
2481 - raised = 1; 2539 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
  2540 + return;
  2541 + }
  2542 +#if !defined(TARGET_PPCEMB)
2482 /* External interrupt */ 2543 /* External interrupt */
2483 - } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {  
2484 - env->exception_index = EXCP_EXTERNAL; 2544 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
2485 /* Taking an external interrupt does not clear the external 2545 /* Taking an external interrupt does not clear the external
2486 * interrupt status 2546 * interrupt status
2487 */ 2547 */
2488 #if 0 2548 #if 0
2489 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT); 2549 env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
2490 #endif 2550 #endif
2491 - raised = 1;  
2492 -#if 0 // TODO  
2493 - /* Thermal interrupt */  
2494 - } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {  
2495 - env->exception_index = EXCP_970_THRM;  
2496 - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);  
2497 - raised = 1; 2551 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
  2552 + return;
  2553 + }
2498 #endif 2554 #endif
  2555 +#if defined(TARGET_PPCEMB)
  2556 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
  2557 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
  2558 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
  2559 + return;
2499 } 2560 }
2500 -#if 0 // TODO  
2501 - /* External debug exception */  
2502 - } else if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {  
2503 - env->exception_index = EXCP_xxx;  
2504 - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);  
2505 - raised = 1;  
2506 #endif 2561 #endif
2507 - }  
2508 - if (raised != 0) {  
2509 - env->error_code = 0;  
2510 - do_interrupt(env); 2562 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
  2563 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
  2564 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
  2565 + return;
  2566 + }
  2567 + /* Thermal interrupt */
  2568 + if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {
  2569 + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);
  2570 + powerpc_excp(env, env->excp_model, POWERPC_EXCP_THERM);
  2571 + return;
  2572 + }
2511 } 2573 }
2512 } 2574 }
2513 #endif /* !CONFIG_USER_ONLY */ 2575 #endif /* !CONFIG_USER_ONLY */
@@ -2572,7 +2634,8 @@ void cpu_ppc_reset (void *opaque) @@ -2572,7 +2634,8 @@ void cpu_ppc_reset (void *opaque)
2572 env->reserve = -1; 2634 env->reserve = -1;
2573 /* Be sure no exception or interrupt is pending */ 2635 /* Be sure no exception or interrupt is pending */
2574 env->pending_interrupts = 0; 2636 env->pending_interrupts = 0;
2575 - env->exception_index = EXCP_NONE; 2637 + env->exception_index = POWERPC_EXCP_NONE;
  2638 + env->error_code = 0;
2576 /* Flush all TLBs */ 2639 /* Flush all TLBs */
2577 tlb_flush(env, 1); 2640 tlb_flush(env, 1);
2578 } 2641 }
target-ppc/op_helper.c
@@ -47,8 +47,8 @@ void do_raise_exception_err (uint32_t exception, int error_code) @@ -47,8 +47,8 @@ void do_raise_exception_err (uint32_t exception, int error_code)
47 printf("Raise exception %3x code : %d\n", exception, error_code); 47 printf("Raise exception %3x code : %d\n", exception, error_code);
48 #endif 48 #endif
49 switch (exception) { 49 switch (exception) {
50 - case EXCP_PROGRAM:  
51 - if (error_code == EXCP_FP && msr_fe0 == 0 && msr_fe1 == 0) 50 + case POWERPC_EXCP_PROGRAM:
  51 + if (error_code == POWERPC_EXCP_FP && msr_fe0 == 0 && msr_fe1 == 0)
52 return; 52 return;
53 break; 53 break;
54 default: 54 default:
@@ -947,7 +947,7 @@ void do_tw (int flags) @@ -947,7 +947,7 @@ void do_tw (int flags)
947 ((int32_t)T0 == (int32_t)T1 && (flags & 0x04)) || 947 ((int32_t)T0 == (int32_t)T1 && (flags & 0x04)) ||
948 ((uint32_t)T0 < (uint32_t)T1 && (flags & 0x02)) || 948 ((uint32_t)T0 < (uint32_t)T1 && (flags & 0x02)) ||
949 ((uint32_t)T0 > (uint32_t)T1 && (flags & 0x01))))) { 949 ((uint32_t)T0 > (uint32_t)T1 && (flags & 0x01))))) {
950 - do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); 950 + do_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
951 } 951 }
952 } 952 }
953 953
@@ -959,7 +959,7 @@ void do_td (int flags) @@ -959,7 +959,7 @@ void do_td (int flags)
959 ((int64_t)T0 == (int64_t)T1 && (flags & 0x04)) || 959 ((int64_t)T0 == (int64_t)T1 && (flags & 0x04)) ||
960 ((uint64_t)T0 < (uint64_t)T1 && (flags & 0x02)) || 960 ((uint64_t)T0 < (uint64_t)T1 && (flags & 0x02)) ||
961 ((uint64_t)T0 > (uint64_t)T1 && (flags & 0x01))))) 961 ((uint64_t)T0 > (uint64_t)T1 && (flags & 0x01)))))
962 - do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); 962 + do_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_TRAP);
963 } 963 }
964 #endif 964 #endif
965 965
@@ -1215,12 +1215,14 @@ void do_load_dcr (void) @@ -1215,12 +1215,14 @@ void do_load_dcr (void)
1215 if (loglevel != 0) { 1215 if (loglevel != 0) {
1216 fprintf(logfile, "No DCR environment\n"); 1216 fprintf(logfile, "No DCR environment\n");
1217 } 1217 }
1218 - do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL); 1218 + do_raise_exception_err(POWERPC_EXCP_PROGRAM,
  1219 + POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
1219 } else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) { 1220 } else if (unlikely(ppc_dcr_read(env->dcr_env, T0, &val) != 0)) {
1220 if (loglevel != 0) { 1221 if (loglevel != 0) {
1221 fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0); 1222 fprintf(logfile, "DCR read error %d %03x\n", (int)T0, (int)T0);
1222 } 1223 }
1223 - do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG); 1224 + do_raise_exception_err(POWERPC_EXCP_PROGRAM,
  1225 + POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
1224 } else { 1226 } else {
1225 T0 = val; 1227 T0 = val;
1226 } 1228 }
@@ -1232,12 +1234,14 @@ void do_store_dcr (void) @@ -1232,12 +1234,14 @@ void do_store_dcr (void)
1232 if (loglevel != 0) { 1234 if (loglevel != 0) {
1233 fprintf(logfile, "No DCR environment\n"); 1235 fprintf(logfile, "No DCR environment\n");
1234 } 1236 }
1235 - do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL); 1237 + do_raise_exception_err(POWERPC_EXCP_PROGRAM,
  1238 + POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL);
1236 } else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) { 1239 } else if (unlikely(ppc_dcr_write(env->dcr_env, T0, T1) != 0)) {
1237 if (loglevel != 0) { 1240 if (loglevel != 0) {
1238 fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0); 1241 fprintf(logfile, "DCR write error %d %03x\n", (int)T0, (int)T0);
1239 } 1242 }
1240 - do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG); 1243 + do_raise_exception_err(POWERPC_EXCP_PROGRAM,
  1244 + POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG);
1241 } 1245 }
1242 } 1246 }
1243 1247
target-ppc/op_mem.h
@@ -296,7 +296,9 @@ void OPPROTO glue(op_lswx, MEMSUFFIX) (void) @@ -296,7 +296,9 @@ void OPPROTO glue(op_lswx, MEMSUFFIX) (void)
296 if (likely(T1 != 0)) { 296 if (likely(T1 != 0)) {
297 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || 297 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
298 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { 298 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
299 - do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); 299 + do_raise_exception_err(POWERPC_EXCP_PROGRAM,
  300 + POWERPC_EXCP_INVAL |
  301 + POWERPC_EXCP_INVAL_LSWX);
300 } else { 302 } else {
301 glue(do_lsw, MEMSUFFIX)(PARAM1); 303 glue(do_lsw, MEMSUFFIX)(PARAM1);
302 } 304 }
@@ -311,7 +313,9 @@ void OPPROTO glue(op_lswx_64, MEMSUFFIX) (void) @@ -311,7 +313,9 @@ void OPPROTO glue(op_lswx_64, MEMSUFFIX) (void)
311 if (likely(T1 != 0)) { 313 if (likely(T1 != 0)) {
312 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || 314 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
313 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { 315 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
314 - do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); 316 + do_raise_exception_err(POWERPC_EXCP_PROGRAM,
  317 + POWERPC_EXCP_INVAL |
  318 + POWERPC_EXCP_INVAL_LSWX);
315 } else { 319 } else {
316 glue(do_lsw_64, MEMSUFFIX)(PARAM1); 320 glue(do_lsw_64, MEMSUFFIX)(PARAM1);
317 } 321 }
@@ -326,7 +330,9 @@ void OPPROTO glue(op_lswx_le, MEMSUFFIX) (void) @@ -326,7 +330,9 @@ void OPPROTO glue(op_lswx_le, MEMSUFFIX) (void)
326 if (likely(T1 != 0)) { 330 if (likely(T1 != 0)) {
327 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || 331 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
328 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { 332 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
329 - do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); 333 + do_raise_exception_err(POWERPC_EXCP_PROGRAM,
  334 + POWERPC_EXCP_INVAL |
  335 + POWERPC_EXCP_INVAL_LSWX);
330 } else { 336 } else {
331 glue(do_lsw_le, MEMSUFFIX)(PARAM1); 337 glue(do_lsw_le, MEMSUFFIX)(PARAM1);
332 } 338 }
@@ -341,7 +347,9 @@ void OPPROTO glue(op_lswx_le_64, MEMSUFFIX) (void) @@ -341,7 +347,9 @@ void OPPROTO glue(op_lswx_le_64, MEMSUFFIX) (void)
341 if (likely(T1 != 0)) { 347 if (likely(T1 != 0)) {
342 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) || 348 if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
343 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) { 349 (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
344 - do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); 350 + do_raise_exception_err(POWERPC_EXCP_PROGRAM,
  351 + POWERPC_EXCP_INVAL |
  352 + POWERPC_EXCP_INVAL_LSWX);
345 } else { 353 } else {
346 glue(do_lsw_le_64, MEMSUFFIX)(PARAM1); 354 glue(do_lsw_le_64, MEMSUFFIX)(PARAM1);
347 } 355 }
@@ -514,7 +522,7 @@ PPC_LDF_OP_64(fs_le, ldflr); @@ -514,7 +522,7 @@ PPC_LDF_OP_64(fs_le, ldflr);
514 void OPPROTO glue(op_lwarx, MEMSUFFIX) (void) 522 void OPPROTO glue(op_lwarx, MEMSUFFIX) (void)
515 { 523 {
516 if (unlikely(T0 & 0x03)) { 524 if (unlikely(T0 & 0x03)) {
517 - do_raise_exception(EXCP_ALIGN); 525 + do_raise_exception(POWERPC_EXCP_ALIGN);
518 } else { 526 } else {
519 T1 = glue(ldl, MEMSUFFIX)((uint32_t)T0); 527 T1 = glue(ldl, MEMSUFFIX)((uint32_t)T0);
520 env->reserve = (uint32_t)T0; 528 env->reserve = (uint32_t)T0;
@@ -526,7 +534,7 @@ void OPPROTO glue(op_lwarx, MEMSUFFIX) (void) @@ -526,7 +534,7 @@ void OPPROTO glue(op_lwarx, MEMSUFFIX) (void)
526 void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void) 534 void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void)
527 { 535 {
528 if (unlikely(T0 & 0x03)) { 536 if (unlikely(T0 & 0x03)) {
529 - do_raise_exception(EXCP_ALIGN); 537 + do_raise_exception(POWERPC_EXCP_ALIGN);
530 } else { 538 } else {
531 T1 = glue(ldl, MEMSUFFIX)((uint64_t)T0); 539 T1 = glue(ldl, MEMSUFFIX)((uint64_t)T0);
532 env->reserve = (uint64_t)T0; 540 env->reserve = (uint64_t)T0;
@@ -537,7 +545,7 @@ void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void) @@ -537,7 +545,7 @@ void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void)
537 void OPPROTO glue(op_ldarx, MEMSUFFIX) (void) 545 void OPPROTO glue(op_ldarx, MEMSUFFIX) (void)
538 { 546 {
539 if (unlikely(T0 & 0x03)) { 547 if (unlikely(T0 & 0x03)) {
540 - do_raise_exception(EXCP_ALIGN); 548 + do_raise_exception(POWERPC_EXCP_ALIGN);
541 } else { 549 } else {
542 T1 = glue(ldq, MEMSUFFIX)((uint32_t)T0); 550 T1 = glue(ldq, MEMSUFFIX)((uint32_t)T0);
543 env->reserve = (uint32_t)T0; 551 env->reserve = (uint32_t)T0;
@@ -548,7 +556,7 @@ void OPPROTO glue(op_ldarx, MEMSUFFIX) (void) @@ -548,7 +556,7 @@ void OPPROTO glue(op_ldarx, MEMSUFFIX) (void)
548 void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void) 556 void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void)
549 { 557 {
550 if (unlikely(T0 & 0x03)) { 558 if (unlikely(T0 & 0x03)) {
551 - do_raise_exception(EXCP_ALIGN); 559 + do_raise_exception(POWERPC_EXCP_ALIGN);
552 } else { 560 } else {
553 T1 = glue(ldq, MEMSUFFIX)((uint64_t)T0); 561 T1 = glue(ldq, MEMSUFFIX)((uint64_t)T0);
554 env->reserve = (uint64_t)T0; 562 env->reserve = (uint64_t)T0;
@@ -560,7 +568,7 @@ void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void) @@ -560,7 +568,7 @@ void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void)
560 void OPPROTO glue(op_lwarx_le, MEMSUFFIX) (void) 568 void OPPROTO glue(op_lwarx_le, MEMSUFFIX) (void)
561 { 569 {
562 if (unlikely(T0 & 0x03)) { 570 if (unlikely(T0 & 0x03)) {
563 - do_raise_exception(EXCP_ALIGN); 571 + do_raise_exception(POWERPC_EXCP_ALIGN);
564 } else { 572 } else {
565 T1 = glue(ld32r, MEMSUFFIX)((uint32_t)T0); 573 T1 = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
566 env->reserve = (uint32_t)T0; 574 env->reserve = (uint32_t)T0;
@@ -572,7 +580,7 @@ void OPPROTO glue(op_lwarx_le, MEMSUFFIX) (void) @@ -572,7 +580,7 @@ void OPPROTO glue(op_lwarx_le, MEMSUFFIX) (void)
572 void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void) 580 void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void)
573 { 581 {
574 if (unlikely(T0 & 0x03)) { 582 if (unlikely(T0 & 0x03)) {
575 - do_raise_exception(EXCP_ALIGN); 583 + do_raise_exception(POWERPC_EXCP_ALIGN);
576 } else { 584 } else {
577 T1 = glue(ld32r, MEMSUFFIX)((uint64_t)T0); 585 T1 = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
578 env->reserve = (uint64_t)T0; 586 env->reserve = (uint64_t)T0;
@@ -583,7 +591,7 @@ void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void) @@ -583,7 +591,7 @@ void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void)
583 void OPPROTO glue(op_ldarx_le, MEMSUFFIX) (void) 591 void OPPROTO glue(op_ldarx_le, MEMSUFFIX) (void)
584 { 592 {
585 if (unlikely(T0 & 0x03)) { 593 if (unlikely(T0 & 0x03)) {
586 - do_raise_exception(EXCP_ALIGN); 594 + do_raise_exception(POWERPC_EXCP_ALIGN);
587 } else { 595 } else {
588 T1 = glue(ld64r, MEMSUFFIX)((uint32_t)T0); 596 T1 = glue(ld64r, MEMSUFFIX)((uint32_t)T0);
589 env->reserve = (uint32_t)T0; 597 env->reserve = (uint32_t)T0;
@@ -594,7 +602,7 @@ void OPPROTO glue(op_ldarx_le, MEMSUFFIX) (void) @@ -594,7 +602,7 @@ void OPPROTO glue(op_ldarx_le, MEMSUFFIX) (void)
594 void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void) 602 void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void)
595 { 603 {
596 if (unlikely(T0 & 0x03)) { 604 if (unlikely(T0 & 0x03)) {
597 - do_raise_exception(EXCP_ALIGN); 605 + do_raise_exception(POWERPC_EXCP_ALIGN);
598 } else { 606 } else {
599 T1 = glue(ld64r, MEMSUFFIX)((uint64_t)T0); 607 T1 = glue(ld64r, MEMSUFFIX)((uint64_t)T0);
600 env->reserve = (uint64_t)T0; 608 env->reserve = (uint64_t)T0;
@@ -607,7 +615,7 @@ void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void) @@ -607,7 +615,7 @@ void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void)
607 void OPPROTO glue(op_stwcx, MEMSUFFIX) (void) 615 void OPPROTO glue(op_stwcx, MEMSUFFIX) (void)
608 { 616 {
609 if (unlikely(T0 & 0x03)) { 617 if (unlikely(T0 & 0x03)) {
610 - do_raise_exception(EXCP_ALIGN); 618 + do_raise_exception(POWERPC_EXCP_ALIGN);
611 } else { 619 } else {
612 if (unlikely(env->reserve != (uint32_t)T0)) { 620 if (unlikely(env->reserve != (uint32_t)T0)) {
613 env->crf[0] = xer_so; 621 env->crf[0] = xer_so;
@@ -624,7 +632,7 @@ void OPPROTO glue(op_stwcx, MEMSUFFIX) (void) @@ -624,7 +632,7 @@ void OPPROTO glue(op_stwcx, MEMSUFFIX) (void)
624 void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void) 632 void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void)
625 { 633 {
626 if (unlikely(T0 & 0x03)) { 634 if (unlikely(T0 & 0x03)) {
627 - do_raise_exception(EXCP_ALIGN); 635 + do_raise_exception(POWERPC_EXCP_ALIGN);
628 } else { 636 } else {
629 if (unlikely(env->reserve != (uint64_t)T0)) { 637 if (unlikely(env->reserve != (uint64_t)T0)) {
630 env->crf[0] = xer_so; 638 env->crf[0] = xer_so;
@@ -640,7 +648,7 @@ void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void) @@ -640,7 +648,7 @@ void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void)
640 void OPPROTO glue(op_stdcx, MEMSUFFIX) (void) 648 void OPPROTO glue(op_stdcx, MEMSUFFIX) (void)
641 { 649 {
642 if (unlikely(T0 & 0x03)) { 650 if (unlikely(T0 & 0x03)) {
643 - do_raise_exception(EXCP_ALIGN); 651 + do_raise_exception(POWERPC_EXCP_ALIGN);
644 } else { 652 } else {
645 if (unlikely(env->reserve != (uint32_t)T0)) { 653 if (unlikely(env->reserve != (uint32_t)T0)) {
646 env->crf[0] = xer_so; 654 env->crf[0] = xer_so;
@@ -656,7 +664,7 @@ void OPPROTO glue(op_stdcx, MEMSUFFIX) (void) @@ -656,7 +664,7 @@ void OPPROTO glue(op_stdcx, MEMSUFFIX) (void)
656 void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void) 664 void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void)
657 { 665 {
658 if (unlikely(T0 & 0x03)) { 666 if (unlikely(T0 & 0x03)) {
659 - do_raise_exception(EXCP_ALIGN); 667 + do_raise_exception(POWERPC_EXCP_ALIGN);
660 } else { 668 } else {
661 if (unlikely(env->reserve != (uint64_t)T0)) { 669 if (unlikely(env->reserve != (uint64_t)T0)) {
662 env->crf[0] = xer_so; 670 env->crf[0] = xer_so;
@@ -673,7 +681,7 @@ void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void) @@ -673,7 +681,7 @@ void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void)
673 void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void) 681 void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void)
674 { 682 {
675 if (unlikely(T0 & 0x03)) { 683 if (unlikely(T0 & 0x03)) {
676 - do_raise_exception(EXCP_ALIGN); 684 + do_raise_exception(POWERPC_EXCP_ALIGN);
677 } else { 685 } else {
678 if (unlikely(env->reserve != (uint32_t)T0)) { 686 if (unlikely(env->reserve != (uint32_t)T0)) {
679 env->crf[0] = xer_so; 687 env->crf[0] = xer_so;
@@ -690,7 +698,7 @@ void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void) @@ -690,7 +698,7 @@ void OPPROTO glue(op_stwcx_le, MEMSUFFIX) (void)
690 void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void) 698 void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void)
691 { 699 {
692 if (unlikely(T0 & 0x03)) { 700 if (unlikely(T0 & 0x03)) {
693 - do_raise_exception(EXCP_ALIGN); 701 + do_raise_exception(POWERPC_EXCP_ALIGN);
694 } else { 702 } else {
695 if (unlikely(env->reserve != (uint64_t)T0)) { 703 if (unlikely(env->reserve != (uint64_t)T0)) {
696 env->crf[0] = xer_so; 704 env->crf[0] = xer_so;
@@ -706,7 +714,7 @@ void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void) @@ -706,7 +714,7 @@ void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void)
706 void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void) 714 void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void)
707 { 715 {
708 if (unlikely(T0 & 0x03)) { 716 if (unlikely(T0 & 0x03)) {
709 - do_raise_exception(EXCP_ALIGN); 717 + do_raise_exception(POWERPC_EXCP_ALIGN);
710 } else { 718 } else {
711 if (unlikely(env->reserve != (uint32_t)T0)) { 719 if (unlikely(env->reserve != (uint32_t)T0)) {
712 env->crf[0] = xer_so; 720 env->crf[0] = xer_so;
@@ -722,7 +730,7 @@ void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void) @@ -722,7 +730,7 @@ void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void)
722 void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void) 730 void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void)
723 { 731 {
724 if (unlikely(T0 & 0x03)) { 732 if (unlikely(T0 & 0x03)) {
725 - do_raise_exception(EXCP_ALIGN); 733 + do_raise_exception(POWERPC_EXCP_ALIGN);
726 } else { 734 } else {
727 if (unlikely(env->reserve != (uint64_t)T0)) { 735 if (unlikely(env->reserve != (uint64_t)T0)) {
728 env->crf[0] = xer_so; 736 env->crf[0] = xer_so;
target-ppc/translate.c
@@ -207,35 +207,44 @@ static inline void gen_update_nip (DisasContext *ctx, target_ulong nip) @@ -207,35 +207,44 @@ static inline void gen_update_nip (DisasContext *ctx, target_ulong nip)
207 gen_op_update_nip(nip); 207 gen_op_update_nip(nip);
208 } 208 }
209 209
210 -#define RET_EXCP(ctx, excp, error) \ 210 +#define GEN_EXCP(ctx, excp, error) \
211 do { \ 211 do { \
212 - if ((ctx)->exception == EXCP_NONE) { \ 212 + if ((ctx)->exception == POWERPC_EXCP_NONE) { \
213 gen_update_nip(ctx, (ctx)->nip); \ 213 gen_update_nip(ctx, (ctx)->nip); \
214 } \ 214 } \
215 gen_op_raise_exception_err((excp), (error)); \ 215 gen_op_raise_exception_err((excp), (error)); \
216 ctx->exception = (excp); \ 216 ctx->exception = (excp); \
217 } while (0) 217 } while (0)
218 218
219 -#define RET_INVAL(ctx) \  
220 -RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_INVAL) 219 +#define GEN_EXCP_INVAL(ctx) \
  220 +GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
  221 + POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL)
221 222
222 -#define RET_PRIVOPC(ctx) \  
223 -RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_OPC) 223 +#define GEN_EXCP_PRIVOPC(ctx) \
  224 +GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
  225 + POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_OPC)
224 226
225 -#define RET_PRIVREG(ctx) \  
226 -RET_EXCP((ctx), EXCP_PROGRAM, EXCP_INVAL | EXCP_PRIV_REG) 227 +#define GEN_EXCP_PRIVREG(ctx) \
  228 +GEN_EXCP((ctx), POWERPC_EXCP_PROGRAM, \
  229 + POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG)
  230 +
  231 +#define GEN_EXCP_NO_FP(ctx) \
  232 +GEN_EXCP(ctx, POWERPC_EXCP_FPU, 0)
  233 +
  234 +#define GEN_EXCP_NO_AP(ctx) \
  235 +GEN_EXCP(ctx, POWERPC_EXCP_APU, 0)
227 236
228 /* Stop translation */ 237 /* Stop translation */
229 -static inline void RET_STOP (DisasContext *ctx) 238 +static inline void GEN_STOP (DisasContext *ctx)
230 { 239 {
231 gen_update_nip(ctx, ctx->nip); 240 gen_update_nip(ctx, ctx->nip);
232 - ctx->exception = EXCP_MTMSR; 241 + ctx->exception = POWERPC_EXCP_STOP;
233 } 242 }
234 243
235 /* No need to update nip here, as execution flow will change */ 244 /* No need to update nip here, as execution flow will change */
236 -static inline void RET_CHG_FLOW (DisasContext *ctx) 245 +static inline void GEN_SYNC (DisasContext *ctx)
237 { 246 {
238 - ctx->exception = EXCP_MTMSR; 247 + ctx->exception = POWERPC_EXCP_SYNC;
239 } 248 }
240 249
241 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \ 250 #define GEN_HANDLER(name, opc1, opc2, opc3, inval, type) \
@@ -535,7 +544,7 @@ GEN_OPCODE_MARK(start); @@ -535,7 +544,7 @@ GEN_OPCODE_MARK(start);
535 /* Invalid instruction */ 544 /* Invalid instruction */
536 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE) 545 GEN_HANDLER(invalid, 0x00, 0x00, 0x00, 0xFFFFFFFF, PPC_NONE)
537 { 546 {
538 - RET_INVAL(ctx); 547 + GEN_EXCP_INVAL(ctx);
539 } 548 }
540 549
541 static opc_handler_t invalid_handler = { 550 static opc_handler_t invalid_handler = {
@@ -1550,7 +1559,7 @@ __GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B); @@ -1550,7 +1559,7 @@ __GEN_LOGICAL2(srd, 0x1B, 0x10, PPC_64B);
1550 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \ 1559 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x00000000, type) \
1551 { \ 1560 { \
1552 if (unlikely(!ctx->fpu_enabled)) { \ 1561 if (unlikely(!ctx->fpu_enabled)) { \
1553 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 1562 + GEN_EXCP_NO_FP(ctx); \
1554 return; \ 1563 return; \
1555 } \ 1564 } \
1556 gen_op_reset_scrfx(); \ 1565 gen_op_reset_scrfx(); \
@@ -1574,7 +1583,7 @@ _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type); @@ -1574,7 +1583,7 @@ _GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, type);
1574 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ 1583 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1575 { \ 1584 { \
1576 if (unlikely(!ctx->fpu_enabled)) { \ 1585 if (unlikely(!ctx->fpu_enabled)) { \
1577 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 1586 + GEN_EXCP_NO_FP(ctx); \
1578 return; \ 1587 return; \
1579 } \ 1588 } \
1580 gen_op_reset_scrfx(); \ 1589 gen_op_reset_scrfx(); \
@@ -1596,7 +1605,7 @@ _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1); @@ -1596,7 +1605,7 @@ _GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1);
1596 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \ 1605 GEN_HANDLER(f##name, op1, op2, 0xFF, inval, PPC_FLOAT) \
1597 { \ 1606 { \
1598 if (unlikely(!ctx->fpu_enabled)) { \ 1607 if (unlikely(!ctx->fpu_enabled)) { \
1599 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 1608 + GEN_EXCP_NO_FP(ctx); \
1600 return; \ 1609 return; \
1601 } \ 1610 } \
1602 gen_op_reset_scrfx(); \ 1611 gen_op_reset_scrfx(); \
@@ -1618,7 +1627,7 @@ _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1); @@ -1618,7 +1627,7 @@ _GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1);
1618 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \ 1627 GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \
1619 { \ 1628 { \
1620 if (unlikely(!ctx->fpu_enabled)) { \ 1629 if (unlikely(!ctx->fpu_enabled)) { \
1621 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 1630 + GEN_EXCP_NO_FP(ctx); \
1622 return; \ 1631 return; \
1623 } \ 1632 } \
1624 gen_op_reset_scrfx(); \ 1633 gen_op_reset_scrfx(); \
@@ -1633,7 +1642,7 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \ @@ -1633,7 +1642,7 @@ GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type) \
1633 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type) \ 1642 GEN_HANDLER(f##name, op1, op2, 0xFF, 0x001F07C0, type) \
1634 { \ 1643 { \
1635 if (unlikely(!ctx->fpu_enabled)) { \ 1644 if (unlikely(!ctx->fpu_enabled)) { \
1636 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 1645 + GEN_EXCP_NO_FP(ctx); \
1637 return; \ 1646 return; \
1638 } \ 1647 } \
1639 gen_op_reset_scrfx(); \ 1648 gen_op_reset_scrfx(); \
@@ -1666,7 +1675,7 @@ GEN_FLOAT_AB(sub, 0x14, 0x000007C0); @@ -1666,7 +1675,7 @@ GEN_FLOAT_AB(sub, 0x14, 0x000007C0);
1666 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT) 1675 GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1667 { 1676 {
1668 if (unlikely(!ctx->fpu_enabled)) { 1677 if (unlikely(!ctx->fpu_enabled)) {
1669 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1678 + GEN_EXCP_NO_FP(ctx);
1670 return; 1679 return;
1671 } 1680 }
1672 gen_op_reset_scrfx(); 1681 gen_op_reset_scrfx();
@@ -1680,7 +1689,7 @@ GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT) @@ -1680,7 +1689,7 @@ GEN_HANDLER(fsqrt, 0x3F, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1680 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT) 1689 GEN_HANDLER(fsqrts, 0x3B, 0x16, 0xFF, 0x001F07C0, PPC_FLOAT_FSQRT)
1681 { 1690 {
1682 if (unlikely(!ctx->fpu_enabled)) { 1691 if (unlikely(!ctx->fpu_enabled)) {
1683 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1692 + GEN_EXCP_NO_FP(ctx);
1684 return; 1693 return;
1685 } 1694 }
1686 gen_op_reset_scrfx(); 1695 gen_op_reset_scrfx();
@@ -1723,7 +1732,7 @@ GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B); @@ -1723,7 +1732,7 @@ GEN_FLOAT_B(ctidz, 0x0F, 0x19, PPC_64B);
1723 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) 1732 GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1724 { 1733 {
1725 if (unlikely(!ctx->fpu_enabled)) { 1734 if (unlikely(!ctx->fpu_enabled)) {
1726 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1735 + GEN_EXCP_NO_FP(ctx);
1727 return; 1736 return;
1728 } 1737 }
1729 gen_op_reset_scrfx(); 1738 gen_op_reset_scrfx();
@@ -1737,7 +1746,7 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT) @@ -1737,7 +1746,7 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
1737 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT) 1746 GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
1738 { 1747 {
1739 if (unlikely(!ctx->fpu_enabled)) { 1748 if (unlikely(!ctx->fpu_enabled)) {
1740 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1749 + GEN_EXCP_NO_FP(ctx);
1741 return; 1750 return;
1742 } 1751 }
1743 gen_op_reset_scrfx(); 1752 gen_op_reset_scrfx();
@@ -1755,7 +1764,7 @@ GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT); @@ -1755,7 +1764,7 @@ GEN_FLOAT_B(abs, 0x08, 0x08, PPC_FLOAT);
1755 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT) 1764 GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT)
1756 { 1765 {
1757 if (unlikely(!ctx->fpu_enabled)) { 1766 if (unlikely(!ctx->fpu_enabled)) {
1758 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1767 + GEN_EXCP_NO_FP(ctx);
1759 return; 1768 return;
1760 } 1769 }
1761 gen_op_reset_scrfx(); 1770 gen_op_reset_scrfx();
@@ -1775,7 +1784,7 @@ GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT); @@ -1775,7 +1784,7 @@ GEN_FLOAT_B(neg, 0x08, 0x01, PPC_FLOAT);
1775 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) 1784 GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1776 { 1785 {
1777 if (unlikely(!ctx->fpu_enabled)) { 1786 if (unlikely(!ctx->fpu_enabled)) {
1778 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1787 + GEN_EXCP_NO_FP(ctx);
1779 return; 1788 return;
1780 } 1789 }
1781 gen_op_load_fpscr_T0(crfS(ctx->opcode)); 1790 gen_op_load_fpscr_T0(crfS(ctx->opcode));
@@ -1787,7 +1796,7 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT) @@ -1787,7 +1796,7 @@ GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT)
1787 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT) 1796 GEN_HANDLER(mffs, 0x3F, 0x07, 0x12, 0x001FF800, PPC_FLOAT)
1788 { 1797 {
1789 if (unlikely(!ctx->fpu_enabled)) { 1798 if (unlikely(!ctx->fpu_enabled)) {
1790 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1799 + GEN_EXCP_NO_FP(ctx);
1791 return; 1800 return;
1792 } 1801 }
1793 gen_op_load_fpscr(); 1802 gen_op_load_fpscr();
@@ -1802,7 +1811,7 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT) @@ -1802,7 +1811,7 @@ GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT)
1802 uint8_t crb; 1811 uint8_t crb;
1803 1812
1804 if (unlikely(!ctx->fpu_enabled)) { 1813 if (unlikely(!ctx->fpu_enabled)) {
1805 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1814 + GEN_EXCP_NO_FP(ctx);
1806 return; 1815 return;
1807 } 1816 }
1808 crb = crbD(ctx->opcode) >> 2; 1817 crb = crbD(ctx->opcode) >> 2;
@@ -1819,7 +1828,7 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) @@ -1819,7 +1828,7 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1819 uint8_t crb; 1828 uint8_t crb;
1820 1829
1821 if (unlikely(!ctx->fpu_enabled)) { 1830 if (unlikely(!ctx->fpu_enabled)) {
1822 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1831 + GEN_EXCP_NO_FP(ctx);
1823 return; 1832 return;
1824 } 1833 }
1825 crb = crbD(ctx->opcode) >> 2; 1834 crb = crbD(ctx->opcode) >> 2;
@@ -1834,7 +1843,7 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT) @@ -1834,7 +1843,7 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
1834 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) 1843 GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1835 { 1844 {
1836 if (unlikely(!ctx->fpu_enabled)) { 1845 if (unlikely(!ctx->fpu_enabled)) {
1837 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1846 + GEN_EXCP_NO_FP(ctx);
1838 return; 1847 return;
1839 } 1848 }
1840 gen_op_load_fpr_FT0(rB(ctx->opcode)); 1849 gen_op_load_fpr_FT0(rB(ctx->opcode));
@@ -1847,7 +1856,7 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT) @@ -1847,7 +1856,7 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
1847 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) 1856 GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1848 { 1857 {
1849 if (unlikely(!ctx->fpu_enabled)) { 1858 if (unlikely(!ctx->fpu_enabled)) {
1850 - RET_EXCP(ctx, EXCP_NO_FP, 0); 1859 + GEN_EXCP_NO_FP(ctx);
1851 return; 1860 return;
1852 } 1861 }
1853 gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode)); 1862 gen_op_store_T0_fpscri(crbD(ctx->opcode) >> 2, FPIMM(ctx->opcode));
@@ -2002,7 +2011,7 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \ @@ -2002,7 +2011,7 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
2002 { \ 2011 { \
2003 if (unlikely(rA(ctx->opcode) == 0 || \ 2012 if (unlikely(rA(ctx->opcode) == 0 || \
2004 rA(ctx->opcode) == rD(ctx->opcode))) { \ 2013 rA(ctx->opcode) == rD(ctx->opcode))) { \
2005 - RET_INVAL(ctx); \ 2014 + GEN_EXCP_INVAL(ctx); \
2006 return; \ 2015 return; \
2007 } \ 2016 } \
2008 if (type == PPC_64B) \ 2017 if (type == PPC_64B) \
@@ -2019,7 +2028,7 @@ GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \ @@ -2019,7 +2028,7 @@ GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
2019 { \ 2028 { \
2020 if (unlikely(rA(ctx->opcode) == 0 || \ 2029 if (unlikely(rA(ctx->opcode) == 0 || \
2021 rA(ctx->opcode) == rD(ctx->opcode))) { \ 2030 rA(ctx->opcode) == rD(ctx->opcode))) { \
2022 - RET_INVAL(ctx); \ 2031 + GEN_EXCP_INVAL(ctx); \
2023 return; \ 2032 return; \
2024 } \ 2033 } \
2025 gen_addr_reg_index(ctx); \ 2034 gen_addr_reg_index(ctx); \
@@ -2067,7 +2076,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B) @@ -2067,7 +2076,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
2067 if (Rc(ctx->opcode)) { 2076 if (Rc(ctx->opcode)) {
2068 if (unlikely(rA(ctx->opcode) == 0 || 2077 if (unlikely(rA(ctx->opcode) == 0 ||
2069 rA(ctx->opcode) == rD(ctx->opcode))) { 2078 rA(ctx->opcode) == rD(ctx->opcode))) {
2070 - RET_INVAL(ctx); 2079 + GEN_EXCP_INVAL(ctx);
2071 return; 2080 return;
2072 } 2081 }
2073 } 2082 }
@@ -2098,7 +2107,7 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \ @@ -2098,7 +2107,7 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
2098 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \ 2107 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
2099 { \ 2108 { \
2100 if (unlikely(rA(ctx->opcode) == 0)) { \ 2109 if (unlikely(rA(ctx->opcode) == 0)) { \
2101 - RET_INVAL(ctx); \ 2110 + GEN_EXCP_INVAL(ctx); \
2102 return; \ 2111 return; \
2103 } \ 2112 } \
2104 if (type == PPC_64B) \ 2113 if (type == PPC_64B) \
@@ -2114,7 +2123,7 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \ @@ -2114,7 +2123,7 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
2114 GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \ 2123 GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type) \
2115 { \ 2124 { \
2116 if (unlikely(rA(ctx->opcode) == 0)) { \ 2125 if (unlikely(rA(ctx->opcode) == 0)) { \
2117 - RET_INVAL(ctx); \ 2126 + GEN_EXCP_INVAL(ctx); \
2118 return; \ 2127 return; \
2119 } \ 2128 } \
2120 gen_addr_reg_index(ctx); \ 2129 gen_addr_reg_index(ctx); \
@@ -2152,7 +2161,7 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B) @@ -2152,7 +2161,7 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2152 { 2161 {
2153 if (Rc(ctx->opcode)) { 2162 if (Rc(ctx->opcode)) {
2154 if (unlikely(rA(ctx->opcode) == 0)) { 2163 if (unlikely(rA(ctx->opcode) == 0)) {
2155 - RET_INVAL(ctx); 2164 + GEN_EXCP_INVAL(ctx);
2156 return; 2165 return;
2157 } 2166 }
2158 } 2167 }
@@ -2367,7 +2376,8 @@ GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER) @@ -2367,7 +2376,8 @@ GEN_HANDLER(lswi, 0x1F, 0x15, 0x12, 0x00000001, PPC_INTEGER)
2367 if (unlikely(((start + nr) > 32 && 2376 if (unlikely(((start + nr) > 32 &&
2368 start <= ra && (start + nr - 32) > ra) || 2377 start <= ra && (start + nr - 32) > ra) ||
2369 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) { 2378 ((start + nr) <= 32 && start <= ra && (start + nr) > ra))) {
2370 - RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX); 2379 + GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
  2380 + POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_LSWX);
2371 return; 2381 return;
2372 } 2382 }
2373 /* NIP cannot be restored if the memory exception comes from an helper */ 2383 /* NIP cannot be restored if the memory exception comes from an helper */
@@ -2426,6 +2436,7 @@ GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO) @@ -2426,6 +2436,7 @@ GEN_HANDLER(eieio, 0x1F, 0x16, 0x1A, 0x03FF0801, PPC_MEM_EIEIO)
2426 /* isync */ 2436 /* isync */
2427 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM) 2437 GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FF0801, PPC_MEM)
2428 { 2438 {
  2439 + GEN_STOP(ctx);
2429 } 2440 }
2430 2441
2431 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])() 2442 #define op_lwarx() (*gen_op_lwarx[ctx->mem_idx])()
@@ -2574,7 +2585,7 @@ GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03CF0801, PPC_MEM_SYNC) @@ -2574,7 +2585,7 @@ GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03CF0801, PPC_MEM_SYNC)
2574 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ 2585 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2575 { \ 2586 { \
2576 if (unlikely(!ctx->fpu_enabled)) { \ 2587 if (unlikely(!ctx->fpu_enabled)) { \
2577 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2588 + GEN_EXCP_NO_FP(ctx); \
2578 return; \ 2589 return; \
2579 } \ 2590 } \
2580 gen_addr_imm_index(ctx, 0); \ 2591 gen_addr_imm_index(ctx, 0); \
@@ -2586,11 +2597,11 @@ GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2586,11 +2597,11 @@ GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2586 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ 2597 GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2587 { \ 2598 { \
2588 if (unlikely(!ctx->fpu_enabled)) { \ 2599 if (unlikely(!ctx->fpu_enabled)) { \
2589 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2600 + GEN_EXCP_NO_FP(ctx); \
2590 return; \ 2601 return; \
2591 } \ 2602 } \
2592 if (unlikely(rA(ctx->opcode) == 0)) { \ 2603 if (unlikely(rA(ctx->opcode) == 0)) { \
2593 - RET_INVAL(ctx); \ 2604 + GEN_EXCP_INVAL(ctx); \
2594 return; \ 2605 return; \
2595 } \ 2606 } \
2596 gen_addr_imm_index(ctx, 0); \ 2607 gen_addr_imm_index(ctx, 0); \
@@ -2603,11 +2614,11 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2603,11 +2614,11 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2603 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ 2614 GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2604 { \ 2615 { \
2605 if (unlikely(!ctx->fpu_enabled)) { \ 2616 if (unlikely(!ctx->fpu_enabled)) { \
2606 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2617 + GEN_EXCP_NO_FP(ctx); \
2607 return; \ 2618 return; \
2608 } \ 2619 } \
2609 if (unlikely(rA(ctx->opcode) == 0)) { \ 2620 if (unlikely(rA(ctx->opcode) == 0)) { \
2610 - RET_INVAL(ctx); \ 2621 + GEN_EXCP_INVAL(ctx); \
2611 return; \ 2622 return; \
2612 } \ 2623 } \
2613 gen_addr_reg_index(ctx); \ 2624 gen_addr_reg_index(ctx); \
@@ -2620,7 +2631,7 @@ GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ @@ -2620,7 +2631,7 @@ GEN_HANDLER(l##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2620 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \ 2631 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2621 { \ 2632 { \
2622 if (unlikely(!ctx->fpu_enabled)) { \ 2633 if (unlikely(!ctx->fpu_enabled)) { \
2623 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2634 + GEN_EXCP_NO_FP(ctx); \
2624 return; \ 2635 return; \
2625 } \ 2636 } \
2626 gen_addr_reg_index(ctx); \ 2637 gen_addr_reg_index(ctx); \
@@ -2645,7 +2656,7 @@ GEN_LDFS(fs, 0x10); @@ -2645,7 +2656,7 @@ GEN_LDFS(fs, 0x10);
2645 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ 2656 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2646 { \ 2657 { \
2647 if (unlikely(!ctx->fpu_enabled)) { \ 2658 if (unlikely(!ctx->fpu_enabled)) { \
2648 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2659 + GEN_EXCP_NO_FP(ctx); \
2649 return; \ 2660 return; \
2650 } \ 2661 } \
2651 gen_addr_imm_index(ctx, 0); \ 2662 gen_addr_imm_index(ctx, 0); \
@@ -2657,11 +2668,11 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2657,11 +2668,11 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2657 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ 2668 GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2658 { \ 2669 { \
2659 if (unlikely(!ctx->fpu_enabled)) { \ 2670 if (unlikely(!ctx->fpu_enabled)) { \
2660 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2671 + GEN_EXCP_NO_FP(ctx); \
2661 return; \ 2672 return; \
2662 } \ 2673 } \
2663 if (unlikely(rA(ctx->opcode) == 0)) { \ 2674 if (unlikely(rA(ctx->opcode) == 0)) { \
2664 - RET_INVAL(ctx); \ 2675 + GEN_EXCP_INVAL(ctx); \
2665 return; \ 2676 return; \
2666 } \ 2677 } \
2667 gen_addr_imm_index(ctx, 0); \ 2678 gen_addr_imm_index(ctx, 0); \
@@ -2674,11 +2685,11 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2674,11 +2685,11 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2674 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ 2685 GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2675 { \ 2686 { \
2676 if (unlikely(!ctx->fpu_enabled)) { \ 2687 if (unlikely(!ctx->fpu_enabled)) { \
2677 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2688 + GEN_EXCP_NO_FP(ctx); \
2678 return; \ 2689 return; \
2679 } \ 2690 } \
2680 if (unlikely(rA(ctx->opcode) == 0)) { \ 2691 if (unlikely(rA(ctx->opcode) == 0)) { \
2681 - RET_INVAL(ctx); \ 2692 + GEN_EXCP_INVAL(ctx); \
2682 return; \ 2693 return; \
2683 } \ 2694 } \
2684 gen_addr_reg_index(ctx); \ 2695 gen_addr_reg_index(ctx); \
@@ -2691,7 +2702,7 @@ GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \ @@ -2691,7 +2702,7 @@ GEN_HANDLER(st##width##ux, 0x1F, 0x17, opc, 0x00000001, PPC_FLOAT) \
2691 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \ 2702 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, PPC_FLOAT) \
2692 { \ 2703 { \
2693 if (unlikely(!ctx->fpu_enabled)) { \ 2704 if (unlikely(!ctx->fpu_enabled)) { \
2694 - RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2705 + GEN_EXCP_NO_FP(ctx); \
2695 return; \ 2706 return; \
2696 } \ 2707 } \
2697 gen_addr_reg_index(ctx); \ 2708 gen_addr_reg_index(ctx); \
@@ -2716,12 +2727,12 @@ GEN_STFS(fs, 0x14); @@ -2716,12 +2727,12 @@ GEN_STFS(fs, 0x14);
2716 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT_STFIWX) 2727 GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT_STFIWX)
2717 { 2728 {
2718 if (unlikely(!ctx->fpu_enabled)) { 2729 if (unlikely(!ctx->fpu_enabled)) {
2719 - RET_EXCP(ctx, EXCP_NO_FP, 0); 2730 + GEN_EXCP_NO_FP(ctx);
2720 return; 2731 return;
2721 } 2732 }
2722 gen_addr_reg_index(ctx); 2733 gen_addr_reg_index(ctx);
2723 /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */ 2734 /* XXX: TODO: memcpy low order 32 bits of FRP(rs) into memory */
2724 - RET_INVAL(ctx); 2735 + GEN_EXCP_INVAL(ctx);
2725 } 2736 }
2726 2737
2727 /*** Branch ***/ 2738 /*** Branch ***/
@@ -2760,6 +2771,16 @@ static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest) @@ -2760,6 +2771,16 @@ static inline void gen_goto_tb (DisasContext *ctx, int n, target_ulong dest)
2760 } 2771 }
2761 } 2772 }
2762 2773
  2774 +static inline void gen_setlr (DisasContext *ctx, target_ulong nip)
  2775 +{
  2776 +#if defined(TARGET_PPC64)
  2777 + if (ctx->sf_mode != 0 && (nip >> 32))
  2778 + gen_op_setlr_64(ctx->nip >> 32, ctx->nip);
  2779 + else
  2780 +#endif
  2781 + gen_op_setlr(ctx->nip);
  2782 +}
  2783 +
2763 /* b ba bl bla */ 2784 /* b ba bl bla */
2764 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) 2785 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2765 { 2786 {
@@ -2776,16 +2797,14 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) @@ -2776,16 +2797,14 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
2776 target = ctx->nip + li - 4; 2797 target = ctx->nip + li - 4;
2777 else 2798 else
2778 target = li; 2799 target = li;
2779 - if (LK(ctx->opcode)) {  
2780 #if defined(TARGET_PPC64) 2800 #if defined(TARGET_PPC64)
2781 - if (ctx->sf_mode)  
2782 - gen_op_setlr_64(ctx->nip >> 32, ctx->nip);  
2783 - else 2801 + if (!ctx->sf_mode)
  2802 + target = (uint32_t)target;
2784 #endif 2803 #endif
2785 - gen_op_setlr(ctx->nip);  
2786 - } 2804 + if (LK(ctx->opcode))
  2805 + gen_setlr(ctx, ctx->nip);
2787 gen_goto_tb(ctx, 0, target); 2806 gen_goto_tb(ctx, 0, target);
2788 - ctx->exception = EXCP_BRANCH; 2807 + ctx->exception = POWERPC_EXCP_BRANCH;
2789 } 2808 }
2790 2809
2791 #define BCOND_IM 0 2810 #define BCOND_IM 0
@@ -2810,6 +2829,10 @@ static inline void gen_bcond (DisasContext *ctx, int type) @@ -2810,6 +2829,10 @@ static inline void gen_bcond (DisasContext *ctx, int type)
2810 } else { 2829 } else {
2811 target = li; 2830 target = li;
2812 } 2831 }
  2832 +#if defined(TARGET_PPC64)
  2833 + if (!ctx->sf_mode)
  2834 + target = (uint32_t)target;
  2835 +#endif
2813 break; 2836 break;
2814 case BCOND_CTR: 2837 case BCOND_CTR:
2815 gen_op_movl_T1_ctr(); 2838 gen_op_movl_T1_ctr();
@@ -2819,14 +2842,8 @@ static inline void gen_bcond (DisasContext *ctx, int type) @@ -2819,14 +2842,8 @@ static inline void gen_bcond (DisasContext *ctx, int type)
2819 gen_op_movl_T1_lr(); 2842 gen_op_movl_T1_lr();
2820 break; 2843 break;
2821 } 2844 }
2822 - if (LK(ctx->opcode)) {  
2823 -#if defined(TARGET_PPC64)  
2824 - if (ctx->sf_mode)  
2825 - gen_op_setlr_64(ctx->nip >> 32, ctx->nip);  
2826 - else  
2827 -#endif  
2828 - gen_op_setlr(ctx->nip);  
2829 - } 2845 + if (LK(ctx->opcode))
  2846 + gen_setlr(ctx, ctx->nip);
2830 if (bo & 0x10) { 2847 if (bo & 0x10) {
2831 /* No CR condition */ 2848 /* No CR condition */
2832 switch (bo & 0x6) { 2849 switch (bo & 0x6) {
@@ -2934,7 +2951,7 @@ static inline void gen_bcond (DisasContext *ctx, int type) @@ -2934,7 +2951,7 @@ static inline void gen_bcond (DisasContext *ctx, int type)
2934 gen_op_debug(); 2951 gen_op_debug();
2935 gen_op_exit_tb(); 2952 gen_op_exit_tb();
2936 } 2953 }
2937 - ctx->exception = EXCP_BRANCH; 2954 + ctx->exception = POWERPC_EXCP_BRANCH;
2938 } 2955 }
2939 2956
2940 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW) 2957 GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
@@ -2995,15 +3012,15 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER) @@ -2995,15 +3012,15 @@ GEN_HANDLER(mcrf, 0x13, 0x00, 0xFF, 0x00000001, PPC_INTEGER)
2995 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW) 3012 GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
2996 { 3013 {
2997 #if defined(CONFIG_USER_ONLY) 3014 #if defined(CONFIG_USER_ONLY)
2998 - RET_PRIVOPC(ctx); 3015 + GEN_EXCP_PRIVOPC(ctx);
2999 #else 3016 #else
3000 /* Restore CPU state */ 3017 /* Restore CPU state */
3001 if (unlikely(!ctx->supervisor)) { 3018 if (unlikely(!ctx->supervisor)) {
3002 - RET_PRIVOPC(ctx); 3019 + GEN_EXCP_PRIVOPC(ctx);
3003 return; 3020 return;
3004 } 3021 }
3005 gen_op_rfi(); 3022 gen_op_rfi();
3006 - RET_CHG_FLOW(ctx); 3023 + GEN_SYNC(ctx);
3007 #endif 3024 #endif
3008 } 3025 }
3009 3026
@@ -3011,26 +3028,29 @@ GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW) @@ -3011,26 +3028,29 @@ GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW)
3011 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B) 3028 GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_64B)
3012 { 3029 {
3013 #if defined(CONFIG_USER_ONLY) 3030 #if defined(CONFIG_USER_ONLY)
3014 - RET_PRIVOPC(ctx); 3031 + GEN_EXCP_PRIVOPC(ctx);
3015 #else 3032 #else
3016 /* Restore CPU state */ 3033 /* Restore CPU state */
3017 if (unlikely(!ctx->supervisor)) { 3034 if (unlikely(!ctx->supervisor)) {
3018 - RET_PRIVOPC(ctx); 3035 + GEN_EXCP_PRIVOPC(ctx);
3019 return; 3036 return;
3020 } 3037 }
3021 gen_op_rfid(); 3038 gen_op_rfid();
3022 - RET_CHG_FLOW(ctx); 3039 + GEN_SYNC(ctx);
3023 #endif 3040 #endif
3024 } 3041 }
3025 #endif 3042 #endif
3026 3043
3027 /* sc */ 3044 /* sc */
3028 -GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW) 3045 +GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFF01D, PPC_FLOW)
3029 { 3046 {
  3047 + uint32_t lev;
  3048 +
  3049 + lev = (ctx->opcode >> 5) & 0x7F;
3030 #if defined(CONFIG_USER_ONLY) 3050 #if defined(CONFIG_USER_ONLY)
3031 - RET_EXCP(ctx, EXCP_SYSCALL_USER, 0); 3051 + GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL_USER, lev);
3032 #else 3052 #else
3033 - RET_EXCP(ctx, EXCP_SYSCALL, 0); 3053 + GEN_EXCP(ctx, POWERPC_EXCP_SYSCALL, lev);
3034 #endif 3054 #endif
3035 } 3055 }
3036 3056
@@ -3108,10 +3128,10 @@ GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC) @@ -3108,10 +3128,10 @@ GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
3108 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC) 3128 GEN_HANDLER(mfmsr, 0x1F, 0x13, 0x02, 0x001FF801, PPC_MISC)
3109 { 3129 {
3110 #if defined(CONFIG_USER_ONLY) 3130 #if defined(CONFIG_USER_ONLY)
3111 - RET_PRIVREG(ctx); 3131 + GEN_EXCP_PRIVREG(ctx);
3112 #else 3132 #else
3113 if (unlikely(!ctx->supervisor)) { 3133 if (unlikely(!ctx->supervisor)) {
3114 - RET_PRIVREG(ctx); 3134 + GEN_EXCP_PRIVREG(ctx);
3115 return; 3135 return;
3116 } 3136 }
3117 gen_op_load_msr(); 3137 gen_op_load_msr();
@@ -3153,7 +3173,7 @@ static inline void gen_op_mfspr (DisasContext *ctx) @@ -3153,7 +3173,7 @@ static inline void gen_op_mfspr (DisasContext *ctx)
3153 sprn, sprn); 3173 sprn, sprn);
3154 } 3174 }
3155 printf("Trying to read privileged spr %d %03x\n", sprn, sprn); 3175 printf("Trying to read privileged spr %d %03x\n", sprn, sprn);
3156 - RET_PRIVREG(ctx); 3176 + GEN_EXCP_PRIVREG(ctx);
3157 } 3177 }
3158 } else { 3178 } else {
3159 /* Not defined */ 3179 /* Not defined */
@@ -3162,7 +3182,8 @@ static inline void gen_op_mfspr (DisasContext *ctx) @@ -3162,7 +3182,8 @@ static inline void gen_op_mfspr (DisasContext *ctx)
3162 sprn, sprn); 3182 sprn, sprn);
3163 } 3183 }
3164 printf("Trying to read invalid spr %d %03x\n", sprn, sprn); 3184 printf("Trying to read invalid spr %d %03x\n", sprn, sprn);
3165 - RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR); 3185 + GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
  3186 + POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3166 } 3187 }
3167 } 3188 }
3168 3189
@@ -3199,17 +3220,17 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC) @@ -3199,17 +3220,17 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
3199 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B) 3220 GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
3200 { 3221 {
3201 #if defined(CONFIG_USER_ONLY) 3222 #if defined(CONFIG_USER_ONLY)
3202 - RET_PRIVREG(ctx); 3223 + GEN_EXCP_PRIVREG(ctx);
3203 #else 3224 #else
3204 if (unlikely(!ctx->supervisor)) { 3225 if (unlikely(!ctx->supervisor)) {
3205 - RET_PRIVREG(ctx); 3226 + GEN_EXCP_PRIVREG(ctx);
3206 return; 3227 return;
3207 } 3228 }
3208 gen_update_nip(ctx, ctx->nip); 3229 gen_update_nip(ctx, ctx->nip);
3209 gen_op_load_gpr_T0(rS(ctx->opcode)); 3230 gen_op_load_gpr_T0(rS(ctx->opcode));
3210 gen_op_store_msr(); 3231 gen_op_store_msr();
3211 /* Must stop the translation as machine state (may have) changed */ 3232 /* Must stop the translation as machine state (may have) changed */
3212 - RET_CHG_FLOW(ctx); 3233 + GEN_SYNC(ctx);
3213 #endif 3234 #endif
3214 } 3235 }
3215 #endif 3236 #endif
@@ -3217,10 +3238,10 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B) @@ -3217,10 +3238,10 @@ GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_64B)
3217 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) 3238 GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3218 { 3239 {
3219 #if defined(CONFIG_USER_ONLY) 3240 #if defined(CONFIG_USER_ONLY)
3220 - RET_PRIVREG(ctx); 3241 + GEN_EXCP_PRIVREG(ctx);
3221 #else 3242 #else
3222 if (unlikely(!ctx->supervisor)) { 3243 if (unlikely(!ctx->supervisor)) {
3223 - RET_PRIVREG(ctx); 3244 + GEN_EXCP_PRIVREG(ctx);
3224 return; 3245 return;
3225 } 3246 }
3226 gen_update_nip(ctx, ctx->nip); 3247 gen_update_nip(ctx, ctx->nip);
@@ -3232,7 +3253,7 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) @@ -3232,7 +3253,7 @@ GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC)
3232 #endif 3253 #endif
3233 gen_op_store_msr(); 3254 gen_op_store_msr();
3234 /* Must stop the translation as machine state (may have) changed */ 3255 /* Must stop the translation as machine state (may have) changed */
3235 - RET_CHG_FLOW(ctx); 3256 + GEN_SYNC(ctx);
3236 #endif 3257 #endif
3237 } 3258 }
3238 3259
@@ -3259,7 +3280,7 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) @@ -3259,7 +3280,7 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3259 sprn, sprn); 3280 sprn, sprn);
3260 } 3281 }
3261 printf("Trying to write privileged spr %d %03x\n", sprn, sprn); 3282 printf("Trying to write privileged spr %d %03x\n", sprn, sprn);
3262 - RET_PRIVREG(ctx); 3283 + GEN_EXCP_PRIVREG(ctx);
3263 } 3284 }
3264 } else { 3285 } else {
3265 /* Not defined */ 3286 /* Not defined */
@@ -3268,7 +3289,8 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC) @@ -3268,7 +3289,8 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
3268 sprn, sprn); 3289 sprn, sprn);
3269 } 3290 }
3270 printf("Trying to write invalid spr %d %03x\n", sprn, sprn); 3291 printf("Trying to write invalid spr %d %03x\n", sprn, sprn);
3271 - RET_EXCP(ctx, EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_SPR); 3292 + GEN_EXCP(ctx, POWERPC_EXCP_PROGRAM,
  3293 + POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_SPR);
3272 } 3294 }
3273 } 3295 }
3274 3296
@@ -3288,10 +3310,10 @@ GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE) @@ -3288,10 +3310,10 @@ GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03E00001, PPC_CACHE)
3288 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE) 3310 GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
3289 { 3311 {
3290 #if defined(CONFIG_USER_ONLY) 3312 #if defined(CONFIG_USER_ONLY)
3291 - RET_PRIVOPC(ctx); 3313 + GEN_EXCP_PRIVOPC(ctx);
3292 #else 3314 #else
3293 if (unlikely(!ctx->supervisor)) { 3315 if (unlikely(!ctx->supervisor)) {
3294 - RET_PRIVOPC(ctx); 3316 + GEN_EXCP_PRIVOPC(ctx);
3295 return; 3317 return;
3296 } 3318 }
3297 gen_addr_reg_index(ctx); 3319 gen_addr_reg_index(ctx);
@@ -3407,13 +3429,11 @@ static GenOpFunc *gen_op_icbi[] = { @@ -3407,13 +3429,11 @@ static GenOpFunc *gen_op_icbi[] = {
3407 }; 3429 };
3408 #endif 3430 #endif
3409 #endif 3431 #endif
  3432 +
3410 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE) 3433 GEN_HANDLER(icbi, 0x1F, 0x16, 0x1E, 0x03E00001, PPC_CACHE)
3411 { 3434 {
3412 - /* NIP cannot be restored if the memory exception comes from an helper */  
3413 - gen_update_nip(ctx, ctx->nip - 4);  
3414 gen_addr_reg_index(ctx); 3435 gen_addr_reg_index(ctx);
3415 op_icbi(); 3436 op_icbi();
3416 - RET_STOP(ctx);  
3417 } 3437 }
3418 3438
3419 /* Optional: */ 3439 /* Optional: */
@@ -3428,10 +3448,10 @@ GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA) @@ -3428,10 +3448,10 @@ GEN_HANDLER(dcba, 0x1F, 0x16, 0x17, 0x03E00001, PPC_CACHE_DCBA)
3428 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT) 3448 GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3429 { 3449 {
3430 #if defined(CONFIG_USER_ONLY) 3450 #if defined(CONFIG_USER_ONLY)
3431 - RET_PRIVREG(ctx); 3451 + GEN_EXCP_PRIVREG(ctx);
3432 #else 3452 #else
3433 if (unlikely(!ctx->supervisor)) { 3453 if (unlikely(!ctx->supervisor)) {
3434 - RET_PRIVREG(ctx); 3454 + GEN_EXCP_PRIVREG(ctx);
3435 return; 3455 return;
3436 } 3456 }
3437 gen_op_set_T1(SR(ctx->opcode)); 3457 gen_op_set_T1(SR(ctx->opcode));
@@ -3444,10 +3464,10 @@ GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT) @@ -3444,10 +3464,10 @@ GEN_HANDLER(mfsr, 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT)
3444 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT) 3464 GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3445 { 3465 {
3446 #if defined(CONFIG_USER_ONLY) 3466 #if defined(CONFIG_USER_ONLY)
3447 - RET_PRIVREG(ctx); 3467 + GEN_EXCP_PRIVREG(ctx);
3448 #else 3468 #else
3449 if (unlikely(!ctx->supervisor)) { 3469 if (unlikely(!ctx->supervisor)) {
3450 - RET_PRIVREG(ctx); 3470 + GEN_EXCP_PRIVREG(ctx);
3451 return; 3471 return;
3452 } 3472 }
3453 gen_op_load_gpr_T1(rB(ctx->opcode)); 3473 gen_op_load_gpr_T1(rB(ctx->opcode));
@@ -3461,16 +3481,15 @@ GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT) @@ -3461,16 +3481,15 @@ GEN_HANDLER(mfsrin, 0x1F, 0x13, 0x14, 0x001F0001, PPC_SEGMENT)
3461 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT) 3481 GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3462 { 3482 {
3463 #if defined(CONFIG_USER_ONLY) 3483 #if defined(CONFIG_USER_ONLY)
3464 - RET_PRIVREG(ctx); 3484 + GEN_EXCP_PRIVREG(ctx);
3465 #else 3485 #else
3466 if (unlikely(!ctx->supervisor)) { 3486 if (unlikely(!ctx->supervisor)) {
3467 - RET_PRIVREG(ctx); 3487 + GEN_EXCP_PRIVREG(ctx);
3468 return; 3488 return;
3469 } 3489 }
3470 gen_op_load_gpr_T0(rS(ctx->opcode)); 3490 gen_op_load_gpr_T0(rS(ctx->opcode));
3471 gen_op_set_T1(SR(ctx->opcode)); 3491 gen_op_set_T1(SR(ctx->opcode));
3472 gen_op_store_sr(); 3492 gen_op_store_sr();
3473 - RET_STOP(ctx);  
3474 #endif 3493 #endif
3475 } 3494 }
3476 3495
@@ -3478,17 +3497,16 @@ GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT) @@ -3478,17 +3497,16 @@ GEN_HANDLER(mtsr, 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT)
3478 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) 3497 GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3479 { 3498 {
3480 #if defined(CONFIG_USER_ONLY) 3499 #if defined(CONFIG_USER_ONLY)
3481 - RET_PRIVREG(ctx); 3500 + GEN_EXCP_PRIVREG(ctx);
3482 #else 3501 #else
3483 if (unlikely(!ctx->supervisor)) { 3502 if (unlikely(!ctx->supervisor)) {
3484 - RET_PRIVREG(ctx); 3503 + GEN_EXCP_PRIVREG(ctx);
3485 return; 3504 return;
3486 } 3505 }
3487 gen_op_load_gpr_T0(rS(ctx->opcode)); 3506 gen_op_load_gpr_T0(rS(ctx->opcode));
3488 gen_op_load_gpr_T1(rB(ctx->opcode)); 3507 gen_op_load_gpr_T1(rB(ctx->opcode));
3489 gen_op_srli_T1(28); 3508 gen_op_srli_T1(28);
3490 gen_op_store_sr(); 3509 gen_op_store_sr();
3491 - RET_STOP(ctx);  
3492 #endif 3510 #endif
3493 } 3511 }
3494 3512
@@ -3498,16 +3516,15 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT) @@ -3498,16 +3516,15 @@ GEN_HANDLER(mtsrin, 0x1F, 0x12, 0x07, 0x001F0001, PPC_SEGMENT)
3498 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA) 3516 GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3499 { 3517 {
3500 #if defined(CONFIG_USER_ONLY) 3518 #if defined(CONFIG_USER_ONLY)
3501 - RET_PRIVOPC(ctx); 3519 + GEN_EXCP_PRIVOPC(ctx);
3502 #else 3520 #else
3503 if (unlikely(!ctx->supervisor)) { 3521 if (unlikely(!ctx->supervisor)) {
3504 if (loglevel != 0) 3522 if (loglevel != 0)
3505 fprintf(logfile, "%s: ! supervisor\n", __func__); 3523 fprintf(logfile, "%s: ! supervisor\n", __func__);
3506 - RET_PRIVOPC(ctx); 3524 + GEN_EXCP_PRIVOPC(ctx);
3507 return; 3525 return;
3508 } 3526 }
3509 gen_op_tlbia(); 3527 gen_op_tlbia();
3510 - RET_STOP(ctx);  
3511 #endif 3528 #endif
3512 } 3529 }
3513 3530
@@ -3515,10 +3532,10 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA) @@ -3515,10 +3532,10 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
3515 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE) 3532 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3516 { 3533 {
3517 #if defined(CONFIG_USER_ONLY) 3534 #if defined(CONFIG_USER_ONLY)
3518 - RET_PRIVOPC(ctx); 3535 + GEN_EXCP_PRIVOPC(ctx);
3519 #else 3536 #else
3520 if (unlikely(!ctx->supervisor)) { 3537 if (unlikely(!ctx->supervisor)) {
3521 - RET_PRIVOPC(ctx); 3538 + GEN_EXCP_PRIVOPC(ctx);
3522 return; 3539 return;
3523 } 3540 }
3524 gen_op_load_gpr_T0(rB(ctx->opcode)); 3541 gen_op_load_gpr_T0(rB(ctx->opcode));
@@ -3528,7 +3545,6 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE) @@ -3528,7 +3545,6 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3528 else 3545 else
3529 #endif 3546 #endif
3530 gen_op_tlbie(); 3547 gen_op_tlbie();
3531 - RET_STOP(ctx);  
3532 #endif 3548 #endif
3533 } 3549 }
3534 3550
@@ -3536,16 +3552,16 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE) @@ -3536,16 +3552,16 @@ GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
3536 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC) 3552 GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3537 { 3553 {
3538 #if defined(CONFIG_USER_ONLY) 3554 #if defined(CONFIG_USER_ONLY)
3539 - RET_PRIVOPC(ctx); 3555 + GEN_EXCP_PRIVOPC(ctx);
3540 #else 3556 #else
3541 if (unlikely(!ctx->supervisor)) { 3557 if (unlikely(!ctx->supervisor)) {
3542 - RET_PRIVOPC(ctx); 3558 + GEN_EXCP_PRIVOPC(ctx);
3543 return; 3559 return;
3544 } 3560 }
3545 /* This has no effect: it should ensure that all previous 3561 /* This has no effect: it should ensure that all previous
3546 * tlbie have completed 3562 * tlbie have completed
3547 */ 3563 */
3548 - RET_STOP(ctx); 3564 + GEN_STOP(ctx);
3549 #endif 3565 #endif
3550 } 3566 }
3551 3567
@@ -3554,16 +3570,15 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC) @@ -3554,16 +3570,15 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC)
3554 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI) 3570 GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3555 { 3571 {
3556 #if defined(CONFIG_USER_ONLY) 3572 #if defined(CONFIG_USER_ONLY)
3557 - RET_PRIVOPC(ctx); 3573 + GEN_EXCP_PRIVOPC(ctx);
3558 #else 3574 #else
3559 if (unlikely(!ctx->supervisor)) { 3575 if (unlikely(!ctx->supervisor)) {
3560 if (loglevel != 0) 3576 if (loglevel != 0)
3561 fprintf(logfile, "%s: ! supervisor\n", __func__); 3577 fprintf(logfile, "%s: ! supervisor\n", __func__);
3562 - RET_PRIVOPC(ctx); 3578 + GEN_EXCP_PRIVOPC(ctx);
3563 return; 3579 return;
3564 } 3580 }
3565 gen_op_slbia(); 3581 gen_op_slbia();
3566 - RET_STOP(ctx);  
3567 #endif 3582 #endif
3568 } 3583 }
3569 3584
@@ -3571,15 +3586,14 @@ GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI) @@ -3571,15 +3586,14 @@ GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI)
3571 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI) 3586 GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI)
3572 { 3587 {
3573 #if defined(CONFIG_USER_ONLY) 3588 #if defined(CONFIG_USER_ONLY)
3574 - RET_PRIVOPC(ctx); 3589 + GEN_EXCP_PRIVOPC(ctx);
3575 #else 3590 #else
3576 if (unlikely(!ctx->supervisor)) { 3591 if (unlikely(!ctx->supervisor)) {
3577 - RET_PRIVOPC(ctx); 3592 + GEN_EXCP_PRIVOPC(ctx);
3578 return; 3593 return;
3579 } 3594 }
3580 gen_op_load_gpr_T0(rB(ctx->opcode)); 3595 gen_op_load_gpr_T0(rB(ctx->opcode));
3581 gen_op_slbie(); 3596 gen_op_slbie();
3582 - RET_STOP(ctx);  
3583 #endif 3597 #endif
3584 } 3598 }
3585 #endif 3599 #endif
@@ -4073,24 +4087,24 @@ GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR) @@ -4073,24 +4087,24 @@ GEN_HANDLER(srq, 0x1F, 0x18, 0x14, 0x00000000, PPC_POWER_BR)
4073 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC) 4087 GEN_HANDLER(dsa, 0x1F, 0x14, 0x13, 0x03FFF801, PPC_602_SPEC)
4074 { 4088 {
4075 /* XXX: TODO */ 4089 /* XXX: TODO */
4076 - RET_INVAL(ctx); 4090 + GEN_EXCP_INVAL(ctx);
4077 } 4091 }
4078 4092
4079 /* esa */ 4093 /* esa */
4080 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC) 4094 GEN_HANDLER(esa, 0x1F, 0x14, 0x12, 0x03FFF801, PPC_602_SPEC)
4081 { 4095 {
4082 /* XXX: TODO */ 4096 /* XXX: TODO */
4083 - RET_INVAL(ctx); 4097 + GEN_EXCP_INVAL(ctx);
4084 } 4098 }
4085 4099
4086 /* mfrom */ 4100 /* mfrom */
4087 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC) 4101 GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4088 { 4102 {
4089 #if defined(CONFIG_USER_ONLY) 4103 #if defined(CONFIG_USER_ONLY)
4090 - RET_PRIVOPC(ctx); 4104 + GEN_EXCP_PRIVOPC(ctx);
4091 #else 4105 #else
4092 if (unlikely(!ctx->supervisor)) { 4106 if (unlikely(!ctx->supervisor)) {
4093 - RET_PRIVOPC(ctx); 4107 + GEN_EXCP_PRIVOPC(ctx);
4094 return; 4108 return;
4095 } 4109 }
4096 gen_op_load_gpr_T0(rA(ctx->opcode)); 4110 gen_op_load_gpr_T0(rA(ctx->opcode));
@@ -4104,15 +4118,14 @@ GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC) @@ -4104,15 +4118,14 @@ GEN_HANDLER(mfrom, 0x1F, 0x09, 0x08, 0x03E0F801, PPC_602_SPEC)
4104 GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB) 4118 GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4105 { 4119 {
4106 #if defined(CONFIG_USER_ONLY) 4120 #if defined(CONFIG_USER_ONLY)
4107 - RET_PRIVOPC(ctx); 4121 + GEN_EXCP_PRIVOPC(ctx);
4108 #else 4122 #else
4109 if (unlikely(!ctx->supervisor)) { 4123 if (unlikely(!ctx->supervisor)) {
4110 - RET_PRIVOPC(ctx); 4124 + GEN_EXCP_PRIVOPC(ctx);
4111 return; 4125 return;
4112 } 4126 }
4113 gen_op_load_gpr_T0(rB(ctx->opcode)); 4127 gen_op_load_gpr_T0(rB(ctx->opcode));
4114 gen_op_6xx_tlbld(); 4128 gen_op_6xx_tlbld();
4115 - RET_STOP(ctx);  
4116 #endif 4129 #endif
4117 } 4130 }
4118 4131
@@ -4120,15 +4133,14 @@ GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB) @@ -4120,15 +4133,14 @@ GEN_HANDLER(tlbld, 0x1F, 0x12, 0x1E, 0x03FF0001, PPC_6xx_TLB)
4120 GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB) 4133 GEN_HANDLER(tlbli, 0x1F, 0x12, 0x1F, 0x03FF0001, PPC_6xx_TLB)
4121 { 4134 {
4122 #if defined(CONFIG_USER_ONLY) 4135 #if defined(CONFIG_USER_ONLY)
4123 - RET_PRIVOPC(ctx); 4136 + GEN_EXCP_PRIVOPC(ctx);
4124 #else 4137 #else
4125 if (unlikely(!ctx->supervisor)) { 4138 if (unlikely(!ctx->supervisor)) {
4126 - RET_PRIVOPC(ctx); 4139 + GEN_EXCP_PRIVOPC(ctx);
4127 return; 4140 return;
4128 } 4141 }
4129 gen_op_load_gpr_T0(rB(ctx->opcode)); 4142 gen_op_load_gpr_T0(rB(ctx->opcode));
4130 gen_op_6xx_tlbli(); 4143 gen_op_6xx_tlbli();
4131 - RET_STOP(ctx);  
4132 #endif 4144 #endif
4133 } 4145 }
4134 4146
@@ -4144,10 +4156,10 @@ GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER) @@ -4144,10 +4156,10 @@ GEN_HANDLER(cli, 0x1F, 0x16, 0x0F, 0x03E00000, PPC_POWER)
4144 { 4156 {
4145 /* Cache line invalidate: privileged and treated as no-op */ 4157 /* Cache line invalidate: privileged and treated as no-op */
4146 #if defined(CONFIG_USER_ONLY) 4158 #if defined(CONFIG_USER_ONLY)
4147 - RET_PRIVOPC(ctx); 4159 + GEN_EXCP_PRIVOPC(ctx);
4148 #else 4160 #else
4149 if (unlikely(!ctx->supervisor)) { 4161 if (unlikely(!ctx->supervisor)) {
4150 - RET_PRIVOPC(ctx); 4162 + GEN_EXCP_PRIVOPC(ctx);
4151 return; 4163 return;
4152 } 4164 }
4153 #endif 4165 #endif
@@ -4162,10 +4174,10 @@ GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER) @@ -4162,10 +4174,10 @@ GEN_HANDLER(dclst, 0x1F, 0x16, 0x13, 0x03E00000, PPC_POWER)
4162 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER) 4174 GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4163 { 4175 {
4164 #if defined(CONFIG_USER_ONLY) 4176 #if defined(CONFIG_USER_ONLY)
4165 - RET_PRIVOPC(ctx); 4177 + GEN_EXCP_PRIVOPC(ctx);
4166 #else 4178 #else
4167 if (unlikely(!ctx->supervisor)) { 4179 if (unlikely(!ctx->supervisor)) {
4168 - RET_PRIVOPC(ctx); 4180 + GEN_EXCP_PRIVOPC(ctx);
4169 return; 4181 return;
4170 } 4182 }
4171 int ra = rA(ctx->opcode); 4183 int ra = rA(ctx->opcode);
@@ -4182,10 +4194,10 @@ GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER) @@ -4182,10 +4194,10 @@ GEN_HANDLER(mfsri, 0x1F, 0x13, 0x13, 0x00000001, PPC_POWER)
4182 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER) 4194 GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4183 { 4195 {
4184 #if defined(CONFIG_USER_ONLY) 4196 #if defined(CONFIG_USER_ONLY)
4185 - RET_PRIVOPC(ctx); 4197 + GEN_EXCP_PRIVOPC(ctx);
4186 #else 4198 #else
4187 if (unlikely(!ctx->supervisor)) { 4199 if (unlikely(!ctx->supervisor)) {
4188 - RET_PRIVOPC(ctx); 4200 + GEN_EXCP_PRIVOPC(ctx);
4189 return; 4201 return;
4190 } 4202 }
4191 gen_addr_reg_index(ctx); 4203 gen_addr_reg_index(ctx);
@@ -4197,14 +4209,14 @@ GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER) @@ -4197,14 +4209,14 @@ GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER)
4197 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER) 4209 GEN_HANDLER(rfsvc, 0x13, 0x12, 0x02, 0x03FFF0001, PPC_POWER)
4198 { 4210 {
4199 #if defined(CONFIG_USER_ONLY) 4211 #if defined(CONFIG_USER_ONLY)
4200 - RET_PRIVOPC(ctx); 4212 + GEN_EXCP_PRIVOPC(ctx);
4201 #else 4213 #else
4202 if (unlikely(!ctx->supervisor)) { 4214 if (unlikely(!ctx->supervisor)) {
4203 - RET_PRIVOPC(ctx); 4215 + GEN_EXCP_PRIVOPC(ctx);
4204 return; 4216 return;
4205 } 4217 }
4206 gen_op_POWER_rfsvc(); 4218 gen_op_POWER_rfsvc();
4207 - RET_CHG_FLOW(ctx); 4219 + GEN_SYNC(ctx);
4208 #endif 4220 #endif
4209 } 4221 }
4210 4222
@@ -4347,17 +4359,17 @@ GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2) @@ -4347,17 +4359,17 @@ GEN_HANDLER(stfqx, 0x1F, 0x17, 0x1C, 0x00000001, PPC_POWER2)
4347 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT) 4359 GEN_HANDLER(mfapidi, 0x1F, 0x13, 0x08, 0x0000F801, PPC_BOOKE_EXT)
4348 { 4360 {
4349 /* XXX: TODO */ 4361 /* XXX: TODO */
4350 - RET_INVAL(ctx); 4362 + GEN_EXCP_INVAL(ctx);
4351 } 4363 }
4352 4364
4353 /* XXX: not implemented on 440 ? */ 4365 /* XXX: not implemented on 440 ? */
4354 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT) 4366 GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
4355 { 4367 {
4356 #if defined(CONFIG_USER_ONLY) 4368 #if defined(CONFIG_USER_ONLY)
4357 - RET_PRIVOPC(ctx); 4369 + GEN_EXCP_PRIVOPC(ctx);
4358 #else 4370 #else
4359 if (unlikely(!ctx->supervisor)) { 4371 if (unlikely(!ctx->supervisor)) {
4360 - RET_PRIVOPC(ctx); 4372 + GEN_EXCP_PRIVOPC(ctx);
4361 return; 4373 return;
4362 } 4374 }
4363 gen_addr_reg_index(ctx); 4375 gen_addr_reg_index(ctx);
@@ -4368,7 +4380,6 @@ GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT) @@ -4368,7 +4380,6 @@ GEN_HANDLER(tlbiva, 0x1F, 0x12, 0x18, 0x03FFF801, PPC_BOOKE_EXT)
4368 else 4380 else
4369 #endif 4381 #endif
4370 gen_op_tlbie(); 4382 gen_op_tlbie();
4371 - RET_STOP(ctx);  
4372 #endif 4383 #endif
4373 } 4384 }
4374 4385
@@ -4550,12 +4561,12 @@ GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C); @@ -4550,12 +4561,12 @@ GEN_MAC_HANDLER(mullhwu, 0x08, 0x0C);
4550 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON) 4561 GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4551 { 4562 {
4552 #if defined(CONFIG_USER_ONLY) 4563 #if defined(CONFIG_USER_ONLY)
4553 - RET_PRIVREG(ctx); 4564 + GEN_EXCP_PRIVREG(ctx);
4554 #else 4565 #else
4555 uint32_t dcrn = SPR(ctx->opcode); 4566 uint32_t dcrn = SPR(ctx->opcode);
4556 4567
4557 if (unlikely(!ctx->supervisor)) { 4568 if (unlikely(!ctx->supervisor)) {
4558 - RET_PRIVREG(ctx); 4569 + GEN_EXCP_PRIVREG(ctx);
4559 return; 4570 return;
4560 } 4571 }
4561 gen_op_set_T0(dcrn); 4572 gen_op_set_T0(dcrn);
@@ -4568,12 +4579,12 @@ GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON) @@ -4568,12 +4579,12 @@ GEN_HANDLER(mfdcr, 0x1F, 0x03, 0x0A, 0x00000001, PPC_EMB_COMMON)
4568 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON) 4579 GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4569 { 4580 {
4570 #if defined(CONFIG_USER_ONLY) 4581 #if defined(CONFIG_USER_ONLY)
4571 - RET_PRIVREG(ctx); 4582 + GEN_EXCP_PRIVREG(ctx);
4572 #else 4583 #else
4573 uint32_t dcrn = SPR(ctx->opcode); 4584 uint32_t dcrn = SPR(ctx->opcode);
4574 4585
4575 if (unlikely(!ctx->supervisor)) { 4586 if (unlikely(!ctx->supervisor)) {
4576 - RET_PRIVREG(ctx); 4587 + GEN_EXCP_PRIVREG(ctx);
4577 return; 4588 return;
4578 } 4589 }
4579 gen_op_set_T0(dcrn); 4590 gen_op_set_T0(dcrn);
@@ -4587,10 +4598,10 @@ GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON) @@ -4587,10 +4598,10 @@ GEN_HANDLER(mtdcr, 0x1F, 0x03, 0x0E, 0x00000001, PPC_EMB_COMMON)
4587 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT) 4598 GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT)
4588 { 4599 {
4589 #if defined(CONFIG_USER_ONLY) 4600 #if defined(CONFIG_USER_ONLY)
4590 - RET_PRIVREG(ctx); 4601 + GEN_EXCP_PRIVREG(ctx);
4591 #else 4602 #else
4592 if (unlikely(!ctx->supervisor)) { 4603 if (unlikely(!ctx->supervisor)) {
4593 - RET_PRIVREG(ctx); 4604 + GEN_EXCP_PRIVREG(ctx);
4594 return; 4605 return;
4595 } 4606 }
4596 gen_op_load_gpr_T0(rA(ctx->opcode)); 4607 gen_op_load_gpr_T0(rA(ctx->opcode));
@@ -4605,10 +4616,10 @@ GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT) @@ -4605,10 +4616,10 @@ GEN_HANDLER(mfdcrx, 0x1F, 0x03, 0x08, 0x00000000, PPC_BOOKE_EXT)
4605 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT) 4616 GEN_HANDLER(mtdcrx, 0x1F, 0x03, 0x0C, 0x00000000, PPC_BOOKE_EXT)
4606 { 4617 {
4607 #if defined(CONFIG_USER_ONLY) 4618 #if defined(CONFIG_USER_ONLY)
4608 - RET_PRIVREG(ctx); 4619 + GEN_EXCP_PRIVREG(ctx);
4609 #else 4620 #else
4610 if (unlikely(!ctx->supervisor)) { 4621 if (unlikely(!ctx->supervisor)) {
4611 - RET_PRIVREG(ctx); 4622 + GEN_EXCP_PRIVREG(ctx);
4612 return; 4623 return;
4613 } 4624 }
4614 gen_op_load_gpr_T0(rA(ctx->opcode)); 4625 gen_op_load_gpr_T0(rA(ctx->opcode));
@@ -4640,10 +4651,10 @@ GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX) @@ -4640,10 +4651,10 @@ GEN_HANDLER(mtdcrux, 0x1F, 0x03, 0x0D, 0x00000000, PPC_DCRUX)
4640 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON) 4651 GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4641 { 4652 {
4642 #if defined(CONFIG_USER_ONLY) 4653 #if defined(CONFIG_USER_ONLY)
4643 - RET_PRIVOPC(ctx); 4654 + GEN_EXCP_PRIVOPC(ctx);
4644 #else 4655 #else
4645 if (unlikely(!ctx->supervisor)) { 4656 if (unlikely(!ctx->supervisor)) {
4646 - RET_PRIVOPC(ctx); 4657 + GEN_EXCP_PRIVOPC(ctx);
4647 return; 4658 return;
4648 } 4659 }
4649 /* interpreted as no-op */ 4660 /* interpreted as no-op */
@@ -4654,10 +4665,10 @@ GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON) @@ -4654,10 +4665,10 @@ GEN_HANDLER(dccci, 0x1F, 0x06, 0x0E, 0x03E00001, PPC_4xx_COMMON)
4654 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON) 4665 GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
4655 { 4666 {
4656 #if defined(CONFIG_USER_ONLY) 4667 #if defined(CONFIG_USER_ONLY)
4657 - RET_PRIVOPC(ctx); 4668 + GEN_EXCP_PRIVOPC(ctx);
4658 #else 4669 #else
4659 if (unlikely(!ctx->supervisor)) { 4670 if (unlikely(!ctx->supervisor)) {
4660 - RET_PRIVOPC(ctx); 4671 + GEN_EXCP_PRIVOPC(ctx);
4661 return; 4672 return;
4662 } 4673 }
4663 gen_addr_reg_index(ctx); 4674 gen_addr_reg_index(ctx);
@@ -4679,10 +4690,10 @@ GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT) @@ -4679,10 +4690,10 @@ GEN_HANDLER(icbt_40x, 0x1F, 0x06, 0x08, 0x03E00001, PPC_40x_ICBT)
4679 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON) 4690 GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4680 { 4691 {
4681 #if defined(CONFIG_USER_ONLY) 4692 #if defined(CONFIG_USER_ONLY)
4682 - RET_PRIVOPC(ctx); 4693 + GEN_EXCP_PRIVOPC(ctx);
4683 #else 4694 #else
4684 if (unlikely(!ctx->supervisor)) { 4695 if (unlikely(!ctx->supervisor)) {
4685 - RET_PRIVOPC(ctx); 4696 + GEN_EXCP_PRIVOPC(ctx);
4686 return; 4697 return;
4687 } 4698 }
4688 /* interpreted as no-op */ 4699 /* interpreted as no-op */
@@ -4693,10 +4704,10 @@ GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON) @@ -4693,10 +4704,10 @@ GEN_HANDLER(iccci, 0x1F, 0x06, 0x1E, 0x00000001, PPC_4xx_COMMON)
4693 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON) 4704 GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4694 { 4705 {
4695 #if defined(CONFIG_USER_ONLY) 4706 #if defined(CONFIG_USER_ONLY)
4696 - RET_PRIVOPC(ctx); 4707 + GEN_EXCP_PRIVOPC(ctx);
4697 #else 4708 #else
4698 if (unlikely(!ctx->supervisor)) { 4709 if (unlikely(!ctx->supervisor)) {
4699 - RET_PRIVOPC(ctx); 4710 + GEN_EXCP_PRIVOPC(ctx);
4700 return; 4711 return;
4701 } 4712 }
4702 /* interpreted as no-op */ 4713 /* interpreted as no-op */
@@ -4707,30 +4718,30 @@ GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON) @@ -4707,30 +4718,30 @@ GEN_HANDLER(icread, 0x1F, 0x06, 0x1F, 0x03E00001, PPC_4xx_COMMON)
4707 GEN_HANDLER(rfci_40x, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP) 4718 GEN_HANDLER(rfci_40x, 0x13, 0x13, 0x01, 0x03FF8001, PPC_40x_EXCP)
4708 { 4719 {
4709 #if defined(CONFIG_USER_ONLY) 4720 #if defined(CONFIG_USER_ONLY)
4710 - RET_PRIVOPC(ctx); 4721 + GEN_EXCP_PRIVOPC(ctx);
4711 #else 4722 #else
4712 if (unlikely(!ctx->supervisor)) { 4723 if (unlikely(!ctx->supervisor)) {
4713 - RET_PRIVOPC(ctx); 4724 + GEN_EXCP_PRIVOPC(ctx);
4714 return; 4725 return;
4715 } 4726 }
4716 /* Restore CPU state */ 4727 /* Restore CPU state */
4717 gen_op_40x_rfci(); 4728 gen_op_40x_rfci();
4718 - RET_CHG_FLOW(ctx); 4729 + GEN_SYNC(ctx);
4719 #endif 4730 #endif
4720 } 4731 }
4721 4732
4722 GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE) 4733 GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4723 { 4734 {
4724 #if defined(CONFIG_USER_ONLY) 4735 #if defined(CONFIG_USER_ONLY)
4725 - RET_PRIVOPC(ctx); 4736 + GEN_EXCP_PRIVOPC(ctx);
4726 #else 4737 #else
4727 if (unlikely(!ctx->supervisor)) { 4738 if (unlikely(!ctx->supervisor)) {
4728 - RET_PRIVOPC(ctx); 4739 + GEN_EXCP_PRIVOPC(ctx);
4729 return; 4740 return;
4730 } 4741 }
4731 /* Restore CPU state */ 4742 /* Restore CPU state */
4732 gen_op_rfci(); 4743 gen_op_rfci();
4733 - RET_CHG_FLOW(ctx); 4744 + GEN_SYNC(ctx);
4734 #endif 4745 #endif
4735 } 4746 }
4736 4747
@@ -4739,15 +4750,15 @@ GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE) @@ -4739,15 +4750,15 @@ GEN_HANDLER(rfci, 0x13, 0x13, 0x01, 0x03FF8001, PPC_BOOKE)
4739 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT) 4750 GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
4740 { 4751 {
4741 #if defined(CONFIG_USER_ONLY) 4752 #if defined(CONFIG_USER_ONLY)
4742 - RET_PRIVOPC(ctx); 4753 + GEN_EXCP_PRIVOPC(ctx);
4743 #else 4754 #else
4744 if (unlikely(!ctx->supervisor)) { 4755 if (unlikely(!ctx->supervisor)) {
4745 - RET_PRIVOPC(ctx); 4756 + GEN_EXCP_PRIVOPC(ctx);
4746 return; 4757 return;
4747 } 4758 }
4748 /* Restore CPU state */ 4759 /* Restore CPU state */
4749 gen_op_rfdi(); 4760 gen_op_rfdi();
4750 - RET_CHG_FLOW(ctx); 4761 + GEN_SYNC(ctx);
4751 #endif 4762 #endif
4752 } 4763 }
4753 4764
@@ -4755,15 +4766,15 @@ GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT) @@ -4755,15 +4766,15 @@ GEN_HANDLER(rfdi, 0x13, 0x07, 0x01, 0x03FF8001, PPC_BOOKE_EXT)
4755 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI) 4766 GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4756 { 4767 {
4757 #if defined(CONFIG_USER_ONLY) 4768 #if defined(CONFIG_USER_ONLY)
4758 - RET_PRIVOPC(ctx); 4769 + GEN_EXCP_PRIVOPC(ctx);
4759 #else 4770 #else
4760 if (unlikely(!ctx->supervisor)) { 4771 if (unlikely(!ctx->supervisor)) {
4761 - RET_PRIVOPC(ctx); 4772 + GEN_EXCP_PRIVOPC(ctx);
4762 return; 4773 return;
4763 } 4774 }
4764 /* Restore CPU state */ 4775 /* Restore CPU state */
4765 gen_op_rfmci(); 4776 gen_op_rfmci();
4766 - RET_CHG_FLOW(ctx); 4777 + GEN_SYNC(ctx);
4767 #endif 4778 #endif
4768 } 4779 }
4769 4780
@@ -4772,10 +4783,10 @@ GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI) @@ -4772,10 +4783,10 @@ GEN_HANDLER(rfmci, 0x13, 0x06, 0x01, 0x03FF8001, PPC_RFMCI)
4772 GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB) 4783 GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4773 { 4784 {
4774 #if defined(CONFIG_USER_ONLY) 4785 #if defined(CONFIG_USER_ONLY)
4775 - RET_PRIVOPC(ctx); 4786 + GEN_EXCP_PRIVOPC(ctx);
4776 #else 4787 #else
4777 if (unlikely(!ctx->supervisor)) { 4788 if (unlikely(!ctx->supervisor)) {
4778 - RET_PRIVOPC(ctx); 4789 + GEN_EXCP_PRIVOPC(ctx);
4779 return; 4790 return;
4780 } 4791 }
4781 switch (rB(ctx->opcode)) { 4792 switch (rB(ctx->opcode)) {
@@ -4790,7 +4801,7 @@ GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB) @@ -4790,7 +4801,7 @@ GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4790 gen_op_store_T0_gpr(rD(ctx->opcode)); 4801 gen_op_store_T0_gpr(rD(ctx->opcode));
4791 break; 4802 break;
4792 default: 4803 default:
4793 - RET_INVAL(ctx); 4804 + GEN_EXCP_INVAL(ctx);
4794 break; 4805 break;
4795 } 4806 }
4796 #endif 4807 #endif
@@ -4800,10 +4811,10 @@ GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB) @@ -4800,10 +4811,10 @@ GEN_HANDLER(tlbre_40x, 0x1F, 0x12, 0x1D, 0x00000001, PPC_40x_TLB)
4800 GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB) 4811 GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
4801 { 4812 {
4802 #if defined(CONFIG_USER_ONLY) 4813 #if defined(CONFIG_USER_ONLY)
4803 - RET_PRIVOPC(ctx); 4814 + GEN_EXCP_PRIVOPC(ctx);
4804 #else 4815 #else
4805 if (unlikely(!ctx->supervisor)) { 4816 if (unlikely(!ctx->supervisor)) {
4806 - RET_PRIVOPC(ctx); 4817 + GEN_EXCP_PRIVOPC(ctx);
4807 return; 4818 return;
4808 } 4819 }
4809 gen_addr_reg_index(ctx); 4820 gen_addr_reg_index(ctx);
@@ -4819,10 +4830,10 @@ GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB) @@ -4819,10 +4830,10 @@ GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB)
4819 GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB) 4830 GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
4820 { 4831 {
4821 #if defined(CONFIG_USER_ONLY) 4832 #if defined(CONFIG_USER_ONLY)
4822 - RET_PRIVOPC(ctx); 4833 + GEN_EXCP_PRIVOPC(ctx);
4823 #else 4834 #else
4824 if (unlikely(!ctx->supervisor)) { 4835 if (unlikely(!ctx->supervisor)) {
4825 - RET_PRIVOPC(ctx); 4836 + GEN_EXCP_PRIVOPC(ctx);
4826 return; 4837 return;
4827 } 4838 }
4828 switch (rB(ctx->opcode)) { 4839 switch (rB(ctx->opcode)) {
@@ -4837,7 +4848,7 @@ GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB) @@ -4837,7 +4848,7 @@ GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
4837 gen_op_4xx_tlbwe_lo(); 4848 gen_op_4xx_tlbwe_lo();
4838 break; 4849 break;
4839 default: 4850 default:
4840 - RET_INVAL(ctx); 4851 + GEN_EXCP_INVAL(ctx);
4841 break; 4852 break;
4842 } 4853 }
4843 #endif 4854 #endif
@@ -4848,10 +4859,10 @@ GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB) @@ -4848,10 +4859,10 @@ GEN_HANDLER(tlbwe_40x, 0x1F, 0x12, 0x1E, 0x00000001, PPC_40x_TLB)
4848 GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) 4859 GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4849 { 4860 {
4850 #if defined(CONFIG_USER_ONLY) 4861 #if defined(CONFIG_USER_ONLY)
4851 - RET_PRIVOPC(ctx); 4862 + GEN_EXCP_PRIVOPC(ctx);
4852 #else 4863 #else
4853 if (unlikely(!ctx->supervisor)) { 4864 if (unlikely(!ctx->supervisor)) {
4854 - RET_PRIVOPC(ctx); 4865 + GEN_EXCP_PRIVOPC(ctx);
4855 return; 4866 return;
4856 } 4867 }
4857 switch (rB(ctx->opcode)) { 4868 switch (rB(ctx->opcode)) {
@@ -4863,7 +4874,7 @@ GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) @@ -4863,7 +4874,7 @@ GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4863 gen_op_store_T0_gpr(rD(ctx->opcode)); 4874 gen_op_store_T0_gpr(rD(ctx->opcode));
4864 break; 4875 break;
4865 default: 4876 default:
4866 - RET_INVAL(ctx); 4877 + GEN_EXCP_INVAL(ctx);
4867 break; 4878 break;
4868 } 4879 }
4869 #endif 4880 #endif
@@ -4873,10 +4884,10 @@ GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE) @@ -4873,10 +4884,10 @@ GEN_HANDLER(tlbre_440, 0x1F, 0x12, 0x1D, 0x00000001, PPC_BOOKE)
4873 GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) 4884 GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
4874 { 4885 {
4875 #if defined(CONFIG_USER_ONLY) 4886 #if defined(CONFIG_USER_ONLY)
4876 - RET_PRIVOPC(ctx); 4887 + GEN_EXCP_PRIVOPC(ctx);
4877 #else 4888 #else
4878 if (unlikely(!ctx->supervisor)) { 4889 if (unlikely(!ctx->supervisor)) {
4879 - RET_PRIVOPC(ctx); 4890 + GEN_EXCP_PRIVOPC(ctx);
4880 return; 4891 return;
4881 } 4892 }
4882 gen_addr_reg_index(ctx); 4893 gen_addr_reg_index(ctx);
@@ -4892,10 +4903,10 @@ GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) @@ -4892,10 +4903,10 @@ GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE)
4892 GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) 4903 GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4893 { 4904 {
4894 #if defined(CONFIG_USER_ONLY) 4905 #if defined(CONFIG_USER_ONLY)
4895 - RET_PRIVOPC(ctx); 4906 + GEN_EXCP_PRIVOPC(ctx);
4896 #else 4907 #else
4897 if (unlikely(!ctx->supervisor)) { 4908 if (unlikely(!ctx->supervisor)) {
4898 - RET_PRIVOPC(ctx); 4909 + GEN_EXCP_PRIVOPC(ctx);
4899 return; 4910 return;
4900 } 4911 }
4901 switch (rB(ctx->opcode)) { 4912 switch (rB(ctx->opcode)) {
@@ -4907,7 +4918,7 @@ GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) @@ -4907,7 +4918,7 @@ GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4907 gen_op_440_tlbwe(rB(ctx->opcode)); 4918 gen_op_440_tlbwe(rB(ctx->opcode));
4908 break; 4919 break;
4909 default: 4920 default:
4910 - RET_INVAL(ctx); 4921 + GEN_EXCP_INVAL(ctx);
4911 break; 4922 break;
4912 } 4923 }
4913 #endif 4924 #endif
@@ -4917,15 +4928,15 @@ GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE) @@ -4917,15 +4928,15 @@ GEN_HANDLER(tlbwe_440, 0x1F, 0x12, 0x1E, 0x00000001, PPC_BOOKE)
4917 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON) 4928 GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4918 { 4929 {
4919 #if defined(CONFIG_USER_ONLY) 4930 #if defined(CONFIG_USER_ONLY)
4920 - RET_PRIVOPC(ctx); 4931 + GEN_EXCP_PRIVOPC(ctx);
4921 #else 4932 #else
4922 if (unlikely(!ctx->supervisor)) { 4933 if (unlikely(!ctx->supervisor)) {
4923 - RET_PRIVOPC(ctx); 4934 + GEN_EXCP_PRIVOPC(ctx);
4924 return; 4935 return;
4925 } 4936 }
4926 gen_op_load_gpr_T0(rD(ctx->opcode)); 4937 gen_op_load_gpr_T0(rD(ctx->opcode));
4927 gen_op_wrte(); 4938 gen_op_wrte();
4928 - RET_EXCP(ctx, EXCP_MTMSR, 0); 4939 + GEN_STOP(ctx);
4929 #endif 4940 #endif
4930 } 4941 }
4931 4942
@@ -4933,15 +4944,15 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON) @@ -4933,15 +4944,15 @@ GEN_HANDLER(wrtee, 0x1F, 0x03, 0x04, 0x000FFC01, PPC_EMB_COMMON)
4933 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON) 4944 GEN_HANDLER(wrteei, 0x1F, 0x03, 0x05, 0x000EFC01, PPC_EMB_COMMON)
4934 { 4945 {
4935 #if defined(CONFIG_USER_ONLY) 4946 #if defined(CONFIG_USER_ONLY)
4936 - RET_PRIVOPC(ctx); 4947 + GEN_EXCP_PRIVOPC(ctx);
4937 #else 4948 #else
4938 if (unlikely(!ctx->supervisor)) { 4949 if (unlikely(!ctx->supervisor)) {
4939 - RET_PRIVOPC(ctx); 4950 + GEN_EXCP_PRIVOPC(ctx);
4940 return; 4951 return;
4941 } 4952 }
4942 gen_op_set_T0(ctx->opcode & 0x00010000); 4953 gen_op_set_T0(ctx->opcode & 0x00010000);
4943 gen_op_wrte(); 4954 gen_op_wrte();
4944 - RET_EXCP(ctx, EXCP_MTMSR, 0); 4955 + GEN_STOP(ctx);
4945 #endif 4956 #endif
4946 } 4957 }
4947 4958
@@ -5009,7 +5020,7 @@ GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type) \ @@ -5009,7 +5020,7 @@ GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type) \
5009 /* Handler for undefined SPE opcodes */ 5020 /* Handler for undefined SPE opcodes */
5010 static inline void gen_speundef (DisasContext *ctx) 5021 static inline void gen_speundef (DisasContext *ctx)
5011 { 5022 {
5012 - RET_INVAL(ctx); 5023 + GEN_EXCP_INVAL(ctx);
5013 } 5024 }
5014 5025
5015 /* SPE load and stores */ 5026 /* SPE load and stores */
@@ -5101,7 +5112,7 @@ static GenOpFunc *gen_op_spe_st##name[] = { \ @@ -5101,7 +5112,7 @@ static GenOpFunc *gen_op_spe_st##name[] = { \
5101 static inline void gen_evl##name (DisasContext *ctx) \ 5112 static inline void gen_evl##name (DisasContext *ctx) \
5102 { \ 5113 { \
5103 if (unlikely(!ctx->spe_enabled)) { \ 5114 if (unlikely(!ctx->spe_enabled)) { \
5104 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5115 + GEN_EXCP_NO_AP(ctx); \
5105 return; \ 5116 return; \
5106 } \ 5117 } \
5107 gen_addr_spe_imm_index(ctx, sh); \ 5118 gen_addr_spe_imm_index(ctx, sh); \
@@ -5113,7 +5124,7 @@ static inline void gen_evl##name (DisasContext *ctx) \ @@ -5113,7 +5124,7 @@ static inline void gen_evl##name (DisasContext *ctx) \
5113 static inline void gen_evl##name##x (DisasContext *ctx) \ 5124 static inline void gen_evl##name##x (DisasContext *ctx) \
5114 { \ 5125 { \
5115 if (unlikely(!ctx->spe_enabled)) { \ 5126 if (unlikely(!ctx->spe_enabled)) { \
5116 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5127 + GEN_EXCP_NO_AP(ctx); \
5117 return; \ 5128 return; \
5118 } \ 5129 } \
5119 gen_addr_reg_index(ctx); \ 5130 gen_addr_reg_index(ctx); \
@@ -5130,7 +5141,7 @@ GEN_SPE_LDX(name) @@ -5130,7 +5141,7 @@ GEN_SPE_LDX(name)
5130 static inline void gen_evst##name (DisasContext *ctx) \ 5141 static inline void gen_evst##name (DisasContext *ctx) \
5131 { \ 5142 { \
5132 if (unlikely(!ctx->spe_enabled)) { \ 5143 if (unlikely(!ctx->spe_enabled)) { \
5133 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5144 + GEN_EXCP_NO_AP(ctx); \
5134 return; \ 5145 return; \
5135 } \ 5146 } \
5136 gen_addr_spe_imm_index(ctx, sh); \ 5147 gen_addr_spe_imm_index(ctx, sh); \
@@ -5142,7 +5153,7 @@ static inline void gen_evst##name (DisasContext *ctx) \ @@ -5142,7 +5153,7 @@ static inline void gen_evst##name (DisasContext *ctx) \
5142 static inline void gen_evst##name##x (DisasContext *ctx) \ 5153 static inline void gen_evst##name##x (DisasContext *ctx) \
5143 { \ 5154 { \
5144 if (unlikely(!ctx->spe_enabled)) { \ 5155 if (unlikely(!ctx->spe_enabled)) { \
5145 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5156 + GEN_EXCP_NO_AP(ctx); \
5146 return; \ 5157 return; \
5147 } \ 5158 } \
5148 gen_addr_reg_index(ctx); \ 5159 gen_addr_reg_index(ctx); \
@@ -5164,7 +5175,7 @@ GEN_SPEOP_ST(name, sh) @@ -5164,7 +5175,7 @@ GEN_SPEOP_ST(name, sh)
5164 static inline void gen_##name (DisasContext *ctx) \ 5175 static inline void gen_##name (DisasContext *ctx) \
5165 { \ 5176 { \
5166 if (unlikely(!ctx->spe_enabled)) { \ 5177 if (unlikely(!ctx->spe_enabled)) { \
5167 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5178 + GEN_EXCP_NO_AP(ctx); \
5168 return; \ 5179 return; \
5169 } \ 5180 } \
5170 gen_op_load_gpr64_T0(rA(ctx->opcode)); \ 5181 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
@@ -5177,7 +5188,7 @@ static inline void gen_##name (DisasContext *ctx) \ @@ -5177,7 +5188,7 @@ static inline void gen_##name (DisasContext *ctx) \
5177 static inline void gen_##name (DisasContext *ctx) \ 5188 static inline void gen_##name (DisasContext *ctx) \
5178 { \ 5189 { \
5179 if (unlikely(!ctx->spe_enabled)) { \ 5190 if (unlikely(!ctx->spe_enabled)) { \
5180 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5191 + GEN_EXCP_NO_AP(ctx); \
5181 return; \ 5192 return; \
5182 } \ 5193 } \
5183 gen_op_load_gpr64_T0(rA(ctx->opcode)); \ 5194 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
@@ -5189,7 +5200,7 @@ static inline void gen_##name (DisasContext *ctx) \ @@ -5189,7 +5200,7 @@ static inline void gen_##name (DisasContext *ctx) \
5189 static inline void gen_##name (DisasContext *ctx) \ 5200 static inline void gen_##name (DisasContext *ctx) \
5190 { \ 5201 { \
5191 if (unlikely(!ctx->spe_enabled)) { \ 5202 if (unlikely(!ctx->spe_enabled)) { \
5192 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5203 + GEN_EXCP_NO_AP(ctx); \
5193 return; \ 5204 return; \
5194 } \ 5205 } \
5195 gen_op_load_gpr64_T0(rA(ctx->opcode)); \ 5206 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
@@ -5239,7 +5250,7 @@ static inline void gen_brinc (DisasContext *ctx) @@ -5239,7 +5250,7 @@ static inline void gen_brinc (DisasContext *ctx)
5239 static inline void gen_##name##i (DisasContext *ctx) \ 5250 static inline void gen_##name##i (DisasContext *ctx) \
5240 { \ 5251 { \
5241 if (unlikely(!ctx->spe_enabled)) { \ 5252 if (unlikely(!ctx->spe_enabled)) { \
5242 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5253 + GEN_EXCP_NO_AP(ctx); \
5243 return; \ 5254 return; \
5244 } \ 5255 } \
5245 gen_op_load_gpr64_T0(rB(ctx->opcode)); \ 5256 gen_op_load_gpr64_T0(rB(ctx->opcode)); \
@@ -5252,7 +5263,7 @@ static inline void gen_##name##i (DisasContext *ctx) \ @@ -5252,7 +5263,7 @@ static inline void gen_##name##i (DisasContext *ctx) \
5252 static inline void gen_##name##i (DisasContext *ctx) \ 5263 static inline void gen_##name##i (DisasContext *ctx) \
5253 { \ 5264 { \
5254 if (unlikely(!ctx->spe_enabled)) { \ 5265 if (unlikely(!ctx->spe_enabled)) { \
5255 - RET_EXCP(ctx, EXCP_NO_SPE, 0); \ 5266 + GEN_EXCP_NO_AP(ctx); \
5256 return; \ 5267 return; \
5257 } \ 5268 } \
5258 gen_op_load_gpr64_T0(rA(ctx->opcode)); \ 5269 gen_op_load_gpr64_T0(rA(ctx->opcode)); \
@@ -5324,7 +5335,7 @@ GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE); //// @@ -5324,7 +5335,7 @@ GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE); ////
5324 static inline void gen_evsel (DisasContext *ctx) 5335 static inline void gen_evsel (DisasContext *ctx)
5325 { 5336 {
5326 if (unlikely(!ctx->spe_enabled)) { 5337 if (unlikely(!ctx->spe_enabled)) {
5327 - RET_EXCP(ctx, EXCP_NO_SPE, 0); 5338 + GEN_EXCP_NO_AP(ctx);
5328 return; 5339 return;
5329 } 5340 }
5330 gen_op_load_crf_T0(ctx->opcode & 0x7); 5341 gen_op_load_crf_T0(ctx->opcode & 0x7);
@@ -5942,7 +5953,7 @@ static inline int gen_intermediate_code_internal (CPUState *env, @@ -5942,7 +5953,7 @@ static inline int gen_intermediate_code_internal (CPUState *env,
5942 nb_gen_labels = 0; 5953 nb_gen_labels = 0;
5943 ctx.nip = pc_start; 5954 ctx.nip = pc_start;
5944 ctx.tb = tb; 5955 ctx.tb = tb;
5945 - ctx.exception = EXCP_NONE; 5956 + ctx.exception = POWERPC_EXCP_NONE;
5946 ctx.spr_cb = env->spr_cb; 5957 ctx.spr_cb = env->spr_cb;
5947 #if defined(CONFIG_USER_ONLY) 5958 #if defined(CONFIG_USER_ONLY)
5948 ctx.mem_idx = msr_le; 5959 ctx.mem_idx = msr_le;
@@ -5969,7 +5980,7 @@ static inline int gen_intermediate_code_internal (CPUState *env, @@ -5969,7 +5980,7 @@ static inline int gen_intermediate_code_internal (CPUState *env,
5969 msr_se = 1; 5980 msr_se = 1;
5970 #endif 5981 #endif
5971 /* Set env in case of segfault during code fetch */ 5982 /* Set env in case of segfault during code fetch */
5972 - while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) { 5983 + while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
5973 if (unlikely(env->nb_breakpoints > 0)) { 5984 if (unlikely(env->nb_breakpoints > 0)) {
5974 for (j = 0; j < env->nb_breakpoints; j++) { 5985 for (j = 0; j < env->nb_breakpoints; j++) {
5975 if (env->breakpoints[j] == ctx.nip) { 5986 if (env->breakpoints[j] == ctx.nip) {
@@ -6038,18 +6049,18 @@ static inline int gen_intermediate_code_internal (CPUState *env, @@ -6038,18 +6049,18 @@ static inline int gen_intermediate_code_internal (CPUState *env,
6038 if (unlikely((ctx.opcode & handler->inval) != 0)) { 6049 if (unlikely((ctx.opcode & handler->inval) != 0)) {
6039 if (loglevel != 0) { 6050 if (loglevel != 0) {
6040 fprintf(logfile, "invalid bits: %08x for opcode: " 6051 fprintf(logfile, "invalid bits: %08x for opcode: "
6041 - "%02x -%02x - %02x (%08x) 0x" ADDRX "\n", 6052 + "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6042 ctx.opcode & handler->inval, opc1(ctx.opcode), 6053 ctx.opcode & handler->inval, opc1(ctx.opcode),
6043 opc2(ctx.opcode), opc3(ctx.opcode), 6054 opc2(ctx.opcode), opc3(ctx.opcode),
6044 ctx.opcode, ctx.nip - 4); 6055 ctx.opcode, ctx.nip - 4);
6045 } else { 6056 } else {
6046 printf("invalid bits: %08x for opcode: " 6057 printf("invalid bits: %08x for opcode: "
6047 - "%02x -%02x - %02x (%08x) 0x" ADDRX "\n", 6058 + "%02x - %02x - %02x (%08x) 0x" ADDRX "\n",
6048 ctx.opcode & handler->inval, opc1(ctx.opcode), 6059 ctx.opcode & handler->inval, opc1(ctx.opcode),
6049 opc2(ctx.opcode), opc3(ctx.opcode), 6060 opc2(ctx.opcode), opc3(ctx.opcode),
6050 ctx.opcode, ctx.nip - 4); 6061 ctx.opcode, ctx.nip - 4);
6051 } 6062 }
6052 - RET_INVAL(ctxp); 6063 + GEN_EXCP_INVAL(ctxp);
6053 break; 6064 break;
6054 } 6065 }
6055 } 6066 }
@@ -6059,7 +6070,7 @@ static inline int gen_intermediate_code_internal (CPUState *env, @@ -6059,7 +6070,7 @@ static inline int gen_intermediate_code_internal (CPUState *env,
6059 #endif 6070 #endif
6060 /* Check trace mode exceptions */ 6071 /* Check trace mode exceptions */
6061 #if 0 // XXX: buggy on embedded PowerPC 6072 #if 0 // XXX: buggy on embedded PowerPC
6062 - if (unlikely((msr_be && ctx.exception == EXCP_BRANCH) || 6073 + if (unlikely((msr_be && ctx.exception == POWERPC_EXCP_BRANCH) ||
6063 /* Check in single step trace mode 6074 /* Check in single step trace mode
6064 * we need to stop except if: 6075 * we need to stop except if:
6065 * - rfi, trap or syscall 6076 * - rfi, trap or syscall
@@ -6068,10 +6079,13 @@ static inline int gen_intermediate_code_internal (CPUState *env, @@ -6068,10 +6079,13 @@ static inline int gen_intermediate_code_internal (CPUState *env,
6068 (msr_se && (ctx.nip < 0x100 || 6079 (msr_se && (ctx.nip < 0x100 ||
6069 ctx.nip > 0xF00 || 6080 ctx.nip > 0xF00 ||
6070 (ctx.nip & 0xFC) != 0x04) && 6081 (ctx.nip & 0xFC) != 0x04) &&
6071 - ctx.exception != EXCP_SYSCALL &&  
6072 - ctx.exception != EXCP_SYSCALL_USER &&  
6073 - ctx.exception != EXCP_TRAP))) {  
6074 - RET_EXCP(ctxp, EXCP_TRACE, 0); 6082 +#if defined(CONFIG_USER_ONLY)
  6083 + ctx.exception != POWERPC_EXCP_SYSCALL_USER &&
  6084 +#else
  6085 + ctx.exception != POWERPC_EXCP_SYSCALL &&
  6086 +#endif
  6087 + ctx.exception != POWERPC_EXCP_TRAP))) {
  6088 + GEN_EXCP(ctxp, POWERPC_EXCP_TRACE, 0);
6075 } 6089 }
6076 #endif 6090 #endif
6077 /* if we reach a page boundary or are single stepping, stop 6091 /* if we reach a page boundary or are single stepping, stop
@@ -6085,9 +6099,9 @@ static inline int gen_intermediate_code_internal (CPUState *env, @@ -6085,9 +6099,9 @@ static inline int gen_intermediate_code_internal (CPUState *env,
6085 break; 6099 break;
6086 #endif 6100 #endif
6087 } 6101 }
6088 - if (ctx.exception == EXCP_NONE) { 6102 + if (ctx.exception == POWERPC_EXCP_NONE) {
6089 gen_goto_tb(&ctx, 0, ctx.nip); 6103 gen_goto_tb(&ctx, 0, ctx.nip);
6090 - } else if (ctx.exception != EXCP_BRANCH) { 6104 + } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
6091 gen_op_reset_T0(); 6105 gen_op_reset_T0();
6092 /* Generate the return instruction */ 6106 /* Generate the return instruction */
6093 gen_op_exit_tb(); 6107 gen_op_exit_tb();