Date: Fri, 23 Nov 2001 02:00:01 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: John Baldwin <jhb@FreeBSD.org> Cc: Peter Jeremy <peter.jeremy@alcatel.com.au>, <cvs-all@FreeBSD.org>, <cvs-committers@FreeBSD.org> Subject: Re: cvs commit: src/sys/i386/include atomic.h Message-ID: <20011123011419.Y17516-100000@delplex.bde.org> In-Reply-To: <XFMail.011121113833.jhb@FreeBSD.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 21 Nov 2001, John Baldwin wrote:
> On 20-Nov-01 Peter Jeremy wrote:
> > On Mon, Nov 12, 2001 at 08:57:33AM -0800, John Baldwin wrote:
> >>jhb 2001/11/12 08:57:33 PST
> >>
> >> Modified files:
> >> sys/i386/include atomic.h
> >> Log:
> >> Use newer constraints for inline assembly for an operand that is both an
> >> input and an output by using the '+' modifier rather than listing the
> >> operand in both the input and output sections.
> >
> > This change still leaves the non-memory operand's constraint as "ir"
> > in all cases - this isn't correct for the char or short cases. I have
> > some old patches to fix this.
>
> There are char and short registers and immediates in x86 asm. The shorts will
> make the assembler insert an extra byte to change the operand size, but it will
> still compile.
Changing the operand size only works for shorts. There is no way to reduce
to a byte register if the operand happens to be loaded into a register other
than %e[abcd]x, and the "r" operand used in atomic.h doesn't specify any
more than this. Example:
%%%
char ch;
foo()
{
asm("incb %4"
: : "a" (0xa), "b" (0xb), "c" (0xc), "d" (0xd), "ir" (ch));
}
%%%
Compiling this gives:
%%%
.file "z.c"
.version "01.01"
gcc2_compiled.:
.text
.p2align 2,0x90
.globl foo
.type foo,@function
foo:
pushl %ebp
movl %esp,%ebp
pushl %edi
pushl %esi
pushl %ebx
movl $10,%esi
movl $11,%ebx
movl $12,%ecx
movl $13,%edx
movb ch,%al
movl %eax,%edi
movl %esi,%eax
#APP
incb %di
#NO_APP
popl %ebx
popl %esi
popl %edi
leave
ret
.Lfe1:
.size foo,.Lfe1-foo
.comm ch,1,1
.ident "[ASM_FILE_END]GCC: (c) 2.95.3 20010315 (release)"
%%%
`ch' gets loaded into %edi since none of %e[abcd]x is free, and gcc
silently generates the wrong name %di for the (not directly accessible)
byte register in the low byte of %edi.
The bugs are mostly in atomic.h and the above example. gcc detects
the error if correct constraint "iq" is used (but it doesn't detect
that %4 can't be converted to a "q" register even if %4 is replaced
by %b4). gcc is normally smart about loading chars into byte registers,
and atomic.h depends on this too much.
This can be fixed using messy tests involving sizeof() in the ATOMIC_ASM()
macro or by moving the constraint to the macro invocations where it is
easy to vary. I prefer the latter, except I want the atomic functions
to have a type-generic interface which seems to require the messy tests.
The last version of Peter's fixes that I saw use the latter.
Bruce
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe cvs-all" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011123011419.Y17516-100000>
