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
;
51 LLVMValueRef func_printf
;
52 LLVMTypeRef printf_type
;
57 assert(LLVMTypeOf(args
[0]) == LLVMPointerType(LLVMInt8TypeInContext(context
), 0));
59 /* Cast any float arguments to doubles as printf expects */
60 for (i
= 1; i
< argcount
; i
++) {
61 LLVMTypeRef type
= LLVMTypeOf(args
[i
]);
63 if (LLVMGetTypeKind(type
) == LLVMFloatTypeKind
)
64 args
[i
] = LLVMBuildFPExt(builder
, args
[i
], LLVMDoubleTypeInContext(context
), "");
67 printf_type
= LLVMFunctionType(LLVMInt32TypeInContext(context
), NULL
, 0, 1);
68 func_printf
= lp_build_const_int_pointer(gallivm
, func_to_pointer((func_pointer
)debug_printf
));
69 func_printf
= LLVMBuildBitCast(builder
, func_printf
, LLVMPointerType(printf_type
, 0), "debug_printf");
71 return LLVMBuildCall(builder
, func_printf
, args
, argcount
, "");
76 * Print a LLVM value of any type
79 lp_build_print_value(struct gallivm_state
*gallivm
,
83 LLVMBuilderRef builder
= gallivm
->builder
;
84 LLVMTypeKind type_kind
;
86 LLVMValueRef params
[2 + LP_MAX_VECTOR_LENGTH
];
87 char type_fmt
[6] = " %x";
88 char format
[2 + 5 * LP_MAX_VECTOR_LENGTH
+ 2] = "%s";
92 type_ref
= LLVMTypeOf(value
);
93 type_kind
= LLVMGetTypeKind(type_ref
);
95 if (type_kind
== LLVMVectorTypeKind
) {
96 length
= LLVMGetVectorSize(type_ref
);
98 type_ref
= LLVMGetElementType(type_ref
);
99 type_kind
= LLVMGetTypeKind(type_ref
);
104 if (type_kind
== LLVMFloatTypeKind
|| type_kind
== LLVMDoubleTypeKind
) {
109 } else if (type_kind
== LLVMIntegerTypeKind
) {
110 if (LLVMGetIntTypeWidth(type_ref
) == 64) {
111 unsigned flen
= strlen(PRId64
);
113 strncpy(type_fmt
+ 2, PRId64
, flen
);
114 } else if (LLVMGetIntTypeWidth(type_ref
) == 8) {
119 } else if (type_kind
== LLVMPointerTypeKind
) {
122 /* Unsupported type */
126 /* Create format string and arguments */
127 assert(strlen(format
) + strlen(type_fmt
) * length
+ 2 <= sizeof format
);
129 params
[1] = lp_build_const_string(gallivm
, msg
);
131 util_strncat(format
, type_fmt
, sizeof(format
) - strlen(format
) - 1);
134 for (i
= 0; i
< length
; ++i
) {
136 util_strncat(format
, type_fmt
, sizeof(format
) - strlen(format
) - 1);
137 param
= LLVMBuildExtractElement(builder
, value
, lp_build_const_int32(gallivm
, i
), "");
138 if (type_kind
== LLVMIntegerTypeKind
&&
139 LLVMGetIntTypeWidth(type_ref
) < sizeof(int) * 8) {
140 LLVMTypeRef int_type
= LLVMIntTypeInContext(gallivm
->context
, sizeof(int) * 8);
141 if (LLVMGetIntTypeWidth(type_ref
) == 8) {
142 param
= LLVMBuildZExt(builder
, param
, int_type
, "");
144 param
= LLVMBuildSExt(builder
, param
, int_type
, "");
147 params
[2 + i
] = param
;
151 util_strncat(format
, "\n", sizeof(format
) - strlen(format
) - 1);
153 params
[0] = lp_build_const_string(gallivm
, format
);
154 return lp_build_print_args(gallivm
, 2 + length
, params
);
159 lp_get_printf_arg_count(const char *fmt
)
175 if (p
[1] == '*' && p
[2] == 's') {
190 * Generate LLVM IR for a c style printf
193 lp_build_printf(struct gallivm_state
*gallivm
,
194 const char *fmt
, ...)
196 LLVMValueRef params
[50];
201 argcount
= lp_get_printf_arg_count(fmt
);
202 assert(Elements(params
) >= argcount
+ 1);
204 va_start(arglist
, fmt
);
205 for (i
= 1; i
<= argcount
; i
++) {
206 params
[i
] = va_arg(arglist
, LLVMValueRef
);
210 params
[0] = lp_build_const_string(gallivm
, fmt
);
211 return lp_build_print_args(gallivm
, argcount
+ 1, params
);