Fix translation race condition for user-only.

Fix tcg/i386 encoding for VPSLLVQ, VPSRLVQ.
 Fix tcg/arm tcg_out_vec_op signature.
 Fix tcg/ppc (32bit) build with clang.
 Remove dupluate TCG_KICK_PERIOD definition.
 Remove unused tcg_global_reg_new.
 Restrict cpu_exec_interrupt and its callees to sysemu.
 Cleanups for tcg/arm.
 -----BEGIN PGP SIGNATURE-----
 
 iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmFA9+MdHHJpY2hhcmQu
 aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/XYwgAi4mIVpxH+5xuzIKR
 ZNFLKv2oB48C/tWd8klRkT1jxewc+T+eE1nBC3s4BbRYf0UNTk+kzXMOfn4GcGdt
 6uVEglCvR07ubqIhfrfT7cb23FsY0OytavaiT2LZAeAdlxKHj++LfwFJ166FPAmN
 H60QhAPG3aTZdXdFasLzI/y0spV7zepZkUiHmtFdgrXcoiidXbWgxEcOFVQx5Rfr
 lIdy8VhZjNDsA0VtISaElePGsmNUjGLgAod3RVtDNQITit2Kn0BhNVk3VXRo6JKv
 GJygeQ0v9wTpDIEvyXDjAlMKCfBWgeL3832BK0bQA+scmxidrSVvOpkgZAD4gLVr
 uNBpnA==
 =xBx2
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/rth-gitlab/tags/pull-tcg-20210914-4' into staging

Fix translation race condition for user-only.
Fix tcg/i386 encoding for VPSLLVQ, VPSRLVQ.
Fix tcg/arm tcg_out_vec_op signature.
Fix tcg/ppc (32bit) build with clang.
Remove dupluate TCG_KICK_PERIOD definition.
Remove unused tcg_global_reg_new.
Restrict cpu_exec_interrupt and its callees to sysemu.
Cleanups for tcg/arm.

# gpg: Signature made Tue 14 Sep 2021 20:28:35 BST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth-gitlab/tags/pull-tcg-20210914-4: (43 commits)
  tcg/arm: More use of the TCGReg enum
  tcg/arm: More use of the ARMInsn enum
  tcg/arm: Give enum arm_cond_code_e a typedef and use it
  tcg/arm: Drop inline markers
  tcg/arm: Simplify usage of encode_imm
  tcg/arm: Split out tcg_out_ldstm
  tcg/arm: Support armv4t in tcg_out_goto and tcg_out_call
  tcg/arm: Simplify use_armv5t_instructions
  tcg/arm: Standardize on tcg_out_<branch>_{reg,imm}
  tcg/arm: Remove fallback definition of __ARM_ARCH
  accel/tcg/user-exec: Fix read-modify-write of code on s390 hosts
  user: Remove cpu_get_pic_interrupt() stubs
  accel/tcg: Restrict TCGCPUOps::cpu_exec_interrupt() to sysemu
  target/xtensa: Restrict cpu_exec_interrupt() handler to sysemu
  target/rx: Restrict cpu_exec_interrupt() handler to sysemu
  target/sparc: Restrict cpu_exec_interrupt() handler to sysemu
  target/sh4: Restrict cpu_exec_interrupt() handler to sysemu
  target/riscv: Restrict cpu_exec_interrupt() handler to sysemu
  target/ppc: Restrict cpu_exec_interrupt() handler to sysemu
  target/openrisc: Restrict cpu_exec_interrupt() handler to sysemu
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2021-09-15 13:27:49 +01:00
commit 0b6206b9c6
85 changed files with 700 additions and 628 deletions

View File

@ -651,8 +651,8 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
loop */ loop */
#if defined(TARGET_I386) #if defined(TARGET_I386)
CPUClass *cc = CPU_GET_CLASS(cpu); CPUClass *cc = CPU_GET_CLASS(cpu);
cc->tcg_ops->do_interrupt(cpu); cc->tcg_ops->fake_user_interrupt(cpu);
#endif #endif /* TARGET_I386 */
*ret = cpu->exception_index; *ret = cpu->exception_index;
cpu->exception_index = -1; cpu->exception_index = -1;
return true; return true;
@ -685,6 +685,7 @@ static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
return false; return false;
} }
#ifndef CONFIG_USER_ONLY
/* /*
* CPU_INTERRUPT_POLL is a virtual event which gets converted into a * CPU_INTERRUPT_POLL is a virtual event which gets converted into a
* "real" interrupt event later. It does not need to be recorded for * "real" interrupt event later. It does not need to be recorded for
@ -698,12 +699,11 @@ static inline bool need_replay_interrupt(int interrupt_request)
return true; return true;
#endif #endif
} }
#endif /* !CONFIG_USER_ONLY */
static inline bool cpu_handle_interrupt(CPUState *cpu, static inline bool cpu_handle_interrupt(CPUState *cpu,
TranslationBlock **last_tb) TranslationBlock **last_tb)
{ {
CPUClass *cc = CPU_GET_CLASS(cpu);
/* Clear the interrupt flag now since we're processing /* Clear the interrupt flag now since we're processing
* cpu->interrupt_request and cpu->exit_request. * cpu->interrupt_request and cpu->exit_request.
* Ensure zeroing happens before reading cpu->exit_request or * Ensure zeroing happens before reading cpu->exit_request or
@ -725,6 +725,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
qemu_mutex_unlock_iothread(); qemu_mutex_unlock_iothread();
return true; return true;
} }
#if !defined(CONFIG_USER_ONLY)
if (replay_mode == REPLAY_MODE_PLAY && !replay_has_interrupt()) { if (replay_mode == REPLAY_MODE_PLAY && !replay_has_interrupt()) {
/* Do nothing */ /* Do nothing */
} else if (interrupt_request & CPU_INTERRUPT_HALT) { } else if (interrupt_request & CPU_INTERRUPT_HALT) {
@ -753,12 +754,14 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
qemu_mutex_unlock_iothread(); qemu_mutex_unlock_iothread();
return true; return true;
} }
#endif #endif /* !TARGET_I386 */
/* The target hook has 3 exit conditions: /* The target hook has 3 exit conditions:
False when the interrupt isn't processed, False when the interrupt isn't processed,
True when it is, and we should restart on a new TB, True when it is, and we should restart on a new TB,
and via longjmp via cpu_loop_exit. */ and via longjmp via cpu_loop_exit. */
else { else {
CPUClass *cc = CPU_GET_CLASS(cpu);
if (cc->tcg_ops->cpu_exec_interrupt && if (cc->tcg_ops->cpu_exec_interrupt &&
cc->tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) { cc->tcg_ops->cpu_exec_interrupt(cpu, interrupt_request)) {
if (need_replay_interrupt(interrupt_request)) { if (need_replay_interrupt(interrupt_request)) {
@ -777,6 +780,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
* reload the 'interrupt_request' value */ * reload the 'interrupt_request' value */
interrupt_request = cpu->interrupt_request; interrupt_request = cpu->interrupt_request;
} }
#endif /* !CONFIG_USER_ONLY */
if (interrupt_request & CPU_INTERRUPT_EXITTB) { if (interrupt_request & CPU_INTERRUPT_EXITTB) {
cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB; cpu->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
/* ensure that no TB jump will be modified as /* ensure that no TB jump will be modified as

View File

@ -60,8 +60,6 @@ void rr_kick_vcpu_thread(CPUState *unused)
static QEMUTimer *rr_kick_vcpu_timer; static QEMUTimer *rr_kick_vcpu_timer;
static CPUState *rr_current_cpu; static CPUState *rr_current_cpu;
#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
static inline int64_t rr_next_kick_time(void) static inline int64_t rr_next_kick_time(void)
{ {
return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD; return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD;

View File

@ -1297,31 +1297,8 @@ static inline void tb_page_add(PageDesc *p, TranslationBlock *tb,
invalidate_page_bitmap(p); invalidate_page_bitmap(p);
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
if (p->flags & PAGE_WRITE) { /* translator_loop() must have made all TB pages non-writable */
target_ulong addr; assert(!(p->flags & PAGE_WRITE));
PageDesc *p2;
int prot;
/* force the host page as non writable (writes will have a
page fault + mprotect overhead) */
page_addr &= qemu_host_page_mask;
prot = 0;
for (addr = page_addr; addr < page_addr + qemu_host_page_size;
addr += TARGET_PAGE_SIZE) {
p2 = page_find(addr >> TARGET_PAGE_BITS);
if (!p2) {
continue;
}
prot |= p2->flags;
p2->flags &= ~PAGE_WRITE;
}
mprotect(g2h_untagged(page_addr), qemu_host_page_size,
(prot & PAGE_BITS) & ~PAGE_WRITE);
if (DEBUG_TB_INVALIDATE_GATE) {
printf("protecting code page: 0x" TB_PAGE_ADDR_FMT "\n", page_addr);
}
}
#else #else
/* if some code is already present, then the pages are already /* if some code is already present, then the pages are already
protected. So we handle the case where only the first TB is protected. So we handle the case where only the first TB is
@ -2394,6 +2371,38 @@ int page_check_range(target_ulong start, target_ulong len, int flags)
return 0; return 0;
} }
void page_protect(tb_page_addr_t page_addr)
{
target_ulong addr;
PageDesc *p;
int prot;
p = page_find(page_addr >> TARGET_PAGE_BITS);
if (p && (p->flags & PAGE_WRITE)) {
/*
* Force the host page as non writable (writes will have a page fault +
* mprotect overhead).
*/
page_addr &= qemu_host_page_mask;
prot = 0;
for (addr = page_addr; addr < page_addr + qemu_host_page_size;
addr += TARGET_PAGE_SIZE) {
p = page_find(addr >> TARGET_PAGE_BITS);
if (!p) {
continue;
}
prot |= p->flags;
p->flags &= ~PAGE_WRITE;
}
mprotect(g2h_untagged(page_addr), qemu_host_page_size,
(prot & PAGE_BITS) & ~PAGE_WRITE);
if (DEBUG_TB_INVALIDATE_GATE) {
printf("protecting code page: 0x" TB_PAGE_ADDR_FMT "\n", page_addr);
}
}
}
/* called from signal handler: invalidate the code and unprotect the /* called from signal handler: invalidate the code and unprotect the
* page. Return 0 if the fault was not handled, 1 if it was handled, * page. Return 0 if the fault was not handled, 1 if it was handled,
* and 2 if it was handled but the caller must cause the TB to be * and 2 if it was handled but the caller must cause the TB to be

View File

@ -42,6 +42,15 @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest)
return ((db->pc_first ^ dest) & TARGET_PAGE_MASK) == 0; return ((db->pc_first ^ dest) & TARGET_PAGE_MASK) == 0;
} }
static inline void translator_page_protect(DisasContextBase *dcbase,
target_ulong pc)
{
#ifdef CONFIG_USER_ONLY
dcbase->page_protect_end = pc | ~TARGET_PAGE_MASK;
page_protect(pc);
#endif
}
void translator_loop(const TranslatorOps *ops, DisasContextBase *db, void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
CPUState *cpu, TranslationBlock *tb, int max_insns) CPUState *cpu, TranslationBlock *tb, int max_insns)
{ {
@ -56,6 +65,7 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
db->num_insns = 0; db->num_insns = 0;
db->max_insns = max_insns; db->max_insns = max_insns;
db->singlestep_enabled = cflags & CF_SINGLE_STEP; db->singlestep_enabled = cflags & CF_SINGLE_STEP;
translator_page_protect(db, db->pc_next);
ops->init_disas_context(db, cpu); ops->init_disas_context(db, cpu);
tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */
@ -137,3 +147,32 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
} }
#endif #endif
} }
static inline void translator_maybe_page_protect(DisasContextBase *dcbase,
target_ulong pc, size_t len)
{
#ifdef CONFIG_USER_ONLY
target_ulong end = pc + len - 1;
if (end > dcbase->page_protect_end) {
translator_page_protect(dcbase, end);
}
#endif
}
#define GEN_TRANSLATOR_LD(fullname, type, load_fn, swap_fn) \
type fullname ## _swap(CPUArchState *env, DisasContextBase *dcbase, \
abi_ptr pc, bool do_swap) \
{ \
translator_maybe_page_protect(dcbase, pc, sizeof(type)); \
type ret = load_fn(env, pc); \
if (do_swap) { \
ret = swap_fn(ret); \
} \
plugin_insn_append(&ret, sizeof(ret)); \
return ret; \
}
FOR_EACH_TRANSLATOR_LD(GEN_TRANSLATOR_LD)
#undef GEN_TRANSLATOR_LD

View File

