[llvm] 7a45b13 - [AVR] Fix some ambiguous cases in AsmParser
Ben Shi via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 6 18:42:30 PST 2023
Author: Ben Shi
Date: 2023-01-07T10:42:07+08:00
New Revision: 7a45b13cd726d04139006fa9aea32940d3158b0f
URL: https://github.com/llvm/llvm-project/commit/7a45b13cd726d04139006fa9aea32940d3158b0f
DIFF: https://github.com/llvm/llvm-project/commit/7a45b13cd726d04139006fa9aea32940d3158b0f.diff
LOG: [AVR] Fix some ambiguous cases in AsmParser
Some specific operands in specific instructions should be treated
as variables/symbols/labels, other than registers.
This patch fixes those ambiguous cases, such as "lds r25, r24",
which means loading the value inside symbol 'r24' into register 'r25'.
Fixes https://github.com/llvm/llvm-project/issues/58853
Reviewed by: aykevl
Differential Revision: https://reviews.llvm.org/D140777
Added:
Modified:
llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
llvm/test/MC/AVR/inst-adiw.s
llvm/test/MC/AVR/inst-call.s
llvm/test/MC/AVR/inst-lds-tiny.s
llvm/test/MC/AVR/inst-lds.s
llvm/test/MC/AVR/inst-rjmp.s
llvm/test/MC/AVR/inst-sbiw.s
llvm/test/MC/AVR/inst-sts-tiny.s
llvm/test/MC/AVR/inst-sts.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
index f58d2cff24f11..8d30b7886040f 100644
--- a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
+++ b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp
@@ -29,6 +29,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
+#include <array>
#include <sstream>
#define DEBUG_TYPE "avr-asm-parser"
@@ -67,7 +68,7 @@ class AVRAsmParser : public MCTargetAsmParser {
OperandMatchResultTy parseMemriOperand(OperandVector &Operands);
- bool parseOperand(OperandVector &Operands);
+ bool parseOperand(OperandVector &Operands, bool maybeReg);
int parseRegisterName(unsigned (*matchFn)(StringRef));
int parseRegisterName();
int parseRegister(bool RestoreOnFailure = false);
@@ -457,9 +458,9 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) {
// Check for sign.
AsmToken tokens[2];
if (Parser.getLexer().peekTokens(tokens) == 2)
- if (tokens[0].getKind() == AsmToken::LParen &&
- tokens[1].getKind() == AsmToken::Minus)
- isNegated = true;
+ if (tokens[0].getKind() == AsmToken::LParen &&
+ tokens[1].getKind() == AsmToken::Minus)
+ isNegated = true;
// Check if we have a target specific modifier (lo8, hi8, &c)
if (CurTok != AsmToken::Identifier ||
@@ -514,7 +515,7 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) {
return false;
}
-bool AVRAsmParser::parseOperand(OperandVector &Operands) {
+bool AVRAsmParser::parseOperand(OperandVector &Operands, bool maybeReg) {
LLVM_DEBUG(dbgs() << "parseOperand\n");
switch (getLexer().getKind()) {
@@ -522,9 +523,8 @@ bool AVRAsmParser::parseOperand(OperandVector &Operands) {
return Error(Parser.getTok().getLoc(), "unexpected token in operand");
case AsmToken::Identifier:
- // Try to parse a register, if it fails,
- // fall through to the next case.
- if (!tryParseRegisterOperand(Operands)) {
+ // Try to parse a register, fall through to the next case if it fails.
+ if (maybeReg && !tryParseRegisterOperand(Operands)) {
return false;
}
[[fallthrough]];
@@ -624,13 +624,12 @@ bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info,
OperandVector &Operands) {
Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
- bool first = true;
+ int OperandNum = -1;
while (getLexer().isNot(AsmToken::EndOfStatement)) {
- if (!first)
+ OperandNum++;
+ if (OperandNum > 0)
eatComma();
- first = false;
-
auto MatchResult = MatchOperandParserImpl(Operands, Mnemonic);
if (MatchResult == MatchOperand_Success) {
@@ -644,7 +643,28 @@ bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info,
return Error(Loc, "failed to parse register and immediate pair");
}
- if (parseOperand(Operands)) {
+ // These specific operands should be treated as addresses/symbols/labels,
+ // other than registers.
+ bool maybeReg = true;
+ if (OperandNum == 1) {
+ std::array<StringRef, 8> Insts = {"lds", "adiw", "sbiw", "ldi"};
+ for (auto Inst : Insts) {
+ if (Inst == Mnemonic) {
+ maybeReg = false;
+ break;
+ }
+ }
+ } else if (OperandNum == 0) {
+ std::array<StringRef, 8> Insts = {"sts", "call", "rcall", "rjmp", "jmp"};
+ for (auto Inst : Insts) {
+ if (Inst == Mnemonic) {
+ maybeReg = false;
+ break;
+ }
+ }
+ }
+
+ if (parseOperand(Operands, maybeReg)) {
SMLoc Loc = getLexer().getLoc();
Parser.eatToEndOfStatement();
return Error(Loc, "unexpected token in argument list");
diff --git a/llvm/test/MC/AVR/inst-adiw.s b/llvm/test/MC/AVR/inst-adiw.s
index 49e3473e48f2e..7904965a51d68 100644
--- a/llvm/test/MC/AVR/inst-adiw.s
+++ b/llvm/test/MC/AVR/inst-adiw.s
@@ -17,6 +17,7 @@ foo:
adiw r30, 0
adiw r24, SYMBOL
+ adiw r24, r25
; CHECK: adiw r26, 12 ; encoding: [0x1c,0x96]
; CHECK: adiw r26, 63 ; encoding: [0xdf,0x96]
@@ -32,6 +33,8 @@ foo:
; CHECK: adiw r24, SYMBOL ; encoding: [0b00AAAAAA,0x96]
; fixup A - offset: 0, value: SYMBOL, kind: fixup_6_adiw
+; CHECK: adiw r24, r25 ; encoding: [0b00AAAAAA,0x96]
+ ; fixup A - offset: 0, value: r25, kind: fixup_6_adiw
; CHECK-INST: adiw r26, 12
; CHECK-INST: adiw r26, 63
@@ -47,3 +50,5 @@ foo:
; CHECK-INST: adiw r24, 0
; CHECK-INST: R_AVR_6_ADIW SYMBOL
+; CHECK-INST: adiw r24, 0
+; CHECK-INST: R_AVR_6_ADIW r25
diff --git a/llvm/test/MC/AVR/inst-call.s b/llvm/test/MC/AVR/inst-call.s
index c29f95711789e..5ded5e1de6a1b 100644
--- a/llvm/test/MC/AVR/inst-call.s
+++ b/llvm/test/MC/AVR/inst-call.s
@@ -9,13 +9,19 @@ foo:
call -12
call 0
+r25:
+ call r25
+
; CHECK: call 4096 ; encoding: [0x0e,0x94,0x00,0x08]
; CHECK: call -124 ; encoding: [0xff,0x95,0xc2,0xff]
; CHECK: call -12 ; encoding: [0xff,0x95,0xfa,0xff]
; CHECK: call 0 ; encoding: [0x0e,0x94,0x00,0x00]
-
+; CHECK: call r25 ; encoding: [0x0e'A',0x94'A',0b00AAAAAA,0x00]
+; CHECK: ; fixup A - offset: 0, value: r25, kind: fixup_call
; CHECK-INST: call 4096
; CHECK-INST: call 8388484
; CHECK-INST: call 8388596
; CHECK-INST: call 0
+; CHECK-INST: call 0
+; CHECK-INST: R_AVR_CALL
diff --git a/llvm/test/MC/AVR/inst-lds-tiny.s b/llvm/test/MC/AVR/inst-lds-tiny.s
index 9faea6b0a928e..045cbea24b1e9 100644
--- a/llvm/test/MC/AVR/inst-lds-tiny.s
+++ b/llvm/test/MC/AVR/inst-lds-tiny.s
@@ -7,6 +7,8 @@ foo:
lds r22, 44
lds r27, 92
lds r20, SYMBOL+12
+ lds r20, r21
+ lds r20, z+6
; CHECK: lds r16, 113 ; encoding: [0x01,0xa7]
; CHECK: lds r29, 62 ; encoding: [0xde,0xa3]
@@ -14,10 +16,18 @@ foo:
; CHECK: lds r27, 92 ; encoding: [0xbc,0xa5]
; CHECK: lds r20, SYMBOL+12 ; encoding: [0x40'A',0xa0'A']
; CHECK: ; fixup A - offset: 0, value: SYMBOL+12, kind: fixup_lds_sts_16
+; CHECK: lds r20, r21 ; encoding: [0x40'A',0xa0'A']
+; CHECK: ; fixup A - offset: 0, value: r21, kind: fixup_lds_sts_16
+; CHECK: lds r20, z+6 ; encoding: [0x40'A',0xa0'A']
+; CHECK: ; fixup A - offset: 0, value: z+6, kind: fixup_lds_sts_16
; CHECK-INST: lds r16, 113
; CHECK-INST: lds r29, 62
; CHECK-INST: lds r22, 44
; CHECK-INST: lds r27, 92
-; CHECK-INST: lds r20, 0
-; CHECK-INST: R_AVR_LDS_STS_16 SYMBOL+0xc
+; CHECK-INST: lds r20, 0
+; CHECK-INST: R_AVR_LDS_STS_16 SYMBOL+0xc
+; CHECK-INST: lds r20, 0
+; CHECK-INST: R_AVR_LDS_STS_16 r21
+; CHECK-INST: lds r20, 0
+; CHECK-INST: R_AVR_LDS_STS_16 z+0x6
diff --git a/llvm/test/MC/AVR/inst-lds.s b/llvm/test/MC/AVR/inst-lds.s
index 7e33e1e2cfb1a..0e4bfb345d827 100644
--- a/llvm/test/MC/AVR/inst-lds.s
+++ b/llvm/test/MC/AVR/inst-lds.s
@@ -7,19 +7,28 @@ foo:
lds r29, 190
lds r22, 172
lds r27, 92
- lds r4, SYMBOL+12
+ lds r4, SYMBOL+12
+ lds r4, r25
+ lds r4, x+2
; CHECK: lds r16, 241 ; encoding: [0x00,0x91,0xf1,0x00]
; CHECK: lds r29, 190 ; encoding: [0xd0,0x91,0xbe,0x00]
; CHECK: lds r22, 172 ; encoding: [0x60,0x91,0xac,0x00]
; CHECK: lds r27, 92 ; encoding: [0xb0,0x91,0x5c,0x00]
-; CHECK: lds r4, SYMBOL+12 ; encoding: [0x40,0x90,A,A]
+; CHECK: lds r4, SYMBOL+12 ; encoding: [0x40,0x90,A,A]
; CHECK: ; fixup A - offset: 2, value: SYMBOL+12, kind: fixup_16
-
+; CHECK: lds r4, r25 ; encoding: [0x40,0x90,A,A]
+; CHECK: ; fixup A - offset: 2, value: r25, kind: fixup_16
+; CHECK: lds r4, x+2 ; encoding: [0x40,0x90,A,A]
+; CHECK: ; fixup A - offset: 2, value: x+2, kind: fixup_16
; CHECK-INST: lds r16, 241
; CHECK-INST: lds r29, 190
; CHECK-INST: lds r22, 172
; CHECK-INST: lds r27, 92
; CHECK-INST: lds r4, 0
-; CHECK-INST: R_AVR_16 SYMBOL+0xc
+; CHECK-INST: R_AVR_16 SYMBOL+0xc
+; CHECK-INST: lds r4, 0
+; CHECK-INST: R_AVR_16 r25
+; CHECK-INST: lds r4, 0
+; CHECK-INST: R_AVR_16 x+0x2
diff --git a/llvm/test/MC/AVR/inst-rjmp.s b/llvm/test/MC/AVR/inst-rjmp.s
index ec553a9236735..22d9f2f8d9b2a 100644
--- a/llvm/test/MC/AVR/inst-rjmp.s
+++ b/llvm/test/MC/AVR/inst-rjmp.s
@@ -14,6 +14,8 @@ foo:
end:
rjmp .-4
rjmp .-6
+x:
+ rjmp x
; CHECK: rjmp .Ltmp0+2 ; encoding: [A,0b1100AAAA]
; CHECK: ; fixup A - offset: 0, value: .Ltmp0+2, kind: fixup_13_pcrel
@@ -31,6 +33,8 @@ end:
; CHECK: ; fixup A - offset: 0, value: .Ltmp4-4, kind: fixup_13_pcrel
; CHECK: rjmp .Ltmp5-6 ; encoding: [A,0b1100AAAA]
; CHECK: ; fixup A - offset: 0, value: .Ltmp5-6, kind: fixup_13_pcrel
+; CHECK: rjmp x ; encoding: [A,0b1100AAAA]
+; CHECK: ; fixup A - offset: 0, value: x, kind: fixup_13_pcrel
; INST: rjmp .+0
; INST: rjmp .+0
@@ -40,3 +44,4 @@ end:
; INST: rjmp .+0
; INST: rjmp .+0
; INST: rjmp .+0
+; INST: rjmp .+0
diff --git a/llvm/test/MC/AVR/inst-sbiw.s b/llvm/test/MC/AVR/inst-sbiw.s
index d15fcac2a16a3..5e20789e0292b 100644
--- a/llvm/test/MC/AVR/inst-sbiw.s
+++ b/llvm/test/MC/AVR/inst-sbiw.s
@@ -17,6 +17,7 @@ foo:
sbiw r24, 2
sbiw r24, SYMBOL-1
+ sbiw r24, z+15
; CHECK: sbiw r26, 54 ; encoding: [0xd6,0x97]
; CHECK: sbiw r26, 63 ; encoding: [0xdf,0x97]
@@ -32,6 +33,8 @@ foo:
; CHECK: sbiw r24, SYMBOL-1 ; encoding: [0b00AAAAAA,0x97]
; fixup A - offset: 0, value: SYMBOL-1, kind: fixup_6_adiw
+; CHECK: sbiw r24, z+15 ; encoding: [0b00AAAAAA,0x97]
+ ; fixup A - offset: 0, value: z+15, kind: fixup_6_adiw
; CHECK-INST: sbiw r26, 54
; CHECK-INST: sbiw r26, 63
@@ -47,3 +50,5 @@ foo:
; CHECK-INST: sbiw r24, 0
; CHECK-INST: R_AVR_6_ADIW SYMBOL-0x1
+; CHECK-INST: sbiw r24, 0
+; CHECK-INST: R_AVR_6_ADIW z+0xf
diff --git a/llvm/test/MC/AVR/inst-sts-tiny.s b/llvm/test/MC/AVR/inst-sts-tiny.s
index a3b1208cbeb95..a0d67c7177fbe 100644
--- a/llvm/test/MC/AVR/inst-sts-tiny.s
+++ b/llvm/test/MC/AVR/inst-sts-tiny.s
@@ -5,13 +5,23 @@ foo:
sts 3, r16
sts 127, r17
sts SYMBOL+1, r25
+ sts x, r25
+ sts r25+1, r25
; CHECK: sts 3, r16 ; encoding: [0x03,0xa8]
; CHECK: sts 127, r17 ; encoding: [0x1f,0xaf]
; CHECK: sts SYMBOL+1, r25 ; encoding: [0x90'A',0xa8'A']
; CHECK: ; fixup A - offset: 0, value: SYMBOL+1, kind: fixup_lds_sts_16
+; CHECK: sts x, r25 ; encoding: [0x90'A',0xa8'A']
+; CHECK: ; fixup A - offset: 0, value: x, kind: fixup_lds_sts_16
+; CHECK: sts r25+1, r25 ; encoding: [0x90'A',0xa8'A']
+; CHECK: ; fixup A - offset: 0, value: r25+1, kind: fixup_lds_sts_16
; CHECK-INST: sts 3, r16
; CHECK-INST: sts 127, r17
; CHECK-INST: sts 0, r25
-; CHECK-INST: R_AVR_LDS_STS_16 SYMBOL+0x1
+; CHECK-INST: R_AVR_LDS_STS_16 SYMBOL+0x1
+; CHECK-INST: sts 0, r25
+; CHECK-INST: R_AVR_LDS_STS_16 x
+; CHECK-INST: sts 0, r25
+; CHECK-INST: R_AVR_LDS_STS_16 r25+0x1
diff --git a/llvm/test/MC/AVR/inst-sts.s b/llvm/test/MC/AVR/inst-sts.s
index f925c84ecda86..19400fdfee600 100644
--- a/llvm/test/MC/AVR/inst-sts.s
+++ b/llvm/test/MC/AVR/inst-sts.s
@@ -4,17 +4,27 @@
foo:
- sts 3, r5
- sts 255, r7
+ sts 3, r5
+ sts 255, r7
sts SYMBOL+1, r25
+ sts r25, r25
+ sts y+3, r25
-; CHECK: sts 3, r5 ; encoding: [0x50,0x92,0x03,0x00]
-; CHECK: sts 255, r7 ; encoding: [0x70,0x92,0xff,0x00]
+; CHECK: sts 3, r5 ; encoding: [0x50,0x92,0x03,0x00]
+; CHECK: sts 255, r7 ; encoding: [0x70,0x92,0xff,0x00]
; CHECK: sts SYMBOL+1, r25 ; encoding: [0x90,0x93,A,A]
; CHECK: ; fixup A - offset: 2, value: SYMBOL+1, kind: fixup_16
+; CHECK: sts r25, r25 ; encoding: [0x90,0x93,A,A]
+; CHECK: ; fixup A - offset: 2, value: r25, kind: fixup_16
+; CHECK: sts y+3, r25 ; encoding: [0x90,0x93,A,A]
+; CHECK: ; fixup A - offset: 2, value: y+3, kind: fixup_16
-; CHECK-INST: sts 3, r5
+; CHECK-INST: sts 3, r5
; CHECK-INST: sts 255, r7
-; CHECK-INST: sts 0, r25
+; CHECK-INST: sts 0, r25
; CHECK-INST: R_AVR_16 SYMBOL+0x1
+; CHECK-INST: sts 0, r25
+; CHECK-INST: R_AVR_16 r25
+; CHECK-INST: sts 0, r25
+; CHECK-INST: R_AVR_16 y+0x3
More information about the llvm-commits
mailing list