Hi folks

Thimo Seufer asked me to check if the s390 host supports works at all.
It did not even build, dyngen failed. I digged into the problem and
found the following:
gcc for s390 generates a data table after each function if necessary
instead of immediate loads. (g5, the oldest supported processor only
suports one halfword immediate load.) dyngen is not prepared for that
and fails. I found that gcc moves this data into the .rodata section if
generating code for z900 and above, which looked like a possible way to
support this.

The attached patch makes qemu build on a s390 host and able to run i386
kernels and userspace. powerpc did not boot, mips failed to start new
processes, the process reports illegal instruction, but the qemu log
does not reflect this.

It does the following changes:
- Hardcode -march=z900 to generate usable op code.
- Add redirection for parameter expansion in op code.
- Cleanup GOTO_LABEL_PARAM.
- Accept any return from function (like "br %r5").
- Support R_390_PC32DBL relocation, including relocations into sections.
- Disable special GOTO_TB handler, it segfaults.

Bastian

-- 
Each kiss is as the first.
                -- Miramanee, Kirk's wife, "The Paradise Syndrome",
                   stardate 4842.6
? diff
? host-op.h
? img
? trace
Index: check_ops.sh
===================================================================
RCS file: /sources/qemu/qemu/check_ops.sh,v
retrieving revision 1.1
diff -u -r1.1 check_ops.sh
--- check_ops.sh        7 Jan 2007 19:38:08 -0000       1.1
+++ check_ops.sh        10 Nov 2007 20:23:52 -0000
@@ -35,6 +35,9 @@
   mips*)
     ret='\tjr.*ra'
     ;;
+  s390*)
+    ret='\tbr.*'
+    ;;
   *)
     echo "Unknown machine `uname -m`"
     ;;
Index: configure
===================================================================
RCS file: /sources/qemu/qemu/configure,v
retrieving revision 1.169
diff -u -r1.169 configure
--- configure   8 Nov 2007 18:05:36 -0000       1.169
+++ configure   10 Nov 2007 20:23:53 -0000
@@ -341,6 +341,9 @@
                ARCH_LDFLAGS="${SP_LDFLAGS}"
            fi
            ;;
+    s390)
+          ARCH_CFLAGS="-march=z900"
+           ;;
 esac
 
 if [ "$solaris" = "yes" -a  "$cpu" = "x86_64" ] ; then
Index: dyngen-exec.h
===================================================================
RCS file: /sources/qemu/qemu/dyngen-exec.h,v
retrieving revision 1.38
diff -u -r1.38 dyngen-exec.h
--- dyngen-exec.h       16 Sep 2007 21:07:49 -0000      1.38
+++ dyngen-exec.h       10 Nov 2007 20:23:53 -0000
@@ -38,7 +38,7 @@
 // Linux/Sparc64 defines uint64_t
 #if !(defined (__sparc_v9__) && defined(__linux__))
 /* XXX may be done for all 64 bits targets ? */
-#if defined (__x86_64__) || defined(__ia64)
+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__)
 typedef unsigned long uint64_t;
 #else
 typedef unsigned long long uint64_t;
@@ -55,7 +55,7 @@
 typedef signed int int32_t;
 // Linux/Sparc64 defines int64_t
 #if !(defined (__sparc_v9__) && defined(__linux__))
-#if defined (__x86_64__) || defined(__ia64)
+#if defined (__x86_64__) || defined(__ia64) || defined(__s390x__)
 typedef signed long int64_t;
 #else
 typedef signed long long int64_t;
@@ -205,7 +205,7 @@
 #define stringify(s)   tostring(s)
 #define tostring(s)    #s
 
-#ifdef __alpha__
+#if defined(__alpha__) || defined(__s390__)
 /* the symbols are considered non exported so a br immediate is generated */
 #define __hidden __attribute__((visibility("hidden")))
 #else
