From patchwork Wed Aug 7 04:53:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 170697 Delivered-To: patch@linaro.org Received: by 2002:a92:512:0:0:0:0:0 with SMTP id q18csp6621854ile; Tue, 6 Aug 2019 21:57:16 -0700 (PDT) X-Google-Smtp-Source: APXvYqw6w8+5KIbBDEoEo2aSzaKO9NnvuXiojbRBoDWnI47o7Kd5WoH65eiT5o8ZteaKQ9pamuvE X-Received: by 2002:a17:906:414:: with SMTP id d20mr6855501eja.275.1565153836609; Tue, 06 Aug 2019 21:57:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565153836; cv=none; d=google.com; s=arc-20160816; b=J9MKUzoP9OMY9WyI4Q+cDv82LbavpfbvkM2MO7IZq89eg757Ja30w0F5UfgCFa6uLD j6Iym2Co+SpmntVR3iKX91ril5nZ7UACrNaXu3drjGtnErJ+CcAngnzl82BVajnY2MKQ d9kFozqsyN4J/Oci7l7Ff2671wiTBZoPWDDQ0U2zKw0fXQWWu/kiSmVKFOGmzW1m0CTY LR58BfE7UM2O1Fl+GGi/lQHrpeEI3A1pghpBOb5K2F2cuqmIxtfLxnoa8td7R20+Tdt7 aGB+E2rDP47k/ccTHq621x2CEPCFuHC/se7rAwY8Ye6PqIu9M8slim/SfuJ85npyaJg2 rEgw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=1+ZCh0ppqRckFKlk6UR/b/e9Pyhyh5ijaXz+rNnMkc4=; b=T3RDrwlLakg0nP45z7CvOUzfyp5+kqVIrNJXk6jBrlB9o28G9NHhcrswkZrX82bi5r TuJokyTFSEkv1laKM40uwhWbP1U9Yl6XlPPYu9tfqGMjBJY5S4IIg/WRFD0CnNIe7Ikg NWPw00xSyiB4fKElR9MIVGE/MycgrpdGtOMKDluWidFK/MwY2SFcwS87/WFc5qU2+t0V igwIWeJY0TvHjH/GAodVTG8kN5RF0o1r8rdRj/xLWpJVapGrcS772bHeupqH2WaMerFO bbGGSIrh8me4ffFH4ZT7RvvarQCVRbnLb4+EELvrxhi0+tO7SnCpJ3XjPHUExrd44a+m zetw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="p+gGLAe/"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id j19si30802907eda.46.2019.08.06.21.57.16 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 06 Aug 2019 21:57:16 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b="p+gGLAe/"; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:37246 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hvE0h-0007r7-Hn for patch@linaro.org; Wed, 07 Aug 2019 00:57:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40659) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hvDxQ-0001Cs-B1 for qemu-devel@nongnu.org; Wed, 07 Aug 2019 00:53:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hvDxO-0004od-HO for qemu-devel@nongnu.org; Wed, 07 Aug 2019 00:53:52 -0400 Received: from mail-pl1-x641.google.com ([2607:f8b0:4864:20::641]:45837) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hvDxO-0004o1-9b for qemu-devel@nongnu.org; Wed, 07 Aug 2019 00:53:50 -0400 Received: by mail-pl1-x641.google.com with SMTP id y8so38795990plr.12 for ; Tue, 06 Aug 2019 21:53:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1+ZCh0ppqRckFKlk6UR/b/e9Pyhyh5ijaXz+rNnMkc4=; b=p+gGLAe/m+zU0edleywRdT2G7HCx7Bu+nzK9e4ItOJ497cRaMWZC91wayPIMM5t2EW Xfsd8LrA9hiFEzRuP2UUHMWwG2NdsGiNrn/NZKl/njB8x9dQ2kiURzxjGtaUFvqw/5kj KNWc+Ji3ddsVuLOJO47gOkjQFWlLF7s2e9CR52Z/sFwAkpIJygD9T0JxniFPODtJ/NpC oe8SS/5r9NBm16AM7lqSda5kBojf+uQK8pjXlKzNJB1ZxG5EtC4iDmnJ4ieNagAj5luO 1Nk4vpc6D1BagxgoA3q8vUtKN1blMyOD9nWvBmHURIllizd43qZ/zJbGQXFmPwVhnB2/ 1P0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1+ZCh0ppqRckFKlk6UR/b/e9Pyhyh5ijaXz+rNnMkc4=; b=DiiRJCKXoaGda12ml6EpSagezRGb2ERArtniLIerCDmAnJr8z7hZ8mFCHhuw5lqCYJ xnnSsI0Q3oY1YRDJX0a9bhkzCaoJtFT33xc89QiwLj8+YMcWfKbUWgHQT4omvUhg4Prz umcNeY4m0aZwZRfNBQ6T4/OakciIdxH3SoHe2auYDfJ6kZ4jBP8I4JM9ygBcRUqrad6q /icDW2EAQZs02eC9NwvGa2Sd6zQVLtLGHxJm5IsR20T7M5wKeXtwODjvDKNo+q8MnsiK 7sYKPecMmJ1rpDj1kgY/g3YkeJdIC1IdbDOtVKTLZ07Vye1TuHXTxYtwNqacPR/qVpt7 4WIg== X-Gm-Message-State: APjAAAVkqyth2xUjUWBT2ryhHw/glOK8fQP6vMiJiyEDBkbeDDZdhu4/ Ovo6p2WrdeAoW5gQwoIwiAc3s01V+Ks= X-Received: by 2002:a17:902:2ae8:: with SMTP id j95mr5932957plb.276.1565153628891; Tue, 06 Aug 2019 21:53:48 -0700 (PDT) Received: from localhost.localdomain (97-113-7-119.tukw.qwest.net. [97.113.7.119]) by smtp.gmail.com with ESMTPSA id t9sm24347921pji.18.2019.08.06.21.53.47 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Tue, 06 Aug 2019 21:53:48 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 6 Aug 2019 21:53:28 -0700 Message-Id: <20190807045335.1361-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190807045335.1361-1-richard.henderson@linaro.org> References: <20190807045335.1361-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::641 Subject: [Qemu-devel] [PATCH 04/11] target/arm: Introduce add_reg_for_lit 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: , Cc: peter.maydell@linaro.org, qemu-arm@nongnu.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Provide a common routine for the places that require ALIGN(PC, 4) as the base address as opposed to plain PC. The two are always the same for A32, but the difference is meaningful for thumb mode. Signed-off-by: Richard Henderson --- Note: This patch is easier to read with -b, as there are several large-ish indentation changes as the if statements fold together. --- target/arm/translate-vfp.inc.c | 38 ++------ target/arm/translate.c | 166 +++++++++++++++------------------ 2 files changed, 82 insertions(+), 122 deletions(-) -- 2.17.1 Reviewed-by: Philippe Mathieu-Daudé diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c index 092eb5ec53..262d4177e5 100644 --- a/target/arm/translate-vfp.inc.c +++ b/target/arm/translate-vfp.inc.c @@ -941,14 +941,8 @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a) offset = -offset; } - if (s->thumb && a->rn == 15) { - /* This is actually UNPREDICTABLE */ - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~2); - } else { - addr = load_reg(s, a->rn); - } - tcg_gen_addi_i32(addr, addr, offset); + /* For thumb, use of PC is UNPREDICTABLE. */ + addr = add_reg_for_lit(s, a->rn, offset); tmp = tcg_temp_new_i32(); if (a->l) { gen_aa32_ld32u(s, tmp, addr, get_mem_index(s)); @@ -983,14 +977,8 @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a) offset = -offset; } - if (s->thumb && a->rn == 15) { - /* This is actually UNPREDICTABLE */ - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~2); - } else { - addr = load_reg(s, a->rn); - } - tcg_gen_addi_i32(addr, addr, offset); + /* For thumb, use of PC is UNPREDICTABLE. */ + addr = add_reg_for_lit(s, a->rn, offset); tmp = tcg_temp_new_i64(); if (a->l) { gen_aa32_ld64(s, tmp, addr, get_mem_index(s)); @@ -1029,13 +1017,8 @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a) return true; } - if (s->thumb && a->rn == 15) { - /* This is actually UNPREDICTABLE */ - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~2); - } else { - addr = load_reg(s, a->rn); - } + /* For thumb, use of PC is UNPREDICTABLE. */ + addr = add_reg_for_lit(s, a->rn, 0); if (a->p) { /* pre-decrement */ tcg_gen_addi_i32(addr, addr, -(a->imm << 2)); @@ -1112,13 +1095,8 @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a) return true; } - if (s->thumb && a->rn == 15) { - /* This is actually UNPREDICTABLE */ - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~2); - } else { - addr = load_reg(s, a->rn); - } + /* For thumb, use of PC is UNPREDICTABLE. */ + addr = add_reg_for_lit(s, a->rn, 0); if (a->p) { /* pre-decrement */ tcg_gen_addi_i32(addr, addr, -(a->imm << 2)); diff --git a/target/arm/translate.c b/target/arm/translate.c index 61933865d5..71d94c053b 100644 --- a/target/arm/translate.c +++ b/target/arm/translate.c @@ -220,6 +220,23 @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg) return tmp; } +/* + * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4). + * This is used for load/store for which use of PC implies (literal), + * or ADD that implies ADR. + */ +static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs) +{ + TCGv_i32 tmp = tcg_temp_new_i32(); + + if (reg == 15) { + tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs); + } else { + tcg_gen_addi_i32(tmp, cpu_R[reg], ofs); + } + return tmp; +} + /* Set a CPU register. The source must be a temporary and will be marked as dead. */ static void store_reg(DisasContext *s, int reg, TCGv_i32 var) @@ -9472,16 +9489,12 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) */ bool wback = extract32(insn, 21, 1); - if (rn == 15) { - if (insn & (1 << 21)) { - /* UNPREDICTABLE */ - goto illegal_op; - } - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, s->pc & ~3); - } else { - addr = load_reg(s, rn); + if (rn == 15 && (insn & (1 << 21))) { + /* UNPREDICTABLE */ + goto illegal_op; } + + addr = add_reg_for_lit(s, rn, 0); offset = (insn & 0xff) * 4; if ((insn & (1 << 23)) == 0) { offset = -offset; @@ -10682,27 +10695,15 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) store_reg(s, rd, tmp); } else { /* Add/sub 12-bit immediate. */ - if (rn == 15) { - offset = s->pc & ~(uint32_t)3; - if (insn & (1 << 23)) - offset -= imm; - else - offset += imm; - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, offset); - store_reg(s, rd, tmp); + if (insn & (1 << 23)) { + imm = -imm; + } + tmp = add_reg_for_lit(s, rn, imm); + if (rn == 13 && rd == 13) { + /* ADD SP, SP, imm or SUB SP, SP, imm */ + store_sp_checked(s, tmp); } else { - tmp = load_reg(s, rn); - if (insn & (1 << 23)) - tcg_gen_subi_i32(tmp, tmp, imm); - else - tcg_gen_addi_i32(tmp, tmp, imm); - if (rn == 13 && rd == 13) { - /* ADD SP, SP, imm or SUB SP, SP, imm */ - store_sp_checked(s, tmp); - } else { - store_reg(s, rd, tmp); - } + store_reg(s, rd, tmp); } } } @@ -10816,61 +10817,53 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn) } } memidx = get_mem_index(s); - if (rn == 15) { - addr = tcg_temp_new_i32(); - /* PC relative. */ - /* s->pc has already been incremented by 4. */ - imm = s->pc & 0xfffffffc; - if (insn & (1 << 23)) - imm += insn & 0xfff; - else - imm -= insn & 0xfff; - tcg_gen_movi_i32(addr, imm); + imm = insn & 0xfff; + if (insn & (1 << 23)) { + /* PC relative or Positive offset. */ + addr = add_reg_for_lit(s, rn, imm); + } else if (rn == 15) { + /* PC relative with negative offset. */ + addr = add_reg_for_lit(s, rn, -imm); } else { addr = load_reg(s, rn); - if (insn & (1 << 23)) { - /* Positive offset. */ - imm = insn & 0xfff; - tcg_gen_addi_i32(addr, addr, imm); - } else { - imm = insn & 0xff; - switch ((insn >> 8) & 0xf) { - case 0x0: /* Shifted Register. */ - shift = (insn >> 4) & 0xf; - if (shift > 3) { - tcg_temp_free_i32(addr); - goto illegal_op; - } - tmp = load_reg(s, rm); - if (shift) - tcg_gen_shli_i32(tmp, tmp, shift); - tcg_gen_add_i32(addr, addr, tmp); - tcg_temp_free_i32(tmp); - break; - case 0xc: /* Negative offset. */ - tcg_gen_addi_i32(addr, addr, -imm); - break; - case 0xe: /* User privilege. */ - tcg_gen_addi_i32(addr, addr, imm); - memidx = get_a32_user_mem_index(s); - break; - case 0x9: /* Post-decrement. */ - imm = -imm; - /* Fall through. */ - case 0xb: /* Post-increment. */ - postinc = 1; - writeback = 1; - break; - case 0xd: /* Pre-decrement. */ - imm = -imm; - /* Fall through. */ - case 0xf: /* Pre-increment. */ - writeback = 1; - break; - default: + imm = insn & 0xff; + switch ((insn >> 8) & 0xf) { + case 0x0: /* Shifted Register. */ + shift = (insn >> 4) & 0xf; + if (shift > 3) { tcg_temp_free_i32(addr); goto illegal_op; } + tmp = load_reg(s, rm); + if (shift) { + tcg_gen_shli_i32(tmp, tmp, shift); + } + tcg_gen_add_i32(addr, addr, tmp); + tcg_temp_free_i32(tmp); + break; + case 0xc: /* Negative offset. */ + tcg_gen_addi_i32(addr, addr, -imm); + break; + case 0xe: /* User privilege. */ + tcg_gen_addi_i32(addr, addr, imm); + memidx = get_a32_user_mem_index(s); + break; + case 0x9: /* Post-decrement. */ + imm = -imm; + /* Fall through. */ + case 0xb: /* Post-increment. */ + postinc = 1; + writeback = 1; + break; + case 0xd: /* Pre-decrement. */ + imm = -imm; + /* Fall through. */ + case 0xf: /* Pre-increment. */ + writeback = 1; + break; + default: + tcg_temp_free_i32(addr); + goto illegal_op; } } @@ -11066,10 +11059,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) if (insn & (1 << 11)) { rd = (insn >> 8) & 7; /* load pc-relative. Bit 1 of PC is ignored. */ - val = read_pc(s) + ((insn & 0xff) * 4); - val &= ~(uint32_t)2; - addr = tcg_temp_new_i32(); - tcg_gen_movi_i32(addr, val); + addr = add_reg_for_lit(s, 15, (insn & 0xff) * 4); tmp = tcg_temp_new_i32(); gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit); @@ -11447,16 +11437,8 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn) * - Add PC/SP (immediate) */ rd = (insn >> 8) & 7; - if (insn & (1 << 11)) { - /* SP */ - tmp = load_reg(s, 13); - } else { - /* PC. bit 1 is ignored. */ - tmp = tcg_temp_new_i32(); - tcg_gen_movi_i32(tmp, read_pc(s) & ~(uint32_t)2); - } val = (insn & 0xff) * 4; - tcg_gen_addi_i32(tmp, tmp, val); + tmp = add_reg_for_lit(s, insn & (1 << 11) ? 13 : 15, val); store_reg(s, rd, tmp); break;