[llvm] r208317 - [ARM64] Check for proper immediate in shift/extend operands

Bradley Smith bradley.smith at arm.com
Thu May 8 07:11:16 PDT 2014


Author: brasmi01
Date: Thu May  8 09:11:16 2014
New Revision: 208317

URL: http://llvm.org/viewvc/llvm-project?rev=208317&view=rev
Log:
[ARM64] Check for proper immediate in shift/extend operands

Modified:
    llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp

Modified: llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp?rev=208317&r1=208316&r2=208317&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp Thu May  8 09:11:16 2014
@@ -56,8 +56,6 @@ private:
   bool parseCondCode(OperandVector &Operands, bool invertCondCode);
   int tryParseRegister();
   int tryMatchVectorRegister(StringRef &Kind, bool expected);
-  bool parseOptionalShift(OperandVector &Operands);
-  bool parseOptionalExtend(OperandVector &Operands);
   bool parseRegister(OperandVector &Operands);
   bool parseMemory(OperandVector &Operands);
   bool parseSymbolicImmVal(const MCExpr *&ImmVal);
@@ -87,6 +85,8 @@ private:
 
   /// }
 
+  OperandMatchResultTy tryParseOptionalShift(OperandVector &Operands);
+  OperandMatchResultTy tryParseOptionalExtend(OperandVector &Operands);
   OperandMatchResultTy tryParseNoIndexMemory(OperandVector &Operands);
   OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
   OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
@@ -2277,60 +2277,72 @@ bool ARM64AsmParser::parseCondCode(Opera
   return false;
 }
 
-/// ParseOptionalShift - Some operands take an optional shift argument. Parse
+/// tryParseOptionalShift - Some operands take an optional shift argument. Parse
 /// them if present.
