Index: llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp =================================================================== --- llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp +++ llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp @@ -67,7 +67,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); @@ -514,7 +514,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 +522,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 +623,11 @@ OperandVector &Operands) { Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc)); - bool first = true; + unsigned OperandNum = 0; while (getLexer().isNot(AsmToken::EndOfStatement)) { - if (!first) + if (OperandNum++ > 0) eatComma(); - first = false; - auto MatchResult = MatchOperandParserImpl(Operands, Mnemonic); if (MatchResult == MatchOperand_Success) { @@ -644,7 +641,14 @@ return Error(Loc, "failed to parse register and immediate pair"); } - if (parseOperand(Operands)) { + // The first operand of 'sts' and the second operand of 'lds' should + // be treated as a variable/address/expression other than a register. + bool maybeReg = true; + if ((Mnemonic == "lds" && OperandNum == 2) || + (Mnemonic == "sts" && OperandNum == 1)) + maybeReg = false; + + if (parseOperand(Operands, maybeReg)) { SMLoc Loc = getLexer().getLoc(); Parser.eatToEndOfStatement(); return Error(Loc, "unexpected token in argument list"); Index: llvm/test/MC/AVR/inst-lds-tiny.s =================================================================== --- llvm/test/MC/AVR/inst-lds-tiny.s +++ 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 Index: llvm/test/MC/AVR/inst-lds.s =================================================================== --- llvm/test/MC/AVR/inst-lds.s +++ 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 Index: llvm/test/MC/AVR/inst-sts-tiny.s =================================================================== --- llvm/test/MC/AVR/inst-sts-tiny.s +++ 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 Index: llvm/test/MC/AVR/inst-sts.s =================================================================== --- llvm/test/MC/AVR/inst-sts.s +++ 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