Commit fdbb46910a2033bd748681346d4261725f5e184b

Authored by bellard
1 parent 43057ab1

Solaris/SPARC host port (Ben Taylor)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1979 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
@@ -9,6 +9,9 @@ CFLAGS=-Wall -O2 -g -fno-strict-aliasing -I. @@ -9,6 +9,9 @@ CFLAGS=-Wall -O2 -g -fno-strict-aliasing -I.
9 ifdef CONFIG_DARWIN 9 ifdef CONFIG_DARWIN
10 CFLAGS+= -mdynamic-no-pic 10 CFLAGS+= -mdynamic-no-pic
11 endif 11 endif
  12 +ifeq ($(ARCH),sparc)
  13 +CFLAGS+=-mcpu=ultrasparc
  14 +endif
12 LDFLAGS=-g 15 LDFLAGS=-g
13 LIBS= 16 LIBS=
14 DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE 17 DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
Makefile.target
@@ -102,6 +102,11 @@ LDFLAGS+=-Wl,-T,$(SRC_PATH)/s390.ld @@ -102,6 +102,11 @@ LDFLAGS+=-Wl,-T,$(SRC_PATH)/s390.ld
102 endif 102 endif
103 103
104 ifeq ($(ARCH),sparc) 104 ifeq ($(ARCH),sparc)
  105 +ifeq ($(CONFIG_SOLARIS),yes)
  106 +CFLAGS+=-mcpu=ultrasparc -m32 -ffixed-g2 -ffixed-g3
  107 +LDFLAGS+=-m32
  108 +OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -fno-omit-frame-pointer -ffixed-i0
  109 +else
105 CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6 110 CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
106 LDFLAGS+=-m32 111 LDFLAGS+=-m32
107 OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0 112 OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0
@@ -109,6 +114,7 @@ HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat @@ -109,6 +114,7 @@ HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat
109 # -static is used to avoid g1/g3 usage by the dynamic linker 114 # -static is used to avoid g1/g3 usage by the dynamic linker
110 LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static 115 LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static
111 endif 116 endif
  117 +endif
