diff options
| author | David Green <david.green@arm.com> | 2018-09-18 09:44:53 +0000 |
|---|---|---|
| committer | David Green <david.green@arm.com> | 2018-09-18 09:44:53 +0000 |
| commit | 85d6a5599509fef8f2b5fe72f4ee23187d65c68e (patch) | |
| tree | 0f493dca96c224fd8f1296b0633995c7a3950cd5 /llvm/lib/Target | |
| parent | 4c077f987c6725012fa47730e9aeba513ea4acb5 (diff) | |
| download | bcm5719-llvm-85d6a5599509fef8f2b5fe72f4ee23187d65c68e.tar.gz bcm5719-llvm-85d6a5599509fef8f2b5fe72f4ee23187d65c68e.zip | |
[AArch64] Attempt to parse more operands as expressions
This tries to make use of evaluateAsRelocatable in AArch64AsmParser::classifySymbolRef
to parse more complex expressions as relocatable operands. It is hopefully better than
the existing code which only handles Symbol +- Constant.
This allows us to parse more complex adr/adrp, mov, ldr/str and add operands. It also
loosens the requirements on parsing addends in ld/st and mov's and adds a number of
tests.
Differential Revision: https://reviews.llvm.org/D51792
llvm-svn: 342455
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 35 |
1 files changed, 11 insertions, 24 deletions
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index e18498c8a4d..8a33d294c57 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -39,6 +39,7 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetOptions.h" #include "llvm/MC/SubtargetFeature.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" @@ -658,7 +659,7 @@ public: return DiagnosticPredicateTy::NearMatch; } - bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const { + bool isSymbolicUImm12Offset(const MCExpr *Expr) const { AArch64MCExpr::VariantKind ELFRefKind; MCSymbolRefExpr::VariantKind DarwinRefKind; int64_t Addend; @@ -683,7 +684,7 @@ public: // Note that we don't range-check the addend. It's adjusted modulo page // size when converted, so there is no "out of range" condition when using // @pageoff. - return Addend >= 0 && (Addend % Scale) == 0; + return true; } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) { // @gotpageoff/@tlvppageoff can only be used directly, not with an addend. @@ -699,7 +700,7 @@ public: const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm()); if (!MCE) - return isSymbolicUImm12Offset(getImm(), Scale); + return isSymbolicUImm12Offset(getImm()); int64_t Val = MCE->getValue(); return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000; @@ -901,7 +902,7 @@ public: for (unsigned i = 0; i != AllowedModifiers.size(); ++i) { if (ELFRefKind == AllowedModifiers[i]) - return Addend == 0; + return true; } return false; @@ -5305,28 +5306,14 @@ AArch64AsmParser::classifySymbolRef(const MCExpr *Expr, return true; } - const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); - if (!BE) - return false; - - SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS()); - if (!SE) - return false; - DarwinRefKind = SE->getKind(); - - if (BE->getOpcode() != MCBinaryExpr::Add && - BE->getOpcode() != MCBinaryExpr::Sub) - return false; - - // See if the addend is a constant, otherwise there's more going - // on here than we can deal with. - auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); - if (!AddendExpr) + // Check that it looks like a symbol + an addend + MCValue Res; + bool Relocatable = Expr->evaluateAsRelocatable(Res, nullptr, nullptr); + if (!Relocatable || !Res.getSymA() || Res.getSymB()) return false; - Addend = AddendExpr->getValue(); - if (BE->getOpcode() == MCBinaryExpr::Sub) - Addend = -Addend; + DarwinRefKind = Res.getSymA()->getKind(); + Addend = Res.getConstant(); // It's some symbol reference + a constant addend, but really // shouldn't use both Darwin and ELF syntax. |

