Example #1
0
        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}");
            }
        }
Example #3
0
        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));
            }
        }