stack.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. /*
  2. Stack manipulation
  3. */
  4. /* $Header$ */
  5. #include <stdio.h>
  6. #include <em_abs.h>
  7. #include "logging.h"
  8. #include "nofloat.h"
  9. #include "global.h"
  10. #include "log.h"
  11. #include "warn.h"
  12. #include "trap.h"
  13. #include "alloc.h"
  14. #include "memdirect.h"
  15. #include "mem.h"
  16. #include "shadow.h"
  17. #include "rsb.h"
  18. #define STACKSIZE 1000L /* initial stack size */
  19. extern size maxstack; /* from main.c */
  20. #ifdef LOGGING
  21. char *stack_sh; /* stadowbytes */
  22. #endif LOGGING
  23. PRIVATE warn_stbits();
  24. init_stack() {
  25. ML = max_addr; /* set Memory Limit */
  26. SP = ML + 1; /* initialize Stack Pointer */
  27. SL = ML + 1; /* initialize Stack Limit */
  28. LB = ML + 1; /* initialize Local Base */
  29. AB = ML + 1; /* initialize Actual Base */
  30. SL = ML + 1 - STACKSIZE; /* initialize Stack Limit */
  31. stack = Malloc(STACKSIZE, "stack space");
  32. #ifdef LOGGING
  33. stack_sh = Malloc(STACKSIZE, "shadowspace for stack");
  34. st_clear_area(ML, SL);
  35. #endif LOGGING
  36. }
  37. /************************************************************************
  38. * EM-register division. *
  39. ************************************************************************
  40. * *
  41. * newSP(p) - check and adjust StackPointer. *
  42. * newLB(p) - check and adjust Local Base and Actual Base *
  43. * *
  44. ************************************************************************/
  45. newSP(ap)
  46. ptr ap;
  47. {
  48. register ptr p = ap;
  49. LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
  50. if (LB < p) {
  51. wtrap(WSPGTLB, ESTACK);
  52. }
  53. if (p < HP) {
  54. wtrap(WSPINHEAP, ESTACK);
  55. }
  56. if (!is_aligned(p, wsize)) {
  57. wtrap(WSPODD, ESTACK);
  58. }
  59. if (maxstack) {
  60. /* more than allowed on command line */
  61. if (ML - p > maxstack) {
  62. warning(WESTACK);
  63. trap(ESTACK);
  64. }
  65. }
  66. if (p < SL) {
  67. /* extend stack space */
  68. register size stacksize = ML + 1 - p;
  69. stacksize = allocfrac(stacksize);
  70. SL = ML + 1 - stacksize;
  71. stack = Realloc(stack, (size)(stacksize), "stack space");
  72. #ifdef LOGGING
  73. stack_sh = Realloc(stack_sh, (size)(stacksize),
  74. "shadowspace for stack");
  75. #endif LOGGING
  76. }
  77. #ifdef LOGGING
  78. if (!in_stack(p)) {
  79. st_clear_area(SP - 1, p);
  80. }
  81. #endif LOGGING
  82. SP = p;
  83. }
  84. newLB(p)
  85. ptr p;
  86. {
  87. if (!in_stack(p)) {
  88. wtrap(WLBOUT, ESTACK);
  89. }
  90. if (!is_aligned(p, wsize)) {
  91. wtrap(WLBODD, ESTACK);
  92. }
  93. if (!is_LB(p)) {
  94. wtrap(WLBRSB, ESTACK);
  95. }
  96. LB = p;
  97. AB = LB + rsbsize;
  98. }
  99. /************************************************************************
  100. * Stack store division. *
  101. ************************************************************************
  102. * *
  103. * st_stdp(addr, p) - STore Data Pointer. *
  104. * st_stip(addr, p) - STore Instruction Pointer. *
  105. * st_stn(addr, l, n) - STore N byte integer. *
  106. * st_stf(addr, f, n) - STore Floating point number. *
  107. * *
  108. ************************************************************************/
  109. st_stdp(addr, ap)
  110. ptr addr, ap;
  111. {
  112. register int i;
  113. register long p = (long) ap;
  114. LOG(("@s6 st_stdp(%lu, %lu)", addr, p));
  115. ch_in_stack(addr, psize);
  116. ch_aligned(addr, wsize);
  117. for (i = 0; i < (int) psize; i++) {
  118. ch_st_prot(addr + i);
  119. stack_loc(addr + i) = (char) (p);
  120. st_dp(addr + i);
  121. p = p>>8;
  122. }
  123. }
  124. st_stip(addr, ap)
  125. ptr addr, ap;
  126. {
  127. register int i;
  128. register long p = (long) ap;
  129. LOG(("@s6 st_stip(%lu, %lu)", addr, p));
  130. ch_in_stack(addr, psize);
  131. ch_aligned(addr, wsize);
  132. for (i = 0; i < (int) psize; i++) {
  133. ch_st_prot(addr + i);
  134. stack_loc(addr + i) = (char) (p);
  135. st_ip(addr + i);
  136. p = p>>8;
  137. }
  138. }
  139. st_stn(addr, al, n)
  140. ptr addr;
  141. long al;
  142. size n;
  143. {
  144. register int i;
  145. register long l = al;
  146. LOG(("@s6 st_stn(%lu, %ld, %lu)", addr, l, n));
  147. ch_in_stack(addr, n);
  148. ch_aligned(addr, n);
  149. /* store the bytes */
  150. for (i = 0; i < (int) n; i++) {
  151. ch_st_prot(addr + i);
  152. stack_loc(addr + i) = (char) l;
  153. #ifdef LOGGING
  154. if (al == 0 && n == psize) {
  155. /* a psize zero, ambiguous */
  156. st_sh(addr + i) = (SH_INT|SH_DATAP);
  157. }
  158. else {
  159. st_sh(addr + i) = SH_INT;
  160. }
  161. #endif LOGGING
  162. l = l>>8;
  163. }
  164. }
  165. #ifndef NOFLOAT
  166. st_stf(addr, f, n)
  167. ptr addr;
  168. double f;
  169. size n;
  170. {
  171. register char *cp = (char *) &f;
  172. register int i;
  173. LOG(("@s6 st_stf(%lu, %g, %lu)", addr, f, n));
  174. ch_in_stack(addr, n);
  175. ch_aligned(addr, wsize);
  176. for (i = 0; i < (int) n; i++) {
  177. ch_st_prot(addr + i);
  178. stack_loc(addr + i) = *(cp++);
  179. st_fl(addr + i);
  180. }
  181. }
  182. #endif NOFLOAT
  183. /************************************************************************
  184. * Stack load division. *
  185. ************************************************************************
  186. * *
  187. * st_lddp(addr) - LoaD Data Pointer from stack. *
  188. * st_ldip(addr) - LoaD Instruction Pointer from stack. *
  189. * st_ldu(addr, n) - LoaD n Unsigned bytes from stack. *
  190. * st_lds(addr, n) - LoaD n Signed bytes from stack. *
  191. * st_ldf(addr, n) - LoaD Floating point number from stack. *
  192. * *
  193. ************************************************************************/
  194. ptr st_lddp(addr)
  195. ptr addr;
  196. {
  197. register ptr p;
  198. LOG(("@s6 st_lddp(%lu)", addr));
  199. ch_in_stack(addr, psize);
  200. ch_aligned(addr, wsize);
  201. #ifdef LOGGING
  202. if (!is_st_set(addr, psize, SH_DATAP)) {
  203. warning(WLDPEXP);
  204. warn_stbits(addr, psize);
  205. }
  206. #endif LOGGING
  207. p = p_in_stack(addr);
  208. LOG(("@s6 st_lddp() returns %lu", p));
  209. return (p);
  210. }
  211. ptr st_ldip(addr)
  212. ptr addr;
  213. {
  214. register ptr p;
  215. LOG(("@s6 st_ldip(%lu)", addr));
  216. ch_in_stack(addr, psize);
  217. ch_aligned(addr, wsize);
  218. #ifdef LOGGING
  219. if (!is_st_set(addr, psize, SH_INSP)) {
  220. warning(WLIPEXP);
  221. warn_stbits(addr, psize);
  222. }
  223. #endif LOGGING
  224. p = p_in_stack(addr);
  225. LOG(("@s6 st_ldip() returns %lu", p));
  226. return (p);
  227. }
  228. unsigned long st_ldu(addr, n)
  229. ptr addr;
  230. size n;
  231. {
  232. register int i;
  233. register unsigned long u = 0;
  234. LOG(("@s6 st_ldu(%lu, %lu)", addr, n));
  235. ch_in_stack(addr, n);
  236. ch_aligned(addr, n);
  237. #ifdef LOGGING
  238. if (!is_st_set(addr, n, SH_INT)) {
  239. warning(n == 1 ? WLCEXP : WLIEXP);
  240. warn_stbits(addr, n);
  241. }
  242. #endif LOGGING
  243. for (i = (int) n-1; i >= 0; i--) {
  244. u = (u<<8) | (btou(stack_loc(addr + i)));
  245. }
  246. LOG(("@s6 st_ldu() returns %ld", u));
  247. return (u);
  248. }
  249. long st_lds(addr, n)
  250. ptr addr;
  251. size n;
  252. {
  253. register int i;
  254. register long l;
  255. LOG(("@s6 st_lds(%lu, %lu)", addr, n));
  256. ch_in_stack(addr, n);
  257. ch_aligned(addr, n);
  258. #ifdef LOGGING
  259. if (!is_st_set(addr, n, SH_INT)) {
  260. warning(n == 1 ? WLCEXP : WLIEXP);
  261. warn_stbits(addr, n);
  262. }
  263. #endif LOGGING
  264. l = btos(stack_loc(addr + n - 1));
  265. for (i = n - 2; i >= 0; i--) {
  266. l = (l<<8) | btol(stack_loc(addr + i));
  267. }
  268. LOG(("@s6 st_lds() returns %ld", l));
  269. return (l);
  270. }
  271. #ifndef NOFLOAT
  272. double st_ldf(addr, n)
  273. ptr addr;
  274. size n;
  275. {
  276. double f = 0.0;
  277. register char *cp = (char *) &f;
  278. register int i;
  279. LOG(("@s6 st_ldf(%lu, %lu)", addr, n));
  280. ch_in_stack(addr, n);
  281. ch_aligned(addr, wsize);
  282. #ifdef LOGGING
  283. if (!is_st_set(addr, n, SH_FLOAT)) {
  284. warning(WLFEXP);
  285. warn_stbits(addr, n);
  286. }
  287. #endif LOGGING
  288. for (i = 0; i < (int) n; i++) {
  289. *(cp++) = stack_loc(addr + i);
  290. }
  291. return (f);
  292. }
  293. #endif NOFLOAT
  294. /************************************************************************
  295. * Stack move division *
  296. ************************************************************************
  297. * *
  298. * st_mvs(s2, s1, n) - Move n bytes in stack from s1 to s2. *
  299. * st_mvd(s, d, n) - Move n bytes from d in data to s in stack. *
  300. * *
  301. * st_mvs(): The intention is to copy the contents of addresses *
  302. * s1, s1+1....s1-(n-1) to addresses s2, s2+1....s2+(n-1). *
  303. * All addresses are expected to be in the stack. This condition *
  304. * is checked for. The shadow bytes of the bytes to be filled in, *
  305. * are marked identical to the source-shadow bytes. *
  306. * *
  307. * st_mvd(), dt_mvd() and dt_mvs() act identically (see data.c). *
  308. * *
  309. ************************************************************************/
  310. st_mvs(s2, s1, n) /* s1 -> s2 */
  311. ptr s2, s1;
  312. size n;
  313. {
  314. register int i;
  315. ch_in_stack(s1, n);
  316. ch_aligned(s1, wsize);
  317. ch_in_stack(s2, n);
  318. ch_aligned(s2, wsize);
  319. for (i = 0; i < (int) n; i++) {
  320. ch_st_prot(s2 + i);
  321. ch_st_prot(s1 + i);
  322. stack_loc(s2 + i) = stack_loc(s1 + i);
  323. #ifdef LOGGING
  324. st_sh(s2 + i) = st_sh(s1 + i) & ~SH_PROT;
  325. #endif LOGGING
  326. }
  327. }
  328. st_mvd(s, d, n) /* d -> s */
  329. ptr s, d;
  330. size n;
  331. {
  332. register int i;
  333. ch_in_data(d, n);
  334. ch_aligned(d, wsize);
  335. ch_in_stack(s, n);
  336. ch_aligned(s, wsize);
  337. for (i = 0; i < (int) n; i++) {
  338. ch_st_prot(s + i);
  339. stack_loc(s + i) = data_loc(d + i);
  340. #ifdef LOGGING
  341. st_sh(s + i) = dt_sh(d + i) & ~SH_PROT;
  342. #endif LOGGING
  343. }
  344. }
  345. /************************************************************************
  346. * Stack pop division. *
  347. ************************************************************************
  348. * *
  349. * dppop() - pop a data ptr, return a ptr. *
  350. * upop(n) - pop n unsigned bytes, return a long. *
  351. * spop(n) - pop n signed bytes, return a long. *
  352. * pop_dt(d, n) - pop n bytes, store at address d in data. *
  353. * pop_st(s, n) - pop n bytes, store at address s in stack. *
  354. * fpop() - pop a floating point number. *
  355. * wpop() - pop a signed word, don't care about any type. *
  356. * *
  357. ************************************************************************/
  358. ptr dppop()
  359. {
  360. register ptr p;
  361. p = st_lddp(SP);
  362. st_dec(psize);
  363. LOG(("@s7 dppop(), return: %lu", p));
  364. return (p);
  365. }
  366. unsigned long upop(n)
  367. size n;
  368. {
  369. register unsigned long l;
  370. l = st_ldu(SP, n);
  371. st_dec(max(n, wsize));
  372. LOG(("@s7 upop(), return: %lu", l));
  373. return (l);
  374. }
  375. long spop(n)
  376. size n;
  377. {
  378. register long l;
  379. l = st_lds(SP, n);
  380. st_dec(max(n, wsize));
  381. LOG(("@s7 spop(), return: %ld", l));
  382. return (l);
  383. }
  384. pop_dt(d, n)
  385. ptr d;
  386. size n;
  387. {
  388. if (n < wsize)
  389. dt_stn(d, (long) upop(n), n);
  390. else {
  391. dt_mvs(d, SP, n);
  392. st_dec(n);
  393. }
  394. }
  395. pop_st(s, n)
  396. ptr s;
  397. size n;
  398. {
  399. if (n < wsize)
  400. st_stn(s, (long) upop(n), n);
  401. else {
  402. st_mvs(s, SP, n);
  403. st_dec(n);
  404. }
  405. }
  406. #ifndef NOFLOAT
  407. double fpop(n)
  408. size n;
  409. {
  410. double d;
  411. d = st_ldf(SP, n);
  412. st_dec(n);
  413. return (d);
  414. }
  415. #endif NOFLOAT
  416. long wpop()
  417. {
  418. register long l;
  419. l = w_in_stack(SP);
  420. st_dec(wsize);
  421. return (l);
  422. }
  423. /************************************************************************
  424. * Stack push division. *
  425. ************************************************************************
  426. * *
  427. * dppush(p) - push a data ptr, load from p. *
  428. * npush(l, n) - push n bytes, load from l. *
  429. * push_dt(d, n) - push n bytes, load from address d in data. *
  430. * push_st(s, n) - push n bytes, load from address s in stack. *
  431. * fpush(f, n) - push a floating point number, of size n. *
  432. * *
  433. ************************************************************************/
  434. dppush(p)
  435. ptr p;
  436. {
  437. st_inc(psize);
  438. st_stdp(SP, p);
  439. }
  440. npush(l, n)
  441. long l;
  442. size n;
  443. {
  444. st_inc(max(n, wsize));
  445. if (n == 1)
  446. l &= MASK1;
  447. else
  448. if (n == 2)
  449. l &= MASK2;
  450. st_stn(SP, l, max(n, wsize));
  451. }
  452. push_dt(d, n)
  453. ptr d;
  454. size n;
  455. {
  456. if (n < wsize) {
  457. npush((long) dt_ldu(d, n), n);
  458. }
  459. else {
  460. st_inc(n);
  461. st_mvd(SP, d, n);
  462. }
  463. }
  464. push_st(s, n)
  465. ptr s;
  466. size n;
  467. {
  468. if (n < wsize) {
  469. npush((long) st_ldu(s, n), n);
  470. }
  471. else {
  472. st_inc(n);
  473. st_mvs(SP, s, n);
  474. }
  475. }
  476. #ifndef NOFLOAT
  477. fpush(f, n)
  478. double f;
  479. size n;
  480. {
  481. st_inc(n);
  482. st_stf(SP, f, n);
  483. }
  484. #endif NOFLOAT
  485. #ifdef LOGGING
  486. PRIVATE warn_stbits(addr, n)
  487. ptr addr;
  488. size n;
  489. {
  490. register int or_bits = 0;
  491. register int and_bits = 0xff;
  492. while (n--) {
  493. or_bits |= st_sh(addr);
  494. and_bits &= st_sh(addr);
  495. addr++;
  496. }
  497. if (or_bits != and_bits) {
  498. /* no use trying to diagnose */
  499. warningcont(WWASMISC);
  500. return;
  501. }
  502. if (or_bits == 0)
  503. warningcont(WWASUND);
  504. if (or_bits & SH_INT)
  505. warningcont(WWASINT);
  506. if (or_bits & SH_FLOAT)
  507. warningcont(WWASFLOAT);
  508. if (or_bits & SH_DATAP)
  509. warningcont(WWASDATAP);
  510. if (or_bits & SH_INSP)
  511. warningcont(WWASINSP);
  512. }
  513. #endif LOGGING