Re: egcs 1.0.1 miscompiles Linux 2.0.33

Christof Petig (christof.petig@wtal.de)
Tue, 03 Mar 1998 10:19:10 +0100


Dear Jeff,

I was a shocked by these misunderstandings. Seems that you never tried
to use an asm() on an i386 computer.

What we would like to do is:

- setup register ecx with (-1), esi with (cs).
- execute run the asm-statements
- tell gcc that ecx and esi do no longer contain the values (-1) and
(cs)

What would be the correct way to tell this to gcc if not by inputs and
clobbers?

Had you never had the need for a construct like this? Any non trivial
asm() statement acts this way.

You wrote:

extern inline char * strstr(const char * cs,const char * ct)
{
register char * __res;
__asm__ __volatile__(
"cld\n\t"
[...]
"xorl %%eax,%%eax\n\t"
"2:"
:"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
:"cx","dx","di","si");
return __res;
}

This asm has some serious problems. Any attempt to fix the
compiler
to be more strict with how it uses registers which are clobbered by

the asm is going to lead to problems.

Note that cx and si are mentioned in both the input and clobber
list. This is wrong. You've set up a case where the inputs
and clobbers must be in the same register. This can't work and
is just going to cause problems.

I'm not an x86 hacker, so it's not really clear to me how you
would rewrite that asm. But it's clearly going to need to be
rewritten. And until it is, I can't do much on the compiler
side as I don't have a valid testcase.

Linus Torvalds statet his need for this procedure.

It has always worked before, and it is also the natural way to do
this.
How would you specify that you want something in an input register
but
that gcc must not use it for anything else?

Before you tell me to use the construct

"=c" (dummy).. :"1" (0xffffffff)

I have two arguments against that:

- it requires a dummy variable, which is just silly to export to
the C
level, and can be rather painful in macro expansion.

- it is "more wrong" than the current code with clobbers: it would

still allow gcc to use %ecx as an input to something else _too_
in
case the value 0xffffffff shows up in some other expression
(let's
say that "ct" had that value, and gcc would decide that it can
use
%ecx for "ct" because ct has a constraint of "g" that would
allow
it).

In short, not only does the "use this register for input but
consider it
clobbered otherwise" semantics make sense, there is no other way to

specify that than to use the above kind of construct.

I agree that it may be harder for the compiler to get right, but
that
doesn't change the fact that it's a valid use and that we have a
valid
need for it.

So ignore the actual x86 code, tell me how you _think_ it should
work.
I claim that the current gcc asm syntax doesn't give me much choice
-
even though I agree with you that it looks strange to have a
clobber
that is also an input.

Richard Henderson wrote

You should use "=&c" to say that the output should use a new
register.
That output will be shared with no other input except an explicit
"0".

come on ... this doesn't touch the problem at the head of this message
(we need to pass a value that is clobbered.) Unless you recommend
pushing all passed values on the stack and restoring them before we
leave the asm(). This would make the asm() statement needless, since it
would never _optimize_ anything for a certain machine.

Or is the question:
- is it valid to use a asm() for machine specific optimizations?

Sorry for answering this emotionally but I can't understand why this
need is not obvious to compiler designers.

Mathias Fr"ohlich wrote:

Note that the condition code register is clobbered here, so "cc"
should be
included in the list of clobbered registers!

is this true ??? This is not common at all. I know "cc" is clobbered.
And this should be fixed. But, does any existing compiler rely on this?

Regards Christof

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu