%hi($tmp) and %lo($tmp) relocations for Mips backend, where $tmp = sym1 - sym2

Mark Seaborn mseaborn at chromium.org
Wed Jan 15 18:21:19 PST 2014


Thanks for the detailed explanation, and sorry for the delayed reply.

The fact that %lo and %hi (VK_Mips_ABS_{HI,LO}) can only be attached to a
MCSymbolRefExpr does seem to be a bit wrong.  They are really functions,
which should be able to wrap any MCExpr.  The fact that "%hi(x - y)" seems
to be converted to "%hi(x) - %hi(y)" by the parser adds to the confusion.
 More comments below...

On 24 December 2013 12:39, Sasa Stankovic <Sasa.Stankovic at rt-rk.com> wrote:

> > 2) Why is it that you handle cases like:
> >
> > .set diff, label2 - label1
> > lui $2, %lo(diff)
> >
> > but not cases where that is written more directly as:
> >
> > lui $2, %lo(label2 - label1)
> >
> > (which still gives the UNREACHABLE error I described earlier in the
> > thread)?  Is it just because the former is easier to implement?  If so,
> is
> > that just a quirk of how these cases are handled via different code paths
> > in MC?
>
> Implementing %lo(label2 - label1) was first thing that I tried. The
> problem was that no MCBinaryExpr constructor takes relocation kind as
> argument; relocations can only be passed to MCSymbolRefExpr. Currently,
> when MipsAsmParser parses %lo(label2 - label1), it creates MCBinaryExpr
> where both operands are MCSymbolRefExpr, and both operands have relocation
> kind for %lo relocation (VK_Mips_ABS_LO). This is the reason for
> UNREACHABLE error, because there are two identical relocations for the
> same offset in .o file.
>
> I then tried to pass VK_Mips_None instead of VK_Mips_ABS_LO to second
> operand, but this also produced couple of UNREACHABLE errors, this time in
> Mips specific code.
>
> Finally, I created target-specific MCExpr subclass, as a subclass of
> MCTargetExpr. The implementation was similar to
> lib/Target/ARM/MCTargetDesc/ARMMCExpr.h. This class has members for
> expression and relocation kind, so associating relocation to expression as
> a whole was easy.
>

Thanks for pointing out ARMMCExpr.h.  Taking a similar approach to
ARMMCExpr.h does seem like it would be a lot cleaner.

Grepping for EvaluateAsRelocatableImpl() shows that this does seem to be
the normal way to implement hi/lo functions in MC.  The following targets
define their own MCExpr subclasses:

 * lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.h
 * lib/Target/ARM/MCTargetDesc/ARMMCExpr.h
 * lib/Target/NVPTX/NVPTXMCExpr.h
 * lib/Target/PowerPC/MCTargetDesc/PPCMCExpr.h (confusingly, this defines
VK_PPC_LO, but there's another VK_PPC_LO defined in
include/llvm/MC/MCExpr.h)
 * lib/Target/Sparc/MCTargetDesc/SparcMCExpr.h

The ARM and NVPTX implementations of EvaluateAsRelocatableImpl() don't
delegate to their subexpressions, but the rest do, calling
getSubExpr()->EvaluateAsRelocatable(), which is what you'd want to do for a
MIPS version so that %lo/%hi work in any context that can accept a constant.



> The patch worked, but then people at Mips noted that gas supports
> assigning symbol difference to temp symbol and applying %hi and %lo on
> that symbol. That seemed much simpler.


The temp symbol approach might be a smaller patch, but it does seem like a
hack that's working around limitations elsewhere.  Can you post the earlier
patch you had for adding a Mips MCExpr subclass?

Cheers,
Mark
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140115/6408abf8/attachment.html>


More information about the llvm-commits mailing list