aboutsummaryrefslogtreecommitdiff
path: root/tcg/mips
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2016-07-14 12:43:06 -0700
committerRichard Henderson <rth@twiddle.net>2016-09-16 08:12:06 -0700
commit85aa80813dd9f5c1f581c743e45678a3bee220f8 (patch)
tree2a140ecb81d60cf1a593a160c0d09f88ae5a3c7d /tcg/mips
parentebc231d7daf1f41b23d8b6a6d1234800b86e5fe2 (diff)
downloadqemu-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.c11
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);
}