18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_WORD_AT_A_TIME_H
38c2ecf20Sopenharmony_ci#define _ASM_WORD_AT_A_TIME_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <asm/compiler.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci/*
88c2ecf20Sopenharmony_ci * word-at-a-time interface for Alpha.
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci/*
128c2ecf20Sopenharmony_ci * We do not use the word_at_a_time struct on Alpha, but it needs to be
138c2ecf20Sopenharmony_ci * implemented to humour the generic code.
148c2ecf20Sopenharmony_ci */
158c2ecf20Sopenharmony_cistruct word_at_a_time {
168c2ecf20Sopenharmony_ci	const unsigned long unused;
178c2ecf20Sopenharmony_ci};
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci#define WORD_AT_A_TIME_CONSTANTS { 0 }
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/* Return nonzero if val has a zero */
228c2ecf20Sopenharmony_cistatic inline unsigned long has_zero(unsigned long val, unsigned long *bits, const struct word_at_a_time *c)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci	unsigned long zero_locations = __kernel_cmpbge(0, val);
258c2ecf20Sopenharmony_ci	*bits = zero_locations;
268c2ecf20Sopenharmony_ci	return zero_locations;
278c2ecf20Sopenharmony_ci}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic inline unsigned long prep_zero_mask(unsigned long val, unsigned long bits, const struct word_at_a_time *c)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	return bits;
328c2ecf20Sopenharmony_ci}
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#define create_zero_mask(bits) (bits)
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistatic inline unsigned long find_zero(unsigned long bits)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
398c2ecf20Sopenharmony_ci	/* Simple if have CIX instructions */
408c2ecf20Sopenharmony_ci	return __kernel_cttz(bits);
418c2ecf20Sopenharmony_ci#else
428c2ecf20Sopenharmony_ci	unsigned long t1, t2, t3;
438c2ecf20Sopenharmony_ci	/* Retain lowest set bit only */
448c2ecf20Sopenharmony_ci	bits &= -bits;
458c2ecf20Sopenharmony_ci	/* Binary search for lowest set bit */
468c2ecf20Sopenharmony_ci	t1 = bits & 0xf0;
478c2ecf20Sopenharmony_ci	t2 = bits & 0xcc;
488c2ecf20Sopenharmony_ci	t3 = bits & 0xaa;
498c2ecf20Sopenharmony_ci	if (t1) t1 = 4;
508c2ecf20Sopenharmony_ci	if (t2) t2 = 2;
518c2ecf20Sopenharmony_ci	if (t3) t3 = 1;
528c2ecf20Sopenharmony_ci	return t1 + t2 + t3;
538c2ecf20Sopenharmony_ci#endif
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci#define zero_bytemask(mask) ((2ul << (find_zero(mask) * 8)) - 1)
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci#endif /* _ASM_WORD_AT_A_TIME_H */
59