Date: Wed, 29 Dec 2004 04:18:17 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: John-Mark Gurney <gurney_j@resnet.uoregon.edu> Cc: amd64@freebsd.org Subject: Re: what is the proper asm spec for xchg Message-ID: <20041229032725.P90388@delplex.bde.org> In-Reply-To: <20041223202302.GG19624@funkthat.com> References: <1103830283.53421.3.camel@server.mcneil.com> <20041223202302.GG19624@funkthat.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 23 Dec 2004, John-Mark Gurney wrote: > Sean McNeil wrote this message on Thu, Dec 23, 2004 at 11:31 -0800: > > I'm looking at why audio/sdl_mixer will not compile and I see that > > devel/sdl12 has an include with > > > > #elif defined(__GNUC__) && defined(__x86_64__) > > static __inline__ Uint16 SDL_Swap16(Uint16 x) > > { > > __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); > > return x; > > } > > > > This appears to be incorrect as it is giving errors when compiled. Does > > anyone more conversant with asm directives for amd64 have an idea what > > this should be? > > well, from amd64/include/endian.h: > #define __byte_swap_word_var(x) \ > __extension__ ({ register __uint16_t __X = (x); \ > __asm ("xchgb %h0, %b0" : "+Q" (__X)); \ ^ actually q > __X; }) The critical difference is that the "q" constraint gives all general registers on amd64's, but "%h" (to give the second lowest 8-bit subregister) only works for the a, b, c and d registers. The "Q" constraint must be used to restrict to the latter. This difference from i386's is because gcc defines "q" registers to be ones whose lowest 8 bits can be addressed directly and amd64's support this for all general registers. The unimportant differences are: (1) The working version uses the "+" constraint where the broken version uses the "=" and "0" constraints. "0" is just old-fashioned and harder to use here. It was needed for general operands before "+" existed, and caused problems depending on optimization and register pressure. Now it is only supported for register operands, but the above only uses register operands so "0" should work. (2) The operand orders are are reversed. This makes no difference to the result because the operand order doesn't matter for exchanges. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20041229032725.P90388>