Commit 04cbbdee authored by Blue Swirl's avatar Blue Swirl
Browse files

Merge branch 'tcg-sparc' of git://repo.or.cz/qemu/rth

* 'tcg-sparc' of git://repo.or.cz/qemu/rth:
  tcg-sparc: Preserve branch destinations during retranslation
  tcg-sparc: Fix and enable direct TB chaining.
  tcg-sparc: Add %g/%o registers to alloc_order
  tcg-sparc: Use defines for temporaries.
  tcg-sparc: Mask shift immediates to avoid illegal insns.
  tcg-sparc: Clean up cruft stemming from attempts to use global registers.
  tcg-sparc: Change AREG0 in generated code to %i0.
  tcg-sparc: Support GUEST_BASE.
  tcg-sparc: Fix qemu_ld/st to handle 32-bit host.
  tcg-sparc: Assume v9 cpu always, i.e. force v8plus in 32-bit mode.
  tcg-sparc: Don't MAP_FIXED on top of the program
  tcg-sparc: Fix ADDX opcode.
  tcg-sparc: Hack in qemu_ld/st64 for 32-bit.
  linux-user: Use memcpy in get_user/put_user.
parents ef04a846 f4bf0b91
Loading
Loading
Loading
Loading
+5 −47
Original line number Diff line number Diff line
@@ -111,7 +111,6 @@ source_path=`dirname "$0"`
cpu=""
interp_prefix="/usr/gnemul/qemu-%M"
static="no"
sparc_cpu=""
cross_prefix=""
audio_drv_list=""
audio_card_list="ac97 es1370 sb16 hda"
@@ -241,21 +240,6 @@ for opt do
  ;;
  --disable-debug-info) debug_info="no"
  ;;
  --sparc_cpu=*)
    sparc_cpu="$optarg"
    case $sparc_cpu in
    v7|v8|v8plus|v8plusa)
      cpu="sparc"
    ;;
    v9)
      cpu="sparc64"
    ;;
    *)
      echo "undefined SPARC architecture. Exiting";
      exit 1
    ;;
    esac
  ;;
  esac
done
# OS specific
@@ -343,8 +327,6 @@ elif check_define __i386__ ; then
elif check_define __x86_64__ ; then
  cpu="x86_64"
elif check_define __sparc__ ; then
  # We can't check for 64 bit (when gcc is biarch) or V8PLUSA
  # They must be specified using --sparc_cpu
  if check_define __arch64__ ; then
    cpu="sparc64"
  else
@@ -792,8 +774,6 @@ for opt do
  ;;
  --enable-uname-release=*) uname_release="$optarg"
  ;;
  --sparc_cpu=*)
  ;;
  --enable-werror) werror="yes"
  ;;
  --disable-werror) werror="no"
@@ -881,35 +861,17 @@ for opt do
  esac
done

#
# If cpu ~= sparc and  sparc_cpu hasn't been defined, plug in the right
# QEMU_CFLAGS/LDFLAGS (assume sparc_v8plus for 32-bit and sparc_v9 for 64-bit)
#
host_guest_base="no"
case "$cpu" in
    sparc) case $sparc_cpu in
           v7|v8)
             QEMU_CFLAGS="-mcpu=${sparc_cpu} -D__sparc_${sparc_cpu}__ $QEMU_CFLAGS"
           ;;
           v8plus|v8plusa)
             QEMU_CFLAGS="-mcpu=ultrasparc -D__sparc_${sparc_cpu}__ $QEMU_CFLAGS"
           ;;
           *) # sparc_cpu not defined in the command line
             QEMU_CFLAGS="-mcpu=ultrasparc -D__sparc_v8plus__ $QEMU_CFLAGS"
           esac
    sparc)
           LDFLAGS="-m32 $LDFLAGS"
           QEMU_CFLAGS="-m32 -ffixed-g2 -ffixed-g3 $QEMU_CFLAGS"
           if test "$solaris" = "no" ; then
             QEMU_CFLAGS="-ffixed-g1 -ffixed-g6 $QEMU_CFLAGS"
           fi
           QEMU_CFLAGS="-m32 -mcpu=ultrasparc $QEMU_CFLAGS"
           host_guest_base="yes"
           ;;
    sparc64)
           QEMU_CFLAGS="-m64 -mcpu=ultrasparc -D__sparc_v9__ $QEMU_CFLAGS"
           LDFLAGS="-m64 $LDFLAGS"
           QEMU_CFLAGS="-ffixed-g5 -ffixed-g6 -ffixed-g7 $QEMU_CFLAGS"
           if test "$solaris" != "no" ; then
             QEMU_CFLAGS="-ffixed-g1 $QEMU_CFLAGS"
           fi
           QEMU_CFLAGS="-m64 -mcpu=ultrasparc $QEMU_CFLAGS"
           host_guest_base="yes"
           ;;
    s390)
           QEMU_CFLAGS="-m31 -march=z990 $QEMU_CFLAGS"
@@ -4131,10 +4093,6 @@ fi

if test "$target_linux_user" = "yes" -o "$target_bsd_user" = "yes" ; then
  case "$ARCH" in
  sparc)
    # -static is used to avoid g1/g3 usage by the dynamic linker
    ldflags="$linker_script -static $ldflags"
    ;;
  alpha | s390x)
    # The default placement of the application is fine.
    ;;
