diff options
author | Richard Henderson <rth@twiddle.net> | 2011-04-18 20:01:20 -0700 |
---|---|---|
committer | Richard Henderson <rth@anchor.twiddle.net> | 2011-05-31 10:18:06 -0700 |
commit | 3b4fefd6e65a7bdb994d10a9fa36c19b5749b502 (patch) | |
tree | 7efb27a3af6cb58a73909e407c6e6179fa49a088 /target-alpha/translate.c | |
parent | e5214853eac8f86aca2f5493e7171d6f36ddde38 (diff) |
target-alpha: Implement TLB flush primitives.
Expose these via MTPR, more or less like the real HW does.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-alpha/translate.c')
-rw-r--r-- | target-alpha/translate.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/target-alpha/translate.c b/target-alpha/translate.c index e664d62aa3..ad6c2ca448 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -1621,7 +1621,6 @@ static void gen_mfpr(int ra, int regno) static void gen_mtpr(int rb, int regno) { TCGv tmp; - int data; if (rb == 31) { tmp = tcg_const_i64(0); @@ -1629,16 +1628,27 @@ static void gen_mtpr(int rb, int regno) tmp = cpu_ir[rb]; } - /* The basic registers are data only, and unknown registers - are read-zero, write-ignore. */ - data = cpu_pr_data(regno); - if (data != 0) { - if (data & PR_BYTE) { - tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE); - } else if (data & PR_LONG) { - tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG); - } else { - tcg_gen_st_i64(tmp, cpu_env, data); + /* These two register numbers perform a TLB cache flush. Thankfully we + can only do this inside PALmode, which means that the current basic + block cannot be affected by the change in mappings. */ + if (regno == 255) { + /* TBIA */ + gen_helper_tbia(); + } else if (regno == 254) { + /* TBIS */ + gen_helper_tbis(tmp); + } else { + /* The basic registers are data only, and unknown registers + are read-zero, write-ignore. */ + int data = cpu_pr_data(regno); + if (data != 0) { + if (data & PR_BYTE) { + tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE); + } else if (data & PR_LONG) { + tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG); + } else { + tcg_gen_st_i64(tmp, cpu_env, data); + } } } |