From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28542 invoked by alias); 29 Jun 2019 16:10:58 -0000 Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org Received: (qmail 28497 invoked by uid 89); 29 Jun 2019 16:10:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=him, yours, Ltd, ltd X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 29 Jun 2019 16:10:51 +0000 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6220136807; Sat, 29 Jun 2019 16:10:50 +0000 (UTC) Received: from zarquon.pink (ovpn-118-14.phx2.redhat.com [10.3.118.14]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2A07F60BEC; Sat, 29 Jun 2019 16:10:48 +0000 (UTC) To: Zdenek Sojka , gcc-help@gcc.gnu.org References: From: Andrew Haley Openpgp: preference=signencrypt Subject: Re: [x86 inline asm]: width of register arguments Message-ID: <4bd282e4-f193-4b22-7f97-e8f50da09717@redhat.com> Date: Sat, 29 Jun 2019 16:10:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2019-06/txt/msg00110.txt.bz2 Hi, On 6/24/19 1:19 PM, Zdenek Sojka wrote: > how does gcc choose the register arguments of an inline assembler and what > can I assume about the "unused" bits? The choice is made by the register allocator. You can't assume anything about the "unused" bits. The "r" register constraint means you get a whole register to use, of the wordsize of the machine. > My questions target the 64bit x86 architecture; I assume the behavior is the > same for all target triplets x86_64-*-* > > 1) does gcc always use register of size matching the size of the variable? No. > 2) can I assume anything about the high-order bits of the register? can I > overwrite them freely? No; yes. > 2a) does gcc use the "high" 8bit registers (ah, bh, ch, dh) for variable > allocation? No. > 2b) can gcc allocate different 8bit variables in the "low" and "high" > registers (eg. al/ah, bl/bh, ...)? > > > For variables of type: > > uint8_t a8, b8; > uint16_t a16, b16; > ... I think not, but I'm unsure. > Enforcing same-sized arguments: > a) > __asm__ ("movb %b1, %b0" : "=r"(a8) : "r"(b8)); > or > __asm__ ("movq %q1, %q0" : "=r"(a8) : "r"(b8)); > is always safe to do? (eg. moving 56bits of garbage won't hurt anything) > OR might gcc assume something about the high-order 56bits (eg. zero, sign-/ > zero-extension of the lower 8 bits), which might get broken by the move? If you ask for a register with the "r" constraint, all of that register is yours to use. > Assuming zero-extension: > __asm__ ("movw %w1, %w0" : "=r"(a16) : "r"((uint8_t)b16)); > or > __asm__ ("movw %w1, %w0" : "=r"(a16) : "r"(b8)); > does not seem to work (high-order 8 bits of a16 are garbage) That's how x86 works. -- Andrew Haley (he/him) Java Platform Lead Engineer Red Hat UK Ltd. https://keybase.io/andrewhaley EAC8 43EB D3EF DB98 CC77 2FAD A5CD 6035 332F A671