comm7.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. /* @(#)comm7.c 1.10 */
  2. /*
  3. * miscellaneous
  4. */
  5. #include "comm0.h"
  6. #include "comm1.h"
  7. #include "y.tab.h"
  8. valu_t
  9. load(ip)
  10. register item_t *ip;
  11. {
  12. #ifdef ASLD
  13. register short typ;
  14. typ = ip->i_type & S_TYP;
  15. if ((typ -= S_MIN) < 0) /* S_UND or S_ABS */
  16. return(ip->i_valu);
  17. return(ip->i_valu + sect[typ].s_base);
  18. #else
  19. #ifdef DUK
  20. if ((ip->i_type & S_TYP) == S_UND || (ip->i_type & S_COM)) {
  21. #else DUK
  22. if ((ip->i_type & S_TYP) == S_UND) {
  23. #endif DUK
  24. if (pass == PASS_3) {
  25. if (relonami != 0)
  26. serror("relocation error");
  27. relonami = ip->i_valu+1;
  28. }
  29. return(0);
  30. }
  31. return(ip->i_valu);
  32. #endif
  33. }
  34. store(ip, val)
  35. register item_t *ip;
  36. valu_t val;
  37. {
  38. #ifdef ASLD
  39. register short typ;
  40. typ = ip->i_type & S_TYP;
  41. if ((typ -= S_MIN) >= 0)
  42. val -= sect[typ].s_base;
  43. #else
  44. if ((ip->i_type & S_TYP) == S_UND)
  45. return(0);
  46. #endif
  47. assert(pass != PASS_3 || (ip->i_type & S_VAR) || ip->i_valu == val);
  48. ip->i_valu = val;
  49. return(1);
  50. }
  51. char *
  52. remember(s)
  53. register char *s;
  54. {
  55. register char *p;
  56. register n;
  57. static nleft = 0;
  58. static char *next;
  59. p = s;
  60. n = 0;
  61. do
  62. n++;
  63. while (*p++);
  64. if ((nleft -= n) < 0) {
  65. next = sbrk(MEMINCR);
  66. if ((int) next == -1)
  67. fatal("out of memory");
  68. nleft = (MEMINCR / sizeof(char)) - n;
  69. assert(nleft >= 0);
  70. }
  71. p = next;
  72. while (*p++ = *s++)
  73. ;
  74. s = next;
  75. next = p;
  76. return(s);
  77. }
  78. combine(typ1, typ2, op)
  79. register typ1, typ2;
  80. {
  81. switch (op) {
  82. case '+':
  83. if (typ1 == S_ABS)
  84. return(typ2);
  85. if (typ2 == S_ABS)
  86. return(typ1);
  87. break;
  88. case '-':
  89. if (typ2 == S_ABS)
  90. return(typ1);
  91. if ((typ1 & ~S_DOT) == (typ2 & ~S_DOT) && typ1 != S_UND)
  92. return(S_ABS|S_VAR);
  93. break;
  94. case '>':
  95. if (typ1 == S_ABS && typ2 == S_ABS)
  96. return(S_ABS);
  97. if (
  98. ((typ1 & ~S_DOT) == (typ2 & ~S_DOT) && typ1 != S_UND)
  99. || (typ1 == S_ABS)
  100. || (typ2 == S_ABS)
  101. )
  102. return(S_ABS|S_VAR);
  103. break;
  104. default:
  105. if (typ1 == S_ABS && typ2 == S_ABS)
  106. return(S_ABS);
  107. break;
  108. }
  109. if (pass != PASS_1)
  110. serror("illegal operator");
  111. return(S_UND);
  112. }
  113. #ifdef LISTING
  114. printx(ndig, val)
  115. valu_t val;
  116. {
  117. static char buf[8];
  118. register char *p;
  119. register c, n;
  120. p = buf; n = ndig;
  121. do {
  122. *p++ = (int) val & 017;
  123. val >>= 4;
  124. } while (--n);
  125. do {
  126. c = "0123456789ABCDEF"[*--p];
  127. putchar(c);
  128. } while (p > buf);
  129. return(ndig);
  130. }
  131. #endif
  132. #ifdef LISTING
  133. listline(textline)
  134. {
  135. register c;
  136. if ((listflag & 4) && (c = getc(listfile)) != '\n' && textline) {
  137. if (listcolm >= 24)
  138. printf(" \\\n\t\t\t");
  139. else
  140. do {
  141. putchar('\t');
  142. listcolm += 8;
  143. } while (listcolm < 24);
  144. do {
  145. assert(c != EOF);
  146. putchar(c);
  147. } while ((c = getc(listfile)) != '\n');
  148. }
  149. if (listflag & 7)
  150. putchar('\n');
  151. listeoln = 1;
  152. listcolm = 0;
  153. listflag = listtemp;
  154. }
  155. #endif LISTING
  156. /* ---------- code optimization ---------- */
  157. #ifdef THREE_PASS
  158. small(fitsmall, gain)
  159. {
  160. register bit;
  161. register char *p;
  162. if (DOTSCT == NULL)
  163. nosect();
  164. if (bflag)
  165. return(0);
  166. if ((bit = nbits++) >= BITMAX) {
  167. if (bit != BITMAX)
  168. nbits--; /* prevent wraparound */
  169. else if (pass == PASS_1)
  170. warning("bit table overflow");
  171. return(0);
  172. }
  173. p = &bittab[bit>>3];
  174. bit = 1 << (bit&7);
  175. switch (pass) {
  176. case PASS_1:
  177. return(0);
  178. case PASS_2:
  179. if (fitsmall) {
  180. DOTGAIN += gain;
  181. *p |= bit;
  182. }
  183. return(fitsmall);
  184. case PASS_3:
  185. assert(fitsmall || (*p & bit) == 0);
  186. return(*p & bit);
  187. }
  188. }
  189. #endif
  190. /* ---------- output ---------- */
  191. emit1(arg)
  192. char arg;
  193. {
  194. #ifdef LISTING
  195. if (listeoln) {
  196. if (listflag & 1) {
  197. listcolm += printx(VALWIDTH, DOTVAL);
  198. listcolm++;
  199. putchar(' ');
  200. }
  201. listeoln = 0;
  202. }
  203. if (listflag & 2)
  204. listcolm += printx(2, (valu_t) arg);
  205. #endif
  206. switch (pass) {
  207. case PASS_1:
  208. if (DOTSCT == NULL)
  209. nosect();
  210. /* no break */
  211. case PASS_2:
  212. DOTSCT->s_zero = 0;
  213. break;
  214. case PASS_3:
  215. AOUTPART(PARTEMIT);
  216. while (DOTSCT->s_zero) {
  217. AOUTPUTC(0, PARTEMIT);
  218. DOTSCT->s_zero--;
  219. }
  220. AOUTPUTC(arg, PARTEMIT);
  221. break;
  222. }
  223. DOTVAL++;
  224. }
  225. emit2(arg)
  226. short arg;
  227. {
  228. #ifdef BYTES_REVERSED
  229. emit1((char)(arg>>8)); emit1((char)arg);
  230. #else
  231. emit1((char)arg); emit1((char)(arg>>8));
  232. #endif
  233. }
  234. emit4(arg)
  235. long arg;
  236. {
  237. #ifdef WORDS_REVERSED
  238. emit2((short)(arg>>16)); emit2((short)(arg));
  239. #else
  240. emit2((short)(arg)); emit2((short)(arg>>16));
  241. #endif
  242. }
  243. emitx(val, n)
  244. valu_t val;
  245. register n;
  246. {
  247. switch (n) {
  248. case 1:
  249. emit1((char)val); break;
  250. case 2:
  251. emit2((short)val); break;
  252. case 4:
  253. emit4((long)val); break;
  254. default:
  255. assert(0);
  256. }
  257. }
  258. emitstr(zero)
  259. {
  260. register i;
  261. register char *p;
  262. p = stringbuf;
  263. i = *p++ & 0377;
  264. while (--i >= 0)
  265. emit1(*p++);
  266. if (zero)
  267. emit1(0);
  268. }
  269. /* ---------- Error checked file I/O ---------- */
  270. ffreopen(s, f)
  271. char *s;
  272. FILE *f;
  273. {
  274. if (freopen(s, "r", f) == NULL)
  275. fatal("can't reopen %s", s);
  276. }
  277. FILE *
  278. ffcreat(s)
  279. char *s;
  280. {
  281. FILE *f;
  282. if ((f = fopen(s, "w")) == NULL)
  283. fatal("can't create %s", s);
  284. return(f);
  285. }
  286. FILE *
  287. fftemp(path, tail)
  288. char *path;
  289. {
  290. register char *dir;
  291. if ((dir = getenv("TMPDIR")) == NULL)
  292. #ifdef TMPDIR
  293. dir = TMPDIR;
  294. #else
  295. dir = "/tmp";
  296. #endif
  297. sprintf(path, "%s/%s", dir, tail);
  298. return(ffcreat(mktemp(path)));
  299. }
  300. putofmt(p, s, part)
  301. register char *p;
  302. register char *s;
  303. {
  304. register i;
  305. register long l;
  306. AOUTPART(part);
  307. while (i = *s++) {
  308. switch (i -= '0') {
  309. /* case 0: p++; break; */
  310. case 1:
  311. l = (long) *((char *)p); p += sizeof(char );
  312. break;
  313. case 2:
  314. l = (long) *((short *)p); p += sizeof(short);
  315. break;
  316. case 4:
  317. l = (long) *((long *)p); p += sizeof(long );
  318. break;
  319. default:
  320. assert(0);
  321. }
  322. while (--i >= 0) {
  323. AOUTPUTC((int)l, part);
  324. l >>= 8;
  325. }
  326. }
  327. }
  328. /* ---------- Error handling ---------- */
  329. yyerror(){} /* we will do our own error printing */
  330. nosect()
  331. {
  332. fatal("no sections");
  333. }
  334. werror()
  335. {
  336. fatal("write error");
  337. }
  338. /* VARARGS1 */
  339. fatal(s, a1, a2, a3, a4)
  340. char *s;
  341. {
  342. nerrors++;
  343. diag(" (fatal)\n", s, a1, a2, a3, a4);
  344. stop();
  345. }
  346. #if DEBUG == 2
  347. assert2(file, line)
  348. char *file;
  349. {
  350. fatal("assertion failed (%s, %d)", file, line);
  351. }
  352. #endif
  353. #if DEBUG == 1
  354. assert1()
  355. {
  356. diag(" (fatal)\n", "assertion failed");
  357. abort();
  358. }
  359. #endif
  360. /* VARARGS1 */
  361. serror(s, a1, a2, a3, a4)
  362. char *s;
  363. {
  364. nerrors++;
  365. diag("\n", s, a1, a2, a3, a4);
  366. }
  367. /* VARARGS1 */
  368. warning(s, a1, a2, a3, a4)
  369. char *s;
  370. {
  371. diag(" (warning)\n", s, a1, a2, a3, a4);
  372. }
  373. /* VARARGS1 */
  374. diag(tail, s, a1, a2, a3, a4)
  375. char *tail, *s;
  376. {
  377. fflush(stdout);
  378. if (modulename)
  379. fprintf(stderr, "\"%s\", line %d: ", modulename, lineno);
  380. else
  381. fprintf(stderr, "%s: ", progname);
  382. fprintf(stderr, s, a1, a2, a3, a4);
  383. fprintf(stderr, tail);
  384. }
  385. nofit()
  386. {
  387. if (pass == PASS_3)
  388. warning("too big");
  389. }