[patch] MIPS gas problems with gcc's explicit relocs

Thiemo Seufer ica2_ts@csv.ica.uni-stuttgart.de
Fri May 28 23:32:00 GMT 2004


Maciej W. Rozycki wrote:
> On Fri, 28 May 2004, Thiemo Seufer wrote:
> 
> > Maciej W. Rozycki wrote:
> > [snip]
> > > 	asm("dla\t%0,%1" : "=r" (result) : "m" (foo));
> > [snip]
> > > 	lui	$2,%highest(foo)
> > > 	daddiu	$2,$2,%higher(foo)
> > > 	dsll	$2,$2,16
> > > 	daddiu	$2,$2,%hi(foo)
> > > 	dsll	$2,$2,16
> > > #APP
> > > 	dla	$2,%lo(foo)($2)
> > > #NO_APP
> > 
> > IMHO this is broken in the compiler. It should either only provide the
> > sympol for %1, [...]
> 
>  This is what gcc 2.95 did and it was inferior -- for each %1 reference, a
> full address load was performed.  A better alternative (and the only one
> if I'd use the "R" constraint; 2.95 got it wrong, though) would be
> finishing the address load sequence before the inline asm and substituting
> "($2)" for %1.  It would waste an instruction if %1 was used for loads and
> stores only, though.

I can't follow you here. As long as gcc is supposed to leave inline asm
alone it shouldn't attempt to do (parts of) the expansion itself. The
resulting asm should be something like

#APP
	dla	$2,foo
#NO_APP

and leave the interpretation up to the assembler.

>  I like the current behavior of gcc for being optimal.

Creating broken code can hardly be called optimal.

> > [...] or handle the dla expansion correctly, preferably with
> > better optimization for superscalar processors (that is, a
> > lui - lui - daddiu - daddiu - dsll32 - daddu sequence).
> 
>  Hmm, do you suggest gcc should interpret the inline asm anyhow?

Not really. :-) I was wondering why loading the "foo" high part resulted
in a suboptimal insn sequence.

>  Anyway, I think gas should be consistent with its interpretation of 
> addresses for load/store and for load address instructions, i.e. it should 
> be possible to split:
> 
> <op>	<reg>,<addr>
> 
> into:
> 
> la	<tmp>,<addr>
> <op>	<reg>,(<tmp>)
> 
> for any valid <addr>.

This would be broken syntax.

	<op>	<reg>,<addr>

loads an absolute address in a register, while

	<op>	<reg>,<addr>(<reg2>)

loads the _content_ pointed to by reg2, with addr as offset.

	<op>	<reg>,(<reg2>)

merely means an offset of zero, and is invalid for (d)la.


Thiemo



More information about the Binutils mailing list