1/*
2 * QuickThreads -- Threads-building toolkit.
3 * Copyright (c) 1993 by David Keppel
4 *
5 * Permission to use, copy, modify and distribute this software and
6 * its documentation for any purpose and without fee is hereby
7 * granted, provided that the above copyright notice and this notice
8 * appear in all copies.  This software is provided as a
9 * proof-of-concept and for demonstration purposes; there is no
10 * representation about the suitability of this software for any
11 * purpose.
12 */
13
14/*
15 * This file (pa-risc.h) is part of the port of QuickThreads for the
16 * PA-RISC 1.1 architecture.  This file is a machine dependent header
17 * file.  It was written in 1994 by Uwe Reder
18 * (`uereder@cip.informatik.uni-erlangen.de') for the Operating Systems
19 * Department (IMMD4) at the University of Erlangen/Nuernberg Germany.
20 */
21
22
23#ifndef QUICKTHREADS_PA_RISC_H
24#define QUICKTHREADS_PA_RISC_H
25
26#if 0
27#include <qt.h>
28#endif
29
30/* size of an integer-register (32 bit) */
31typedef unsigned long qt_word_t;
32
33/* PA-RISC's stack grows up */
34#define QUICKTHREADS_GROW_UP
35
36/* Stack layout on PA-RISC according to PA-RISC Procedure Calling Conventions:
37
38    Callee-save registers are: gr3-gr18, fr12-fr21.
39    Also save gr2, return pointer.
40
41    +---
42    | fr12          Each floating register is a double word (8 bytes).
43    | fr13          Floating registers are only saved if `qt_block' is
44    | fr14          called, in which case it saves the floating-point
45    | fr15          registers then calls `qt_blocki' to save the integer
46    | fr16	    registers.
47    | fr17
48    | fr18
49    | fr19
50    | fr20
51    | fr21
52    | <arg word 3>  fixed arguments (must be allocated; may remain unused)
53    | <arg word 2>
54    | <arg word 1>
55    | <arg word 0>
56    | <LPT>         frame marker
57    | <LPT'>
58    | <RP'>
59    | <Current RP>
60    | <Static Link>
61    | <Clean Up>
62    | <RP''>
63    | <Previous SP>
64    +---
65    | gr3           word each (4 bytes)
66    | gr4
67    | gr5
68    | gr6
69    | gr7
70    | gr8
71    | gr9
72    | gr10
73    | gr11
74    | gr12
75    | gr13
76    | gr14
77    | gr15
78    | gr16
79    | gr17
80    | gr18
81    | <16 bytes filled in (sp has to be 64-bytes aligned)>
82    | <arg word 3>  fixed arguments (must be allocated; may remain unused)
83    | <arg word 2>
84    | <arg word 1>
85    | <arg word 0>
86    | <LPT>         frame marker
87    | <LPT'>
88    | <RP'>
89    | <Current RP>
90    | <Static Link>
91    | <Clean Up>
92    | <RP''>
93    | <Previous SP>
94    +---            <--- sp
95*/
96
97/* When a never-before-run thread is restored, the return pc points
98   to a fragment of code that starts the thread running.  For
99   non-vargs functions, it just calls the client's `only' function.
100   For varargs functions, it calls the startup, user, and cleanup
101   functions. */
102
103/* Note: Procedue Labels on PA-RISC
104
105   <--2--><-------28---------><1-><1->
106   -----------------------------------
107   | SID |    Adress Part    | L | X |
108   -----------------------------------
109
110   On HP-UX the L field is used to flag wheather the procedure
111   label (plabel) is a pointer to an LT entry or to the entry point
112   of the procedure (PA-RISC Procedure Calling Conventions Reference
113   Manual, 5.3.2 Procedure Labels and Dynamic Calls). */
114
115#define QUICKTHREADS_PA_RISC_READ_PLABEL(plabel) \
116    ( (((int)plabel) & 2) ? \
117        ( (*((int *)(((int)plabel) & 0xfffffffc)))) : ((int)plabel) )
118
119/* Stack must be 64 bytes aligned. */
120#define QUICKTHREADS_STKALIGN (64)
121
122/* Internal helper for putting stuff on stack (negative index!). */
123#define QUICKTHREADS_SPUT(top, at, val)   \
124    (((qt_word_t *)(top))[-(at)] = (qt_word_t)(val))
125
126/* Offsets of various registers which are modified on the stack.
127   rp (return-pointer) has to be stored in the frame-marker-area
128   of the "older" stack-segment. */
129
130#define QUICKTHREADS_crp  (12+4+16+5)
131#define QUICKTHREADS_15   (12+4+4)
132#define QUICKTHREADS_16   (12+4+3)
133#define QUICKTHREADS_17   (12+4+2)
134#define QUICKTHREADS_18   (12+4+1)
135
136
137/** This stuff is for NON-VARARGS. **/
138
139/* Stack looks like this (2 stack frames):
140
141    <--- 64-bytes aligned --><------- 64-bytes aligned ------------>
142   |                        ||                                      |
143    <--16--><------48-------><----16*4-----><--16-><------48------->
144   ||      |                ||             |      |                ||
145   ||filler|arg|frame-marker||register-save|filler|arg|frame-marker||
146   ------------------------------------------------------------------
147 */
148
149#define QUICKTHREADS_STKBASE  (16+48+(16*sizeof(qt_word_t))+16+48)
150
151/* The index, relative to sp, of where to put each value. */
152#define QUICKTHREADS_ONLY_INDEX   (QUICKTHREADS_15)
153#define QUICKTHREADS_USER_INDEX   (QUICKTHREADS_16)
154#define QUICKTHREADS_ARGT_INDEX   (QUICKTHREADS_17)
155#define QUICKTHREADS_ARGU_INDEX   (QUICKTHREADS_18)
156
157extern void qt_start(void);
158#define QUICKTHREADS_ARGS_MD(sp)  \
159    (QUICKTHREADS_SPUT (sp, QUICKTHREADS_crp, QUICKTHREADS_PA_RISC_READ_PLABEL(qt_start)))
160
161
162/** This is for VARARGS. **/
163
164#define QUICKTHREADS_VARGS_DEFAULT
165
166/* Stack looks like this (2 stack frames):
167
168    <------ 64-bytes aligned -------><--------- 64-bytes aligned ---------->
169   |                                ||                                      |
170    <---?--><--?---><16><----32-----><----16*4-----><-16--><16><----32----->
171   ||      |       |   |            ||             |      |   |            ||
172   ||filler|varargs|arg|frame-marker||register-save|filler|arg|frame-marker||
173   --------------------------------------------------------------------------
174 */
175
176/* Sp is moved to the end of the first stack frame. */
177#define QUICKTHREADS_VARGS_MD0(sp, vasize) \
178    ((qt_t *)(((char *)sp) + QUICKTHREADS_STKROUNDUP(vasize + 4*4 + 32)))
179
180/* To reach the arguments from the end of the first stack frame use 32
181   as a negative adjustment. */
182#define QUICKTHREADS_VARGS_ADJUST(sp)	((qt_t *)(((char *)sp) - 32))
183
184/* Offset to reach the end of the second stack frame. */
185#define QUICKTHREADS_VSTKBASE	((16*sizeof(qt_word_t)) + 16 + 4*4 + 32)
186
187extern void qt_vstart(void);
188#define QUICKTHREADS_VARGS_MD1(sp) \
189    (QUICKTHREADS_SPUT (sp, QUICKTHREADS_crp, QUICKTHREADS_PA_RISC_READ_PLABEL(qt_vstart)))
190
191#define QUICKTHREADS_VARGT_INDEX      (QUICKTHREADS_15)
192#define QUICKTHREADS_VSTARTUP_INDEX   (QUICKTHREADS_16)
193#define QUICKTHREADS_VUSERF_INDEX     (QUICKTHREADS_17)
194#define QUICKTHREADS_VCLEANUP_INDEX   (QUICKTHREADS_18)
195
196#endif /* ndef QUICKTHREADS_PA_RISC_H */
197