From: Max Chou <max.chou@sifive.com>
To: qemu-devel@nongnu.org, qemu-riscv@nongnu.org
Cc: Palmer Dabbelt <palmer@dabbelt.com>,
Alistair Francis <Alistair.Francis@wdc.com>,
Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>,
Richard Henderson <richard.henderson@linaro.org>,
Max Chou <max.chou@sifive.com>
Subject: [PATCH 2/2] tcg/riscv64: Fall back when AUIPC pairs are out of range
Date: Fri, 4 Sep 2026 01:04:05 +0800 [thread overview]
Message-ID: <20260903170405.3632015-3-max.chou@sifive.com> (raw)
In-Reply-To: <20260903170405.3632015-1-max.chou@sifive.com>
tcg_out_movi and tcg_out_call_int only check whether a
PC-relative displacement is signed 32-bit before emitting an AUIPC
pair. This does not account for rounding the signed 12-bit immediate,
which can require an unencodable positive 0x80000000 AUIPC contribution.
Validate the split and emit the pair only when it fits. Otherwise,
tcg_out_movi keeps its existing full-address materialization and
tcg_out_call_int uses its existing indirect far-call sequence.
Fixes: dfa8e74f9463 ("tcg/riscv: Add the relocation functions")
Signed-off-by: Max Chou <max.chou@sifive.com>
---
tcg/riscv64/tcg-target.c.inc | 43 +++++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 15 deletions(-)
diff --git a/tcg/riscv64/tcg-target.c.inc b/tcg/riscv64/tcg-target.c.inc
index 1c41f8ffade..12efb44c3d7 100644
--- a/tcg/riscv64/tcg-target.c.inc
+++ b/tcg/riscv64/tcg-target.c.inc
@@ -667,6 +667,21 @@ static bool reloc_call(tcg_insn_unit *src_rw, const tcg_insn_unit *target)
return false;
}
+static bool tcg_out_auipc_pair(TCGContext *s, const tcg_insn_unit *target,
+ RISCVInsn opc, TCGReg base,
+ TCGReg rd, TCGReg rs1)
+{
+ intptr_t hi, lo;
+
+ if (!split_auipc_offset(s->code_ptr, target, &hi, &lo)) {
+ return false;
+ }
+ tcg_out_opc_upper(s, OPC_AUIPC, base, hi);
+ tcg_out_opc_imm(s, opc, rd, rs1, lo);
+
+ return true;
+}
+
static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
intptr_t value, intptr_t addend)
{
@@ -803,7 +818,8 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
tcg_target_long val)
{
tcg_target_long lo, hi, tmp;
- int shift, ret;
+ int shift;
+ bool ret;
if (type == TCG_TYPE_I32) {
val = (int32_t)val;
@@ -824,12 +840,9 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
return;
}
- tmp = tcg_pcrel_diff(s, (void *)val);
- if (tmp == (int32_t)tmp) {
- tcg_out_opc_upper(s, OPC_AUIPC, rd, 0);
- tcg_out_opc_imm(s, OPC_ADDI, rd, rd, 0);
- ret = reloc_call(s->code_ptr - 2, (const tcg_insn_unit *)val);
- tcg_debug_assert(ret == true);
+ ret = tcg_out_auipc_pair(s, (const tcg_insn_unit *)val, OPC_ADDI, rd, rd,
+ rd);
+ if (ret) {
return;
}
@@ -1583,7 +1596,7 @@ static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
{
TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
ptrdiff_t offset = tcg_pcrel_diff(s, arg);
- int ret;
+ bool ret;
init_setting_vtype(s);
@@ -1591,14 +1604,14 @@ static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
if (offset == sextreg(offset, 0, 20)) {
/* short jump: -2097150 to 2097152 */
tcg_out_opc_jump(s, OPC_JAL, link, offset);
- } else if (offset == (int32_t)offset) {
- /* long jump: -2147483646 to 2147483648 */
- tcg_out_opc_upper(s, OPC_AUIPC, TCG_REG_TMP0, 0);
- tcg_out_opc_imm(s, OPC_JALR, link, TCG_REG_TMP0, 0);
- ret = reloc_call(s->code_ptr - 2, arg);
- tcg_debug_assert(ret == true);
} else {
- /* far jump: 64-bit */
+ ret = tcg_out_auipc_pair(s, arg, OPC_JALR, TCG_REG_TMP0, link,
+ TCG_REG_TMP0);
+ if (ret) {
+ return;
+ }
+
+ /* Far jump: 64-bit. */
tcg_target_long imm = sextreg((tcg_target_long)arg, 0, 12);
tcg_target_long base = (tcg_target_long)arg - imm;
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, base);
--
2.43.7
prev parent reply other threads:[~2026-09-03 17:05 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 17:04 [PATCH 0/2] tcg/riscv64: Fix AUIPC pair range validation Max Chou
2026-09-03 17:04 ` [PATCH 1/2] tcg/riscv64: Validate AUIPC relocation range Max Chou
2026-09-03 17:31 ` Philippe Mathieu-Daudé
2026-09-04 7:56 ` Max Chou
2026-09-03 17:04 ` Max Chou [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260903170405.3632015-3-max.chou@sifive.com \
--to=max.chou@sifive.com \
--cc=Alistair.Francis@wdc.com \
--cc=daniel.barboza@oss.qualcomm.com \
--cc=palmer@dabbelt.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=richard.henderson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.