TCGOutOpBinary passes (output, value, count), but MIPS variable shift
instructions encode (rd, rt, rs), where rt is the value and rs is the
count. tcg_out_opc_reg() takes its register fields in (rd, rs, rt)
order, so passing (a0, a1, a2) encodes the value as the count and the
count as the value.


Swap a1 and a2 at the four variable shift emitters. This covers the I32
and I64 forms of SHL, SHR, SAR, and ROTR.


A freestanding AArch64 test forces each operation into a separate
translation block and records one failure bit per form. With QEMU 11.0.3
in a pre-R6 MIPS64EL execution environment:


  unpatched: exit status 0xff
  patched:   exit status 0x00


For example, the DSRAV host instruction changes from:


  dsrav s0,s0,s1


to:


  dsrav s0,s1,s0


where s1 contains the value and s0 contains the count at that point.


Fixes: 03568c0d5395 ("tcg: Convert rotl, rotr to TCGOutOpBinary")
Fixes: b5aafbaa8346 ("tcg: Convert sar to TCGOutOpBinary")
Fixes: 27d21ee7c791 ("tcg: Convert shl to TCGOutOpBinary")
Fixes: edd6ba8a6bc8 ("tcg: Convert shr to TCGOutOpBinary")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4103
Signed-off-by: Quintin Kong <[email protected]&gt;
---
&nbsp;tcg/mips64/tcg-target.c.inc | 8 ++++----
&nbsp;1 file changed, 4 insertions(+), 4 deletions(-)


diff --git a/tcg/mips64/tcg-target.c.inc b/tcg/mips64/tcg-target.c.inc
index 60c703a09..2b34f3716 100644
--- a/tcg/mips64/tcg-target.c.inc
+++ b/tcg/mips64/tcg-target.c.inc
@@ -1836,7 +1836,7 @@ static void tgen_rotr(TCGContext *s, TCGType type,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
TCGReg a0, TCGReg a1, TCGReg a2)
&nbsp;{
&nbsp; &nbsp; &nbsp;MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_ROTRV : 
OPC_DROTRV;
- &nbsp; &nbsp;tcg_out_opc_reg(s, insn, a0, a1, a2);
+ &nbsp; &nbsp;tcg_out_opc_reg(s, insn, a0, a2, a1);
&nbsp;}
&nbsp;
&nbsp;static void tgen_rotri(TCGContext *s, TCGType type,
@@ -1860,7 +1860,7 @@ static void tgen_sar(TCGContext *s, TCGType type,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
TCGReg a0, TCGReg a1, TCGReg a2)
&nbsp;{
&nbsp; &nbsp; &nbsp;MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_SRAV : OPC_DSRAV;
- &nbsp; &nbsp;tcg_out_opc_reg(s, insn, a0, a1, a2);
+ &nbsp; &nbsp;tcg_out_opc_reg(s, insn, a0, a2, a1);
&nbsp;}
&nbsp;
&nbsp;static void tgen_sari(TCGContext *s, TCGType type,
@@ -1883,7 +1883,7 @@ static void tgen_shl(TCGContext *s, TCGType type,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
TCGReg a0, TCGReg a1, TCGReg a2)
&nbsp;{
&nbsp; &nbsp; &nbsp;MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_SLLV : OPC_DSLLV;
- &nbsp; &nbsp;tcg_out_opc_reg(s, insn, a0, a1, a2);
+ &nbsp; &nbsp;tcg_out_opc_reg(s, insn, a0, a2, a1);
&nbsp;}
&nbsp;
&nbsp;static void tgen_shli(TCGContext *s, TCGType type,
@@ -1906,7 +1906,7 @@ static void tgen_shr(TCGContext *s, TCGType type,
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
TCGReg a0, TCGReg a1, TCGReg a2)
&nbsp;{
&nbsp; &nbsp; &nbsp;MIPSInsn insn = type == TCG_TYPE_I32 ? OPC_SRLV : OPC_DSRLV;
- &nbsp; &nbsp;tcg_out_opc_reg(s, insn, a0, a1, a2);
+ &nbsp; &nbsp;tcg_out_opc_reg(s, insn, a0, a2, a1);
&nbsp;}
&nbsp;
&nbsp;static void tgen_shri(TCGContext *s, TCGType type,
--
2.43.0





         原始邮件
         
       
发件人:2358543632 <[email protected]&gt;
发件时间:2026年7月29日 00:32
收件人:qemu-devel <[email protected]&gt;
抄送:qemu-stable <[email protected]&gt;, philmd <[email protected]&gt;, 
aurelien <[email protected]&gt;
主题:[RFC PATCH 11.0 0/2] tcg/mips64: Fix shifts and unaligned loads - [DORA-B]



Hi,


I am sending this RFC for two code-generation bugs in the MIPS64 TCG host
backend that are still present in QEMU 11.0.3.


The first patch fixes the register order used for variable shifts and
rotates. The backend currently exchanges the value and shift-count
registers for the 32-bit and 64-bit SHL, SHR, SAR, and ROTR operations.
A standalone AArch64 test covering all eight forms returns 0xff before
the fix and 0 afterwards:


&nbsp; https://gitlab.com/qemu-project/qemu/-/work_items/4103


The second patch preserves the address register across pre-R6 unaligned
load pairs. When the qemu_ld output overlaps its dead address input, the
first LWR/LWL or LDR/LDL instruction can overwrite the base needed by the
second instruction. Standalone RISC-V tests for both widths fail to
terminate before the fix and exit successfully afterwards:


&nbsp; https://gitlab.com/qemu-project/qemu/-/work_items/4102


I tested both changes using clean QEMU 11.0.3 sources. The shift,
unaligned-lw, and unaligned-ld tests returned 255/137/137 before the
patches and 0/0/0 afterwards. The two patch files also pass
scripts/checkpatch.pl without warnings.


The MIPS host backend was removed from master by commits bfa0801e91ca and
586663f1fa29, so there is no corresponding master patch to submit. Would
the stable maintainers consider these small fixes directly for the QEMU
11.0 branch? If a stable-only change is not appropriate here, I would
appreciate guidance on how these release bugs should be handled.


Thanks,
Quintin


---


Quintin Kong (2):
&nbsp; tcg/mips64: Fix variable shift operand order
&nbsp; tcg/mips64: Preserve the base of unaligned loads


&nbsp;tcg/mips64/tcg-target.c.inc | 13 +++++++++----
&nbsp;1 file changed, 9 insertions(+), 4 deletions(-)


--
2.43.0

Reply via email to