summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index d13234cafdb..7f2159f79e1 100644
--- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "MCTargetDesc/SystemZMCTargetDesc.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
@@ -368,6 +369,17 @@ public:
}
OperandMatchResultTy
parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
+ OperandMatchResultTy
+ parsePCRel(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ int64_t MinVal, int64_t MaxVal);
+ OperandMatchResultTy
+ parsePCRel16(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ return parsePCRel(Operands, -(1LL << 16), (1LL << 16) - 1);
+ }
+ OperandMatchResultTy
+ parsePCRel32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1);
+ }
};
}
@@ -653,6 +665,37 @@ parseAccessReg(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return MatchOperand_Success;
}
+SystemZAsmParser::OperandMatchResultTy SystemZAsmParser::
+parsePCRel(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
+ int64_t MinVal, int64_t MaxVal) {
+ MCContext &Ctx = getContext();
+ MCStreamer &Out = getStreamer();
+ const MCExpr *Expr;
+ SMLoc StartLoc = Parser.getTok().getLoc();
+ if (getParser().parseExpression(Expr))
+ return MatchOperand_NoMatch;
+
+ // For consistency with the GNU assembler, treat immediates as offsets
+ // from ".".
+ if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) {
+ int64_t Value = CE->getValue();
+ if ((Value & 1) || Value < MinVal || Value > MaxVal) {
+ Error(StartLoc, "offset out of range");
+ return MatchOperand_ParseFail;
+ }
+ MCSymbol *Sym = Ctx.CreateTempSymbol();
+ Out.EmitLabel(Sym);
+ const MCExpr *Base = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
+ Ctx);
+ Expr = Value == 0 ? Base : MCBinaryExpr::CreateAdd(Base, Expr, Ctx);
+ }
+
+ SMLoc EndLoc =
+ SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ Operands.push_back(SystemZOperand::createImm(Expr, StartLoc, EndLoc));
+ return MatchOperand_Success;
+}
+
// Force static initialization.
extern "C" void LLVMInitializeSystemZAsmParser() {
RegisterMCAsmParser<SystemZAsmParser> X(TheSystemZTarget);
OpenPOWER on IntegriCloud