From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by sourceware.org (Postfix) with ESMTPS id 350EB384B825 for ; Thu, 5 Nov 2020 12:14:55 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 350EB384B825 Received: from monopod.intra.ispras.ru (unknown [10.10.3.121]) by mail.ispras.ru (Postfix) with ESMTPS id 9ACAC40A2075; Thu, 5 Nov 2020 12:14:53 +0000 (UTC) Date: Thu, 5 Nov 2020 15:14:53 +0300 (MSK) From: Alexander Monakov To: Uros Bizjak cc: Jakub Jelinek , X86 ML , Andy Lutomirski , GCC Development Subject: Re: typeof and operands in named address spaces In-Reply-To: Message-ID: References: User-Agent: Alpine 2.20.13 (LNX 116 2015-12-14) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Spam-Status: No, score=-3.2 required=5.0 tests=BAYES_00, KAM_DMARC_STATUS, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Nov 2020 12:14:56 -0000 On Thu, 5 Nov 2020, Uros Bizjak wrote: > On Thu, Nov 5, 2020 at 12:38 PM Alexander Monakov wrote: > > > > On Thu, 5 Nov 2020, Uros Bizjak via Gcc wrote: > > > > > > What is the usecase for stripping the address space for asm operands? > > > > > > Please see the end of [2], where the offset to is passed in %rsi > > > to the call to this_cpu_cmpxchg16b_emu. this_cpu_cmpxchg16b_emu > > > implements access with PER_CPU_VAR((%rsi)), which expands to > > > %gs:(%rsi), so it is the same as %gs: in cmpxchg16b alternative. > > > The offset is loaded by lea , %rsi to %rsi reg. > > > > I see, thanks. But then with the typeof-stripping-address-space solution > > you'd be making a very evil cast (producing address of an object that > > does not actually exist in the generic address space). I can write such > > a solution, but it is clearly Undefined Behavior: > > > > #define strip_as(mem) (*(__typeof(0?(mem):(mem))*)(intptr_t)&(mem)) > > > > void foo(__seg_fs int *x) > > { > > asm("# %0" :: "m"(x[1])); > > asm("# %0" :: "m"(strip_as(x[1]))); > > } > > > > yields > > > > foo: > > # %fs:4(%rdi) > > # 4(%rdi) > > ret > > > > > > I think a clean future solution is adding a operand modifier that would > > print the memory operand without the segment prefix. > > I was also thinking of introducing of operand modifier, but Richi > advises the following: > > --cut here-- > typedef __UINTPTR_TYPE__ uintptr_t; > > __seg_fs int x; > > uintptr_t test (void) > { > uintptr_t *p = (uintptr_t *)(uintptr_t) &x; > uintptr_t addr; > > asm volatile ("lea %1, %0" : "=r"(addr) : "m"(*p)); > > return addr; > } This is even worse undefined behavior compared to my solution above: this code references memory in uintptr_t type, while mine preserves the original type via __typeof. So this can visibly break with TBAA (though the kernel uses -fno-strict-aliasing, so this particular concern wouldn't apply there). If you don't care about preserving sizeof and type you can use a cast to char: #define strip_as(mem) (*(char *)(intptr_t)&(mem)) Alexander