stack.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. /*
  2. Stack manipulation
  3. */
  4. /* $Id$ */
  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. char *stackML_sh; /* speed up access of stadowbytes */
  23. #endif /* LOGGING */
  24. PRIVATE warn_stbits();
  25. init_stack() {
  26. ML = max_addr; /* set Memory Limit */
  27. SP = ML + 1; /* initialize Stack Pointer */
  28. SL = ML + 1; /* initialize Stack Limit */
  29. LB = ML + 1; /* initialize Local Base */
  30. AB = ML + 1; /* initialize Actual Base */
  31. SL = ML + 1 - STACKSIZE; /* initialize Stack Limit */
  32. stack = Malloc(STACKSIZE, "stack space");
  33. stackML = stack + ML;
  34. #ifdef LOGGING
  35. stack_sh = Malloc(STACKSIZE, "shadowspace for stack");
  36. stackML_sh = stack_sh + ML;
  37. st_clear_area(ML, SL);
  38. #endif /* LOGGING */
  39. }
  40. /************************************************************************
  41. * EM-register division. *
  42. ************************************************************************
  43. * *
  44. * newSP(p) - check and adjust StackPointer. *
  45. * incSP(n) - increment stack pointer. n already checked *
  46. * decSP(n) - decrement stack pointer. n already checked *
  47. * newLB(p) - check and adjust Local Base and Actual Base *
  48. * *
  49. ************************************************************************/
  50. newSP(ap)
  51. ptr ap;
  52. {
  53. register ptr p = ap;
  54. LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
  55. if (LB < p) {
  56. wtrap(WSPGTLB, ESTACK);
  57. }
  58. if (!is_wordaligned(p)) {
  59. wtrap(WSPODD, ESTACK);
  60. }
  61. if (p < SP) {
  62. if (p < HP) {
  63. wtrap(WSPINHEAP, ESTACK);
  64. }
  65. if (maxstack) {
  66. /* more than allowed on command line */
  67. if (ML - p > maxstack) {
  68. warning(WESTACK);
  69. trap(ESTACK);
  70. }
  71. }
  72. if (p < SL) {
  73. /* extend stack space */
  74. register size stacksize = ML + 1 - p;
  75. stacksize = allocfrac(stacksize);
  76. SL = ML + 1 - stacksize;
  77. stack = Realloc(stack, (size)(stacksize), "stack space");
  78. stackML = stack + ML;
  79. #ifdef LOGGING
  80. stack_sh = Realloc(stack_sh, (size)(stacksize),
  81. "shadowspace for stack");
  82. stackML_sh = stack_sh + ML;
  83. #endif /* LOGGING */
  84. }
  85. #ifdef LOGGING
  86. st_clear_area(SP - 1, p);
  87. #endif /* LOGGING */
  88. }
  89. SP = p;
  90. }
  91. incSP(n)
  92. #ifdef LOGGING
  93. register
  94. #endif
  95. size n;
  96. {
  97. register ptr p = SP - n;
  98. if (p < HP || maxstack || p < SL) newSP(p);
  99. else {
  100. LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
  101. #ifdef LOGGING
  102. /* inline version of st_clear_area.
  103. */
  104. SP = p;
  105. {
  106. while (n--) {
  107. st_undef(p);
  108. p++;
  109. }
  110. }
  111. #endif
  112. }
  113. }
  114. decSP(n)
  115. size n;
  116. {
  117. register ptr p = SP + n;
  118. if (LB < p) newSP(p);
  119. else {
  120. LOG(("@s6 newSP(%lu), ML = %lu, SP = %lu", p, ML, SP));
  121. SP = p;
  122. }
  123. }
  124. newLB(p)
  125. ptr p;
  126. {
  127. if (!in_stack(p)) {
  128. wtrap(WLBOUT, ESTACK);
  129. }
  130. if (!is_wordaligned(p)) {
  131. wtrap(WLBODD, ESTACK);
  132. }
  133. if (!is_LB(p)) {
  134. wtrap(WLBRSB, ESTACK);
  135. }
  136. LB = p;
  137. AB = LB + rsbsize;
  138. }
  139. /************************************************************************
  140. * Stack store division. *
  141. ************************************************************************
  142. * *
  143. * st_stdp(addr, p) - STore Data Pointer. *
  144. * st_stip(addr, p) - STore Instruction Pointer. *
  145. * st_stn(addr, l, n) - STore N byte integer. *
  146. * st_stw(addr, l) - STore wordsize integer. *
  147. * st_stf(addr, f, n) - STore Floating point number. *
  148. * *
  149. ************************************************************************/
  150. st_stdp(addr, ap)
  151. register ptr addr;
  152. ptr ap;
  153. {
  154. register int i;
  155. register long p = (long) ap;
  156. LOG(("@s6 st_stdp(%lu, %lu)", addr, p));
  157. ch_in_stack(addr, psize);
  158. ch_wordaligned(addr);
  159. for (i = (int) psize; i > 0; i--, addr++) {
  160. ch_st_prot(addr);
  161. stack_loc(addr) = (char) (p);
  162. st_dp(addr);
  163. p = p>>8;
  164. }
  165. }
  166. st_stip(addr, ap)
  167. register ptr addr;
  168. ptr ap;
  169. {
  170. register int i;
  171. register long p = (long) ap;
  172. LOG(("@s6 st_stip(%lu, %lu)", addr, p));
  173. ch_in_stack(addr, psize);
  174. ch_wordaligned(addr);
  175. for (i = (int) psize; i > 0; i--, addr++) {
  176. ch_st_prot(addr);
  177. stack_loc(addr) = (char) (p);
  178. st_ip(addr);
  179. p = p>>8;
  180. }
  181. }
  182. st_stn(addr, al, n)
  183. register ptr addr;
  184. long al;
  185. size n;
  186. {
  187. register int i;
  188. register long l = al;
  189. #ifdef LOGGING
  190. /* a psize zero is ambiguous */
  191. int sh_flags = (l == 0 && n == psize) ? (SH_INT|SH_DATAP) : SH_INT;
  192. #endif
  193. LOG(("@s6 st_stn(%lu, %ld, %lu)", addr, l, n));
  194. ch_in_stack(addr, n);
  195. ch_aligned(addr, n);
  196. /* store the bytes */
  197. for (i = (int) n; i > 0; i--, addr++) {
  198. ch_st_prot(addr);
  199. stack_loc(addr) = (char) l;
  200. #ifdef LOGGING
  201. st_sh(addr) = sh_flags;
  202. #endif /* LOGGING */
  203. l = l>>8;
  204. }
  205. }
  206. st_stw(addr, al)
  207. register ptr addr;
  208. long al;
  209. {
  210. register int i;
  211. register long l = al;
  212. #ifdef LOGGING
  213. /* a psize zero is ambiguous */
  214. int sh_flags = (l == 0 && wsize == psize) ? (SH_INT|SH_DATAP) : SH_INT;
  215. #endif
  216. LOG(("@s6 st_stw(%lu, %ld)", addr, l));
  217. ch_w_in_stack(addr);
  218. ch_wordaligned(addr);
  219. /* store the bytes */
  220. for (i = (int) wsize; i > 0; i--, addr++) {
  221. ch_st_prot(addr);
  222. stack_loc(addr) = (char) l;
  223. #ifdef LOGGING
  224. st_sh(addr) = sh_flags;
  225. #endif /* LOGGING */
  226. l = l>>8;
  227. }
  228. }
  229. #ifndef NOFLOAT
  230. st_stf(addr, f, n)
  231. register ptr addr;
  232. double f;
  233. size n;
  234. {
  235. register char *cp = (char *) &f;
  236. float fl;
  237. register int i;
  238. LOG(("@s6 st_stf(%lu, %g, %lu)", addr, f, n));
  239. ch_in_stack(addr, n);
  240. ch_wordaligned(addr);
  241. if ((int) n == 4) {
  242. fl = f;
  243. cp = (char *) &fl;
  244. }
  245. for (i = (int) n; i > 0; i--, addr++) {
  246. ch_st_prot(addr);
  247. stack_loc(addr) = *(cp++);
  248. st_fl(addr);
  249. }
  250. }
  251. #endif /* NOFLOAT */
  252. /************************************************************************
  253. * Stack load division. *
  254. ************************************************************************
  255. * *
  256. * st_lddp(addr) - LoaD Data Pointer from stack. *
  257. * st_ldip(addr) - LoaD Instruction Pointer from stack. *
  258. * st_ldu(addr, n) - LoaD n Unsigned bytes from stack. *
  259. * st_lduw(addr) - LoaD wsize Unsigned bytes from stack. *
  260. * st_lds(addr, n) - LoaD n Signed bytes from stack. *
  261. * st_ldsw(addr) - LoaD wsize Signed bytes from stack. *
  262. * st_ldf(addr, n) - LoaD Floating point number from stack. *
  263. * *
  264. ************************************************************************/
  265. ptr st_lddp(addr)
  266. register ptr addr;
  267. {
  268. register ptr p;
  269. LOG(("@s6 st_lddp(%lu)", addr));
  270. ch_in_stack(addr, psize);
  271. ch_wordaligned(addr);
  272. #ifdef LOGGING
  273. if (!is_st_set(addr, psize, SH_DATAP)) {
  274. warning(WLDPEXP);
  275. warn_stbits(addr, psize);
  276. }
  277. #endif /* LOGGING */
  278. p = p_in_stack(addr);
  279. LOG(("@s6 st_lddp() returns %lu", p));
  280. return (p);
  281. }
  282. ptr st_ldip(addr)
  283. register ptr addr;
  284. {
  285. register ptr p;
  286. LOG(("@s6 st_ldip(%lu)", addr));
  287. ch_in_stack(addr, psize);
  288. ch_wordaligned(addr);
  289. #ifdef LOGGING
  290. if (!is_st_set(addr, psize, SH_INSP)) {
  291. warning(WLIPEXP);
  292. warn_stbits(addr, psize);
  293. }
  294. #endif /* LOGGING */
  295. p = p_in_stack(addr);
  296. LOG(("@s6 st_ldip() returns %lu", p));
  297. return (p);
  298. }
  299. unsigned long st_ldu(addr, n)
  300. register ptr addr;
  301. size n;
  302. {
  303. register int i;
  304. register unsigned long u = 0;
  305. LOG(("@s6 st_ldu(%lu, %lu)", addr, n));
  306. ch_in_stack(addr, n);
  307. ch_aligned(addr, n);
  308. #ifdef LOGGING
  309. if (!is_st_set(addr, n, SH_INT)) {
  310. warning(n == 1 ? WLCEXP : WLIEXP);
  311. warn_stbits(addr, n);
  312. }
  313. #endif /* LOGGING */
  314. addr += n-1;
  315. for (i = (int) n-1; i >= 0; i--, addr--) {
  316. u = (u<<8) | (btou(stack_loc(addr)));
  317. }
  318. LOG(("@s6 st_ldu() returns %ld", u));
  319. return (u);
  320. }
  321. unsigned long st_lduw(addr)
  322. register ptr addr;
  323. {
  324. register int i;
  325. register unsigned long u = 0;
  326. LOG(("@s6 st_lduw(%lu)", addr));
  327. ch_w_in_stack(addr);
  328. ch_wordaligned(addr);
  329. #ifdef LOGGING
  330. if (!is_st_set(addr, wsize, SH_INT)) {
  331. warning(WLIEXP);
  332. warn_stbits(addr, wsize);
  333. }
  334. #endif /* LOGGING */
  335. addr += wsize - 1;
  336. for (i = (int) wsize-1; i >= 0; i--, addr--) {
  337. u = (u<<8) | (btou(stack_loc(addr)));
  338. }
  339. LOG(("@s6 st_lduw() returns %ld", u));
  340. return (u);
  341. }
  342. long st_lds(addr, n)
  343. register ptr addr;
  344. size n;
  345. {
  346. register int i;
  347. register long l;
  348. LOG(("@s6 st_lds(%lu, %lu)", addr, n));
  349. ch_in_stack(addr, n);
  350. ch_aligned(addr, n);
  351. #ifdef LOGGING
  352. if (!is_st_set(addr, n, SH_INT)) {
  353. warning(n == 1 ? WLCEXP : WLIEXP);
  354. warn_stbits(addr, n);
  355. }
  356. #endif /* LOGGING */
  357. addr += n - 2;
  358. l = btos(stack_loc(addr + 1));
  359. for (i = n - 2; i >= 0; i--, addr--) {
  360. l = (l<<8) | btol(stack_loc(addr));
  361. }
  362. LOG(("@s6 st_lds() returns %ld", l));
  363. return (l);
  364. }
  365. long st_ldsw(addr)
  366. register ptr addr;
  367. {
  368. register int i;
  369. register long l;
  370. LOG(("@s6 st_ldsw(%lu)", addr));
  371. ch_w_in_stack(addr);
  372. ch_wordaligned(addr);
  373. #ifdef LOGGING
  374. if (!is_st_set(addr, wsize, SH_INT)) {
  375. warning(WLIEXP);
  376. warn_stbits(addr, wsize);
  377. }
  378. #endif /* LOGGING */
  379. addr += wsize - 2;
  380. l = btos(stack_loc(addr+1));
  381. for (i = wsize - 2; i >= 0; i--, addr--) {
  382. l = (l<<8) | btol(stack_loc(addr));
  383. }
  384. LOG(("@s6 st_ldsw() returns %ld", l));
  385. return (l);
  386. }
  387. #ifndef NOFLOAT
  388. double st_ldf(addr, n)
  389. register ptr addr;
  390. size n;
  391. {
  392. double f;
  393. float fl;
  394. register char *cp;
  395. register int i;
  396. LOG(("@s6 st_ldf(%lu, %lu)", addr, n));
  397. if ((int)n == 4) {
  398. cp = (char *) &fl;
  399. }
  400. else {
  401. cp = (char *) &f;
  402. }
  403. ch_in_stack(addr, n);
  404. ch_wordaligned(addr);
  405. #ifdef LOGGING
  406. if (!is_st_set(addr, n, SH_FLOAT)) {
  407. warning(WLFEXP);
  408. warn_stbits(addr, n);
  409. }
  410. #endif /* LOGGING */
  411. for (i = (int) n; i > 0; i--, addr++) {
  412. *(cp++) = stack_loc(addr);
  413. }
  414. if ((int)n == 4) {
  415. f = fl;
  416. }
  417. return (f);
  418. }
  419. #endif /* NOFLOAT */
  420. /************************************************************************
  421. * Stack move division *
  422. ************************************************************************
  423. * *
  424. * st_mvs(s2, s1, n) - Move n bytes in stack from s1 to s2. *
  425. * st_mvd(s, d, n) - Move n bytes from d in data to s in stack. *
  426. * *
  427. * st_mvs(): The intention is to copy the contents of addresses *
  428. * s1, s1+1....s1-(n-1) to addresses s2, s2+1....s2+(n-1). *
  429. * All addresses are expected to be in the stack. This condition *
  430. * is checked for. The shadow bytes of the bytes to be filled in, *
  431. * are marked identical to the source-shadow bytes. *
  432. * *
  433. * st_mvd(), dt_mvd() and dt_mvs() act identically (see data.c). *
  434. * *
  435. ************************************************************************/
  436. st_mvs(s2, s1, n) /* s1 -> s2 */
  437. register ptr s2, s1;
  438. size n;
  439. {
  440. register int i;
  441. ch_in_stack(s1, n);
  442. ch_wordaligned(s1);
  443. ch_in_stack(s2, n);
  444. ch_wordaligned(s2);
  445. for (i = (int) n; i > 0; i--, s1++, s2++) {
  446. ch_st_prot(s2);
  447. ch_st_prot(s1);
  448. stack_loc(s2) = stack_loc(s1);
  449. #ifdef LOGGING
  450. st_sh(s2) = st_sh(s1) & ~SH_PROT;
  451. #endif /* LOGGING */
  452. }
  453. }
  454. st_mvd(s, d, n) /* d -> s */
  455. register ptr s, d;
  456. size n;
  457. {
  458. register int i;
  459. ch_in_data(d, n);
  460. ch_wordaligned(d);
  461. ch_in_stack(s, n);
  462. ch_wordaligned(s);
  463. for (i = (int) n; i > 0; i--, s++, d++) {
  464. ch_st_prot(s);
  465. stack_loc(s) = data_loc(d);
  466. #ifdef LOGGING
  467. st_sh(s) = dt_sh(d) & ~SH_PROT;
  468. #endif /* LOGGING */
  469. }
  470. }
  471. /************************************************************************
  472. * Stack pop division. *
  473. ************************************************************************
  474. * *
  475. * dppop() - pop a data ptr, return a ptr. *
  476. * upop(n) - pop n unsigned bytes, return a long. *
  477. * uwpop() - pop wsize unsigned bytes, return a long. *
  478. * spop(n) - pop n signed bytes, return a long. *
  479. * swpop() - pop wsize signed bytes, return a long. *
  480. * pop_dt(d, n) - pop n bytes, store at address d in data. *
  481. * popw_dt(d) - pop wsize bytes, store at address d in data. *
  482. * pop_st(s, n) - pop n bytes, store at address s in stack. *
  483. * popw_st(s) - pop wsize bytes, store at address s in stack. *
  484. * fpop() - pop a floating point number. *
  485. * wpop() - pop a signed word, don't care about any type. *
  486. * *
  487. ************************************************************************/
  488. ptr dppop()
  489. {
  490. register ptr p;
  491. p = st_lddp(SP);
  492. decSP(psize);
  493. LOG(("@s7 dppop(), return: %lu", p));
  494. return (p);
  495. }
  496. unsigned long upop(n)
  497. size n;
  498. {
  499. register unsigned long l;
  500. l = st_ldu(SP, n);
  501. decSP(max(n, wsize));
  502. LOG(("@s7 upop(), return: %lu", l));
  503. return (l);
  504. }
  505. unsigned long uwpop()
  506. {
  507. register unsigned long l;
  508. l = st_lduw(SP);
  509. decSP(wsize);
  510. LOG(("@s7 uwpop(), return: %lu", l));
  511. return (l);
  512. }
  513. long spop(n)
  514. size n;
  515. {
  516. register long l;
  517. l = st_lds(SP, n);
  518. decSP(max(n, wsize));
  519. LOG(("@s7 spop(), return: %ld", l));
  520. return (l);
  521. }
  522. long swpop()
  523. {
  524. register long l;
  525. l = st_ldsw(SP);
  526. decSP(wsize);
  527. LOG(("@s7 swpop(), return: %ld", l));
  528. return (l);
  529. }
  530. pop_dt(d, n)
  531. ptr d;
  532. size n;
  533. {
  534. if (n < wsize)
  535. dt_stn(d, (long) upop(n), n);
  536. else {
  537. dt_mvs(d, SP, n);
  538. decSP(n);
  539. }
  540. }
  541. popw_dt(d)
  542. ptr d;
  543. {
  544. dt_mvs(d, SP, wsize);
  545. decSP(wsize);
  546. }
  547. pop_st(s, n)
  548. ptr s;
  549. size n;
  550. {
  551. if (n < wsize)
  552. st_stn(s, (long) upop(n), n);
  553. else {
  554. st_mvs(s, SP, n);
  555. decSP(n);
  556. }
  557. }
  558. popw_st(s)
  559. ptr s;
  560. {
  561. st_mvs(s, SP, wsize);
  562. decSP(wsize);
  563. }
  564. #ifndef NOFLOAT
  565. double fpop(n)
  566. size n;
  567. {
  568. double d;
  569. d = st_ldf(SP, n);
  570. decSP(n);
  571. return (d);
  572. }
  573. #endif /* NOFLOAT */
  574. long wpop()
  575. {
  576. register long l;
  577. l = w_in_stack(SP);
  578. decSP(wsize);
  579. return (l);
  580. }
  581. /************************************************************************
  582. * Stack push division. *
  583. ************************************************************************
  584. * *
  585. * dppush(p) - push a data ptr, load from p. *
  586. * wpush(l) - push a word, load from l. *
  587. * npush(l, n) - push n bytes, load from l. *
  588. * push_dt(d, n) - push n bytes, load from address d in data. *
  589. * pushw_dt(d) - push wsize bytes, load from address d in data.*
  590. * push_st(s, n) - push n bytes, load from address s in stack. *
  591. * pushw_st(s) - push wsize bytes, load from address s in stack.*
  592. * fpush(f, n) - push a floating point number, of size n. *
  593. * *
  594. ************************************************************************/
  595. dppush(p)
  596. ptr p;
  597. {
  598. incSP(psize);
  599. st_stdp(SP, p);
  600. }
  601. wpush(l)
  602. long l;
  603. {
  604. incSP(wsize);
  605. st_stw(SP, l);
  606. }
  607. npush(l, n)
  608. register long l;
  609. register size n;
  610. {
  611. if (n <= wsize) {
  612. incSP(wsize);
  613. if (n == 1) l &= MASK1;
  614. else if (n == 2) l &= MASK2;
  615. st_stw(SP, l);
  616. }
  617. else {
  618. incSP(n);
  619. st_stn(SP, l, n);
  620. }
  621. }
  622. push_dt(d, n)
  623. ptr d;
  624. size n;
  625. {
  626. if (n < wsize) {
  627. npush((long) dt_ldu(d, n), n);
  628. }
  629. else {
  630. incSP(n);
  631. st_mvd(SP, d, n);
  632. }
  633. }
  634. pushw_dt(d)
  635. ptr d;
  636. {
  637. incSP(wsize);
  638. st_mvd(SP, d, wsize);
  639. }
  640. push_st(s, n)
  641. ptr s;
  642. size n;
  643. {
  644. if (n < wsize) {
  645. npush((long) st_ldu(s, n), n);
  646. }
  647. else {
  648. incSP(n);
  649. st_mvs(SP, s, n);
  650. }
  651. }
  652. pushw_st(s)
  653. ptr s;
  654. {
  655. incSP(wsize);
  656. st_mvs(SP, s, wsize);
  657. }
  658. #ifndef NOFLOAT
  659. fpush(f, n)
  660. double f;
  661. size n;
  662. {
  663. incSP(n);
  664. st_stf(SP, f, n);
  665. }
  666. #endif /* NOFLOAT */
  667. #ifdef LOGGING
  668. PRIVATE warn_stbits(addr, n)
  669. register ptr addr;
  670. register size n;
  671. {
  672. register int or_bits = 0;
  673. register int and_bits = 0xff;
  674. while (n--) {
  675. or_bits |= st_sh(addr);
  676. and_bits &= st_sh(addr);
  677. addr++;
  678. }
  679. if (or_bits != and_bits) {
  680. /* no use trying to diagnose */
  681. warningcont(WWASMISC);
  682. return;
  683. }
  684. if (or_bits == 0)
  685. warningcont(WWASUND);
  686. if (or_bits & SH_INT)
  687. warningcont(WWASINT);
  688. if (or_bits & SH_FLOAT)
  689. warningcont(WWASFLOAT);
  690. if (or_bits & SH_DATAP)
  691. warningcont(WWASDATAP);
  692. if (or_bits & SH_INSP)
  693. warningcont(WWASINSP);
  694. }
  695. #endif /* LOGGING */