+0 −2
Original line number Diff line number Diff line
@@ -316,9 +316,7 @@ void disas(FILE *out, void *code, unsigned long size)
    print_insn = print_insn_alpha;
#elif defined(__sparc__)
    print_insn = print_insn_sparc;
#if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__)
    disasm_info.mach = bfd_mach_sparc_v9b;
#endif
#elif defined(__arm__)
    print_insn = print_insn_arm;
#elif defined(__MIPSEB__)
+6 −3
Original line number Diff line number Diff line
@@ -132,9 +132,10 @@ static inline void tlb_flush(CPUArchState *env, int flush_global)
#define CODE_GEN_AVG_BLOCK_SIZE 64
#endif

#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__)
#define USE_DIRECT_JUMP
#elif defined(CONFIG_TCG_INTERPRETER)
#if defined(__arm__) || defined(_ARCH_PPC) \
    || defined(__x86_64__) || defined(__i386__) \
    || defined(__sparc__) \
    || defined(CONFIG_TCG_INTERPRETER)
#define USE_DIRECT_JUMP
#endif

@@ -244,6 +245,8 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
#endif
}
#elif defined(__sparc__)
void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
#else
#error tb_set_jmp_target1 is missing
#endif
+5 −7
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ static int nb_tbs;
/* any access to the tbs or the page table must use this lock */
spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;

#if defined(__arm__) || defined(__sparc_v9__)
#if defined(__arm__) || defined(__sparc__)
/* The prologue must be reachable with a direct jump. ARM and Sparc64
 have limited branch ranges (possibly also PPC) so place it in a
 section close to code segment. */
@@ -541,10 +541,9 @@ static void code_gen_alloc(unsigned long tb_size)
        /* Cannot map more than that */
        if (code_gen_buffer_size > (800 * 1024 * 1024))
            code_gen_buffer_size = (800 * 1024 * 1024);
#elif defined(__sparc_v9__)
#elif defined(__sparc__) && HOST_LONG_BITS == 64
        // Map the buffer below 2G, so we can use direct calls and branches
        flags |= MAP_FIXED;
        start = (void *) 0x60000000UL;
        start = (void *) 0x40000000UL;
        if (code_gen_buffer_size > (512 * 1024 * 1024))
            code_gen_buffer_size = (512 * 1024 * 1024);
#elif defined(__arm__)
@@ -582,10 +581,9 @@ static void code_gen_alloc(unsigned long tb_size)
        /* Cannot map more than that */
        if (code_gen_buffer_size > (800 * 1024 * 1024))
            code_gen_buffer_size = (800 * 1024 * 1024);
#elif defined(__sparc_v9__)
#elif defined(__sparc__) && HOST_LONG_BITS == 64
        // Map the buffer below 2G, so we can use direct calls and branches
        flags |= MAP_FIXED;
        addr = (void *) 0x60000000UL;
        addr = (void *) 0x40000000UL;
        if (code_gen_buffer_size > (512 * 1024 * 1024)) {
            code_gen_buffer_size = (512 * 1024 * 1024);
        }
+15 −32
Original line number Diff line number Diff line
@@ -289,46 +289,29 @@ static inline int access_ok(int type, abi_ulong addr, abi_ulong size)
 * struct has been locked - usually with lock_user_struct().
 */
#define __put_user(x, hptr)\
({\
({ __typeof(*hptr) pu_ = (x);\
    switch(sizeof(*hptr)) {\
    case 1:\
        *(uint8_t *)(hptr) = (uint8_t)(typeof(*hptr))(x);\
        break;\
    case 2:\
        *(uint16_t *)(hptr) = tswap16((uint16_t)(typeof(*hptr))(x));\
        break;\
    case 4:\
        *(uint32_t *)(hptr) = tswap32((uint32_t)(typeof(*hptr))(x));\
        break;\
    case 8:\
        *(uint64_t *)(hptr) = tswap64((typeof(*hptr))(x));\
        break;\
    default:\
        abort();\
    case 1: break;\
    case 2: pu_ = tswap16(pu_); break; \
    case 4: pu_ = tswap32(pu_); break; \
    case 8: pu_ = tswap64(pu_); break; \
    default: abort();\
    }\
    memcpy(hptr, &pu_, sizeof(pu_)); \
    0;\
})

#define __get_user(x, hptr) \
({\
({ __typeof(*hptr) gu_; \
    memcpy(&gu_, hptr, sizeof(gu_)); \
    switch(sizeof(*hptr)) {\
    case 1:\
        x = (typeof(*hptr))*(uint8_t *)(hptr);\
        break;\
    case 2:\
        x = (typeof(*hptr))tswap16(*(uint16_t *)(hptr));\
        break;\
    case 4:\
        x = (typeof(*hptr))tswap32(*(uint32_t *)(hptr));\
        break;\
    case 8:\
        x = (typeof(*hptr))tswap64(*(uint64_t *)(hptr));\
        break;\
    default:\
        /* avoid warning */\
        x = 0;\
        abort();\
    case 1: break; \
    case 2: gu_ = tswap16(gu_); break; \
    case 4: gu_ = tswap32(gu_); break; \
    case 8: gu_ = tswap64(gu_); break; \
    default: abort();\
    }\
    (x) = gu_; \
    0;\
})

Loading