Commit 6416d16f authored by Max Filippov's avatar Max Filippov
Browse files

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: default avatarMax Filippov <jcmvbkbc@gmail.com>
parent 15477819
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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;
    }
+0 −5
Original line number Diff line number Diff line
@@ -253,12 +253,7 @@ void HELPER(wsr_windowbase)(CPUXtensaState *env, uint32_t v)
void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
{
    int callinc = (env->sregs[PS] & PS_CALLINC) >> PS_CALLINC_SHIFT;
    uint32_t windowstart = xtensa_replicate_windowstart(env) >>
        (env->sregs[WINDOW_BASE] + 1);

    if (windowstart & ((1 << callinc) - 1)) {
        HELPER(window_check)(env, pc, callinc);
    }
    env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - imm;
    xtensa_rotate_window(env, callinc);
    env->sregs[WINDOW_START] |=
+880 −582

File changed.

Preview size limit exceeded, changes collapsed.