+
+
+/**
+ * Performs lp_build_const_mask_aos, but first swizzles the mask
+ */
+LLVMValueRef
+lp_build_const_mask_aos_swizzled(struct gallivm_state *gallivm,
+ struct lp_type type,
+ unsigned mask,
+ unsigned channels,
+ const unsigned char *swizzle)
+{
+ unsigned i, mask_swizzled;
+ mask_swizzled = 0;
+
+ for (i = 0; i < channels; ++i) {
+ if (swizzle[i] < 4) {
+ mask_swizzled |= ((mask & (1 << swizzle[i])) >> swizzle[i]) << i;
+ }
+ }
+
+ return lp_build_const_mask_aos(gallivm, type, mask_swizzled, channels);
+}
+
+
+/**
+ * Build a zero-terminated constant string.
+ */
+LLVMValueRef
+lp_build_const_string(struct gallivm_state *gallivm,
+ const char *str)
+{
+ unsigned len = strlen(str) + 1;
+ LLVMTypeRef i8 = LLVMInt8TypeInContext(gallivm->context);
+ LLVMValueRef string = LLVMAddGlobal(gallivm->module, LLVMArrayType(i8, len), "");
+ LLVMSetGlobalConstant(string, TRUE);
+ LLVMSetLinkage(string, LLVMInternalLinkage);
+ LLVMSetInitializer(string, LLVMConstStringInContext(gallivm->context, str, len, TRUE));
+ string = LLVMConstBitCast(string, LLVMPointerType(i8, 0));
+ return string;
+}
+
+
+/**
+ * Build a callable function pointer.
+ *
+ * We use function pointer constants instead of LLVMAddGlobalMapping()
+ * to work around a bug in LLVM 2.6, and for efficiency/simplicity.
+ */
+LLVMValueRef
+lp_build_const_func_pointer(struct gallivm_state *gallivm,
+ const void *ptr,
+ LLVMTypeRef ret_type,
+ LLVMTypeRef *arg_types,
+ unsigned num_args,
+ const char *name)
+{
+ LLVMTypeRef function_type;
+ LLVMValueRef function;
+
+ function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0);
+
+ function = lp_build_const_int_pointer(gallivm, ptr);
+
+ function = LLVMBuildBitCast(gallivm->builder, function,
+ LLVMPointerType(function_type, 0),
+ name);
+
+ return function;
+}