[llvm] r271644 - [mips] Implement 'la' macro in PIC mode for O32.
Daniel Sanders via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 3 02:53:06 PDT 2016
Author: dsanders
Date: Fri Jun 3 04:53:06 2016
New Revision: 271644
URL: http://llvm.org/viewvc/llvm-project?rev=271644&view=rev
Log:
[mips] Implement 'la' macro in PIC mode for O32.
Summary:
N32 support will follow in a later patch since the symbol version of 'la'
incorrectly believes N32 to have 64-bit pointers and rejects it early.
This fixes the three incorrectly expanded 'la' macros found in bionic.
Reviewers: sdardis
Subscribers: dsanders, llvm-commits, sdardis
Differential Revision: http://reviews.llvm.org/D20820
Added:
llvm/trunk/test/MC/Mips/macro-la-pic.s
Modified:
llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
llvm/trunk/test/CodeGen/Mips/hf1_body.ll
Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=271644&r1=271643&r2=271644&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Fri Jun 3 04:53:06 2016
@@ -2376,15 +2376,85 @@ bool MipsAsmParser::loadAndAddSymbolAddr
MCStreamer &Out,
const MCSubtargetInfo *STI) {
MipsTargetStreamer &TOut = getTargetStreamer();
+ bool UseSrcReg = SrcReg != Mips::NoRegister;
warnIfNoMacro(IDLoc);
- const MCExpr *Symbol = cast<MCExpr>(SymExpr);
+ if (inPicMode() && ABI.IsO32()) {
+ MCValue Res;
+ if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
+ Error(IDLoc, "expected relocatable expression");
+ return true;
+ }
+ if (Res.getSymB() != nullptr) {
+ Error(IDLoc, "expected relocatable expression with only one symbol");
+ return true;
+ }
+
+ // The case where the result register is $25 is somewhat special. If the
+ // symbol in the final relocation is external and not modified with a
+ // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
+ if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
+ Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() &&
+ !Res.getSymA()->getSymbol().isTemporary()) {
+ const MCExpr *CallExpr =
+ MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
+ TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
+ MCOperand::createExpr(CallExpr), IDLoc, STI);
+ return false;
+ }
+
+ // The remaining cases are:
+ // External GOT: lw $tmp, %got(symbol+offset)($gp)
+ // >addiu $tmp, $tmp, %lo(offset)
+ // >addiu $rd, $tmp, $rs
+ // Local GOT: lw $tmp, %got(symbol+offset)($gp)
+ // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
+ // >addiu $rd, $tmp, $rs
+ // The addiu's marked with a '>' may be omitted if they are redundant. If
+ // this happens then the last instruction must use $rd as the result
+ // register.
+ const MipsMCExpr *GotExpr =
+ MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
+ const MCExpr *LoExpr = nullptr;
+ if (Res.getSymA()->getSymbol().isInSection() ||
+ Res.getSymA()->getSymbol().isTemporary())
+ LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
+ else if (Res.getConstant() != 0) {
+ // External symbols fully resolve the symbol with just the %got(symbol)
+ // but we must still account for any offset to the symbol for expressions
+ // like symbol+8.
+ LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
+ }
+
+ unsigned TmpReg = DstReg;
+ if (UseSrcReg &&
+ getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
+ SrcReg)) {
+ // If $rs is the same as $rd, we need to use AT.
+ // If it is not available we exit.
+ unsigned ATReg = getATReg(IDLoc);
+ if (!ATReg)
+ return true;
+ TmpReg = ATReg;
+ }
+
+ TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
+ MCOperand::createExpr(GotExpr), IDLoc, STI);
+
+ if (LoExpr)
+ TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
+ IDLoc, STI);
+
+ if (UseSrcReg)
+ TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
+
+ return false;
+ }
+
const MipsMCExpr *HiExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_HI, Symbol, getContext());
+ MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
const MipsMCExpr *LoExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_LO, Symbol, getContext());
-
- bool UseSrcReg = SrcReg != Mips::NoRegister;
+ MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
// This is the 64-bit symbol address expansion.
if (ABI.ArePtrs64bit() && isGP64bit()) {
@@ -2395,9 +2465,9 @@ bool MipsAsmParser::loadAndAddSymbolAddr
return true;
const MipsMCExpr *HighestExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, Symbol, getContext());
+ MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
const MipsMCExpr *HigherExpr =
- MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, Symbol, getContext());
+ MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
if (UseSrcReg &&
getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
Modified: llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp?rev=271644&r1=271643&r2=271644&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp (original)
+++ llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp Fri Jun 3 04:53:06 2016
@@ -122,33 +122,6 @@ void MipsInstPrinter::printInst(const MC
}
}
-static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,
- raw_ostream &OS) {
- int Offset = 0;
- const MCSymbolRefExpr *SRE;
-
- if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
- SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
- const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(BE->getRHS());
- assert(SRE && CE && "Binary expression must be sym+const.");
- Offset = CE->getValue();
- } else if (const MipsMCExpr *ME = dyn_cast<MipsMCExpr>(Expr)) {
- ME->print(OS, MAI);
- return;
- } else
- SRE = cast<MCSymbolRefExpr>(Expr);
-
- assert(SRE->getKind() == MCSymbolRefExpr::VK_None && "Invalid kind!");
-
- SRE->getSymbol().print(OS, MAI);
-
- if (Offset) {
- if (Offset > 0)
- OS << '+';
- OS << Offset;
- }
-}
-
void MipsInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
raw_ostream &O) {
const MCOperand &Op = MI->getOperand(OpNo);
@@ -163,7 +136,7 @@ void MipsInstPrinter::printOperand(const
}
assert(Op.isExpr() && "unknown operand kind in printOperand");
- printExpr(Op.getExpr(), &MAI, O);
+ Op.getExpr()->print(O, &MAI, true);
}
template <unsigned Bits, unsigned Offset>
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp?rev=271644&r1=271643&r2=271644&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.cpp Fri Jun 3 04:53:06 2016
@@ -102,6 +102,10 @@ unsigned MipsABIInfo::GetBasePtr() const
return ArePtrs64bit() ? Mips::S7_64 : Mips::S7;
}
+unsigned MipsABIInfo::GetGlobalPtr() const {
+ return ArePtrs64bit() ? Mips::GP_64 : Mips::GP;
+}
+
unsigned MipsABIInfo::GetNullPtr() const {
return ArePtrs64bit() ? Mips::ZERO_64 : Mips::ZERO;
}
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h?rev=271644&r1=271643&r2=271644&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsABIInfo.h Fri Jun 3 04:53:06 2016
@@ -66,6 +66,7 @@ public:
unsigned GetStackPtr() const;
unsigned GetFramePtr() const;
unsigned GetBasePtr() const;
+ unsigned GetGlobalPtr() const;
unsigned GetNullPtr() const;
unsigned GetZeroReg() const;
unsigned GetPtrAdduOp() const;
Modified: llvm/trunk/test/CodeGen/Mips/hf1_body.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Mips/hf1_body.ll?rev=271644&r1=271643&r2=271644&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/Mips/hf1_body.ll (original)
+++ llvm/trunk/test/CodeGen/Mips/hf1_body.ll Fri Jun 3 04:53:06 2016
@@ -23,7 +23,7 @@ entry:
; ALL: .set reorder
; ALL: .reloc 0, R_MIPS_NONE, v_sf
; GAS: la $25, $__fn_local_v_sf
-; IAS: lui $25, %hi($$__fn_local_v_sf)
+; IAS: lw $25, %got($$__fn_local_v_sf)($gp)
; IAS: addiu $25, $25, %lo($$__fn_local_v_sf)
; ALL: mfc1 $4, $f12
; ALL: jr $25
Added: llvm/trunk/test/MC/Mips/macro-la-pic.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/macro-la-pic.s?rev=271644&view=auto
==============================================================================
--- llvm/trunk/test/MC/Mips/macro-la-pic.s (added)
+++ llvm/trunk/test/MC/Mips/macro-la-pic.s Fri Jun 3 04:53:06 2016
@@ -0,0 +1,54 @@
+# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 | \
+# RUN: FileCheck %s
+# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r6 | \
+# RUN: FileCheck %s
+# N32 should be acceptable too but it currently errors out.
+# N64 should be acceptable too but we cannot convert la to dla yet.
+
+.option pic2
+la $5, symbol # CHECK: lw $5, %got(symbol)($gp) # encoding: [0x8f,0x85,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+la $5, symbol($6) # CHECK: lw $5, %got(symbol)($gp) # encoding: [0x8f,0x85,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+ # CHECK: addu $5, $5, $6 # encoding: [0x00,0xa6,0x28,0x21]
+la $6, symbol($6) # CHECK: lw $1, %got(symbol)($gp) # encoding: [0x8f,0x81,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+ # CHECK: addu $6, $1, $6 # encoding: [0x00,0x26,0x30,0x21]
+la $5, symbol+8 # CHECK: lw $5, %got(symbol+8)($gp) # encoding: [0x8f,0x85,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+la $5, symbol+8($6) # CHECK: lw $5, %got(symbol+8)($gp) # encoding: [0x8f,0x85,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+ # CHECK: addu $5, $5, $6 # encoding: [0x00,0xa6,0x28,0x21]
+la $6, symbol+8($6) # CHECK: lw $1, %got(symbol+8)($gp) # encoding: [0x8f,0x81,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+ # CHECK: addiu $1, $1, 8 # encoding: [0x24,0x21,0x00,0x08]
+ # CHECK: addu $6, $1, $6 # encoding: [0x00,0x26,0x30,0x21]
+la $5, 1f # CHECK: lw $5, %got($tmp0)($gp) # encoding: [0x8f,0x85,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got($tmp0), kind: fixup_Mips_GOT
+ # CHECK: addiu $5, $5, %lo($tmp0) # encoding: [0x24,0xa5,A,A]
+ # CHECK: # fixup A - offset: 0, value: %lo($tmp0), kind: fixup_Mips_LO16
+1:
+
+# PIC expansions involving $25 are special.
+la $25, symbol # CHECK: lw $25, %call16(symbol)($gp) # encoding: [0x8f,0x99,A,A]
+ # CHECK: # fixup A - offset: 0, value: %call16(symbol), kind: fixup_Mips_CALL16
+la $25, symbol($6) # CHECK: lw $25, %got(symbol)($gp) # encoding: [0x8f,0x99,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+ # CHECK: addu $25, $25, $6 # encoding: [0x03,0x26,0xc8,0x21]
+la $25, symbol($25) # CHECK: lw $1, %got(symbol)($gp) # encoding: [0x8f,0x81,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol), kind: fixup_Mips_GOT
+ # CHECK: addu $25, $1, $25 # encoding: [0x00,0x39,0xc8,0x21]
+la $25, symbol+8 # CHECK: lw $25, %got(symbol+8)($gp) # encoding: [0x8f,0x99,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+la $25, symbol+8($6) # CHECK: lw $25, %got(symbol+8)($gp) # encoding: [0x8f,0x99,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+ # CHECK: addu $25, $25, $6 # encoding: [0x03,0x26,0xc8,0x21]
+la $25, symbol+8($25) # CHECK: lw $1, %got(symbol+8)($gp) # encoding: [0x8f,0x81,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got(symbol+8), kind: fixup_Mips_GOT
+ # CHECK: addiu $1, $1, 8 # encoding: [0x24,0x21,0x00,0x08]
+ # CHECK: addu $25, $1, $25 # encoding: [0x00,0x39,0xc8,0x21]
+la $25, 1f # CHECK: lw $25, %got($tmp1)($gp) # encoding: [0x8f,0x99,A,A]
+ # CHECK: # fixup A - offset: 0, value: %got($tmp1), kind: fixup_Mips_GOT
+ # CHECK: addiu $25, $25, %lo($tmp1) # encoding: [0x27,0x39,A,A]
+ # CHECK: # fixup A - offset: 0, value: %lo($tmp1), kind: fixup_Mips_LO16
+1:
More information about the llvm-commits
mailing list