112 118
113 ifeq ($(ARCH),sparc64) 119 ifeq ($(ARCH),sparc64)
114 CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6 120 CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6
cpu-exec.c
@@ -253,7 +253,7 @@ int cpu_exec(CPUState *env1) @@ -253,7 +253,7 @@ int cpu_exec(CPUState *env1)
253 uint32_t *saved_regwptr; 253 uint32_t *saved_regwptr;
254 #endif 254 #endif
255 #endif 255 #endif
256 -#ifdef __sparc__ 256 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
257 int saved_i7, tmp_T0; 257 int saved_i7, tmp_T0;
258 #endif 258 #endif
259 int ret, interrupt_request; 259 int ret, interrupt_request;
@@ -323,7 +323,7 @@ int cpu_exec(CPUState *env1) @@ -323,7 +323,7 @@ int cpu_exec(CPUState *env1)
323 #if defined(reg_T2) 323 #if defined(reg_T2)
324 saved_T2 = T2; 324 saved_T2 = T2;
325 #endif 325 #endif
326 -#ifdef __sparc__ 326 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
327 /* we also save i7 because longjmp may not restore it */ 327 /* we also save i7 because longjmp may not restore it */
328 asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); 328 asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
329 #endif 329 #endif
@@ -447,7 +447,7 @@ int cpu_exec(CPUState *env1) @@ -447,7 +447,7 @@ int cpu_exec(CPUState *env1)
447 447
448 T0 = 0; /* force lookup of first TB */ 448 T0 = 0; /* force lookup of first TB */
449 for(;;) { 449 for(;;) {
450 -#ifdef __sparc__ 450 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
451 /* g1 can be modified by some libc? functions */ 451 /* g1 can be modified by some libc? functions */
452 tmp_T0 = T0; 452 tmp_T0 = T0;
453 #endif 453 #endif
@@ -467,7 +467,7 @@ int cpu_exec(CPUState *env1) @@ -467,7 +467,7 @@ int cpu_exec(CPUState *env1)
467 do_interrupt(intno, 0, 0, 0, 1); 467 do_interrupt(intno, 0, 0, 0, 1);
468 /* ensure that no TB jump will be modified as 468 /* ensure that no TB jump will be modified as
469 the program flow was changed */ 469 the program flow was changed */
470 -#ifdef __sparc__ 470 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
471 tmp_T0 = 0; 471 tmp_T0 = 0;
472 #else 472 #else
473 T0 = 0; 473 T0 = 0;
@@ -486,7 +486,7 @@ int cpu_exec(CPUState *env1) @@ -486,7 +486,7 @@ int cpu_exec(CPUState *env1)
486 env->error_code = 0; 486 env->error_code = 0;
487 do_interrupt(env); 487 do_interrupt(env);
488 env->interrupt_request &= ~CPU_INTERRUPT_HARD; 488 env->interrupt_request &= ~CPU_INTERRUPT_HARD;
489 -#ifdef __sparc__ 489 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
490 tmp_T0 = 0; 490 tmp_T0 = 0;
491 #else 491 #else
492 T0 = 0; 492 T0 = 0;
@@ -497,7 +497,7 @@ int cpu_exec(CPUState *env1) @@ -497,7 +497,7 @@ int cpu_exec(CPUState *env1)
497 env->error_code = 0; 497 env->error_code = 0;
498 do_interrupt(env); 498 do_interrupt(env);
499 env->interrupt_request &= ~CPU_INTERRUPT_TIMER; 499 env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
500 -#ifdef __sparc__ 500 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
501 tmp_T0 = 0; 501 tmp_T0 = 0;
502 #else 502 #else
503 T0 = 0; 503 T0 = 0;
@@ -516,7 +516,7 @@ int cpu_exec(CPUState *env1) @@ -516,7 +516,7 @@ int cpu_exec(CPUState *env1)
516 env->error_code = 0; 516 env->error_code = 0;
517 do_interrupt(env); 517 do_interrupt(env);
518 env->interrupt_request &= ~CPU_INTERRUPT_HARD; 518 env->interrupt_request &= ~CPU_INTERRUPT_HARD;
519 -#ifdef __sparc__ 519 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
520 tmp_T0 = 0; 520 tmp_T0 = 0;
521 #else 521 #else
522 T0 = 0; 522 T0 = 0;
@@ -534,7 +534,7 @@ int cpu_exec(CPUState *env1) @@ -534,7 +534,7 @@ int cpu_exec(CPUState *env1)
534 env->interrupt_request &= ~CPU_INTERRUPT_HARD; 534 env->interrupt_request &= ~CPU_INTERRUPT_HARD;
535 do_interrupt(env->interrupt_index); 535 do_interrupt(env->interrupt_index);
536 env->interrupt_index = 0; 536 env->interrupt_index = 0;
537 -#ifdef __sparc__ 537 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
538 tmp_T0 = 0; 538 tmp_T0 = 0;
539 #else 539 #else
540 T0 = 0; 540 T0 = 0;
@@ -567,7 +567,7 @@ int cpu_exec(CPUState *env1) @@ -567,7 +567,7 @@ int cpu_exec(CPUState *env1)
567 env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; 567 env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
568 /* ensure that no TB jump will be modified as 568 /* ensure that no TB jump will be modified as
569 the program flow was changed */ 569 the program flow was changed */
570 -#ifdef __sparc__ 570 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
571 tmp_T0 = 0; 571 tmp_T0 = 0;
572 #else 572 #else
573 T0 = 0; 573 T0 = 0;
@@ -635,7 +635,7 @@ int cpu_exec(CPUState *env1) @@ -635,7 +635,7 @@ int cpu_exec(CPUState *env1)
635 lookup_symbol(tb->pc)); 635 lookup_symbol(tb->pc));
636 } 636 }
637 #endif 637 #endif
638 -#ifdef __sparc__ 638 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
639 T0 = tmp_T0; 639 T0 = tmp_T0;
640 #endif 640 #endif
641 /* see if we can patch the calling TB. When the TB 641 /* see if we can patch the calling TB. When the TB
@@ -671,7 +671,9 @@ int cpu_exec(CPUState *env1) @@ -671,7 +671,9 @@ int cpu_exec(CPUState *env1)
671 "mov %%o7,%%i0" 671 "mov %%o7,%%i0"
672 : /* no outputs */ 672 : /* no outputs */
673 : "r" (gen_func) 673 : "r" (gen_func)
674 - : "i0", "i1", "i2", "i3", "i4", "i5"); 674 + : "i0", "i1", "i2", "i3", "i4", "i5",
  675 + "l0", "l1", "l2", "l3", "l4", "l5",
  676 + "l6", "l7");
