Commit fdbb4691 authored by Fabrice Bellard's avatar Fabrice Bellard
Browse files

Solaris/SPARC host port (Ben Taylor)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1979 c046a42c-6fe2-441c-8c8c-71466251a162
parent 43057ab1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -9,6 +9,9 @@ CFLAGS=-Wall -O2 -g -fno-strict-aliasing -I.
ifdef CONFIG_DARWIN
CFLAGS+= -mdynamic-no-pic
endif
ifeq ($(ARCH),sparc)
CFLAGS+=-mcpu=ultrasparc
endif
LDFLAGS=-g
LIBS=
DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+6 −0
Original line number Diff line number Diff line
@@ -102,6 +102,11 @@ LDFLAGS+=-Wl,-T,$(SRC_PATH)/s390.ld
endif

ifeq ($(ARCH),sparc)
ifeq ($(CONFIG_SOLARIS),yes)
CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g2 -ffixed-g3
LDFLAGS+=-m32
OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -fno-omit-frame-pointer -ffixed-i0
else
CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
LDFLAGS+=-m32
OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
@@ -109,6 +114,7 @@ HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat
# -static is used to avoid g1/g3 usage by the dynamic linker
LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static
endif
endif

ifeq ($(ARCH),sparc64)
CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
+14 −12
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ int cpu_exec(CPUState *env1)
    uint32_t *saved_regwptr;
#endif
#endif
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
    int saved_i7, tmp_T0;
#endif
    int ret, interrupt_request;
@@ -323,7 +323,7 @@ int cpu_exec(CPUState *env1)
#if defined(reg_T2)
    saved_T2 = T2;
#endif
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
    /* we also save i7 because longjmp may not restore it */
    asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
#endif
@@ -447,7 +447,7 @@ int cpu_exec(CPUState *env1)

            T0 = 0; /* force lookup of first TB */
            for(;;) {
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
                /* g1 can be modified by some libc? functions */ 
                tmp_T0 = T0;
#endif	    
@@ -467,7 +467,7 @@ int cpu_exec(CPUState *env1)
                        do_interrupt(intno, 0, 0, 0, 1);
                        /* ensure that no TB jump will be modified as
                           the program flow was changed */
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
                        tmp_T0 = 0;
#else
                        T0 = 0;
@@ -486,7 +486,7 @@ int cpu_exec(CPUState *env1)
			    env->error_code = 0;
                            do_interrupt(env);
                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
                            tmp_T0 = 0;
#else
                            T0 = 0;
@@ -497,7 +497,7 @@ int cpu_exec(CPUState *env1)
                            env->error_code = 0;
                            do_interrupt(env);
                            env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
                            tmp_T0 = 0;
#else
                            T0 = 0;
@@ -516,7 +516,7 @@ int cpu_exec(CPUState *env1)
                        env->error_code = 0;
                        do_interrupt(env);
                        env->interrupt_request &= ~CPU_INTERRUPT_HARD;
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
                        tmp_T0 = 0;
#else
                        T0 = 0;
@@ -534,7 +534,7 @@ int cpu_exec(CPUState *env1)
			    env->interrupt_request &= ~CPU_INTERRUPT_HARD;
			    do_interrupt(env->interrupt_index);
			    env->interrupt_index = 0;
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
                            tmp_T0 = 0;
#else
                            T0 = 0;
@@ -567,7 +567,7 @@ int cpu_exec(CPUState *env1)
                        env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
                        /* ensure that no TB jump will be modified as
                           the program flow was changed */
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
                        tmp_T0 = 0;
#else
                        T0 = 0;
@@ -635,7 +635,7 @@ int cpu_exec(CPUState *env1)
                            lookup_symbol(tb->pc));
                }
#endif
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
                T0 = tmp_T0;
#endif	    
                /* see if we can patch the calling TB. When the TB
@@ -671,7 +671,9 @@ int cpu_exec(CPUState *env1)
                                     "mov	%%o7,%%i0"
                                     : /* no outputs */
                                     : "r" (gen_func) 
                                     : "i0", "i1", "i2", "i3", "i4", "i5");
                                     : "i0", "i1", "i2", "i3", "i4", "i5",
                                       "l0", "l1", "l2", "l3", "l4", "l5",
                                       "l6", "l7");
