Skip to content

Commit 7a45b13

Browse files
committed
[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 llvm#58853 Reviewed by: aykevl Differential Revision: https://reviews.llvm.org/D140777
1 parent 68b6cab commit 7a45b13

File tree

9 files changed

+107
-27
lines changed

9 files changed

+107
-27
lines changed

llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/Support/Debug.h"
3030
#include "llvm/Support/MathExtras.h"
3131

32+
#include <array>
3233
#include <sstream>
3334

3435
#define DEBUG_TYPE "avr-asm-parser"
@@ -67,7 +68,7 @@ class AVRAsmParser : public MCTargetAsmParser {
6768

6869
OperandMatchResultTy parseMemriOperand(OperandVector &Operands);
6970

70-
bool parseOperand(OperandVector &Operands);
71+
bool parseOperand(OperandVector &Operands, bool maybeReg);
7172
int parseRegisterName(unsigned (*matchFn)(StringRef));
7273
int parseRegisterName();
7374
int parseRegister(bool RestoreOnFailure = false);
@@ -457,9 +458,9 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) {
457458
// Check for sign.
458459
AsmToken tokens[2];
459460
if (Parser.getLexer().peekTokens(tokens) == 2)
460-
if (tokens[0].getKind() == AsmToken::LParen &&
461-
tokens[1].getKind() == AsmToken::Minus)
462-
isNegated = true;
461+
if (tokens[0].getKind() == AsmToken::LParen &&
462+
tokens[1].getKind() == AsmToken::Minus)
463+
isNegated = true;
463464

464465
// Check if we have a target specific modifier (lo8, hi8, &c)
465466
if (CurTok != AsmToken::Identifier ||
@@ -514,17 +515,16 @@ bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) {
514515
return false;
515516
}
516517

517-
bool AVRAsmParser::parseOperand(OperandVector &Operands) {
518+
bool AVRAsmParser::parseOperand(OperandVector &Operands, bool maybeReg) {
518519
LLVM_DEBUG(dbgs() << "parseOperand\n");
519520

520521
switch (getLexer().getKind()) {
521522
default:
522523
return Error(Parser.getTok().getLoc(), "unexpected token in operand");
523524

524525
case AsmToken::Identifier:
525-
// Try to parse a register, if it fails,
526-
// fall through to the next case.
527-
if (!tryParseRegisterOperand(Operands)) {
526+
// Try to parse a register, fall through to the next case if it fails.
527+
if (maybeReg && !tryParseRegisterOperand(Operands)) {
528528
return false;
529529
}
530530
[[fallthrough]];
@@ -624,13 +624,12 @@ bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info,
624624
OperandVector &Operands) {
625625
Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
626626

627-
bool first = true;
627+
int OperandNum = -1;
628628
while (getLexer().isNot(AsmToken::EndOfStatement)) {
629-
if (!first)
629+
OperandNum++;
630+
if (OperandNum > 0)
630631
eatComma();
631632

632-
first = false;
633-
634633
auto MatchResult = MatchOperandParserImpl(Operands, Mnemonic);
635634

636635
if (MatchResult == MatchOperand_Success) {
@@ -644,7 +643,28 @@ bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info,
644643
return Error(Loc, "failed to parse register and immediate pair");
645644
}
646645

647-
if (parseOperand(Operands)) {
646+
// These specific operands should be treated as addresses/symbols/labels,
647+
// other than registers.
648+
bool maybeReg = true;
649+
if (OperandNum == 1) {
650+
std::array<StringRef, 8> Insts = {"lds", "adiw", "sbiw", "ldi"};
651+
for (auto Inst : Insts) {
652+
if (Inst == Mnemonic) {
653+
maybeReg = false;
654+
break;
655+
}
656+
}
657+
} else if (OperandNum == 0) {
658+
std::array<StringRef, 8> Insts = {"sts", "call", "rcall", "rjmp", "jmp"};
659+
for (auto Inst : Insts) {
660+
if (Inst == Mnemonic) {
661+
maybeReg = false;
662+
break;
663+
}
664+
}
665+
}
666+
667+
if (parseOperand(Operands, maybeReg)) {
648668
SMLoc Loc = getLexer().getLoc();
649669
Parser.eatToEndOfStatement();
650670
return Error(Loc, "unexpected token in argument list");

llvm/test/MC/AVR/inst-adiw.s

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ foo:
1717
adiw r30, 0
1818

1919
adiw r24, SYMBOL
20+
adiw r24, r25
2021

2122
; CHECK: adiw r26, 12 ; encoding: [0x1c,0x96]
2223
; CHECK: adiw r26, 63 ; encoding: [0xdf,0x96]
@@ -32,6 +33,8 @@ foo:
3233

3334
; CHECK: adiw r24, SYMBOL ; encoding: [0b00AAAAAA,0x96]
3435
; fixup A - offset: 0, value: SYMBOL, kind: fixup_6_adiw
36+
; CHECK: adiw r24, r25 ; encoding: [0b00AAAAAA,0x96]
37+
; fixup A - offset: 0, value: r25, kind: fixup_6_adiw
3538

3639
; CHECK-INST: adiw r26, 12
3740
; CHECK-INST: adiw r26, 63
@@ -47,3 +50,5 @@ foo:
4750

4851
; CHECK-INST: adiw r24, 0
4952
; CHECK-INST: R_AVR_6_ADIW SYMBOL
53+
; CHECK-INST: adiw r24, 0
54+
; CHECK-INST: R_AVR_6_ADIW r25

llvm/test/MC/AVR/inst-call.s

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,19 @@ foo:
99
call -12
1010
call 0
1111

12+
r25:
13+
call r25
14+
1215
; CHECK: call 4096 ; encoding: [0x0e,0x94,0x00,0x08]
1316
; CHECK: call -124 ; encoding: [0xff,0x95,0xc2,0xff]
1417
; CHECK: call -12 ; encoding: [0xff,0x95,0xfa,0xff]
1518
; CHECK: call 0 ; encoding: [0x0e,0x94,0x00,0x00]
16-
19+
; CHECK: call r25 ; encoding: [0x0e'A',0x94'A',0b00AAAAAA,0x00]
20+
; CHECK: ; fixup A - offset: 0, value: r25, kind: fixup_call
1721

1822
; CHECK-INST: call 4096
1923
; CHECK-INST: call 8388484
2024
; CHECK-INST: call 8388596
2125
; CHECK-INST: call 0
26+
; CHECK-INST: call 0
27+
; CHECK-INST: R_AVR_CALL

llvm/test/MC/AVR/inst-lds-tiny.s

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,27 @@ foo:
77
lds r22, 44
88
lds r27, 92
99
lds r20, SYMBOL+12
10+
lds r20, r21
11+
lds r20, z+6
1012

1113
; CHECK: lds r16, 113 ; encoding: [0x01,0xa7]
1214
; CHECK: lds r29, 62 ; encoding: [0xde,0xa3]
1315
; CHECK: lds r22, 44 ; encoding: [0x6c,0xa2]
1416
; CHECK: lds r27, 92 ; encoding: [0xbc,0xa5]
1517
; CHECK: lds r20, SYMBOL+12 ; encoding: [0x40'A',0xa0'A']
1618
; CHECK: ; fixup A - offset: 0, value: SYMBOL+12, kind: fixup_lds_sts_16
19+
; CHECK: lds r20, r21 ; encoding: [0x40'A',0xa0'A']
20+
; CHECK: ; fixup A - offset: 0, value: r21, kind: fixup_lds_sts_16
21+
; CHECK: lds r20, z+6 ; encoding: [0x40'A',0xa0'A']
22+
; CHECK: ; fixup A - offset: 0, value: z+6, kind: fixup_lds_sts_16
1723

1824
; CHECK-INST: lds r16, 113
1925
; CHECK-INST: lds r29, 62
2026
; CHECK-INST: lds r22, 44
2127
; CHECK-INST: lds r27, 92
22-
; CHECK-INST: lds r20, 0
23-
; CHECK-INST: R_AVR_LDS_STS_16 SYMBOL+0xc
28+
; CHECK-INST: lds r20, 0
29+
; CHECK-INST: R_AVR_LDS_STS_16 SYMBOL+0xc
30+
; CHECK-INST: lds r20, 0
31+
; CHECK-INST: R_AVR_LDS_STS_16 r21
32+
; CHECK-INST: lds r20, 0
33+
; CHECK-INST: R_AVR_LDS_STS_16 z+0x6

llvm/test/MC/AVR/inst-lds.s

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,28 @@ foo:
77
lds r29, 190
88
lds r22, 172
99
lds r27, 92
10-
lds r4, SYMBOL+12
10+
lds r4, SYMBOL+12
11+
lds r4, r25
12+
lds r4, x+2
1113

1214
; CHECK: lds r16, 241 ; encoding: [0x00,0x91,0xf1,0x00]
1315
; CHECK: lds r29, 190 ; encoding: [0xd0,0x91,0xbe,0x00]
1416
; CHECK: lds r22, 172 ; encoding: [0x60,0x91,0xac,0x00]
1517
; CHECK: lds r27, 92 ; encoding: [0xb0,0x91,0x5c,0x00]
16-
; CHECK: lds r4, SYMBOL+12 ; encoding: [0x40,0x90,A,A]
18+
; CHECK: lds r4, SYMBOL+12 ; encoding: [0x40,0x90,A,A]
1719
; CHECK: ; fixup A - offset: 2, value: SYMBOL+12, kind: fixup_16
18-
20+
; CHECK: lds r4, r25 ; encoding: [0x40,0x90,A,A]
21+
; CHECK: ; fixup A - offset: 2, value: r25, kind: fixup_16
22+
; CHECK: lds r4, x+2 ; encoding: [0x40,0x90,A,A]
23+
; CHECK: ; fixup A - offset: 2, value: x+2, kind: fixup_16
1924

2025
; CHECK-INST: lds r16, 241
2126
; CHECK-INST: lds r29, 190
2227
; CHECK-INST: lds r22, 172
2328
; CHECK-INST: lds r27, 92
2429
; CHECK-INST: lds r4, 0
25-
; CHECK-INST: R_AVR_16 SYMBOL+0xc
30+
; CHECK-INST: R_AVR_16 SYMBOL+0xc
31+
; CHECK-INST: lds r4, 0
32+
; CHECK-INST: R_AVR_16 r25
33+
; CHECK-INST: lds r4, 0
34+
; CHECK-INST: R_AVR_16 x+0x2

llvm/test/MC/AVR/inst-rjmp.s

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ foo:
1414
end:
1515
rjmp .-4
1616
rjmp .-6
17+
x:
18+
rjmp x
1719

1820
; CHECK: rjmp .Ltmp0+2 ; encoding: [A,0b1100AAAA]
1921
; CHECK: ; fixup A - offset: 0, value: .Ltmp0+2, kind: fixup_13_pcrel
@@ -31,6 +33,8 @@ end:
3133
; CHECK: ; fixup A - offset: 0, value: .Ltmp4-4, kind: fixup_13_pcrel
3234
; CHECK: rjmp .Ltmp5-6 ; encoding: [A,0b1100AAAA]
3335
; CHECK: ; fixup A - offset: 0, value: .Ltmp5-6, kind: fixup_13_pcrel
36+
; CHECK: rjmp x ; encoding: [A,0b1100AAAA]
37+
; CHECK: ; fixup A - offset: 0, value: x, kind: fixup_13_pcrel
3438

3539
; INST: rjmp .+0
3640
; INST: rjmp .+0
@@ -40,3 +44,4 @@ end:
4044
; INST: rjmp .+0
4145
; INST: rjmp .+0
4246
; INST: rjmp .+0
47+
; INST: rjmp .+0

llvm/test/MC/AVR/inst-sbiw.s

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ foo:
1717
sbiw r24, 2
1818

1919
sbiw r24, SYMBOL-1
20+
sbiw r24, z+15
2021

2122
; CHECK: sbiw r26, 54 ; encoding: [0xd6,0x97]
2223
; CHECK: sbiw r26, 63 ; encoding: [0xdf,0x97]
@@ -32,6 +33,8 @@ foo:
3233

3334
; CHECK: sbiw r24, SYMBOL-1 ; encoding: [0b00AAAAAA,0x97]
3435
; fixup A - offset: 0, value: SYMBOL-1, kind: fixup_6_adiw
36+
; CHECK: sbiw r24, z+15 ; encoding: [0b00AAAAAA,0x97]
37+
; fixup A - offset: 0, value: z+15, kind: fixup_6_adiw
3538

3639
; CHECK-INST: sbiw r26, 54
3740
; CHECK-INST: sbiw r26, 63
@@ -47,3 +50,5 @@ foo:
4750

4851
; CHECK-INST: sbiw r24, 0
4952
; CHECK-INST: R_AVR_6_ADIW SYMBOL-0x1
53+
; CHECK-INST: sbiw r24, 0
54+
; CHECK-INST: R_AVR_6_ADIW z+0xf

llvm/test/MC/AVR/inst-sts-tiny.s

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,23 @@ foo:
55
sts 3, r16
66
sts 127, r17
77
sts SYMBOL+1, r25
8+
sts x, r25
9+
sts r25+1, r25
810

911
; CHECK: sts 3, r16 ; encoding: [0x03,0xa8]
1012
; CHECK: sts 127, r17 ; encoding: [0x1f,0xaf]
1113
; CHECK: sts SYMBOL+1, r25 ; encoding: [0x90'A',0xa8'A']
1214
; CHECK: ; fixup A - offset: 0, value: SYMBOL+1, kind: fixup_lds_sts_16
15+
; CHECK: sts x, r25 ; encoding: [0x90'A',0xa8'A']
16+
; CHECK: ; fixup A - offset: 0, value: x, kind: fixup_lds_sts_16
17+
; CHECK: sts r25+1, r25 ; encoding: [0x90'A',0xa8'A']
18+
; CHECK: ; fixup A - offset: 0, value: r25+1, kind: fixup_lds_sts_16
1319

1420
; CHECK-INST: sts 3, r16
1521
; CHECK-INST: sts 127, r17
1622
; CHECK-INST: sts 0, r25
17-
; CHECK-INST: R_AVR_LDS_STS_16 SYMBOL+0x1
23+
; CHECK-INST: R_AVR_LDS_STS_16 SYMBOL+0x1
24+
; CHECK-INST: sts 0, r25
25+
; CHECK-INST: R_AVR_LDS_STS_16 x
26+
; CHECK-INST: sts 0, r25
27+
; CHECK-INST: R_AVR_LDS_STS_16 r25+0x1

llvm/test/MC/AVR/inst-sts.s

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,27 @@
44

55
foo:
66

7-
sts 3, r5
8-
sts 255, r7
7+
sts 3, r5
8+
sts 255, r7
99
sts SYMBOL+1, r25
10+
sts r25, r25
11+
sts y+3, r25
1012

11-
; CHECK: sts 3, r5 ; encoding: [0x50,0x92,0x03,0x00]
12-
; CHECK: sts 255, r7 ; encoding: [0x70,0x92,0xff,0x00]
13+
; CHECK: sts 3, r5 ; encoding: [0x50,0x92,0x03,0x00]
14+
; CHECK: sts 255, r7 ; encoding: [0x70,0x92,0xff,0x00]
1315
; CHECK: sts SYMBOL+1, r25 ; encoding: [0x90,0x93,A,A]
1416
; CHECK: ; fixup A - offset: 2, value: SYMBOL+1, kind: fixup_16
17+
; CHECK: sts r25, r25 ; encoding: [0x90,0x93,A,A]
18+
; CHECK: ; fixup A - offset: 2, value: r25, kind: fixup_16
19+
; CHECK: sts y+3, r25 ; encoding: [0x90,0x93,A,A]
20+
; CHECK: ; fixup A - offset: 2, value: y+3, kind: fixup_16
1521

1622

17-
; CHECK-INST: sts 3, r5
23+
; CHECK-INST: sts 3, r5
1824
; CHECK-INST: sts 255, r7
19-
; CHECK-INST: sts 0, r25
25+
; CHECK-INST: sts 0, r25
2026
; CHECK-INST: R_AVR_16 SYMBOL+0x1
27+
; CHECK-INST: sts 0, r25
28+
; CHECK-INST: R_AVR_16 r25
29+
; CHECK-INST: sts 0, r25
30+
; CHECK-INST: R_AVR_16 y+0x3

0 commit comments

Comments
 (0)