@ -680,18 +680,26 @@ int cpu_signal_handler(int host_signum, void *pinfo,
pc = uc->uc_mcontext.psw.addr; pc = uc->uc_mcontext.psw.addr;
/* ??? On linux, the non-rt signal handler has 4 (!) arguments instead /*
of the normal 2 arguments. The 3rd argument contains the "int_code" * ??? On linux, the non-rt signal handler has 4 (!) arguments instead
from the hardware which does in fact contain the is_write value. * of the normal 2 arguments. The 4th argument contains the "Translation-
The rt signal handler, as far as I can tell, does not give this value * Exception Identification for DAT Exceptions" from the hardware (aka
at all. Not that we could get to it from here even if it were. */ * "int_parm_long"), which does in fact contain the is_write value.
/* ??? This is not even close to complete, since it ignores all * The rt signal handler, as far as I can tell, does not give this value
of the read-modify-write instructions. */ * at all. Not that we could get to it from here even if it were.
* So fall back to parsing instructions. Treat read-modify-write ones as
* writes, which is not fully correct, but for tracking self-modifying code
* this is better than treating them as reads. Checking si_addr page flags
* might be a viable improvement, albeit a racy one.
*/
/* ??? This is not even close to complete. */
pinsn = (uint16_t *)pc; pinsn = (uint16_t *)pc;
switch (pinsn[0] >> 8) { switch (pinsn[0] >> 8) {
case 0x50: /* ST */ case 0x50: /* ST */
case 0x42: /* STC */ case 0x42: /* STC */
case 0x40: /* STH */ case 0x40: /* STH */
case 0xba: /* CS */
case 0xbb: /* CDS */
is_write = 1; is_write = 1;
break; break;
case 0xc4: /* RIL format insns */ case 0xc4: /* RIL format insns */
@ -702,6 +710,12 @@ int cpu_signal_handler(int host_signum, void *pinfo,
is_write = 1; is_write = 1;
} }
break; break;
case 0xc8: /* SSF format insns */
switch (pinsn[0] & 0xf) {
case 0x2: /* CSST */
is_write = 1;
}
break;
case 0xe3: /* RXY format insns */ case 0xe3: /* RXY format insns */
switch (pinsn[2] & 0xff) { switch (pinsn[2] & 0xff) {
case 0x50: /* STY */ case 0x50: /* STY */
@ -715,7 +729,27 @@ int cpu_signal_handler(int host_signum, void *pinfo,
is_write = 1; is_write = 1;
} }
break; break;
case 0xeb: /* RSY format insns */
switch (pinsn[2] & 0xff) {
case 0x14: /* CSY */
case 0x30: /* CSG */
case 0x31: /* CDSY */
case 0x3e: /* CDSG */
case 0xe4: /* LANG */
case 0xe6: /* LAOG */
case 0xe7: /* LAXG */
case 0xe8: /* LAAG */
case 0xea: /* LAALG */
case 0xf4: /* LAN */
case 0xf6: /* LAO */
case 0xf7: /* LAX */
case 0xfa: /* LAAL */
case 0xf8: /* LAA */
is_write = 1;
}
break;
} }
return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask);
} }

View File

@ -33,11 +33,6 @@ uint64_t cpu_get_tsc(CPUX86State *env)
return cpu_get_host_ticks(); return cpu_get_host_ticks();
} }
int cpu_get_pic_interrupt(CPUX86State *env)
{
return -1;
}
void bsd_i386_write_dt(void *ptr, unsigned long addr, unsigned long limit, void bsd_i386_write_dt(void *ptr, unsigned long addr, unsigned long limit,
int flags) int flags)
{ {

View File

@ -33,11 +33,6 @@ uint64_t cpu_get_tsc(CPUX86State *env)
return cpu_get_host_ticks(); return cpu_get_host_ticks();
} }
int cpu_get_pic_interrupt(CPUX86State *env)
{
return -1;
}
void bsd_x86_64_write_dt(void *ptr, unsigned long addr, void bsd_x86_64_write_dt(void *ptr, unsigned long addr,
unsigned long limit, int flags) unsigned long limit, int flags)
{ {

View File

@ -33,6 +33,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end);
void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr); void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr);
#ifdef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
void page_protect(tb_page_addr_t page_addr);
int page_unprotect(target_ulong address, uintptr_t pc); int page_unprotect(target_ulong address, uintptr_t pc);
#endif #endif

View File

@ -23,6 +23,7 @@
#include "exec/exec-all.h" #include "exec/exec-all.h"
#include "exec/cpu_ldst.h" #include "exec/cpu_ldst.h"
#include "exec/plugin-gen.h" #include "exec/plugin-gen.h"
#include "exec/translate-all.h"
#include "tcg/tcg.h" #include "tcg/tcg.h"
@ -74,6 +75,17 @@ typedef struct DisasContextBase {
int num_insns; int num_insns;
int max_insns; int max_insns;
bool singlestep_enabled; bool singlestep_enabled;
#ifdef CONFIG_USER_ONLY
/*
* Guest address of the last byte of the last protected page.
*
* Pages containing the translated instructions are made non-writable in
* order to achieve consistency in case another thread is modifying the
* code while translate_insn() fetches the instruction bytes piecemeal.
* Such writer threads are blocked on mmap_lock() in page_unprotect().
*/
target_ulong page_protect_end;
#endif
} DisasContextBase; } DisasContextBase;
/** /**
@ -156,27 +168,23 @@ bool translator_use_goto_tb(DisasContextBase *db, target_ulong dest);
*/ */
#define GEN_TRANSLATOR_LD(fullname, type, load_fn, swap_fn) \ #define GEN_TRANSLATOR_LD(fullname, type, load_fn, swap_fn) \
static inline type \ type fullname ## _swap(CPUArchState *env, DisasContextBase *dcbase, \
fullname ## _swap(CPUArchState *env, abi_ptr pc, bool do_swap) \ abi_ptr pc, bool do_swap); \
static inline type fullname(CPUArchState *env, \
DisasContextBase *dcbase, abi_ptr pc) \
{ \ { \
type ret = load_fn(env, pc); \ return fullname ## _swap(env, dcbase, pc, false); \
if (do_swap) { \
ret = swap_fn(ret); \
} \
plugin_insn_append(&ret, sizeof(ret)); \
return ret; \
} \
\
static inline type fullname(CPUArchState *env, abi_ptr pc) \
{ \
return fullname ## _swap(env, pc, false); \
} }
GEN_TRANSLATOR_LD(translator_ldub, uint8_t, cpu_ldub_code, /* no swap */) #define FOR_EACH_TRANSLATOR_LD(F) \
GEN_TRANSLATOR_LD(translator_ldsw, int16_t, cpu_ldsw_code, bswap16) F(translator_ldub, uint8_t, cpu_ldub_code, /* no swap */) \
GEN_TRANSLATOR_LD(translator_lduw, uint16_t, cpu_lduw_code, bswap16) F(translator_ldsw, int16_t, cpu_ldsw_code, bswap16) \
GEN_TRANSLATOR_LD(translator_ldl, uint32_t, cpu_ldl_code, bswap32) F(translator_lduw, uint16_t, cpu_lduw_code, bswap16) \
GEN_TRANSLATOR_LD(translator_ldq, uint64_t, cpu_ldq_code, bswap64) F(translator_ldl, uint32_t, cpu_ldl_code, bswap32) \
F(translator_ldq, uint64_t, cpu_ldq_code, bswap64)
FOR_EACH_TRANSLATOR_LD(GEN_TRANSLATOR_LD)
#undef GEN_TRANSLATOR_LD #undef GEN_TRANSLATOR_LD
#endif /* EXEC__TRANSLATOR_H */ #endif /* EXEC__TRANSLATOR_H */

View File

@ -35,16 +35,6 @@ struct TCGCPUOps {
void (*cpu_exec_enter)(CPUState *cpu); void (*cpu_exec_enter)(CPUState *cpu);
/** @cpu_exec_exit: Callback for cpu_exec cleanup */ /** @cpu_exec_exit: Callback for cpu_exec cleanup */
void (*cpu_exec_exit)(CPUState *cpu); void (*cpu_exec_exit)(CPUState *cpu);
/** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
/**
* @do_interrupt: Callback for interrupt handling.
*
* note that this is in general SOFTMMU only, but it actually isn't
* because of an x86 hack (accel/tcg/cpu-exec.c), so we cannot put it
* in the SOFTMMU section in general.
*/
void (*do_interrupt)(CPUState *cpu);
/** /**
* @tlb_fill: Handle a softmmu tlb miss or user-only address fault * @tlb_fill: Handle a softmmu tlb miss or user-only address fault
* *
@ -61,7 +51,23 @@ struct TCGCPUOps {
void (*debug_excp_handler)(CPUState *cpu); void (*debug_excp_handler)(CPUState *cpu);
#ifdef NEED_CPU_H #ifdef NEED_CPU_H
#if defined(CONFIG_USER_ONLY) && defined(TARGET_I386)
/**
* @fake_user_interrupt: Callback for 'fake exception' handling.
*
* Simulate 'fake exception' which will be handled outside the
* cpu execution loop (hack for x86 user mode).
*/
void (*fake_user_interrupt)(CPUState *cpu);
#else
/**
* @do_interrupt: Callback for interrupt handling.
*/
void (*do_interrupt)(CPUState *cpu);
#endif /* !CONFIG_USER_ONLY || !TARGET_I386 */
#ifdef CONFIG_SOFTMMU #ifdef CONFIG_SOFTMMU
/** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
/** /**
* @do_transaction_failed: Callback for handling failed memory transactions * @do_transaction_failed: Callback for handling failed memory transactions
* (ie bus faults or external aborts; not MMU faults) * (ie bus faults or external aborts; not MMU faults)

View File

@ -843,7 +843,6 @@ static inline void tcg_gen_plugin_cb_end(void)
#if TARGET_LONG_BITS == 32 #if TARGET_LONG_BITS == 32
#define tcg_temp_new() tcg_temp_new_i32() #define tcg_temp_new() tcg_temp_new_i32()
#define tcg_global_reg_new tcg_global_reg_new_i32
#define tcg_global_mem_new tcg_global_mem_new_i32 #define tcg_global_mem_new tcg_global_mem_new_i32
#define tcg_temp_local_new() tcg_temp_local_new_i32() #define tcg_temp_local_new() tcg_temp_local_new_i32()
#define tcg_temp_free tcg_temp_free_i32 #define tcg_temp_free tcg_temp_free_i32
@ -851,7 +850,6 @@ static inline void tcg_gen_plugin_cb_end(void)
#define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32 #define tcg_gen_qemu_st_tl tcg_gen_qemu_st_i32
#else #else
#define tcg_temp_new() tcg_temp_new_i64() #define tcg_temp_new() tcg_temp_new_i64()
#define tcg_global_reg_new tcg_global_reg_new_i64
#define tcg_global_mem_new tcg_global_mem_new_i64 #define tcg_global_mem_new tcg_global_mem_new_i64
#define tcg_temp_local_new() tcg_temp_local_new_i64() #define tcg_temp_local_new() tcg_temp_local_new_i64()
#define tcg_temp_free tcg_temp_free_i64 #define tcg_temp_free tcg_temp_free_i64

View File

@ -120,13 +120,6 @@ const char *qemu_uname_release;
by remapping the process stack directly at the right place */ by remapping the process stack directly at the right place */
unsigned long guest_stack_size = 8 * 1024 * 1024UL; unsigned long guest_stack_size = 8 * 1024 * 1024UL;
#if defined(TARGET_I386)
int cpu_get_pic_interrupt(CPUX86State *env)
{
return -1;
}
#endif
/***********************************************************/ /***********************************************************/
/* Helper routines for implementing atomic operations. */ /* Helper routines for implementing atomic operations. */

View File

@ -218,10 +218,10 @@ static const struct SysemuCPUOps alpha_sysemu_ops = {
static const struct TCGCPUOps alpha_tcg_ops = { static const struct TCGCPUOps alpha_tcg_ops = {
.initialize = alpha_translate_init, .initialize = alpha_translate_init,
.cpu_exec_interrupt = alpha_cpu_exec_interrupt,
.tlb_fill = alpha_cpu_tlb_fill, .tlb_fill = alpha_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = alpha_cpu_exec_interrupt,
.do_interrupt = alpha_cpu_do_interrupt, .do_interrupt = alpha_cpu_do_interrupt,
.do_transaction_failed = alpha_cpu_do_transaction_failed, .do_transaction_failed = alpha_cpu_do_transaction_failed,
.do_unaligned_access = alpha_cpu_do_unaligned_access, .do_unaligned_access = alpha_cpu_do_unaligned_access,

View File

@ -274,10 +274,10 @@ struct AlphaCPU {
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
extern const VMStateDescription vmstate_alpha_cpu; extern const VMStateDescription vmstate_alpha_cpu;
#endif
void alpha_cpu_do_interrupt(CPUState *cpu); void alpha_cpu_do_interrupt(CPUState *cpu);
bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req); bool alpha_cpu_exec_interrupt(CPUState *cpu, int int_req);
#endif /* !CONFIG_USER_ONLY */
void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags); void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags);
hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); hwaddr alpha_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int alpha_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);

View File

