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, |