diff options
author | Richard Henderson | 2019-03-23 06:03:39 +0100 |
---|---|---|
committer | Richard Henderson | 2019-06-10 16:03:42 +0200 |
commit | 269bd5d8f61c6b0825ed3c6a5fe01a3ad71c3b4a (patch) | |
tree | b51b8c1ca4eadac1eee562a5e1671b778e022250 /tcg/riscv | |
parent | cpu: Move icount_decr to CPUNegativeOffsetState (diff) | |
download | qemu-269bd5d8f61c6b0825ed3c6a5fe01a3ad71c3b4a.tar.gz qemu-269bd5d8f61c6b0825ed3c6a5fe01a3ad71c3b4a.tar.xz qemu-269bd5d8f61c6b0825ed3c6a5fe01a3ad71c3b4a.zip |
cpu: Move the softmmu tlb to CPUNegativeOffsetState
We have for some time had code within the tcg backends to
handle large positive offsets from env. This move makes
sure that need not happen. Indeed, we are able to assert
at build time that simple offsets suffice for all hosts.
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/riscv')
-rw-r--r-- | tcg/riscv/tcg-target.inc.c | 31 |
1 files changed, 7 insertions, 24 deletions
diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c index 96c33bf621..1f0ae64aae 100644 --- a/tcg/riscv/tcg-target.inc.c +++ b/tcg/riscv/tcg-target.inc.c @@ -962,6 +962,10 @@ static void * const qemu_st_helpers[16] = { /* We don't support oversize guests */ QEMU_BUILD_BUG_ON(TCG_TARGET_REG_BITS < TARGET_LONG_BITS); +/* We expect to use a 12-bit negative offset from ENV. */ +QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) > 0); +QEMU_BUILD_BUG_ON(TLB_MASK_TABLE_OFS(0) < -(1 << 11)); + static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, TCGReg addrh, TCGMemOpIdx oi, tcg_insn_unit **label_ptr, bool is_load) @@ -971,32 +975,11 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl, unsigned a_bits = get_alignment_bits(opc); tcg_target_long compare_mask; int mem_index = get_mmuidx(oi); - int mask_off, table_off; + int fast_ofs = TLB_MASK_TABLE_OFS(mem_index); + int mask_ofs = fast_ofs + offsetof(CPUTLBDescFast, mask); + int table_ofs = fast_ofs + offsetof(CPUTLBDescFast, table); TCGReg mask_base = TCG_AREG0, table_base = TCG_AREG0; - mask_off = offsetof(CPUArchState, tlb_.f[mem_index].mask); - table_off = offsetof(CPUArchState, tlb_.f[mem_index].table); - if (table_off > 0x7ff) { - int mask_hi = mask_off - sextreg(mask_off, 0, 12); - int table_hi = table_off - sextreg(table_off, 0, 12); - - if (likely(mask_hi == table_hi)) { - mask_base = table_base = TCG_REG_TMP1; - tcg_out_opc_upper(s, OPC_LUI, mask_base, mask_hi); - tcg_out_opc_reg(s, OPC_ADD, mask_base, mask_base, TCG_AREG0); - mask_off -= mask_hi; - table_off -= mask_hi; - } else { - mask_base = TCG_REG_TMP0; - table_base = TCG_REG_TMP1; - tcg_out_opc_upper(s, OPC_LUI, mask_base, mask_hi); - tcg_out_opc_reg(s, OPC_ADD, mask_base, mask_base, TCG_AREG0); - table_off -= mask_off; - mask_off -= mask_hi; - tcg_out_opc_imm(s, OPC_ADDI, table_base, mask_base, mask_off); - } - } - tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, mask_base, mask_off); tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, table_base, table_off); |