public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* GCC Inline ASM generates incorrect assembler code (or documentation is unclear, or I am &*&$@$#*&).
@ 2001-12-14 14:27 Armand Liberi
  2001-12-14 15:51 ` Jan Hubicka
  0 siblings, 1 reply; 3+ messages in thread
From: Armand Liberi @ 2001-12-14 14:27 UTC (permalink / raw)
  To: gcc

Hello,

I have a small example of what I think might be a GCC bug involving inline
asm constraints.  I get the same results on three different versions of GCC,
one in RedHat Linux 7.2, one in the newest CygWin distribution for Windows,
and one in a LynxOS distribution that also comes via RedHat as I understand
it and is several years old.

I first submitted it to the PR web site but it was rejected because of the
LynxOS GCC version number.  It was suggested that I send it to you as a more
general question.

So, if you could tell me if it is a bug, a documentation error, or stupidty,
I would appreciate it.

-------------------------------------------------
Problem
-------------------------------------------------
With the variable declarations:

unsigned int singleInt;
unsigned int lotsOfInts[100]={0};

                asm ("FSTPL %0":"=m" (singleInt)); generates "FSTPL
singleInt" as expected, and

                asm ("FSTPL %0":"=m" (lotsOfInts)); generates "FSTPL
lotsOfInts" as expected, and

                asm ("FLDL %0"::"m" (singleInt)); generates "FLDL singleInt"
as expected, BUT

                asm ("FLDL %0"::"m" (lotsOfInts)); generates "FLDL .LC0"
which is NOT expected (by me).

This actually happened using an FSAVE/FRSTOR sequence in a SIGFPE signal
handler.  As the above illustrates, it was not the instruction that caused
the problem - just that an array address is involved rather than a single
variable.  We pay for support from LynuxWorks and they gave me two fixes
shown below.  Those also appear to be bugs to me but, like so many other
people on the net, I'm a little confused about the constraint rules, etc.,
and cannot find any clear statement of those rules.
-------------------------------------------------
Fixes
-------------------------------------------------
 Two have been suggested to me by LynuxWorks support:

1.  Change 'asm ("FLDL %0"::"m" (lotsOfInts));'
    to 'asm ("FLDL %0":"=m" (lotsOfInts));'.  I.E., use an output constraint
to describe an input (???)

2.  Use 'asm ("FLDL lotsOfInts);'.  I.E., don't use constraints."  (I found
a page on the web that said that if the restraints are left off of the
inputs/outputs, then a "clobber" restraint of "memory" should be included
but I can't find any reference to that any where else.

And, I found that:

3.  Using lotsOfInts[0] corrects the code also.
-------------------------------------------------

Thanks for taking the time to look at this.

Regards,
Armand

He who asks is a fool for five minutes, but he who does not ask remains a
fool forever. - Chinese proverb
Life is just one five minute period after another. - Armand Liberi"



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: GCC Inline ASM generates incorrect assembler code (or documentation is unclear, or I am &*&$@$#*&).
  2001-12-14 14:27 GCC Inline ASM generates incorrect assembler code (or documentation is unclear, or I am &*&$@$#*&) Armand Liberi
@ 2001-12-14 15:51 ` Jan Hubicka
  2001-12-17  8:04   ` Armand Liberi
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Hubicka @ 2001-12-14 15:51 UTC (permalink / raw)
  To: Armand Liberi; +Cc: gcc

> And, I found that:
> 
> 3.  Using lotsOfInts[0] corrects the code also.
I guess you are just hitting the C semantics of arrays. lotsOfInts is pointer to the
array. If you pass it to the asm statement, you get the pointer value, not the array
itself.

Honza
> -------------------------------------------------
> 
> Thanks for taking the time to look at this.
> 
> Regards,
> Armand
> 
> He who asks is a fool for five minutes, but he who does not ask remains a
> fool forever. - Chinese proverb
> Life is just one five minute period after another. - Armand Liberi"
> 
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: GCC Inline ASM generates incorrect assembler code (or documentation is unclear, or I am &*&$@$#*&).
  2001-12-14 15:51 ` Jan Hubicka
@ 2001-12-17  8:04   ` Armand Liberi
  0 siblings, 0 replies; 3+ messages in thread
From: Armand Liberi @ 2001-12-17  8:04 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc

Hello,

I suppose I should clarify my question.  As I stated in my first E-mail, the
initial indication of a problem came when I tried an experiment using an
FSAVE/FRSTOR pair:

asm("FSAVE %0":"=m" (fpEnv)); where fpEnv is an array of 54 unsigned shorts.

and, later,

asm("FRSTORE %0"::"m" (fpEnv)); where fpEnv is an array of 54 unsigned
shorts.

The FSAVE instruction compiles correctly and its execution results in the
storing of the FPU environment in the fpEnv array.  The FRSTOR instruction
compiles incorrectly.  A pointer to fpEnv is passed to the assembler code.
When executed, this results in the FPU environment being "restored" from the
wrong address.

There are at least three ways to "fix" this:

1.  The makers of LynxOS, LynuxWorks, suggested that I use an "output"
constraint for fpEnv in the FRSTOR:

asm("FRSTORE %0":"=m" (fpEnv)); where fpEnv is an array of 54 unsigned
shorts.

This does result in correct assembler code but would seem just a bit
ridiculous in light of the rules (as I read them).  The first is "Each
operand is described by an operand-constraint string followed by the C
expression in parentheses.  A colon separates the assembler template from
the first output operand and another separates the last output from the
first input, if any" (Page 194 of Using and Porting GNU CC under "Assembler
Instructions with C Expression Operands").  Second, "'=' Means that this
operand is write-only for this instruction: the previous value is discarded
and replaced by output data" from page 343 under "Constraint Modifier
Characters."

If there is some defense of this "fix", or "work-around", other than the
fact that it incorrectly generates correct code, please tell me.

2.  LynuxWorks support also suggested that I use no constraints - an option
that I haven't found mentioned in the manual.  So, that would be:

asm("FRSTORE fpEnv"); where fpEnv is an array of 54 unsigned shorts.

That also results in correct code.  However, "A Brief Tutorial on GCC inline
asm (x86 biased)" by Colin Plumb, that I found on the internet appears to
declare this to be a dangerous practice:

"There are two special cases for clobbered values.  One is "memory", meaning
that this instruction writes to some memory (other than a listed output) and
GCC shouldn't cache memory values in registers across this asm.  An asm
memcpy() implementation would need this. You do *not* need to list "memory"
just because outputs are in memory; gcc understands that."

I haven't found any reference in my manual to a "memory" constraint that may
be listed in the "clobber" section and has the effect listed above.  So, as
near as I can tell, this would be an undocumented "fix" that is, to my mind,
not suitable.

3. I tried using "fpEnv[0]" instead of "fpEnv":

asm("FRSTORE %0":"=m" (fpEnv[0])); where fpEnv is an array of 54 unsigned
shorts.

This also generates the correct assembler code and seems to hint at the
problem as Jan has stated - it is a pointer thing.  But, that doesn't
explain much.  In particular, it doesn't explain why this change is not
necessary for the FSAVE output variable.  In other words,

asm("FSAVE %0":"=m" (fpEnv)); where fpEnv is an array of 54 unsigned shorts.
and
asm("FSAVE %0":"=m" (fpEnv[0])); where fpEnv is an array of 54 unsigned
shorts.

generate the same code!  So, what about the "pointer thing"?  Apparently,
the rules (defaults?) for output constraints are different from the rules
(defaults?) for input constraints.  If so, where can I read about that?

So, once again I would like to thank anyone that has gotten this far fro
reading this and if there is some help to be had for me, please let me know!

And, I have tried this on the latest compiler from the CygWin distribution,
an older compiler, and the very old compiler supplied with LynxOS.

One more thing.  Am I writing to some sort of public list that I can
subscribe to?  Thanks.

Regards,
Armand

He who asks is a fool for five minutes, but he who does not ask remains a
fool forever. - Chinese proverb
Life is just one five minute period after another. - Armand Liberi


----- Original Message -----
From: "Jan Hubicka" <jh@suse.cz>
To: "Armand Liberi" <aliberi@acutronic.com>
Cc: <gcc@gcc.gnu.org>
Sent: Friday, December 14, 2001 5:26 PM
Subject: Re: GCC Inline ASM generates incorrect assembler code (or
documentation is unclear, or I am &*&$@$#*&).


> > And, I found that:
> >
> > 3.  Using lotsOfInts[0] corrects the code also.
> I guess you are just hitting the C semantics of arrays. lotsOfInts is
pointer to the
> array. If you pass it to the asm statement, you get the pointer value, not
the array
> itself.
>
> Honza
> > -------------------------------------------------
> >
> > Thanks for taking the time to look at this.
> >
> > Regards,
> > Armand
> >
> > He who asks is a fool for five minutes, but he who does not ask remains
a
> > fool forever. - Chinese proverb
> > Life is just one five minute period after another. - Armand Liberi"
> >
> >
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2001-12-17 15:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-14 14:27 GCC Inline ASM generates incorrect assembler code (or documentation is unclear, or I am &*&$@$#*&) Armand Liberi
2001-12-14 15:51 ` Jan Hubicka
2001-12-17  8:04   ` Armand Liberi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).