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)\
signature.asc
Description: Digital signature