comm6.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  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. #ifdef DUK
  102. ip->i_type = typ;
  103. #else DUK
  104. ip->i_type = typ | S_EXT;
  105. #endif DUK
  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 NOLD:
  135. * ASLD:
  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. * - symbol table entries are produced in commfinish()
  140. * NOLD:
  141. * - i_valu cannot be used since it is needed for relocation info
  142. * - only one .comm with a particular symbol is allowed per module
  143. * - symbol table entries are produced in newcomm()
  144. */
  145. newcomm(ip, val)
  146. register item_t *ip;
  147. valu_t val;
  148. {
  149. if (pass == PASS_1) {
  150. if (DOTSCT == NULL)
  151. nosect();
  152. if (val == 0)
  153. serror("bad size");
  154. /* printf("declare %s: %o\n", ip->i_name, DOTTYP); */
  155. if ((ip->i_type & ~S_EXT) == S_UND) {
  156. --unresolved;
  157. ip->i_type = S_COM|S_EXT|DOTTYP;
  158. #ifdef ASLD
  159. ip->i_valu = val;
  160. } else if (ip->i_type == (S_COM|S_EXT|DOTTYP)) {
  161. if (ip->i_valu < val)
  162. ip->i_valu = val;
  163. #endif
  164. } else
  165. serror("multiple declared");
  166. }
  167. #ifndef ASLD
  168. if (PASS_SYMB == 0)
  169. return;
  170. if (pass != PASS_3)
  171. /*
  172. * save symbol table index
  173. * for possible relocation
  174. */
  175. ip->i_valu = outhead.oh_nname;
  176. #ifdef DUK
  177. newsymb(ip->i_name, S_COM|S_EXT|DOTTYP, (short)0, val);
  178. #else DUK
  179. newsymb(ip->i_name, S_EXT|DOTTYP, (short)0, val);
  180. #endif DUK
  181. #endif
  182. }
  183. switchsect(newtyp)
  184. short newtyp;
  185. {
  186. register sect_t *sp;
  187. if (sp = DOTSCT)
  188. sp->s_size = DOTVAL - sp->s_base;
  189. if (newtyp == S_UND) {
  190. DOTSCT = NULL;
  191. DOTTYP = newtyp;
  192. return;
  193. }
  194. assert(newtyp >= S_MIN);
  195. sp = &sect[newtyp - S_MIN];
  196. if (pass == PASS_3) {
  197. #ifdef AOUTSEEK
  198. aoutpart = -1;
  199. aoutseek[PARTEMIT] = sp->s_foff + sp->s_size - sp->s_zero;
  200. #else
  201. fseek(aoutfile[PARTEMIT], sp->s_foff + sp->s_size - sp->s_zero, 0);
  202. #endif
  203. }
  204. DOTVAL = sp->s_size + sp->s_base;
  205. DOTSCT = sp;
  206. DOTTYP = newtyp;
  207. }
  208. align(bytes)
  209. valu_t bytes;
  210. {
  211. register valu_t gap;
  212. register sect_t *sp;
  213. if ((sp = DOTSCT) == NULL)
  214. nosect();
  215. if (bytes == 0)
  216. bytes = ALIGNWORD;
  217. if (sp->s_lign % bytes)
  218. if (bytes % sp->s_lign)
  219. serror("illegal alignment");
  220. else
  221. sp->s_lign = bytes;
  222. if (pass == PASS_1)
  223. /*
  224. * be pessimistic: biggest gap possible
  225. */
  226. gap = bytes - 1;
  227. else {
  228. /*
  229. * calculate gap correctly;
  230. * will be the same in PASS_2 and PASS_3
  231. */
  232. if ((gap = DOTVAL % bytes) != 0)
  233. gap = bytes - gap;
  234. #ifdef THREE_PASS
  235. if (pass == PASS_2)
  236. /*
  237. * keep track of gain with respect to PASS_1
  238. */
  239. DOTGAIN += (bytes - 1) - gap;
  240. #endif
  241. }
  242. DOTVAL += gap;
  243. sp->s_zero += gap;
  244. }
  245. #ifdef RELOCATION
  246. newrelo(s, n)
  247. short s;
  248. {
  249. struct outrelo outrelo;
  250. #ifdef DUK
  251. int iscomm;
  252. #endif DUK
  253. if (rflag == 0)
  254. return;
  255. if (PASS_RELO == 0)
  256. return;
  257. s &= ~S_DOT;
  258. assert((s & ~(S_COM|S_VAR|S_TYP)) == 0);
  259. #ifndef THREE_PASS
  260. if (s == S_UND)
  261. serror("bad relocation");
  262. #endif
  263. /*
  264. * always relocation info if S_VAR to solve problems with:
  265. * move b,d0
  266. * b=a
  267. * a: .data2 0
  268. */
  269. #ifdef DUK
  270. iscomm = s & S_COM;
  271. #endif DUK
  272. s &= ~S_COM;
  273. if ((n & RELPC) == 0 && s == S_ABS)
  274. return;
  275. if ((n & RELPC) != 0 && s == DOTTYP)
  276. return;
  277. if (pass != PASS_3) {
  278. outhead.oh_nrelo++;
  279. return;
  280. }
  281. s &= ~S_VAR;
  282. outrelo.or_type = (char)n;
  283. outrelo.or_sect = (char)DOTTYP;
  284. #ifndef ASLD
  285. #ifdef DUK
  286. if (s == S_UND || iscomm) {
  287. #else DUK
  288. if (s == S_UND) {
  289. #endif DUK
  290. assert(relonami != 0);
  291. outrelo.or_nami = relonami-1;
  292. relonami = 0;
  293. } else
  294. #endif
  295. if (s < S_MIN) {
  296. assert(s == S_ABS);
  297. /*
  298. * use first non existing entry (argh)
  299. */
  300. outrelo.or_nami = outhead.oh_nname;
  301. } else {
  302. /*
  303. * section symbols are at the end
  304. */
  305. outrelo.or_nami = outhead.oh_nname
  306. - outhead.oh_nsect
  307. + (s - S_MIN)
  308. ;
  309. }
  310. outrelo.or_addr = (long)DOTVAL;
  311. putofmt((char *)&outrelo, SF_RELO, PARTRELO);
  312. }
  313. #endif
  314. newsymb(name, type, desc, valu)
  315. register char *name;
  316. short type;
  317. short desc;
  318. valu_t valu;
  319. {
  320. struct outname outname;
  321. if (name && *name == 0)
  322. name = 0;
  323. assert(PASS_SYMB);
  324. if (pass != PASS_3) {
  325. if (name)
  326. outhead.oh_nchar += strlen(name)+1;
  327. outhead.oh_nname++;
  328. return;
  329. }
  330. if (name) {
  331. AOUTPART(PARTCHAR);
  332. outname.on_foff = outhead.oh_nchar;
  333. do {
  334. AOUTPUTC(*name, PARTCHAR);
  335. outhead.oh_nchar++;
  336. } while (*name++);
  337. } else
  338. outname.on_foff = 0;
  339. outname.on_type = type;
  340. outname.on_desc = desc;
  341. outname.on_valu = valu & ~((0xFFFFFFFF)<<(8*sizeof(valu_t)));
  342. putofmt((char *)&outname, SF_NAME, PARTNAME);
  343. }