18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
28c2ecf20Sopenharmony_ci#ifndef _ASM_IA64_RSE_H
38c2ecf20Sopenharmony_ci#define _ASM_IA64_RSE_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci/*
68c2ecf20Sopenharmony_ci * Copyright (C) 1998, 1999 Hewlett-Packard Co
78c2ecf20Sopenharmony_ci * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
88c2ecf20Sopenharmony_ci *
98c2ecf20Sopenharmony_ci * Register stack engine related helper functions.  This file may be
108c2ecf20Sopenharmony_ci * used in applications, so be careful about the name-space and give
118c2ecf20Sopenharmony_ci * some consideration to non-GNU C compilers (though __inline__ is
128c2ecf20Sopenharmony_ci * fine).
138c2ecf20Sopenharmony_ci */
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic __inline__ unsigned long
168c2ecf20Sopenharmony_ciia64_rse_slot_num (unsigned long *addr)
178c2ecf20Sopenharmony_ci{
188c2ecf20Sopenharmony_ci	return (((unsigned long) addr) >> 3) & 0x3f;
198c2ecf20Sopenharmony_ci}
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_ci/*
228c2ecf20Sopenharmony_ci * Return TRUE if ADDR is the address of an RNAT slot.
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_cistatic __inline__ unsigned long
258c2ecf20Sopenharmony_ciia64_rse_is_rnat_slot (unsigned long *addr)
268c2ecf20Sopenharmony_ci{
278c2ecf20Sopenharmony_ci	return ia64_rse_slot_num(addr) == 0x3f;
288c2ecf20Sopenharmony_ci}
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/*
318c2ecf20Sopenharmony_ci * Returns the address of the RNAT slot that covers the slot at
328c2ecf20Sopenharmony_ci * address SLOT_ADDR.
338c2ecf20Sopenharmony_ci */
348c2ecf20Sopenharmony_cistatic __inline__ unsigned long *
358c2ecf20Sopenharmony_ciia64_rse_rnat_addr (unsigned long *slot_addr)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3));
388c2ecf20Sopenharmony_ci}
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/*
418c2ecf20Sopenharmony_ci * Calculate the number of registers in the dirty partition starting at BSPSTORE and
428c2ecf20Sopenharmony_ci * ending at BSP.  This isn't simply (BSP-BSPSTORE)/8 because every 64th slot stores
438c2ecf20Sopenharmony_ci * ar.rnat.
448c2ecf20Sopenharmony_ci */
458c2ecf20Sopenharmony_cistatic __inline__ unsigned long
468c2ecf20Sopenharmony_ciia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp)
478c2ecf20Sopenharmony_ci{
488c2ecf20Sopenharmony_ci	unsigned long slots = (bsp - bspstore);
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci	return slots - (ia64_rse_slot_num(bspstore) + slots)/0x40;
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/*
548c2ecf20Sopenharmony_ci * The inverse of the above: given bspstore and the number of
558c2ecf20Sopenharmony_ci * registers, calculate ar.bsp.
568c2ecf20Sopenharmony_ci */
578c2ecf20Sopenharmony_cistatic __inline__ unsigned long *
588c2ecf20Sopenharmony_ciia64_rse_skip_regs (unsigned long *addr, long num_regs)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	long delta = ia64_rse_slot_num(addr) + num_regs;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	if (num_regs < 0)
638c2ecf20Sopenharmony_ci		delta -= 0x3e;
648c2ecf20Sopenharmony_ci	return addr + num_regs + delta/0x3f;
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci#endif /* _ASM_IA64_RSE_H */
68