xref: /minix3/common/lib/libc/arch/sparc64/string/strmacros.h (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /*	$NetBSD: strmacros.h,v 1.1 2013/03/17 00:42:32 christos Exp $	*/
2*84d9c625SLionel Sambuc 
3*84d9c625SLionel Sambuc /*
4*84d9c625SLionel Sambuc  * Copyright (c) 1996-2002 Eduardo Horvath
5*84d9c625SLionel Sambuc  * All rights reserved.
6*84d9c625SLionel Sambuc  *
7*84d9c625SLionel Sambuc  * Redistribution and use in source and binary forms, with or without
8*84d9c625SLionel Sambuc  * modification, are permitted provided that the following conditions
9*84d9c625SLionel Sambuc  * are met:
10*84d9c625SLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
11*84d9c625SLionel Sambuc  *notice, this list of conditions and the following disclaimer.
12*84d9c625SLionel Sambuc  *
13*84d9c625SLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR  ``AS IS'' AND
14*84d9c625SLionel Sambuc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15*84d9c625SLionel Sambuc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16*84d9c625SLionel Sambuc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR  BE LIABLE
17*84d9c625SLionel Sambuc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18*84d9c625SLionel Sambuc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19*84d9c625SLionel Sambuc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20*84d9c625SLionel Sambuc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21*84d9c625SLionel Sambuc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22*84d9c625SLionel Sambuc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23*84d9c625SLionel Sambuc  * SUCH DAMAGE.
24*84d9c625SLionel Sambuc  *
25*84d9c625SLionel Sambuc  */
26*84d9c625SLionel Sambuc 
27*84d9c625SLionel Sambuc #include <machine/asm.h>
28*84d9c625SLionel Sambuc #if defined(_KERNEL) && !defined(_RUMPKERNEL)
29*84d9c625SLionel Sambuc #define USE_BLOCK_STORE_LOAD	/* enable block load/store ops */
30*84d9c625SLionel Sambuc #include "assym.h"
31*84d9c625SLionel Sambuc #include <machine/param.h>
32*84d9c625SLionel Sambuc #include <machine/ctlreg.h>
33*84d9c625SLionel Sambuc #include <machine/psl.h>
34*84d9c625SLionel Sambuc #include <machine/frame.h>
35*84d9c625SLionel Sambuc #include <machine/intr.h>
36*84d9c625SLionel Sambuc #include <machine/locore.h>
37*84d9c625SLionel Sambuc 
38*84d9c625SLionel Sambuc #ifdef USE_BLOCK_STORE_LOAD
39*84d9c625SLionel Sambuc 
40*84d9c625SLionel Sambuc #define BLOCK_SIZE SPARC64_BLOCK_SIZE
41*84d9c625SLionel Sambuc #define BLOCK_ALIGN SPARC64_BLOCK_ALIGN
42*84d9c625SLionel Sambuc 
43*84d9c625SLionel Sambuc /*
44*84d9c625SLionel Sambuc  * The following routines allow fpu use in the kernel.
45*84d9c625SLionel Sambuc  *
46*84d9c625SLionel Sambuc  * They allocate a stack frame and use all local regs.	Extra
47*84d9c625SLionel Sambuc  * local storage can be requested by setting the siz parameter,
48*84d9c625SLionel Sambuc  * and can be accessed at %sp+CC64FSZ.
49*84d9c625SLionel Sambuc  */
50*84d9c625SLionel Sambuc 
51*84d9c625SLionel Sambuc #define ENABLE_FPU(siz)							\
52*84d9c625SLionel Sambuc 	save	%sp, -(CC64FSZ), %sp;	/* Allocate a stack frame */	\
53*84d9c625SLionel Sambuc 	sethi	%hi(FPLWP), %l1;					\
54*84d9c625SLionel Sambuc 	add	%fp, STKB-FS_SIZE, %l0;		/* Allocate a fpstate */\
55*84d9c625SLionel Sambuc 	LDPTR	[%l1 + %lo(FPLWP)], %l2;	/* Load fplwp */	\
56*84d9c625SLionel Sambuc 	andn	%l0, BLOCK_ALIGN, %l0;		/* Align it */		\
57*84d9c625SLionel Sambuc 	clr	%l3;				/* NULL fpstate */	\
58*84d9c625SLionel Sambuc 	brz,pt	%l2, 1f;			/* fplwp == NULL? */	\
59*84d9c625SLionel Sambuc 	 add	%l0, -STKB-CC64FSZ-(siz), %sp;	/* Set proper %sp */	\
60*84d9c625SLionel Sambuc 	LDPTR	[%l2 + L_FPSTATE], %l3;					\
61*84d9c625SLionel Sambuc 	brz,pn	%l3, 1f;	/* Make sure we have an fpstate */	\
62*84d9c625SLionel Sambuc 	 mov	%l3, %o0;						\
63*84d9c625SLionel Sambuc 	call	_C_LABEL(savefpstate);	/* Save the old fpstate */	\
64*84d9c625SLionel Sambuc 1:									\
65*84d9c625SLionel Sambuc 	 set	EINTSTACK-STKB, %l4;	/* Are we on intr stack? */	\
66*84d9c625SLionel Sambuc 	cmp	%sp, %l4;						\
67*84d9c625SLionel Sambuc 	bgu,pt	%xcc, 1f;						\
68*84d9c625SLionel Sambuc 	 set	INTSTACK-STKB, %l4;					\
69*84d9c625SLionel Sambuc 	cmp	%sp, %l4;						\
70*84d9c625SLionel Sambuc 	blu	%xcc, 1f;						\
71*84d9c625SLionel Sambuc 0:									\
72*84d9c625SLionel Sambuc 	 sethi	%hi(_C_LABEL(lwp0)), %l4;	/* Yes, use lpw0 */	\
73*84d9c625SLionel Sambuc 	ba,pt	%xcc, 2f; /* XXXX needs to change to CPUs idle proc */	\
74*84d9c625SLionel Sambuc 	 or	%l4, %lo(_C_LABEL(lwp0)), %l5;				\
75*84d9c625SLionel Sambuc 1:									\
76*84d9c625SLionel Sambuc 	sethi	%hi(CURLWP), %l4;		/* Use curlwp */	\
77*84d9c625SLionel Sambuc 	LDPTR	[%l4 + %lo(CURLWP)], %l5;				\
78*84d9c625SLionel Sambuc 	brz,pn	%l5, 0b; nop;	/* If curlwp is NULL need to use lwp0 */\
79*84d9c625SLionel Sambuc 2:									\
80*84d9c625SLionel Sambuc 	LDPTR	[%l5 + L_FPSTATE], %l6;		/* Save old fpstate */	\
81*84d9c625SLionel Sambuc 	STPTR	%l0, [%l5 + L_FPSTATE];		/* Insert new fpstate */\
82*84d9c625SLionel Sambuc 	STPTR	%l5, [%l1 + %lo(FPLWP)];	/* Set new fplwp */	\
83*84d9c625SLionel Sambuc 	wr	%g0, FPRS_FEF, %fprs		/* Enable FPU */
84*84d9c625SLionel Sambuc 
85*84d9c625SLionel Sambuc /*
86*84d9c625SLionel Sambuc  * Weve saved our possible fpstate, now disable the fpu
87*84d9c625SLionel Sambuc  * and continue with life.
88*84d9c625SLionel Sambuc  */
89*84d9c625SLionel Sambuc #ifdef DEBUG
90*84d9c625SLionel Sambuc #define __CHECK_FPU				\
91*84d9c625SLionel Sambuc 	LDPTR	[%l5 + L_FPSTATE], %l7;		\
92*84d9c625SLionel Sambuc 	cmp	%l7, %l0;			\
93*84d9c625SLionel Sambuc 	tnz	1;
94*84d9c625SLionel Sambuc #else
95*84d9c625SLionel Sambuc #define __CHECK_FPU
96*84d9c625SLionel Sambuc #endif
97*84d9c625SLionel Sambuc 
98*84d9c625SLionel Sambuc #define RESTORE_FPU							 \
99*84d9c625SLionel Sambuc 	__CHECK_FPU							 \
100*84d9c625SLionel Sambuc 	STPTR	%l2, [%l1 + %lo(FPLWP)];	/* Restore old fproc */	 \
101*84d9c625SLionel Sambuc 	wr	%g0, 0, %fprs;			/* Disable fpu */	 \
102*84d9c625SLionel Sambuc 	brz,pt	%l3, 1f;			/* Skip if no fpstate */ \
103*84d9c625SLionel Sambuc 	 STPTR	%l6, [%l5 + L_FPSTATE];		/* Restore old fpstate */\
104*84d9c625SLionel Sambuc 									 \
105*84d9c625SLionel Sambuc 	mov	%l3, %o0;						 \
106*84d9c625SLionel Sambuc 	call	_C_LABEL(loadfpstate);		/* Reload orig fpstate */\
107*84d9c625SLionel Sambuc 1: 									 \
108*84d9c625SLionel Sambuc 	 membar #Sync;				/* Finish all FP ops */
109*84d9c625SLionel Sambuc 
110*84d9c625SLionel Sambuc #endif	/* USE_BLOCK_STORE_LOAD */
111*84d9c625SLionel Sambuc 
112*84d9c625SLionel Sambuc #ifdef USE_BLOCK_STORE_LOAD
113*84d9c625SLionel Sambuc #if 0
114*84d9c625SLionel Sambuc #define ASI_STORE	ASI_BLK_COMMIT_P
115*84d9c625SLionel Sambuc #else
116*84d9c625SLionel Sambuc #define ASI_STORE	ASI_BLK_P
117*84d9c625SLionel Sambuc #endif
118*84d9c625SLionel Sambuc #endif	/* USE_BLOCK_STORE_LOAD */
119*84d9c625SLionel Sambuc #endif /* _KERNEL && !_RUMPKERNEL */
120