diff options
author | Marcin Nowakowski <marcin.nowakowski@fungible.com> | 2023-02-16 06:17:14 +0100 |
---|---|---|
committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2023-03-07 18:09:13 +0100 |
commit | 9055ffd76edc80a6f0d134213522c8cbbafd0f36 (patch) | |
tree | 40a31afcbc54c670ecfbd5dca6dd2cd76638061c /target/mips | |
parent | a43972e1769b6b35c2c5826e707ea784242b6287 (diff) | |
download | qemu-9055ffd76edc80a6f0d134213522c8cbbafd0f36.zip qemu-9055ffd76edc80a6f0d134213522c8cbbafd0f36.tar.gz qemu-9055ffd76edc80a6f0d134213522c8cbbafd0f36.tar.bz2 |
target/mips: Fix JALS32/J32 instruction handling for microMIPS
microMIPS J & JAL instructions perform a jump in a 128MB region and 5
top bits of the address need to be preserved. This is different behavior
compared to standard mips systems, where the jump is executed within a
256MB region.
Note that microMIPS32 instruction set documentation appears to have
inconsistent information regarding JALX32 instruction - it is written in
the doc that:
"To execute a procedure call within the current 256 MB-aligned region
(...)
The low 26 bits of the target address is the target field shifted left
2 bits."
But the target address is already 26 bits. Moreover, the operation
description indicates that 28 bits are copied, so the statement about
use of 26 bits is _most likely_ incorrect and the corresponding code
remains the same as for standard mips instruction set.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@fungible.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230216051717.3911212-2-marcin.nowakowski@fungible.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Diffstat (limited to 'target/mips')
-rw-r--r-- | target/mips/tcg/translate.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/target/mips/tcg/translate.c b/target/mips/tcg/translate.c index 8cad3d1..24993bc 100644 --- a/target/mips/tcg/translate.c +++ b/target/mips/tcg/translate.c @@ -4887,6 +4887,14 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc, break; case OPC_J: case OPC_JAL: + { + /* Jump to immediate */ + int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000 + : 0xF0000000; + btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask) + | (uint32_t)offset; + break; + } case OPC_JALX: /* Jump to immediate */ btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) | |