From: takahiro.akashi@linaro.org (AKASHI Takahiro)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 4/6] arm64: insn: add instruction decoders for ldp/stp and add/sub
Date: Wed, 11 Nov 2015 13:54:37 +0900 [thread overview]
Message-ID: <5642CA0D.9080708@linaro.org> (raw)
In-Reply-To: <999DB062-D4C8-4050-ADF7-9C6CEEC0BF73@gmail.com>
On 11/10/2015 10:40 PM, Jungseok Lee wrote:
> On Nov 6, 2015, at 3:44 PM, AKASHI Takahiro wrote:
>> 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 <takahiro.akashi@linaro.org>
>> ---
>> 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)
>
> According to C4.2.7, the third argument looks like 0xD69F03E0. Rn field is 11111
> in case of eret.
Thanks. Fix it (c3.2.7 though).
-Takahiro AKASHI
> Best Regards
> Jungseok Lee
>
>> #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 <asm/insn.h>
>>
>> #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;
>> +}
>> --
>> 1.7.9.5
>>
>
next prev parent reply other threads:[~2015-11-11 4:54 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-06 6:44 [PATCH v5 0/6] arm64: ftrace: fix incorrect output from stack tracer AKASHI Takahiro
2015-11-06 6:44 ` [PATCH v5 1/6] arm64: ftrace: modify a stack frame in a safe way AKASHI Takahiro
2015-11-06 6:44 ` [PATCH v5 2/6] arm64: ftrace: fix a stack tracer's output under function graph tracer AKASHI Takahiro
2015-11-09 14:04 ` Jungseok Lee
2015-11-10 2:42 ` AKASHI Takahiro
2015-11-13 15:01 ` Jungseok Lee
2015-11-16 9:23 ` AKASHI Takahiro
2015-11-06 6:44 ` [PATCH v5 3/6] ftrace: allow arch-specific stack tracer AKASHI Takahiro
2015-11-06 13:39 ` Steven Rostedt
2015-11-06 6:44 ` [PATCH v5 4/6] arm64: insn: add instruction decoders for ldp/stp and add/sub AKASHI Takahiro
2015-11-10 13:40 ` Jungseok Lee
2015-11-11 4:54 ` AKASHI Takahiro [this message]
2015-11-06 6:44 ` [PATCH v5 5/6] arm64: ftrace: add arch-specific stack tracer AKASHI Takahiro
2015-11-10 14:05 ` Jungseok Lee
2015-11-11 5:03 ` AKASHI Takahiro
2015-11-11 22:56 ` Jungseok Lee
2015-11-06 6:44 ` [PATCH v5 6/6] arm64: ftrace: add a test of function prologue analyzer AKASHI Takahiro
2015-11-09 14:24 ` [PATCH v5 0/6] arm64: ftrace: fix incorrect output from stack tracer Jungseok Lee
2015-11-10 2:58 ` AKASHI Takahiro
2015-11-10 13:32 ` Jungseok Lee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5642CA0D.9080708@linaro.org \
--to=takahiro.akashi@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).