mirror of https://github.com/xqemu/xqemu.git
s390 support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@65 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
7854b05654
commit
fb3e5849bb
|
@ -42,6 +42,9 @@ case "$cpu" in
|
||||||
mips)
|
mips)
|
||||||
cpu="mips"
|
cpu="mips"
|
||||||
;;
|
;;
|
||||||
|
s390)
|
||||||
|
cpu="s390"
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
cpu="unknown"
|
cpu="unknown"
|
||||||
;;
|
;;
|
||||||
|
@ -137,7 +140,7 @@ fi
|
||||||
else
|
else
|
||||||
|
|
||||||
# if cross compiling, cannot launch a program, so make a static guess
|
# 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"
|
bigendian="yes"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -212,6 +215,8 @@ elif test "$cpu" = "powerpc" ; then
|
||||||
echo "ARCH=ppc" >> config.mak
|
echo "ARCH=ppc" >> config.mak
|
||||||
elif test "$cpu" = "mips" ; then
|
elif test "$cpu" = "mips" ; then
|
||||||
echo "ARCH=mips" >> config.mak
|
echo "ARCH=mips" >> config.mak
|
||||||
|
elif test "$cpu" = "s390" ; then
|
||||||
|
echo "ARCH=s390" >> config.mak
|
||||||
else
|
else
|
||||||
echo "Unsupported CPU"
|
echo "Unsupported CPU"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
62
dyngen.c
62
dyngen.c
|
@ -28,6 +28,15 @@
|
||||||
|
|
||||||
#include "thunk.h"
|
#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 */
|
/* all dynamically generated functions begin with this code */
|
||||||
#define OP_PREFIX "op_"
|
#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;
|
copy_size = p - p_start;
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
error("unsupported CPU (%d)", e_machine);
|
error("unsupported CPU (%d)", e_machine);
|
||||||
}
|
}
|
||||||
|
@ -405,6 +425,42 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
error("unsupported CPU for relocations (%d)", e_machine);
|
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:
|
case EM_SPARC:
|
||||||
cpu_name = "sparc";
|
cpu_name = "sparc";
|
||||||
break;
|
break;
|
||||||
|
case EM_S390:
|
||||||
|
cpu_name = "s390";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
error("unsupported CPU (e_machine=%d)", e_machine);
|
error("unsupported CPU (e_machine=%d)", e_machine);
|
||||||
}
|
}
|
||||||
|
@ -617,6 +676,9 @@ fprintf(outfile,
|
||||||
case EM_PPC:
|
case EM_PPC:
|
||||||
fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x4e800020; /* blr */\n");
|
fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x4e800020; /* blr */\n");
|
||||||
break;
|
break;
|
||||||
|
case EM_S390:
|
||||||
|
fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
error("no return generation for cpu '%s'", cpu_name);
|
error("no return generation for cpu '%s'", cpu_name);
|
||||||
}
|
}
|
||||||
|
|
14
exec-i386.c
14
exec-i386.c
|
@ -87,6 +87,20 @@ static inline int testandset (int *p)
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
int global_cpu_lock = 0;
|
||||||
|
|
||||||
void cpu_lock(void)
|
void cpu_lock(void)
|
||||||
|
|
|
@ -93,6 +93,12 @@ register unsigned int T1 asm("l1");
|
||||||
register unsigned int A0 asm("l2");
|
register unsigned int A0 asm("l2");
|
||||||
register struct CPUX86State *env asm("l3");
|
register struct CPUX86State *env asm("l3");
|
||||||
#endif
|
#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 */
|
/* force GCC to generate only one epilog at the end of the function */
|
||||||
#define FORCE_RET() asm volatile ("");
|
#define FORCE_RET() asm volatile ("");
|
||||||
|
|
|
@ -50,6 +50,12 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __s390__
|
||||||
|
static inline void flush_icache_range(unsigned long start, unsigned long stop)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __powerpc__
|
#ifdef __powerpc__
|
||||||
|
|
||||||
#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
|
#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
|
||||||
|
|
Loading…
Reference in New Issue