ia64 host support (David Mosberger)
[qemu] / cpu-exec.c
index 1edfa19..59f1277 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  i386 emulator main execution loop
  * 
- *  Copyright (c) 2003 Fabrice Bellard
+ *  Copyright (c) 2003-2005 Fabrice Bellard
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -285,9 +285,18 @@ int cpu_exec(CPUState *env1)
                        }
                     }
 #elif defined(TARGET_SPARC)
-                    if (interrupt_request & CPU_INTERRUPT_HARD) {
-                       do_interrupt(env->interrupt_index);
-                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                    if ((interrupt_request & CPU_INTERRUPT_HARD) &&
+                       (env->psret != 0)) {
+                       int pil = env->interrupt_index & 15;
+                       int type = env->interrupt_index & 0xf0;
+
+                       if (((type == TT_EXTINT) &&
+                            (pil == 15 || pil > env->psrpil)) ||
+                           type != TT_EXTINT) {
+                           env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                           do_interrupt(env->interrupt_index);
+                           env->interrupt_index = 0;
+                       }
                    } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
                        //do_interrupt(0, 0, 0, 0, 0);
                        env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
@@ -346,7 +355,8 @@ int cpu_exec(CPUState *env1)
                 cs_base = env->segs[R_CS].base;
                 pc = cs_base + env->eip;
 #elif defined(TARGET_ARM)
-                flags = env->thumb;
+                flags = env->thumb | (env->vfp.vec_len << 1)
+                        | (env->vfp.vec_stride << 4);
                 cs_base = 0;
                 pc = env->regs[15];
 #elif defined(TARGET_SPARC)
@@ -354,7 +364,7 @@ int cpu_exec(CPUState *env1)
                 cs_base = env->npc;
                 pc = env->pc;
 #elif defined(TARGET_PPC)
-                flags = 0;
+                flags = (msr_pr << MSR_PR) | (msr_fp << MSR_FP) | (msr_se << MSR_SE);
                 cs_base = 0;
                 pc = env->nip;
 #else
@@ -563,6 +573,15 @@ int cpu_exec(CPUState *env1)
             );
     }
 }
+#elif defined(__ia64)
+               struct fptr {
+                       void *ip;
+                       void *gp;
+               } fp;
+
+               fp.ip = tc_ptr;
+               fp.gp = code_gen_buffer + 2 * (1 << 20);
+               (*(void (*)(void)) &fp)();
 #else
                 gen_func();
 #endif
@@ -619,6 +638,7 @@ int cpu_exec(CPUState *env1)
 #endif
 #elif defined(TARGET_ARM)
     env->cpsr = compute_cpsr();
+    /* XXX: Save/restore host fpu exception state?.  */
 #elif defined(TARGET_SPARC)
 #elif defined(TARGET_PPC)
 #else
@@ -1107,6 +1127,40 @@ int cpu_signal_handler(int host_signum, struct siginfo *info,
                              &uc->uc_sigmask, puc);
 }
 
+#elif defined(__ia64)
+
+#ifndef __ISR_VALID
+  /* This ought to be in <bits/siginfo.h>... */
+# define __ISR_VALID   1
+# define si_flags      _sifields._sigfault._si_pad0
+#endif
+
+int cpu_signal_handler(int host_signum, struct siginfo *info, void *puc)
+{
+    struct ucontext *uc = puc;
+    unsigned long ip;
+    int is_write = 0;
+
+    ip = uc->uc_mcontext.sc_ip;
+    switch (host_signum) {
+      case SIGILL:
+      case SIGFPE:
+      case SIGSEGV:
+      case SIGBUS:
+      case SIGTRAP:
+         if (info->si_code && (info->si_flags & __ISR_VALID))
+             /* ISR.W (write-access) is bit 33:  */
+             is_write = (info->si_isr >> 33) & 1;
+         break;
+
+      default:
+         break;
+    }
+    return handle_cpu_signal(ip, (unsigned long)info->si_addr,
+                             is_write,
+                             &uc->uc_sigmask, puc);
+}
+
 #else
 
 #error host CPU specific signal handler needed