Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

gcc-2.6.0: help w/asm

0 views
Skip to first unread message

Caleb Epstein

unread,
Jul 21, 1994, 4:11:30 PM7/21/94
to
I tried posting this to the linux-activists mailing list, but
have received no response.

It seems that the semantics of asm() have changed somewhat
from gcc-2.5.8 to gcc-2.6.0 and as a result parts of the Linux kernel
need to be changed. Some of these changes were addressed in patch 30
to kernel version 1.1, but there's still a problem with the UltraStor
SCSI driver.

When building this module, I get the following:

gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes \
-O2 -fomit-frame-pointer -pipe -m486 -c ultrastor.c -o ultrastor.o
ultrastor.c: In function `ultrastor_queuecommand':
ultrastor.c:309: inconsistent operand constraints in an `asm'
ultrastor.c:309: inconsistent operand constraints in an `asm'
ultrastor.c: In function `ultrastor_abort':
ultrastor.c:309: inconsistent operand constraints in an `asm'

The offending code in ultrastor.c looks like this:

/* This asm is fragile: it doesn't work without the casts and it may
not work without optimization. Maybe I should add a swap builtin
to gcc. --jfc */
static inline unsigned char xchgb(unsigned char reg,
volatile unsigned char *mem)
{
asm("xchgb %0,%1" :
"=r" (reg), "=m" (*(unsigned char *)mem) :
"0" (reg), "1" (*(unsigned char *)mem)); /* line 309 */
return reg;
}

The xchgb() C function is meant to be a more-or-less atomic
operation to return the value of a variable while setting it to
another value. Unfortunately, my assembler skills are nonexistent: I
don't understand gcc asm() directives or the changes which happened
from 2.5.8 to 2.6.0. Would any kind soul like to take a hack at
recoding this function so gcc-2.6.0 will accept it?

Many thanks in advance,

--
[ c...@jpmorgan.com ][ Caleb Epstein ][ JP Morgan & Co. Incorporated ]

Richard Earnshaw

unread,
Jul 22, 1994, 10:22:32 AM7/22/94
to
In article <30mkpi$8...@archive.ny.jpmorgan.com>, c...@aww.ny.jpmorgan.com (Caleb Epstein) writes:
|> static inline unsigned char xchgb(unsigned char reg,
|> volatile unsigned char *mem)
|> {
|> asm("xchgb %0,%1" :
|> "=r" (reg), "=m" (*(unsigned char *)mem) :
|> "0" (reg), "1" (*(unsigned char *)mem)); /* line 309 */
|> return reg;
|> }
|>

I'm not a 386 expert, but try

static inline unsigned char xchgb(unsigned char reg,
volatile unsigned char *mem)
{
asm ("xchgb %0, %1" :

"+r" (reg), "+m" (*(unsigned char *)mem));
return reg;
}

'+' in a constraint says that the operand is read as well as written.

David Kastrup

unread,
Jul 23, 1994, 5:22:18 AM7/23/94
to
r...@cs.utwente.nl (Richard Earnshaw) writes:

>In article <30mkpi$8...@archive.ny.jpmorgan.com>, c...@aww.ny.jpmorgan.com (Caleb Epstein) writes:
>|> static inline unsigned char xchgb(unsigned char reg,
>|> volatile unsigned char *mem)
>|> {
>|> asm("xchgb %0,%1" :
>|> "=r" (reg), "=m" (*(unsigned char *)mem) :
>|> "0" (reg), "1" (*(unsigned char *)mem)); /* line 309 */
>|> return reg;
>|> }
>|>

The "r" constraint is definitely wrong, as it can indicate an SI or
DI register as well. Look into your docs.

>I'm not a 386 expert, but try

>static inline unsigned char xchgb(unsigned char reg,
> volatile unsigned char *mem)
>{
> asm ("xchgb %0, %1" :
> "+r" (reg), "+m" (*(unsigned char *)mem));
> return reg;
>}

>'+' in a constraint says that the operand is read as well as written.

--
David Kastrup d...@pool.informatik.rwth-aachen.de
Tel: +49-241-72419 Fax: +49-241-79502
Goethestr. 20, D-52064 Aachen

Caleb Epstein

unread,
Jul 25, 1994, 9:51:04 AM7/25/94
to
I wrote:

Caleb> [ I'm having trouble compiling the Linux kernel w/gcc-2.6.0 ]

Caleb> static inline unsigned char xchgb(unsigned char reg,
Caleb> volatile unsigned char *mem)
Caleb> {
Caleb> asm("xchgb %0,%1" :
Caleb> "=r" (reg), "=m" (*(unsigned char *)mem) :
Caleb> "0" (reg), "1" (*(unsigned char *)mem)); /* line 309 */
Caleb> return reg;
Caleb> }

Caleb> [ gcc complains "inconsistent operand constraints in an 'asm'"
Caleb> on line 309; this is an error not a warning. ]

Richard Earnshaw wrote:

Richard> I'm not a 386 expert, but try:
Richard> static inline unsigned char xchgb(unsigned char reg,
Richard> volatile unsigned char *mem)
Richard> {
Richard> asm ("xchgb %0, %1" :
Richard> "+r" (reg), "+m" (*(unsigned char *)mem));
Richard> return reg;
Richard> }

Richard> '+' in a constraint says that the operand is read as well as written.

Well, I tried Richard's suggestion and unfortunately it didn't
work (thanks for trying, though, Richard). I get the error

ultrastor.c:308: output operand constraint contains '+'

Line 308 is the line with the +r/+m stuff. There was a recent
patch (1.1.35) to the Linux kernel which changed the "=r" in the
original xchgb() function to an "=q", but this also fails to correct
the problem - I get the same error as with the original "=r".
Combining the two patches so that Richard's suggestion becomes
"+q"... also fails.

David Kastrup wrote:

David> The "r" constraint is definitely wrong, as it can indicate an SI or
David> DI register as well. Look into your docs.

Which docs? I've looked briefly at the gcc info pages, but as
I know zero assembler this really isn't that helpful. It is written
from the point of view of someone who already knows what they are
doing, and I don't. Your note about the "r" constraint is correct, as
the official kernel has been patched to change the "r" to a "q".
Unfortunately it still doesn't fix the error when compiling the code.

Is it possible that this is simply a bug in gcc-2.6.0? I've
tried every combination of "=" and "+" constraints on the original
code and on Richard's suggested patch. Each one fails with either the
original error or the "constraint contains '+'" error. I'd really
appreciate any help on this. Thanks,

0 new messages