/** * lp_build_printf. * * Build printf call in LLVM IR. The output goes to stdout. * The additional variable arguments need to have type * LLVMValueRef. */ LLVMValueRef lp_build_printf(struct gallivm_state *gallivm, const char *fmt, ...) { va_list arglist; int i = 0; int argcount = lp_get_printf_arg_count(fmt); LLVMBuilderRef builder = gallivm->builder; LLVMContextRef context = gallivm->context; LLVMModuleRef module = gallivm->module; LLVMValueRef params[50]; LLVMValueRef fmtarg = lp_build_const_string_variable(module, context, fmt, strlen(fmt) + 1); LLVMValueRef int0 = lp_build_const_int32(gallivm, 0); LLVMValueRef index[2]; LLVMValueRef func_printf = LLVMGetNamedFunction(module, "printf"); assert(Elements(params) >= argcount + 1); index[0] = index[1] = int0; if (!func_printf) { LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntTypeInContext(context, 32), NULL, 0, 1); func_printf = LLVMAddFunction(module, "printf", printf_type); } params[0] = LLVMBuildGEP(builder, fmtarg, index, 2, ""); va_start(arglist, fmt); for (i = 1; i <= argcount; i++) { LLVMValueRef val = va_arg(arglist, LLVMValueRef); LLVMTypeRef type = LLVMTypeOf(val); /* printf wants doubles, so lets convert so that * we can actually print them */ if (LLVMGetTypeKind(type) == LLVMFloatTypeKind) val = LLVMBuildFPExt(builder, val, LLVMDoubleTypeInContext(context), ""); params[i] = val; } va_end(arglist); return LLVMBuildCall(builder, func_printf, params, argcount + 1, ""); }
/** * Generate LLVM IR for a c style printf */ LLVMValueRef lp_build_printf(struct gallivm_state *gallivm, const char *fmt, ...) { LLVMValueRef params[50]; va_list arglist; int argcount; int i; argcount = lp_get_printf_arg_count(fmt); assert(Elements(params) >= argcount + 1); va_start(arglist, fmt); for (i = 1; i <= argcount; i++) { params[i] = va_arg(arglist, LLVMValueRef); } va_end(arglist); params[0] = lp_build_const_string(gallivm, fmt); return lp_build_print_args(gallivm, argcount + 1, params); }