annotate src/alloca.c @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 7d55a9ba150c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1 /* alloca.c -- allocate automatically reclaimed memory
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
2 (Mostly) portable public-domain implementation -- D A Gwyn
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
3
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
4 This implementation of the PWB library alloca function,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
5 which is used to allocate space off the run-time stack so
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
6 that it is automatically reclaimed upon procedure exit,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
7 was inspired by discussions with J. Q. Johnson of Cornell.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
8 J.Otto Tennant <jot@cray.com> contributed the Cray support.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
9
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
10 There are some preprocessor constants that can
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
11 be defined when compiling for your specific system, for
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
12 improved efficiency; however, the defaults should be okay.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
13
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
14 The general concept of this implementation is to keep
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
15 track of all alloca-allocated blocks, and reclaim any
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
16 that are found to be deeper in the stack than the current
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
17 invocation. This heuristic does not reclaim storage as
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
18 soon as it becomes invalid, but it will do so eventually.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
19
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
20 As a special case, alloca(0) reclaims storage without
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
21 allocating any. It is a good idea to use alloca(0) in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
22 your main control loop, etc. to force garbage collection. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
23
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
24 /* Synched up with: FSF 19.30. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
25
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
26 /* Authorsip:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
27
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
28 FSF: A long time ago.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
29 Very few changes for XEmacs.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
30 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
31
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
32 #ifdef HAVE_CONFIG_H
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
33 #include <config.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
34 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
35
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
36 /* XEmacs: If compiling with GCC 2, this file is theoretically not needed.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
37 However, alloca() is broken under GCC 2 on many machines: you
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
38 cannot put a call to alloca() as part of an argument to a function.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
39 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
40 /* If someone has defined alloca as a macro,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
41 there must be some other way alloca is supposed to work. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
42 /* XEmacs sometimes uses the C alloca even when a builtin alloca is available,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
43 because it's safer. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
44 #if defined (EMACS_WANTS_C_ALLOCA) || (!defined (alloca) && (!defined (__GNUC__) || __GNUC__ < 2))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
45
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
46 #ifdef emacs
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
47 #ifdef static
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
48 /* actually, only want this if static is defined as ""
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
49 -- this is for usg, in which emacs must undefine static
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
50 in order to make unexec workable
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
51 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
52 #ifndef STACK_DIRECTION
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
53 you
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
54 lose
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
55 -- must know STACK_DIRECTION at compile-time
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
56 #endif /* STACK_DIRECTION undefined */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
57 #endif /* static */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
58 #endif /* emacs */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
59
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
60 /* If your stack is a linked list of frames, you have to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
61 provide an "address metric" ADDRESS_FUNCTION macro. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
62
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
63 #if defined (CRAY) && defined (CRAY_STACKSEG_END)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
64 long i00afunc ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
65 #define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
66 #else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
67 #define ADDRESS_FUNCTION(arg) &(arg)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
68 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
69
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
70 #ifdef __STDC__ /* XEmacs change */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
71 typedef void *pointer;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
72 #else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
73 typedef char *pointer;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
74 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
75
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
76 /* XEmacs: With ERROR_CHECK_MALLOC defined, there is no xfree -- it's
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
77 a macro that does some stuff to try and trap invalid frees,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
78 and then calls xfree_1 to actually do the work. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
79
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
80 #ifdef emacs
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
81 # ifdef ERROR_CHECK_MALLOC
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
82 void xfree_1 (pointer);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
83 # define xfree xfree_1
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
84 # else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
85 void xfree (pointer);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
86 # endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
87 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
88
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
89 #define NULL 0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
90
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
91 /* Different portions of Emacs need to call different versions of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
92 malloc. The Emacs executable needs alloca to call xmalloc, because
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
93 ordinary malloc isn't protected from input signals. On the other
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
94 hand, the utilities in lib-src need alloca to call malloc; some of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
95 them are very simple, and don't have an xmalloc routine.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
96
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
97 Non-Emacs programs expect this to call use xmalloc.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
98
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
99 Callers below should use malloc. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
100
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
101 #ifndef emacs
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
102 #define malloc xmalloc
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
103 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
104 extern pointer malloc ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
105
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
106 /* Define STACK_DIRECTION if you know the direction of stack
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
107 growth for your system; otherwise it will be automatically
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
108 deduced at run-time.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
109
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
110 STACK_DIRECTION > 0 => grows toward higher addresses
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
111 STACK_DIRECTION < 0 => grows toward lower addresses
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
112 STACK_DIRECTION = 0 => direction of growth unknown */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
113
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
114 #ifndef STACK_DIRECTION
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
115 #define STACK_DIRECTION 0 /* Direction unknown. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
116 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
117
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
118 #if STACK_DIRECTION != 0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
119
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
120 #define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
121
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
122 #else /* STACK_DIRECTION == 0; need run-time code. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
123
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
124 static int stack_dir; /* 1 or -1 once known. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
125 #define STACK_DIR stack_dir
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
126
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
127 static void
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
128 find_stack_direction ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
129 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
130 static char *addr = NULL; /* Address of first `dummy', once known. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
131 auto char dummy; /* To get stack address. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
132
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
133 if (addr == NULL)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
134 { /* Initial entry. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
135 addr = ADDRESS_FUNCTION (dummy);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
136
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
137 find_stack_direction (); /* Recurse once. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
138 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
139 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
140 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
141 /* Second entry. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
142 if (ADDRESS_FUNCTION (dummy) > addr)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
143 stack_dir = 1; /* Stack grew upward. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
144 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
145 stack_dir = -1; /* Stack grew downward. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
146 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
147 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
148
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
149 #endif /* STACK_DIRECTION == 0 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
150
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
151 /* An "alloca header" is used to:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
152 (a) chain together all alloca'ed blocks;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
153 (b) keep track of stack depth.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
154
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
155 It is very important that sizeof(header) agree with malloc
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
156 alignment chunk size. The following default should work okay. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
157
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
158 #ifndef ALIGN_SIZE
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
159 #define ALIGN_SIZE sizeof(double)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
160 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
161
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
162 typedef union hdr
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
163 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
164 char align[ALIGN_SIZE]; /* To force sizeof(header). */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
165 struct
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
166 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
167 union hdr *next; /* For chaining headers. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
168 char *deep; /* For stack depth measure. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
169 } h;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
170 } header;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
171
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
172 static header *last_alloca_header = NULL; /* -> last alloca header. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
173
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
174 /* Return a pointer to at least SIZE bytes of storage,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
175 which will be automatically reclaimed upon exit from
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
176 the procedure that called alloca. Originally, this space
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
177 was supposed to be taken from the current stack frame of the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
178 caller, but that method cannot be made to work for some
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
179 implementations of C, for example under Gould's UTX/32. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
180
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
181 pointer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
182 #ifdef EMACS_WANTS_C_ALLOCA
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
183 c_alloca (size)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
184 #else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
185 alloca (size)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
186 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
187 unsigned size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
188 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
189 auto char probe; /* Probes stack depth: */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
190 register char *depth = ADDRESS_FUNCTION (probe);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
191
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
192 #if STACK_DIRECTION == 0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
193 if (STACK_DIR == 0) /* Unknown growth direction. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
194 find_stack_direction ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
195 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
196
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
197 /* Reclaim garbage, defined as all alloca'd storage that
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
198 was allocated from deeper in the stack than currently. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
199
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
200 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
201 register header *hp; /* Traverses linked list. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
202
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
203 for (hp = last_alloca_header; hp != NULL;)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
204 if ((STACK_DIR > 0 && hp->h.deep > depth)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
205 || (STACK_DIR < 0 && hp->h.deep < depth))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
206 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
207 register header *np = hp->h.next;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
208
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
209 free ((pointer) hp); /* Collect garbage. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
210
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
211 hp = np; /* -> next header. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
212 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
213 else
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
214 break; /* Rest are not deeper. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
215
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
216 last_alloca_header = hp; /* -> last valid storage. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
217 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
218
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
219 if (size == 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
220 return NULL; /* No allocation required. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
221
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
222 /* Allocate combined header + user data storage. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
223
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
224 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
225 register pointer new = malloc (sizeof (header) + size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
226 /* Address of header. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
227
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
228 ((header *) new)->h.next = last_alloca_header;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
229 ((header *) new)->h.deep = depth;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
230
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
231 last_alloca_header = (header *) new;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
232
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
233 /* User storage begins just after header. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
234
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
235 return (pointer) ((char *) new + sizeof (header));
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
236 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
237 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
238
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
239 #if defined (CRAY) && defined (CRAY_STACKSEG_END)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
240
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
241 #ifdef DEBUG_I00AFUNC
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
242 #include <stdio.h>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
243 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
244
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
245 #ifndef CRAY_STACK
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
246 #define CRAY_STACK
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
247 #ifndef CRAY2
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
248 /* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
249 struct stack_control_header
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
250 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
251 long shgrow:32; /* Number of times stack has grown. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
252 long shaseg:32; /* Size of increments to stack. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
253 long shhwm:32; /* High water mark of stack. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
254 long shsize:32; /* Current size of stack (all segments). */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
255 };
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
256
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
257 /* The stack segment linkage control information occurs at
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
258 the high-address end of a stack segment. (The stack
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
259 grows from low addresses to high addresses.) The initial
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
260 part of the stack segment linkage control information is
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
261 0200 (octal) words. This provides for register storage
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
262 for the routine which overflows the stack. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
263
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
264 struct stack_segment_linkage
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
265 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
266 long ss[0200]; /* 0200 overflow words. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
267 long sssize:32; /* Number of words in this segment. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
268 long ssbase:32; /* Offset to stack base. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
269 long:32;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
270 long sspseg:32; /* Offset to linkage control of previous
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
271 segment of stack. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
272 long:32;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
273 long sstcpt:32; /* Pointer to task common address block. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
274 long sscsnm; /* Private control structure number for
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
275 microtasking. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
276 long ssusr1; /* Reserved for user. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
277 long ssusr2; /* Reserved for user. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
278 long sstpid; /* Process ID for pid based multi-tasking. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
279 long ssgvup; /* Pointer to multitasking thread giveup. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
280 long sscray[7]; /* Reserved for Cray Research. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
281 long ssa0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
282 long ssa1;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
283 long ssa2;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
284 long ssa3;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
285 long ssa4;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
286 long ssa5;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
287 long ssa6;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
288 long ssa7;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
289 long sss0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
290 long sss1;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
291 long sss2;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
292 long sss3;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
293 long sss4;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
294 long sss5;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
295 long sss6;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
296 long sss7;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
297 };
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
298
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
299 #else /* CRAY2 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
300 /* The following structure defines the vector of words
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
301 returned by the STKSTAT library routine. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
302 struct stk_stat
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
303 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
304 long now; /* Current total stack size. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
305 long maxc; /* Amount of contiguous space which would
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
306 be required to satisfy the maximum
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
307 stack demand to date. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
308 long high_water; /* Stack high-water mark. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
309 long overflows; /* Number of stack overflow ($STKOFEN) calls. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
310 long hits; /* Number of internal buffer hits. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
311 long extends; /* Number of block extensions. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
312 long stko_mallocs; /* Block allocations by $STKOFEN. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
313 long underflows; /* Number of stack underflow calls ($STKRETN). */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
314 long stko_free; /* Number of deallocations by $STKRETN. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
315 long stkm_free; /* Number of deallocations by $STKMRET. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
316 long segments; /* Current number of stack segments. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
317 long maxs; /* Maximum number of stack segments so far. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
318 long pad_size; /* Stack pad size. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
319 long current_address; /* Current stack segment address. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
320 long current_size; /* Current stack segment size. This
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
321 number is actually corrupted by STKSTAT to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
322 include the fifteen word trailer area. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
323 long initial_address; /* Address of initial segment. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
324 long initial_size; /* Size of initial segment. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
325 };
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
326
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
327 /* The following structure describes the data structure which trails
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
328 any stack segment. I think that the description in 'asdef' is
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
329 out of date. I only describe the parts that I am sure about. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
330
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
331 struct stk_trailer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
332 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
333 long this_address; /* Address of this block. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
334 long this_size; /* Size of this block (does not include
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
335 this trailer). */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
336 long unknown2;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
337 long unknown3;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
338 long link; /* Address of trailer block of previous
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
339 segment. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
340 long unknown5;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
341 long unknown6;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
342 long unknown7;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
343 long unknown8;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
344 long unknown9;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
345 long unknown10;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
346 long unknown11;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
347 long unknown12;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
348 long unknown13;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
349 long unknown14;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
350 };
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
351
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
352 #endif /* CRAY2 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
353 #endif /* not CRAY_STACK */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
354
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
355 #ifdef CRAY2
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
356 /* Determine a "stack measure" for an arbitrary ADDRESS.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
357 I doubt that "lint" will like this much. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
358
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
359 static long
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
360 i00afunc (long *address)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
361 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
362 struct stk_stat status;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
363 struct stk_trailer *trailer;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
364 long *block, size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
365 long result = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
366
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
367 /* We want to iterate through all of the segments. The first
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
368 step is to get the stack status structure. We could do this
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
369 more quickly and more directly, perhaps, by referencing the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
370 $LM00 common block, but I know that this works. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
371
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
372 STKSTAT (&status);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
373
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
374 /* Set up the iteration. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
375
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
376 trailer = (struct stk_trailer *) (status.current_address
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
377 + status.current_size
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
378 - 15);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
379
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
380 /* There must be at least one stack segment. Therefore it is
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
381 a fatal error if "trailer" is null. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
382
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
383 if (trailer == 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
384 abort ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
385
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
386 /* Discard segments that do not contain our argument address. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
387
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
388 while (trailer != 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
389 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
390 block = (long *) trailer->this_address;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
391 size = trailer->this_size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
392 if (block == 0 || size == 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
393 abort ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
394 trailer = (struct stk_trailer *) trailer->link;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
395 if ((block <= address) && (address < (block + size)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
396 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
397 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
398
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
399 /* Set the result to the offset in this segment and add the sizes
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
400 of all predecessor segments. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
401
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
402 result = address - block;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
403
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
404 if (trailer == 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
405 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
406 return result;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
407 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
408
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
409 do
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
410 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
411 if (trailer->this_size <= 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
412 abort ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
413 result += trailer->this_size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
414 trailer = (struct stk_trailer *) trailer->link;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
415 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
416 while (trailer != 0);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
417
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
418 /* We are done. Note that if you present a bogus address (one
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
419 not in any segment), you will get a different number back, formed
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
420 from subtracting the address of the first block. This is probably
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
421 not what you want. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
422
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
423 return (result);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
424 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
425
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
426 #else /* not CRAY2 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
427 /* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
428 Determine the number of the cell within the stack,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
429 given the address of the cell. The purpose of this
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
430 routine is to linearize, in some sense, stack addresses
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
431 for alloca. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
432
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
433 static long
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
434 i00afunc (long address)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
435 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
436 long stkl = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
437
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
438 long size, pseg, this_segment, stack;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
439 long result = 0;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
440
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
441 struct stack_segment_linkage *ssptr;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
442
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
443 /* Register B67 contains the address of the end of the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
444 current stack segment. If you (as a subprogram) store
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
445 your registers on the stack and find that you are past
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
446 the contents of B67, you have overflowed the segment.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
447
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
448 B67 also points to the stack segment linkage control
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
449 area, which is what we are really interested in. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
450
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
451 stkl = CRAY_STACKSEG_END ();
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
452 ssptr = (struct stack_segment_linkage *) stkl;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
453
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
454 /* If one subtracts 'size' from the end of the segment,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
455 one has the address of the first word of the segment.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
456
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
457 If this is not the first segment, 'pseg' will be
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
458 nonzero. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
459
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
460 pseg = ssptr->sspseg;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
461 size = ssptr->sssize;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
462
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
463 this_segment = stkl - size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
464
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
465 /* It is possible that calling this routine itself caused
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
466 a stack overflow. Discard stack segments which do not
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
467 contain the target address. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
468
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
469 while (!(this_segment <= address && address <= stkl))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
470 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
471 #ifdef DEBUG_I00AFUNC
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
472 fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
473 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
474 if (pseg == 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
475 break;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
476 stkl = stkl - pseg;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
477 ssptr = (struct stack_segment_linkage *) stkl;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
478 size = ssptr->sssize;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
479 pseg = ssptr->sspseg;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
480 this_segment = stkl - size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
481 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
482
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
483 result = address - this_segment;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
484
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
485 /* If you subtract pseg from the current end of the stack,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
486 you get the address of the previous stack segment's end.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
487 This seems a little convoluted to me, but I'll bet you save
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
488 a cycle somewhere. */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
489
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
490 while (pseg != 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
491 {
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
492 #ifdef DEBUG_I00AFUNC
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
493 fprintf (stderr, "%011o %011o\n", pseg, size);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
494 #endif
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
495 stkl = stkl - pseg;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
496 ssptr = (struct stack_segment_linkage *) stkl;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
497 size = ssptr->sssize;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
498 pseg = ssptr->sspseg;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
499 result += size;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
500 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
501 return (result);
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
502 }
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
503
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
504 #endif /* not CRAY2 */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
505 #endif /* CRAY */
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
506
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
507 #endif /* complicated expression at top of file */