diff --git a/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp b/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp --- 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 #include #define DEBUG_TYPE "avr-asm-parser" @@ -67,7 +68,7 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 Insts = {"lds", "adiw", "sbiw", "ldi"}; + for (auto Inst : Insts) { + if (Inst == Mnemonic) { + maybeReg = false; + break; + } + } + } else if (OperandNum == 0) { + std::array 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 --- a/llvm/test/MC/AVR/inst-adiw.s +++ b/llvm/test/MC/AVR/inst-adiw.s @@ -17,6 +17,7 @@ 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 @@ ; 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 @@ ; 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 --- a/llvm/test/MC/AVR/inst-call.s +++ b/llvm/test/MC/AVR/inst-call.s @@ -9,13 +9,19 @@ 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 --- a/llvm/test/MC/AVR/inst-lds-tiny.s +++ b/llvm/test/MC/AVR/inst-lds-tiny.s @@ -7,6 +7,8 @@ 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 @@ ; 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 --- a/llvm/test/MC/AVR/inst-lds.s +++ b/llvm/test/MC/AVR/inst-lds.s @@ -7,19 +7,28 @@ 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 --- a/llvm/test/MC/AVR/inst-rjmp.s +++ b/llvm/test/MC/AVR/inst-rjmp.s @@ -14,6 +14,8 @@ 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 @@ ; 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 @@ ; 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 --- a/llvm/test/MC/AVR/inst-sbiw.s +++ b/llvm/test/MC/AVR/inst-sbiw.s @@ -17,6 +17,7 @@ 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 @@ ; 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 @@ ; 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 --- a/llvm/test/MC/AVR/inst-sts-tiny.s +++ b/llvm/test/MC/AVR/inst-sts-tiny.s @@ -5,13 +5,23 @@ 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 --- 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