diff options
| author | Ehsan Akhgari <ehsan.akhgari@gmail.com> | 2014-07-04 19:13:05 +0000 | 
|---|---|---|
| committer | Ehsan Akhgari <ehsan.akhgari@gmail.com> | 2014-07-04 19:13:05 +0000 | 
| commit | 4103da6bfb48de048751e4e5c68f085757b005e0 (patch) | |
| tree | 1621a254b4b2f81b8b46af5d99dd437b13f9afb6 /llvm | |
| parent | 2dc0d9bddb578f5ddf02495caf97a6281ee06fab (diff) | |
| download | bcm5719-llvm-4103da6bfb48de048751e4e5c68f085757b005e0.tar.gz bcm5719-llvm-4103da6bfb48de048751e4e5c68f085757b005e0.zip  | |
Add support for parsing the not operator in Microsoft inline assembly
This fixes http://llvm.org/PR20202
llvm-svn: 212352
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 41 | 
1 files changed, 36 insertions, 5 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 3e57914f9e9..f0765ed50d7 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -235,6 +235,7 @@ private:      IES_RSHIFT,      IES_PLUS,      IES_MINUS, +    IES_NOT,      IES_MULTIPLY,      IES_DIVIDE,      IES_LBRAC, @@ -372,6 +373,7 @@ private:          State = IES_ERROR;          break;        case IES_PLUS: +      case IES_NOT:        case IES_MULTIPLY:        case IES_DIVIDE:        case IES_LPAREN: @@ -401,6 +403,19 @@ private:        }        PrevState = CurrState;      } +    void onNot() { +      IntelExprState CurrState = State; +      switch (State) { +      default: +        State = IES_ERROR; +        break; +      case IES_PLUS: +      case IES_NOT: +        State = IES_NOT; +        break; +      } +      PrevState = CurrState; +    }      void onRegister(unsigned Reg) {        IntelExprState CurrState = State;        switch (State) { @@ -438,6 +453,7 @@ private:          break;        case IES_PLUS:        case IES_MINUS: +      case IES_NOT:          State = IES_INTEGER;          Sym = SymRef;          SymName = SymRefName; @@ -453,6 +469,7 @@ private:          break;        case IES_PLUS:        case IES_MINUS: +      case IES_NOT:        case IES_OR:        case IES_AND:        case IES_LSHIFT: @@ -476,11 +493,22 @@ private:                      PrevState == IES_OR || PrevState == IES_AND ||                      PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||                      PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || -                    PrevState == IES_LPAREN || PrevState == IES_LBRAC) && +                    PrevState == IES_LPAREN || PrevState == IES_LBRAC || +                    PrevState == IES_NOT) &&                     CurrState == IES_MINUS) {            // Unary minus.  No need to pop the minus operand because it was never            // pushed.            IC.pushOperand(IC_IMM, -TmpInt); // Push -Imm. +        } else if ((PrevState == IES_PLUS || PrevState == IES_MINUS || +                    PrevState == IES_OR || PrevState == IES_AND || +                    PrevState == IES_LSHIFT || PrevState == IES_RSHIFT || +                    PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || +                    PrevState == IES_LPAREN || PrevState == IES_LBRAC || +                    PrevState == IES_NOT) && +                   CurrState == IES_NOT) { +          // Unary not.  No need to pop the not operand because it was never +          // pushed. +          IC.pushOperand(IC_IMM, ~TmpInt); // Push ~Imm.          } else {            IC.pushOperand(IC_IMM, TmpInt);          } @@ -561,6 +589,7 @@ private:          break;        case IES_PLUS:        case IES_MINUS: +      case IES_NOT:        case IES_OR:        case IES_AND:        case IES_LSHIFT: @@ -568,13 +597,14 @@ private:        case IES_MULTIPLY:        case IES_DIVIDE:        case IES_LPAREN: -        // FIXME: We don't handle this type of unary minus, yet. +        // FIXME: We don't handle this type of unary minus or not, yet.          if ((PrevState == IES_PLUS || PrevState == IES_MINUS ||              PrevState == IES_OR || PrevState == IES_AND ||              PrevState == IES_LSHIFT || PrevState == IES_RSHIFT ||              PrevState == IES_MULTIPLY || PrevState == IES_DIVIDE || -            PrevState == IES_LPAREN || PrevState == IES_LBRAC) && -            CurrState == IES_MINUS) { +            PrevState == IES_LPAREN || PrevState == IES_LBRAC || +            PrevState == IES_NOT) && +            (CurrState == IES_MINUS || CurrState == IES_NOT)) {            State = IES_ERROR;            break;          } @@ -1141,6 +1171,7 @@ bool X86AsmParser::ParseIntelExpression(IntelExprStateMachine &SM, SMLoc &End) {      }      case AsmToken::Plus:    SM.onPlus(); break;      case AsmToken::Minus:   SM.onMinus(); break; +    case AsmToken::Tilde:   SM.onNot(); break;      case AsmToken::Star:    SM.onStar(); break;      case AsmToken::Slash:   SM.onDivide(); break;      case AsmToken::Pipe:    SM.onOr(); break; @@ -1523,7 +1554,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {    // Immediate.    if (getLexer().is(AsmToken::Integer) || getLexer().is(AsmToken::Minus) || -      getLexer().is(AsmToken::LParen)) {     +      getLexer().is(AsmToken::Tilde) || getLexer().is(AsmToken::LParen)) {      AsmToken StartTok = Tok;      IntelExprStateMachine SM(/*Imm=*/0, /*StopOnLBrac=*/true,                               /*AddImmPrefix=*/false);  | 