675 #elif defined(__arm__) 677 #elif defined(__arm__)
676 asm volatile ("mov pc, %0\n\t" 678 asm volatile ("mov pc, %0\n\t"
677 ".global exec_loop\n\t" 679 ".global exec_loop\n\t"
@@ -836,7 +838,7 @@ int cpu_exec(CPUState *env1) @@ -836,7 +838,7 @@ int cpu_exec(CPUState *env1)
836 #else 838 #else
837 #error unsupported target CPU 839 #error unsupported target CPU
838 #endif 840 #endif
839 -#ifdef __sparc__ 841 +#if defined(__sparc__) && !defined(HOST_SOLARIS)
840 asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); 842 asm volatile ("mov %0, %%i7" : : "r" (saved_i7));
841 #endif 843 #endif
842 T0 = saved_T0; 844 T0 = saved_T0;
dyngen-exec.h
@@ -121,6 +121,13 @@ extern int printf(const char *, ...); @@ -121,6 +121,13 @@ extern int printf(const char *, ...);
121 #define AREG3 "s2" 121 #define AREG3 "s2"
122 #endif 122 #endif
123 #ifdef __sparc__ 123 #ifdef __sparc__
  124 +#ifdef HOST_SOLARIS
  125 +#define AREG0 "g2"
  126 +#define AREG1 "g3"
  127 +#define AREG2 "g4"
  128 +#define AREG3 "g5"
  129 +#define AREG4 "g6"
  130 +#else
124 #define AREG0 "g6" 131 #define AREG0 "g6"
125 #define AREG1 "g1" 132 #define AREG1 "g1"
126 #define AREG2 "g2" 133 #define AREG2 "g2"
@@ -133,6 +140,7 @@ extern int printf(const char *, ...); @@ -133,6 +140,7 @@ extern int printf(const char *, ...);
133 #define AREG9 "l5" 140 #define AREG9 "l5"
134 #define AREG10 "l6" 141 #define AREG10 "l6"
135 #define AREG11 "l7" 142 #define AREG11 "l7"
  143 +#endif
136 #define USE_FP_CONVERT 144 #define USE_FP_CONVERT
137 #endif 145 #endif
138 #ifdef __s390__ 146 #ifdef __s390__
@@ -241,10 +249,8 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; @@ -241,10 +249,8 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
241 ASM_NAME(__op_gen_label) #n) 249 ASM_NAME(__op_gen_label) #n)
242 #endif 250 #endif
243 #ifdef __sparc__ 251 #ifdef __sparc__
244 -#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0\n" \  
245 - "nop")  
246 -#define GOTO_LABEL_PARAM(n) asm volatile ( \  
247 - "set " ASM_NAME(__op_gen_label) #n ", %g1; jmp %g1; nop") 252 +#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0; nop")
  253 +#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n ";nop")
