18cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/**
28cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @file IA64minstate.h
38cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
48cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark Copy of source code from linux kernel
58cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * @remark linux/arch/ia64/kernel/minstate.h
68cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
78cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
88cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
98cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include <linux/config.h>
108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#include "IA64entry.h"
128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * A couple of convenience macros that make writing and reading
158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * SAVE_MIN and SAVE_REST easier.
168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rARPR		r31
188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rCRIFS		r30
198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rCRIPSR		r29
208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rCRIIP		r28
218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rARRSC		r27
228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rARPFS		r26
238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rARUNAT		r25
248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rARRNAT		r24
258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rARBSPSTORE	r23
268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rKRBS		r22
278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rB6		r21
288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define rR1		r20
298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Here start the source dependent macros.
328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * For ivt.s we want to access the stack virtually so we dont have
368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * to disable translation on interrupts.
378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define MINSTATE_START_SAVE_MIN_VIRT					\
398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* r1 = current (virtual) */					\
408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	dep r1=-1, r1, 61, 3;						\
418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov ar.rsc=0;							\
438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* compute base of RBS */					\
458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	addl rKRBS=IA64_RBS_OFFSET, r1;					\
468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov rARRNAT=ar.rnat;						\
478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* get sp  */							\
488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pKern) mov r1=sp;							\
498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* compute base of memory stack */				\
518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE, r1;			\
528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* save ar.bspstore */						\
538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov rARBSPSTORE=ar.bspstore;					\
548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* if in kernel mode, use sp (r12) */				\
568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pKern) addl r1=-IA64_PT_REGS_SIZE, r1;					\
578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* switch to kernel RBS */					\
588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov ar.bspstore=rKRBS;						\
598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov r18=ar.bsp;							\
618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* set eager mode, pl 0, little-endian, loadrs=0 */		\
628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov ar.rsc=0x3;
638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define MINSTATE_END_SAVE_MIN_VIRT					\
658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* make `current' a kernel virtual address */			\
668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	or r13=r13, r14;						\
678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* switch back to bank 1 (must be last in insn group) */	\
688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	bsw.1;								\
698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * For mca_asm.S we want to access the stack physically since the state
738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * is saved before we go virtual and dont want to destroy the iip or ipsr.
748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define MINSTATE_START_SAVE_MIN_PHYS					\
768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pKern) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE;	\
778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov ar.rsc=0;							\
798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* compute base of register backing store */			\
808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	addl rKRBS=IA64_RBS_OFFSET, r1;					\
818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov rARRNAT=ar.rnat;						\
838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* compute physical addr of sp	*/				\
848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pKern) dep r1=0, sp, 61, 3;						\
858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* compute base of memory stack */				\
868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE, r1;			\
878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* save ar.bspstore */						\
888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov rARBSPSTORE=ar.bspstore;					\
898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* compute kernel virtual addr of RBS */			\
908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	dep rKRBS=-1, rKRBS, 61, 3;					\
918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* if in kernel mode, use sp (r12) */				\
938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pKern) addl r1=-IA64_PT_REGS_SIZE, r1;					\
948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* switch to kernel RBS */					\
958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov ar.bspstore=rKRBS;						\
968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov r18=ar.bsp;							\
988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* set eager mode, pl 0, little-endian, loadrs=0 */		\
998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	mov ar.rsc=0x3;
1008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define MINSTATE_END_SAVE_MIN_PHYS					\
1028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* make sp a kernel virtual address */				\
1038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	or r12=r12, r14;						\
1048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* make `current' a kernel virtual address */			\
1058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	or r13=r13, r14;						\
1068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;
1078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifdef MINSTATE_VIRT
1098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd# define MINSTATE_START_SAVE_MIN	MINSTATE_START_SAVE_MIN_VIRT
1108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd# define MINSTATE_END_SAVE_MIN		MINSTATE_END_SAVE_MIN_VIRT
1118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif
1128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#ifdef MINSTATE_PHYS
1148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd# define MINSTATE_START_SAVE_MIN	MINSTATE_START_SAVE_MIN_PHYS
1158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd# define MINSTATE_END_SAVE_MIN		MINSTATE_END_SAVE_MIN_PHYS
1168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#endif
1178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
1188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
1198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
1208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * the minimum state necessary that allows us to turn psr.ic back
1218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * on.
1228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
1238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Assumed state upon entry:
1248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	psr.ic: off
1258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	psr.dt: off
1268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	r31:	contains saved predicates (pr)
1278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
1288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Upon exit, the state is as follows:
1298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	psr.ic: off
1308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	r2 = points to &pt_regs.r16
1318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	r12 = kernel sp (kernel virtual address)
1328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	r13 = points to current task_struct (kernel virtual address)
1338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	p15 = TRUE if psr.i is set in cr.ipsr
1348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	predicate registers (other than p2, p3, and p15), b6, r3, r8, r9,
1358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *		r10, r11, r14, r15: preserved
1368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
1378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Note that psr.ic is NOT turned on by this macro.  This is so that
1388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * we can pass interruption state as arguments to a handler.
1398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
1408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define DO_SAVE_MIN(COVER, SAVE_IFS, EXTRA)				\
1418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov rARRSC=ar.rsc;						\
1428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov rARPFS=ar.pfs;						\
1438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov rR1=r1;							\
1448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov rARUNAT=ar.unat;						\
1458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov rCRIPSR=cr.ipsr;						\
1468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* rB6 = branch reg 6 */			  		\
1478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov rB6=b6;							\
1488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov rCRIIP=cr.iip;						\
1498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* r1 = current (physical) */			  		\
1508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r1=IA64_KR(CURRENT);					\
1518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	COVER;								\
1528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	invala;								\
1548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* extract psr.cpl */				  		\
1558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	extr.u r16=rCRIPSR, 32, 2;					\
1568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* are we in kernel mode already? (psr.cpl==0) */ 		\
1588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cmp.eq pKern, pUser=r0, r16;					\
1598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* switch from user to kernel RBS: */				\
1608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	SAVE_IFS;							\
1628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	MINSTATE_START_SAVE_MIN						\
1638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* initialize first base pointer */	  			\
1658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r16=r1;							\
1668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* initialize second base pointer */	  			\
1678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	adds r17=8, r1;							\
1688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r16]=rCRIPSR, 16;	/* save cr.ipsr */			\
1708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r17]=rCRIIP, 16;	/* save cr.iip */			\
1718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pKern)	mov r18=r0;		/* make sure r18 isn't NaT */		\
1728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r16]=rCRIFS, 16;	/* save cr.ifs */			\
1748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r17]=rARUNAT, 16;	/* save ar.unat */			\
1758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	sub r18=r18, rKRBS;	/* r18=RSE.ndirty*8 */			\
1768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r16]=rARPFS, 16;	/* save ar.pfs */			\
1788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r17]=rARRSC, 16;	/* save ar.rsc */			\
1798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	tbit.nz p15, p0=rCRIPSR, IA64_PSR_I_BIT				\
1808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;			/* avoid RAW on r16 & r17 */		\
1818cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pKern)	adds r16=16, r16;	/* skip over ar_rnat field */		\
1828cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pKern)	adds r17=16, r17;	/* skip over ar_bspstore field */	\
1838cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	st8 [r16]=rARRNAT, 16;	/* save ar.rnat */			\
1848cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd(pUser)	st8 [r17]=rARBSPSTORE, 16;	/* save ar.bspstore */		\
1858cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1868cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r16]=rARPR, 16;	/* save predicates */			\
1878cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r17]=rB6, 16;	/* save b6 */				\
1888cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* compute ar.rsc to be used for "loadrs" */			\
1898cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	shl r18=r18, 16;						\
1908cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1918cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r16]=r18, 16;	/* save ar.rsc value for "loadrs" */	\
1928cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8.spill [r17]=rR1, 16;	/* save original r1 */		\
1938cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1948cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r16]=r2, 16;				\
1958cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r17]=r3, 16;				\
1968cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	adds r2=IA64_PT_REGS_R16_OFFSET, r1;				\
1978cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
1988cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;		st8.spill [r16]=r12, 16;		\
1998cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;		st8.spill [r17]=r13, 16;		\
2008cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* initialize pSys=0, pNonSys=1 */			  	\
2018cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	cmp.eq pNonSys, pSys=r0, r0					\
2028cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
2038cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;		st8.spill [r16]=r14, 16;		\
2048cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;		st8.spill [r17]=r15, 16;		\
2058cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	dep r14=-1, r0, 61, 3;						\
2068cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
2078cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;		st8.spill [r16]=r8, 16;			\
2088cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;		st8.spill [r17]=r9, 16;			\
2098cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	/* switch to kernel memory stack (with 16 bytes of scratch) */	\
2108cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	adds r12=-16, r1;						\
2118cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
2128cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;		st8.spill [r16]=r10, 16;		\
2138cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;		st8.spill [r17]=r11, 16;		\
2148cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r13=IA64_KR(CURRENT);	/* establish `current' */	\
2158cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
2168cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	EXTRA;								\
2178cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	movl r1=__gp;		/* establish kernel global pointer */	\
2188cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;								\
2198cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	MINSTATE_END_SAVE_MIN
2208cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2218cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd/*
2228cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * SAVE_REST saves the remainder of pt_regs (with psr.ic on).  This
2238cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * macro guarantees to preserve all predicate registers, r8, r9, r10,
2248cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * r11, r14, and r15.
2258cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *
2268cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd * Assumed state upon entry:
2278cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	psr.ic: on
2288cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	psr.dt: on
2298cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	r2:	points to &pt_regs.r16
2308cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd *	r3:	points to &pt_regs.r17
2318cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd */
2328cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define SAVE_REST				\
2338cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r2]=r16, 16;	\
2348cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r3]=r17, 16;	\
2358cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2368cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r2]=r18, 16;	\
2378cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r3]=r19, 16;	\
2388cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2398cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r16=ar.ccv;		/* M-unit */	\
2408cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	movl r18=FPSR_DEFAULT	/* L-unit */	\
2418cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2428cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r17=ar.fpsr;	/* M-unit */	\
2438cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov ar.fpsr=r18;	/* M-unit */	\
2448cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2458cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r2]=r20, 16;	\
2468cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r3]=r21, 16;	\
2478cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r18=b0;				\
2488cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2498cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r2]=r22, 16;	\
2508cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r3]=r23, 16;	\
2518cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	mov r19=b7;				\
2528cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2538cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r2]=r24, 16;	\
2548cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r3]=r25, 16;	\
2558cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2568cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r2]=r26, 16;	\
2578cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r3]=r27, 16;	\
2588cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2598cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r2]=r28, 16;	\
2608cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r3]=r29, 16;	\
2618cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2628cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 0, 0;	st8.spill [r2]=r30, 16;	\
2638cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd.mem.offset 8, 0;	st8.spill [r3]=r31, 16;	\
2648cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2658cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r2]=r16, 16;	/* ar.ccv */	\
2668cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r3]=r17, 16;	/* ar.fpsr */	\
2678cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2688cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r2]=r18, 16;	/* b0 */	\
2698cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	st8 [r3]=r19, 16+8;	/* b7 */	\
2708cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2718cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	stf.spill [r2]=f6, 32;			\
2728cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	stf.spill [r3]=f7, 32;			\
2738cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	;;					\
2748cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	stf.spill [r2]=f8, 32;			\
2758cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	stf.spill [r3]=f9, 32
2768cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd
2778cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs,)
2788cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define SAVE_MIN_WITH_COVER_R19	\
2798cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd	DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs, mov r15=r19)
2808cfa702f803c5ef6a2b062a489a1b2cf66b45b5eMike Dodd#define SAVE_MIN		DO_SAVE_MIN(, mov rCRIFS=r0,)
281