@ -293,7 +293,6 @@ bool alpha_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
prot, mmu_idx, TARGET_PAGE_SIZE); prot, mmu_idx, TARGET_PAGE_SIZE);
return true; return true;
} }
#endif /* USER_ONLY */
void alpha_cpu_do_interrupt(CPUState *cs) void alpha_cpu_do_interrupt(CPUState *cs)
{ {
@ -348,7 +347,6 @@ void alpha_cpu_do_interrupt(CPUState *cs)
cs->exception_index = -1; cs->exception_index = -1;
#if !defined(CONFIG_USER_ONLY)
switch (i) { switch (i) {
case EXCP_RESET: case EXCP_RESET:
i = 0x0000; i = 0x0000;
@ -404,7 +402,6 @@ void alpha_cpu_do_interrupt(CPUState *cs)
/* Switch to PALmode. */ /* Switch to PALmode. */
env->flags |= ENV_FLAG_PAL_MODE; env->flags |= ENV_FLAG_PAL_MODE;
#endif /* !USER_ONLY */
} }
bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
@ -451,6 +448,8 @@ bool alpha_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */
void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags) void alpha_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{ {
static const char linux_reg_names[31][4] = { static const char linux_reg_names[31][4] = {

View File

@ -2971,7 +2971,7 @@ static void alpha_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{ {
DisasContext *ctx = container_of(dcbase, DisasContext, base); DisasContext *ctx = container_of(dcbase, DisasContext, base);
CPUAlphaState *env = cpu->env_ptr; CPUAlphaState *env = cpu->env_ptr;
uint32_t insn = translator_ldl(env, ctx->base.pc_next); uint32_t insn = translator_ldl(env, &ctx->base, ctx->base.pc_next);
ctx->base.pc_next += 4; ctx->base.pc_next += 4;
ctx->base.is_jmp = translate_one(ctx, insn); ctx->base.is_jmp = translate_one(ctx, insn);

View File

@ -24,15 +24,15 @@
#include "qemu/bswap.h" #include "qemu/bswap.h"
/* Load an instruction and return it in the standard little-endian order */ /* Load an instruction and return it in the standard little-endian order */
static inline uint32_t arm_ldl_code(CPUARMState *env, target_ulong addr, static inline uint32_t arm_ldl_code(CPUARMState *env, DisasContextBase *s,
bool sctlr_b) target_ulong addr, bool sctlr_b)
{ {
return translator_ldl_swap(env, addr, bswap_code(sctlr_b)); return translator_ldl_swap(env, s, addr, bswap_code(sctlr_b));
} }
/* Ditto, for a halfword (Thumb) instruction */ /* Ditto, for a halfword (Thumb) instruction */
static inline uint16_t arm_lduw_code(CPUARMState *env, target_ulong addr, static inline uint16_t arm_lduw_code(CPUARMState *env, DisasContextBase* s,
bool sctlr_b) target_ulong addr, bool sctlr_b)
{ {
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
/* In big-endian (BE32) mode, adjacent Thumb instructions have been swapped /* In big-endian (BE32) mode, adjacent Thumb instructions have been swapped
@ -41,7 +41,7 @@ static inline uint16_t arm_lduw_code(CPUARMState *env, target_ulong addr,
addr ^= 2; addr ^= 2;
} }
#endif #endif
return translator_lduw_swap(env, addr, bswap_code(sctlr_b)); return translator_lduw_swap(env, s, addr, bswap_code(sctlr_b));
} }
#endif #endif

View File

@ -440,6 +440,8 @@ static void arm_cpu_reset(DeviceState *dev)
arm_rebuild_hflags(env); arm_rebuild_hflags(env);
} }
#ifndef CONFIG_USER_ONLY
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
unsigned int target_el, unsigned int target_el,
unsigned int cur_el, bool secure, unsigned int cur_el, bool secure,
@ -556,7 +558,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
return unmasked || pstate_unmasked; return unmasked || pstate_unmasked;
} }
bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request) static bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
CPUClass *cc = CPU_GET_CLASS(cs); CPUClass *cc = CPU_GET_CLASS(cs);
CPUARMState *env = cs->env_ptr; CPUARMState *env = cs->env_ptr;
@ -608,6 +610,7 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
cc->tcg_ops->do_interrupt(cs); cc->tcg_ops->do_interrupt(cs);
return true; return true;
} }
#endif /* !CONFIG_USER_ONLY */
void arm_cpu_update_virq(ARMCPU *cpu) void arm_cpu_update_virq(ARMCPU *cpu)
{ {
@ -2010,11 +2013,11 @@ static const struct SysemuCPUOps arm_sysemu_ops = {
static const struct TCGCPUOps arm_tcg_ops = { static const struct TCGCPUOps arm_tcg_ops = {
.initialize = arm_translate_init, .initialize = arm_translate_init,
.synchronize_from_tb = arm_cpu_synchronize_from_tb, .synchronize_from_tb = arm_cpu_synchronize_from_tb,
.cpu_exec_interrupt = arm_cpu_exec_interrupt,
.tlb_fill = arm_cpu_tlb_fill, .tlb_fill = arm_cpu_tlb_fill,
.debug_excp_handler = arm_debug_excp_handler, .debug_excp_handler = arm_debug_excp_handler,
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
.cpu_exec_interrupt = arm_cpu_exec_interrupt,
.do_interrupt = arm_cpu_do_interrupt, .do_interrupt = arm_cpu_do_interrupt,
.do_transaction_failed = arm_cpu_do_transaction_failed, .do_transaction_failed = arm_cpu_do_transaction_failed,
.do_unaligned_access = arm_cpu_do_unaligned_access, .do_unaligned_access = arm_cpu_do_unaligned_access,

View File

@ -1040,11 +1040,10 @@ uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
extern const VMStateDescription vmstate_arm_cpu; extern const VMStateDescription vmstate_arm_cpu;
#endif
void arm_cpu_do_interrupt(CPUState *cpu); void arm_cpu_do_interrupt(CPUState *cpu);
void arm_v7m_cpu_do_interrupt(CPUState *cpu); void arm_v7m_cpu_do_interrupt(CPUState *cpu);
bool arm_cpu_exec_interrupt(CPUState *cpu, int int_req); #endif /* !CONFIG_USER_ONLY */
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr, hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
MemTxAttrs *attrs); MemTxAttrs *attrs);

View File

@ -22,7 +22,7 @@
/* CPU models. These are not needed for the AArch64 linux-user build. */ /* CPU models. These are not needed for the AArch64 linux-user build. */
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) #if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
#ifdef CONFIG_TCG #if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request) static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
CPUClass *cc = CPU_GET_CLASS(cs); CPUClass *cc = CPU_GET_CLASS(cs);
@ -46,7 +46,7 @@ static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
} }
return ret; return ret;
} }
#endif /* CONFIG_TCG */ #endif /* !CONFIG_USER_ONLY && CONFIG_TCG */
static void arm926_initfn(Object *obj) static void arm926_initfn(Object *obj)
{ {
@ -898,11 +898,11 @@ static void pxa270c5_initfn(Object *obj)
static const struct TCGCPUOps arm_v7m_tcg_ops = { static const struct TCGCPUOps arm_v7m_tcg_ops = {
.initialize = arm_translate_init, .initialize = arm_translate_init,
.synchronize_from_tb = arm_cpu_synchronize_from_tb, .synchronize_from_tb = arm_cpu_synchronize_from_tb,
.cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
.tlb_fill = arm_cpu_tlb_fill, .tlb_fill = arm_cpu_tlb_fill,
.debug_excp_handler = arm_debug_excp_handler, .debug_excp_handler = arm_debug_excp_handler,
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
.cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
.do_interrupt = arm_v7m_cpu_do_interrupt, .do_interrupt = arm_v7m_cpu_do_interrupt,
.do_transaction_failed = arm_cpu_do_transaction_failed, .do_transaction_failed = arm_cpu_do_transaction_failed,
.do_unaligned_access = arm_cpu_do_unaligned_access, .do_unaligned_access = arm_cpu_do_unaligned_access,

View File

@ -14772,7 +14772,7 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
} }
s->pc_curr = s->base.pc_next; s->pc_curr = s->base.pc_next;
insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b); insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
s->insn = insn; s->insn = insn;
s->base.pc_next += 4; s->base.pc_next += 4;

View File

@ -9312,7 +9312,7 @@ static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
* boundary, so we cross the page if the first 16 bits indicate * boundary, so we cross the page if the first 16 bits indicate
* that this is a 32 bit insn. * that this is a 32 bit insn.
*/ */
uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b); uint16_t insn = arm_lduw_code(env, &s->base, s->base.pc_next, s->sctlr_b);
return !thumb_insn_is_16bit(s, s->base.pc_next, insn); return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
} }
@ -9551,7 +9551,7 @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
} }
dc->pc_curr = dc->base.pc_next; dc->pc_curr = dc->base.pc_next;
insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b); insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
dc->insn = insn; dc->insn = insn;
dc->base.pc_next += 4; dc->base.pc_next += 4;
disas_arm_insn(dc, insn); disas_arm_insn(dc, insn);
@ -9621,11 +9621,12 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
} }
dc->pc_curr = dc->base.pc_next; dc->pc_curr = dc->base.pc_next;
insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b); insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn); is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
dc->base.pc_next += 2; dc->base.pc_next += 2;
if (!is_16bit) { if (!is_16bit) {
uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b); uint32_t insn2 = arm_lduw_code(env, &dc->base, dc->base.pc_next,
dc->sctlr_b);
insn = insn << 16 | insn2; insn = insn << 16 | insn2;
dc->base.pc_next += 2; dc->base.pc_next += 2;

View File

@ -197,10 +197,7 @@ static const struct TCGCPUOps avr_tcg_ops = {
.synchronize_from_tb = avr_cpu_synchronize_from_tb, .synchronize_from_tb = avr_cpu_synchronize_from_tb,
.cpu_exec_interrupt = avr_cpu_exec_interrupt, .cpu_exec_interrupt = avr_cpu_exec_interrupt,
.tlb_fill = avr_cpu_tlb_fill, .tlb_fill = avr_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY
.do_interrupt = avr_cpu_do_interrupt, .do_interrupt = avr_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */
}; };
static void avr_cpu_class_init(ObjectClass *oc, void *data) static void avr_cpu_class_init(ObjectClass *oc, void *data)

View File

@ -205,20 +205,20 @@ static const struct SysemuCPUOps cris_sysemu_ops = {
static const struct TCGCPUOps crisv10_tcg_ops = { static const struct TCGCPUOps crisv10_tcg_ops = {
.initialize = cris_initialize_crisv10_tcg, .initialize = cris_initialize_crisv10_tcg,
.cpu_exec_interrupt = cris_cpu_exec_interrupt,
.tlb_fill = cris_cpu_tlb_fill, .tlb_fill = cris_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = cris_cpu_exec_interrupt,
.do_interrupt = crisv10_cpu_do_interrupt, .do_interrupt = crisv10_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */
}; };
static const struct TCGCPUOps crisv32_tcg_ops = { static const struct TCGCPUOps crisv32_tcg_ops = {
.initialize = cris_initialize_tcg, .initialize = cris_initialize_tcg,
.cpu_exec_interrupt = cris_cpu_exec_interrupt,
.tlb_fill = cris_cpu_tlb_fill, .tlb_fill = cris_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = cris_cpu_exec_interrupt,
.do_interrupt = cris_cpu_do_interrupt, .do_interrupt = cris_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */
}; };

View File

@ -185,11 +185,11 @@ struct CRISCPU {
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
extern const VMStateDescription vmstate_cris_cpu; extern const VMStateDescription vmstate_cris_cpu;
#endif
void cris_cpu_do_interrupt(CPUState *cpu); void cris_cpu_do_interrupt(CPUState *cpu);
void crisv10_cpu_do_interrupt(CPUState *cpu); void crisv10_cpu_do_interrupt(CPUState *cpu);
bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req); bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req);
#endif
void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags); void cris_cpu_dump_state(CPUState *cs, FILE *f, int flags);

View File

@ -41,20 +41,6 @@
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
void cris_cpu_do_interrupt(CPUState *cs)
{
CRISCPU *cpu = CRIS_CPU(cs);
CPUCRISState *env = &cpu->env;
cs->exception_index = -1;
env->pregs[PR_ERP] = env->pc;
}
void crisv10_cpu_do_interrupt(CPUState *cs)
{
cris_cpu_do_interrupt(cs);
}
bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx, MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr) bool probe, uintptr_t retaddr)
@ -287,7 +273,6 @@ hwaddr cris_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy)); D(fprintf(stderr, "%s %x -> %x\n", __func__, addr, phy));
return phy; return phy;
} }
#endif
bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
@ -319,3 +304,5 @@ bool cris_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return ret; return ret;
} }
#endif /* !CONFIG_USER_ONLY */

View File

