From patchwork Fri Oct 30 05:25:40 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AKASHI Takahiro X-Patchwork-Id: 7523831 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B31FDBEEA4 for ; Fri, 30 Oct 2015 05:30:47 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A294820522 for ; Fri, 30 Oct 2015 05:30:46 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A6E4E2047D for ; Fri, 30 Oct 2015 05:30:45 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zs2FQ-0004HU-3o; Fri, 30 Oct 2015 05:29:08 +0000 Received: from mail-pa0-x22c.google.com ([2607:f8b0:400e:c03::22c]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zs2EU-0003cS-VS for linux-arm-kernel@lists.infradead.org; Fri, 30 Oct 2015 05:28:13 +0000 Received: by padhk11 with SMTP id hk11so63066899pad.1 for ; Thu, 29 Oct 2015 22:27:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Y0rxtq4cyGzbBiCv7eSoscXOYgJv1Vpkchg1Z5Ppkzg=; b=h+q+VBZgWLeOL/DO0xh+bEXYKgXuJPzJSG0hGiNVOLhXDVHvqsWuNq8HH+QJB/NId8 iRtsRX6fHQIzUP79DQlCyJi1cnek7mfEV6iFLJZn+vAQc4dMQn3bY09ohWWSB2FS0aUT JDzFcnDHLSrryxBneurQI76aYYufTj/20ou0cpfTX/GS0O+DtL090r9g90fgYXlXz2VI bWri75p85CHvxWLMPf2DqKDRsjnLTm/j12YTh/ZqrLEkF95PMD6sl9QIdtgk659DY1Mk 9ei3009JO223M1P+1q/TqgK7yI+1jWoKJlnnorm4YKWQLv3faOH0lT2pWe4ZLx+Q9MLp QUog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Y0rxtq4cyGzbBiCv7eSoscXOYgJv1Vpkchg1Z5Ppkzg=; b=TTdQ1J9MvYtMFFDRUwELaEXt4+cjajkayNwjr+kQQUPvON6pobxP5RIRLwW75OFmVM S/y9A1pw94i5ld8jAtr/dyXnPyEElUlxFzf7+BH0kUssZMNn0TeAr/I1mwMP5Zq62Lic k5AX0snNmIRGe5bB1q02fs3rEYOKpwvu8PvspdfiZQSgLhAi7st9TpE9Aom0RV6m72BN Ws2hna8R5+WROFRw1y3WKO1jz0peaH2Ae/GG7xL/netjkKnVVetlnRr9twdEHRBm/gUY O6VizitmYQfUrGqp6e5Fm5fSzOgrVAj+zfZJFuKFiCuvICuZbuHkFO4Bh2ryTDNQedbT IF5Q== X-Gm-Message-State: ALoCoQnu5pftXBE/xQNEWV3aaMc6twxmxRcThZLNEbH9byKGssuQ1Wvl/CZKUIX08rA31YyqIK7S X-Received: by 10.68.69.72 with SMTP id c8mr6367946pbu.2.1446182870315; Thu, 29 Oct 2015 22:27:50 -0700 (PDT) Received: from localhost.localdomain (61-205-6-54m5.grp1.mineo.jp. [61.205.6.54]) by smtp.googlemail.com with ESMTPSA id ho3sm5571377pbb.18.2015.10.29.22.27.45 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 29 Oct 2015 22:27:49 -0700 (PDT) From: AKASHI Takahiro To: catalin.marinas@arm.com, will.deacon@arm.com, rostedt@goodmis.org Subject: [PATCH v4 5/6] arm64: insn: add instruction decoders for ldp/stp and add/sub Date: Fri, 30 Oct 2015 14:25:40 +0900 Message-Id: <1446182741-31019-6-git-send-email-takahiro.akashi@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1446182741-31019-1-git-send-email-takahiro.akashi@linaro.org> References: <1446182741-31019-1-git-send-email-takahiro.akashi@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151029_222811_229300_7E597661 X-CRM114-Status: GOOD ( 13.99 ) X-Spam-Score: -2.6 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: jungseoklee85@gmail.com, linux-kernel@vger.kernel.org, AKASHI Takahiro , broonie@kernel.org, david.griego@linaro.org, olof@lixom.net, linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A function prologue analyzer is a requisite for implementing stack tracer and getting better views of stack usages on arm64. To implement a function prologue analyzer, we have to be able to decode, at least, stp, add, sub and mov instructions. This patch adds decoders for those instructions, that are used solely by stack tracer for now, but generic enough for other uses. Signed-off-by: AKASHI Takahiro --- arch/arm64/include/asm/insn.h | 18 ++++++++ arch/arm64/kernel/insn.c | 102 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index 30e50eb..8d5c538 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h @@ -165,6 +165,8 @@ enum aarch64_insn_ldst_type { AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX, AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX, AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX, + AARCH64_INSN_LDST_LOAD_PAIR, + AARCH64_INSN_LDST_STORE_PAIR, }; enum aarch64_insn_adsb_type { @@ -225,6 +227,8 @@ static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \ __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800) +__AARCH64_INSN_FUNCS(stp, 0x7FC00000, 0x29000000) +__AARCH64_INSN_FUNCS(ldp, 0x7FC00000, 0x29400000) __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000) __AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000) __AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000) @@ -277,6 +281,7 @@ __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000) __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000) __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000) +__AARCH64_INSN_FUNCS(eret, 0xFFFFFFFF, 0xD69F00E0) #undef __AARCH64_INSN_FUNCS @@ -370,6 +375,19 @@ bool aarch32_insn_is_wide(u32 insn); u32 aarch32_insn_extract_reg_num(u32 insn, int offset); u32 aarch32_insn_mcr_extract_opc2(u32 insn); u32 aarch32_insn_mcr_extract_crm(u32 insn); +int aarch64_insn_decode_add_sub_imm(u32 insn, + enum aarch64_insn_register *dst, + enum aarch64_insn_register *src, + int *imm, + enum aarch64_insn_variant *variant, + enum aarch64_insn_adsb_type *type); +int aarch64_insn_decode_load_store_pair(u32 insn, + enum aarch64_insn_register *reg1, + enum aarch64_insn_register *reg2, + enum aarch64_insn_register *base, + int *offset, + enum aarch64_insn_variant *variant, + enum aarch64_insn_ldst_type *type); #endif /* __ASSEMBLY__ */ #endif /* __ASM_INSN_H */ diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index c08b9ad..b56a66c 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c @@ -33,6 +33,7 @@ #include #define AARCH64_INSN_SF_BIT BIT(31) +#define AARCH64_INSN_S_BIT BIT(29) #define AARCH64_INSN_N_BIT BIT(22) static int aarch64_insn_encoding_class[] = { @@ -1141,3 +1142,104 @@ u32 aarch32_insn_mcr_extract_crm(u32 insn) { return insn & CRM_MASK; } + +enum aarch64_insn_register aarch64_insn_extract_reg_num(u32 insn, + enum aarch64_insn_register_type type) +{ + int shift; + + switch (type) { + case AARCH64_INSN_REGTYPE_RT: + case AARCH64_INSN_REGTYPE_RD: + shift = 0; + break; + case AARCH64_INSN_REGTYPE_RN: + shift = 5; + break; + case AARCH64_INSN_REGTYPE_RT2: + case AARCH64_INSN_REGTYPE_RA: + shift = 10; + break; + case AARCH64_INSN_REGTYPE_RM: + shift = 16; + break; + default: + pr_err("%s: unknown register type decoding %d\n", __func__, + type); + return ~0L; + } + + return (insn & (GENMASK(4, 0) << shift)) >> shift; +} + +int aarch64_insn_decode_add_sub_imm(u32 insn, + enum aarch64_insn_register *dst, + enum aarch64_insn_register *src, + int *imm, + enum aarch64_insn_variant *variant, + enum aarch64_insn_adsb_type *type) +{ + if (aarch64_insn_is_add_imm(insn)) + *type = ((insn) & AARCH64_INSN_S_BIT) ? + AARCH64_INSN_ADSB_ADD_SETFLAGS : + AARCH64_INSN_ADSB_ADD; + else if (aarch64_insn_is_sub_imm(insn)) + *type = ((insn) & AARCH64_INSN_S_BIT) ? + AARCH64_INSN_ADSB_SUB_SETFLAGS : + AARCH64_INSN_ADSB_SUB; + else + return 0; + + *variant = (insn & AARCH64_INSN_SF_BIT) ? AARCH64_INSN_VARIANT_64BIT : + AARCH64_INSN_VARIANT_32BIT; + + *dst = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RD); + + *src = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RN); + + /* TODO: ignore shilft field[23:22] */ + *imm = (int)aarch64_insn_decode_immediate(AARCH64_INSN_IMM_12, insn); + + return 1; +} + +int aarch64_insn_decode_load_store_pair(u32 insn, + enum aarch64_insn_register *reg1, + enum aarch64_insn_register *reg2, + enum aarch64_insn_register *base, + int *offset, + enum aarch64_insn_variant *variant, + enum aarch64_insn_ldst_type *type) +{ + int imm; + + if (aarch64_insn_is_stp(insn)) + *type = AARCH64_INSN_LDST_STORE_PAIR; + else if (aarch64_insn_is_stp_post(insn)) + *type = AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX; + else if (aarch64_insn_is_stp_pre(insn)) + *type = AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX; + else if (aarch64_insn_is_ldp(insn)) + *type = AARCH64_INSN_LDST_LOAD_PAIR; + else if (aarch64_insn_is_ldp_post(insn)) + *type = AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX; + else if (aarch64_insn_is_ldp_pre(insn)) + *type = AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX; + else + return 0; + + *variant = (insn & AARCH64_INSN_S_BIT) ? AARCH64_INSN_VARIANT_64BIT : + AARCH64_INSN_VARIANT_32BIT; + + *reg1 = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RT); + + *reg2 = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RT2); + + *base = aarch64_insn_extract_reg_num(insn, AARCH64_INSN_REGTYPE_RN); + + imm = (int)aarch64_insn_decode_immediate(AARCH64_INSN_IMM_7, insn); + asm("sbfm %0, %0, 0, 6" : "+r" (imm)); + *offset = imm * 8; + + return 1; +}