Skip to content

Commit e3030f1

Browse files
[ARM] FIX: Fix parsing pkhtb with a condition code
This was broken by #83436 as in optional operands meant when the CC operand is provided the `parsePKHImm` parser is applied to register operands, which previously erroneously produced an error.
1 parent 5cfcd9b commit e3030f1

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
#include <iterator>
6464
#include <limits>
6565
#include <memory>
66+
#include <optional>
6667
#include <string>
6768
#include <utility>
6869
#include <vector>
@@ -457,6 +458,7 @@ class ARMAsmParser : public MCTargetAsmParser {
457458
int tryParseRegister(bool AllowOutofBoundReg = false);
458459
bool tryParseRegisterWithWriteBack(OperandVector &);
459460
int tryParseShiftRegister(OperandVector &);
461+
std::optional<ARM_AM::ShiftOpc> tryParseShiftToken();
460462
bool parseRegisterList(OperandVector &, bool EnforceOrder = true,
461463
bool AllowRAAC = false,
462464
bool AllowOutOfBoundReg = false);
@@ -647,12 +649,13 @@ class ARMAsmParser : public MCTargetAsmParser {
647649
ParseStatus parseProcIFlagsOperand(OperandVector &);
648650
ParseStatus parseMSRMaskOperand(OperandVector &);
649651
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);
651654
ParseStatus parsePKHLSLImm(OperandVector &O) {
652-
return parsePKHImm(O, "lsl", 0, 31);
655+
return parsePKHImm(O, ARM_AM::lsl, 0, 31);
653656
}
654657
ParseStatus parsePKHASRImm(OperandVector &O) {
655-
return parsePKHImm(O, "asr", 1, 32);
658+
return parsePKHImm(O, ARM_AM::asr, 1, 32);
656659
}
657660
ParseStatus parseSetEndImm(OperandVector &);
658661
ParseStatus parseShifterImm(OperandVector &);
@@ -4228,30 +4231,36 @@ int ARMAsmParser::tryParseRegister(bool AllowOutOfBoundReg) {
42284231
return RegNum;
42294232
}
42304233

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() {
42374235
MCAsmParser &Parser = getParser();
4238-
SMLoc S = Parser.getTok().getLoc();
42394236
const AsmToken &Tok = Parser.getTok();
42404237
if (Tok.isNot(AsmToken::Identifier))
4241-
return -1;
4238+
return std::nullopt;
42424239

42434240
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)
42454242
.Case("asl", ARM_AM::lsl)
42464243
.Case("lsl", ARM_AM::lsl)
42474244
.Case("lsr", ARM_AM::lsr)
42484245
.Case("asr", ARM_AM::asr)
42494246
.Case("ror", ARM_AM::ror)
42504247
.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();
42524259

4253-
if (ShiftTy == ARM_AM::no_shift)
4260+
auto ShiftTyOpt = tryParseShiftToken();
4261+
if (ShiftTyOpt == std::nullopt)
42544262
return 1;
4263+
auto ShiftTy = ShiftTyOpt.value();
42554264

42564265
Parser.Lex(); // Eat the operator.
42574266

@@ -5284,17 +5293,24 @@ ParseStatus ARMAsmParser::parseBankedRegOperand(OperandVector &Operands) {
52845293
return ParseStatus::Success;
52855294
}
52865295

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) {
52895301
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+
52985314
Parser.Lex(); // Eat shift type token.
52995315

53005316
// There must be a '#' and a shift amount.

llvm/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ namespace ARM_AM {
4141

4242
inline const char *getAddrOpcStr(AddrOpc Op) { return Op == sub ? "-" : ""; }
4343

44-
inline const char *getShiftOpcStr(ShiftOpc Op) {
44+
inline const StringRef getShiftOpcStr(ShiftOpc Op) {
4545
switch (Op) {
4646
default: llvm_unreachable("Unknown shift opc!");
4747
case ARM_AM::asr: return "asr";

llvm/test/MC/ARM/basic-arm-instructions.s

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,6 +1774,9 @@ Lforward:
17741774
pkhtb r2, r2, r3, asr #31
17751775
pkhtb r2, r2, r3, asr #15
17761776

1777+
it ne
1778+
pkhtbne r2, r2, r3, asr #15
1779+
17771780
@ CHECK: pkhbt r2, r2, r3 @ encoding: [0x13,0x20,0x82,0xe6]
17781781
@ CHECK: pkhbt r2, r2, r3, lsl #31 @ encoding: [0x93,0x2f,0x82,0xe6]
17791782
@ CHECK: pkhbt r2, r2, r3 @ encoding: [0x13,0x20,0x82,0xe6]
@@ -1782,6 +1785,7 @@ Lforward:
17821785
@ CHECK: pkhbt r2, r3, r2 @ encoding: [0x12,0x20,0x83,0xe6]
17831786
@ CHECK: pkhtb r2, r2, r3, asr #31 @ encoding: [0xd3,0x2f,0x82,0xe6]
17841787
@ CHECK: pkhtb r2, r2, r3, asr #15 @ encoding: [0xd3,0x27,0x82,0xe6]
1788+
@ CHECK: pkhtbne r2, r2, r3, asr #15 @ encoding: [0xd3,0x27,0x82,0x16]
17851789

17861790
@------------------------------------------------------------------------------
17871791
@ FIXME: PLD

0 commit comments

Comments
 (0)