aboutsummaryrefslogtreecommitdiff
path: root/target/xtensa/cpu.h
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2018-08-29 10:37:29 -0700
committerMax Filippov <jcmvbkbc@gmail.com>2018-10-01 11:08:35 -0700
commit6416d16f7544c53ccb6ce7d74e8f01f502b558d3 (patch)
tree05d399b3284cdb2de815b4c60887b9031d3c0894 /target/xtensa/cpu.h
parent15477819427f5d2f0eddd4daba4159dee5f3b2ec (diff)
downloadqemu-6416d16f7544c53ccb6ce7d74e8f01f502b558d3.zip
qemu-6416d16f7544c53ccb6ce7d74e8f01f502b558d3.tar.gz
qemu-6416d16f7544c53ccb6ce7d74e8f01f502b558d3.tar.bz2
target/xtensa: extract test for window overflow exception
- add ps.callinc to the TB flags, that allows testing all instructions for window overflow statically; - drop gen_window_check* functions; replace them with get_window_check that accepts bitmask of used registers; - add XtensaOpcodeOps::test_overflow that returns bitmask of implicitly used registers; use it for entry and call{,x}{4,8,12}; - drop window overflow test from the entry helper; - drop parameter 0 from translate_[di]cache and use translate_nop for d/i cache opcodes that don't need memory accessibility check; - add bitmask XtensaOpcodeOps::windowed_register_op that marks opcode arguments that refer to windowed registers; - translate windowed_register_op mask to a mask of actually used registers in the disassembly loop; - add check for window overflow right after the check for debug exception; Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'target/xtensa/cpu.h')
-rw-r--r--target/xtensa/cpu.h9
1 files changed, 9 insertions, 0 deletions
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 0a0323f..be23495 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -351,6 +351,9 @@ typedef void (*XtensaOpcodeOp)(DisasContext *dc, const uint32_t arg[],
typedef bool (*XtensaOpcodeBoolTest)(DisasContext *dc,
const uint32_t arg[],
const uint32_t par[]);
+typedef uint32_t (*XtensaOpcodeUintTest)(DisasContext *dc,
+ const uint32_t arg[],
+ const uint32_t par[]);
enum {
XTENSA_OP_ILL = 0x1,
@@ -374,8 +377,10 @@ typedef struct XtensaOpcodeOps {
const char *name;
XtensaOpcodeOp translate;
XtensaOpcodeBoolTest test_ill;
+ XtensaOpcodeUintTest test_overflow;
const uint32_t *par;
uint32_t op_flags;
+ uint32_t windowed_register_op;
} XtensaOpcodeOps;
typedef struct XtensaOpcodeTranslators {
@@ -686,6 +691,8 @@ static inline int cpu_mmu_index(CPUXtensaState *env, bool ifetch)
#define XTENSA_TBFLAG_WINDOW_SHIFT 15
#define XTENSA_TBFLAG_YIELD 0x20000
#define XTENSA_TBFLAG_CWOE 0x40000
+#define XTENSA_TBFLAG_CALLINC_MASK 0x180000
+#define XTENSA_TBFLAG_CALLINC_SHIFT 19
static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
target_ulong *cs_base, uint32_t *flags)
@@ -724,6 +731,8 @@ static inline void cpu_get_tb_cpu_state(CPUXtensaState *env, target_ulong *pc,
uint32_t w = ctz32(windowstart | 0x8);
*flags |= (w << XTENSA_TBFLAG_WINDOW_SHIFT) | XTENSA_TBFLAG_CWOE;
+ *flags |= extract32(env->sregs[PS], PS_CALLINC_SHIFT,
+ PS_CALLINC_LEN) << XTENSA_TBFLAG_CALLINC_SHIFT;
} else {
*flags |= 3 << XTENSA_TBFLAG_WINDOW_SHIFT;
}