microblaze: User-mode emulation of hw-excp signals
authorEdgar E. Iglesias <edgar.iglesias@petalogix.com>
Thu, 9 Sep 2010 08:24:01 +0000 (10:24 +0200)
committerEdgar E. Iglesias <edgar.iglesias@gmail.com>
Thu, 9 Sep 2010 08:24:01 +0000 (10:24 +0200)
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@petalogix.com>
linux-user/main.c

index fa29d7773af4dade2673d8366bdb3615de816fd9..69d050f91bd516f95a6cd84fe98bdcc7bed9f8ac 100644 (file)
@@ -2233,6 +2233,37 @@ void cpu_loop (CPUState *env)
             env->regs[3] = ret;
             env->sregs[SR_PC] = env->regs[14];
             break;
+        case EXCP_HW_EXCP:
+            env->regs[17] = env->sregs[SR_PC] + 4;
+            if (env->iflags & D_FLAG) {
+                env->sregs[SR_ESR] |= 1 << 12;
+                env->sregs[SR_PC] -= 4;
+                /* FIXME: if branch was immed, replay the imm aswell.  */
+            }
+
+            env->iflags &= ~(IMM_FLAG | D_FLAG);
+
+            switch (env->sregs[SR_ESR] & 31) {
+                case ESR_EC_FPU:
+                    info.si_signo = SIGFPE;
+                    info.si_errno = 0;
+                    if (env->sregs[SR_FSR] & FSR_IO) {
+                        info.si_code = TARGET_FPE_FLTINV;
+                    }
+                    if (env->sregs[SR_FSR] & FSR_DZ) {
+                        info.si_code = TARGET_FPE_FLTDIV;
+                    }
+                    info._sifields._sigfault._addr = 0;
+                    queue_signal(env, info.si_signo, &info);
+                    break;
+                default:
+                    printf ("Unhandled hw-exception: 0x%x\n",
+                            env->sregs[SR_ESR] & 5);
+                    cpu_dump_state(env, stderr, fprintf, 0);
+                    exit (1);
+                    break;
+            }
+            break;
         case EXCP_DEBUG:
             {
                 int sig;