%hi($tmp) and %lo($tmp) relocations for Mips backend, where $tmp = sym1 - sym2
Mark Seaborn
mseaborn at chromium.org
Thu Dec 12 13:24:53 PST 2013
On 12 December 2013 12:21, Mark Seaborn <mseaborn at chromium.org> wrote:
> On 11 December 2013 14:05, Sasa Stankovic <Sasa.Stankovic at rt-rk.com>wrote:
>
>> + // Check for expressions %hi(tmp) and %lo(tmp), where tmp =
>> sym1-sym2.
>>
> + if (Target.getSymA() != NULL &&
>> Target.getSymA()->getSymbol().isVariable()
>> + && Target.getSymB() == NULL && Target.getConstant() == 0) {
>> + const MCExpr *SymValue = Target.getSymA()->getSymbol()
>> + .getVariableValue();
>> + const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(SymValue);
>> +
>> + if (BE && BE->getOpcode() == MCBinaryExpr::Sub) {
>> + const MCSymbolRefExpr *LHS =
>> dyn_cast<MCSymbolRefExpr>(BE->getLHS());
>> + const MCSymbolRefExpr *RHS =
>> dyn_cast<MCSymbolRefExpr>(BE->getRHS());
>> + if (LHS != NULL && LHS->getSymbol().isDefined()
>> + && RHS != NULL && RHS->getSymbol().isDefined()) {
>> + // Don't emit relocation for expressions %hi(tmp) and
>> %lo(tmp),
>> + // where tmp = sym1-sym2.
>> + IsResolved = true;
>> +
>> + // Calculate symbol value.
>> + uint64_t Value1 =
>> +
>> Layout.getSymbolOffset(&Asm.getSymbolData(LHS->getSymbol()));
>> + uint64_t Value2 =
>> +
>> Layout.getSymbolOffset(&Asm.getSymbolData(RHS->getSymbol()));
>> + Value = Value1 - Value2;
>> + }
>> + }
>> + }
>
>
> I think you shouldn't need to add code for evaluating a Sub expression to
> a MIPS-specific file (as I commented on an earlier version of this change
> at
> https://codereview.chromium.org/27690005/diff/188001/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp#newcode116
> ).
>
To expand on that, currently if I try to compile this test code:
__asm__(
"lui $2, %lo(label2 - label1)\n"
"label1:\n"
".fill 0x54321\n"
"label2:\n");
Then I get the error:
ELFRelocs might be unstable!
UNREACHABLE executed at .../sw/llvm/lib/MC/MCELFObjectTargetWriter.cpp:54!
which is caused by:
1) having two relocations generated for the same address, and
2) the lack of a "return 0" in cmpRel() in MCELFObjectTargetWriter.cpp to
handle (1).
If I fix (2) by adding a "return 0", then I get:
$ clang symbol_diff_asm.c -emit-llvm -S -o - | llc - -o obj.o -mtriple mips
-filetype=obj
$ mipsel-linux-gnu-objdump -Dr obj.o
...
0: 3c024325 lui v0,0x4325
0: R_MIPS_LO16 .text
0: R_MIPS_LO16 .text
We end up with two R_MIPS_LO16 relocations for the same address
because getExprOpValue() in MipsMCCodeEmitter.cpp does this:
if (Kind == MCExpr::Binary) {
unsigned Res = getExprOpValue(cast<MCBinaryExpr>(Expr)->getLHS(),
Fixups);
Res += getExprOpValue(cast<MCBinaryExpr>(Expr)->getRHS(), Fixups);
return Res;
}
That code is clearly wrong because it treats any binary operator, including
"-", as a "+"! If you're going to fix "-" to work, it might be a good idea
to fix that incorrect code.
Cheers,
Mark
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131212/9ec12087/attachment.html>
More information about the llvm-commits
mailing list