248 #endif 254 #endif
249 #ifdef __arm__ 255 #ifdef __arm__
250 #define EXIT_TB() asm volatile ("b exec_loop") 256 #define EXIT_TB() asm volatile ("b exec_loop")
dyngen.c
@@ -1440,6 +1440,12 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1440,6 +1440,12 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1440 } 1440 }
1441 #elif defined(HOST_SPARC) 1441 #elif defined(HOST_SPARC)
1442 { 1442 {
  1443 +#define INSN_SAVE 0x9de3a000
  1444 +#define INSN_RET 0x81c7e008
  1445 +#define INSN_RESTORE 0x81e80000
  1446 +#define INSN_RETURN 0x81cfe008
  1447 +#define INSN_NOP 0x01000000
  1448 +
1443 uint32_t start_insn, end_insn1, end_insn2; 1449 uint32_t start_insn, end_insn1, end_insn2;
1444 uint8_t *p; 1450 uint8_t *p;
1445 p = (void *)(p_end - 8); 1451 p = (void *)(p_end - 8);
@@ -1448,12 +1454,17 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1448,12 +1454,17 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1448 start_insn = get32((uint32_t *)(p_start + 0x0)); 1454 start_insn = get32((uint32_t *)(p_start + 0x0));
1449 end_insn1 = get32((uint32_t *)(p + 0x0)); 1455 end_insn1 = get32((uint32_t *)(p + 0x0));
1450 end_insn2 = get32((uint32_t *)(p + 0x4)); 1456 end_insn2 = get32((uint32_t *)(p + 0x4));
1451 - if ((start_insn & ~0x1fff) == 0x9de3a000) { 1457 + if ((start_insn & ~0x1fff) == INSN_SAVE) {
1452 p_start += 0x4; 1458 p_start += 0x4;
1453 start_offset += 0x4; 1459 start_offset += 0x4;
1454 if ((int)(start_insn | ~0x1fff) < -128) 1460 if ((int)(start_insn | ~0x1fff) < -128)
1455 error("Found bogus save at the start of %s", name); 1461 error("Found bogus save at the start of %s", name);
1456 - if (end_insn1 != 0x81c7e008 || end_insn2 != 0x81e80000) 1462 + if (end_insn1 == INSN_RET && end_insn2 == INSN_RESTORE)
  1463 + /* SPARC v7: ret; restore; */ ;
  1464 + else if (end_insn1 == INSN_RETURN && end_insn2 == INSN_NOP)
  1465 + /* SPARC v9: return; nop; */ ;
  1466 + else
  1467 +
1457 error("ret; restore; not found at end of %s", name); 1468 error("ret; restore; not found at end of %s", name);
1458 } else { 1469 } else {
1459 error("No save at the beginning of %s", name); 1470 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, @@ -1462,7 +1473,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1462 /* Skip a preceeding nop, if present. */ 1473 /* Skip a preceeding nop, if present. */
1463 if (p > p_start) { 1474 if (p > p_start) {
1464 skip_insn = get32((uint32_t *)(p - 0x4)); 1475 skip_insn = get32((uint32_t *)(p - 0x4));
1465 - if (skip_insn == 0x01000000) 1476 + if (skip_insn == INSN_NOP)
1466 p -= 4; 1477 p -= 4;
1467 } 1478 }
1468 #endif 1479 #endif
@@ -2151,6 +2162,18 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -2151,6 +2162,18 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
2151 reloc_offset, reloc_offset, name, addend, 2162 reloc_offset, reloc_offset, name, addend,
2152 reloc_offset); 2163 reloc_offset);
2153 break; 2164 break;
  2165 + case R_SPARC_WDISP22:
  2166 + fprintf(outfile,
  2167 + " *(uint32_t *)(gen_code_ptr + %d) = "
  2168 + "((*(uint32_t *)(gen_code_ptr + %d)) "
  2169 + " & ~0x3fffff) "
  2170 + " | ((((%s + %d) - (long)(gen_code_ptr + %d))>>2) "
  2171 + " & 0x3fffff);\n",
  2172 + rel->r_offset - start_offset,
  2173 + rel->r_offset - start_offset,
  2174 + name, addend,
  2175 + rel->r_offset - start_offset);
  2176 + break;
2154 default: 2177 default:
2155 error("unsupported sparc relocation (%d)", type); 2178 error("unsupported sparc relocation (%d)", type);
2156 } 2179 }
dyngen.h
@@ -19,7 +19,13 @@ @@ -19,7 +19,13 @@
19 */ 19 */
20 20
21 int __op_param1, __op_param2, __op_param3; 21 int __op_param1, __op_param2, __op_param3;
22 -int __op_gen_label1, __op_gen_label2, __op_gen_label3; 22 +#ifdef __sparc__
  23 + void __op_gen_label1(){}
  24 + void __op_gen_label2(){}
  25 + void __op_gen_label3(){}
  26 +#else
  27 + int __op_gen_label1, __op_gen_label2, __op_gen_label3;
  28 +#endif
