~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/auxiliary/gallivm/lp_bld_bitarit.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 *
3
 
 * Copyright 2010 VMware, Inc.
4
 
 * All Rights Reserved.
5
 
 *
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:
13
 
 *
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.
21
 
 *
22
 
 * The above copyright notice and this permission notice (including the
23
 
 * next paragraph) shall be included in all copies or substantial portions
24
 
 * of the Software.
25
 
 *
26
 
 **************************************************************************/
27
 
 
28
 
 
29
 
#include "util/u_debug.h"
30
 
 
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"
36
 
 
37
 
/**
38
 
 * Return (a | b)
39
 
 */
40
 
LLVMValueRef
41
 
lp_build_or(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
42
 
{
43
 
   LLVMBuilderRef builder = bld->gallivm->builder;
44
 
   const struct lp_type type = bld->type;
45
 
   LLVMValueRef res;
46
 
 
47
 
   assert(lp_check_value(type, a));
48
 
   assert(lp_check_value(type, b));
49
 
 
50
 
   /* can't do bitwise ops on floating-point values */
51
 
   if (type.floating) {
52
 
      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
53
 
      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
54
 
   }
55
 
 
56
 
   res = LLVMBuildOr(builder, a, b, "");
57
 
 
58
 
   if (type.floating) {
59
 
      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
60
 
   }
61
 
 
62
 
   return res;
63
 
}
64
 
 
65
 
/* bitwise XOR (a ^ b) */
66
 
LLVMValueRef
67
 
lp_build_xor(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
68
 
{
69
 
   LLVMBuilderRef builder = bld->gallivm->builder;
70
 
   const struct lp_type type = bld->type;
71
 
   LLVMValueRef res;
72
 
 
73
 
   assert(lp_check_value(type, a));
74
 
   assert(lp_check_value(type, b));
75
 
 
76
 
   /* can't do bitwise ops on floating-point values */
77
 
   if (type.floating) {
78
 
      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
79
 
      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
80
 
   }
81
 
 
82
 
   res = LLVMBuildXor(builder, a, b, "");
83
 
 
84
 
   if (type.floating) {
85
 
      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
86
 
   }
87
 
 
88
 
   return res;
89
 
}
90
 
 
91
 
/**
92
 
 * Return (a & b)
93
 
 */
94
 
LLVMValueRef
95
 
lp_build_and(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
96
 
{
97
 
   LLVMBuilderRef builder = bld->gallivm->builder;
98
 
   const struct lp_type type = bld->type;
99
 
   LLVMValueRef res;
100
 
 
101
 
   assert(lp_check_value(type, a));
102
 
   assert(lp_check_value(type, b));
103
 
 
104
 
   /* can't do bitwise ops on floating-point values */
105
 
   if (type.floating) {
106
 
      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
107
 
      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
108
 
   }
109
 
 
110
 
   res = LLVMBuildAnd(builder, a, b, "");
111
 
 
112
 
   if (type.floating) {
113
 
      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
114
 
   }
115
 
 
116
 
   return res;
117
 
}
118
 
 
119
 
 
120
 
/**
121
 
 * Return (a & ~b)
122
 
 */
123
 
LLVMValueRef
124
 
lp_build_andnot(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
125
 
{
126
 
   LLVMBuilderRef builder = bld->gallivm->builder;
127
 
   const struct lp_type type = bld->type;
128
 
   LLVMValueRef res;
129
 
 
130
 
   assert(lp_check_value(type, a));
131
 
   assert(lp_check_value(type, b));
132
 
 
133
 
   /* can't do bitwise ops on floating-point values */
134
 
   if (type.floating) {
135
 
      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
136
 
      b = LLVMBuildBitCast(builder, b, bld->int_vec_type, "");
137
 
   }
138
 
 
139
 
   res = LLVMBuildNot(builder, b, "");
140
 
   res = LLVMBuildAnd(builder, a, res, "");
141
 
 
142
 
   if (type.floating) {
143
 
      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
144
 
   }
145
 
 
146
 
   return res;
147
 
}
148
 
 
149
 
/* bitwise NOT */
150
 
LLVMValueRef
151
 
lp_build_not(struct lp_build_context *bld, LLVMValueRef a)
152
 
{
153
 
   LLVMBuilderRef builder = bld->gallivm->builder;
154
 
   const struct lp_type type = bld->type;
155
 
   LLVMValueRef res;
156
 
 
157
 
   assert(lp_check_value(type, a));
158
 
 
159
 
   if (type.floating) {
160
 
      a = LLVMBuildBitCast(builder, a, bld->int_vec_type, "");
161
 
   }
162
 
   res = LLVMBuildNot(builder, a, "");
163
 
   if (type.floating) {
164
 
      res = LLVMBuildBitCast(builder, res, bld->vec_type, "");
165
 
   }
166
 
   return res;
167
 
}
168
 
 
169
 
/**
170
 
 * Shift left.
171
 
 * Result is undefined if the shift count is not smaller than the type width.
172
 
 */
173
 
LLVMValueRef
174
 
lp_build_shl(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
175
 
{
176
 
   LLVMBuilderRef builder = bld->gallivm->builder;
177
 
   const struct lp_type type = bld->type;
178
 
   LLVMValueRef res;
179
 
 
180
 
   assert(!type.floating);
181
 
 
182
 
   assert(lp_check_value(type, a));
183
 
   assert(lp_check_value(type, b));
184
 
 
185
 
   (void)type;
186
 
 
187
 
   res = LLVMBuildShl(builder, a, b, "");
188
 
 
189
 
   return res;
190
 
}
191
 
 
192
 
 
193
 
/**
194
 
 * Shift right.
195
 
 * Result is undefined if the shift count is not smaller than the type width.
196
 
 */
197
 
LLVMValueRef
198
 
lp_build_shr(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b)
199
 
{
200
 
   LLVMBuilderRef builder = bld->gallivm->builder;
201
 
   const struct lp_type type = bld->type;
202
 
   LLVMValueRef res;
203
 
 
204
 
   assert(!type.floating);
205
 
 
206
 
   assert(lp_check_value(type, a));
207
 
   assert(lp_check_value(type, b));
208
 
 
209
 
   if (type.sign) {
210
 
      res = LLVMBuildAShr(builder, a, b, "");
211
 
   } else {
212
 
      res = LLVMBuildLShr(builder, a, b, "");
213
 
   }
214
 
 
215
 
   return res;
216
 
}
217
 
 
218
 
 
219
 
/**
220
 
 * Shift left with immediate.
221
 
 * The immediate shift count must be smaller than the type width.
222
 
 */
223
 
LLVMValueRef
224
 
lp_build_shl_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
225
 
{
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);
229
 
}
230
 
 
231
 
 
232
 
/**
233
 
 * Shift right with immediate.
234
 
 * The immediate shift count must be smaller than the type width.
235
 
 */
236
 
LLVMValueRef
237
 
lp_build_shr_imm(struct lp_build_context *bld, LLVMValueRef a, unsigned imm)
238
 
{
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);
242
 
}
243
 
 
244
 
LLVMValueRef
245
 
lp_build_popcount(struct lp_build_context *bld, LLVMValueRef a)
246
 
{
247
 
   LLVMBuilderRef builder = bld->gallivm->builder;
248
 
   LLVMValueRef result;
249
 
   char intr_str[256];
250
 
 
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);
253
 
   return result;
254
 
}
255
 
 
256
 
LLVMValueRef
257
 
lp_build_bitfield_reverse(struct lp_build_context *bld, LLVMValueRef a)
258
 
{
259
 
   LLVMBuilderRef builder = bld->gallivm->builder;
260
 
   LLVMValueRef result;
261
 
   char intr_str[256];
262
 
 
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);
265
 
   return result;
266
 
}
267
 
 
268
 
LLVMValueRef
269
 
lp_build_cttz(struct lp_build_context *bld, LLVMValueRef a)
270
 
{
271
 
   LLVMBuilderRef builder = bld->gallivm->builder;
272
 
   LLVMValueRef result;
273
 
   char intr_str[256];
274
 
 
275
 
   lp_format_intrinsic(intr_str, sizeof(intr_str), "llvm.cttz", bld->vec_type);
276
 
 
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, "");
281
 
}
282
 
 
283
 
LLVMValueRef
284
 
lp_build_ctlz(struct lp_build_context *bld, LLVMValueRef a)
285
 
{
286
 
   LLVMBuilderRef builder = bld->gallivm->builder;
287
 
   LLVMValueRef result;
288
 
   char intr_str[256];
289
 
 
290
 
   lp_format_intrinsic(intr_str, sizeof(intr_str), "llvm.ctlz", bld->vec_type);
291
 
 
292
 
   LLVMValueRef undef_val = LLVMConstNull(LLVMInt1TypeInContext(bld->gallivm->context));
293
 
   result = lp_build_intrinsic_binary(builder, intr_str, bld->vec_type, a, undef_val);
294
 
   return result;
295
 
}