1 /**************************************************************************
3 * Copyright 2010 VMware, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
31 #include "util/u_debug.h"
32 #include "util/u_memory.h"
33 #include "util/u_string.h"
34 #include "lp_bld_const.h"
35 #include "lp_bld_init.h"
36 #include "lp_bld_const.h"
37 #include "lp_bld_printf.h"
38 #include "lp_bld_type.h"
42 * Generates LLVM IR to call debug_printf.
45 lp_build_print_args(struct gallivm_state
* gallivm
,
49 LLVMBuilderRef builder
= gallivm
->builder
;
50 LLVMContextRef context
= gallivm
->context
;
55 assert(LLVMTypeOf(args
[0]) == LLVMPointerType(LLVMInt8TypeInContext(context
), 0));
57 /* Cast any float arguments to doubles as printf expects */
58 for (i
= 1; i
< argcount
; i
++) {
59 LLVMTypeRef type
= LLVMTypeOf(args
[i
]);
61 if (LLVMGetTypeKind(type
) == LLVMFloatTypeKind
)
62 args
[i
] = LLVMBuildFPExt(builder
, args
[i
], LLVMDoubleTypeInContext(context
), "");
65 if (!gallivm
->debug_printf_hook
) {
66 LLVMTypeRef printf_type
= LLVMFunctionType(LLVMInt32TypeInContext(context
), NULL
, 0, 1);
67 gallivm
->debug_printf_hook
= LLVMAddFunction(gallivm
->module
, "debug_printf", printf_type
);
69 return LLVMBuildCall(builder
, gallivm
->debug_printf_hook
, args
, argcount
, "");
74 * Print a LLVM value of any type
77 lp_build_print_value(struct gallivm_state
*gallivm
,
81 LLVMBuilderRef builder
= gallivm
->builder
;
82 LLVMTypeKind type_kind
;
84 LLVMValueRef params
[2 + LP_MAX_VECTOR_LENGTH
];
85 char type_fmt
[6] = " %x";
86 char format
[2 + 5 * LP_MAX_VECTOR_LENGTH
+ 2] = "%s";
90 type_ref
= LLVMTypeOf(value
);
91 type_kind
= LLVMGetTypeKind(type_ref
);
93 if (type_kind
== LLVMVectorTypeKind
) {
94 length
= LLVMGetVectorSize(type_ref
);
96 type_ref
= LLVMGetElementType(type_ref
);
97 type_kind
= LLVMGetTypeKind(type_ref
);
102 if (type_kind
== LLVMFloatTypeKind
|| type_kind
== LLVMDoubleTypeKind
) {
107 } else if (type_kind
== LLVMIntegerTypeKind
) {
108 if (LLVMGetIntTypeWidth(type_ref
) == 64) {
109 snprintf(type_fmt
+ 2, 3, "%s", PRId64
);
110 } else if (LLVMGetIntTypeWidth(type_ref
) == 8) {
115 } else if (type_kind
== LLVMPointerTypeKind
) {
118 /* Unsupported type */
122 /* Create format string and arguments */
123 assert(strlen(format
) + strlen(type_fmt
) * length
+ 2 <= sizeof format
);
125 params
[1] = lp_build_const_string(gallivm
, msg
);
127 strncat(format
, type_fmt
, sizeof(format
) - strlen(format
) - 1);
130 for (i
= 0; i
< length
; ++i
) {
132 strncat(format
, type_fmt
, sizeof(format
) - strlen(format
) - 1);
133 param
= LLVMBuildExtractElement(builder
, value
, lp_build_const_int32(gallivm
, i
), "");
134 if (type_kind
== LLVMIntegerTypeKind
&&
135 LLVMGetIntTypeWidth(type_ref
) < sizeof(int) * 8) {
136 LLVMTypeRef int_type
= LLVMIntTypeInContext(gallivm
->context
, sizeof(int) * 8);
137 if (LLVMGetIntTypeWidth(type_ref
) == 8) {
138 param
= LLVMBuildZExt(builder
, param
, int_type
, "");
140 param
= LLVMBuildSExt(builder
, param
, int_type
, "");
143 params
[2 + i
] = param
;
147 strncat(format
, "\n", sizeof(format
) - strlen(format
) - 1);
149 params
[0] = lp_build_const_string(gallivm
, format
);
150 return lp_build_print_args(gallivm
, 2 + length
, params
);
155 lp_get_printf_arg_count(const char *fmt
)
171 if (p
[1] == '*' && p
[2] == 's') {
186 * Generate LLVM IR for a c style printf
189 lp_build_printf(struct gallivm_state
*gallivm
,
190 const char *fmt
, ...)
192 LLVMValueRef params
[50];
194 unsigned argcount
, i
;
196 argcount
= lp_get_printf_arg_count(fmt
);
197 assert(ARRAY_SIZE(params
) >= argcount
+ 1);
199 va_start(arglist
, fmt
);
200 for (i
= 1; i
<= argcount
; i
++) {
201 params
[i
] = va_arg(arglist
, LLVMValueRef
);
205 params
[0] = lp_build_const_string(gallivm
, fmt
);
206 return lp_build_print_args(gallivm
, argcount
+ 1, params
);