After looking up the error in the FAQ for the new gcc it looks like I
need to learn more about asm statements.
[[ asm-err.txt : 4633 in asm-err.txt ]]
I have included the excerpt on why it believes that the rtl_time.h
statements are incorrect (line 158 and the next function that uses cx). I
can try to fix this but if there is a lot more to do besides this then I
would rather wait and leave this as a TODO. Also note that this might not
be isolated to rtl_time.h as any asm statement may contain it. Also the
kernel and rtl both compile on their own, the kernel boots and X runs,
the modules for rtl can be inserted, but no new applications can be made.
The include file shows how to fix the problem but there may or may not be
hidden dependencies that I am unaware of in the rtl code. Please let me
know the status and direction to go (fix or wait).
Thanks,
John
Problems with invalid `asm' statements

Previous releases of GCC (for example, GCC 2.7.2 or EGCS 1.1.2) did not detect as 
invalid a clobber specifier that
clobbered an operand. Instead, it could spuriously and silently generate incorrect 
code for certain non-obvious cases of
source code. Even more unfortunately, the manual (Using and Porting GCC, section 
Extended Asm, see the bug report
entry) did not explicitly say that it was invalid to specify clobber registers that 
were destined to overlap operands; it
could arguably be interpreted that it was correct to clobber an input operand to mark 
it as not holding a usable value
after the asm.

For the general case, there is no way to tell whether a specified clobber is intended 
to overlap with a specific (input)
operand or is a program error, where the choice of actual register for operands failed 
to avoid the clobbered register.
Such unavoidable overlap is detected by versions GCC 2.95 and newer, and flagged as an 
error rather than accepted. An
error message is given, such as:

  foo.c: In function `foo':
  foo.c:7: Invalid `asm' statement:
  foo.c:7: fixed or forbidden register 0 (ax) was spilled for class AREG.

Unfortunately, a lot of existing software, for example the Linux kernel version 2.0.35 
for the Intel x86, has constructs
where input operands are marked as clobbered.

The manual now describes how to write constructs with operands that are modified by 
the construct, but not actually
used. To write an asm which modifies an input operand but does not output anything 
usable, specify that operand as an
output operand outputting to an unused dummy variable.

In the following example for the x86 architecture (taken from the Linux 2.0.35 kernel 
-- include/asm-i386/delay.h),
the register-class constraint "a" denotes a register class containing the single 
register "ax" (aka. "eax"). It is
therefore invalid to clobber "ax"; this operand has to be specified as an output as 
well as an input. The following code is
therefore invalid:

extern __inline__ void
__delay (int loops)
{
  __asm__ __volatile__
    (".align 2,0x90\n1:\tdecl %0\n\tjns 1b"
     : /* no outputs */
     : "a" (loops)
     : "ax");
}

It could be argued that since the register class for "a" contains only a single 
register, this could be detected as an
"obvious" intended clobber of the input operand. While that is feasible, it opens up 
for further "obvious" cases, where
the level of obviousness changes from person to person. As there is a correct way to 
write such asm constructs, this
obviousness-detection is not needed other than for reasons of compatibility with an 
existing code-base, and that code
base can be corrected.

This corrected and clobber-less version, is valid for GCC 2.95 as well as for previous 
versions of GCC and EGCS:

extern __inline__ void
__delay (int loops)
{
  int dummy;

  __asm__ __volatile__
    (".align 2,0x90\n1:\tdecl %0\n\tjns 1b"
     : "=a" (dummy)
     : "0" (loops));
}

Note that the asm construct now has an output operand, but it is unused. Normally asm 
constructs with only unused
output operands may be removed by gcc, unless marked volatile as above.

Reply via email to