@ -112,7 +112,8 @@ static int read_packet_words(CPUHexagonState *env, DisasContext *ctx,
memset(words, 0, PACKET_WORDS_MAX * sizeof(uint32_t)); memset(words, 0, PACKET_WORDS_MAX * sizeof(uint32_t));
for (nwords = 0; !found_end && nwords < PACKET_WORDS_MAX; nwords++) { for (nwords = 0; !found_end && nwords < PACKET_WORDS_MAX; nwords++) {
words[nwords] = words[nwords] =
translator_ldl(env, ctx->base.pc_next + nwords * sizeof(uint32_t)); translator_ldl(env, &ctx->base,
ctx->base.pc_next + nwords * sizeof(uint32_t));
found_end = is_packet_end(words[nwords]); found_end = is_packet_end(words[nwords]);
} }
if (!found_end) { if (!found_end) {

View File

@ -144,10 +144,10 @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
static const struct TCGCPUOps hppa_tcg_ops = { static const struct TCGCPUOps hppa_tcg_ops = {
.initialize = hppa_translate_init, .initialize = hppa_translate_init,
.synchronize_from_tb = hppa_cpu_synchronize_from_tb, .synchronize_from_tb = hppa_cpu_synchronize_from_tb,
.cpu_exec_interrupt = hppa_cpu_exec_interrupt,
.tlb_fill = hppa_cpu_tlb_fill, .tlb_fill = hppa_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = hppa_cpu_exec_interrupt,
.do_interrupt = hppa_cpu_do_interrupt, .do_interrupt = hppa_cpu_do_interrupt,
.do_unaligned_access = hppa_cpu_do_unaligned_access, .do_unaligned_access = hppa_cpu_do_unaligned_access,
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */

View File

@ -325,13 +325,13 @@ int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc);
hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr); hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr);
int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void hppa_cpu_do_interrupt(CPUState *cpu);
bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
void hppa_cpu_dump_state(CPUState *cs, FILE *f, int); void hppa_cpu_dump_state(CPUState *cs, FILE *f, int);
bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool hppa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx, MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr); bool probe, uintptr_t retaddr);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
void hppa_cpu_do_interrupt(CPUState *cpu);
bool hppa_cpu_exec_interrupt(CPUState *cpu, int int_req);
int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx, int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
int type, hwaddr *pphys, int *pprot); int type, hwaddr *pphys, int *pprot);
extern const MemoryRegionOps hppa_io_eir_ops; extern const MemoryRegionOps hppa_io_eir_ops;

View File

@ -88,7 +88,6 @@ void HELPER(write_eiem)(CPUHPPAState *env, target_ureg val)
eval_interrupt(env_archcpu(env)); eval_interrupt(env_archcpu(env));
qemu_mutex_unlock_iothread(); qemu_mutex_unlock_iothread();
} }
#endif /* !CONFIG_USER_ONLY */
void hppa_cpu_do_interrupt(CPUState *cs) void hppa_cpu_do_interrupt(CPUState *cs)
{ {
@ -100,7 +99,6 @@ void hppa_cpu_do_interrupt(CPUState *cs)
uint64_t iasq_f = env->iasq_f; uint64_t iasq_f = env->iasq_f;
uint64_t iasq_b = env->iasq_b; uint64_t iasq_b = env->iasq_b;
#ifndef CONFIG_USER_ONLY
target_ureg old_psw; target_ureg old_psw;
/* As documented in pa2.0 -- interruption handling. */ /* As documented in pa2.0 -- interruption handling. */
@ -187,7 +185,6 @@ void hppa_cpu_do_interrupt(CPUState *cs)
env->iaoq_b = env->iaoq_f + 4; env->iaoq_b = env->iaoq_f + 4;
env->iasq_f = 0; env->iasq_f = 0;
env->iasq_b = 0; env->iasq_b = 0;
#endif
if (qemu_loglevel_mask(CPU_LOG_INT)) { if (qemu_loglevel_mask(CPU_LOG_INT)) {
static const char * const names[] = { static const char * const names[] = {
@ -248,7 +245,6 @@ void hppa_cpu_do_interrupt(CPUState *cs)
bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
#ifndef CONFIG_USER_ONLY
HPPACPU *cpu = HPPA_CPU(cs); HPPACPU *cpu = HPPA_CPU(cs);
CPUHPPAState *env = &cpu->env; CPUHPPAState *env = &cpu->env;
@ -258,6 +254,7 @@ bool hppa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
hppa_cpu_do_interrupt(cs); hppa_cpu_do_interrupt(cs);
return true; return true;
} }
#endif
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */

View File

@ -34,7 +34,6 @@
#undef TCGv #undef TCGv
#undef tcg_temp_new #undef tcg_temp_new
#undef tcg_global_reg_new
#undef tcg_global_mem_new #undef tcg_global_mem_new
#undef tcg_temp_local_new #undef tcg_temp_local_new
#undef tcg_temp_free #undef tcg_temp_free
@ -59,7 +58,6 @@
#define TCGv_reg TCGv_i64 #define TCGv_reg TCGv_i64
#define tcg_temp_new tcg_temp_new_i64 #define tcg_temp_new tcg_temp_new_i64
#define tcg_global_reg_new tcg_global_reg_new_i64
#define tcg_global_mem_new tcg_global_mem_new_i64 #define tcg_global_mem_new tcg_global_mem_new_i64
#define tcg_temp_local_new tcg_temp_local_new_i64 #define tcg_temp_local_new tcg_temp_local_new_i64
#define tcg_temp_free tcg_temp_free_i64 #define tcg_temp_free tcg_temp_free_i64
@ -155,7 +153,6 @@
#else #else
#define TCGv_reg TCGv_i32 #define TCGv_reg TCGv_i32
#define tcg_temp_new tcg_temp_new_i32 #define tcg_temp_new tcg_temp_new_i32
#define tcg_global_reg_new tcg_global_reg_new_i32
#define tcg_global_mem_new tcg_global_mem_new_i32 #define tcg_global_mem_new tcg_global_mem_new_i32
#define tcg_temp_local_new tcg_temp_local_new_i32 #define tcg_temp_local_new tcg_temp_local_new_i32
#define tcg_temp_free tcg_temp_free_i32 #define tcg_temp_free tcg_temp_free_i32
@ -4177,7 +4174,7 @@ static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
{ {
/* Always fetch the insn, even if nullified, so that we check /* Always fetch the insn, even if nullified, so that we check
the page permissions for execute. */ the page permissions for execute. */
uint32_t insn = translator_ldl(env, ctx->base.pc_next); uint32_t insn = translator_ldl(env, &ctx->base, ctx->base.pc_next);
/* Set up the IA queue for the next insn. /* Set up the IA queue for the next insn.
This will be overwritten by a branch. */ This will be overwritten by a branch. */

View File

@ -1836,12 +1836,15 @@ int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void x86_cpu_list(void); void x86_cpu_list(void);
int cpu_x86_support_mca_broadcast(CPUX86State *env); int cpu_x86_support_mca_broadcast(CPUX86State *env);
#ifndef CONFIG_USER_ONLY
int cpu_get_pic_interrupt(CPUX86State *s); int cpu_get_pic_interrupt(CPUX86State *s);
/* MSDOS compatibility mode FPU exception support */ /* MSDOS compatibility mode FPU exception support */
void x86_register_ferr_irq(qemu_irq irq); void x86_register_ferr_irq(qemu_irq irq);
void fpu_check_raise_ferr_irq(CPUX86State *s); void fpu_check_raise_ferr_irq(CPUX86State *s);
void cpu_set_ignne(void); void cpu_set_ignne(void);
void cpu_clear_ignne(void); void cpu_clear_ignne(void);
#endif
/* mpx_helper.c */ /* mpx_helper.c */
void cpu_sync_bndcs_hflags(CPUX86State *env); void cpu_sync_bndcs_hflags(CPUX86State *env);

View File

@ -38,7 +38,9 @@ QEMU_BUILD_BUG_ON(TCG_PHYS_ADDR_BITS > TARGET_PHYS_ADDR_SPACE_BITS);
* @cpu: vCPU the interrupt is to be handled by. * @cpu: vCPU the interrupt is to be handled by.
*/ */
void x86_cpu_do_interrupt(CPUState *cpu); void x86_cpu_do_interrupt(CPUState *cpu);
#ifndef CONFIG_USER_ONLY
bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req); bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
#endif
/* helper.c */ /* helper.c */
bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,

View File

@ -929,9 +929,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int,
e2); e2);
env->eip = offset; env->eip = offset;
} }
#endif
#ifdef TARGET_X86_64
void helper_sysret(CPUX86State *env, int dflag) void helper_sysret(CPUX86State *env, int dflag)
{ {
int cpl, selector; int cpl, selector;
@ -984,7 +982,7 @@ void helper_sysret(CPUX86State *env, int dflag)
DESC_W_MASK | DESC_A_MASK); DESC_W_MASK | DESC_A_MASK);
} }
} }
#endif #endif /* TARGET_X86_64 */
/* real mode interrupt */ /* real mode interrupt */
static void do_interrupt_real(CPUX86State *env, int intno, int is_int, static void do_interrupt_real(CPUX86State *env, int intno, int is_int,
@ -1112,76 +1110,6 @@ void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw)
do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw); do_interrupt_all(env_archcpu(env), intno, 0, 0, 0, is_hw);
} }
bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
int intno;
interrupt_request = x86_cpu_pending_interrupt(cs, interrupt_request);
if (!interrupt_request) {
return false;
}
/* Don't process multiple interrupt requests in a single call.
* This is required to make icount-driven execution deterministic.
*/
switch (interrupt_request) {
#if !defined(CONFIG_USER_ONLY)
case CPU_INTERRUPT_POLL:
cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
apic_poll_irq(cpu->apic_state);
break;
#endif
case CPU_INTERRUPT_SIPI:
do_cpu_sipi(cpu);
break;
case CPU_INTERRUPT_SMI:
cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0);
cs->interrupt_request &= ~CPU_INTERRUPT_SMI;
#ifdef CONFIG_USER_ONLY
cpu_abort(CPU(cpu), "SMI interrupt: cannot enter SMM in user-mode");
#else
do_smm_enter(cpu);
#endif /* CONFIG_USER_ONLY */
break;
case CPU_INTERRUPT_NMI:
cpu_svm_check_intercept_param(env, SVM_EXIT_NMI, 0, 0);
cs->interrupt_request &= ~CPU_INTERRUPT_NMI;
env->hflags2 |= HF2_NMI_MASK;
do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
break;
case CPU_INTERRUPT_MCE:
cs->interrupt_request &= ~CPU_INTERRUPT_MCE;
do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
break;
case CPU_INTERRUPT_HARD:
cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0, 0);
cs->interrupt_request &= ~(CPU_INTERRUPT_HARD |
CPU_INTERRUPT_VIRQ);
intno = cpu_get_pic_interrupt(env);
qemu_log_mask(CPU_LOG_TB_IN_ASM,
"Servicing hardware INT=0x%02x\n", intno);
do_interrupt_x86_hardirq(env, intno, 1);
break;
#if !defined(CONFIG_USER_ONLY)
case CPU_INTERRUPT_VIRQ:
cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0);
intno = x86_ldl_phys(cs, env->vm_vmcb
+ offsetof(struct vmcb, control.int_vector));
qemu_log_mask(CPU_LOG_TB_IN_ASM,
"Servicing virtual hardware INT=0x%02x\n", intno);
do_interrupt_x86_hardirq(env, intno, 1);
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
env->int_ctl &= ~V_IRQ_MASK;
break;
#endif
}
/* Ensure that no TB jump will be modified as the program flow was changed. */
return true;
}
void helper_lldt(CPUX86State *env, int selector) void helper_lldt(CPUX86State *env, int selector)
{ {
SegmentCache *dt; SegmentCache *dt;

View File

@ -125,6 +125,68 @@ void x86_cpu_do_interrupt(CPUState *cs)
} }
} }
bool x86_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
int intno;
interrupt_request = x86_cpu_pending_interrupt(cs, interrupt_request);
if (!interrupt_request) {
return false;
}
/* Don't process multiple interrupt requests in a single call.
* This is required to make icount-driven execution deterministic.
*/
switch (interrupt_request) {
case CPU_INTERRUPT_POLL:
cs->interrupt_request &= ~CPU_INTERRUPT_POLL;
apic_poll_irq(cpu->apic_state);
break;
case CPU_INTERRUPT_SIPI:
do_cpu_sipi(cpu);
break;
case CPU_INTERRUPT_SMI:
cpu_svm_check_intercept_param(env, SVM_EXIT_SMI, 0, 0);
cs->interrupt_request &= ~CPU_INTERRUPT_SMI;
do_smm_enter(cpu);
break;
case CPU_INTERRUPT_NMI:
cpu_svm_check_intercept_param(env, SVM_EXIT_NMI, 0, 0);
cs->interrupt_request &= ~CPU_INTERRUPT_NMI;
env->hflags2 |= HF2_NMI_MASK;
do_interrupt_x86_hardirq(env, EXCP02_NMI, 1);
break;
case CPU_INTERRUPT_MCE:
cs->interrupt_request &= ~CPU_INTERRUPT_MCE;
do_interrupt_x86_hardirq(env, EXCP12_MCHK, 0);
break;
case CPU_INTERRUPT_HARD:
cpu_svm_check_intercept_param(env, SVM_EXIT_INTR, 0, 0);
cs->interrupt_request &= ~(CPU_INTERRUPT_HARD |
CPU_INTERRUPT_VIRQ);
intno = cpu_get_pic_interrupt(env);
qemu_log_mask(CPU_LOG_TB_IN_ASM,
"Servicing hardware INT=0x%02x\n", intno);
do_interrupt_x86_hardirq(env, intno, 1);
break;
case CPU_INTERRUPT_VIRQ:
cpu_svm_check_intercept_param(env, SVM_EXIT_VINTR, 0, 0);
intno = x86_ldl_phys(cs, env->vm_vmcb
+ offsetof(struct vmcb, control.int_vector));
qemu_log_mask(CPU_LOG_TB_IN_ASM,
"Servicing virtual hardware INT=0x%02x\n", intno);
do_interrupt_x86_hardirq(env, intno, 1);
cs->interrupt_request &= ~CPU_INTERRUPT_VIRQ;
env->int_ctl &= ~V_IRQ_MASK;
break;
}
/* Ensure that no TB jump will be modified as the program flow was changed. */
return true;
}
/* check if Port I/O is allowed in TSS */ /* check if Port I/O is allowed in TSS */
void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size) void helper_check_io(CPUX86State *env, uint32_t addr, uint32_t size)
{ {

View File

@ -72,10 +72,12 @@ static const struct TCGCPUOps x86_tcg_ops = {
.synchronize_from_tb = x86_cpu_synchronize_from_tb, .synchronize_from_tb = x86_cpu_synchronize_from_tb,
.cpu_exec_enter = x86_cpu_exec_enter, .cpu_exec_enter = x86_cpu_exec_enter,
.cpu_exec_exit = x86_cpu_exec_exit, .cpu_exec_exit = x86_cpu_exec_exit,
.cpu_exec_interrupt = x86_cpu_exec_interrupt,
.do_interrupt = x86_cpu_do_interrupt,
.tlb_fill = x86_cpu_tlb_fill, .tlb_fill = x86_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifdef CONFIG_USER_ONLY
.fake_user_interrupt = x86_cpu_do_interrupt,
#else
.do_interrupt = x86_cpu_do_interrupt,
.cpu_exec_interrupt = x86_cpu_exec_interrupt,
.debug_excp_handler = breakpoint_handler, .debug_excp_handler = breakpoint_handler,
.debug_check_breakpoint = x86_debug_check_breakpoint, .debug_check_breakpoint = x86_debug_check_breakpoint,
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */

View File

@ -2028,28 +2028,28 @@ static uint64_t advance_pc(CPUX86State *env, DisasContext *s, int num_bytes)
static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s) static inline uint8_t x86_ldub_code(CPUX86State *env, DisasContext *s)
{ {
return translator_ldub(env, advance_pc(env, s, 1)); return translator_ldub(env, &s->base, advance_pc(env, s, 1));
} }
static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s) static inline int16_t x86_ldsw_code(CPUX86State *env, DisasContext *s)
{ {
return translator_ldsw(env, advance_pc(env, s, 2)); return translator_ldsw(env, &s->base, advance_pc(env, s, 2));
} }
static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s) static inline uint16_t x86_lduw_code(CPUX86State *env, DisasContext *s)
{ {
return translator_lduw(env, advance_pc(env, s, 2)); return translator_lduw(env, &s->base, advance_pc(env, s, 2));
} }
static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s) static inline uint32_t x86_ldl_code(CPUX86State *env, DisasContext *s)
{ {
return translator_ldl(env, advance_pc(env, s, 4)); return translator_ldl(env, &s->base, advance_pc(env, s, 4));
} }
#ifdef TARGET_X86_64 #ifdef TARGET_X86_64
static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s) static inline uint64_t x86_ldq_code(CPUX86State *env, DisasContext *s)
{ {
return translator_ldq(env, advance_pc(env, s, 8)); return translator_ldq(env, &s->base, advance_pc(env, s, 8));
} }
#endif #endif

View File

@ -515,10 +515,10 @@ static const struct SysemuCPUOps m68k_sysemu_ops = {
static const struct TCGCPUOps m68k_tcg_ops = { static const struct TCGCPUOps m68k_tcg_ops = {
.initialize = m68k_tcg_init, .initialize = m68k_tcg_init,
.cpu_exec_interrupt = m68k_cpu_exec_interrupt,
.tlb_fill = m68k_cpu_tlb_fill, .tlb_fill = m68k_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = m68k_cpu_exec_interrupt,
.do_interrupt = m68k_cpu_do_interrupt, .do_interrupt = m68k_cpu_do_interrupt,
.do_transaction_failed = m68k_cpu_transaction_failed, .do_transaction_failed = m68k_cpu_transaction_failed,
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */

View File

@ -166,8 +166,10 @@ struct M68kCPU {
}; };
#ifndef CONFIG_USER_ONLY
void m68k_cpu_do_interrupt(CPUState *cpu); void m68k_cpu_do_interrupt(CPUState *cpu);
bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req); bool m68k_cpu_exec_interrupt(CPUState *cpu, int int_req);
#endif /* !CONFIG_USER_ONLY */
void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags); void m68k_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);

View File

@ -24,18 +24,7 @@
#include "semihosting/semihost.h" #include "semihosting/semihost.h"
#include "tcg/tcg.h" #include "tcg/tcg.h"
#if defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
void m68k_cpu_do_interrupt(CPUState *cs)
{
cs->exception_index = -1;
}
static inline void do_interrupt_m68k_hardirq(CPUM68KState *env)
{
}
#else
static void cf_rte(CPUM68KState *env) static void cf_rte(CPUM68KState *env)
{ {
@ -516,7 +505,6 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
cpu_loop_exit(cs); cpu_loop_exit(cs);
} }
} }
#endif
bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
@ -538,6 +526,8 @@ bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */
static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr) static void raise_exception_ra(CPUM68KState *env, int tt, uintptr_t raddr)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);

View File

@ -415,7 +415,7 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
static inline uint16_t read_im16(CPUM68KState *env, DisasContext *s) static inline uint16_t read_im16(CPUM68KState *env, DisasContext *s)
{ {
uint16_t im; uint16_t im;
im = translator_lduw(env, s->pc); im = translator_lduw(env, &s->base, s->pc);
s->pc += 2; s->pc += 2;
return im; return im;
} }

View File

@ -365,10 +365,10 @@ static const struct SysemuCPUOps mb_sysemu_ops = {
static const struct TCGCPUOps mb_tcg_ops = { static const struct TCGCPUOps mb_tcg_ops = {
.initialize = mb_tcg_init, .initialize = mb_tcg_init,
.synchronize_from_tb = mb_cpu_synchronize_from_tb, .synchronize_from_tb = mb_cpu_synchronize_from_tb,
.cpu_exec_interrupt = mb_cpu_exec_interrupt,
.tlb_fill = mb_cpu_tlb_fill, .tlb_fill = mb_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = mb_cpu_exec_interrupt,
.do_interrupt = mb_cpu_do_interrupt, .do_interrupt = mb_cpu_do_interrupt,
.do_transaction_failed = mb_cpu_transaction_failed, .do_transaction_failed = mb_cpu_transaction_failed,
.do_unaligned_access = mb_cpu_do_unaligned_access, .do_unaligned_access = mb_cpu_do_unaligned_access,

View File

@ -355,8 +355,10 @@ struct MicroBlazeCPU {
}; };
#ifndef CONFIG_USER_ONLY
void mb_cpu_do_interrupt(CPUState *cs); void mb_cpu_do_interrupt(CPUState *cs);
bool mb_cpu_exec_interrupt(CPUState *cs, int int_req); bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
#endif /* !CONFIG_USER_ONLY */
void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
MMUAccessType access_type, MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr); int mmu_idx, uintptr_t retaddr);

View File

@ -26,16 +26,6 @@
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
void mb_cpu_do_interrupt(CPUState *cs)
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
CPUMBState *env = &cpu->env;
cs->exception_index = -1;
env->res_addr = RES_ADDR_NONE;
env->regs[14] = env->pc;
}
bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx, MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr) bool probe, uintptr_t retaddr)
@ -271,7 +261,6 @@ hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
return paddr; return paddr;
} }
#endif
bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
@ -289,6 +278,8 @@ bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */
void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr, void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type, MMUAccessType access_type,
int mmu_idx, uintptr_t retaddr) int mmu_idx, uintptr_t retaddr)

View File

@ -539,10 +539,10 @@ static const struct SysemuCPUOps mips_sysemu_ops = {
static const struct TCGCPUOps mips_tcg_ops = { static const struct TCGCPUOps mips_tcg_ops = {
.initialize = mips_tcg_init, .initialize = mips_tcg_init,
.synchronize_from_tb = mips_cpu_synchronize_from_tb, .synchronize_from_tb = mips_cpu_synchronize_from_tb,
.cpu_exec_interrupt = mips_cpu_exec_interrupt,
.tlb_fill = mips_cpu_tlb_fill, .tlb_fill = mips_cpu_tlb_fill,
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
.cpu_exec_interrupt = mips_cpu_exec_interrupt,
.do_interrupt = mips_cpu_do_interrupt, .do_interrupt = mips_cpu_do_interrupt,
.do_transaction_failed = mips_cpu_do_transaction_failed, .do_transaction_failed = mips_cpu_do_transaction_failed,
.do_unaligned_access = mips_cpu_do_unaligned_access, .do_unaligned_access = mips_cpu_do_unaligned_access,

View File

@ -86,24 +86,6 @@ void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb)
env->hflags |= tb->flags & MIPS_HFLAG_BMASK; env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
} }
bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
if (interrupt_request & CPU_INTERRUPT_HARD) {
MIPSCPU *cpu = MIPS_CPU(cs);
CPUMIPSState *env = &cpu->env;
if (cpu_mips_hw_interrupts_enabled(env) &&
cpu_mips_hw_interrupts_pending(env)) {
/* Raise it */
cs->exception_index = EXCP_EXT_INTERRUPT;
env->error_code = 0;
mips_cpu_do_interrupt(cs);
return true;
}
}
return false;
}
static const char * const excp_names[EXCP_LAST + 1] = { static const char * const excp_names[EXCP_LAST + 1] = {
[EXCP_RESET] = "reset", [EXCP_RESET] = "reset",
[EXCP_SRESET] = "soft reset", [EXCP_SRESET] = "soft reset",

View File

@ -1627,7 +1627,7 @@ static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
uint32_t op, minor, minor2, mips32_op; uint32_t op, minor, minor2, mips32_op;
uint32_t cond, fmt, cc; uint32_t cond, fmt, cc;
insn = translator_lduw(env, ctx->base.pc_next + 2); insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
ctx->opcode = (ctx->opcode << 16) | insn; ctx->opcode = (ctx->opcode << 16) | insn;
rt = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 21) & 0x1f;

View File

@ -455,7 +455,7 @@ static void decode_i64_mips16(DisasContext *ctx,
static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx) static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
{ {
int extend = translator_lduw(env, ctx->base.pc_next + 2); int extend = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
int op, rx, ry, funct, sa; int op, rx, ry, funct, sa;
int16_t imm, offset; int16_t imm, offset;
@ -688,7 +688,7 @@ static int decode_ase_mips16e(CPUMIPSState *env, DisasContext *ctx)
/* No delay slot, so just process as a normal instruction */ /* No delay slot, so just process as a normal instruction */
break; break;
case M16_OPC_JAL: case M16_OPC_JAL:
offset = translator_lduw(env, ctx->base.pc_next + 2); offset = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
offset = (((ctx->opcode & 0x1f) << 21) offset = (((ctx->opcode & 0x1f) << 21)
| ((ctx->opcode >> 5) & 0x1f) << 16 | ((ctx->opcode >> 5) & 0x1f) << 16
| offset) << 2; | offset) << 2;

View File

@ -3656,7 +3656,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
int offset; int offset;
int imm; int imm;
insn = translator_lduw(env, ctx->base.pc_next + 2); insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 2);
ctx->opcode = (ctx->opcode << 16) | insn; ctx->opcode = (ctx->opcode << 16) | insn;
rt = extract32(ctx->opcode, 21, 5); rt = extract32(ctx->opcode, 21, 5);
@ -3775,7 +3775,7 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
break; break;
case NM_P48I: case NM_P48I:
{ {
insn = translator_lduw(env, ctx->base.pc_next + 4); insn = translator_lduw(env, &ctx->base, ctx->base.pc_next + 4);
target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16; target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
switch (extract32(ctx->opcode, 16, 5)) { switch (extract32(ctx->opcode, 16, 5)) {
case NM_LI48: case NM_LI48:

View File

@ -1339,6 +1339,24 @@ void mips_cpu_do_interrupt(CPUState *cs)
cs->exception_index = EXCP_NONE; cs->exception_index = EXCP_NONE;
} }
bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
if (interrupt_request & CPU_INTERRUPT_HARD) {
MIPSCPU *cpu = MIPS_CPU(cs);
CPUMIPSState *env = &cpu->env;
if (cpu_mips_hw_interrupts_enabled(env) &&
cpu_mips_hw_interrupts_pending(env)) {
/* Raise it */
cs->exception_index = EXCP_EXT_INTERRUPT;
env->error_code = 0;
mips_cpu_do_interrupt(cs);
return true;
}
}
return false;
}
void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra) void r4k_invalidate_tlb(CPUMIPSState *env, int idx, int use_extra)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);

View File

@ -18,8 +18,6 @@
void mips_tcg_init(void); void mips_tcg_init(void);
void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb); void mips_cpu_synchronize_from_tb(CPUState *cs, const TranslationBlock *tb);
void mips_cpu_do_interrupt(CPUState *cpu);
bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx, MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr); bool probe, uintptr_t retaddr);
@ -41,6 +39,9 @@ static inline void QEMU_NORETURN do_raise_exception(CPUMIPSState *env,
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
void mips_cpu_do_interrupt(CPUState *cpu);
bool mips_cpu_exec_interrupt(CPUState *cpu, int int_req);
void mmu_init(CPUMIPSState *env, const mips_def_t *def); void mmu_init(CPUMIPSState *env, const mips_def_t *def);
void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask); void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask);

