diff options
author | Richard Henderson <rth@twiddle.net> | 2016-07-14 12:43:06 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2016-09-16 08:12:06 -0700 |
commit | 85aa80813dd9f5c1f581c743e45678a3bee220f8 (patch) | |
tree | 2a140ecb81d60cf1a593a160c0d09f88ae5a3c7d /tcg/mips | |
parent | ebc231d7daf1f41b23d8b6a6d1234800b86e5fe2 (diff) | |
download | qemu-85aa80813dd9f5c1f581c743e45678a3bee220f8.zip qemu-85aa80813dd9f5c1f581c743e45678a3bee220f8.tar.gz qemu-85aa80813dd9f5c1f581c743e45678a3bee220f8.tar.bz2 |
tcg: Support arbitrary size + alignment
Previously we allowed fully unaligned operations, but not operations
that are aligned but with less alignment than the operation size.
In addition, arm32, ia64, mips, and sparc had been omitted from the
previous overalignment patch, which would have led to that alignment
being enforced.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'tcg/mips')
-rw-r--r-- | tcg/mips/tcg-target.inc.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c index 2f9be48..acb6ff0 100644 --- a/tcg/mips/tcg-target.inc.c +++ b/tcg/mips/tcg-target.inc.c @@ -1040,7 +1040,9 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl, TCGReg addrh, TCGMemOpIdx oi, tcg_insn_unit *label_ptr[2], bool is_load) { - TCGMemOp s_bits = get_memop(oi) & MO_SIZE; + TCGMemOp opc = get_memop(oi); + unsigned s_bits = opc & MO_SIZE; + unsigned a_bits = get_alignment_bits(opc); int mem_index = get_mmuidx(oi); int cmp_off = (is_load @@ -1071,10 +1073,15 @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg base, TCGReg addrl, tcg_out_opc_imm(s, OPC_LW, TCG_TMP0, TCG_REG_A0, cmp_off + (TARGET_LONG_BITS == 64 ? LO_OFF : 0)); + /* We don't currently support unaligned accesses. + We could do so with mips32r6. */ + if (a_bits < s_bits) { + a_bits = s_bits; + } /* Mask the page bits, keeping the alignment bits to compare against. In between on 32-bit targets, load the tlb addend for the fast path. */ tcg_out_movi(s, TCG_TYPE_I32, TCG_TMP1, - TARGET_PAGE_MASK | ((1 << s_bits) - 1)); + TARGET_PAGE_MASK | ((1 << a_bits) - 1)); if (TARGET_LONG_BITS == 32) { tcg_out_opc_imm(s, OPC_LW, TCG_REG_A0, TCG_REG_A0, add_off); } |