BuildFAdd() public method

public BuildFAdd ( Value lhs, Value rhs, string varName = tmpvarname ) : Value
lhs Value
rhs Value
varName string
return Value
Beispiel #1
0
        public override Value CodeGen(IRBuilder builder)
        {
            Value l = this.LHS.CodeGen(builder);
            Value r = this.RHS.CodeGen(builder);
            if(l.IsNull || r.IsNull) return Value.Null;

            switch(this.Op)
            {
                case '+':
                    return builder.BuildFAdd(l, r);
                case '-':
                    return builder.BuildFSub(l, r);
                case '*':
                    return builder.BuildFMul(l, r);
                case '<':
                    // Convert bool 0/1 to double 0.0 or 1.0
                    return builder.BuildFCmpAndPromote(l, LLVMRealPredicate.RealULT, 
                                                       r, TypeRef.CreateDouble());
            }

            // If it wasn't a builtin binary operator, it must be a user defined one. Emit
            // a call to it.
            Function f = CodeGenManager.Module.GetFunction("binary" + this.Op);
            Debug.Assert(f != null);

            Value[] ops = new Value[] { l, r };
            return builder.BuildCall(f, ops, "binop");
        }
Beispiel #2
0
        public override Value CodeGen(IRBuilder builder)
        {
            Value l = this.LHS.CodeGen(builder);
            Value r = this.RHS.CodeGen(builder);
            if(l.IsNull || r.IsNull) return Value.Null;

            switch(this.Op)
            {
                case '+':
                    return builder.BuildFAdd(l, r);
                case '-':
                    return builder.BuildFSub(l, r);
                case '*':
                    return builder.BuildFMul(l, r);
                case '<':
                    // Convert bool 0/1 to double 0.0 or 1.0
                    return builder.BuildFCmpAndPromote(l, LLVMRealPredicate.RealULT, r, TypeRef.CreateDouble());
            }

            CodeGenManager.ErrorOutput.WriteLine("Unknown binary operator.");
            return Value.Null;
        }
Beispiel #3
0
        public override Value CodeGen(IRBuilder builder)
        {
            Value startV = this.Start.CodeGen(builder);
            if(startV.IsNull) return startV;

            BasicBlock startBlock = builder.GetInsertPoint();
            Function func = startBlock.GetParent();

            BasicBlock loopBB = func.AppendBasicBlock("loop");
            builder.BuildBr(loopBB);
            builder.SetInsertPoint(loopBB);

            Value variable = builder.BuildPhi(TypeRef.CreateDouble(), this.VarName, new PhiIncoming(startV, startBlock));

            /* Within the loop, the variable is defined equal to the PHI node. If it
            * shadows an existing variable, we have to restore it, so save it
            * now. */
            Value oldVal = Value.Null;
            CodeGenManager.NamedValues.TryGetValue(this.VarName, out oldVal);
            CodeGenManager.NamedValues[this.VarName] = variable;

            /* Emit the body of the loop.  This, like any other expr, can change the
            * current BB.  Note that we ignore the value computed by the body, but
            * don't allow an error */
            Body.CodeGen(builder);

            // Emit the step value;
            Value stepV = Value.Null;

            if(this.Step != null)
                stepV = this.Step.CodeGen(builder);
            else
                stepV = Value.CreateConstDouble(1);

            Value nextVar = builder.BuildFAdd(variable, stepV, "nextvar");

            // Compute the end condition
            Value endCond = this.End.CodeGen(builder);
            endCond = builder.BuildFCmp(endCond, LLVMRealPredicate.RealONE, Value.CreateConstDouble(0), "loopcond");

            BasicBlock loopEndBB = builder.GetInsertPoint();
            BasicBlock afterBB = func.AppendBasicBlock("afterloop");
            builder.BuildCondBr(endCond, loopBB, afterBB);
            builder.SetInsertPoint(afterBB);

            builder.AddPhiIncoming(variable, nextVar, loopEndBB);

            if(!oldVal.IsNull)
                CodeGenManager.NamedValues[this.VarName] = oldVal;

            return Value.CreateConstDouble(0);
        }
Beispiel #4
0
        public override Value CodeGen(IRBuilder builder)
        {
            // Output this as:
            //   var = alloca double
            //   ...
            //   start = startexpr
            //   store start -> var
            //   goto loop
            // loop: 
            //   ...
            //   bodyexpr
            //   ...
            // loopend:
            //   step = stepexpr
            //   endcond = endexpr
            //
            //   curvar = load var
            //   nextvar = curvar + step
            //   store nextvar -> var
            //   br endcond, loop, endloop
            // outloop:

            BasicBlock startBlock = builder.GetInsertPoint();
            Function func = startBlock.GetParent();

            Value alloca = builder.BuildEntryBlockAlloca(func, TypeRef.CreateDouble(), this.VarName);

            Value startV = this.Start.CodeGen(builder);
            if(startV.IsNull) return startV;

            builder.BuildStore(startV, alloca);

            BasicBlock loopBB = func.AppendBasicBlock("loop");
            builder.BuildBr(loopBB);
            builder.SetInsertPoint(loopBB);

            /* Within the loop, the variable is defined equal to the PHI node. If it
            * shadows an existing variable, we have to restore it, so save it
            * now. */
            Value oldVal = Value.Null;
            CodeGenManager.NamedValues.TryGetValue(this.VarName, out oldVal);
            CodeGenManager.NamedValues[this.VarName] = alloca;

            /* Emit the body of the loop.  This, like any other expr, can change the
            * current BB.  Note that we ignore the value computed by the body, but
            * don't allow an error */
            Body.CodeGen(builder);

            // Emit the step value;
            Value stepV = Value.Null;

            if(this.Step != null)
                stepV = this.Step.CodeGen(builder);
            else
                stepV = Value.CreateConstDouble(1);

            // Compute the end condition
            Value endCond = this.End.CodeGen(builder);
            endCond = builder.BuildFCmp(endCond, LLVMRealPredicate.RealONE, Value.CreateConstDouble(0), "loopcond");

            Value curvar = builder.BuildLoad(alloca, VarName);
            Value nextVar = builder.BuildFAdd(curvar, stepV, "nextvar");
            builder.BuildStore(nextVar, alloca);

            BasicBlock loopEndBB = builder.GetInsertPoint();
            BasicBlock afterBB = func.AppendBasicBlock("afterloop");
            builder.BuildCondBr(endCond, loopBB, afterBB);
            builder.SetInsertPoint(afterBB);

            if(!oldVal.IsNull)
                CodeGenManager.NamedValues[this.VarName] = oldVal;
            else
                CodeGenManager.NamedValues.Remove(this.VarName);

            return Value.CreateConstDouble(0);
        }