View File

@ -16041,17 +16041,17 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
is_slot = ctx->hflags & MIPS_HFLAG_BMASK; is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
if (ctx->insn_flags & ISA_NANOMIPS32) { if (ctx->insn_flags & ISA_NANOMIPS32) {
ctx->opcode = translator_lduw(env, ctx->base.pc_next); ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
insn_bytes = decode_isa_nanomips(env, ctx); insn_bytes = decode_isa_nanomips(env, ctx);
} else if (!(ctx->hflags & MIPS_HFLAG_M16)) { } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
ctx->opcode = translator_ldl(env, ctx->base.pc_next); ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
insn_bytes = 4; insn_bytes = 4;
decode_opc(env, ctx); decode_opc(env, ctx);
} else if (ctx->insn_flags & ASE_MICROMIPS) { } else if (ctx->insn_flags & ASE_MICROMIPS) {
ctx->opcode = translator_lduw(env, ctx->base.pc_next); ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
insn_bytes = decode_isa_micromips(env, ctx); insn_bytes = decode_isa_micromips(env, ctx);
} else if (ctx->insn_flags & ASE_MIPS16) { } else if (ctx->insn_flags & ASE_MIPS16) {
ctx->opcode = translator_lduw(env, ctx->base.pc_next); ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
insn_bytes = decode_ase_mips16e(env, ctx); insn_bytes = decode_ase_mips16e(env, ctx);
} else { } else {
gen_reserved_instruction(ctx); gen_reserved_instruction(ctx);

View File

@ -57,8 +57,3 @@ bool mips_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
raise_mmu_exception(env, address, access_type); raise_mmu_exception(env, address, access_type);
do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr); do_raise_exception_err(env, cs->exception_index, env->error_code, retaddr);
} }
void mips_cpu_do_interrupt(CPUState *cs)
{
cs->exception_index = EXCP_NONE;
}

View File

@ -127,6 +127,7 @@ static void nios2_cpu_realizefn(DeviceState *dev, Error **errp)
ncc->parent_realize(dev, errp); ncc->parent_realize(dev, errp);
} }
#ifndef CONFIG_USER_ONLY
static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request) static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
Nios2CPU *cpu = NIOS2_CPU(cs); Nios2CPU *cpu = NIOS2_CPU(cs);
@ -140,7 +141,7 @@ static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
} }
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */
static void nios2_cpu_disas_set_info(CPUState *cpu, disassemble_info *info) static void nios2_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
{ {
@ -219,10 +220,10 @@ static const struct SysemuCPUOps nios2_sysemu_ops = {
static const struct TCGCPUOps nios2_tcg_ops = { static const struct TCGCPUOps nios2_tcg_ops = {
.initialize = nios2_tcg_init, .initialize = nios2_tcg_init,
.cpu_exec_interrupt = nios2_cpu_exec_interrupt,
.tlb_fill = nios2_cpu_tlb_fill, .tlb_fill = nios2_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = nios2_cpu_exec_interrupt,
.do_interrupt = nios2_cpu_do_interrupt, .do_interrupt = nios2_cpu_do_interrupt,
.do_unaligned_access = nios2_cpu_do_unaligned_access, .do_unaligned_access = nios2_cpu_do_unaligned_access,
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */

View File

@ -186,10 +186,10 @@ static const struct SysemuCPUOps openrisc_sysemu_ops = {
static const struct TCGCPUOps openrisc_tcg_ops = { static const struct TCGCPUOps openrisc_tcg_ops = {
.initialize = openrisc_translate_init, .initialize = openrisc_translate_init,
.cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
.tlb_fill = openrisc_cpu_tlb_fill, .tlb_fill = openrisc_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = openrisc_cpu_exec_interrupt,
.do_interrupt = openrisc_cpu_do_interrupt, .do_interrupt = openrisc_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */
}; };

View File

@ -312,8 +312,6 @@ struct OpenRISCCPU {
void cpu_openrisc_list(void); void cpu_openrisc_list(void);
void openrisc_cpu_do_interrupt(CPUState *cpu);
bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); void openrisc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int openrisc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
@ -331,6 +329,9 @@ int print_insn_or1k(bfd_vma addr, disassemble_info *info);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
extern const VMStateDescription vmstate_openrisc_cpu; extern const VMStateDescription vmstate_openrisc_cpu;
void openrisc_cpu_do_interrupt(CPUState *cpu);
bool openrisc_cpu_exec_interrupt(CPUState *cpu, int int_req);
/* hw/openrisc_pic.c */ /* hw/openrisc_pic.c */
void cpu_openrisc_pic_init(OpenRISCCPU *cpu); void cpu_openrisc_pic_init(OpenRISCCPU *cpu);

View File

@ -28,7 +28,6 @@
void openrisc_cpu_do_interrupt(CPUState *cs) void openrisc_cpu_do_interrupt(CPUState *cs)
{ {
#ifndef CONFIG_USER_ONLY
OpenRISCCPU *cpu = OPENRISC_CPU(cs); OpenRISCCPU *cpu = OPENRISC_CPU(cs);
CPUOpenRISCState *env = &cpu->env; CPUOpenRISCState *env = &cpu->env;
int exception = cs->exception_index; int exception = cs->exception_index;
@ -96,7 +95,6 @@ void openrisc_cpu_do_interrupt(CPUState *cs)
} else { } else {
cpu_abort(cs, "Unhandled exception 0x%x\n", exception); cpu_abort(cs, "Unhandled exception 0x%x\n", exception);
} }
#endif
cs->exception_index = -1; cs->exception_index = -1;
} }

View File

@ -9,7 +9,6 @@ openrisc_ss.add(files(
'exception_helper.c', 'exception_helper.c',
'fpu_helper.c', 'fpu_helper.c',
'gdbstub.c', 'gdbstub.c',
'interrupt.c',
'interrupt_helper.c', 'interrupt_helper.c',
'mmu.c', 'mmu.c',
'sys_helper.c', 'sys_helper.c',
@ -17,7 +16,10 @@ openrisc_ss.add(files(
)) ))
openrisc_softmmu_ss = ss.source_set() openrisc_softmmu_ss = ss.source_set()
openrisc_softmmu_ss.add(files('machine.c')) openrisc_softmmu_ss.add(files(
'interrupt.c',
'machine.c',
))
target_arch += {'openrisc': openrisc_ss} target_arch += {'openrisc': openrisc_ss}
target_softmmu_arch += {'openrisc': openrisc_softmmu_ss} target_softmmu_arch += {'openrisc': openrisc_softmmu_ss}

View File

@ -1613,7 +1613,7 @@ static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
{ {
DisasContext *dc = container_of(dcbase, DisasContext, base); DisasContext *dc = container_of(dcbase, DisasContext, base);
OpenRISCCPU *cpu = OPENRISC_CPU(cs); OpenRISCCPU *cpu = OPENRISC_CPU(cs);
uint32_t insn = translator_ldl(&cpu->env, dc->base.pc_next); uint32_t insn = translator_ldl(&cpu->env, &dc->base, dc->base.pc_next);
if (!decode(dc, insn)) { if (!decode(dc, insn)) {
gen_illegal_exception(dc); gen_illegal_exception(dc);

View File

@ -1254,8 +1254,6 @@ DECLARE_OBJ_CHECKERS(PPCVirtualHypervisor, PPCVirtualHypervisorClass,
PPC_VIRTUAL_HYPERVISOR, TYPE_PPC_VIRTUAL_HYPERVISOR) PPC_VIRTUAL_HYPERVISOR, TYPE_PPC_VIRTUAL_HYPERVISOR)
#endif /* CONFIG_USER_ONLY */ #endif /* CONFIG_USER_ONLY */
void ppc_cpu_do_interrupt(CPUState *cpu);
bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags); void ppc_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int ppc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int ppc_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
@ -1271,6 +1269,8 @@ int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs, int ppc32_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
int cpuid, void *opaque); int cpuid, void *opaque);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
void ppc_cpu_do_interrupt(CPUState *cpu);
bool ppc_cpu_exec_interrupt(CPUState *cpu, int int_req);
void ppc_cpu_do_system_reset(CPUState *cs); void ppc_cpu_do_system_reset(CPUState *cs);
void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector); void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector);
extern const VMStateDescription vmstate_ppc_cpu; extern const VMStateDescription vmstate_ppc_cpu;

View File

@ -9014,10 +9014,10 @@ static const struct SysemuCPUOps ppc_sysemu_ops = {
static const struct TCGCPUOps ppc_tcg_ops = { static const struct TCGCPUOps ppc_tcg_ops = {
.initialize = ppc_translate_init, .initialize = ppc_translate_init,
.cpu_exec_interrupt = ppc_cpu_exec_interrupt,
.tlb_fill = ppc_cpu_tlb_fill, .tlb_fill = ppc_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = ppc_cpu_exec_interrupt,
.do_interrupt = ppc_cpu_do_interrupt, .do_interrupt = ppc_cpu_do_interrupt,
.cpu_exec_enter = ppc_cpu_exec_enter, .cpu_exec_enter = ppc_cpu_exec_enter,
.cpu_exec_exit = ppc_cpu_exec_exit, .cpu_exec_exit = ppc_cpu_exec_exit,

View File

@ -40,24 +40,8 @@
/*****************************************************************************/ /*****************************************************************************/
/* Exception processing */ /* Exception processing */
#if defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
void ppc_cpu_do_interrupt(CPUState *cs)
{
PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env;
cs->exception_index = POWERPC_EXCP_NONE;
env->error_code = 0;
}
static void ppc_hw_interrupt(CPUPPCState *env)
{
CPUState *cs = env_cpu(env);
cs->exception_index = POWERPC_EXCP_NONE;
env->error_code = 0;
}
#else /* defined(CONFIG_USER_ONLY) */
static inline void dump_syscall(CPUPPCState *env) static inline void dump_syscall(CPUPPCState *env)
{ {
qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64 qemu_log_mask(CPU_LOG_INT, "syscall r0=%016" PRIx64
@ -1113,7 +1097,6 @@ void ppc_cpu_do_fwnmi_machine_check(CPUState *cs, target_ulong vector)
powerpc_set_excp_state(cpu, vector, msr); powerpc_set_excp_state(cpu, vector, msr);
} }
#endif /* !CONFIG_USER_ONLY */
bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
@ -1130,6 +1113,8 @@ bool ppc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */
#if defined(DEBUG_OP) #if defined(DEBUG_OP)
static void cpu_dump_rfi(target_ulong RA, target_ulong msr) static void cpu_dump_rfi(target_ulong RA, target_ulong msr)
{ {

View File

@ -8585,7 +8585,7 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
ctx->base.pc_next, ctx->mem_idx, (int)msr_ir); ctx->base.pc_next, ctx->mem_idx, (int)msr_ir);
ctx->cia = pc = ctx->base.pc_next; ctx->cia = pc = ctx->base.pc_next;
insn = translator_ldl_swap(env, pc, need_byteswap(ctx)); insn = translator_ldl_swap(env, dcbase, pc, need_byteswap(ctx));
ctx->base.pc_next = pc += 4; ctx->base.pc_next = pc += 4;
if (!is_prefix_insn(ctx, insn)) { if (!is_prefix_insn(ctx, insn)) {
@ -8600,7 +8600,8 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_INSN); gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_INSN);
ok = true; ok = true;
} else { } else {
uint32_t insn2 = translator_ldl_swap(env, pc, need_byteswap(ctx)); uint32_t insn2 = translator_ldl_swap(env, dcbase, pc,
need_byteswap(ctx));
ctx->base.pc_next = pc += 4; ctx->base.pc_next = pc += 4;
ok = decode_insn64(ctx, deposit64(insn2, 32, 32, insn)); ok = decode_insn64(ctx, deposit64(insn2, 32, 32, insn));
} }

View File

@ -644,10 +644,10 @@ static const struct SysemuCPUOps riscv_sysemu_ops = {
static const struct TCGCPUOps riscv_tcg_ops = { static const struct TCGCPUOps riscv_tcg_ops = {
.initialize = riscv_translate_init, .initialize = riscv_translate_init,
.synchronize_from_tb = riscv_cpu_synchronize_from_tb, .synchronize_from_tb = riscv_cpu_synchronize_from_tb,
.cpu_exec_interrupt = riscv_cpu_exec_interrupt,
.tlb_fill = riscv_cpu_tlb_fill, .tlb_fill = riscv_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = riscv_cpu_exec_interrupt,
.do_interrupt = riscv_cpu_do_interrupt, .do_interrupt = riscv_cpu_do_interrupt,
.do_transaction_failed = riscv_cpu_do_transaction_failed, .do_transaction_failed = riscv_cpu_do_transaction_failed,
.do_unaligned_access = riscv_cpu_do_unaligned_access, .do_unaligned_access = riscv_cpu_do_unaligned_access,

View File

@ -334,7 +334,6 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, CPUState *cs,
int cpuid, void *opaque); int cpuid, void *opaque);
int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
bool riscv_cpu_fp_enabled(CPURISCVState *env); bool riscv_cpu_fp_enabled(CPURISCVState *env);
bool riscv_cpu_virt_enabled(CPURISCVState *env); bool riscv_cpu_virt_enabled(CPURISCVState *env);
void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable); void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
@ -362,6 +361,7 @@ void riscv_cpu_list(void);
#define cpu_mmu_index riscv_cpu_mmu_index #define cpu_mmu_index riscv_cpu_mmu_index
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request);
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env); void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts); int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value); uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);

