This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: MIPS gas relaxation still doesn't work


On 16 Oct 2002, Jim Wilson wrote:

> > The tough problems I've noticed so far is the small limit
> >on the number of constraints, which is only ten
> 
> This should be fixed as of gcc-3.1, since you can have named operands now.
> Taking an example from the gcc docs:
>         asm ("cmoveq %1,%2,%[result]"
>              : [result] "=r"(result)
>              : "r" (test), "r"(new), "[result]"(old));

 Excellent!  Please forgive me being a bit behind on recent gcc
developments, but so far I needed a stable version to debug Linux (and
previously glibc), so I stuck to 2.95.4 for MIPS (and for others, for
consistency) so far.

> > and the unability to pass
> >a machine address, as the "R" constraint, which is expected to provide the
> >function, doesn't work here and the "m" and "o" ones may require a macro
> >expansion. 
> 
> I'm not sure exactly what problem you are trying to report here, but I think
> it is likely true that we will need new constraint codes.  Previously we didn't
> need special constraint codes for asms because everyone relied on the assembler
> macros for loads.  Now that we want to get people to stop using assembler
> macros, we may need to add special constraint codes so that people can write
> the asms that they need.

 Sometimes there is a need for a machine expressable address (i.e. of the
"imm16(reg)" form), such as in the following code (a real-life example): 

static inline void set_bit(unsigned long nr, volatile void *addr)
{
	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
	unsigned long temp;

	__asm__ __volatile__(
		"1:\tlld\t%0, %1\t\t# set_bit\n\t"
		"or\t%0, %2\n\t"
		"scd\t%0, %1\n\t"
		"beqz\t%0, 1b"
		: "=&r" (temp), "=m" (*m)
		: "ir" (1UL << (nr & 0x3f)), "m" (*m)
		: "memory");
}

This works but it sucks -- if "addr" is a global variable both "lld" and
"scd" may unnecessarily expand to many instructions.  Additionally if $at
becomes unavailable, the code doesn't build.

 Currently this may be solved as follows: 

static inline void set_bit(unsigned long nr, volatile void *addr)
{
	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
	unsigned long temp, ptr;

	__asm__ __volatile__(
		".set\tpush\n\t"
		".set\tnoat\n\t"
		"dla\t%2, %4\t\t# set_bit\n\t"
		"1:\tlld\t%0, (%2)\n\t"
		"or\t%0, %3\n\t"
		"scd\t%0, (%2)\n\t"
		"beqz\t%0, 1b\n\t"
		".set\pop"
		: "=&r" (temp), "=m" (*m), "=&r" (ptr)
		: "Ir" (1UL << (nr & 0x3f)), "m" (*m)
		: "memory");
}

At least it works, but it sucks as well -- the "dla" may be unnecessary if
"addr" happens to be already loaded into one of registers or is an
automatic variable accessible e.g. with imm16($sp).

 This begs to be rewritten simply as follows:

static inline void set_bit(unsigned long nr, volatile void *addr)
{
	unsigned long *m = ((unsigned long *) addr) + (nr >> 6);
	unsigned long temp;

	__asm__ __volatile__(
		".set\tpush\n\t"
		".set\tnoat\n\t"
		"1:\tlld\t%0, %1\t\t# set_bit\n\t"
		"or\t%0, %2\n\t"
		"scd\t%0, %1\n\t"
		"beqz\t%0, 1b\n\t"
		".set\pop"
		: "=&r" (temp), "=R" (*m)
		: "Ir" (1UL << (nr & 0x3f)), "R" (*m)
		: "memory");
}

as the definition of "R" is "imm16(reg)".  This should let gcc emit any
reloads if necessary and allow the code not to worry about loading of the
address itself (which is not a subject of it).  But it often doesn't work.
If the "m" address happens to fit the "R" constraint, it works fine,
otherwise an "`asm' operand requires impossible reload" error triggers.  A
brief study of gcc I did not so long ago revealed it doesn't have any way
to deduce how to do a reload between an operand that satisfies the "m" 
constraint and an operand that satisfies the "R" one.

 There is a number of places in Linux that would benefit from working "R".

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]