Merge remote-tracking branch 'remotes/rth/tcg-ppc-merge-1' into staging

* remotes/rth/tcg-ppc-merge-1: (25 commits)
  tcg-ppc: Use the return address as a base pointer
  tcg-ppc: Merge cache-utils into the backend
  qemu/osdep: Remove the need for qemu_init_auxval
  tcg-ppc: Rename the tcg/ppc64 backend
  tcg-ppc: Remove the backend
  tcg-ppc64: Merge ppc32 shifts
  tcg-ppc64: Support mulsh_i32
  tcg-ppc64: Merge ppc32 register usage
  tcg-ppc64: Merge ppc32 qemu_ld/st
  tcg-ppc64: Merge ppc32 brcond2, setcond2, muluh
  tcg-ppc64: Begin merging ppc32 with ppc64
  tcg-ppc64: Fix sub2 implementation
  tcg-ppc64: Merge 32-bit ABIs into the prologue / frame code
  tcg-ppc64: Adjust tcg_out_call for ELFv2
  tcg-ppc64: Support the ppc64 elfv2 ABI
  tcg-ppc64: Use the correct test in tcg_out_call
  tcg-ppc64: Better parameterize the stack frame
  tcg-ppc64: Fix TCG_TARGET_CALL_STACK_OFFSET
  tcg-ppc64: Move call macros out of tcg-target.h
  tcg-ppc64: Make TCG_AREG0 and TCG_REG_CALL_STACK enum constants
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-06-23 18:26:58 +01:00
commit 7ba48975d3
15 changed files with 2114 additions and 3768 deletions

2
configure vendored
View file

@ -4747,6 +4747,8 @@ elif test "$ARCH" = "s390x" ; then
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/s390 $QEMU_INCLUDES"
elif test "$ARCH" = "x86_64" -o "$ARCH" = "x32" ; then
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/i386 $QEMU_INCLUDES"
elif test "$ARCH" = "ppc64" ; then
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/ppc $QEMU_INCLUDES"
else
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/\$(ARCH) $QEMU_INCLUDES"
fi

1
exec.c
View file

@ -50,7 +50,6 @@
#include "exec/memory-internal.h"
#include "exec/ram_addr.h"
#include "qemu/cache-utils.h"
#include "qemu/range.h"

View file

@ -224,7 +224,7 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
/* no need to flush icache explicitly */
}
#elif defined(_ARCH_PPC)
void ppc_tb_set_jmp_target(unsigned long jmp_addr, unsigned long addr);
void ppc_tb_set_jmp_target(uintptr_t jmp_addr, uintptr_t addr);
#define tb_set_jmp_target1 ppc_tb_set_jmp_target
#elif defined(__i386__) || defined(__x86_64__)
static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)

View file

@ -1,44 +0,0 @@
#ifndef QEMU_CACHE_UTILS_H
#define QEMU_CACHE_UTILS_H
#if defined(_ARCH_PPC)
#include <stdint.h> /* uintptr_t */
struct qemu_cache_conf {
unsigned long dcache_bsize;
unsigned long icache_bsize;
};
extern struct qemu_cache_conf qemu_cache_conf;
void qemu_cache_utils_init(void);
/* mildly adjusted code from tcg-dyngen.c */
static inline void flush_icache_range(uintptr_t start, uintptr_t stop)
{
unsigned long p, start1, stop1;
unsigned long dsize = qemu_cache_conf.dcache_bsize;
unsigned long isize = qemu_cache_conf.icache_bsize;
start1 = start & ~(dsize - 1);
stop1 = (stop + dsize - 1) & ~(dsize - 1);
for (p = start1; p < stop1; p += dsize) {
asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
}
asm volatile ("sync" : : : "memory");
start &= start & ~(isize - 1);
stop1 = (stop + isize - 1) & ~(isize - 1);
for (p = start1; p < stop1; p += isize) {
asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
}
asm volatile ("sync" : : : "memory");
asm volatile ("isync" : : : "memory");
}
#else
#define qemu_cache_utils_init() do { } while (0)
#endif
#endif /* QEMU_CACHE_UTILS_H */

View file

@ -251,18 +251,6 @@ unsigned long qemu_getauxval(unsigned long type);
static inline unsigned long qemu_getauxval(unsigned long type) { return 0; }
#endif
/**
* qemu_init_auxval:
* @envp: the third argument to main
*
* If supported and required, locate the auxiliary vector at program startup.
*/
#if defined(CONFIG_GETAUXVAL) || !defined(__linux__)
static inline void qemu_init_auxval(char **envp) { }
#else
void qemu_init_auxval(char **envp);
#endif
void qemu_set_tty_echo(int fd, bool echo);
void os_mem_prealloc(int fd, char *area, size_t sz);

View file

