From patchwork Tue Mar 27 13:54:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Martin X-Patchwork-Id: 7485 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id D431C23E13 for ; Tue, 27 Mar 2012 13:54:26 +0000 (UTC) Received: from mail-gy0-f180.google.com (mail-gy0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id A49CCA183FB for ; Tue, 27 Mar 2012 13:54:26 +0000 (UTC) Received: by mail-gy0-f180.google.com with SMTP id z12so5674767ghb.11 for ; Tue, 27 Mar 2012 06:54:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=mime-version:x-forwarded-to:x-forwarded-for:delivered-to :received-spf:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state; bh=ZJtRbXCv3mY6fnVE8UGAISSSI1FGmrq1rCzzXbDcv0A=; b=JXr3BTWF9wfpieI4UAlopFL/LFzinkYoPT6eCumRFaAAcW+V1t7zMgAuauk2xU9t24 7RBgy2WA1QVCJAiI0SlC21ujCoiBJZvwZJcHN9L89YJxH/HomX/UhbSSUb/WzylFDVbt MRSGj2hTpwXUedu5ygocScajzdNEabBUlZ70SRZWnbzsEObrRIGZwWU16IV/GgpqCuPd 93a86+8ZeDsUjMwAf2dimk98v6aA86Lik2d6EJh8yH1iof/bmgReruGwM0/VkdDNZpwF XdY0EVkprgHHzGdovO8iyt3bS4B9T9BabAW2ufOpNksu2apEHqIkfjJ0CWcSt5nHkLFS 2Oiw== MIME-Version: 1.0 Received: by 10.50.194.226 with SMTP id hz2mr8567735igc.44.1332856466072; Tue, 27 Mar 2012 06:54:26 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.5.205 with SMTP id 13csp18206ibw; Tue, 27 Mar 2012 06:54:24 -0700 (PDT) Received: by 10.204.130.151 with SMTP id t23mr10332639bks.27.1332856463435; Tue, 27 Mar 2012 06:54:23 -0700 (PDT) Received: from mail-bk0-f50.google.com (mail-bk0-f50.google.com [209.85.214.50]) by mx.google.com with ESMTPS id il2si9097360bkc.144.2012.03.27.06.54.22 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 27 Mar 2012 06:54:23 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.214.50 is neither permitted nor denied by best guess record for domain of dave.martin@linaro.org) client-ip=209.85.214.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.214.50 is neither permitted nor denied by best guess record for domain of dave.martin@linaro.org) smtp.mail=dave.martin@linaro.org Received: by mail-bk0-f50.google.com with SMTP id w11so7894172bku.37 for ; Tue, 27 Mar 2012 06:54:22 -0700 (PDT) Received: by 10.204.154.210 with SMTP id p18mr6865919bkw.122.1332856462758; Tue, 27 Mar 2012 06:54:22 -0700 (PDT) Received: from e103592.peterhouse.linaro.org (fw-lnat.cambridge.arm.com. [217.140.96.63]) by mx.google.com with ESMTPS id jr13sm39341831bkb.14.2012.03.27.06.54.21 (version=SSLv3 cipher=OTHER); Tue, 27 Mar 2012 06:54:22 -0700 (PDT) From: Dave Martin To: linux-arm-kernel@lists.infradead.org Cc: patches@linaro.org, Stefano Stabellini , Ian Campbell , Rusty Russell , Christoffer Dall , Will Deacon , Marc Zyngier , Rabin Vincent , Jon Medhurst Subject: [PATCH v2 3/4] ARM: opcodes: Add helpers for emitting custom opcodes Date: Tue, 27 Mar 2012 14:54:04 +0100 Message-Id: <1332856445-7007-4-git-send-email-dave.martin@linaro.org> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1332856445-7007-1-git-send-email-dave.martin@linaro.org> References: <1332856445-7007-1-git-send-email-dave.martin@linaro.org> X-Gm-Message-State: ALoCoQlAtEgXvq3bLQEXl45JJwWLTRzCE2IPK230iet/AfcIIrDm9xA5E8Du03x9Ni5G7c15Dgbc This patch adds some __inst_() macros for injecting custom opcodes in assembler (both inline and in .S files). They should make it easier and cleaner to get things right in little-/big- endian/ARM/Thumb-2 kernels without a lot of #ifdefs. This pure-preprocessor approach is preferred over the alternative method of wedging extra assembler directives into the assembler input using top-level asm() blocks, since there is no way to guarantee that the compiler won't reorder those with respect to each other or with respect to non-toplevel asm() blocks, unless -fno-toplevel-reorder is passed (which is in itself somewhat undesirable because it defeats some potential optimisations). Currently _does_ silently rely on the compiler not reordering at the top level, but it seems better to avoid adding extra code which depends on this if the same result can be achieved in another way. Signed-off-by: Dave Martin Acked-by: Nicolas Pitre --- arch/arm/include/asm/opcodes.h | 69 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 69 insertions(+), 0 deletions(-) diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h index f57e417..f7937e1 100644 --- a/arch/arm/include/asm/opcodes.h +++ b/arch/arm/include/asm/opcodes.h @@ -156,4 +156,73 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr); | ___asm_opcode_identity32(___asm_opcode_identity16(second)) \ ) +/* + * Opcode injection helpers + * + * In rare cases it is necessary to assemble an opcode which the + * assembler does not support directly, or which would normally be + * rejected because of the CFLAGS or AFLAGS used to build the affected + * file. + * + * Before using these macros, consider carefully whether it is feasible + * instead to change the build flags for your file, or whether it really + * makes sense to support old assembler versions when building that + * particular kernel feature. + * + * The macros defined here should only be used where there is no viable + * alternative. + * + * + * __inst_arm(x): emit the specified ARM opcode + * __inst_thumb16(x): emit the specified 16-bit Thumb opcode + * __inst_thumb32(x): emit the specified 32-bit Thumb opcode + * + * __inst_arm_thumb16(arm, thumb): emit either the specified arm or + * 16-bit Thumb opcode, depending on whether an ARM or Thumb-2 + * kernel is being built + * + * __inst_arm_thumb32(arm, thumb): emit either the specified arm or + * 32-bit Thumb opcode, depending on whether an ARM or Thumb-2 + * kernel is being built + * + * + * Note that using these macros directly is poor practice. Instead, you + * should use them to define human-readable wrapper macros to encode the + * instructions that you care about. In code which might run on ARMv7 or + * above, you can usually use the __inst_arm_thumb{16,32} macros to + * specify the ARM and Thumb alternatives at the same time. This ensures + * that the correct opcode gets emitted depending on the instruction set + * used for the kernel build. + */ +#include + +#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x)) +#define __inst_thumb32(x) ___inst_thumb32( \ + ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)), \ + ___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x)) \ +) +#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x)) + +#ifdef CONFIG_THUMB2_KERNEL +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \ + __inst_thumb16(thumb_opcode) +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \ + __inst_thumb32(thumb_opcode) +#else +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) +#endif + +/* Helpers for the helpers. Don't use these directly. */ +#ifdef __ASSEMBLY__ +#define ___inst_arm(x) .long x +#define ___inst_thumb16(x) .short x +#define ___inst_thumb32(first, second) .short first, second +#else +#define ___inst_arm(x) ".long " __stringify(x) "\n\t" +#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t" +#define ___inst_thumb32(first, second) \ + ".short " __stringify(first) ", " __stringify(second) "\n\t" +#endif + #endif /* __ASM_ARM_OPCODES_H */