1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2*4882a593Smuzhiyun #ifndef _ASM_IA64_RSE_H 3*4882a593Smuzhiyun #define _ASM_IA64_RSE_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun /* 6*4882a593Smuzhiyun * Copyright (C) 1998, 1999 Hewlett-Packard Co 7*4882a593Smuzhiyun * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com> 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * Register stack engine related helper functions. This file may be 10*4882a593Smuzhiyun * used in applications, so be careful about the name-space and give 11*4882a593Smuzhiyun * some consideration to non-GNU C compilers (though __inline__ is 12*4882a593Smuzhiyun * fine). 13*4882a593Smuzhiyun */ 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun static __inline__ unsigned long ia64_rse_slot_num(unsigned long * addr)16*4882a593Smuzhiyunia64_rse_slot_num (unsigned long *addr) 17*4882a593Smuzhiyun { 18*4882a593Smuzhiyun return (((unsigned long) addr) >> 3) & 0x3f; 19*4882a593Smuzhiyun } 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun /* 22*4882a593Smuzhiyun * Return TRUE if ADDR is the address of an RNAT slot. 23*4882a593Smuzhiyun */ 24*4882a593Smuzhiyun static __inline__ unsigned long ia64_rse_is_rnat_slot(unsigned long * addr)25*4882a593Smuzhiyunia64_rse_is_rnat_slot (unsigned long *addr) 26*4882a593Smuzhiyun { 27*4882a593Smuzhiyun return ia64_rse_slot_num(addr) == 0x3f; 28*4882a593Smuzhiyun } 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun /* 31*4882a593Smuzhiyun * Returns the address of the RNAT slot that covers the slot at 32*4882a593Smuzhiyun * address SLOT_ADDR. 33*4882a593Smuzhiyun */ 34*4882a593Smuzhiyun static __inline__ unsigned long * ia64_rse_rnat_addr(unsigned long * slot_addr)35*4882a593Smuzhiyunia64_rse_rnat_addr (unsigned long *slot_addr) 36*4882a593Smuzhiyun { 37*4882a593Smuzhiyun return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3)); 38*4882a593Smuzhiyun } 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun /* 41*4882a593Smuzhiyun * Calculate the number of registers in the dirty partition starting at BSPSTORE and 42*4882a593Smuzhiyun * ending at BSP. This isn't simply (BSP-BSPSTORE)/8 because every 64th slot stores 43*4882a593Smuzhiyun * ar.rnat. 44*4882a593Smuzhiyun */ 45*4882a593Smuzhiyun static __inline__ unsigned long ia64_rse_num_regs(unsigned long * bspstore,unsigned long * bsp)46*4882a593Smuzhiyunia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp) 47*4882a593Smuzhiyun { 48*4882a593Smuzhiyun unsigned long slots = (bsp - bspstore); 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun return slots - (ia64_rse_slot_num(bspstore) + slots)/0x40; 51*4882a593Smuzhiyun } 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun /* 54*4882a593Smuzhiyun * The inverse of the above: given bspstore and the number of 55*4882a593Smuzhiyun * registers, calculate ar.bsp. 56*4882a593Smuzhiyun */ 57*4882a593Smuzhiyun static __inline__ unsigned long * ia64_rse_skip_regs(unsigned long * addr,long num_regs)58*4882a593Smuzhiyunia64_rse_skip_regs (unsigned long *addr, long num_regs) 59*4882a593Smuzhiyun { 60*4882a593Smuzhiyun long delta = ia64_rse_slot_num(addr) + num_regs; 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun if (num_regs < 0) 63*4882a593Smuzhiyun delta -= 0x3e; 64*4882a593Smuzhiyun return addr + num_regs + delta/0x3f; 65*4882a593Smuzhiyun } 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun #endif /* _ASM_IA64_RSE_H */ 68