aboutsummaryrefslogtreecommitdiff
path: root/target-xtensa/translate.c
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2014-02-07 15:57:22 +0400
committerMax Filippov <jcmvbkbc@gmail.com>2014-02-24 04:47:01 +0400
commite848dd4248230c0463841a16d1fa9eb054a2d211 (patch)
tree73d214173bd6e72b4e9c9e9237a18e0c19f91d28 /target-xtensa/translate.c
parent7c84259019a945e4ff275994b96c0de4496d2a5e (diff)
target-xtensa: add basic checks to icache opcodes
Check privilege level for privileged instructions (IHU, III, IIU and IPFL are privileged), memory accessibility for instructions that reference memory (IH* and IPFL) and windowed register validity for all instruction cache instructions. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'target-xtensa/translate.c')
-rw-r--r--target-xtensa/translate.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 5ad900fde9..a59103d2f8 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -2332,22 +2332,42 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
#undef gen_dcache_hit_test4
#undef gen_dcache_hit_test8
+#define gen_icache_hit_test(w, shift) do { \
+ TCGv_i32 addr = tcg_temp_new_i32(); \
+ gen_window_check1(dc, RRI##w##_S); \
+ tcg_gen_movi_i32(cpu_pc, dc->pc); \
+ tcg_gen_addi_i32(addr, cpu_R[RRI##w##_S], \
+ RRI##w##_IMM##w << shift); \
+ gen_helper_itlb_hit_test(cpu_env, addr); \
+ tcg_temp_free(addr); \
+ } while (0)
+
+#define gen_icache_hit_test4() gen_icache_hit_test(4, 4)
+#define gen_icache_hit_test8() gen_icache_hit_test(8, 2)
+
case 12: /*IPFc*/
HAS_OPTION(XTENSA_OPTION_ICACHE);
+ gen_window_check1(dc, RRI8_S);
break;
case 13: /*ICEc*/
switch (OP1) {
case 0: /*IPFLl*/
HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
+ gen_check_privilege(dc);
+ gen_icache_hit_test4();
break;
case 2: /*IHUl*/
HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
+ gen_check_privilege(dc);
+ gen_icache_hit_test4();
break;
case 3: /*IIUl*/
HAS_OPTION(XTENSA_OPTION_ICACHE_INDEX_LOCK);
+ gen_check_privilege(dc);
+ gen_window_check1(dc, RRI4_S);
break;
default: /*reserved*/
@@ -2358,10 +2378,13 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
case 14: /*IHIc*/
HAS_OPTION(XTENSA_OPTION_ICACHE);
+ gen_icache_hit_test8();
break;
case 15: /*IIIc*/
HAS_OPTION(XTENSA_OPTION_ICACHE);
+ gen_check_privilege(dc);
+ gen_window_check1(dc, RRI8_S);
break;
default: /*reserved*/
@@ -2370,6 +2393,10 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
}
break;
+#undef gen_icache_hit_test
+#undef gen_icache_hit_test4
+#undef gen_icache_hit_test8
+
case 9: /*L16SI*/
gen_load_store(ld16s, 1);
break;