Commit fb3e5849bb139e8213b7afb5abd7ef5cc985d10b

Authored by bellard
1 parent 7854b056

s390 support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@65 c046a42c-6fe2-441c-8c8c-71466251a162
configure
@@ -42,6 +42,9 @@ case "$cpu" in @@ -42,6 +42,9 @@ case "$cpu" in
42 mips) 42 mips)
43 cpu="mips" 43 cpu="mips"
44 ;; 44 ;;
  45 + s390)
  46 + cpu="s390"
  47 + ;;
45 *) 48 *)
46 cpu="unknown" 49 cpu="unknown"
47 ;; 50 ;;
@@ -137,7 +140,7 @@ fi @@ -137,7 +140,7 @@ fi
137 else 140 else
138 141
139 # if cross compiling, cannot launch a program, so make a static guess 142 # if cross compiling, cannot launch a program, so make a static guess
140 -if test "$cpu" = "powerpc" -o "$cpu" = "mips" ; then 143 +if test "$cpu" = "powerpc" -o "$cpu" = "mips" -o "$cpu" = "s390" ; then
141 bigendian="yes" 144 bigendian="yes"
142 fi 145 fi
143 146
@@ -212,6 +215,8 @@ elif test "$cpu" = "powerpc" ; then @@ -212,6 +215,8 @@ elif test "$cpu" = "powerpc" ; then
212 echo "ARCH=ppc" >> config.mak 215 echo "ARCH=ppc" >> config.mak
213 elif test "$cpu" = "mips" ; then 216 elif test "$cpu" = "mips" ; then
214 echo "ARCH=mips" >> config.mak 217 echo "ARCH=mips" >> config.mak
  218 +elif test "$cpu" = "s390" ; then
  219 + echo "ARCH=s390" >> config.mak
215 else 220 else
216 echo "Unsupported CPU" 221 echo "Unsupported CPU"
217 exit 1 222 exit 1
dyngen.c
@@ -28,6 +28,15 @@ @@ -28,6 +28,15 @@
28 28
29 #include "thunk.h" 29 #include "thunk.h"
30 30
  31 +/* temporary fix to make it compile with old elf headers (XXX: use
  32 + included elf.h in all cases) */
  33 +#ifndef EM_390
  34 +#define EM_S390 22 /* IBM S390 */
  35 +#define R_390_8 1 /* Direct 8 bit. */
  36 +#define R_390_16 3 /* Direct 16 bit. */
  37 +#define R_390_32 4 /* Direct 32 bit. */
  38 +#endif
  39 +
31 /* all dynamically generated functions begin with this code */ 40 /* all dynamically generated functions begin with this code */
32 #define OP_PREFIX "op_" 41 #define OP_PREFIX "op_"
33 42
@@ -236,6 +245,17 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -236,6 +245,17 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
236 copy_size = p - p_start; 245 copy_size = p - p_start;
237 } 246 }
238 break; 247 break;
  248 + case EM_S390:
  249 + {
  250 + uint8_t *p;
  251 + p = (void *)(p_end - 2);
  252 + if (p == p_start)
  253 + error("empty code for %s", name);
  254 + if (get16((uint16_t *)p) != 0x07fe && get16((uint16_t *)p) != 0x07f4)
  255 + error("br %r14 expected at the end of %s", name);
  256 + copy_size = p - p_start;
  257 + }
  258 + break;
239 default: 259 default:
240 error("unsupported CPU (%d)", e_machine); 260 error("unsupported CPU (%d)", e_machine);
241 } 261 }
@@ -405,6 +425,42 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -405,6 +425,42 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
405 } 425 }
406 } 426 }
407 break; 427 break;
  428 + case EM_S390:
  429 + {
  430 + Elf32_Rela *rel;
  431 + char name[256];
  432 + int type;
  433 + long addend;
  434 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  435 + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
  436 + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
  437 + if (strstart(sym_name, "__op_param", &p)) {
  438 + snprintf(name, sizeof(name), "param%s", p);
  439 + } else {
  440 + snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
  441 + }
  442 + type = ELF32_R_TYPE(rel->r_info);
  443 + addend = rel->r_addend;
  444 + switch(type) {
  445 + case R_390_32:
  446 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  447 + rel->r_offset - offset, name, addend);
  448 + break;
  449 + case R_390_16:
  450 + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  451 + rel->r_offset - offset, name, addend);
  452 + break;
  453 + case R_390_8:
  454 + fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  455 + rel->r_offset - offset, name, addend);
  456 + break;
  457 + default:
  458 + error("unsupported s390 relocation (%d)", type);
  459 + }
  460 + }
  461 + }
  462 + }
  463 + break;
