Index: llvm/trunk/lib/MC/MCParser/AsmParser.cpp =================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp @@ -2067,7 +2067,6 @@ case AsmToken::AmpAmp: case AsmToken::Exclaim: case AsmToken::ExclaimEqual: - case AsmToken::Percent: case AsmToken::Less: case AsmToken::LessEqual: case AsmToken::LessLess: @@ -2106,37 +2105,44 @@ } unsigned ParenLevel = 0; - unsigned AddTokens = 0; // Darwin doesn't use spaces to delmit arguments. AsmLexerSkipSpaceRAII ScopedSkipSpace(Lexer, IsDarwin); + bool SpaceEaten; + for (;;) { + SpaceEaten = false; if (Lexer.is(AsmToken::Eof) || Lexer.is(AsmToken::Equal)) return TokError("unexpected token in macro instantiation"); - if (ParenLevel == 0 && Lexer.is(AsmToken::Comma)) - break; + if (ParenLevel == 0) { - if (Lexer.is(AsmToken::Space)) { - Lex(); // Eat spaces + if (Lexer.is(AsmToken::Comma)) + break; + + if (Lexer.is(AsmToken::Space)) { + SpaceEaten = true; + Lex(); // Eat spaces + } // Spaces can delimit parameters, but could also be part an expression. // If the token after a space is an operator, add the token and the next // one into this argument if (!IsDarwin) { if (isOperator(Lexer.getKind())) { - // Check to see whether the token is used as an operator, - // or part of an identifier - const char *NextChar = getTok().getEndLoc().getPointer(); - if (*NextChar == ' ') - AddTokens = 2; - } + MA.push_back(getTok()); + Lex(); - if (!AddTokens && ParenLevel == 0) { - break; + // Whitespace after an operator can be ignored. + if (Lexer.is(AsmToken::Space)) + Lex(); + + continue; } } + if (SpaceEaten) + break; } // handleMacroEntry relies on not advancing the lexer here @@ -2152,8 +2158,6 @@ // Append the token to the current argument list. MA.push_back(getTok()); - if (AddTokens) - AddTokens--; Lex(); } Index: llvm/trunk/test/MC/AsmParser/macros-gas.s =================================================================== --- llvm/trunk/test/MC/AsmParser/macros-gas.s +++ llvm/trunk/test/MC/AsmParser/macros-gas.s @@ -39,10 +39,10 @@ .ascii "\_a \_b \_c" .endm -// CHECK: .ascii "1 (23) " +// CHECK: .ascii "1 (2 3) " test3_prime 1, (2 3) -// CHECK: .ascii "1 (23) " +// CHECK: .ascii "1 (2 3) " test3_prime 1 (2 3) // CHECK: .ascii "1 2 " Index: llvm/trunk/test/MC/Mips/user-macro-argument-separation.s =================================================================== --- llvm/trunk/test/MC/Mips/user-macro-argument-separation.s +++ llvm/trunk/test/MC/Mips/user-macro-argument-separation.s @@ -0,0 +1,40 @@ +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32r2 | \ +# RUN: FileCheck %s +# RUN: llvm-mc %s -triple=mipsel-unknown-linux -show-encoding -mcpu=mips32r2 | \ +# RUN: FileCheck %s +# RUN: llvm-mc %s -triple=mips-unknown-linux -show-encoding -mcpu=mips32r2 | \ +# RUN: FileCheck %s + +# Check that the IAS expands macro instructions in the same way as GAS + +.extern sym +# imm and rs are deliberately swapped to test whitespace separated arguments. +.macro EX2 insn, rd, imm, rs +.ex\@: \insn \rd, \rs, \imm +.endm + +.option pic0 + +EX2 addiu $2, 1 $3 # CHECK: addiu $2, $3, 1 +EX2 addiu $2, ~1 $3 # CHECK: addiu $2, $3, -2 +EX2 addiu $2, ~ 1 $3 # CHECK: addiu $2, $3, -2 +EX2 addiu $2, 1+1 $3 # CHECK: addiu $2, $3, 2 +EX2 addiu $2, 1+ 1 $3 # CHECK: addiu $2, $3, 2 +EX2 addiu $2, 1 +1 $3 # CHECK: addiu $2, $3, 2 +EX2 addiu $2, 1 + 1 $3 # CHECK: addiu $2, $3, 2 +EX2 addiu $2, 1+~1 $3 # CHECK: addiu $2, $3, -1 +EX2 addiu $2, 1+~ 1 $3 # CHECK: addiu $2, $3, -1 +EX2 addiu $2, 1+ ~1 $3 # CHECK: addiu $2, $3, -1 +EX2 addiu $2, 1 +~1 $3 # CHECK: addiu $2, $3, -1 +EX2 addiu $2, 1 +~ 1 $3 # CHECK: addiu $2, $3, -1 +EX2 addiu $2, 1 + ~1 $3 # CHECK: addiu $2, $3, -1 +EX2 addiu $2, 1 + ~ 1 $3 # CHECK: addiu $2, $3, -1 +EX2 addiu $2, 1+(1) $3 # CHECK: addiu $2, $3, 2 +EX2 addiu $2, 1 +(1) $3 # CHECK: addiu $2, $3, 2 +EX2 addiu $2, 1+ (1) $3 # CHECK: addiu $2, $3, 2 +EX2 addiu $2, 1 + (1) $3 # CHECK: addiu $2, $3, 2 +EX2 addiu $2, 1+(1)+1 $3 # CHECK: addiu $2, $3, 3 +EX2 addiu $2, 1 +(1)+1 $3 # CHECK: addiu $2, $3, 3 +EX2 addiu $2, 1+ (1)+1 $3 # CHECK: addiu $2, $3, 3 +EX2 addiu $2, 1 + (1)+1 $3 # CHECK: addiu $2, $3, 3 +nop # CHECK: nop