diff options
Diffstat (limited to 'llvm/lib/AsmParser')
| -rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 73 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 2 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | 
4 files changed, 77 insertions, 1 deletions
| diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index af4f43986ef..4f8ce3ddc7b 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -823,6 +823,8 @@ lltok::Kind LLLexer::LexIdentifier() {      }                                                                          \    } while (false) +  INSTKEYWORD(fneg,  FNeg); +    INSTKEYWORD(add,   Add);  INSTKEYWORD(fadd,   FAdd);    INSTKEYWORD(sub,   Sub);  INSTKEYWORD(fsub,   FSub);    INSTKEYWORD(mul,   Mul);  INSTKEYWORD(fmul,   FMul); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 5fe1e125d48..856be2fb64a 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3295,7 +3295,31 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {      ID.Kind = ValID::t_Constant;      return false;    } - +  +  // Unary Operators. +  case lltok::kw_fneg: { +    unsigned Opc = Lex.getUIntVal(); +    Constant *Val; +    Lex.Lex(); +    if (ParseToken(lltok::lparen, "expected '(' in unary constantexpr") || +        ParseGlobalTypeAndValue(Val) || +        ParseToken(lltok::rparen, "expected ')' in unary constantexpr")) +      return true; +     +    // Check that the type is valid for the operator. +    switch (Opc) { +    case Instruction::FNeg: +      if (!Val->getType()->isFPOrFPVectorTy()) +        return Error(ID.Loc, "constexpr requires fp operands"); +      break; +    default: llvm_unreachable("Unknown unary operator!"); +    } +    unsigned Flags = 0; +    Constant *C = ConstantExpr::get(Opc, Val, Flags); +    ID.ConstantVal = C; +    ID.Kind = ValID::t_Constant; +    return false; +  }    // Binary Operators.    case lltok::kw_add:    case lltok::kw_fadd: @@ -5492,6 +5516,16 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,    case lltok::kw_catchswitch: return ParseCatchSwitch(Inst, PFS);    case lltok::kw_catchpad:    return ParseCatchPad(Inst, PFS);    case lltok::kw_cleanuppad:  return ParseCleanupPad(Inst, PFS); +  // Unary Operators. +  case lltok::kw_fneg: { +    FastMathFlags FMF = EatFastMathFlagsIfPresent(); +    int Res = ParseUnaryOp(Inst, PFS, KeywordVal, 2); +    if (Res != 0) +      return Res; +    if (FMF.any()) +      Inst->setFastMathFlags(FMF); +    return false; +  }    // Binary Operators.    case lltok::kw_add:    case lltok::kw_sub: @@ -6064,6 +6098,43 @@ bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {  }  //===----------------------------------------------------------------------===// +// Unary Operators. +//===----------------------------------------------------------------------===// + +/// ParseUnaryOp +///  ::= UnaryOp TypeAndValue ',' Value +/// +/// If OperandType is 0, then any FP or integer operand is allowed.  If it is 1, +/// then any integer operand is allowed, if it is 2, any fp operand is allowed. +bool LLParser::ParseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, +                            unsigned Opc, unsigned OperandType) { +  LocTy Loc; Value *LHS; +  if (ParseTypeAndValue(LHS, Loc, PFS)) +    return true; + +  bool Valid; +  switch (OperandType) { +  default: llvm_unreachable("Unknown operand type!"); +  case 0: // int or FP. +    Valid = LHS->getType()->isIntOrIntVectorTy() || +            LHS->getType()->isFPOrFPVectorTy(); +    break; +  case 1:  +    Valid = LHS->getType()->isIntOrIntVectorTy();  +    break; +  case 2:  +    Valid = LHS->getType()->isFPOrFPVectorTy();  +    break; +  } + +  if (!Valid) +    return Error(Loc, "invalid operand type for instruction"); + +  Inst = UnaryOperator::Create((Instruction::UnaryOps)Opc, LHS); +  return false; +} + +//===----------------------------------------------------------------------===//  // Binary Operators.  //===----------------------------------------------------------------------===// diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index cec1a8e8f7e..6f8962b6d4e 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -571,6 +571,8 @@ namespace llvm {      bool ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS);      bool ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS); +    bool ParseUnaryOp(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc, +                      unsigned OperandType);      bool ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc,                           unsigned OperandType);      bool ParseLogical(Instruction *&Inst, PerFunctionState &PFS, unsigned Opc); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index f8f5955a16c..dae1d41fd8c 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -270,6 +270,7 @@ enum Kind {    kw_umin,    // Instruction Opcodes (Opcode in UIntVal). +  kw_fneg,    kw_add,    kw_fadd,    kw_sub, | 