@@ -224,6 +224,13 @@
 #define PARAM1 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param1)); _r; })
 #define PARAM2 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param2)); _r; })
 #define PARAM3 ({ int _r; asm("" : "=r"(_r) : "0" (&__op_param3)); _r; })
+#elif defined(__s390__)
+extern int __op_param1 __hidden;
+extern int __op_param2 __hidden;
+extern int __op_param3 __hidden;
+#define PARAM1 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param1) "; 
larl %0,-4; l %0,0(%0)" : "=r"(_r) : ); _r; })
+#define PARAM2 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param2) "; 
larl %0,-4; l %0,0(%0)" : "=r"(_r) : ); _r; })
+#define PARAM3 ({ int _r; asm("bras %0,8; .long " ASM_NAME(__op_param3) "; 
larl %0,-4; l %0,0(%0)" : "=r"(_r) : ); _r; })
 #else
 #if defined(__APPLE__)
 static int __op_param1, __op_param2, __op_param3;
@@ -254,7 +261,7 @@
 #define GOTO_LABEL_PARAM(n) asm volatile ("b " ASM_NAME(__op_gen_label) #n)
 #elif defined(__s390__)
 #define EXIT_TB() asm volatile ("br %r14")
-#define GOTO_LABEL_PARAM(n) asm volatile ("bras %r7,8; .long " 
ASM_NAME(__op_gen_label) #n "; l %r7, 0(%r7); br %r7")
+#define GOTO_LABEL_PARAM(n) asm volatile ("larl %r7,12; l %r7,0(%r7); br %r7; 
.long " ASM_NAME(__op_gen_label) #n)
 #elif defined(__alpha__)
 #define EXIT_TB() asm volatile ("ret")
 #elif defined(__ia64__)
Index: dyngen.c
===================================================================
RCS file: /sources/qemu/qemu/dyngen.c,v
retrieving revision 1.57
diff -u -r1.57 dyngen.c
--- dyngen.c    7 Nov 2007 16:07:32 -0000       1.57
+++ dyngen.c    10 Nov 2007 20:23:53 -0000
@@ -1495,8 +1495,8 @@
         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);
+        if ((get16((uint16_t *)p) & 0xfff0) != 0x07f0)
+            error("br expected at the end of %s", name);
         copy_size = p - p_start;
     }
 #elif defined(HOST_ALPHA)
@@ -2120,6 +2120,19 @@
                             fprintf(outfile, "    *(uint8_t *)(gen_code_ptr + 
%d) = %s + %d;\n",
                                     reloc_offset, relname, addend);
                             break;
+                        case R_390_PC32DBL:
+                            if 
(ELF32_ST_TYPE(symtab[ELFW(R_SYM)(rel->r_info)].st_info) == STT_SECTION) {
+                                fprintf(outfile,
+                                        "    *(uint32_t *)(gen_code_ptr + %d) 
+= "
+                                        "((long)&%s - (long)gen_code_ptr) >> 
1;\n",
+                                        reloc_offset, name);
+                            }
+                            else
+                                fprintf(outfile,
+                                        "    *(uint32_t *)(gen_code_ptr + %d) 
= "
+                                        "(%s + %d - ((uint32_t)gen_code_ptr + 
%d)) >> 1;\n",
+                                        reloc_offset, relname, addend, 
reloc_offset);
+                            break;
                         default:
                             error("unsupported s390 relocation (%d)", type);
                         }
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.70
diff -u -r1.70 exec-all.h
--- exec-all.h  4 Nov 2007 02:24:57 -0000       1.70
+++ exec-all.h  10 Nov 2007 20:23:53 -0000
@@ -350,7 +350,8 @@
                  "1:\n");\
 } while (0)
 
-#elif defined(__s390__)
+#elif 0 && defined(__s390__)
+/* XXX: SIGSEGV */
 /* GCC spills R13, so we have to restore it before branching away */
 
 #define GOTO_TB(opname, tbparam, n)\

Attachment: signature.asc
Description: Digital signature

Reply via email to