@ -28,7 +28,6 @@
#include "qemu.h"
#include "qemu-common.h"
#include "qemu/cache-utils.h"
#include "cpu.h"
#include "tcg.h"
#include "qemu/timer.h"
@ -3829,9 +3828,6 @@ int main(int argc, char **argv, char **envp)
module_call_init(MODULE_INIT_QOM);
qemu_init_auxval(envp);
qemu_cache_utils_init();
if ((envlist = envlist_create()) == NULL) {
(void) fprintf(stderr, "Unable to allocate envlist\n");
exit(1);

File diff suppressed because it is too large Load diff

View file

@ -21,60 +21,35 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TCG_TARGET_PPC
#define TCG_TARGET_PPC 1
#ifndef TCG_TARGET_PPC64
#define TCG_TARGET_PPC64 1
#ifdef _ARCH_PPC64
# define TCG_TARGET_REG_BITS 64
#else
# define TCG_TARGET_REG_BITS 32
#endif
#define TCG_TARGET_NB_REGS 32
#define TCG_TARGET_INSN_UNIT_SIZE 4
typedef enum {
TCG_REG_R0 = 0,
TCG_REG_R1,
TCG_REG_R2,
TCG_REG_R3,
TCG_REG_R4,
TCG_REG_R5,
TCG_REG_R6,
TCG_REG_R7,
TCG_REG_R8,
TCG_REG_R9,
TCG_REG_R10,
TCG_REG_R11,
TCG_REG_R12,
TCG_REG_R13,
TCG_REG_R14,
TCG_REG_R15,
TCG_REG_R16,
TCG_REG_R17,
TCG_REG_R18,
TCG_REG_R19,
TCG_REG_R20,
TCG_REG_R21,
TCG_REG_R22,
TCG_REG_R23,
TCG_REG_R24,
TCG_REG_R25,
TCG_REG_R26,
TCG_REG_R27,
TCG_REG_R28,
TCG_REG_R29,
TCG_REG_R30,
TCG_REG_R31
TCG_REG_R0, TCG_REG_R1, TCG_REG_R2, TCG_REG_R3,
TCG_REG_R4, TCG_REG_R5, TCG_REG_R6, TCG_REG_R7,
TCG_REG_R8, TCG_REG_R9, TCG_REG_R10, TCG_REG_R11,
TCG_REG_R12, TCG_REG_R13, TCG_REG_R14, TCG_REG_R15,
TCG_REG_R16, TCG_REG_R17, TCG_REG_R18, TCG_REG_R19,
TCG_REG_R20, TCG_REG_R21, TCG_REG_R22, TCG_REG_R23,
TCG_REG_R24, TCG_REG_R25, TCG_REG_R26, TCG_REG_R27,
TCG_REG_R28, TCG_REG_R29, TCG_REG_R30, TCG_REG_R31,
TCG_REG_CALL_STACK = TCG_REG_R1,
TCG_AREG0 = TCG_REG_R27
} TCGReg;
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_R1
#define TCG_TARGET_STACK_ALIGN 16
#if defined _CALL_DARWIN || defined __APPLE__
#define TCG_TARGET_CALL_STACK_OFFSET 24
#elif defined _CALL_AIX
#define TCG_TARGET_CALL_STACK_OFFSET 52
#elif defined _CALL_SYSV
#define TCG_TARGET_CALL_ALIGN_ARGS 1
#define TCG_TARGET_CALL_STACK_OFFSET 8
#else
#error Unsupported system
#endif
/* optional instructions automatically implemented */
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi */
#define TCG_TARGET_HAS_ext16u_i32 0
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
@ -82,8 +57,6 @@ typedef enum {
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_ext8u_i32 1
#define TCG_TARGET_HAS_ext16u_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
@ -95,15 +68,44 @@ typedef enum {
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_movcond_i32 1
#define TCG_TARGET_HAS_mulu2_i32 1
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_muluh_i32 1
#define TCG_TARGET_HAS_mulsh_i32 1
#define TCG_AREG0 TCG_REG_R27
#if TCG_TARGET_REG_BITS == 64
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_ext8u_i64 0
#define TCG_TARGET_HAS_ext16u_i64 0
#define TCG_TARGET_HAS_ext32u_i64 0
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_neg_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_movcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#endif
#define tcg_qemu_tb_exec(env, tb_ptr) \
((uintptr_t __attribute__ ((longcall)) \
(*)(void *, void *))tcg_ctx.code_gen_prologue)(env, tb_ptr)
void flush_icache_range(uintptr_t start, uintptr_t stop);
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,131 +0,0 @@
/*
* Tiny Code Generator for QEMU
*
* Copyright (c) 2008 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef TCG_TARGET_PPC64
#define TCG_TARGET_PPC64 1
#define TCG_TARGET_NB_REGS 32
#define TCG_TARGET_INSN_UNIT_SIZE 4
typedef enum {
TCG_REG_R0 = 0,
TCG_REG_R1,
TCG_REG_R2,
TCG_REG_R3,
TCG_REG_R4,
TCG_REG_R5,
TCG_REG_R6,
TCG_REG_R7,
TCG_REG_R8,
TCG_REG_R9,
TCG_REG_R10,
TCG_REG_R11,
TCG_REG_R12,
TCG_REG_R13,
TCG_REG_R14,
TCG_REG_R15,
TCG_REG_R16,
TCG_REG_R17,
TCG_REG_R18,
TCG_REG_R19,
TCG_REG_R20,
TCG_REG_R21,
TCG_REG_R22,
TCG_REG_R23,
TCG_REG_R24,
TCG_REG_R25,
TCG_REG_R26,
TCG_REG_R27,
TCG_REG_R28,
TCG_REG_R29,
TCG_REG_R30,
TCG_REG_R31
} TCGReg;
/* used for function call generation */
#define TCG_REG_CALL_STACK TCG_REG_R1
#define TCG_TARGET_STACK_ALIGN 16
#define TCG_TARGET_CALL_STACK_OFFSET 48
/* optional instructions automatically implemented */
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi */
#define TCG_TARGET_HAS_ext16u_i32 0
#define TCG_TARGET_HAS_ext8u_i64 0
#define TCG_TARGET_HAS_ext16u_i64 0
#define TCG_TARGET_HAS_ext32u_i64 0
/* optional instructions */
#define TCG_TARGET_HAS_div_i32 1
#define TCG_TARGET_HAS_rem_i32 0
#define TCG_TARGET_HAS_rot_i32 1
#define TCG_TARGET_HAS_ext8s_i32 1
#define TCG_TARGET_HAS_ext16s_i32 1
#define TCG_TARGET_HAS_bswap16_i32 1
#define TCG_TARGET_HAS_bswap32_i32 1
#define TCG_TARGET_HAS_not_i32 1
#define TCG_TARGET_HAS_neg_i32 1
#define TCG_TARGET_HAS_andc_i32 1
#define TCG_TARGET_HAS_orc_i32 1
#define TCG_TARGET_HAS_eqv_i32 1
#define TCG_TARGET_HAS_nand_i32 1
#define TCG_TARGET_HAS_nor_i32 1
#define TCG_TARGET_HAS_deposit_i32 1
#define TCG_TARGET_HAS_movcond_i32 1
#define TCG_TARGET_HAS_add2_i32 0
#define TCG_TARGET_HAS_sub2_i32 0
#define TCG_TARGET_HAS_mulu2_i32 0
#define TCG_TARGET_HAS_muls2_i32 0
#define TCG_TARGET_HAS_muluh_i32 0
#define TCG_TARGET_HAS_mulsh_i32 0
#define TCG_TARGET_HAS_trunc_shr_i32 0
#define TCG_TARGET_HAS_div_i64 1
#define TCG_TARGET_HAS_rem_i64 0
#define TCG_TARGET_HAS_rot_i64 1
#define TCG_TARGET_HAS_ext8s_i64 1
#define TCG_TARGET_HAS_ext16s_i64 1
#define TCG_TARGET_HAS_ext32s_i64 1
#define TCG_TARGET_HAS_bswap16_i64 1
#define TCG_TARGET_HAS_bswap32_i64 1
#define TCG_TARGET_HAS_bswap64_i64 1
#define TCG_TARGET_HAS_not_i64 1
#define TCG_TARGET_HAS_neg_i64 1
#define TCG_TARGET_HAS_andc_i64 1
#define TCG_TARGET_HAS_orc_i64 1
#define TCG_TARGET_HAS_eqv_i64 1
#define TCG_TARGET_HAS_nand_i64 1
#define TCG_TARGET_HAS_nor_i64 1
#define TCG_TARGET_HAS_deposit_i64 1
#define TCG_TARGET_HAS_movcond_i64 1
#define TCG_TARGET_HAS_add2_i64 1
#define TCG_TARGET_HAS_sub2_i64 1
#define TCG_TARGET_HAS_mulu2_i64 0
#define TCG_TARGET_HAS_muls2_i64 0
#define TCG_TARGET_HAS_muluh_i64 1
#define TCG_TARGET_HAS_mulsh_i64 1
#define TCG_AREG0 TCG_REG_R27
#define TCG_TARGET_EXTEND_ARGS 1
#endif

View file

@ -37,7 +37,6 @@
#endif
#include "qemu-common.h"
#include "qemu/cache-utils.h"
#include "qemu/host-utils.h"
#include "qemu/timer.h"

View file

@ -1,7 +1,7 @@
util-obj-y = osdep.o cutils.o unicode.o qemu-timer-common.o
util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o event_notifier-win32.o
util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o event_notifier-posix.o qemu-openpty.o
util-obj-y += envlist.o path.o host-utils.o cache-utils.o module.o
util-obj-y += envlist.o path.o host-utils.o module.o
util-obj-y += bitmap.o bitops.o hbitmap.o
util-obj-y += fifo8.o
util-obj-y += acl.o

View file

@ -1,86 +0,0 @@
#include "qemu-common.h"
#include "qemu/cache-utils.h"
#if defined(_ARCH_PPC)
struct qemu_cache_conf qemu_cache_conf = {
.dcache_bsize = 16,
.icache_bsize = 16
};
#if defined _AIX
#include <sys/systemcfg.h>
void qemu_cache_utils_init(void)
{
qemu_cache_conf.icache_bsize = _system_configuration.icache_line;
qemu_cache_conf.dcache_bsize = _system_configuration.dcache_line;
}
#elif defined __linux__
#include "qemu/osdep.h"
#include "elf.h"
void qemu_cache_utils_init(void)
{
unsigned long dsize = qemu_getauxval(AT_DCACHEBSIZE);
unsigned long isize = qemu_getauxval(AT_ICACHEBSIZE);
if (dsize == 0 || isize == 0) {
if (dsize == 0) {
fprintf(stderr, "getauxval AT_DCACHEBSIZE failed\n");
}
if (isize == 0) {
fprintf(stderr, "getauxval AT_ICACHEBSIZE failed\n");
}
exit(1);
}
qemu_cache_conf.dcache_bsize = dsize;
qemu_cache_conf.icache_bsize = isize;
}
#elif defined __APPLE__
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
void qemu_cache_utils_init(void)
{
size_t len;
unsigned cacheline;
int name[2] = { CTL_HW, HW_CACHELINE };
len = sizeof(cacheline);
if (sysctl(name, 2, &cacheline, &len, NULL, 0)) {
perror("sysctl CTL_HW HW_CACHELINE failed");
} else {
qemu_cache_conf.dcache_bsize = cacheline;
qemu_cache_conf.icache_bsize = cacheline;
}
}
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/sysctl.h>
void qemu_cache_utils_init(void)
{
size_t len = 4;
unsigned cacheline;
if (sysctlbyname ("machdep.cacheline_size", &cacheline, &len, NULL, 0)) {
fprintf(stderr, "sysctlbyname machdep.cacheline_size failed: %s\n",
strerror(errno));
exit(1);
}
qemu_cache_conf.dcache_bsize = cacheline;
qemu_cache_conf.icache_bsize = cacheline;
}
#endif
#endif /* _ARCH_PPC */

View file

@ -48,24 +48,51 @@ typedef struct {
static const ElfW_auxv_t *auxv;
void qemu_init_auxval(char **envp)
static const ElfW_auxv_t *qemu_init_auxval(void)
{
/* The auxiliary vector is located just beyond the initial environment. */
while (*envp++ != NULL) {
continue;
ElfW_auxv_t *a;
ssize_t size = 512, r, ofs;
int fd;
/* Allocate some initial storage. Make sure the first entry is set
to end-of-list, so that we've got a valid list in case of error. */
auxv = a = g_malloc(size);
a[0].a_type = 0;
a[0].a_val = 0;
fd = open("/proc/self/auxv", O_RDONLY);
if (fd < 0) {
return a;
}
auxv = (const ElfW_auxv_t *)envp;
/* Read the first SIZE bytes. Hopefully, this covers everything. */
r = read(fd, a, size);
if (r == size) {
/* Continue to expand until we do get a partial read. */
do {
ofs = size;
size *= 2;
auxv = a = g_realloc(a, size);
r = read(fd, (char *)a + ofs, ofs);
} while (r == ofs);
}
close(fd);
return a;
}
unsigned long qemu_getauxval(unsigned long type)
{
/* If we were able to find the auxiliary vector, use it. */
if (auxv) {
const ElfW_auxv_t *a;
for (a = auxv; a->a_type != 0; a++) {
if (a->a_type == type) {
return a->a_val;
}
const ElfW_auxv_t *a = auxv;
if (unlikely(a == NULL)) {
a = qemu_init_auxval();
}
for (; a->a_type != 0; a++) {
if (a->a_type == type) {
return a->a_val;
}
}

4
vl.c
View file

@ -82,7 +82,6 @@ int main(int argc, char **argv)
#include "qemu/timer.h"
#include "sysemu/char.h"
#include "qemu/bitmap.h"
#include "qemu/cache-utils.h"
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
#include "migration/block.h"
@ -2974,9 +2973,6 @@ int main(int argc, char **argv, char **envp)
rtc_clock = QEMU_CLOCK_HOST;
qemu_init_auxval(envp);
qemu_cache_utils_init();
QLIST_INIT (&vm_change_state_head);
os_setup_early_signal_handling();