View File

@ -75,11 +75,9 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
return RISCV_EXCP_NONE; /* indicates no pending interrupt */ return RISCV_EXCP_NONE; /* indicates no pending interrupt */
} }
} }
#endif
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
#if !defined(CONFIG_USER_ONLY)
if (interrupt_request & CPU_INTERRUPT_HARD) { if (interrupt_request & CPU_INTERRUPT_HARD) {
RISCVCPU *cpu = RISCV_CPU(cs); RISCVCPU *cpu = RISCV_CPU(cs);
CPURISCVState *env = &cpu->env; CPURISCVState *env = &cpu->env;
@ -90,12 +88,9 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return true; return true;
} }
} }
#endif
return false; return false;
} }
#if !defined(CONFIG_USER_ONLY)
/* Return true is floating point support is currently enabled */ /* Return true is floating point support is currently enabled */
bool riscv_cpu_fp_enabled(CPURISCVState *env) bool riscv_cpu_fp_enabled(CPURISCVState *env)
{ {

View File

@ -500,7 +500,8 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
} else { } else {
uint32_t opcode32 = opcode; uint32_t opcode32 = opcode;
opcode32 = deposit32(opcode32, 16, 16, opcode32 = deposit32(opcode32, 16, 16,
translator_lduw(env, ctx->base.pc_next + 2)); translator_lduw(env, &ctx->base,
ctx->base.pc_next + 2));
ctx->pc_succ_insn = ctx->base.pc_next + 4; ctx->pc_succ_insn = ctx->base.pc_next + 4;
if (!decode_insn32(ctx, opcode32)) { if (!decode_insn32(ctx, opcode32)) {
gen_exception_illegal(ctx); gen_exception_illegal(ctx);
@ -561,7 +562,7 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
{ {
DisasContext *ctx = container_of(dcbase, DisasContext, base); DisasContext *ctx = container_of(dcbase, DisasContext, base);
CPURISCVState *env = cpu->env_ptr; CPURISCVState *env = cpu->env_ptr;
uint16_t opcode16 = translator_lduw(env, ctx->base.pc_next); uint16_t opcode16 = translator_lduw(env, &ctx->base, ctx->base.pc_next);
decode_opc(env, ctx, opcode16); decode_opc(env, ctx, opcode16);
ctx->base.pc_next = ctx->pc_succ_insn; ctx->base.pc_next = ctx->pc_succ_insn;

View File

@ -186,10 +186,10 @@ static const struct SysemuCPUOps rx_sysemu_ops = {
static const struct TCGCPUOps rx_tcg_ops = { static const struct TCGCPUOps rx_tcg_ops = {
.initialize = rx_translate_init, .initialize = rx_translate_init,
.synchronize_from_tb = rx_cpu_synchronize_from_tb, .synchronize_from_tb = rx_cpu_synchronize_from_tb,
.cpu_exec_interrupt = rx_cpu_exec_interrupt,
.tlb_fill = rx_cpu_tlb_fill, .tlb_fill = rx_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = rx_cpu_exec_interrupt,
.do_interrupt = rx_cpu_do_interrupt, .do_interrupt = rx_cpu_do_interrupt,
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */
}; };

View File

@ -124,8 +124,10 @@ typedef RXCPU ArchCPU;
#define CPU_RESOLVING_TYPE TYPE_RX_CPU #define CPU_RESOLVING_TYPE TYPE_RX_CPU
const char *rx_crname(uint8_t cr); const char *rx_crname(uint8_t cr);
#ifndef CONFIG_USER_ONLY
void rx_cpu_do_interrupt(CPUState *cpu); void rx_cpu_do_interrupt(CPUState *cpu);
bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req); bool rx_cpu_exec_interrupt(CPUState *cpu, int int_req);
#endif /* !CONFIG_USER_ONLY */
void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags); void rx_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int rx_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);

View File

@ -40,6 +40,8 @@ void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte)
env->psw_c = FIELD_EX32(psw, PSW, C); env->psw_c = FIELD_EX32(psw, PSW, C);
} }
#ifndef CONFIG_USER_ONLY
#define INT_FLAGS (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR) #define INT_FLAGS (CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIR)
void rx_cpu_do_interrupt(CPUState *cs) void rx_cpu_do_interrupt(CPUState *cs)
{ {
@ -142,6 +144,8 @@ bool rx_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */
hwaddr rx_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) hwaddr rx_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{ {
return addr; return addr;

View File

@ -388,14 +388,16 @@ static void update_cc_op(DisasContext *s)
} }
} }
static inline uint64_t ld_code2(CPUS390XState *env, uint64_t pc) static inline uint64_t ld_code2(CPUS390XState *env, DisasContext *s,
uint64_t pc)
{ {
return (uint64_t)cpu_lduw_code(env, pc); return (uint64_t)translator_lduw(env, &s->base, pc);
} }
static inline uint64_t ld_code4(CPUS390XState *env, uint64_t pc) static inline uint64_t ld_code4(CPUS390XState *env, DisasContext *s,
uint64_t pc)
{ {
return (uint64_t)(uint32_t)cpu_ldl_code(env, pc); return (uint64_t)(uint32_t)translator_ldl(env, &s->base, pc);
} }
static int get_mem_index(DisasContext *s) static int get_mem_index(DisasContext *s)
@ -6273,7 +6275,7 @@ static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s)
ilen = s->ex_value & 0xf; ilen = s->ex_value & 0xf;
op = insn >> 56; op = insn >> 56;
} else { } else {
insn = ld_code2(env, pc); insn = ld_code2(env, s, pc);
op = (insn >> 8) & 0xff; op = (insn >> 8) & 0xff;
ilen = get_ilen(op); ilen = get_ilen(op);
switch (ilen) { switch (ilen) {
@ -6281,10 +6283,10 @@ static const DisasInsn *extract_insn(CPUS390XState *env, DisasContext *s)
insn = insn << 48; insn = insn << 48;
break; break;
case 4: case 4:
insn = ld_code4(env, pc) << 32; insn = ld_code4(env, s, pc) << 32;
break; break;
case 6: case 6:
insn = (insn << 48) | (ld_code4(env, pc + 2) << 16); insn = (insn << 48) | (ld_code4(env, s, pc + 2) << 16);
break; break;
default: default:
g_assert_not_reached(); g_assert_not_reached();

View File

@ -236,10 +236,10 @@ static const struct SysemuCPUOps sh4_sysemu_ops = {
static const struct TCGCPUOps superh_tcg_ops = { static const struct TCGCPUOps superh_tcg_ops = {
.initialize = sh4_translate_init, .initialize = sh4_translate_init,
.synchronize_from_tb = superh_cpu_synchronize_from_tb, .synchronize_from_tb = superh_cpu_synchronize_from_tb,
.cpu_exec_interrupt = superh_cpu_exec_interrupt,
.tlb_fill = superh_cpu_tlb_fill, .tlb_fill = superh_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = superh_cpu_exec_interrupt,
.do_interrupt = superh_cpu_do_interrupt, .do_interrupt = superh_cpu_do_interrupt,
.do_unaligned_access = superh_cpu_do_unaligned_access, .do_unaligned_access = superh_cpu_do_unaligned_access,
.io_recompile_replay_branch = superh_io_recompile_replay_branch, .io_recompile_replay_branch = superh_io_recompile_replay_branch,

View File

@ -204,8 +204,6 @@ struct SuperHCPU {
}; };
void superh_cpu_do_interrupt(CPUState *cpu);
bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags); void superh_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); hwaddr superh_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int superh_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int superh_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
@ -223,6 +221,8 @@ bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
void sh4_cpu_list(void); void sh4_cpu_list(void);
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
void superh_cpu_do_interrupt(CPUState *cpu);
bool superh_cpu_exec_interrupt(CPUState *cpu, int int_req);
void cpu_sh4_invalidate_tlb(CPUSH4State *s); void cpu_sh4_invalidate_tlb(CPUSH4State *s);
uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSH4State *s, uint32_t cpu_sh4_read_mmaped_itlb_addr(CPUSH4State *s,
hwaddr addr); hwaddr addr);

View File

@ -45,11 +45,6 @@
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
void superh_cpu_do_interrupt(CPUState *cs)
{
cs->exception_index = -1;
}
int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr) int cpu_sh4_is_cached(CPUSH4State *env, target_ulong addr)
{ {
/* For user mode, only U0 area is cacheable. */ /* For user mode, only U0 area is cacheable. */
@ -784,8 +779,6 @@ int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
return 0; return 0;
} }
#endif
bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
if (interrupt_request & CPU_INTERRUPT_HARD) { if (interrupt_request & CPU_INTERRUPT_HARD) {
@ -803,6 +796,8 @@ bool superh_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */
bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx, MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr) bool probe, uintptr_t retaddr)

View File

@ -1907,7 +1907,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
/* Read all of the insns for the region. */ /* Read all of the insns for the region. */
for (i = 0; i < max_insns; ++i) { for (i = 0; i < max_insns; ++i) {
insns[i] = translator_lduw(env, pc + i * 2); insns[i] = translator_lduw(env, &ctx->base, pc + i * 2);
} }
ld_adr = ld_dst = ld_mop = -1; ld_adr = ld_dst = ld_mop = -1;
@ -2307,7 +2307,7 @@ static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
} }
#endif #endif
ctx->opcode = translator_lduw(env, ctx->base.pc_next); ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
decode_opc(ctx); decode_opc(ctx);
ctx->base.pc_next += 2; ctx->base.pc_next += 2;
} }

View File