-bool ARM64AsmParser::parseOptionalShift(OperandVector &Operands) {
+ARM64AsmParser::OperandMatchResultTy
+ARM64AsmParser::tryParseOptionalShift(OperandVector &Operands) {
   const AsmToken &Tok = Parser.getTok();
-  ARM64_AM::ShiftType ShOp = StringSwitch<ARM64_AM::ShiftType>(Tok.getString())
+  std::string LowerID = Tok.getString().lower();
+  ARM64_AM::ShiftType ShOp = StringSwitch<ARM64_AM::ShiftType>(LowerID)
                                  .Case("lsl", ARM64_AM::LSL)
                                  .Case("lsr", ARM64_AM::LSR)
                                  .Case("asr", ARM64_AM::ASR)
                                  .Case("ror", ARM64_AM::ROR)
                                  .Case("msl", ARM64_AM::MSL)
-                                 .Case("LSL", ARM64_AM::LSL)
-                                 .Case("LSR", ARM64_AM::LSR)
-                                 .Case("ASR", ARM64_AM::ASR)
-                                 .Case("ROR", ARM64_AM::ROR)
-                                 .Case("MSL", ARM64_AM::MSL)
                                  .Default(ARM64_AM::InvalidShift);
   if (ShOp == ARM64_AM::InvalidShift)
-    return true;
+    return MatchOperand_NoMatch;
 
   SMLoc S = Tok.getLoc();
   Parser.Lex();
 
   // We expect a number here.
   bool Hash = getLexer().is(AsmToken::Hash);
-  if (!Hash && getLexer().isNot(AsmToken::Integer))
-    return TokError("immediate value expected for shifter operand");
+  if (!Hash && getLexer().isNot(AsmToken::Integer)) {
+    TokError("immediate value expected for shifter operand");
+    return MatchOperand_ParseFail;
+  }
 
   if (Hash)
     Parser.Lex(); // Eat the '#'.
 
+  // Make sure we do actually have a number
+  if (!Parser.getTok().is(AsmToken::Integer)) {
+    Error(Parser.getTok().getLoc(),
+          "expected integer shift amount");
+    return MatchOperand_ParseFail;
+  }
+
   SMLoc ExprLoc = getLoc();
   const MCExpr *ImmVal;
   if (getParser().parseExpression(ImmVal))
-    return true;
+    return MatchOperand_ParseFail;
 
   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
-  if (!MCE)
-    return TokError("immediate value expected for shifter operand");
+  if (!MCE) {
+    TokError("immediate value expected for shifter operand");
+    return MatchOperand_ParseFail;
+  }
 
-  if ((MCE->getValue() & 0x3f) != MCE->getValue())
-    return Error(ExprLoc, "immediate value too large for shifter operand");
+  if ((MCE->getValue() & 0x3f) != MCE->getValue()) {
+    Error(ExprLoc, "immediate value too large for shifter operand");
+    return MatchOperand_ParseFail;
+  }
 
   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
   Operands.push_back(
       ARM64Operand::CreateShifter(ShOp, MCE->getValue(), S, E, getContext()));
-  return false;
+  return MatchOperand_Success;
 }
 
-/// parseOptionalExtend - Some operands take an optional extend argument. Parse
+/// tryParseOptionalExtend - Some operands take an optional extend argument. Parse
 /// them if present.
-bool ARM64AsmParser::parseOptionalExtend(OperandVector &Operands) {
+ARM64AsmParser::OperandMatchResultTy
+ARM64AsmParser::tryParseOptionalExtend(OperandVector &Operands) {
   const AsmToken &Tok = Parser.getTok();
+  std::string LowerID = Tok.getString().lower();
   ARM64_AM::ExtendType ExtOp =
-      StringSwitch<ARM64_AM::ExtendType>(Tok.getString())
+      StringSwitch<ARM64_AM::ExtendType>(LowerID)
           .Case("uxtb", ARM64_AM::UXTB)
           .Case("uxth", ARM64_AM::UXTH)
           .Case("uxtw", ARM64_AM::UXTW)
@@ -2340,18 +2352,9 @@ bool ARM64AsmParser::parseOptionalExtend
           .Case("sxth", ARM64_AM::SXTH)
           .Case("sxtw", ARM64_AM::SXTW)
           .Case("sxtx", ARM64_AM::SXTX)
-          .Case("UXTB", ARM64_AM::UXTB)
-          .Case("UXTH", ARM64_AM::UXTH)
-          .Case("UXTW", ARM64_AM::UXTW)
-          .Case("UXTX", ARM64_AM::UXTX)
-          .Case("LSL", ARM64_AM::UXTX) // Alias for UXTX
-          .Case("SXTB", ARM64_AM::SXTB)
-          .Case("SXTH", ARM64_AM::SXTH)
-          .Case("SXTW", ARM64_AM::SXTW)
-          .Case("SXTX", ARM64_AM::SXTX)
           .Default(ARM64_AM::InvalidExtend);
   if (ExtOp == ARM64_AM::InvalidExtend)
-    return true;
+    return MatchOperand_NoMatch;
 
   SMLoc S = Tok.getLoc();
   Parser.Lex();
@@ -2361,7 +2364,7 @@ bool ARM64AsmParser::parseOptionalExtend
     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
     Operands.push_back(
         ARM64Operand::CreateExtend(ExtOp, 0, S, E, getContext()));
-    return false;
+    return MatchOperand_Success;
   }
 
   bool Hash = getLexer().is(AsmToken::Hash);
@@ -2369,24 +2372,33 @@ bool ARM64AsmParser::parseOptionalExtend
     SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
     Operands.push_back(
         ARM64Operand::CreateExtend(ExtOp, 0, S, E, getContext()));
-    return false;
+    return MatchOperand_Success;
   }
 
   if (Hash)
     Parser.Lex(); // Eat the '#'.
 
+  // Make sure we do actually have a number
+  if (!Parser.getTok().is(AsmToken::Integer)) {
+    Error(Parser.getTok().getLoc(),
+          "expected integer shift amount");
+    return MatchOperand_ParseFail;
+  }
+
   const MCExpr *ImmVal;
   if (getParser().parseExpression(ImmVal))
-    return true;
+    return MatchOperand_ParseFail;
 
   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
-  if (!MCE)
-    return TokError("immediate value expected for extend operand");
+  if (!MCE) {
+    TokError("immediate value expected for extend operand");
+    return MatchOperand_ParseFail;
+  }
 
   SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
   Operands.push_back(
       ARM64Operand::CreateExtend(ExtOp, MCE->getValue(), S, E, getContext()));
-  return false;
+  return MatchOperand_Success;
 }
 
 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
@@ -3216,12 +3228,16 @@ bool ARM64AsmParser::parseOperand(Operan
       return false;
 
     // This could be an optional "shift" operand.
-    if (!parseOptionalShift(Operands))
-      return false;
+    OperandMatchResultTy GotShift = tryParseOptionalShift(Operands);
+    // We can only continue if no tokens were eaten.
+    if (GotShift != MatchOperand_NoMatch)
+      return GotShift;
 
     // Or maybe it could be an optional "extend" operand.
-    if (!parseOptionalExtend(Operands))
-      return false;
+    OperandMatchResultTy GotExtend = tryParseOptionalExtend(Operands);
+    // We can only continue if no tokens were eaten.
+    if (GotExtend != MatchOperand_NoMatch)
+      return GotExtend;
 
     // This was not a register so parse other operands that start with an
     // identifier (like labels) as expressions and create them as immediates.





More information about the llvm-commits mailing list