1/*
2 * Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
3 * Copyright (C) 1999 Philipp Rumpf <prumpf@tux.org>
4 * Copyright (C) 1999 SuSE GmbH
5 *
6 *    This program is free software; you can redistribute it and/or modify
7 *    it under the terms of the GNU General Public License as published by
8 *    the Free Software Foundation; either version 2, or (at your option)
9 *    any later version.
10 *
11 *    This program is distributed in the hope that it will be useful,
12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *    GNU General Public License for more details.
15 *
16 *    You should have received a copy of the GNU General Public License
17 *    along with this program; if not, write to the Free Software
18 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _PARISC_ASSEMBLY_H
22#define _PARISC_ASSEMBLY_H
23
24#if defined(__LP64__) && defined(__ASSEMBLY__)
25/* the 64-bit pa gnu assembler unfortunately defaults to .level 1.1 or 2.0 so
26 * work around that for now... */
27	.level 2.0w
28#endif
29
30#include <asm/offset.h>
31#include <asm/page.h>
32
33#include <asm/asmregs.h>
34
35	sp	=	30
36	gp	=	27
37	ipsw	=	22
38
39	/*
40	 * We provide two versions of each macro to convert from physical
41	 * to virtual and vice versa. The "_r1" versions take one argument
42	 * register, but trashes r1 to do the conversion. The other
43	 * version takes two arguments: a src and destination register.
44	 * However, the source and destination registers can not be
45	 * the same register.
46	 */
47
48	.macro  tophys  grvirt, grphys
49	ldil    L%(__PAGE_OFFSET), \grphys
50	sub     \grvirt, \grphys, \grphys
51	.endm
52
53	.macro  tovirt  grphys, grvirt
54	ldil    L%(__PAGE_OFFSET), \grvirt
55	add     \grphys, \grvirt, \grvirt
56	.endm
57
58	.macro  tophys_r1  gr
59	ldil    L%(__PAGE_OFFSET), %r1
60	sub     \gr, %r1, \gr
61	.endm
62
63	.macro  tovirt_r1  gr
64	ldil    L%(__PAGE_OFFSET), %r1
65	add     \gr, %r1, \gr
66	.endm
67
68	.macro delay value
69	ldil	L%\value, 1
70	ldo	R%\value(1), 1
71	addib,UV,n -1,1,.
72	addib,NUV,n -1,1,.+8
73	nop
74	.endm
75
76	.macro	debug value
77	.endm
78
79
80	/* Shift Left - note the r and t can NOT be the same! */
81	.macro shl r, sa, t
82	dep,z	\r, 31-\sa, 32-\sa, \t
83	.endm
84
85	/* The PA 2.0 shift left */
86	.macro shlw r, sa, t
87	depw,z	\r, 31-\sa, 32-\sa, \t
88	.endm
89
90	/* And the PA 2.0W shift left */
91	.macro shld r, sa, t
92	depd,z	\r, 63-\sa, 64-\sa, \t
93	.endm
94
95	/* load 32-bit 'value' into 'reg' compensating for the ldil
96	 * sign-extension when running in wide mode.
97	 * WARNING!! neither 'value' nor 'reg' can be expressions
98	 * containing '.'!!!! */
99	.macro	load32 value, reg
100	ldil	L%\value, \reg
101	ldo	R%\value(\reg), \reg
102	.endm
103
104#ifdef __LP64__
105#define LDREG   ldd
106#define STREG   std
107#define RP_OFFSET	16
108#else
109#define LDREG   ldw
110#define STREG   stw
111#define RP_OFFSET	20
112#endif
113
114	.macro loadgp
115#ifdef __LP64__
116	ldil		L%__gp, %r27
117	ldo		R%__gp(%r27), %r27
118#else
119	ldil		L%$global$, %r27
120	ldo		R%$global$(%r27), %r27
121#endif
122	.endm
123
124#define SAVE_SP(r, where) mfsp r, %r1 ! STREG %r1, where
125#define REST_SP(r, where) LDREG where, %r1 ! mtsp %r1, r
126#define SAVE_CR(r, where) mfctl r, %r1 ! STREG %r1, where
127#define REST_CR(r, where) LDREG where, %r1 ! mtctl %r1, r
128
129	.macro	save_general	regs
130	STREG %r1, PT_GR1 (\regs)
131	STREG %r2, PT_GR2 (\regs)
132	STREG %r3, PT_GR3 (\regs)
133	STREG %r4, PT_GR4 (\regs)
134	STREG %r5, PT_GR5 (\regs)
135	STREG %r6, PT_GR6 (\regs)
136	STREG %r7, PT_GR7 (\regs)
137	STREG %r8, PT_GR8 (\regs)
138	STREG %r9, PT_GR9 (\regs)
139	STREG %r10, PT_GR10(\regs)
140	STREG %r11, PT_GR11(\regs)
141	STREG %r12, PT_GR12(\regs)
142	STREG %r13, PT_GR13(\regs)
143	STREG %r14, PT_GR14(\regs)
144	STREG %r15, PT_GR15(\regs)
145	STREG %r16, PT_GR16(\regs)
146	STREG %r17, PT_GR17(\regs)
147	STREG %r18, PT_GR18(\regs)
148	STREG %r19, PT_GR19(\regs)
149	STREG %r20, PT_GR20(\regs)
150	STREG %r21, PT_GR21(\regs)
151	STREG %r22, PT_GR22(\regs)
152	STREG %r23, PT_GR23(\regs)
153	STREG %r24, PT_GR24(\regs)
154	STREG %r25, PT_GR25(\regs)
155	/* r26 is saved in get_stack and used to preserve a value across virt_map */
156	STREG %r27, PT_GR27(\regs)
157	STREG %r28, PT_GR28(\regs)
158	/* r29 is saved in get_stack and used to point to saved registers */
159	/* r30 stack pointer saved in get_stack */
160	STREG %r31, PT_GR31(\regs)
161	.endm
162
163	.macro	rest_general	regs
164	/* r1 used as a temp in rest_stack and is restored there */
165	LDREG PT_GR2 (\regs), %r2
166	LDREG PT_GR3 (\regs), %r3
167	LDREG PT_GR4 (\regs), %r4
168	LDREG PT_GR5 (\regs), %r5
169	LDREG PT_GR6 (\regs), %r6
170	LDREG PT_GR7 (\regs), %r7
171	LDREG PT_GR8 (\regs), %r8
172	LDREG PT_GR9 (\regs), %r9
173	LDREG PT_GR10(\regs), %r10
174	LDREG PT_GR11(\regs), %r11
175	LDREG PT_GR12(\regs), %r12
176	LDREG PT_GR13(\regs), %r13
177	LDREG PT_GR14(\regs), %r14
178	LDREG PT_GR15(\regs), %r15
179	LDREG PT_GR16(\regs), %r16
180	LDREG PT_GR17(\regs), %r17
181	LDREG PT_GR18(\regs), %r18
182	LDREG PT_GR19(\regs), %r19
183	LDREG PT_GR20(\regs), %r20
184	LDREG PT_GR21(\regs), %r21
185	LDREG PT_GR22(\regs), %r22
186	LDREG PT_GR23(\regs), %r23
187	LDREG PT_GR24(\regs), %r24
188	LDREG PT_GR25(\regs), %r25
189	LDREG PT_GR26(\regs), %r26
190	LDREG PT_GR27(\regs), %r27
191	LDREG PT_GR28(\regs), %r28
192	/* r29 points to register save area, and is restored in rest_stack */
193	/* r30 stack pointer restored in rest_stack */
194	LDREG PT_GR31(\regs), %r31
195	.endm
196
197	.macro	save_fp 	regs
198	fstd,ma  %fr0, 8(\regs)
199	fstd,ma	 %fr1, 8(\regs)
200	fstd,ma	 %fr2, 8(\regs)
201	fstd,ma	 %fr3, 8(\regs)
202	fstd,ma	 %fr4, 8(\regs)
203	fstd,ma	 %fr5, 8(\regs)
204	fstd,ma	 %fr6, 8(\regs)
205	fstd,ma	 %fr7, 8(\regs)
206	fstd,ma	 %fr8, 8(\regs)
207	fstd,ma	 %fr9, 8(\regs)
208	fstd,ma	%fr10, 8(\regs)
209	fstd,ma	%fr11, 8(\regs)
210	fstd,ma	%fr12, 8(\regs)
211	fstd,ma	%fr13, 8(\regs)
212	fstd,ma	%fr14, 8(\regs)
213	fstd,ma	%fr15, 8(\regs)
214	fstd,ma	%fr16, 8(\regs)
215	fstd,ma	%fr17, 8(\regs)
216	fstd,ma	%fr18, 8(\regs)
217	fstd,ma	%fr19, 8(\regs)
218	fstd,ma	%fr20, 8(\regs)
219	fstd,ma	%fr21, 8(\regs)
220	fstd,ma	%fr22, 8(\regs)
221	fstd,ma	%fr23, 8(\regs)
222	fstd,ma	%fr24, 8(\regs)
223	fstd,ma	%fr25, 8(\regs)
224	fstd,ma	%fr26, 8(\regs)
225	fstd,ma	%fr27, 8(\regs)
226	fstd,ma	%fr28, 8(\regs)
227	fstd,ma	%fr29, 8(\regs)
228	fstd,ma	%fr30, 8(\regs)
229	fstd	%fr31, 0(\regs)
230	.endm
231
232	.macro	rest_fp 	regs
233	fldd	0(\regs),	 %fr31
234	fldd,mb	-8(\regs),       %fr30
235	fldd,mb	-8(\regs),       %fr29
236	fldd,mb	-8(\regs),       %fr28
237	fldd,mb	-8(\regs),       %fr27
238	fldd,mb	-8(\regs),       %fr26
239	fldd,mb	-8(\regs),       %fr25
240	fldd,mb	-8(\regs),       %fr24
241	fldd,mb	-8(\regs),       %fr23
242	fldd,mb	-8(\regs),       %fr22
243	fldd,mb	-8(\regs),       %fr21
244	fldd,mb	-8(\regs),       %fr20
245	fldd,mb	-8(\regs),       %fr19
246	fldd,mb	-8(\regs),       %fr18
247	fldd,mb	-8(\regs),       %fr17
248	fldd,mb	-8(\regs),       %fr16
249	fldd,mb	-8(\regs),       %fr15
250	fldd,mb	-8(\regs),       %fr14
251	fldd,mb	-8(\regs),       %fr13
252	fldd,mb	-8(\regs),       %fr12
253	fldd,mb	-8(\regs),       %fr11
254	fldd,mb	-8(\regs),       %fr10
255	fldd,mb	-8(\regs),       %fr9
256	fldd,mb	-8(\regs),       %fr8
257	fldd,mb	-8(\regs),       %fr7
258	fldd,mb	-8(\regs),       %fr6
259	fldd,mb	-8(\regs),       %fr5
260	fldd,mb	-8(\regs),       %fr4
261	fldd,mb	-8(\regs),       %fr3
262	fldd,mb	-8(\regs),       %fr2
263	fldd,mb	-8(\regs),       %fr1
264	fldd,mb	-8(\regs),       %fr0
265	.endm
266
267#ifdef __LP64__
268	.macro	callee_save
269	std,ma	  %r3,	144(%r30)
270	mfctl	  %cr27, %r3
271	std	  %r4,	-136(%r30)
272	std	  %r5,	-128(%r30)
273	std	  %r6,	-120(%r30)
274	std	  %r7,	-112(%r30)
275	std	  %r8,	-104(%r30)
276	std	  %r9,	 -96(%r30)
277	std	 %r10,	 -88(%r30)
278	std	 %r11,	 -80(%r30)
279	std	 %r12,	 -72(%r30)
280	std	 %r13,	 -64(%r30)
281	std	 %r14,	 -56(%r30)
282	std	 %r15,	 -48(%r30)
283	std	 %r16,	 -40(%r30)
284	std	 %r17,	 -32(%r30)
285	std	 %r18,	 -24(%r30)
286	std	  %r3,	 -16(%r30)
287	.endm
288
289	.macro	callee_rest
290	ldd	 -16(%r30),    %r3
291	ldd	 -24(%r30),   %r18
292	ldd	 -32(%r30),   %r17
293	ldd	 -40(%r30),   %r16
294	ldd	 -48(%r30),   %r15
295	ldd	 -56(%r30),   %r14
296	ldd	 -64(%r30),   %r13
297	ldd	 -72(%r30),   %r12
298	ldd	 -80(%r30),   %r11
299	ldd	 -88(%r30),   %r10
300	ldd	 -96(%r30),    %r9
301	ldd	-104(%r30),    %r8
302	ldd	-112(%r30),    %r7
303	ldd	-120(%r30),    %r6
304	ldd	-128(%r30),    %r5
305	ldd	-136(%r30),    %r4
306	mtctl	%r3, %cr27
307	ldd,mb	-144(%r30),    %r3
308	.endm
309
310#else /* ! __LP64__ */
311
312	.macro	callee_save
313	stw,ma	 %r3,	128(%r30)
314	mfctl	 %cr27, %r3
315	stw	 %r4,	-124(%r30)
316	stw	 %r5,	-120(%r30)
317	stw	 %r6,	-116(%r30)
318	stw	 %r7,	-112(%r30)
319	stw	 %r8,	-108(%r30)
320	stw	 %r9,	-104(%r30)
321	stw	 %r10,	-100(%r30)
322	stw	 %r11,	 -96(%r30)
323	stw	 %r12,	 -92(%r30)
324	stw	 %r13,	 -88(%r30)
325	stw	 %r14,	 -84(%r30)
326	stw	 %r15,	 -80(%r30)
327	stw	 %r16,	 -76(%r30)
328	stw	 %r17,	 -72(%r30)
329	stw	 %r18,	 -68(%r30)
330	stw	  %r3,	 -64(%r30)
331	.endm
332
333	.macro	callee_rest
334	ldw	 -64(%r30),    %r3
335	ldw	 -68(%r30),   %r18
336	ldw	 -72(%r30),   %r17
337	ldw	 -76(%r30),   %r16
338	ldw	 -80(%r30),   %r15
339	ldw	 -84(%r30),   %r14
340	ldw	 -88(%r30),   %r13
341	ldw	 -92(%r30),   %r12
342	ldw	 -96(%r30),   %r11
343	ldw	-100(%r30),   %r10
344	ldw	-104(%r30),   %r9
345	ldw	-108(%r30),   %r8
346	ldw	-112(%r30),   %r7
347	ldw	-116(%r30),   %r6
348	ldw	-120(%r30),   %r5
349	ldw	-124(%r30),   %r4
350	mtctl	%r3, %cr27
351	ldw,mb	-128(%r30),   %r3
352	.endm
353#endif /* ! __LP64__ */
354
355	.macro	save_specials	regs
356
357	SAVE_SP  (%sr0, PT_SR0 (\regs))
358	SAVE_SP  (%sr1, PT_SR1 (\regs))
359	SAVE_SP  (%sr2, PT_SR2 (\regs))
360	SAVE_SP  (%sr3, PT_SR3 (\regs))
361	SAVE_SP  (%sr4, PT_SR4 (\regs))
362	SAVE_SP  (%sr5, PT_SR5 (\regs))
363	SAVE_SP  (%sr6, PT_SR6 (\regs))
364	SAVE_SP  (%sr7, PT_SR7 (\regs))
365
366	SAVE_CR  (%cr17, PT_IASQ0(\regs))
367	mtctl	 %r0,	%cr17
368	SAVE_CR  (%cr17, PT_IASQ1(\regs))
369
370	SAVE_CR  (%cr18, PT_IAOQ0(\regs))
371	mtctl	 %r0,	%cr18
372	SAVE_CR  (%cr18, PT_IAOQ1(\regs))
373
374#ifdef __LP64__
375	/* cr11 (sar) is a funny one.  5 bits on PA1.1 and 6 bit on PA2.0
376	 * For PA2.0 mtsar or mtctl always write 6 bits, but mfctl only
377	 * reads 5 bits.  Use mfctl,w to read all six bits.  Otherwise
378	 * we loose the 6th bit on a save/restore over interrupt.
379	 */
380	mfctl,w  %cr11, %r1
381	STREG    %r1, PT_SAR (\regs)
382#else
383	SAVE_CR  (%cr11, PT_SAR  (\regs))
384#endif
385	SAVE_CR  (%cr19, PT_IIR  (\regs))
386
387	/*
388	 * Code immediately following this macro (in intr_save) relies
389	 * on r8 containing ipsw.
390	 */
391	mfctl    %cr22, %r8
392	STREG    %r8,   PT_PSW(\regs)
393	.endm
394
395	.macro	rest_specials	regs
396
397	REST_SP  (%sr0, PT_SR0 (\regs))
398	REST_SP  (%sr1, PT_SR1 (\regs))
399	REST_SP  (%sr2, PT_SR2 (\regs))
400	REST_SP  (%sr3, PT_SR3 (\regs))
401	REST_SP  (%sr4, PT_SR4 (\regs))
402	REST_SP  (%sr5, PT_SR5 (\regs))
403	REST_SP  (%sr6, PT_SR6 (\regs))
404	REST_SP  (%sr7, PT_SR7 (\regs))
405
406	REST_CR	(%cr17, PT_IASQ0(\regs))
407	REST_CR	(%cr17, PT_IASQ1(\regs))
408
409	REST_CR	(%cr18, PT_IAOQ0(\regs))
410	REST_CR	(%cr18, PT_IAOQ1(\regs))
411
412	REST_CR (%cr11, PT_SAR	(\regs))
413
414	REST_CR	(%cr22, PT_PSW	(\regs))
415	.endm
416
417#endif
418