@ -77,6 +77,7 @@ static void sparc_cpu_reset(DeviceState *dev)
env->cache_control = 0; env->cache_control = 0;
} }
#ifndef CONFIG_USER_ONLY
static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request) static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
if (interrupt_request & CPU_INTERRUPT_HARD) { if (interrupt_request & CPU_INTERRUPT_HARD) {
@ -96,6 +97,7 @@ static bool sparc_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
} }
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */
static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info) static void cpu_sparc_disas_set_info(CPUState *cpu, disassemble_info *info)
{ {
@ -863,10 +865,10 @@ static const struct SysemuCPUOps sparc_sysemu_ops = {
static const struct TCGCPUOps sparc_tcg_ops = { static const struct TCGCPUOps sparc_tcg_ops = {
.initialize = sparc_tcg_init, .initialize = sparc_tcg_init,
.synchronize_from_tb = sparc_cpu_synchronize_from_tb, .synchronize_from_tb = sparc_cpu_synchronize_from_tb,
.cpu_exec_interrupt = sparc_cpu_exec_interrupt,
.tlb_fill = sparc_cpu_tlb_fill, .tlb_fill = sparc_cpu_tlb_fill,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = sparc_cpu_exec_interrupt,
.do_interrupt = sparc_cpu_do_interrupt, .do_interrupt = sparc_cpu_do_interrupt,
.do_transaction_failed = sparc_cpu_do_transaction_failed, .do_transaction_failed = sparc_cpu_do_transaction_failed,
.do_unaligned_access = sparc_cpu_do_unaligned_access, .do_unaligned_access = sparc_cpu_do_unaligned_access,

View File

@ -5855,7 +5855,7 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
CPUSPARCState *env = cs->env_ptr; CPUSPARCState *env = cs->env_ptr;
unsigned int insn; unsigned int insn;
insn = translator_ldl(env, dc->pc); insn = translator_ldl(env, &dc->base, dc->pc);
dc->base.pc_next += 4; dc->base.pc_next += 4;
disas_sparc_insn(dc, insn); disas_sparc_insn(dc, insn);

View File

@ -192,11 +192,11 @@ static const struct SysemuCPUOps xtensa_sysemu_ops = {
static const struct TCGCPUOps xtensa_tcg_ops = { static const struct TCGCPUOps xtensa_tcg_ops = {
.initialize = xtensa_translate_init, .initialize = xtensa_translate_init,
.cpu_exec_interrupt = xtensa_cpu_exec_interrupt,
.tlb_fill = xtensa_cpu_tlb_fill, .tlb_fill = xtensa_cpu_tlb_fill,
.debug_excp_handler = xtensa_breakpoint_handler, .debug_excp_handler = xtensa_breakpoint_handler,
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
.cpu_exec_interrupt = xtensa_cpu_exec_interrupt,
.do_interrupt = xtensa_cpu_do_interrupt, .do_interrupt = xtensa_cpu_do_interrupt,
.do_transaction_failed = xtensa_cpu_do_transaction_failed, .do_transaction_failed = xtensa_cpu_do_transaction_failed,
.do_unaligned_access = xtensa_cpu_do_unaligned_access, .do_unaligned_access = xtensa_cpu_do_unaligned_access,

View File

@ -566,12 +566,14 @@ struct XtensaCPU {
bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size, bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx, MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr); bool probe, uintptr_t retaddr);
#ifndef CONFIG_USER_ONLY
void xtensa_cpu_do_interrupt(CPUState *cpu); void xtensa_cpu_do_interrupt(CPUState *cpu);
bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request); bool xtensa_cpu_exec_interrupt(CPUState *cpu, int interrupt_request);
void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
unsigned size, MMUAccessType access_type, unsigned size, MMUAccessType access_type,
int mmu_idx, MemTxAttrs attrs, int mmu_idx, MemTxAttrs attrs,
MemTxResult response, uintptr_t retaddr); MemTxResult response, uintptr_t retaddr);
#endif
void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, int flags); void xtensa_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); hwaddr xtensa_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
void xtensa_count_regs(const XtensaConfig *config, void xtensa_count_regs(const XtensaConfig *config,

View File

@ -255,11 +255,6 @@ void xtensa_cpu_do_interrupt(CPUState *cs)
} }
check_interrupts(env); check_interrupts(env);
} }
#else
void xtensa_cpu_do_interrupt(CPUState *cs)
{
}
#endif
bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request) bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{ {
@ -270,3 +265,5 @@ bool xtensa_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
} }
return false; return false;
} }
#endif /* !CONFIG_USER_ONLY */

View File

@ -882,7 +882,8 @@ static int arg_copy_compare(const void *a, const void *b)
static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc) static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
{ {
xtensa_isa isa = dc->config->isa; xtensa_isa isa = dc->config->isa;
unsigned char b[MAX_INSN_LENGTH] = {translator_ldub(env, dc->pc)}; unsigned char b[MAX_INSN_LENGTH] = {translator_ldub(env, &dc->base,
dc->pc)};
unsigned len = xtensa_op0_insn_len(dc, b[0]); unsigned len = xtensa_op0_insn_len(dc, b[0]);
xtensa_format fmt; xtensa_format fmt;
int slot, slots; int slot, slots;
@ -907,7 +908,7 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
dc->base.pc_next = dc->pc + len; dc->base.pc_next = dc->pc + len;
for (i = 1; i < len; ++i) { for (i = 1; i < len; ++i) {
b[i] = translator_ldub(env, dc->pc + i); b[i] = translator_ldub(env, &dc->base, dc->pc + i);
} }
xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len); xtensa_insnbuf_from_chars(isa, dc->insnbuf, b, len);
fmt = xtensa_format_decode(isa, dc->insnbuf); fmt = xtensa_format_decode(isa, dc->insnbuf);

File diff suppressed because it is too large Load Diff

View File

@ -26,34 +26,9 @@
#ifndef ARM_TCG_TARGET_H #ifndef ARM_TCG_TARGET_H
#define ARM_TCG_TARGET_H #define ARM_TCG_TARGET_H
/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
#ifndef __ARM_ARCH
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|| defined(__ARM_ARCH_7EM__)
# define __ARM_ARCH 7
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|| defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
# define __ARM_ARCH 6
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5E__) \
|| defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
|| defined(__ARM_ARCH_5TEJ__)
# define __ARM_ARCH 5
# else
# define __ARM_ARCH 4
# endif
#endif
extern int arm_arch; extern int arm_arch;
#if defined(__ARM_ARCH_5T__) \ #define use_armv5t_instructions (__ARM_ARCH >= 5 || arm_arch >= 5)
|| defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
# define use_armv5t_instructions 1
#else
# define use_armv5t_instructions use_armv6_instructions
#endif
#define use_armv6_instructions (__ARM_ARCH >= 6 || arm_arch >= 6) #define use_armv6_instructions (__ARM_ARCH >= 6 || arm_arch >= 6)
#define use_armv7_instructions (__ARM_ARCH >= 7 || arm_arch >= 7) #define use_armv7_instructions (__ARM_ARCH >= 7 || arm_arch >= 7)

View File

@ -241,8 +241,9 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
#define P_EXT 0x100 /* 0x0f opcode prefix */ #define P_EXT 0x100 /* 0x0f opcode prefix */
#define P_EXT38 0x200 /* 0x0f 0x38 opcode prefix */ #define P_EXT38 0x200 /* 0x0f 0x38 opcode prefix */
#define P_DATA16 0x400 /* 0x66 opcode prefix */ #define P_DATA16 0x400 /* 0x66 opcode prefix */
#define P_VEXW 0x1000 /* Set VEX.W = 1 */
#if TCG_TARGET_REG_BITS == 64 #if TCG_TARGET_REG_BITS == 64
# define P_REXW 0x1000 /* Set REX.W = 1 */ # define P_REXW P_VEXW /* Set REX.W = 1; match VEXW */
# define P_REXB_R 0x2000 /* REG field as byte register */ # define P_REXB_R 0x2000 /* REG field as byte register */
# define P_REXB_RM 0x4000 /* R/M field as byte register */ # define P_REXB_RM 0x4000 /* R/M field as byte register */
# define P_GS 0x8000 /* gs segment override */ # define P_GS 0x8000 /* gs segment override */
@ -410,13 +411,13 @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
#define OPC_VPBROADCASTW (0x79 | P_EXT38 | P_DATA16) #define OPC_VPBROADCASTW (0x79 | P_EXT38 | P_DATA16)
#define OPC_VPBROADCASTD (0x58 | P_EXT38 | P_DATA16) #define OPC_VPBROADCASTD (0x58 | P_EXT38 | P_DATA16)
#define OPC_VPBROADCASTQ (0x59 | P_EXT38 | P_DATA16) #define OPC_VPBROADCASTQ (0x59 | P_EXT38 | P_DATA16)
#define OPC_VPERMQ (0x00 | P_EXT3A | P_DATA16 | P_REXW) #define OPC_VPERMQ (0x00 | P_EXT3A | P_DATA16 | P_VEXW)
#define OPC_VPERM2I128 (0x46 | P_EXT3A | P_DATA16 | P_VEXL) #define OPC_VPERM2I128 (0x46 | P_EXT3A | P_DATA16 | P_VEXL)
#define OPC_VPSLLVD (0x47 | P_EXT38 | P_DATA16) #define OPC_VPSLLVD (0x47 | P_EXT38 | P_DATA16)
#define OPC_VPSLLVQ (0x47 | P_EXT38 | P_DATA16 | P_REXW) #define OPC_VPSLLVQ (0x47 | P_EXT38 | P_DATA16 | P_VEXW)
#define OPC_VPSRAVD (0x46 | P_EXT38 | P_DATA16) #define OPC_VPSRAVD (0x46 | P_EXT38 | P_DATA16)
#define OPC_VPSRLVD (0x45 | P_EXT38 | P_DATA16) #define OPC_VPSRLVD (0x45 | P_EXT38 | P_DATA16)
#define OPC_VPSRLVQ (0x45 | P_EXT38 | P_DATA16 | P_REXW) #define OPC_VPSRLVQ (0x45 | P_EXT38 | P_DATA16 | P_VEXW)
#define OPC_VZEROUPPER (0x77 | P_EXT) #define OPC_VZEROUPPER (0x77 | P_EXT)
#define OPC_XCHG_ax_r32 (0x90) #define OPC_XCHG_ax_r32 (0x90)
@ -576,7 +577,7 @@ static void tcg_out_vex_opc(TCGContext *s, int opc, int r, int v,
/* Use the two byte form if possible, which cannot encode /* Use the two byte form if possible, which cannot encode
VEX.W, VEX.B, VEX.X, or an m-mmmm field other than P_EXT. */ VEX.W, VEX.B, VEX.X, or an m-mmmm field other than P_EXT. */
if ((opc & (P_EXT | P_EXT38 | P_EXT3A | P_REXW)) == P_EXT if ((opc & (P_EXT | P_EXT38 | P_EXT3A | P_VEXW)) == P_EXT
&& ((rm | index) & 8) == 0) { && ((rm | index) & 8) == 0) {
/* Two byte VEX prefix. */ /* Two byte VEX prefix. */
tcg_out8(s, 0xc5); tcg_out8(s, 0xc5);
@ -601,7 +602,7 @@ static void tcg_out_vex_opc(TCGContext *s, int opc, int r, int v,
tmp |= (rm & 8 ? 0 : 0x20); /* VEX.B */ tmp |= (rm & 8 ? 0 : 0x20); /* VEX.B */
tcg_out8(s, tmp); tcg_out8(s, tmp);
tmp = (opc & P_REXW ? 0x80 : 0); /* VEX.W */ tmp = (opc & P_VEXW ? 0x80 : 0); /* VEX.W */
} }
tmp |= (opc & P_VEXL ? 0x04 : 0); /* VEX.L */ tmp |= (opc & P_VEXL ? 0x04 : 0); /* VEX.L */

View File

@ -25,9 +25,24 @@
#include "elf.h" #include "elf.h"
#include "../tcg-pool.c.inc" #include "../tcg-pool.c.inc"
#if defined _CALL_DARWIN || defined __APPLE__ /*
#define TCG_TARGET_CALL_DARWIN * Standardize on the _CALL_FOO symbols used by GCC:
#endif * Apple XCode does not define _CALL_DARWIN.
* Clang defines _CALL_ELF (64-bit) but not _CALL_SYSV (32-bit).
*/
#if !defined(_CALL_SYSV) && \
!defined(_CALL_DARWIN) && \
!defined(_CALL_AIX) && \
!defined(_CALL_ELF)
# if defined(__APPLE__)
# define _CALL_DARWIN
# elif defined(__ELF__) && TCG_TARGET_REG_BITS == 32
# define _CALL_SYSV
# else
# error "Unknown ABI"
# endif
#endif
#ifdef _CALL_SYSV #ifdef _CALL_SYSV
# define TCG_TARGET_CALL_ALIGN_ARGS 1 # define TCG_TARGET_CALL_ALIGN_ARGS 1
#endif #endif
@ -169,7 +184,7 @@ static const int tcg_target_call_oarg_regs[] = {
}; };
static const int tcg_target_callee_save_regs[] = { static const int tcg_target_callee_save_regs[] = {
#ifdef TCG_TARGET_CALL_DARWIN #ifdef _CALL_DARWIN
TCG_REG_R11, TCG_REG_R11,
#endif #endif
TCG_REG_R14, TCG_REG_R14,
@ -2372,7 +2387,7 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int count)
# define LINK_AREA_SIZE (6 * SZR) # define LINK_AREA_SIZE (6 * SZR)
# define LR_OFFSET (1 * SZR) # define LR_OFFSET (1 * SZR)
# define TCG_TARGET_CALL_STACK_OFFSET (LINK_AREA_SIZE + 8 * SZR) # define TCG_TARGET_CALL_STACK_OFFSET (LINK_AREA_SIZE + 8 * SZR)
#elif defined(TCG_TARGET_CALL_DARWIN) #elif defined(_CALL_DARWIN)
# define LINK_AREA_SIZE (6 * SZR) # define LINK_AREA_SIZE (6 * SZR)
# define LR_OFFSET (2 * SZR) # define LR_OFFSET (2 * SZR)
#elif TCG_TARGET_REG_BITS == 64 #elif TCG_TARGET_REG_BITS == 64