From nobody Fri Dec 19 14:32:18 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1565961741; cv=none; d=zoho.com; s=zohoarc; b=oJeTi+wIkuMO98KBNhVvXNz4bf/uD9twyLNhm+ej/7vJMZHnszoNUA84Z+DaI/ow30jzYD1G3I35ZocOFaveFUX9BrET0gKHLY5h8bHqIr74Rzl+tcy+qzDu7dXUX4/prNB9Wqby+3v2SF0PUjSjYySZEB5ECu9EDq4dIaxdvgI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1565961741; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=C/JEEaZRwqLGuvRocz89/Usr+xyIhfyyDXXpmxVSBvI=; b=Oij159+uzcFAbP5hH7J37MM5Td7AcJ1ZMvJPpPG5c1CC5wPjcdNpg3m0K9pDPXo/cxLpxiWsuUgNcZwjgl0vY0+sZ87nyEKgAzUAsRin3DvNbziPjkxhFMG9QAjM4QnknO+7Z45qg8KmrhR+dj0dcGHPvki4JhIyBkodeyN7Q2c= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1565961741231983.9531007550357; Fri, 16 Aug 2019 06:22:21 -0700 (PDT) Received: from localhost ([::1]:55972 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hycBP-0000Iw-Kb for importer@patchew.org; Fri, 16 Aug 2019 09:22:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:35228) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyc6o-0003Lv-Cb for qemu-devel@nongnu.org; Fri, 16 Aug 2019 09:17:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hyc6m-0005QZ-JF for qemu-devel@nongnu.org; Fri, 16 Aug 2019 09:17:34 -0400 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]:54855) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hyc6m-0005O9-9S for qemu-devel@nongnu.org; Fri, 16 Aug 2019 09:17:32 -0400 Received: by mail-wm1-x335.google.com with SMTP id p74so4022923wme.4 for ; Fri, 16 Aug 2019 06:17:30 -0700 (PDT) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [81.2.115.148]) by smtp.gmail.com with ESMTPSA id 4sm8705796wro.78.2019.08.16.06.17.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Aug 2019 06:17:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=C/JEEaZRwqLGuvRocz89/Usr+xyIhfyyDXXpmxVSBvI=; b=j6kpUeSE+0hpVOmsBWC56DSFLDS2Yki5H6ITbYDnoE+si+4EynVU/5Ca0e4ngDeOL7 5JiHHbMoDB4UH/2HETRmzLP5NJfFxDZIH5UaxHZ0e8qGh5xIY6EMtAyTiiDRjB5cdL5+ hdseATFko0Dp0nbH5UXtNgxcu955Jo9InD43o9B1b10Zvk0pD291vz0RsJeDot+S7Ffg nZEeamC2K1iTSnQ+W08a/AsbiUI08KJm0Ztc4RoIZreWmly5asDhKrgylYowtKZKip5M 8q65WIC0GpMGIA19eDOCFsxG0b+Mjt9F0Xl5ryw+/jjUbAoV51rs/A01aF/XTwcKXVGi tAPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=C/JEEaZRwqLGuvRocz89/Usr+xyIhfyyDXXpmxVSBvI=; b=brNRWy5D1PfojFFMxvyNWgjv7003/FV9PHyaJhWO3By88Os37yicntTfEi5t9zIGI3 64hO9kTui50eL0NW+g5vJL73yBz9FmtXoZ7hUucGDHiW/wBzvH6tE2gPm39vz/NlMYcE StelV1JSdDAjWoPp7OEWTDEY4aGrqWW1a4LX41sX7QsZImLkelol9RVirdnb0SS4ZBUI zeDjwiZlF+pYAX3HY9HcPUwkdTePFzgmdWv6hlrGwSAxOGtWXv4z6iO2xqfFgFrnwYbN qUP6DuNSMhhNdJtAOjoEyoiOhdhCcRRFTjAVqI+I7JOTIJN53G+uY+vA9pnIOonQigko HejQ== X-Gm-Message-State: APjAAAVO5yrQ7KEIloYcPsQw/zA3wlWXYmqKeBUR9LMxrBVBPOmsgIem ImbDFVYPF5zIW3XGn/i4ezbC5CL1oaaXqQ== X-Google-Smtp-Source: APXvYqxZXJAL9dP6Hu33w+V8ifNV1p0DlCkdqNUv7uF8uIyHavx/Aq0k6hqanl1DI55d6k8mnMI/xQ== X-Received: by 2002:a1c:107:: with SMTP id 7mr7515583wmb.84.1565961449492; Fri, 16 Aug 2019 06:17:29 -0700 (PDT) From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 16 Aug 2019 14:16:58 +0100 Message-Id: <20190816131719.28244-9-peter.maydell@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190816131719.28244-1-peter.maydell@linaro.org> References: <20190816131719.28244-1-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::335 Subject: [Qemu-devel] [PULL 08/29] target/arm: Introduce read_pc X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) From: Richard Henderson We currently have 3 different ways of computing the architectural value of "PC" as seen in the ARM ARM. The value of s->pc has been incremented past the current insn, but that is all. Thus for a32, PC =3D s->pc + 4; for t32, PC =3D s->pc; for t16, PC =3D s->pc + 2. These differing computations make it impossible at present to unify the various code paths. With the newly introduced s->pc_curr, we can compute the correct value for all cases, using the formula given in the ARM ARM. This changes the behaviour for load_reg() and load_reg_var() when called with reg=3D=3D15 from a 32-bit Thumb instruction: previously they would have returned the incorrect value of pc_curr + 6, and now they will return the architecturally correct value of PC, which is pc_curr + 4. This will not affect well-behaved guest software, because all of the places we call these functions from T32 code are instructions where using r15 is UNPREDICTABLE. Using the architectural PC value here is more consistent with the T16 and A32 behaviour. Signed-off-by: Richard Henderson Reviewed-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daud=C3=A9 Message-id: 20190807045335.1361-4-richard.henderson@linaro.org [PMM: added commit message note about UNPREDICTABLE T32 cases] Signed-off-by: Peter Maydell --- target/arm/translate.c | 59 ++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/target/arm/translate.c b/target/arm/translate.c index fed08c63f81..41523c0241f 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -196,17 +196,17 @@ static inline void store_cpu_offset(TCGv_i32 var, int= offset) #define store_cpu_field(var, name) \ store_cpu_offset(var, offsetof(CPUARMState, name)) =20 +/* The architectural value of PC. */ +static uint32_t read_pc(DisasContext *s) +{ + return s->pc_curr + (s->thumb ? 4 : 8); +} + /* Set a variable to the value of a CPU register. */ static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg) { if (reg =3D=3D 15) { - uint32_t addr; - /* normally, since we updated PC, we need only to add one insn */ - if (s->thumb) - addr =3D (long)s->pc + 2; - else - addr =3D (long)s->pc + 4; - tcg_gen_movi_i32(var, addr); + tcg_gen_movi_i32(var, read_pc(s)); } else { tcg_gen_mov_i32(var, cpu_R[reg]); } @@ -7853,16 +7853,14 @@ static void disas_arm_insn(DisasContext *s, unsigne= d int insn) /* branch link and change to thumb (blx ) */ int32_t offset; =20 - val =3D (uint32_t)s->pc; tmp =3D tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); + tcg_gen_movi_i32(tmp, s->pc); store_reg(s, 14, tmp); /* Sign-extend the 24-bit offset */ offset =3D (((int32_t)insn) << 8) >> 8; + val =3D read_pc(s); /* offset * 4 + bit24 * 2 + (thumb bit) */ val +=3D (offset << 2) | ((insn >> 23) & 2) | 1; - /* pipeline offset */ - val +=3D 4; /* protected by ARCH(5); above, near the start of uncond block= */ gen_bx_im(s, val); return; @@ -9138,10 +9136,8 @@ static void disas_arm_insn(DisasContext *s, unsigned= int insn) } else { /* store */ if (i =3D=3D 15) { - /* special case: r15 =3D PC + 8 */ - val =3D (long)s->pc + 4; tmp =3D tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); + tcg_gen_movi_i32(tmp, read_pc(s)); } else if (user) { tmp =3D tcg_temp_new_i32(); tmp2 =3D tcg_const_i32(i); @@ -9207,15 +9203,13 @@ static void disas_arm_insn(DisasContext *s, unsigne= d int insn) int32_t offset; =20 /* branch (and link) */ - val =3D (int32_t)s->pc; if (insn & (1 << 24)) { tmp =3D tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, val); + tcg_gen_movi_i32(tmp, s->pc); store_reg(s, 14, tmp); } offset =3D sextract32(insn << 2, 0, 26); - val +=3D offset + 4; - gen_jmp(s, val); + gen_jmp(s, read_pc(s) + offset); } break; case 0xc: @@ -9573,12 +9567,7 @@ static void disas_thumb2_insn(DisasContext *s, uint3= 2_t insn) tcg_temp_free_i32(addr); } else if ((insn & (7 << 5)) =3D=3D 0) { /* Table Branch. */ - if (rn =3D=3D 15) { - addr =3D tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc); - } else { - addr =3D load_reg(s, rn); - } + addr =3D load_reg(s, rn); tmp =3D load_reg(s, rm); tcg_gen_add_i32(addr, addr, tmp); if (insn & (1 << 4)) { @@ -9594,7 +9583,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32= _t insn) } tcg_temp_free_i32(addr); tcg_gen_shli_i32(tmp, tmp, 1); - tcg_gen_addi_i32(tmp, tmp, s->pc); + tcg_gen_addi_i32(tmp, tmp, read_pc(s)); store_reg(s, 15, tmp); } else { bool is_lasr =3D false; @@ -10327,7 +10316,7 @@ static void disas_thumb2_insn(DisasContext *s, uint= 32_t insn) tcg_gen_movi_i32(cpu_R[14], s->pc | 1); } =20 - offset +=3D s->pc; + offset +=3D read_pc(s); if (insn & (1 << 12)) { /* b/bl */ gen_jmp(s, offset); @@ -10568,7 +10557,7 @@ static void disas_thumb2_insn(DisasContext *s, uint= 32_t insn) offset |=3D (insn & (1 << 11)) << 8; =20 /* jump to the offset */ - gen_jmp(s, s->pc + offset); + gen_jmp(s, read_pc(s) + offset); } } else { /* @@ -11062,7 +11051,7 @@ static void disas_thumb_insn(DisasContext *s, uint3= 2_t insn) if (insn & (1 << 11)) { rd =3D (insn >> 8) & 7; /* load pc-relative. Bit 1 of PC is ignored. */ - val =3D s->pc + 2 + ((insn & 0xff) * 4); + val =3D read_pc(s) + ((insn & 0xff) * 4); val &=3D ~(uint32_t)2; addr =3D tcg_temp_new_i32(); tcg_gen_movi_i32(addr, val); @@ -11449,7 +11438,7 @@ static void disas_thumb_insn(DisasContext *s, uint3= 2_t insn) } else { /* PC. bit 1 is ignored. */ tmp =3D tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2); + tcg_gen_movi_i32(tmp, read_pc(s) & ~(uint32_t)2); } val =3D (insn & 0xff) * 4; tcg_gen_addi_i32(tmp, tmp, val); @@ -11569,9 +11558,7 @@ static void disas_thumb_insn(DisasContext *s, uint3= 2_t insn) tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel); tcg_temp_free_i32(tmp); offset =3D ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3; - val =3D (uint32_t)s->pc + 2; - val +=3D offset; - gen_jmp(s, val); + gen_jmp(s, read_pc(s) + offset); break; =20 case 15: /* IT, nop-hint. */ @@ -11735,7 +11722,7 @@ static void disas_thumb_insn(DisasContext *s, uint3= 2_t insn) arm_skip_unless(s, cond); =20 /* jump to the offset */ - val =3D (uint32_t)s->pc + 2; + val =3D read_pc(s); offset =3D ((int32_t)insn << 24) >> 24; val +=3D offset << 1; gen_jmp(s, val); @@ -11761,9 +11748,9 @@ static void disas_thumb_insn(DisasContext *s, uint3= 2_t insn) break; } /* unconditional branch */ - val =3D (uint32_t)s->pc; + val =3D read_pc(s); offset =3D ((int32_t)insn << 21) >> 21; - val +=3D (offset << 1) + 2; + val +=3D offset << 1; gen_jmp(s, val); break; =20 @@ -11787,7 +11774,7 @@ static void disas_thumb_insn(DisasContext *s, uint3= 2_t insn) /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */ uint32_t uoffset =3D ((int32_t)insn << 21) >> 9; =20 - tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset); + tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset); } break; } --=20 2.20.1