Add more bits for native hammer boot support.
[dragonfly.git] / sys / boot / ficl / stack.c
1 /*******************************************************************
2 ** s t a c k . c
3 ** Forth Inspired Command Language
4 ** Author: John Sadler (john_sadler@alum.mit.edu)
5 ** Created: 16 Oct 1997
6 ** $Id: stack.c,v 1.10 2001/12/05 07:21:34 jsadler Exp $
7 *******************************************************************/
8 /*
9 ** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
10 ** All rights reserved.
11 **
12 ** Get the latest Ficl release at http://ficl.sourceforge.net
13 **
14 ** I am interested in hearing from anyone who uses ficl. If you have
15 ** a problem, a success story, a defect, an enhancement request, or
16 ** if you would like to contribute to the ficl release, please
17 ** contact me by email at the address above.
18 **
19 ** L I C E N S E  and  D I S C L A I M E R
20 ** 
21 ** Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions
23 ** are met:
24 ** 1. Redistributions of source code must retain the above copyright
25 **    notice, this list of conditions and the following disclaimer.
26 ** 2. Redistributions in binary form must reproduce the above copyright
27 **    notice, this list of conditions and the following disclaimer in the
28 **    documentation and/or other materials provided with the distribution.
29 **
30 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
31 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 ** ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
34 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 ** SUCH DAMAGE.
41 */
42
43 /*
44  * $FreeBSD: src/sys/boot/ficl/stack.c,v 1.5 2002/04/09 17:45:11 dcs Exp $
45  * $DragonFly: src/sys/boot/ficl/stack.c,v 1.3 2003/11/10 06:08:33 dillon Exp $
46  */
47
48 #ifdef TESTMAIN
49 #include <stdlib.h>
50 #else
51 #include <stand.h>
52 #endif
53 #include "ficl.h"
54
55 #define STKDEPTH(s) ((s)->sp - (s)->base)
56
57 /*
58 ** N O T E: Stack convention:
59 **
60 ** sp points to the first available cell
61 ** push: store value at sp, increment sp
62 ** pop:  decrement sp, fetch value at sp
63 ** Stack grows from low to high memory
64 */
65
66 /*******************************************************************
67                     v m C h e c k S t a c k
68 ** Check the parameter stack for underflow or overflow.
69 ** nCells controls the type of check: if nCells is zero,
70 ** the function checks the stack state for underflow and overflow.
71 ** If nCells > 0, checks to see that the stack has room to push
72 ** that many cells. If less than zero, checks to see that the
73 ** stack has room to pop that many cells. If any test fails,
74 ** the function throws (via vmThrow) a VM_ERREXIT exception.
75 *******************************************************************/
76 void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells)
77 {
78     FICL_STACK *pStack = pVM->pStack;
79     int nFree = pStack->base + pStack->nCells - pStack->sp;
80
81     if (popCells > STKDEPTH(pStack))
82     {
83         vmThrowErr(pVM, "Error: stack underflow");
84     }
85
86     if (nFree < pushCells - popCells)
87     {
88         vmThrowErr(pVM, "Error: stack overflow");
89     }
90
91     return;
92 }
93
94 #if FICL_WANT_FLOAT
95 void vmCheckFStack(FICL_VM *pVM, int popCells, int pushCells)
96 {
97     FICL_STACK *fStack = pVM->fStack;
98     int nFree = fStack->base + fStack->nCells - fStack->sp;
99
100     if (popCells > STKDEPTH(fStack))
101     {
102         vmThrowErr(pVM, "Error: float stack underflow");
103     }
104
105     if (nFree < pushCells - popCells)
106     {
107         vmThrowErr(pVM, "Error: float stack overflow");
108     }
109 }
110 #endif
111
112 /*******************************************************************
113                     s t a c k C r e a t e
114 ** 
115 *******************************************************************/
116
117 FICL_STACK *stackCreate(unsigned nCells)
118 {
119     size_t size = sizeof (FICL_STACK) + nCells * sizeof (CELL);
120     FICL_STACK *pStack = ficlMalloc(size);
121
122 #if FICL_ROBUST
123     assert (nCells != 0);
124     assert (pStack != NULL);
125 #endif
126
127     pStack->nCells = nCells;
128     pStack->sp     = pStack->base;
129     pStack->pFrame = NULL;
130     return pStack;
131 }
132
133
134 /*******************************************************************
135                     s t a c k D e l e t e
136 ** 
137 *******************************************************************/
138
139 void stackDelete(FICL_STACK *pStack)
140 {
141     if (pStack)
142         ficlFree(pStack);
143     return;
144 }
145
146
147 /*******************************************************************
148                     s t a c k D e p t h 
149 ** 
150 *******************************************************************/
151
152 int stackDepth(FICL_STACK *pStack)
153 {
154     return STKDEPTH(pStack);
155 }
156
157 /*******************************************************************
158                     s t a c k D r o p
159 ** 
160 *******************************************************************/
161
162 void stackDrop(FICL_STACK *pStack, int n)
163 {
164 #if FICL_ROBUST
165     assert(n > 0);
166 #endif
167     pStack->sp -= n;
168     return;
169 }
170
171
172 /*******************************************************************
173                     s t a c k F e t c h
174 ** 
175 *******************************************************************/
176
177 CELL stackFetch(FICL_STACK *pStack, int n)
178 {
179     return pStack->sp[-n-1];
180 }
181
182 void stackStore(FICL_STACK *pStack, int n, CELL c)
183 {
184     pStack->sp[-n-1] = c;
185     return;
186 }
187
188
189 /*******************************************************************
190                     s t a c k G e t T o p
191 ** 
192 *******************************************************************/
193
194 CELL stackGetTop(FICL_STACK *pStack)
195 {
196     return pStack->sp[-1];
197 }
198
199
200 /*******************************************************************
201                     s t a c k L i n k
202 ** Link a frame using the stack's frame pointer. Allot space for
203 ** nCells cells in the frame
204 ** 1) Push pFrame
205 ** 2) pFrame = sp
206 ** 3) sp += nCells
207 *******************************************************************/
208
209 void stackLink(FICL_STACK *pStack, int nCells)
210 {
211     stackPushPtr(pStack, pStack->pFrame);
212     pStack->pFrame = pStack->sp;
213     pStack->sp += nCells;
214     return;
215 }
216
217
218 /*******************************************************************
219                     s t a c k U n l i n k
220 ** Unink a stack frame previously created by stackLink
221 ** 1) sp = pFrame
222 ** 2) pFrame = pop()
223 *******************************************************************/
224
225 void stackUnlink(FICL_STACK *pStack)
226 {
227     pStack->sp = pStack->pFrame;
228     pStack->pFrame = stackPopPtr(pStack);
229     return;
230 }
231
232
233 /*******************************************************************
234                     s t a c k P i c k
235 ** 
236 *******************************************************************/
237
238 void stackPick(FICL_STACK *pStack, int n)
239 {
240     stackPush(pStack, stackFetch(pStack, n));
241     return;
242 }
243
244
245 /*******************************************************************
246                     s t a c k P o p
247 ** 
248 *******************************************************************/
249
250 CELL stackPop(FICL_STACK *pStack)
251 {
252     return *--pStack->sp;
253 }
254
255 void *stackPopPtr(FICL_STACK *pStack)
256 {
257     return (*--pStack->sp).p;
258 }
259
260 FICL_UNS stackPopUNS(FICL_STACK *pStack)
261 {
262     return (*--pStack->sp).u;
263 }
264
265 FICL_INT stackPopINT(FICL_STACK *pStack)
266 {
267     return (*--pStack->sp).i;
268 }
269
270 #if (FICL_WANT_FLOAT)
271 float stackPopFloat(FICL_STACK *pStack)
272 {
273     return (*(--pStack->sp)).f;
274 }
275 #endif
276
277 /*******************************************************************
278                     s t a c k P u s h
279 ** 
280 *******************************************************************/
281
282 void stackPush(FICL_STACK *pStack, CELL c)
283 {
284     *pStack->sp++ = c;
285 }
286
287 void stackPushPtr(FICL_STACK *pStack, void *ptr)
288 {
289     *pStack->sp++ = LVALUEtoCELL(ptr);
290 }
291
292 void stackPushUNS(FICL_STACK *pStack, FICL_UNS u)
293 {
294     *pStack->sp++ = LVALUEtoCELL(u);
295 }
296
297 void stackPushINT(FICL_STACK *pStack, FICL_INT i)
298 {
299     *pStack->sp++ = LVALUEtoCELL(i);
300 }
301
302 #if (FICL_WANT_FLOAT)
303 void stackPushFloat(FICL_STACK *pStack, FICL_FLOAT f)
304 {
305     *pStack->sp++ = LVALUEtoCELL(f);
306 }
307 #endif
308
309 /*******************************************************************
310                     s t a c k R e s e t
311 ** 
312 *******************************************************************/
313
314 void stackReset(FICL_STACK *pStack)
315 {
316     pStack->sp = pStack->base;
317     return;
318 }
319
320
321 /*******************************************************************
322                     s t a c k R o l l 
323 ** Roll nth stack entry to the top (counting from zero), if n is 
324 ** >= 0. Drop other entries as needed to fill the hole.
325 ** If n < 0, roll top-of-stack to nth entry, pushing others
326 ** upward as needed to fill the hole.
327 *******************************************************************/
328
329 void stackRoll(FICL_STACK *pStack, int n)
330 {
331     CELL c;
332     CELL *pCell;
333
334     if (n == 0)
335         return;
336     else if (n > 0)
337     {
338         pCell = pStack->sp - n - 1;
339         c = *pCell;
340
341         for (;n > 0; --n, pCell++)
342         {
343             *pCell = pCell[1];
344         }
345
346         *pCell = c;
347     }
348     else
349     {
350         pCell = pStack->sp - 1;
351         c = *pCell;
352
353         for (; n < 0; ++n, pCell--)
354         {
355             *pCell = pCell[-1];
356         }
357
358         *pCell = c;
359     }
360     return;
361 }
362
363
364 /*******************************************************************
365                     s t a c k S e t T o p
366 ** 
367 *******************************************************************/
368
369 void stackSetTop(FICL_STACK *pStack, CELL c)
370 {
371     pStack->sp[-1] = c;
372     return;
373 }
374
375