From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752708AbcF1MXx (ORCPT ); Tue, 28 Jun 2016 08:23:53 -0400 Received: from ns.sciencehorizons.net ([71.41.210.147]:51359 "HELO ns.sciencehorizons.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1752096AbcF1MXw (ORCPT ); Tue, 28 Jun 2016 08:23:52 -0400 Date: 28 Jun 2016 08:23:50 -0400 Message-ID: <20160628122350.6688.qmail@ns.sciencehorizons.net> From: "George Spelvin" To: vegard.nossum@gmail.com Subject: Re: [PATCH] firmware: declare __{start,end}_builtin_fw as pointers Cc: linux-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org +#define external_array(type, name) \ + ({ \ + extern type name[]; \ + type *name_ptr = name; \ + asm ("" : "+r" (name_ptr)); \ + name_ptr; \ + }) I've had to pull similar tricks to persuade GCC to generate the code I wanted (in my case, it was optimization: "evaluate it in this order, damn it!"), and I prefer to use the asm itself with overlapping operands to do the assignment. #define external_array(type, name) \ ({ \ extern type name[]; \ type *name_ptr; asm ("" : "=g" (name_ptr) : "0" (name)); \ name_ptr; \ }) You could define a wrapper if you like, something like /* * Assign dst = src, but prevent the compiler from inferring anything * about the assigned value, so it can't do any unwanted optimization. */ #define blind_assign(dst,src) asm("" : "=X" (dst) : "0" (src)) In case it helps, here's a list of architecture-independent operand constraints (that I think is exhaustive, but I'm not 100% sure): r - general-purpose register f - floating-point register m - memory o - offsettable memory (excluding pre/post inc/decrement modes) i - immediate g - "general", any of the above X - "wildcard". This matches anything at all, including special-purpose registers that are not included in "r".