[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