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 | ... | ... |