]> git.proxmox.com Git - qemu.git/commitdiff
s390 support
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 29 Mar 2003 17:32:36 +0000 (17:32 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 29 Mar 2003 17:32:36 +0000 (17:32 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@65 c046a42c-6fe2-441c-8c8c-71466251a162

configure
dyngen.c
exec-i386.c
exec-i386.h
translate-i386.c

index d58c46079539735a18eba689b00fdcb317f870b5..c8d06adaac44f34f7107ebe29556757644f02416 100755 (executable)
--- a/configure
+++ b/configure
@@ -42,6 +42,9 @@ case "$cpu" in
   mips)
     cpu="mips"
   ;;
+  s390)
+    cpu="s390"
+  ;;
   *)
     cpu="unknown"
   ;;
@@ -137,7 +140,7 @@ fi
 else
 
 # if cross compiling, cannot launch a program, so make a static guess
-if test "$cpu" = "powerpc" -o "$cpu" = "mips" ; then
+if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" ; then
     bigendian="yes"
 fi
 
@@ -212,6 +215,8 @@ elif test "$cpu" = "powerpc" ; then
   echo "ARCH=ppc" >> config.mak
 elif test "$cpu" = "mips" ; then
   echo "ARCH=mips" >> config.mak
+elif test "$cpu" = "s390" ; then
+  echo "ARCH=s390" >> config.mak
 else
   echo "Unsupported CPU"
   exit 1
index 5cd59cb9dfbb5f3ed75ae6c54f36e1d0e651a26f..52cabcfabcba564b5a9a9686a42b19d4cc3241b0 100644 (file)
--- a/dyngen.c
+++ b/dyngen.c
 
 #include "thunk.h"
 
+/* temporary fix to make it compile with old elf headers (XXX: use
+   included elf.h in all cases) */
+#ifndef EM_390
+#define EM_S390                22              /* IBM S390 */
+#define R_390_8                1              /* Direct 8 bit.  */
+#define R_390_16       3              /* Direct 16 bit.  */
+#define R_390_32       4              /* Direct 32 bit.  */
+#endif
+
 /* all dynamically generated functions begin with this code */
 #define OP_PREFIX "op_"
 
@@ -236,6 +245,17 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
             copy_size = p - p_start;
         }
         break;
+    case EM_S390:
+       {
+           uint8_t *p;
+           p = (void *)(p_end - 2);
+           if (p == p_start)
+               error("empty code for %s", name);
+           if (get16((uint16_t *)p) != 0x07fe && get16((uint16_t *)p) != 0x07f4)
+               error("br %r14 expected at the end of %s", name);
+           copy_size = p - p_start;
+       }
+        break;
     default:
         error("unsupported CPU (%d)", e_machine);
     }
@@ -405,6 +425,42 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
                 }
             }
             break;
+        case EM_S390:
+            {
+                Elf32_Rela *rel;
+                char name[256];
+                int type;
+                long addend;
+                for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
+                    if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
+                        sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
+                        if (strstart(sym_name, "__op_param", &p)) {
+                            snprintf(name, sizeof(name), "param%s", p);
+                        } else {
+                            snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
+                        }
+                        type = ELF32_R_TYPE(rel->r_info);
+                        addend = rel->r_addend;
+                        switch(type) {
+                        case R_390_32:
+                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n", 
+                                    rel->r_offset - offset, name, addend);
+                            break;
+                        case R_390_16:
+                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %ld) = %s + %ld;\n", 
+                                    rel->r_offset - offset, name, addend);
+                            break;
+                        case R_390_8:
+                            fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + %ld) = %s + %ld;\n", 
+                                    rel->r_offset - offset, name, addend);
+                            break;
+                        default:
+                            error("unsupported s390 relocation (%d)", type);
+                        }
+                    }
+                }
+            }
+            break;
         default:
             error("unsupported CPU for relocations (%d)", e_machine);
         }
@@ -556,6 +612,9 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
     case EM_SPARC:
         cpu_name = "sparc";
         break;
+    case EM_S390:
+        cpu_name = "s390";
+        break;
     default:
         error("unsupported CPU (e_machine=%d)", e_machine);
     }
@@ -617,6 +676,9 @@ fprintf(outfile,
     case EM_PPC:
         fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x4e800020; /* blr */\n");
         break;
+    case EM_S390:
+        fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n");
+        break;
     default:
         error("no return generation for cpu '%s'", cpu_name);
     }
index f59e1ccecf1e25d6f5a7005593344edd69764ba9..dedcbfabd6015554d1b479ba0f9494673968df87 100644 (file)
@@ -87,6 +87,20 @@ static inline int testandset (int *p)
 }
 #endif
 
+#ifdef __s390__
+static inline int testandset (int *p)
+{
+    int ret;
+
+    __asm__ __volatile__ ("0: cs    %0,%1,0(%2)\n"
+                         "   jl    0b"
+                         : "=&d" (ret)
+                         : "r" (1), "a" (p), "0" (*p) 
+                         : "cc", "memory" );
+    return ret;
+}
+#endif
+
 int global_cpu_lock = 0;
 
 void cpu_lock(void)
index 7a6f74b924903419bad51521addcda9a66fbba3d..28da51def96c0b5d253f90be6d39ed6b64157b24 100644 (file)
@@ -93,6 +93,12 @@ register unsigned int T1 asm("l1");
 register unsigned int A0 asm("l2");
 register struct CPUX86State *env asm("l3");
 #endif
+#ifdef __s390__
+register unsigned int T0 asm("r7");
+register unsigned int T1 asm("r8");
+register unsigned int A0 asm("r9");
+register struct CPUX86State *env asm("r10");
+#endif
 
 /* force GCC to generate only one epilog at the end of the function */
 #define FORCE_RET() asm volatile ("");
index 730398e97179cf118a26ee83ae373899d1156246..55e8a8dde6fddc172b3eda8ac7d75022b337c32a 100644 (file)
@@ -50,6 +50,12 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
 }
 #endif
 
+#ifdef __s390__
+static inline void flush_icache_range(unsigned long start, unsigned long stop)
+{
+}
+#endif
+
 #ifdef __powerpc__
 
 #define MIN_CACHE_LINE_SIZE 8 /* conservative value */