public override Value VisitBinaryOpExpression([NotNull] BinaryOpExpressionContext context) { var lhs = context.Lhs.Accept(this); var rhs = context.Rhs.Accept(this); if (lhs == null || rhs == null) { return(null); } switch (context.Op) { case '<': { var tmp = InstructionBuilder.Compare(RealPredicate.UnorderedOrLessThan, lhs, rhs) .RegisterName("cmptmp"); return(InstructionBuilder.UIToFPCast(tmp, InstructionBuilder.Context.DoubleType) .RegisterName("booltmp")); } case '^': { var pow = GetOrDeclareFunction(new Prototype("llvm.pow.f64", "value", "power")); return(InstructionBuilder.Call(pow, lhs, rhs) .RegisterName("powtmp")); } case '+': return(InstructionBuilder.FAdd(lhs, rhs).RegisterName("addtmp")); case '-': return(InstructionBuilder.FSub(lhs, rhs).RegisterName("subtmp")); case '*': return(InstructionBuilder.FMul(lhs, rhs).RegisterName("multmp")); case '/': return(InstructionBuilder.FDiv(lhs, rhs).RegisterName("divtmp")); default: { // User defined op? var opKind = context.GetOperatorInfo(ParserStack.Parser); if (opKind != OperatorKind.InfixLeftAssociative && opKind != OperatorKind.InfixRightAssociative) { throw new ArgumentException($"Invalid binary operator {context.Op}", nameof(context)); } string calleeName = $"$binary{context.Op}"; var function = GetFunction(calleeName); if (function == null) { throw new ArgumentException($"Unknown function reference {calleeName}", nameof(context)); } var args = context.Args.Select(a => a.Accept(this)).ToList( ); return(InstructionBuilder.Call(function, args).RegisterName("calltmp")); } } }
public override Value Visit(BinaryOperatorExpression binaryOperator) { EmitLocation(binaryOperator); switch (binaryOperator.Op) { case BuiltInOperatorKind.Less: { var tmp = InstructionBuilder.Compare(RealPredicate.UnorderedOrLessThan , binaryOperator.Left.Accept(this) , binaryOperator.Right.Accept(this) ).RegisterName("cmptmp"); return(InstructionBuilder.UIToFPCast(tmp, InstructionBuilder.Context.DoubleType) .RegisterName("booltmp")); } case BuiltInOperatorKind.Pow: { var pow = GetOrDeclareFunction(new Prototype("llvm.pow.f64", "value", "power")); return(InstructionBuilder.Call(pow , binaryOperator.Left.Accept(this) , binaryOperator.Right.Accept(this) ).RegisterName("powtmp")); } case BuiltInOperatorKind.Add: return(InstructionBuilder.FAdd(binaryOperator.Left.Accept(this) , binaryOperator.Right.Accept(this) ).RegisterName("addtmp")); case BuiltInOperatorKind.Subtract: return(InstructionBuilder.FSub(binaryOperator.Left.Accept(this) , binaryOperator.Right.Accept(this) ).RegisterName("subtmp")); case BuiltInOperatorKind.Multiply: return(InstructionBuilder.FMul(binaryOperator.Left.Accept(this) , binaryOperator.Right.Accept(this) ).RegisterName("multmp")); case BuiltInOperatorKind.Divide: return(InstructionBuilder.FDiv(binaryOperator.Left.Accept(this) , binaryOperator.Right.Accept(this) ).RegisterName("divtmp")); case BuiltInOperatorKind.Assign: Alloca target = LookupVariable((( VariableReferenceExpression )binaryOperator.Left).Name); Value value = binaryOperator.Right.Accept(this); InstructionBuilder.Store(value, target); return(value); default: throw new CodeGeneratorException($"ICE: Invalid binary operator {binaryOperator.Op}"); } }
public override Value VisitBinaryOpExpression([NotNull] BinaryOpExpressionContext context) { var lhs = context.Lhs.Accept(this); var rhs = context.Rhs.Accept(this); if (lhs == null || rhs == null) { return(null); } switch (context.Op) { case '<': { var tmp = InstructionBuilder.Compare(RealPredicate.UnorderedOrLessThan, lhs, rhs) .RegisterName("cmptmp"); return(InstructionBuilder.UIToFPCast(tmp, InstructionBuilder.Context.DoubleType) .RegisterName("booltmp")); } case '^': { var pow = GetOrDeclareFunction(new Prototype("llvm.pow.f64", "value", "power")); return(InstructionBuilder.Call(pow, lhs, rhs) .RegisterName("powtmp")); } case '+': return(InstructionBuilder.FAdd(lhs, rhs).RegisterName("addtmp")); case '-': return(InstructionBuilder.FSub(lhs, rhs).RegisterName("subtmp")); case '*': return(InstructionBuilder.FMul(lhs, rhs).RegisterName("multmp")); case '/': return(InstructionBuilder.FDiv(lhs, rhs).RegisterName("divtmp")); default: throw new ArgumentException($"Invalid binary operator {context.Op}", nameof(context)); } }