408 default: 464 default:
409 error("unsupported CPU for relocations (%d)", e_machine); 465 error("unsupported CPU for relocations (%d)", e_machine);
410 } 466 }
@@ -556,6 +612,9 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) @@ -556,6 +612,9 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
556 case EM_SPARC: 612 case EM_SPARC:
557 cpu_name = "sparc"; 613 cpu_name = "sparc";
558 break; 614 break;
  615 + case EM_S390:
  616 + cpu_name = "s390";
  617 + break;
559 default: 618 default:
560 error("unsupported CPU (e_machine=%d)", e_machine); 619 error("unsupported CPU (e_machine=%d)", e_machine);
561 } 620 }
@@ -617,6 +676,9 @@ fprintf(outfile, @@ -617,6 +676,9 @@ fprintf(outfile,
617 case EM_PPC: 676 case EM_PPC:
618 fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x4e800020; /* blr */\n"); 677 fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x4e800020; /* blr */\n");
619 break; 678 break;
  679 + case EM_S390:
  680 + fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n");
  681 + break;
620 default: 682 default:
621 error("no return generation for cpu '%s'", cpu_name); 683 error("no return generation for cpu '%s'", cpu_name);
622 } 684 }
exec-i386.c
@@ -87,6 +87,20 @@ static inline int testandset (int *p) @@ -87,6 +87,20 @@ static inline int testandset (int *p)
87 } 87 }
88 #endif 88 #endif
89 89
  90 +#ifdef __s390__
  91 +static inline int testandset (int *p)
  92 +{
  93 + int ret;
  94 +
  95 + __asm__ __volatile__ ("0: cs %0,%1,0(%2)\n"
  96 + " jl 0b"
  97 + : "=&d" (ret)
  98 + : "r" (1), "a" (p), "0" (*p)
  99 + : "cc", "memory" );
  100 + return ret;
  101 +}
  102 +#endif
  103 +
90 int global_cpu_lock = 0; 104 int global_cpu_lock = 0;
91 105
92 void cpu_lock(void) 106 void cpu_lock(void)
exec-i386.h
@@ -93,6 +93,12 @@ register unsigned int T1 asm(&quot;l1&quot;); @@ -93,6 +93,12 @@ register unsigned int T1 asm(&quot;l1&quot;);
93 register unsigned int A0 asm("l2"); 93 register unsigned int A0 asm("l2");
94 register struct CPUX86State *env asm("l3"); 94 register struct CPUX86State *env asm("l3");
95 #endif 95 #endif
  96 +#ifdef __s390__
  97 +register unsigned int T0 asm("r7");
  98 +register unsigned int T1 asm("r8");
  99 +register unsigned int A0 asm("r9");
  100 +register struct CPUX86State *env asm("r10");
  101 +#endif
96 102
97 /* force GCC to generate only one epilog at the end of the function */ 103 /* force GCC to generate only one epilog at the end of the function */
98 #define FORCE_RET() asm volatile (""); 104 #define FORCE_RET() asm volatile ("");
translate-i386.c
@@ -50,6 +50,12 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop) @@ -50,6 +50,12 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
50 } 50 }
51 #endif 51 #endif
52 52
  53 +#ifdef __s390__
  54 +static inline void flush_icache_range(unsigned long start, unsigned long stop)
  55 +{
  56 +}
  57 +#endif
  58 +
53 #ifdef __powerpc__ 59 #ifdef __powerpc__
54 60
55 #define MIN_CACHE_LINE_SIZE 8 /* conservative value */ 61 #define MIN_CACHE_LINE_SIZE 8 /* conservative value */