mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-24 03:59:52 +00:00
Merge remote-tracking branch 'remotes/rth/tcg-mips' into staging
* remotes/rth/tcg-mips: (24 commits) tcg-mips: Enable direct chaining of TBs tcg-mips: Simplify movcond tcg-mips: Simplify brcond2 tcg-mips: Improve setcond eq/ne vs zeros tcg-mips: Simplify setcond2 tcg-mips: Simplify brcond tcg-mips: Simplify setcond tcg-mips: Commonize opcode implementations tcg-mips: Improve add2/sub2 tcg-mips: Hoist args loads tcg-mips: Fix subtract immediate range tcg-mips: Name the opcode enumeration tcg-mips: Use EXT for AND on mips32r2 tcg-mips: Use T9 for TCG_TMP1 tcg-mips: Introduce TCG_TMP0, TCG_TMP1 tcg-mips: Rearrange register allocation tcg-mips: Convert to new_ldst tcg-mips: Convert to new qemu_l/st helpers tcg-mips: Move softmmu slow path out of line tcg-mips: Split large ldst offsets ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
27aa948502
7
configure
vendored
7
configure
vendored
@ -4029,11 +4029,14 @@ fi
|
|||||||
if test "$pie" = "no" ; then
|
if test "$pie" = "no" ; then
|
||||||
textseg_addr=
|
textseg_addr=
|
||||||
case "$cpu" in
|
case "$cpu" in
|
||||||
arm | hppa | i386 | m68k | ppc | ppc64 | s390* | sparc | sparc64 | x86_64 | x32)
|
arm | i386 | ppc* | s390* | sparc* | x86_64 | x32)
|
||||||
|
# ??? Rationale for choosing this address
|
||||||
textseg_addr=0x60000000
|
textseg_addr=0x60000000
|
||||||
;;
|
;;
|
||||||
mips)
|
mips)
|
||||||
textseg_addr=0x400000
|
# A 256M aligned address, high in the address space, with enough
|
||||||
|
# room for the code_gen_buffer above it before the stack.
|
||||||
|
textseg_addr=0x60000000
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if [ -n "$textseg_addr" ]; then
|
if [ -n "$textseg_addr" ]; then
|
||||||
|
@ -131,7 +131,7 @@ static inline void tlb_flush(CPUState *cpu, int flush_global)
|
|||||||
#if defined(__arm__) || defined(_ARCH_PPC) \
|
#if defined(__arm__) || defined(_ARCH_PPC) \
|
||||||
|| defined(__x86_64__) || defined(__i386__) \
|
|| defined(__x86_64__) || defined(__i386__) \
|
||||||
|| defined(__sparc__) || defined(__aarch64__) \
|
|| defined(__sparc__) || defined(__aarch64__) \
|
||||||
|| defined(__s390x__) \
|
|| defined(__s390x__) || defined(__mips__) \
|
||||||
|| defined(CONFIG_TCG_INTERPRETER)
|
|| defined(CONFIG_TCG_INTERPRETER)
|
||||||
#define USE_DIRECT_JUMP
|
#define USE_DIRECT_JUMP
|
||||||
#endif
|
#endif
|
||||||
@ -268,7 +268,7 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr)
|
|||||||
__asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
|
__asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#elif defined(__sparc__)
|
#elif defined(__sparc__) || defined(__mips__)
|
||||||
void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
|
void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr);
|
||||||
#else
|
#else
|
||||||
#error tb_set_jmp_target1 is missing
|
#error tb_set_jmp_target1 is missing
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -60,16 +60,14 @@ typedef enum {
|
|||||||
TCG_REG_K1,
|
TCG_REG_K1,
|
||||||
TCG_REG_GP,
|
TCG_REG_GP,
|
||||||
TCG_REG_SP,
|
TCG_REG_SP,
|
||||||
TCG_REG_FP,
|
TCG_REG_S8,
|
||||||
TCG_REG_RA,
|
TCG_REG_RA,
|
||||||
|
|
||||||
|
TCG_REG_CALL_STACK = TCG_REG_SP,
|
||||||
|
TCG_AREG0 = TCG_REG_S0,
|
||||||
} TCGReg;
|
} TCGReg;
|
||||||
|
|
||||||
#define TCG_CT_CONST_ZERO 0x100
|
|
||||||
#define TCG_CT_CONST_U16 0x200
|
|
||||||
#define TCG_CT_CONST_S16 0x400
|
|
||||||
|
|
||||||
/* used for function call generation */
|
/* used for function call generation */
|
||||||
#define TCG_REG_CALL_STACK TCG_REG_SP
|
|
||||||
#define TCG_TARGET_STACK_ALIGN 8
|
#define TCG_TARGET_STACK_ALIGN 8
|
||||||
#define TCG_TARGET_CALL_STACK_OFFSET 16
|
#define TCG_TARGET_CALL_STACK_OFFSET 16
|
||||||
#define TCG_TARGET_CALL_ALIGN_ARGS 1
|
#define TCG_TARGET_CALL_ALIGN_ARGS 1
|
||||||
@ -120,15 +118,13 @@ extern bool use_mips32r2_instructions;
|
|||||||
#define TCG_TARGET_HAS_ext16s_i32 use_mips32r2_instructions
|
#define TCG_TARGET_HAS_ext16s_i32 use_mips32r2_instructions
|
||||||
#define TCG_TARGET_HAS_rot_i32 use_mips32r2_instructions
|
#define TCG_TARGET_HAS_rot_i32 use_mips32r2_instructions
|
||||||
|
|
||||||
#define TCG_TARGET_HAS_new_ldst 0
|
#define TCG_TARGET_HAS_new_ldst 1
|
||||||
|
|
||||||
/* optional instructions automatically implemented */
|
/* optional instructions automatically implemented */
|
||||||
#define TCG_TARGET_HAS_neg_i32 0 /* sub rd, zero, rt */
|
#define TCG_TARGET_HAS_neg_i32 0 /* sub rd, zero, rt */
|
||||||
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */
|
#define TCG_TARGET_HAS_ext8u_i32 0 /* andi rt, rs, 0xff */
|
||||||
#define TCG_TARGET_HAS_ext16u_i32 0 /* andi rt, rs, 0xffff */
|
#define TCG_TARGET_HAS_ext16u_i32 0 /* andi rt, rs, 0xffff */
|
||||||
|
|
||||||
#define TCG_AREG0 TCG_REG_S0
|
|
||||||
|
|
||||||
#ifdef __OpenBSD__
|
#ifdef __OpenBSD__
|
||||||
#include <machine/sysarch.h>
|
#include <machine/sysarch.h>
|
||||||
#else
|
#else
|
||||||
|
103
translate-all.c
103
translate-all.c
@ -475,6 +475,10 @@ static inline PageDesc *page_find(tb_page_addr_t index)
|
|||||||
#elif defined(__s390x__)
|
#elif defined(__s390x__)
|
||||||
/* We have a +- 4GB range on the branches; leave some slop. */
|
/* We have a +- 4GB range on the branches; leave some slop. */
|
||||||
# define MAX_CODE_GEN_BUFFER_SIZE (3ul * 1024 * 1024 * 1024)
|
# define MAX_CODE_GEN_BUFFER_SIZE (3ul * 1024 * 1024 * 1024)
|
||||||
|
#elif defined(__mips__)
|
||||||
|
/* We have a 256MB branch region, but leave room to make sure the
|
||||||
|
main executable is also within that region. */
|
||||||
|
# define MAX_CODE_GEN_BUFFER_SIZE (128ul * 1024 * 1024)
|
||||||
#else
|
#else
|
||||||
# define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
|
# define MAX_CODE_GEN_BUFFER_SIZE ((size_t)-1)
|
||||||
#endif
|
#endif
|
||||||
@ -509,14 +513,47 @@ static inline size_t size_code_gen_buffer(size_t tb_size)
|
|||||||
return tb_size;
|
return tb_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __mips__
|
||||||
|
/* In order to use J and JAL within the code_gen_buffer, we require
|
||||||
|
that the buffer not cross a 256MB boundary. */
|
||||||
|
static inline bool cross_256mb(void *addr, size_t size)
|
||||||
|
{
|
||||||
|
return ((uintptr_t)addr ^ ((uintptr_t)addr + size)) & 0xf0000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We weren't able to allocate a buffer without crossing that boundary,
|
||||||
|
so make do with the larger portion of the buffer that doesn't cross.
|
||||||
|
Returns the new base of the buffer, and adjusts code_gen_buffer_size. */
|
||||||
|
static inline void *split_cross_256mb(void *buf1, size_t size1)
|
||||||
|
{
|
||||||
|
void *buf2 = (void *)(((uintptr_t)buf1 + size1) & 0xf0000000);
|
||||||
|
size_t size2 = buf1 + size1 - buf2;
|
||||||
|
|
||||||
|
size1 = buf2 - buf1;
|
||||||
|
if (size1 < size2) {
|
||||||
|
size1 = size2;
|
||||||
|
buf1 = buf2;
|
||||||
|
}
|
||||||
|
|
||||||
|
tcg_ctx.code_gen_buffer_size = size1;
|
||||||
|
return buf1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_STATIC_CODE_GEN_BUFFER
|
#ifdef USE_STATIC_CODE_GEN_BUFFER
|
||||||
static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
|
static uint8_t static_code_gen_buffer[DEFAULT_CODE_GEN_BUFFER_SIZE]
|
||||||
__attribute__((aligned(CODE_GEN_ALIGN)));
|
__attribute__((aligned(CODE_GEN_ALIGN)));
|
||||||
|
|
||||||
static inline void *alloc_code_gen_buffer(void)
|
static inline void *alloc_code_gen_buffer(void)
|
||||||
{
|
{
|
||||||
map_exec(static_code_gen_buffer, tcg_ctx.code_gen_buffer_size);
|
void *buf = static_code_gen_buffer;
|
||||||
return static_code_gen_buffer;
|
#ifdef __mips__
|
||||||
|
if (cross_256mb(buf, tcg_ctx.code_gen_buffer_size)) {
|
||||||
|
buf = split_cross_256mb(buf, tcg_ctx.code_gen_buffer_size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
map_exec(buf, tcg_ctx.code_gen_buffer_size);
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
#elif defined(USE_MMAP)
|
#elif defined(USE_MMAP)
|
||||||
static inline void *alloc_code_gen_buffer(void)
|
static inline void *alloc_code_gen_buffer(void)
|
||||||
@ -545,20 +582,76 @@ static inline void *alloc_code_gen_buffer(void)
|
|||||||
start = 0x40000000ul;
|
start = 0x40000000ul;
|
||||||
# elif defined(__s390x__)
|
# elif defined(__s390x__)
|
||||||
start = 0x90000000ul;
|
start = 0x90000000ul;
|
||||||
|
# elif defined(__mips__)
|
||||||
|
/* ??? We ought to more explicitly manage layout for softmmu too. */
|
||||||
|
# ifdef CONFIG_USER_ONLY
|
||||||
|
start = 0x68000000ul;
|
||||||
|
# elif _MIPS_SIM == _ABI64
|
||||||
|
start = 0x128000000ul;
|
||||||
|
# else
|
||||||
|
start = 0x08000000ul;
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
buf = mmap((void *)start, tcg_ctx.code_gen_buffer_size,
|
buf = mmap((void *)start, tcg_ctx.code_gen_buffer_size,
|
||||||
PROT_WRITE | PROT_READ | PROT_EXEC, flags, -1, 0);
|
PROT_WRITE | PROT_READ | PROT_EXEC, flags, -1, 0);
|
||||||
return buf == MAP_FAILED ? NULL : buf;
|
if (buf == MAP_FAILED) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __mips__
|
||||||
|
if (cross_256mb(buf, tcg_ctx.code_gen_buffer_size)) {
|
||||||
|
/* Try again, with the original still mapped, to avoid re-aquiring
|
||||||
|
that 256mb crossing. This time don't specify an address. */
|
||||||
|
size_t size2, size1 = tcg_ctx.code_gen_buffer_size;
|
||||||
|
void *buf2 = mmap(NULL, size1, PROT_WRITE | PROT_READ | PROT_EXEC,
|
||||||
|
flags, -1, 0);
|
||||||
|
if (buf2 != MAP_FAILED) {
|
||||||
|
if (!cross_256mb(buf2, size1)) {
|
||||||
|
/* Success! Use the new buffer. */
|
||||||
|
munmap(buf, size1);
|
||||||
|
return buf2;
|
||||||
|
}
|
||||||
|
/* Failure. Work with what we had. */
|
||||||
|
munmap(buf2, size1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Split the original buffer. Free the smaller half. */
|
||||||
|
buf2 = split_cross_256mb(buf, size1);
|
||||||
|
size2 = tcg_ctx.code_gen_buffer_size;
|
||||||
|
munmap(buf + (buf == buf2 ? size2 : 0), size1 - size2);
|
||||||
|
return buf2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return buf;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void *alloc_code_gen_buffer(void)
|
static inline void *alloc_code_gen_buffer(void)
|
||||||
{
|
{
|
||||||
void *buf = g_malloc(tcg_ctx.code_gen_buffer_size);
|
void *buf = g_malloc(tcg_ctx.code_gen_buffer_size);
|
||||||
|
|
||||||
if (buf) {
|
if (buf == NULL) {
|
||||||
map_exec(buf, tcg_ctx.code_gen_buffer_size);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __mips__
|
||||||
|
if (cross_256mb(buf, tcg_ctx.code_gen_buffer_size)) {
|
||||||
|
void *buf2 = g_malloc(tcg_ctx.code_gen_buffer_size);
|
||||||
|
if (buf2 != NULL && !cross_256mb(buf2, size1)) {
|
||||||
|
/* Success! Use the new buffer. */
|
||||||
|
free(buf);
|
||||||
|
buf = buf2;
|
||||||
|
} else {
|
||||||
|
/* Failure. Work with what we had. Since this is malloc
|
||||||
|
and not mmap, we can't free the other half. */
|
||||||
|
free(buf2);
|
||||||
|
buf = split_cross_256mb(buf, tcg_ctx.code_gen_buffer_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
map_exec(buf, tcg_ctx.code_gen_buffer_size);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
#endif /* USE_STATIC_CODE_GEN_BUFFER, USE_MMAP */
|
#endif /* USE_STATIC_CODE_GEN_BUFFER, USE_MMAP */
|
||||||
|
Loading…
Reference in New Issue
Block a user