private LLVMValueRef GenerateFloatingPointMath(string op, LLVMValueRef lhs, LLVMValueRef rhs, LLVMBuilderRef builder) { Debug.Assert(lhs.TypeOf().TypeKind == LLVM.Int32Type().TypeKind || lhs.TypeOf().TypeKind == LLVM.DoubleType().TypeKind); Debug.Assert(rhs.TypeOf().TypeKind == LLVM.Int32Type().TypeKind || rhs.TypeOf().TypeKind == LLVM.DoubleType().TypeKind); // Promotion for floats and ints to work together -- very fragile. Need to do better type checking. if (lhs.TypeOf().TypeKind == LLVM.Int32Type().TypeKind) { lhs = LLVM.BuildSIToFP(builder, lhs, LLVM.DoubleType(), ""); } if (rhs.TypeOf().TypeKind == LLVM.Int32Type().TypeKind) { rhs = LLVM.BuildSIToFP(builder, rhs, LLVM.DoubleType(), ""); } if (op == "+") { return LLVM.BuildFAdd(builder, lhs, rhs, ""); } else if (op == "-") { return LLVM.BuildFSub(builder, lhs, rhs, ""); } else if (op == "*") { return LLVM.BuildFMul(builder, lhs, rhs, ""); } else if (op == "/") { return LLVM.BuildFDiv(builder, lhs, rhs, ""); } else if (op == "%") { return LLVM.BuildFRem(builder, lhs, rhs, ""); } else if (op == "<") { return LLVM.BuildFCmp(builder, LLVMRealPredicate.LLVMRealOLT, lhs, rhs, ""); } else if (op == ">") { return LLVM.BuildFCmp(builder, LLVMRealPredicate.LLVMRealOGT, lhs, rhs, ""); } else if (op == "==") { return LLVM.BuildFCmp(builder, LLVMRealPredicate.LLVMRealOEQ, lhs, rhs, ""); } else if (op == ">=") { return LLVM.BuildFCmp(builder, LLVMRealPredicate.LLVMRealOGE, lhs, rhs, ""); } else if (op == "<=") { return LLVM.BuildFCmp(builder, LLVMRealPredicate.LLVMRealOLE, lhs, rhs, ""); } else { throw new Exception("unknown operator"); } }
private LLVMValueRef GenerateIntegerMath(string op, LLVMValueRef lhs, LLVMValueRef rhs, LLVMBuilderRef builder) { Debug.Assert(lhs.TypeOf().TypeKind == LLVM.Int32Type().TypeKind); Debug.Assert(rhs.TypeOf().TypeKind == LLVM.Int32Type().TypeKind); if (op == "+") { return LLVM.BuildAdd(builder, lhs, rhs, ""); } else if (op == "-") { return LLVM.BuildSub(builder, lhs, rhs, ""); } else if (op == "*") { return LLVM.BuildMul(builder, lhs, rhs, ""); } else if (op == "/") { return LLVM.BuildSDiv(builder, lhs, rhs, ""); } else if (op == "%") { return LLVM.BuildSRem(builder, lhs, rhs, ""); } else if (op == "<") { return LLVM.BuildICmp(builder, LLVMIntPredicate.LLVMIntSLT, lhs, rhs, ""); } else if (op == ">") { return LLVM.BuildICmp(builder, LLVMIntPredicate.LLVMIntSGT, lhs, rhs, ""); } else if (op == "==") { return LLVM.BuildICmp(builder, LLVMIntPredicate.LLVMIntEQ, lhs, rhs, ""); } else if (op == ">=") { return LLVM.BuildICmp(builder, LLVMIntPredicate.LLVMIntSGE, lhs, rhs, ""); } else if (op == "<=") { return LLVM.BuildICmp(builder, LLVMIntPredicate.LLVMIntSLE, lhs, rhs, ""); } else { throw new Exception("unknown operator"); } }