5 /* $Id: stack.c,v 2.5 1994/06/24 10:49:09 ceriel Exp $ */
17 #include "memdirect.h"
22 #define STACKSIZE 1000L /* initial stack size */
24 extern size maxstack; /* from main.c */
27 char *stack_sh; /* stadowbytes */
28 char *stackML_sh; /* speed up access of stadowbytes */
31 PRIVATE warn_stbits();
34 ML = max_addr; /* set Memory Limit */
35 SP = ML + 1; /* initialize Stack Pointer */
36 SL = ML + 1; /* initialize Stack Limit */
37 LB = ML + 1; /* initialize Local Base */
38 AB = ML + 1; /* initialize Actual Base */
40 SL = ML + 1 - STACKSIZE; /* initialize Stack Limit */
41 stack = Malloc(STACKSIZE, "stack space");
44 stack_sh = Malloc(STACKSIZE, "shadowspace for stack");
45 stackML_sh = stack_sh + ML;
46 st_clear_area(ML, SL);
51 /************************************************************************
52 * EM-register division. *
53 ************************************************************************
55 * newSP(p) - check and adjust StackPointer. *
56 * incSP(n) - increment stack pointer. n already checked *
57 * decSP(n) - decrement stack pointer. n already checked *
58 * newLB(p) - check and adjust Local Base and Actual Base *
60 ************************************************************************/
67 LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
69 wtrap(WSPGTLB, ESTACK);
71 if (!is_wordaligned(p)) {
72 wtrap(WSPODD, ESTACK);
76 wtrap(WSPINHEAP, ESTACK);
79 /* more than allowed on command line */
80 if (ML - p > maxstack) {
86 /* extend stack space */
87 register size stacksize = ML + 1 - p;
89 stacksize = allocfrac(stacksize);
90 SL = ML + 1 - stacksize;
91 stack = Realloc(stack, (size)(stacksize), "stack space");
94 stack_sh = Realloc(stack_sh, (size)(stacksize),
95 "shadowspace for stack");
96 stackML_sh = stack_sh + ML;
101 st_clear_area(SP - 1, p);
113 register ptr p = SP - n;
115 if (p < HP || maxstack || p < SL) newSP(p);
117 LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
119 /* inline version of st_clear_area.
135 register ptr p = SP + n;
137 if (LB < p) newSP(p);
139 LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
148 wtrap(WLBOUT, ESTACK);
150 if (!is_wordaligned(p)) {
151 wtrap(WLBODD, ESTACK);
154 wtrap(WLBRSB, ESTACK);
161 /************************************************************************
162 * Stack store division. *
163 ************************************************************************
165 * st_stdp(addr, p) - STore Data Pointer. *
166 * st_stip(addr, p) - STore Instruction Pointer. *
167 * st_stn(addr, l, n) - STore N byte integer. *
168 * st_stw(addr, l) - STore wordsize integer. *
169 * st_stf(addr, f, n) - STore Floating point number. *
171 ************************************************************************/
178 register long p = (long) ap;
180 LOG(("@s6 st_stdp(%lu, %lu)", addr, p));
181 ch_in_stack(addr, psize);
182 ch_wordaligned(addr);
183 for (i = (int) psize; i > 0; i--, addr++) {
185 stack_loc(addr) = (char) (p);
197 register long p = (long) ap;
199 LOG(("@s6 st_stip(%lu, %lu)", addr, p));
200 ch_in_stack(addr, psize);
201 ch_wordaligned(addr);
202 for (i = (int) psize; i > 0; i--, addr++) {
204 stack_loc(addr) = (char) (p);
216 register long l = al;
218 /* a psize zero is ambiguous */
219 int sh_flags = (l == 0 && n == psize) ? (SH_INT|SH_DATAP) : SH_INT;
222 LOG(("@s6 st_stn(%lu, %ld, %lu)", addr, l, n));
223 ch_in_stack(addr, n);
226 /* store the bytes */
227 for (i = (int) n; i > 0; i--, addr++) {
229 stack_loc(addr) = (char) l;
231 st_sh(addr) = sh_flags;
242 register long l = al;
244 /* a psize zero is ambiguous */
245 int sh_flags = (l == 0 && wsize == psize) ? (SH_INT|SH_DATAP) : SH_INT;
248 LOG(("@s6 st_stw(%lu, %ld)", addr, l));
250 ch_wordaligned(addr);
252 /* store the bytes */
253 for (i = (int) wsize; i > 0; i--, addr++) {
255 stack_loc(addr) = (char) l;
257 st_sh(addr) = sh_flags;
269 register char *cp = (char *) &f;
273 LOG(("@s6 st_stf(%lu, %g, %lu)", addr, f, n));
274 ch_in_stack(addr, n);
275 ch_wordaligned(addr);
280 for (i = (int) n; i > 0; i--, addr++) {
282 stack_loc(addr) = *(cp++);
288 /************************************************************************
289 * Stack load division. *
290 ************************************************************************
292 * st_lddp(addr) - LoaD Data Pointer from stack. *
293 * st_ldip(addr) - LoaD Instruction Pointer from stack. *
294 * st_ldu(addr, n) - LoaD n Unsigned bytes from stack. *
295 * st_lduw(addr) - LoaD wsize Unsigned bytes from stack. *
296 * st_lds(addr, n) - LoaD n Signed bytes from stack. *
297 * st_ldsw(addr) - LoaD wsize Signed bytes from stack. *
298 * st_ldf(addr, n) - LoaD Floating point number from stack. *
300 ************************************************************************/
307 LOG(("@s6 st_lddp(%lu)", addr));
309 ch_in_stack(addr, psize);
310 ch_wordaligned(addr);
312 if (!is_st_set(addr, psize, SH_DATAP)) {
314 warn_stbits(addr, psize);
318 p = p_in_stack(addr);
319 LOG(("@s6 st_lddp() returns %lu", p));
328 LOG(("@s6 st_ldip(%lu)", addr));
330 ch_in_stack(addr, psize);
331 ch_wordaligned(addr);
333 if (!is_st_set(addr, psize, SH_INSP)) {
335 warn_stbits(addr, psize);
339 p = p_in_stack(addr);
340 LOG(("@s6 st_ldip() returns %lu", p));
344 unsigned long st_ldu(addr, n)
349 register unsigned long u = 0;
351 LOG(("@s6 st_ldu(%lu, %lu)", addr, n));
353 ch_in_stack(addr, n);
356 if (!is_st_set(addr, n, SH_INT)) {
357 warning(n == 1 ? WLCEXP : WLIEXP);
358 warn_stbits(addr, n);
363 for (i = (int) n-1; i >= 0; i--, addr--) {
364 u = (u<<8) | (btou(stack_loc(addr)));
366 LOG(("@s6 st_ldu() returns %ld", u));
370 unsigned long st_lduw(addr)
374 register unsigned long u = 0;
376 LOG(("@s6 st_lduw(%lu)", addr));
379 ch_wordaligned(addr);
381 if (!is_st_set(addr, wsize, SH_INT)) {
383 warn_stbits(addr, wsize);
388 for (i = (int) wsize-1; i >= 0; i--, addr--) {
389 u = (u<<8) | (btou(stack_loc(addr)));
391 LOG(("@s6 st_lduw() returns %ld", u));
402 LOG(("@s6 st_lds(%lu, %lu)", addr, n));
404 ch_in_stack(addr, n);
407 if (!is_st_set(addr, n, SH_INT)) {
408 warning(n == 1 ? WLCEXP : WLIEXP);
409 warn_stbits(addr, n);
414 l = btos(stack_loc(addr + 1));
415 for (i = n - 2; i >= 0; i--, addr--) {
416 l = (l<<8) | btol(stack_loc(addr));
418 LOG(("@s6 st_lds() returns %ld", l));
428 LOG(("@s6 st_ldsw(%lu)", addr));
431 ch_wordaligned(addr);
433 if (!is_st_set(addr, wsize, SH_INT)) {
435 warn_stbits(addr, wsize);
440 l = btos(stack_loc(addr+1));
441 for (i = wsize - 2; i >= 0; i--, addr--) {
442 l = (l<<8) | btol(stack_loc(addr));
444 LOG(("@s6 st_ldsw() returns %ld", l));
449 double st_ldf(addr, n)
458 LOG(("@s6 st_ldf(%lu, %lu)", addr, n));
466 ch_in_stack(addr, n);
467 ch_wordaligned(addr);
469 if (!is_st_set(addr, n, SH_FLOAT)) {
471 warn_stbits(addr, n);
475 for (i = (int) n; i > 0; i--, addr++) {
476 *(cp++) = stack_loc(addr);
485 /************************************************************************
486 * Stack move division *
487 ************************************************************************
489 * st_mvs(s2, s1, n) - Move n bytes in stack from s1 to s2. *
490 * st_mvd(s, d, n) - Move n bytes from d in data to s in stack. *
492 * st_mvs(): The intention is to copy the contents of addresses *
493 * s1, s1+1....s1-(n-1) to addresses s2, s2+1....s2+(n-1). *
494 * All addresses are expected to be in the stack. This condition *
495 * is checked for. The shadow bytes of the bytes to be filled in, *
496 * are marked identical to the source-shadow bytes. *
498 * st_mvd(), dt_mvd() and dt_mvs() act identically (see data.c). *
500 ************************************************************************/
502 st_mvs(s2, s1, n) /* s1 -> s2 */
513 for (i = (int) n; i > 0; i--, s1++, s2++) {
516 stack_loc(s2) = stack_loc(s1);
518 st_sh(s2) = st_sh(s1) & ~SH_PROT;
523 st_mvd(s, d, n) /* d -> s */
534 for (i = (int) n; i > 0; i--, s++, d++) {
536 stack_loc(s) = data_loc(d);
538 st_sh(s) = dt_sh(d) & ~SH_PROT;
543 /************************************************************************
544 * Stack pop division. *
545 ************************************************************************
547 * dppop() - pop a data ptr, return a ptr. *
548 * upop(n) - pop n unsigned bytes, return a long. *
549 * uwpop() - pop wsize unsigned bytes, return a long. *
550 * spop(n) - pop n signed bytes, return a long. *
551 * swpop() - pop wsize signed bytes, return a long. *
552 * pop_dt(d, n) - pop n bytes, store at address d in data. *
553 * popw_dt(d) - pop wsize bytes, store at address d in data. *
554 * pop_st(s, n) - pop n bytes, store at address s in stack. *
555 * popw_st(s) - pop wsize bytes, store at address s in stack. *
556 * fpop() - pop a floating point number. *
557 * wpop() - pop a signed word, don't care about any type. *
559 ************************************************************************/
567 LOG(("@s7 dppop(), return: %lu", p));
571 unsigned long upop(n)
574 register unsigned long l;
577 decSP(max(n, wsize));
578 LOG(("@s7 upop(), return: %lu", l));
582 unsigned long uwpop()
584 register unsigned long l;
588 LOG(("@s7 uwpop(), return: %lu", l));
598 decSP(max(n, wsize));
599 LOG(("@s7 spop(), return: %ld", l));
609 LOG(("@s7 swpop(), return: %ld", l));
618 dt_stn(d, (long) upop(n), n);
628 dt_mvs(d, SP, wsize);
637 st_stn(s, (long) upop(n), n);
647 st_mvs(s, SP, wsize);
672 /************************************************************************
673 * Stack push division. *
674 ************************************************************************
676 * dppush(p) - push a data ptr, load from p. *
677 * wpush(l) - push a word, load from l. *
678 * npush(l, n) - push n bytes, load from l. *
679 * push_dt(d, n) - push n bytes, load from address d in data. *
680 * pushw_dt(d) - push wsize bytes, load from address d in data.*
681 * push_st(s, n) - push n bytes, load from address s in stack. *
682 * pushw_st(s) - push wsize bytes, load from address s in stack.*
683 * fpush(f, n) - push a floating point number, of size n. *
685 ************************************************************************/
707 if (n == 1) l &= MASK1;
708 else if (n == 2) l &= MASK2;
722 npush((long) dt_ldu(d, n), n);
734 st_mvd(SP, d, wsize);
742 npush((long) st_ldu(s, n), n);
754 st_mvs(SP, s, wsize);
769 PRIVATE warn_stbits(addr, n)
773 register int or_bits = 0;
774 register int and_bits = 0xff;
777 or_bits |= st_sh(addr);
778 and_bits &= st_sh(addr);
782 if (or_bits != and_bits) {
783 /* no use trying to diagnose */
784 warningcont(WWASMISC);
788 warningcont(WWASUND);
789 if (or_bits & SH_INT)
790 warningcont(WWASINT);
791 if (or_bits & SH_FLOAT)
792 warningcont(WWASFLOAT);
793 if (or_bits & SH_DATAP)
794 warningcont(WWASDATAP);
795 if (or_bits & SH_INSP)
796 warningcont(WWASINSP);