Commit fdbb46910a2033bd748681346d4261725f5e184b
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
Showing
9 changed files
with
104 additions
and
24 deletions
Makefile
... | ... | @@ -9,6 +9,9 @@ CFLAGS=-Wall -O2 -g -fno-strict-aliasing -I. |
9 | 9 | ifdef CONFIG_DARWIN |
10 | 10 | CFLAGS+= -mdynamic-no-pic |
11 | 11 | endif |
12 | +ifeq ($(ARCH),sparc) | |
13 | +CFLAGS+=-mcpu=ultrasparc | |
14 | +endif | |
12 | 15 | LDFLAGS=-g |
13 | 16 | LIBS= |
14 | 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 | 102 | endif |
103 | 103 | |
104 | 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 | 110 | CFLAGS+=-m32 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6 |
106 | 111 | LDFLAGS+=-m32 |
107 | 112 | OP_CFLAGS=$(CFLAGS) -fno-delayed-branch -ffixed-i0 |
... | ... | @@ -109,6 +114,7 @@ HELPER_CFLAGS=$(CFLAGS) -ffixed-i0 -mflat |
109 | 114 | # -static is used to avoid g1/g3 usage by the dynamic linker |
110 | 115 | LDFLAGS+=-Wl,-T,$(SRC_PATH)/sparc.ld -static |
111 | 116 | endif |
117 | +endif | |
112 | 118 | |
113 | 119 | ifeq ($(ARCH),sparc64) |
114 | 120 | CFLAGS+=-m64 -ffixed-g1 -ffixed-g2 -ffixed-g3 -ffixed-g6 | ... | ... |
cpu-exec.c
... | ... | @@ -253,7 +253,7 @@ int cpu_exec(CPUState *env1) |
253 | 253 | uint32_t *saved_regwptr; |
254 | 254 | #endif |
255 | 255 | #endif |
256 | -#ifdef __sparc__ | |
256 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
257 | 257 | int saved_i7, tmp_T0; |
258 | 258 | #endif |
259 | 259 | int ret, interrupt_request; |
... | ... | @@ -323,7 +323,7 @@ int cpu_exec(CPUState *env1) |
323 | 323 | #if defined(reg_T2) |
324 | 324 | saved_T2 = T2; |
325 | 325 | #endif |
326 | -#ifdef __sparc__ | |
326 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
327 | 327 | /* we also save i7 because longjmp may not restore it */ |
328 | 328 | asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); |
329 | 329 | #endif |
... | ... | @@ -447,7 +447,7 @@ int cpu_exec(CPUState *env1) |
447 | 447 | |
448 | 448 | T0 = 0; /* force lookup of first TB */ |
449 | 449 | for(;;) { |
450 | -#ifdef __sparc__ | |
450 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
451 | 451 | /* g1 can be modified by some libc? functions */ |
452 | 452 | tmp_T0 = T0; |
453 | 453 | #endif |
... | ... | @@ -467,7 +467,7 @@ int cpu_exec(CPUState *env1) |
467 | 467 | do_interrupt(intno, 0, 0, 0, 1); |
468 | 468 | /* ensure that no TB jump will be modified as |
469 | 469 | the program flow was changed */ |
470 | -#ifdef __sparc__ | |
470 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
471 | 471 | tmp_T0 = 0; |
472 | 472 | #else |
473 | 473 | T0 = 0; |
... | ... | @@ -486,7 +486,7 @@ int cpu_exec(CPUState *env1) |
486 | 486 | env->error_code = 0; |
487 | 487 | do_interrupt(env); |
488 | 488 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
489 | -#ifdef __sparc__ | |
489 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
490 | 490 | tmp_T0 = 0; |
491 | 491 | #else |
492 | 492 | T0 = 0; |
... | ... | @@ -497,7 +497,7 @@ int cpu_exec(CPUState *env1) |
497 | 497 | env->error_code = 0; |
498 | 498 | do_interrupt(env); |
499 | 499 | env->interrupt_request &= ~CPU_INTERRUPT_TIMER; |
500 | -#ifdef __sparc__ | |
500 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
501 | 501 | tmp_T0 = 0; |
502 | 502 | #else |
503 | 503 | T0 = 0; |
... | ... | @@ -516,7 +516,7 @@ int cpu_exec(CPUState *env1) |
516 | 516 | env->error_code = 0; |
517 | 517 | do_interrupt(env); |
518 | 518 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
519 | -#ifdef __sparc__ | |
519 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
520 | 520 | tmp_T0 = 0; |
521 | 521 | #else |
522 | 522 | T0 = 0; |
... | ... | @@ -534,7 +534,7 @@ int cpu_exec(CPUState *env1) |
534 | 534 | env->interrupt_request &= ~CPU_INTERRUPT_HARD; |
535 | 535 | do_interrupt(env->interrupt_index); |
536 | 536 | env->interrupt_index = 0; |
537 | -#ifdef __sparc__ | |
537 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
538 | 538 | tmp_T0 = 0; |
539 | 539 | #else |
540 | 540 | T0 = 0; |
... | ... | @@ -567,7 +567,7 @@ int cpu_exec(CPUState *env1) |
567 | 567 | env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; |
568 | 568 | /* ensure that no TB jump will be modified as |
569 | 569 | the program flow was changed */ |
570 | -#ifdef __sparc__ | |
570 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
571 | 571 | tmp_T0 = 0; |
572 | 572 | #else |
573 | 573 | T0 = 0; |
... | ... | @@ -635,7 +635,7 @@ int cpu_exec(CPUState *env1) |
635 | 635 | lookup_symbol(tb->pc)); |
636 | 636 | } |
637 | 637 | #endif |
638 | -#ifdef __sparc__ | |
638 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
639 | 639 | T0 = tmp_T0; |
640 | 640 | #endif |
641 | 641 | /* see if we can patch the calling TB. When the TB |
... | ... | @@ -671,7 +671,9 @@ int cpu_exec(CPUState *env1) |
671 | 671 | "mov %%o7,%%i0" |
672 | 672 | : /* no outputs */ |
673 | 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 | 677 | #elif defined(__arm__) |
676 | 678 | asm volatile ("mov pc, %0\n\t" |
677 | 679 | ".global exec_loop\n\t" |
... | ... | @@ -836,7 +838,7 @@ int cpu_exec(CPUState *env1) |
836 | 838 | #else |
837 | 839 | #error unsupported target CPU |
838 | 840 | #endif |
839 | -#ifdef __sparc__ | |
841 | +#if defined(__sparc__) && !defined(HOST_SOLARIS) | |
840 | 842 | asm volatile ("mov %0, %%i7" : : "r" (saved_i7)); |
841 | 843 | #endif |
842 | 844 | T0 = saved_T0; | ... | ... |
dyngen-exec.h
... | ... | @@ -121,6 +121,13 @@ extern int printf(const char *, ...); |
121 | 121 | #define AREG3 "s2" |
122 | 122 | #endif |
123 | 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 | 131 | #define AREG0 "g6" |
125 | 132 | #define AREG1 "g1" |
126 | 133 | #define AREG2 "g2" |
... | ... | @@ -133,6 +140,7 @@ extern int printf(const char *, ...); |
133 | 140 | #define AREG9 "l5" |
134 | 141 | #define AREG10 "l6" |
135 | 142 | #define AREG11 "l7" |
143 | +#endif | |
136 | 144 | #define USE_FP_CONVERT |
137 | 145 | #endif |
138 | 146 | #ifdef __s390__ |
... | ... | @@ -241,10 +249,8 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; |
241 | 249 | ASM_NAME(__op_gen_label) #n) |
242 | 250 | #endif |
243 | 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 | 254 | #endif |
249 | 255 | #ifdef __arm__ |
250 | 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 | 1440 | } |
1441 | 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 | 1449 | uint32_t start_insn, end_insn1, end_insn2; |
1444 | 1450 | uint8_t *p; |
1445 | 1451 | p = (void *)(p_end - 8); |
... | ... | @@ -1448,12 +1454,17 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
1448 | 1454 | start_insn = get32((uint32_t *)(p_start + 0x0)); |
1449 | 1455 | end_insn1 = get32((uint32_t *)(p + 0x0)); |
1450 | 1456 | end_insn2 = get32((uint32_t *)(p + 0x4)); |
1451 | - if ((start_insn & ~0x1fff) == 0x9de3a000) { | |
1457 | + if ((start_insn & ~0x1fff) == INSN_SAVE) { | |
1452 | 1458 | p_start += 0x4; |
1453 | 1459 | start_offset += 0x4; |
1454 | 1460 | if ((int)(start_insn | ~0x1fff) < -128) |
1455 | 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 | 1468 | error("ret; restore; not found at end of %s", name); |
1458 | 1469 | } else { |
1459 | 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 | 1473 | /* Skip a preceeding nop, if present. */ |
1463 | 1474 | if (p > p_start) { |
1464 | 1475 | skip_insn = get32((uint32_t *)(p - 0x4)); |
1465 | - if (skip_insn == 0x01000000) | |
1476 | + if (skip_insn == INSN_NOP) | |
1466 | 1477 | p -= 4; |
1467 | 1478 | } |
1468 | 1479 | #endif |
... | ... | @@ -2151,6 +2162,18 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
2151 | 2162 | reloc_offset, reloc_offset, name, addend, |
2152 | 2163 | reloc_offset); |
2153 | 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 | 2177 | default: |
2155 | 2178 | error("unsupported sparc relocation (%d)", type); |
2156 | 2179 | } | ... | ... |
dyngen.h
... | ... | @@ -19,7 +19,13 @@ |
19 | 19 | */ |
20 | 20 | |
21 | 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 | 29 | int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; |
24 | 30 | |
25 | 31 | #ifdef __i386__ | ... | ... |
fpu/softfloat-native.c
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | void set_float_rounding_mode(int val STATUS_PARAM) |
7 | 7 | { |
8 | 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 | 10 | fpsetround(val); |
11 | 11 | #elif defined(__arm__) |
12 | 12 | /* nothing to do */ |
... | ... | @@ -22,9 +22,14 @@ void set_floatx80_rounding_precision(int val STATUS_PARAM) |
22 | 22 | } |
23 | 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 | 33 | #endif |
29 | 34 | |
30 | 35 | #if defined(__powerpc__) | ... | ... |
target-mips/cpu.h
... | ... | @@ -8,6 +8,13 @@ |
8 | 8 | #include "cpu-defs.h" |
9 | 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 | 18 | typedef union fpr_t fpr_t; |
12 | 19 | union fpr_t { |
13 | 20 | float64 fd; /* ieee double precision */ | ... | ... |
vl.c
... | ... | @@ -563,6 +563,28 @@ int64_t cpu_get_real_ticks(void) |
563 | 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 | 588 | #else |
567 | 589 | #error unsupported CPU |
568 | 590 | #endif | ... | ... |