23 int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; 29 int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
24 30
25 #ifdef __i386__ 31 #ifdef __i386__
fpu/softfloat-native.c
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 void set_float_rounding_mode(int val STATUS_PARAM) 6 void set_float_rounding_mode(int val STATUS_PARAM)
7 { 7 {
8 STATUS(float_rounding_mode) = val; 8 STATUS(float_rounding_mode) = val;
9 -#if defined(_BSD) && !defined(__APPLE__) 9 +#if defined(_BSD) && !defined(__APPLE__) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
10 fpsetround(val); 10 fpsetround(val);
11 #elif defined(__arm__) 11 #elif defined(__arm__)
12 /* nothing to do */ 12 /* nothing to do */
@@ -22,9 +22,14 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM) @@ -22,9 +22,14 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM)
22 } 22 }
23 #endif 23 #endif
24 24
25 -#if defined(_BSD)  
26 -#define lrint(d) ((long)rint(d))  
27 -#define llrint(d) ((long long)rint(d)) 25 +#if defined(_BSD) || (defined(HOST_SOLARIS) && HOST_SOLARIS < 10)
  26 +#define lrint(d) ((int32_t)rint(d))
  27 +#define llrint(d) ((int64_t)rint(d))
  28 +#define lrintf(f) ((int32_t)rint(f))
  29 +#define llrintf(f) ((int64_t)rint(f))
  30 +#define sqrtf(f) ((float)sqrt(f))
  31 +#define remainderf(fa, fb) ((float)remainder(fa, fb))
  32 +#define rintf(f) ((float)rint(f))
28 #endif 33 #endif
29 34
30 #if defined(__powerpc__) 35 #if defined(__powerpc__)
target-mips/cpu.h
@@ -8,6 +8,13 @@ @@ -8,6 +8,13 @@
8 #include "cpu-defs.h" 8 #include "cpu-defs.h"
9 #include "softfloat.h" 9 #include "softfloat.h"
10 10
  11 +// uint_fast8_t and uint_fast16_t not in <sys/int_types.h>
  12 +// XXX: move that elsewhere
  13 +#if defined(HOST_SOLARIS) && SOLARISREV < 10
  14 +typedef unsigned char uint_fast8_t;
  15 +typedef unsigned int uint_fast16_t;
  16 +#endif
  17 +
11 typedef union fpr_t fpr_t; 18 typedef union fpr_t fpr_t;
12 union fpr_t { 19 union fpr_t {
13 float64 fd; /* ieee double precision */ 20 float64 fd; /* ieee double precision */
@@ -563,6 +563,28 @@ int64_t cpu_get_real_ticks(void) @@ -563,6 +563,28 @@ int64_t cpu_get_real_ticks(void)
563 return val; 563 return val;
564 } 564 }
565 565
  566 +#elif defined(__sparc__) && defined(HOST_SOLARIS)
  567 +
  568 +uint64_t cpu_get_real_ticks (void)
  569 +{
  570 +#if defined(_LP64)
  571 + uint64_t rval;
  572 + asm volatile("rd %%tick,%0" : "=r"(rval));
  573 + return rval;
  574 +#else
  575 + union {
  576 + uint64_t i64;
  577 + struct {
  578 + uint32_t high;
  579 + uint32_t low;
  580 + } i32;
  581 + } rval;
  582 + asm volatile("rd %%tick,%1; srlx %1,32,%0"
  583 + : "=r"(rval.i32.high), "=r"(rval.i32.low));
  584 + return rval.i64;
  585 +#endif
  586 +}
  587 +
566 #else 588 #else
567 #error unsupported CPU 589 #error unsupported CPU
568 #endif 590 #endif