comm6.c 6.5 KB

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