SH: Improve movca.l/ocbi emulation.
Author: Vladimir Prus <vladimir@codesourcery.com>
Fix movcal.l/ocbi emulation.
* target-sh4/cpu.h (memory_content): New.
(CPUSH4State): New fields movcal_backup and movcal_backup_tail.
* target-sh4/helper.h (helper_movcal)
(helper_discard_movcal_backup, helper_ocbi): New.
* target-sh4/op_helper.c (helper_movcal)
(helper_discard_movcal_backup, helper_ocbi): New.
* target-sh4/translate.c (DisasContext): New field has_movcal.
(sh4_defs): Update CVS for SH7785.
(cpu_sh4_init): Initialize env->movcal_backup_tail.
(_decode_opc): Discard movca.l-backup.
Make use of helper_movcal and helper_ocbi.
(gen_intermediate_code_internal): Initialize has_movcal to 1.
Thanks to Shin-ichiro KAWASAKI and Paul Mundt for valuable feedback.
Acked-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6966 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index c506086..d2e9b3b 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -644,4 +644,48 @@
}
}
+int cpu_sh4_is_cached(CPUSH4State * env, target_ulong addr)
+{
+ int n;
+ int use_asid = (env->mmucr & MMUCR_SV) == 0 || (env->sr & SR_MD) == 0;
+
+ /* check area */
+ if (env->sr & SR_MD) {
+ /* For previledged mode, P2 and P4 area is not cachable. */
+ if ((0xA0000000 <= addr && addr < 0xC0000000) || 0xE0000000 <= addr)
+ return 0;
+ } else {
+ /* For user mode, only U0 area is cachable. */
+ if (0x80000000 <= addr)
+ return 0;
+ }
+
+ /*
+ * TODO : Evaluate CCR and check if the cache is on or off.
+ * Now CCR is not in CPUSH4State, but in SH7750State.
+ * When you move the ccr inot CPUSH4State, the code will be
+ * as follows.
+ */
+#if 0
+ /* check if operand cache is enabled or not. */
+ if (!(env->ccr & 1))
+ return 0;
+#endif
+
+ /* if MMU is off, no check for TLB. */
+ if (env->mmucr & MMUCR_AT)
+ return 1;
+
+ /* check TLB */
+ n = find_tlb_entry(env, addr, env->itlb, ITLB_SIZE, use_asid);
+ if (n >= 0)
+ return env->itlb[n].c;
+
+ n = find_tlb_entry(env, addr, env->utlb, UTLB_SIZE, use_asid);
+ if (n >= 0)
+ return env->utlb[n].c;
+
+ return 0;
+}
+
#endif