comm6.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /* $Header$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* @(#)comm6.c 1.7 */
  7. /*
  8. * implement pseudo instructions
  9. */
  10. #include "comm0.h"
  11. #include "comm1.h"
  12. #include "y.tab.h"
  13. newequate(ip, typ)
  14. register item_t *ip;
  15. register short typ;
  16. {
  17. typ &= ~S_EXT;
  18. if (typ & S_COM)
  19. typ = S_UND;
  20. else if ((typ & S_VAR) && (typ & S_TYP) != S_ABS)
  21. typ = S_UND;
  22. #ifdef THREE_PASS
  23. else if (pass == PASS_1 && typ == S_UND)
  24. typ = S_VAR;
  25. else if (pass == PASS_2 && (ip->i_type & S_TYP) == S_UND)
  26. ip->i_type |= typ;
  27. #endif THREE_PASS
  28. if (typ == S_UND)
  29. serror("illegal equate");
  30. if (pass == PASS_3)
  31. assert((ip->i_type & S_TYP) == (typ & S_TYP));
  32. newident(ip, typ);
  33. }
  34. newident(ip, typ)
  35. register item_t *ip;
  36. {
  37. register flag;
  38. #ifdef GENLAB
  39. static char genlab[] = GENLAB;
  40. #endif GENLAB
  41. if (pass == PASS_1) {
  42. /* printf("declare %s: %o\n", ip->i_name, typ); */
  43. if (ip->i_type & ~S_EXT)
  44. serror("multiple declared");
  45. else
  46. --unresolved;
  47. ip->i_type |= typ;
  48. }
  49. if (PASS_SYMB == 0)
  50. return;
  51. #ifdef THREE_PASS
  52. if (ip->i_type & S_EXT)
  53. flag = SYM_EXT;
  54. else
  55. flag = SYM_LOC;
  56. #else
  57. flag = SYM_EXT|SYM_LOC; /* S_EXT not stable in PASS_1 */
  58. #endif THREE_PASS
  59. #ifdef GENLAB
  60. if (strncmp(ip->i_name, genlab, sizeof(genlab)-1) == 0)
  61. flag = SYM_LAB;
  62. #endif GENLAB
  63. if (sflag & flag)
  64. newsymb(
  65. ip->i_name,
  66. ip->i_type & (S_EXT|S_TYP),
  67. (short)0,
  68. load(ip)
  69. );
  70. }
  71. newlabel(ip)
  72. register item_t *ip;
  73. {
  74. #ifdef THREE_PASS
  75. register addr_t oldval = ip->i_valu;
  76. #endif
  77. if (DOTSCT == NULL)
  78. nosect();
  79. ip->i_type &= ~S_TYP;
  80. ip->i_type |= DOTTYP;
  81. if (store(ip, (valu_t) DOTVAL) == 0)
  82. return;
  83. #ifdef THREE_PASS
  84. assert(pass != PASS_2 || oldval - ip->i_valu == DOTGAIN);
  85. #endif
  86. }
  87. newsect(ip)
  88. register item_t *ip;
  89. {
  90. register ushort typ;
  91. register sect_t *sp = NULL;
  92. typ = ip->i_type & S_TYP;
  93. if (typ == S_UND) {
  94. /*
  95. * new section
  96. */
  97. assert(pass == PASS_1);
  98. --unresolved;
  99. typ = outhead.oh_nsect + S_MIN;
  100. outhead.oh_nsect++;
  101. if (outhead.oh_nsect > SECTMAX || typ > S_MAX)
  102. fatal("too many sections");
  103. sp = &sect[typ - S_MIN];
  104. sp->s_item = ip;
  105. sp->s_lign = ALIGNSECT;
  106. #ifndef ASLD
  107. ip->i_type = typ;
  108. #else
  109. ip->i_type = typ | S_EXT;
  110. #endif
  111. ip->i_valu = 0;
  112. } else if (typ >= S_MIN) {
  113. sp = &sect[typ - S_MIN];
  114. if (sp->s_item != ip)
  115. sp = NULL;
  116. }
  117. if (sp == NULL)
  118. serror("multiple declared");
  119. else
  120. switchsect(typ);
  121. }
  122. newbase(base)
  123. valu_t base;
  124. {
  125. #ifdef ASLD
  126. register sect_t *sp;
  127. if ((sp = DOTSCT) == NULL)
  128. nosect();
  129. if (sp->s_flag & BASED)
  130. serror("already based");
  131. sp->s_base = base;
  132. sp->s_flag |= BASED;
  133. DOTVAL += base;
  134. #else
  135. warning(".base ignored");
  136. #endif
  137. }
  138. /*
  139. * NOTE: A rather different solution is used for ASLD and not ASLD:
  140. * ASLD, or local commons:
  141. * - maximum length of .comm is recorded in i_valu during PASS_1
  142. * - address of .comm is recorded in i_valu in later passes:
  143. * assigned at end of PASS_1, corrected for s_gain at end of PASS_2
  144. * not ASLD:
  145. * - maximum length of .comm is recorded in i_valu during PASS_1
  146. * - i_valu is used for relocation info during PASS_3
  147. */
  148. newcomm(ip, val)
  149. register item_t *ip;
  150. valu_t val;
  151. {
  152. if (pass == PASS_1) {
  153. if (DOTSCT == NULL)
  154. nosect();
  155. if (val == 0)
  156. serror("bad size");
  157. /* printf("declare %s: %o\n", ip->i_name, DOTTYP); */
  158. if ((ip->i_type & ~S_EXT) == S_UND) {
  159. --unresolved;
  160. ip->i_type = S_COM|DOTTYP|(ip->i_type&S_EXT);
  161. ip->i_valu = val;
  162. new_common(ip);
  163. } else if (ip->i_type == (S_COM|DOTTYP|(ip->i_type&S_EXT))) {
  164. if (ip->i_valu < val)
  165. ip->i_valu = val;
  166. } else
  167. serror("multiple declared");
  168. }
  169. }
  170. switchsect(newtyp)
  171. short newtyp;
  172. {
  173. register sect_t *sp;
  174. if (sp = DOTSCT)
  175. sp->s_size = DOTVAL - sp->s_base;
  176. if (newtyp == S_UND) {
  177. DOTSCT = NULL;
  178. DOTTYP = newtyp;
  179. return;
  180. }
  181. assert(newtyp >= S_MIN);
  182. sp = &sect[newtyp - S_MIN];
  183. if (pass == PASS_3) {
  184. wr_outsect(newtyp - S_MIN);
  185. }
  186. DOTVAL = sp->s_size + sp->s_base;
  187. DOTSCT = sp;
  188. DOTTYP = newtyp;
  189. }
  190. align(bytes)
  191. valu_t bytes;
  192. {
  193. register valu_t gap;
  194. register sect_t *sp;
  195. if ((sp = DOTSCT) == NULL)
  196. nosect();
  197. if (bytes == 0)
  198. bytes = ALIGNWORD;
  199. if (sp->s_lign % bytes)
  200. if (bytes % sp->s_lign)
  201. serror("illegal alignment");
  202. else
  203. sp->s_lign = bytes;
  204. if (pass == PASS_1)
  205. /*
  206. * be pessimistic: biggest gap possible
  207. */
  208. gap = bytes - 1;
  209. else {
  210. /*
  211. * calculate gap correctly;
  212. * will be the same in PASS_2 and PASS_3
  213. */
  214. if ((gap = DOTVAL % bytes) != 0)
  215. gap = bytes - gap;
  216. #ifdef THREE_PASS
  217. if (pass == PASS_2)
  218. /*
  219. * keep track of gain with respect to PASS_1
  220. */
  221. DOTGAIN += (bytes - 1) - gap;
  222. #endif
  223. }
  224. DOTVAL += gap;
  225. sp->s_zero += gap;
  226. }
  227. #ifdef RELOCATION
  228. static int nrelo;
  229. static struct outrelo relobuf[100];
  230. struct outrelo *
  231. neworelo()
  232. {
  233. if (nrelo == 100) {
  234. wr_relo(relobuf, 100);
  235. nrelo = 0;
  236. }
  237. return &relobuf[nrelo++];
  238. }
  239. newrelo(s, n)
  240. short s;
  241. {
  242. register struct outrelo *outrelo;
  243. int iscomm;
  244. if (rflag == 0)
  245. return;
  246. if (PASS_RELO == 0)
  247. return;
  248. s &= ~S_DOT;
  249. assert((s & ~(S_COM|S_VAR|S_TYP)) == 0);
  250. #ifdef ASLD
  251. #ifndef THREE_PASS
  252. if (s == S_UND)
  253. serror("bad relocation");
  254. #endif
  255. #endif
  256. /*
  257. * always relocation info if S_VAR to solve problems with:
  258. * move b,d0
  259. * b=a
  260. * a: .data2 0
  261. */
  262. iscomm = s & S_COM;
  263. s &= ~S_COM;
  264. if ((n & RELPC) == 0 && s == S_ABS)
  265. return;
  266. if ((n & RELPC) != 0 && s == DOTTYP)
  267. return;
  268. if (pass != PASS_3) {
  269. outhead.oh_nrelo++;
  270. return;
  271. }
  272. s &= ~S_VAR;
  273. outrelo = neworelo();
  274. outrelo->or_type = (char)n;
  275. outrelo->or_sect = (char)DOTTYP;
  276. #ifndef ASLD
  277. if (s == S_UND || iscomm) {
  278. assert(relonami != 0);
  279. outrelo->or_nami = relonami-1;
  280. relonami = 0;
  281. } else
  282. #endif
  283. if (s < S_MIN) {
  284. assert(s == S_ABS);
  285. /*
  286. * use first non existing entry (argh)
  287. */
  288. outrelo->or_nami = outhead.oh_nname;
  289. } else {
  290. /*
  291. * section symbols are at the end
  292. */
  293. outrelo->or_nami = outhead.oh_nname
  294. - outhead.oh_nsect
  295. + (s - S_MIN)
  296. ;
  297. }
  298. outrelo->or_addr = (long)DOTVAL;
  299. }
  300. #endif
  301. static char sbuf[1024];
  302. static char *psbuf = sbuf;
  303. mwr_string(nm,len)
  304. register char *nm;
  305. {
  306. register char *q = psbuf;
  307. while (len--) {
  308. *q++ = *nm++;
  309. if (q == &sbuf[1024]) {
  310. wr_string(sbuf,1024L);
  311. q = sbuf;
  312. }
  313. }
  314. psbuf = q;
  315. }
  316. static struct outname obuf[100];
  317. static int nnames;
  318. static struct outname *
  319. newoname()
  320. {
  321. if (nnames == 100) {
  322. wr_name(obuf,100);
  323. nnames = 0;
  324. }
  325. return &obuf[nnames++];
  326. }
  327. newsymb(name, type, desc, valu)
  328. register char *name;
  329. short type;
  330. short desc;
  331. valu_t valu;
  332. {
  333. register struct outname *outname;
  334. if (name && *name == 0)
  335. name = 0;
  336. assert(PASS_SYMB);
  337. if (pass != PASS_3) {
  338. if (name)
  339. outhead.oh_nchar += strlen(name)+1;
  340. outhead.oh_nname++;
  341. return;
  342. }
  343. nname++;
  344. outname = newoname();
  345. if (name) {
  346. int len = strlen(name) + 1;
  347. mwr_string(name, len);
  348. outname->on_foff = outhead.oh_nchar;
  349. outhead.oh_nchar += len;
  350. } else
  351. outname->on_foff = 0;
  352. outname->on_type = type;
  353. outname->on_desc = desc;
  354. outname->on_valu = valu & ~((0xFFFFFFFF)<<(8*sizeof(valu_t)));
  355. }
  356. oflush()
  357. {
  358. #ifdef RELOCATION
  359. if (nrelo) wr_relo(relobuf,nrelo);
  360. #endif
  361. if (nnames) wr_name(obuf,nnames);
  362. if (psbuf > sbuf) wr_string(sbuf, (long) (psbuf - sbuf));
  363. }
  364. new_common(ip)
  365. item_t *ip;
  366. {
  367. register struct common_t *cp;
  368. static nleft = 0;
  369. static struct common_t *next;
  370. if (--nleft < 0) {
  371. next = (struct common_t *) sbrk(MEMINCR);
  372. if ((int) next == -1) {
  373. fatal("out of memory");
  374. }
  375. nleft += (MEMINCR / sizeof (struct common_t));
  376. }
  377. cp = next++;
  378. cp->c_next = commons;
  379. cp->c_it = ip;
  380. commons = cp;
  381. }