Skip to content

Commit 160509b

Browse files
authored
[SYCL][COMPAT] Add helper function ternary_logic_op() to perform bitwise logical operations on three input values based on the specified 8-bit truth table (#16509)
Signed-off-by: chenwei.sun <chenwei.sun@intel.com> --------- Signed-off-by: chenwei.sun <chenwei.sun@intel.com>
1 parent 1537ca2 commit 160509b

File tree

3 files changed

+695
-0
lines changed

3 files changed

+695
-0
lines changed

sycl/doc/syclcompat/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,10 @@ with bytes selected according to a third unsigned integer argument.
13891389
`match_all_over_sub_group` and `match_any_over_sub_group` allows comparison of
13901390
values across work-items within a sub-group.
13911391

1392+
The function `ternary_logic_op`performs bitwise logical operations on three input values of
1393+
`a`, `b` and `c` based on the specified 8-bit truth table `lut` and return the
1394+
result.
1395+
13921396
The functions `select_from_sub_group`, `shift_sub_group_left`,
13931397
`shift_sub_group_right` and `permute_sub_group_by_xor` provide equivalent
13941398
functionality to `sycl::select_from_group`, `sycl::shift_group_left`,
@@ -1419,6 +1423,8 @@ inline double cast_ints_to_double(int high32, int low32);
14191423
inline unsigned int byte_level_permute(unsigned int a, unsigned int b,
14201424
unsigned int s);
14211425
1426+
inline uint32_t lop3(uint32_t a, uint32_t b, uint32_t c, uint8_t lut)
1427+
14221428
template <typename ValueT> inline int ffs(ValueT a);
14231429
14241430
template <typename T>

sycl/include/syclcompat/util.hpp

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,110 @@ inline unsigned int byte_level_permute(unsigned int a, unsigned int b,
199199
return ret;
200200
}
201201

202+
/// \brief The function performs bitwise logical operations on three input
203+
/// values of \p a, \p b and \p c based on the specified 8-bit truth table \p
204+
/// lut and return the result
205+
///
206+
/// \param [in] a Input value
207+
/// \param [in] b Input value
208+
/// \param [in] c Input value
209+
/// \param [in] lut truth table for looking up
210+
/// \returns The result
211+
inline uint32_t ternary_logic_op(uint32_t a, uint32_t b, uint32_t c,
212+
uint8_t lut) {
213+
uint32_t result = 0;
214+
#if defined(__SYCL_DEVICE_ONLY__) && defined(__NVPTX__)
215+
asm volatile("lop3.b32 %0, %1, %2, %3, %4;"
216+
: "=r"(result)
217+
: "r"(a), "r"(b), "r"(c), "n"(lut));
218+
#else
219+
switch (lut) {
220+
case 0x0:
221+
result = 0;
222+
break;
223+
case 0x1:
224+
result = ~a & ~b & ~c;
225+
break;
226+
case 0x2:
227+
result = ~a & ~b & c;
228+
case 0x4:
229+
result = ~a & b & ~c;
230+
break;
231+
case 0x8:
232+
result = ~a & b & c;
233+
break;
234+
case 0x10:
235+
result = a & ~b & ~c;
236+
break;
237+
case 0x20:
238+
result = a & ~b & c;
239+
break;
240+
case 0x40:
241+
result = a & b & ~c;
242+
break;
243+
case 0x80:
244+
result = a & b & c;
245+
break;
246+
case 0x1a:
247+
result = (a & b | c) ^ a;
248+
break;
249+
case 0x1e:
250+
result = a ^ (b | c);
251+
break;
252+
case 0x2d:
253+
result = ~a ^ (~b & c);
254+
break;
255+
case 0x78:
256+
result = a ^ (b & c);
257+
break;
258+
case 0x96:
259+
result = a ^ b ^ c;
260+
break;
261+
case 0xb4:
262+
result = a ^ (b & ~c);
263+
break;
264+
case 0xb8:
265+
result = a ^ (b & (c ^ a));
266+
break;
267+
case 0xd2:
268+
result = a ^ (~b & c);
269+
break;
270+
case 0xe8:
271+
result = a & (b | c) | (b & c);
272+
break;
273+
case 0xea:
274+
result = a & b | c;
275+
break;
276+
case 0xfe:
277+
result = a | b | c;
278+
break;
279+
case 0xff:
280+
result = -1;
281+
break;
282+
default: {
283+
if (lut & 0x01)
284+
result |= ~a & ~b & ~c;
285+
if (lut & 0x02)
286+
result |= ~a & ~b & c;
287+
if (lut & 0x04)
288+
result |= ~a & b & ~c;
289+
if (lut & 0x08)
290+
result |= ~a & b & c;
291+
if (lut & 0x10)
292+
result |= a & ~b & ~c;
293+
if (lut & 0x20)
294+
result |= a & ~b & c;
295+
if (lut & 0x40)
296+
result |= a & b & ~c;
297+
if (lut & 0x80)
298+
result |= a & b & c;
299+
break;
300+
}
301+
}
302+
#endif // defined(__SYCL_DEVICE_ONLY__) && defined(__NVPTX__)
303+
return result;
304+
}
305+
202306
/// Find position of first least significant set bit in an integer.
203307
/// ffs(0) returns 0.
204308
///

0 commit comments

Comments
 (0)