|
63 | 63 | #include <iterator>
|
64 | 64 | #include <limits>
|
65 | 65 | #include <memory>
|
| 66 | +#include <optional> |
66 | 67 | #include <string>
|
67 | 68 | #include <utility>
|
68 | 69 | #include <vector>
|
@@ -457,6 +458,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
457 | 458 | int tryParseRegister(bool AllowOutofBoundReg = false);
|
458 | 459 | bool tryParseRegisterWithWriteBack(OperandVector &);
|
459 | 460 | int tryParseShiftRegister(OperandVector &);
|
| 461 | + std::optional<ARM_AM::ShiftOpc> tryParseShiftToken(); |
460 | 462 | bool parseRegisterList(OperandVector &, bool EnforceOrder = true,
|
461 | 463 | bool AllowRAAC = false,
|
462 | 464 | bool AllowOutOfBoundReg = false);
|
@@ -647,12 +649,13 @@ class ARMAsmParser : public MCTargetAsmParser {
|
647 | 649 | ParseStatus parseProcIFlagsOperand(OperandVector &);
|
648 | 650 | ParseStatus parseMSRMaskOperand(OperandVector &);
|
649 | 651 | ParseStatus parseBankedRegOperand(OperandVector &);
|
650 |
| - ParseStatus parsePKHImm(OperandVector &O, StringRef Op, int Low, int High); |
| 652 | + ParseStatus parsePKHImm(OperandVector &O, ARM_AM::ShiftOpc, int Low, |
| 653 | + int High); |
651 | 654 | ParseStatus parsePKHLSLImm(OperandVector &O) {
|
652 |
| - return parsePKHImm(O, "lsl", 0, 31); |
| 655 | + return parsePKHImm(O, ARM_AM::lsl, 0, 31); |
653 | 656 | }
|
654 | 657 | ParseStatus parsePKHASRImm(OperandVector &O) {
|
655 |
| - return parsePKHImm(O, "asr", 1, 32); |
| 658 | + return parsePKHImm(O, ARM_AM::asr, 1, 32); |
656 | 659 | }
|
657 | 660 | ParseStatus parseSetEndImm(OperandVector &);
|
658 | 661 | ParseStatus parseShifterImm(OperandVector &);
|
@@ -4228,30 +4231,36 @@ int ARMAsmParser::tryParseRegister(bool AllowOutOfBoundReg) {
|
4228 | 4231 | return RegNum;
|
4229 | 4232 | }
|
4230 | 4233 |
|
4231 |
| -// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. |
4232 |
| -// If a recoverable error occurs, return 1. If an irrecoverable error |
4233 |
| -// occurs, return -1. An irrecoverable error is one where tokens have been |
4234 |
| -// consumed in the process of trying to parse the shifter (i.e., when it is |
4235 |
| -// indeed a shifter operand, but malformed). |
4236 |
| -int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) { |
| 4234 | +std::optional<ARM_AM::ShiftOpc> ARMAsmParser::tryParseShiftToken() { |
4237 | 4235 | MCAsmParser &Parser = getParser();
|
4238 |
| - SMLoc S = Parser.getTok().getLoc(); |
4239 | 4236 | const AsmToken &Tok = Parser.getTok();
|
4240 | 4237 | if (Tok.isNot(AsmToken::Identifier))
|
4241 |
| - return -1; |
| 4238 | + return std::nullopt; |
4242 | 4239 |
|
4243 | 4240 | std::string lowerCase = Tok.getString().lower();
|
4244 |
| - ARM_AM::ShiftOpc ShiftTy = StringSwitch<ARM_AM::ShiftOpc>(lowerCase) |
| 4241 | + return StringSwitch<std::optional<ARM_AM::ShiftOpc>>(lowerCase) |
4245 | 4242 | .Case("asl", ARM_AM::lsl)
|
4246 | 4243 | .Case("lsl", ARM_AM::lsl)
|
4247 | 4244 | .Case("lsr", ARM_AM::lsr)
|
4248 | 4245 | .Case("asr", ARM_AM::asr)
|
4249 | 4246 | .Case("ror", ARM_AM::ror)
|
4250 | 4247 | .Case("rrx", ARM_AM::rrx)
|
4251 |
| - .Default(ARM_AM::no_shift); |
| 4248 | + .Default(std::nullopt); |
| 4249 | +} |
| 4250 | + |
| 4251 | +// Try to parse a shifter (e.g., "lsl <amt>"). On success, return 0. |
| 4252 | +// If a recoverable error occurs, return 1. If an irrecoverable error |
| 4253 | +// occurs, return -1. An irrecoverable error is one where tokens have been |
| 4254 | +// consumed in the process of trying to parse the shifter (i.e., when it is |
| 4255 | +// indeed a shifter operand, but malformed). |
| 4256 | +int ARMAsmParser::tryParseShiftRegister(OperandVector &Operands) { |
| 4257 | + MCAsmParser &Parser = getParser(); |
| 4258 | + SMLoc S = Parser.getTok().getLoc(); |
4252 | 4259 |
|
4253 |
| - if (ShiftTy == ARM_AM::no_shift) |
| 4260 | + auto ShiftTyOpt = tryParseShiftToken(); |
| 4261 | + if (ShiftTyOpt == std::nullopt) |
4254 | 4262 | return 1;
|
| 4263 | + auto ShiftTy = ShiftTyOpt.value(); |
4255 | 4264 |
|
4256 | 4265 | Parser.Lex(); // Eat the operator.
|
4257 | 4266 |
|
@@ -5284,17 +5293,24 @@ ParseStatus ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
|
5284 | 5293 | return ParseStatus::Success;
|
5285 | 5294 | }
|
5286 | 5295 |
|
5287 |
| -ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands, StringRef Op, |
5288 |
| - int Low, int High) { |
| 5296 | +// FIXME: Unify the different methods for handling shift operators |
| 5297 | +// and use TableGen matching mechanisms to do the validation rather than |
| 5298 | +// separate parsing paths. |
| 5299 | +ParseStatus ARMAsmParser::parsePKHImm(OperandVector &Operands, |
| 5300 | + ARM_AM::ShiftOpc Op, int Low, int High) { |
5289 | 5301 | MCAsmParser &Parser = getParser();
|
5290 |
| - const AsmToken &Tok = Parser.getTok(); |
5291 |
| - if (Tok.isNot(AsmToken::Identifier)) |
5292 |
| - return Error(Parser.getTok().getLoc(), Op + " operand expected."); |
5293 |
| - StringRef ShiftName = Tok.getString(); |
5294 |
| - std::string LowerOp = Op.lower(); |
5295 |
| - std::string UpperOp = Op.upper(); |
5296 |
| - if (ShiftName != LowerOp && ShiftName != UpperOp) |
5297 |
| - return Error(Parser.getTok().getLoc(), Op + " operand expected."); |
| 5302 | + auto ShiftCodeOpt = tryParseShiftToken(); |
| 5303 | + |
| 5304 | + if (!ShiftCodeOpt.has_value()) |
| 5305 | + return ParseStatus::NoMatch; |
| 5306 | + auto ShiftCode = ShiftCodeOpt.value(); |
| 5307 | + |
| 5308 | + // The wrong shift code has been provided. Can error here as has matched the |
| 5309 | + // correct operand in this case. |
| 5310 | + if (ShiftCode != Op) |
| 5311 | + return Error(Parser.getTok().getLoc(), |
| 5312 | + ARM_AM::getShiftOpcStr(Op) + " operand expected."); |
| 5313 | + |
5298 | 5314 | Parser.Lex(); // Eat shift type token.
|
5299 | 5315 |
|
5300 | 5316 | // There must be a '#' and a shift amount.
|
|
0 commit comments