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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
* USE OR OTHER DEALINGS IN THE SOFTWARE.
22
* The above copyright notice and this permission notice (including the
23
* next paragraph) shall be included in all copies or substantial portions
26
**************************************************************************/
29
#include "util/u_debug.h"
31
#include "lp_bld_type.h"
32
#include "lp_bld_debug.h"
33
#include "lp_bld_const.h"
34
#include "lp_bld_bitarit.h"
35
#include "lp_bld_intr.h"
41
lp_build_or(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
43
LLVMBuilderRef builder = bld->gallivm->builder;
44
const struct lp_type type = bld->type;
47
assert(lp_check_value(type, a));
48
assert(lp_check_value(type, b));
50
/* can't do bitwise ops on floating-point values */
52
a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
53
b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
56
res = LLVMBuildOr(builder, a, b, "");
59
res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
65
/* bitwise XOR (a ^ b) */
67
lp_build_xor(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
69
LLVMBuilderRef builder = bld->gallivm->builder;
70
const struct lp_type type = bld->type;
73
assert(lp_check_value(type, a));
74
assert(lp_check_value(type, b));
76
/* can't do bitwise ops on floating-point values */
78
a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
79
b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
82
res = LLVMBuildXor(builder, a, b, "");
85
res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
95
lp_build_and(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
97
LLVMBuilderRef builder = bld->gallivm->builder;
98
const struct lp_type type = bld->type;
101
assert(lp_check_value(type, a));
102
assert(lp_check_value(type, b));
104
/* can't do bitwise ops on floating-point values */
106
a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
107
b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
110
res = LLVMBuildAnd(builder, a, b, "");
113
res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
124
lp_build_andnot(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
126
LLVMBuilderRef builder = bld->gallivm->builder;
127
const struct lp_type type = bld->type;
130
assert(lp_check_value(type, a));
131
assert(lp_check_value(type, b));
133
/* can't do bitwise ops on floating-point values */
135
a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
136
b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
139
res = LLVMBuildNot(builder, b, "");
140
res = LLVMBuildAnd(builder, a, res, "");
143
res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
151
lp_build_not(struct lp_build_context *bld, LLVMValueRef a)
153
LLVMBuilderRef builder = bld->gallivm->builder;
154
const struct lp_type type = bld->type;
157
assert(lp_check_value(type, a));
160
a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
162
res = LLVMBuildNot(builder, a, "");
164
res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
171
* Result is undefined if the shift count is not smaller than the type width.
174
lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
176
LLVMBuilderRef builder = bld->gallivm->builder;
177
const struct lp_type type = bld->type;
180
assert(!type.floating);
182
assert(lp_check_value(type, a));
183
assert(lp_check_value(type, b));
187
res = LLVMBuildShl(builder, a, b, "");
195
* Result is undefined if the shift count is not smaller than the type width.
198
lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
200
LLVMBuilderRef builder = bld->gallivm->builder;
201
const struct lp_type type = bld->type;
204
assert(!type.floating);
206
assert(lp_check_value(type, a));
207
assert(lp_check_value(type, b));
210
res = LLVMBuildAShr(builder, a, b, "");
212
res = LLVMBuildLShr(builder, a, b, "");
220
* Shift left with immediate.
221
* The immediate shift count must be smaller than the type width.
224
lp_build_shl_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
226
LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
227
assert(imm < bld->type.width);
228
return lp_build_shl(bld, a, b);
233
* Shift right with immediate.
234
* The immediate shift count must be smaller than the type width.
237
lp_build_shr_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
239
LLVMValueRef b = lp_build_const_int_vec(bld->gallivm, bld->type, imm);
240
assert(imm < bld->type.width);
241
return lp_build_shr(bld, a, b);
245
lp_build_popcount(struct lp_build_context *bld, LLVMValueRef a)
247
LLVMBuilderRef builder = bld->gallivm->builder;
251
lp_format_intrinsic(intr_str, sizeof(intr_str), "llvm.ctpop", bld->vec_type);
252
result = lp_build_intrinsic_unary(builder, intr_str, bld->vec_type, a);
257
lp_build_bitfield_reverse(struct lp_build_context *bld, LLVMValueRef a)
259
LLVMBuilderRef builder = bld->gallivm->builder;
263
lp_format_intrinsic(intr_str, sizeof(intr_str), "llvm.bitreverse", bld->vec_type);
264
result = lp_build_intrinsic_unary(builder, intr_str, bld->vec_type, a);
269
lp_build_cttz(struct lp_build_context *bld, LLVMValueRef a)
271
LLVMBuilderRef builder = bld->gallivm->builder;
275
lp_format_intrinsic(intr_str, sizeof(intr_str), "llvm.cttz", bld->vec_type);
277
LLVMValueRef undef_val = LLVMConstNull(LLVMInt1TypeInContext(bld->gallivm->context));
278
result = lp_build_intrinsic_binary(builder, intr_str, bld->vec_type, a, undef_val);
279
return LLVMBuildSelect(builder, LLVMBuildICmp(builder, LLVMIntEQ, a, bld->zero, ""),
280
lp_build_const_int_vec(bld->gallivm, bld->type, -1), result, "");
284
lp_build_ctlz(struct lp_build_context *bld, LLVMValueRef a)
286
LLVMBuilderRef builder = bld->gallivm->builder;
290
lp_format_intrinsic(intr_str, sizeof(intr_str), "llvm.ctlz", bld->vec_type);
292
LLVMValueRef undef_val = LLVMConstNull(LLVMInt1TypeInContext(bld->gallivm->context));
293
result = lp_build_intrinsic_binary(builder, intr_str, bld->vec_type, a, undef_val);