#elif defined(__arm__)
                asm volatile ("mov pc, %0\n\t"
                              ".global exec_loop\n\t"
@@ -836,7 +838,7 @@ int cpu_exec(CPUState *env1)
#else
#error unsupported target CPU
#endif
#ifdef __sparc__
#if defined(__sparc__) && !defined(HOST_SOLARIS)
    asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
#endif
    T0 = saved_T0;
+10 −4
Original line number Diff line number Diff line
@@ -121,6 +121,13 @@ extern int printf(const char *, ...);
#define AREG3 "s2"
#endif
#ifdef __sparc__
#ifdef HOST_SOLARIS
#define AREG0 "g2"
#define AREG1 "g3"
#define AREG2 "g4"
#define AREG3 "g5"
#define AREG4 "g6"
#else
#define AREG0 "g6"
#define AREG1 "g1"
#define AREG2 "g2"
@@ -133,6 +140,7 @@ extern int printf(const char *, ...);
#define AREG9 "l5"
#define AREG10 "l6"
#define AREG11 "l7"
#endif
#define USE_FP_CONVERT
#endif
#ifdef __s390__
@@ -241,10 +249,8 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
					  ASM_NAME(__op_gen_label) #n)
#endif
#ifdef __sparc__
#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0\n" \
                                "nop")
#define        GOTO_LABEL_PARAM(n) asm volatile ( \
               "set " ASM_NAME(__op_gen_label) #n ", %g1; jmp %g1; nop")
#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop")
#endif
#ifdef __arm__
#define EXIT_TB() asm volatile ("b exec_loop")
+26 −3
Original line number Diff line number Diff line
@@ -1440,6 +1440,12 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
    }
#elif defined(HOST_SPARC)
    {
#define INSN_SAVE       0x9de3a000
#define INSN_RET        0x81c7e008
#define INSN_RESTORE    0x81e80000
#define INSN_RETURN     0x81cfe008
#define INSN_NOP        0x01000000

        uint32_t start_insn, end_insn1, end_insn2;
        uint8_t *p;
        p = (void *)(p_end - 8);
@@ -1448,12 +1454,17 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
        start_insn = get32((uint32_t *)(p_start + 0x0));
        end_insn1 = get32((uint32_t *)(p + 0x0));
        end_insn2 = get32((uint32_t *)(p + 0x4));
        if ((start_insn & ~0x1fff) == 0x9de3a000) {
        if ((start_insn & ~0x1fff) == INSN_SAVE) {
            p_start += 0x4;
            start_offset += 0x4;
            if ((int)(start_insn | ~0x1fff) < -128)
                error("Found bogus save at the start of %s", name);
            if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000)
            if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
                /* SPARC v7: ret; restore; */ ;
            else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
                /* SPARC v9: return; nop; */ ;
            else

                error("ret; restore; not found at end of %s", name);
        } else {
            error("No save at the beginning of %s", name);
@@ -1462,7 +1473,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
        /* Skip a preceeding nop, if present.  */
        if (p > p_start) {
            skip_insn = get32((uint32_t *)(p - 0x4));
            if (skip_insn == 0x01000000)
            if (skip_insn == INSN_NOP)
                p -= 4;
        }
#endif
@@ -2151,6 +2162,18 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
				    reloc_offset, reloc_offset, name, addend,
				    reloc_offset);
			    break;
                        case R_SPARC_WDISP22:
                            fprintf(outfile,
                                    "    *(uint32_t *)(gen_code_ptr + %d) = "
                                    "((*(uint32_t *)(gen_code_ptr + %d)) "
                                    " & ~0x3fffff) "
                                    " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
                                    "    & 0x3fffff);\n",
                                    rel->r_offset - start_offset,
                                    rel->r_offset - start_offset,
                                    name, addend,
                                    rel->r_offset - start_offset);
                            break;
                        default:
                            error("unsupported sparc relocation (%d)", type);
                        }
Loading