target/xtensa: check zero overhead loop alignment

ISA book documents that the first instruction of zero overhead loop
must fit completely into naturally aligned region of an instruction
fetch unit size. Check that condition and log a message if it's
violated.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
Max Filippov 2018-04-27 13:07:53 -07:00
parent e3800998e6
commit f40385c959
3 changed files with 9 additions and 0 deletions

View File

@ -369,6 +369,7 @@ struct XtensaConfig {
unsigned nareg; unsigned nareg;
int excm_level; int excm_level;
int ndepc; int ndepc;
unsigned inst_fetch_width;
uint32_t vecbase; uint32_t vecbase;
uint32_t exception_vector[EXC_MAX]; uint32_t exception_vector[EXC_MAX];
unsigned ninterrupt; unsigned ninterrupt;

View File

@ -456,6 +456,7 @@
.options = XTENSA_OPTIONS, \ .options = XTENSA_OPTIONS, \
.nareg = XCHAL_NUM_AREGS, \ .nareg = XCHAL_NUM_AREGS, \
.ndepc = (XCHAL_XEA_VERSION >= 2), \ .ndepc = (XCHAL_XEA_VERSION >= 2), \
.inst_fetch_width = XCHAL_INST_FETCH_WIDTH, \
EXCEPTIONS_SECTION, \ EXCEPTIONS_SECTION, \
INTERRUPTS_SECTION, \ INTERRUPTS_SECTION, \
TLB_SECTION, \ TLB_SECTION, \

View File

@ -970,6 +970,13 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
} }
dc->next_pc = dc->pc + len; dc->next_pc = dc->pc + len;
if (xtensa_option_enabled(dc->config, XTENSA_OPTION_LOOP) &&
dc->lbeg == dc->pc &&
((dc->pc ^ (dc->next_pc - 1)) & -dc->config->inst_fetch_width)) {
qemu_log_mask(LOG_GUEST_ERROR,
"unaligned first instruction of a loop (pc = %08x)\n",
dc->pc);
}
for (i = 1; i < len; ++i) { for (i = 1; i < len; ++i) {
b[i] = cpu_ldub_code(env, dc->pc + i); b[i] = cpu_ldub_code(env, dc->pc + i);
} }