aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorVitaly Chikunov <vt@altlinux.org>2020-03-09 23:45:57 +0300
committerMichael Roth <mdroth@linux.vnet.ibm.com>2020-06-03 19:57:29 -0500
commit4a9486a02d17e81a54bc4b631fec7112a1850a9d (patch)
tree2ed4979b77728bf7755001ae22079bd904d659ec /target
parentc44c4f7229a4c5d2d10efaede2570537cb1e3285 (diff)
downloadqemu-4a9486a02d17e81a54bc4b631fec7112a1850a9d.zip
qemu-4a9486a02d17e81a54bc4b631fec7112a1850a9d.tar.gz
qemu-4a9486a02d17e81a54bc4b631fec7112a1850a9d.tar.bz2
target/ppc: Fix rlwinm on ppc64
rlwinm cannot just AND with Mask if shift value is zero on ppc64 when Mask Begin is greater than Mask End and high bits are set to 1. Note that PowerISA 3.0B says that for `rlwinm' ROTL32 is used, and ROTL32 is defined (in 3.3.14) so that rotated value should have two copies of lower word of the source value. This seems to be another incarnation of the fix from 820724d170 ("target-ppc: Fix rlwimi, rlwinm, rlwnm again"), except I leave optimization when Mask value is less than 32 bits. Fixes: 7b4d326f47 ("target-ppc: Use the new deposit and extract ops") Cc: qemu-stable@nongnu.org Signed-off-by: Vitaly Chikunov <vt@altlinux.org> Message-Id: <20200309204557.14836-1-vt@altlinux.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> (cherry picked from commit 94f040aaecf4e41cc68991b80204b1b6886bbdd0) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'target')
-rw-r--r--target/ppc/translate.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index f5fe5d0..f87f6ee 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -1938,15 +1938,17 @@ static void gen_rlwinm(DisasContext *ctx)
me += 32;
#endif
mask = MASK(mb, me);
- if (sh == 0) {
- tcg_gen_andi_tl(t_ra, t_rs, mask);
- } else if (mask <= 0xffffffffu) {
- TCGv_i32 t0 = tcg_temp_new_i32();
- tcg_gen_trunc_tl_i32(t0, t_rs);
- tcg_gen_rotli_i32(t0, t0, sh);
- tcg_gen_andi_i32(t0, t0, mask);
- tcg_gen_extu_i32_tl(t_ra, t0);
- tcg_temp_free_i32(t0);
+ if (mask <= 0xffffffffu) {
+ if (sh == 0) {
+ tcg_gen_andi_tl(t_ra, t_rs, mask);
+ } else {
+ TCGv_i32 t0 = tcg_temp_new_i32();
+ tcg_gen_trunc_tl_i32(t0, t_rs);
+ tcg_gen_rotli_i32(t0, t0, sh);
+ tcg_gen_andi_i32(t0, t0, mask);
+ tcg_gen_extu_i32_tl(t_ra, t0);
+ tcg_temp_free_i32(t0);
+ }
} else {
#if defined(TARGET_PPC64)
tcg_gen_deposit_i64(t_ra, t_rs, t_rs, 32, 32);