assci.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. */
  6. #include "ass00.h"
  7. #include "assex.h"
  8. #include <em_mes.h>
  9. #include <em_pseu.h>
  10. #include <em_ptyp.h>
  11. #ifndef NORCSID
  12. static char rcs_id[] = "$Id$" ;
  13. #endif
  14. /*
  15. * read compact code and fill in tables
  16. */
  17. static int tabval;
  18. static cons_t argval;
  19. static int oksizes; /* MES EMX,.,. seen */
  20. static enum m_type { CON, ROM, HOLBSS } memtype ;
  21. static int valtype; /* Transfer of type information between
  22. valsize, inpseudo and putval
  23. */
  24. int table3(i) {
  25. switch(i) {
  26. case sp_ilb1:
  27. tabval = get8();
  28. break;
  29. case sp_dlb1:
  30. make_string(get8());
  31. i= sp_dnam;
  32. break;
  33. case sp_dlb2:
  34. tabval = get16();
  35. if ( tabval<0 ) {
  36. error("illegal data label .%d",tabval);
  37. tabval=0 ;
  38. }
  39. make_string(tabval);
  40. i= sp_dnam;
  41. break;
  42. case sp_cst2:
  43. argval = get16();
  44. break;
  45. case sp_ilb2:
  46. tabval = get16();
  47. if ( tabval<0 ) {
  48. error("illegal instruction label %d",tabval);
  49. tabval=0 ;
  50. }
  51. i = sp_ilb1;
  52. break;
  53. case sp_cst4:
  54. i = sp_cst2;
  55. argval = get32();
  56. break;
  57. case sp_dnam:
  58. case sp_pnam:
  59. inident();
  60. break ;
  61. case sp_scon:
  62. getstring() ;
  63. break;
  64. case sp_doff:
  65. getarg(sym_ptyp);
  66. getarg(cst_ptyp);
  67. break;
  68. case sp_icon:
  69. case sp_ucon:
  70. case sp_fcon:
  71. getarg(cst_ptyp);
  72. consiz = argval;
  73. if ( consiz<wordsize ?
  74. wordsize%consiz!=0 : consiz%wordsize!=0 ) {
  75. fatal("illegal object size") ;
  76. }
  77. getstring();
  78. break;
  79. }
  80. return(i);
  81. }
  82. int get16() {
  83. register int l_byte, h_byte;
  84. l_byte = get8();
  85. h_byte = get8();
  86. if ( h_byte>=128 ) h_byte -= 256 ;
  87. return l_byte | (h_byte*256) ;
  88. }
  89. int getu16() {
  90. register int l_byte, h_byte;
  91. l_byte = get8();
  92. h_byte = get8();
  93. return l_byte | (h_byte*256) ;
  94. }
  95. cons_t get32() {
  96. register cons_t l;
  97. register int h_byte;
  98. l = get8(); l |= (unsigned)get8()*256 ; l |= get8()*256L*256L ;
  99. h_byte = get8() ;
  100. if ( h_byte>=128 ) h_byte -= 256 ;
  101. return l | (h_byte*256L*256*256L) ;
  102. }
  103. int table1() {
  104. register i;
  105. i = xget8();
  106. if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
  107. tabval = i-sp_fmnem;
  108. return(sp_fmnem);
  109. }
  110. if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {
  111. tabval = i;
  112. return(sp_fpseu);
  113. }
  114. if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {
  115. tabval = i - sp_filb0;
  116. return(sp_ilb1);
  117. }
  118. return(table3(i));
  119. }
  120. int table2() {
  121. register i;
  122. i = get8();
  123. if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) {
  124. argval = i - sp_zcst0;
  125. return(sp_cst2);
  126. }
  127. return(table3(i));
  128. }
  129. int getarg(typset) {
  130. register t,argtyp;
  131. argtyp = t = table2();
  132. t -= sp_fspec;
  133. t = 1 << t;
  134. if ((typset & t) == 0)
  135. error("bad argument type %d",argtyp);
  136. return(argtyp);
  137. }
  138. cons_t getint() {
  139. getarg(cst_ptyp);
  140. return(argval);
  141. }
  142. glob_t *getlab(status) {
  143. getarg(sym_ptyp);
  144. return(glo2lookup(string,status));
  145. }
  146. char *getdig(str,number) char *str; register unsigned number; {
  147. register int remain;
  148. remain= number%10;
  149. number /= 10;
  150. if ( number ) str= getdig(str,number) ;
  151. *str++ = '0'+remain ;
  152. return str ;
  153. }
  154. make_string(n) unsigned n ; {
  155. string[0] = '.';
  156. *getdig(&string[1],n)= 0;
  157. }
  158. getstring() {
  159. register char *p;
  160. register n;
  161. getarg(cst_ptyp);
  162. if ( argval < 0 || argval >= MAXSTRING-1 )
  163. fatal("string/identifier too long");
  164. strlngth = n = argval;
  165. p = string;
  166. while (--n >= 0)
  167. *p++ = get8();
  168. *p = 0 ;
  169. }
  170. inident() {
  171. getstring();
  172. }
  173. char *inproname() {
  174. getarg(ptyp(sp_pnam));
  175. return(string);
  176. }
  177. int needed() {
  178. register glob_t *g;
  179. register proc_t *p;
  180. for(;;){
  181. switch ( table2() ) {
  182. case sp_dnam :
  183. if (g = xglolookup(string,SEARCHING)) {
  184. if ((g->g_status&DEF) != 0)
  185. continue ;
  186. } else continue ;
  187. break ;
  188. case sp_pnam :
  189. p = searchproc(string,xprocs,oursize->n_xproc);
  190. if (p->p_name) {
  191. if ((p->p_status & DEF) != 0)
  192. continue ;
  193. } else continue ;
  194. break ;
  195. default :
  196. error("Unexpected byte after ms_ext") ;
  197. case sp_cend :
  198. return FALSE ;
  199. }
  200. while ( table2()!=sp_cend ) ;
  201. return TRUE ;
  202. }
  203. }
  204. cons_t valsize() {
  205. switch(valtype=table2()) { /* valtype is used by putval and inpseudo */
  206. case sp_cst2:
  207. return wordsize ;
  208. case sp_ilb1:
  209. case sp_dnam:
  210. case sp_doff:
  211. case sp_pnam:
  212. return ptrsize ;
  213. case sp_scon:
  214. return strlngth ;
  215. case sp_fcon:
  216. case sp_icon:
  217. case sp_ucon:
  218. return consiz ;
  219. case sp_cend:
  220. return 0 ;
  221. default:
  222. fatal("value expected") ;
  223. /* NOTREACHED */
  224. }
  225. }
  226. newline(type) {
  227. register line_t *n_lnp ;
  228. if ( type>VALLOW ) type=VALLOW ;
  229. n_lnp = lnp_cast getarea((unsigned)linesize[type]) ;
  230. n_lnp->l_next = pstate.s_fline ;
  231. pstate.s_fline = n_lnp ;
  232. n_lnp->type1 = type ;
  233. n_lnp->opoff = NO_OFF ;
  234. }
  235. read_compact() {
  236. /*
  237. * read module in compact EM1 code
  238. */
  239. init_module();
  240. pass = 1;
  241. eof_seen = 0;
  242. do {
  243. compact_line() ;
  244. line_num++;
  245. } while (!eof_seen) ;
  246. endproc() ; /* Throw away unwanted garbage */
  247. if ( mod_sizes ) end_module();
  248. /* mod_sizes is only false for rejected library modules */
  249. }
  250. int compact_line() {
  251. register instr_no ;
  252. /*
  253. * read one "line" of compact code.
  254. */
  255. curglosym=0;
  256. switch (table1()) {
  257. default:
  258. fatal("unknown byte at start of \"line\""); /* NOTREACHED */
  259. case EOF:
  260. eof_seen++ ;
  261. while ( pstate.s_prevstat != pst_cast 0 ) {
  262. error("missing end") ; do_proc() ;
  263. }
  264. return ;
  265. case sp_fmnem:
  266. if ( pstate.s_curpro == prp_cast 0) {
  267. error("instruction outside procedure");
  268. }
  269. instr_no = tabval;
  270. if ( (em_flag[instr_no]&EM_PAR)==PAR_NO ) {
  271. newline(MISSING) ;
  272. pstate.s_fline->instr_num= instr_no ;
  273. return ;
  274. }
  275. /*
  276. * This instruction should have an opcode, so read it after
  277. * this switch.
  278. */
  279. break;
  280. case sp_dnam:
  281. chkstart() ;
  282. align(wordsize) ;
  283. curglosym = glo2lookup(string,DEFINING);
  284. curglosym->g_val.g_addr = databytes;
  285. lastglosym = curglosym;
  286. setline() ; line_num++ ;
  287. if (table1() != sp_fpseu)
  288. fatal("no pseudo after data label");
  289. case sp_fpseu:
  290. inpseudo(tabval);
  291. setline() ;
  292. return ;
  293. case sp_ilb1:
  294. newline(LOCSYM) ;
  295. pstate.s_fline->ad.ad_lp = loclookup(tabval,DEFINING);
  296. pstate.s_fline->instr_num = sp_ilb1;
  297. return ;
  298. }
  299. /*
  300. * Now process argument
  301. */
  302. switch(table2()) {
  303. default:
  304. fatal("unknown byte at start of argument"); /*NOTREACHED*/
  305. case sp_cst2:
  306. if ( (em_flag[instr_no]&EM_PAR)==PAR_B ) {
  307. /* value indicates a label */
  308. newline(LOCSYM) ;
  309. pstate.s_fline->ad.ad_lp=
  310. loclookup((int)argval,OCCURRING) ;
  311. } else {
  312. if ( argval>=VAL1(VALLOW) && argval<=VAL1(VALHIGH)) {
  313. newline(VALLOW) ;
  314. pstate.s_fline->type1 = argval+VALMID ;
  315. } else {
  316. newline(CONST) ;
  317. pstate.s_fline->ad.ad_i = argval;
  318. pstate.s_fline->type1 = CONST;
  319. }
  320. }
  321. break;
  322. case sp_ilb1:
  323. newline(LOCSYM) ;
  324. pstate.s_fline->ad.ad_lp = loclookup(tabval,OCCURRING);
  325. break;
  326. case sp_dnam:
  327. newline(GLOSYM) ;
  328. pstate.s_fline->ad.ad_gp = glo2lookup(string,OCCURRING);
  329. break;
  330. case sp_pnam:
  331. newline(PROCNAME) ;
  332. pstate.s_fline->ad.ad_pp=prolookup(string,PRO_OCC);
  333. break;
  334. case sp_cend:
  335. if ( (em_flag[instr_no]&EM_PAR)!=PAR_W ) {
  336. fatal("missing operand") ;
  337. }
  338. newline(MISSING) ;
  339. break ;
  340. case sp_doff:
  341. newline(GLOOFF) ;
  342. pstate.s_fline->ad.ad_df.df_i = argval ;
  343. pstate.s_fline->ad.ad_df.df_gp= glo2lookup(string,OCCURRING) ;
  344. break ;
  345. }
  346. pstate.s_fline->instr_num= instr_no ;
  347. return ;
  348. }
  349. inpseudo(instr_no) {
  350. cons_t cst;
  351. register proc_t *prptr;
  352. cons_t objsize;
  353. cons_t par1,par2;
  354. register char *pars;
  355. /*
  356. * get operands of pseudo (if needed) and process it.
  357. */
  358. switch ( ctrunc(instr_no) ) {
  359. case ps_bss:
  360. chkstart() ;
  361. typealign(HOLBSS) ;
  362. cst = getint(); /* number of bytes */
  363. extbss(cst);
  364. break;
  365. case ps_hol:
  366. chkstart() ;
  367. typealign(HOLBSS) ;
  368. holsize=getint();
  369. holbase=databytes;
  370. extbss(holsize);
  371. break;
  372. case ps_rom:
  373. case ps_con:
  374. chkstart() ;
  375. typealign( ctrunc(instr_no)==ps_rom ? ROM : CON ) ;
  376. while( (objsize=valsize())!=0 ) {
  377. if ( valtype!=sp_scon) sizealign(objsize) ;
  378. putval() ;
  379. databytes+=objsize ;
  380. }
  381. break;
  382. case ps_end:
  383. prptr= pstate.s_curpro ;
  384. if ( prptr == prp_cast 0 ) fatal("unexpected END") ;
  385. proctab[prptr->p_num].pr_off = textbytes;
  386. if (procflag) {
  387. printf("%6lu\t%6lo\t%5d\t%-12s\t%s",
  388. textbytes,textbytes,
  389. prptr->p_num,prptr->p_name,curfile);
  390. if (archmode)
  391. printf("(%.14s)",archhdr.ar_name);
  392. printf("\n");
  393. }
  394. par2 = proctab[prptr->p_num].pr_loc ;
  395. if ( getarg(cst_ptyp|ptyp(sp_cend))==sp_cend ) {
  396. if ( par2 == -1 ) {
  397. fatal("size of local area unspecified") ;
  398. }
  399. } else {
  400. if ( par2 != -1 && argval!=par2 ) {
  401. fatal("inconsistent local area size") ;
  402. }
  403. proctab[prptr->p_num].pr_loc = argval ;
  404. }
  405. setline();
  406. do_proc();
  407. break;
  408. case ps_mes:
  409. switch( int_cast getint() ) {
  410. case ms_err:
  411. error("module with error") ; ertrap();
  412. /* NOTREACHED */
  413. case ms_emx:
  414. if ( oksizes ) {
  415. if ( wordsize!=getint() ) {
  416. fatal("Inconsistent word size");
  417. }
  418. if ( ptrsize!=getint() ) {
  419. fatal("Inconsistent pointer size");
  420. }
  421. } else {
  422. oksizes++ ;
  423. wordsize=getint();ptrsize=getint();
  424. if ( wordsize!=2 && wordsize!=4 ) {
  425. fatal("Illegal word size");
  426. }
  427. if ( ptrsize!=2 && ptrsize!=4 ) {
  428. fatal("Illegal pointer size");
  429. }
  430. setsizes() ;
  431. }
  432. ++mod_sizes ;
  433. break;
  434. case ms_src:
  435. break;
  436. case ms_flt:
  437. intflags |= 020; break; /*floats used*/
  438. case ms_ext:
  439. if ( !needed() ) {
  440. eof_seen++ ;
  441. }
  442. if ( line_num>2 ) {
  443. werror("mes ms_ext must be first or second pseudo") ;
  444. }
  445. return ;
  446. }
  447. while (table2() != sp_cend)
  448. ;
  449. break;
  450. case ps_exc:
  451. par1 = getint();
  452. par2 = getint();
  453. if (par1 == 0 || par2 == 0)
  454. break;
  455. exchange((int)par2,(int)par1) ;
  456. break;
  457. case ps_exa:
  458. getlab(EXTERNING);
  459. break;
  460. case ps_ina:
  461. getlab(INTERNING);
  462. break;
  463. case ps_pro:
  464. chkstart() ;
  465. initproc();
  466. pars = inproname();
  467. if ( getarg(cst_ptyp|ptyp(sp_cend))==sp_cend ) {
  468. par2 = -1 ;
  469. } else {
  470. par2 = argval ;
  471. }
  472. prptr = prolookup(pars,PRO_DEF);
  473. proctab[prptr->p_num].pr_loc = par2;
  474. pstate.s_curpro=prptr;
  475. break;
  476. case ps_inp:
  477. prptr = prolookup(inproname(),PRO_INT);
  478. break;
  479. case ps_exp:
  480. prptr = prolookup(inproname(),PRO_EXT);
  481. break;
  482. default:
  483. fatal("unknown pseudo");
  484. }
  485. if ( !mod_sizes ) fatal("Missing size specification");
  486. if ( databytes>maxadr ) error("Maximum data area size exceeded") ;
  487. }
  488. setline() {
  489. /* Get line numbers correct */
  490. if ( pstate.s_fline &&
  491. ctrunc(pstate.s_fline->instr_num) == sp_fpseu ) {
  492. /* Already one present */
  493. pstate.s_fline->ad.ad_ln.ln_extra++ ;
  494. } else {
  495. newline(LINES) ;
  496. pstate.s_fline->instr_num= sp_fpseu ;
  497. pstate.s_fline->ad.ad_ln.ln_extra= 0 ;
  498. pstate.s_fline->ad.ad_ln.ln_first= line_num ;
  499. }
  500. }
  501. cons_t maxval(bits) int bits ; {
  502. /* find the maximum positive value,
  503. * fitting in 'bits' bits AND
  504. * fitting in a 'cons_t' .
  505. */
  506. cons_t val ;
  507. val=1 ;
  508. while ( bits-- ) {
  509. val<<= 1 ;
  510. if ( val<0 ) return ~val ;
  511. }
  512. return val-1 ;
  513. }
  514. setsizes() {
  515. maxadr = maxval(8*ptrsize) ;
  516. maxint = maxval(8*wordsize-1) ;
  517. maxunsig = maxval(8*wordsize) ;
  518. maxdint = maxval(2*8*wordsize-1) ;
  519. maxdunsig = maxval(2*8*wordsize) ;
  520. }
  521. exchange(p1,p2) {
  522. int size, line ;
  523. int l_of_p1, l_of_p2, l_of_before ;
  524. register line_t *t_lnp,*a_lnp, *b_lnp ;
  525. /* Since the lines are linked backwards it is easy
  526. * to count the number of lines backwards.
  527. * Each instr counts for 1, each pseudo for ln_extra + 1.
  528. * The line numbers in error messages etc. are INCORRECT
  529. * If exc's are used.
  530. */
  531. line= line_num ; size=0 ;
  532. newline(LINES) ; a_lnp=pstate.s_fline ;
  533. a_lnp->instr_num= sp_fpseu ;
  534. a_lnp->ad.ad_ln.ln_first= line ;
  535. a_lnp->ad.ad_ln.ln_extra= -1 ;
  536. for ( ; a_lnp ; a_lnp= a_lnp->l_next ) {
  537. line-- ;
  538. switch ( ctrunc(a_lnp->instr_num) ) {
  539. case sp_fpseu :
  540. line= a_lnp->ad.ad_ln.ln_first ;
  541. size += a_lnp->ad.ad_ln.ln_extra ;
  542. break ;
  543. case sp_ilb1 :
  544. a_lnp->ad.ad_lp->l_min -= p2 ;
  545. break ;
  546. }
  547. size++ ;
  548. if ( size>=p1 ) break ;
  549. }
  550. if ( ( size-= p1 )>0 ) {
  551. if ( ctrunc(a_lnp->instr_num) !=sp_fpseu ) {
  552. fatal("EXC inconsistency") ;
  553. }
  554. doinsert(a_lnp,line,size-1) ;
  555. a_lnp->ad.ad_ln.ln_extra -= size ;
  556. size=0 ;
  557. } else {
  558. if( a_lnp) doinsert(a_lnp,line,-1) ;
  559. }
  560. b_lnp= a_lnp ;
  561. while ( b_lnp ) {
  562. b_lnp= b_lnp->l_next ;
  563. line-- ;
  564. switch ( ctrunc(b_lnp->instr_num) ) {
  565. case sp_fpseu :
  566. size += b_lnp->ad.ad_ln.ln_extra ;
  567. line = b_lnp->ad.ad_ln.ln_first ;
  568. break ;
  569. case sp_ilb1 :
  570. b_lnp->ad.ad_lp->l_min += p1 ;
  571. break ;
  572. }
  573. size++ ;
  574. if ( size>=p2 ) break ;
  575. }
  576. if ( !b_lnp ) { /* if a_lnp==0, so is b_lnp */
  577. fatal("Cannot perform exchange") ;
  578. }
  579. if ( ( size-= p2 )>0 ) {
  580. if ( ctrunc(b_lnp->instr_num) !=sp_fpseu ) {
  581. fatal("EXC inconsistency") ;
  582. }
  583. doinsert(b_lnp,line,size-1) ;
  584. b_lnp->ad.ad_ln.ln_extra -= size ;
  585. } else {
  586. doinsert(b_lnp,line,-1) ;
  587. }
  588. t_lnp = b_lnp->l_next ;
  589. b_lnp->l_next = pstate.s_fline ;
  590. pstate.s_fline= a_lnp->l_next ;
  591. a_lnp->l_next=t_lnp ;
  592. }
  593. doinsert(lnp,first,extra) line_t *lnp ; {
  594. /* Beware : s_fline will be clobbered and restored */
  595. register line_t *t_lnp ;
  596. t_lnp= pstate.s_fline;
  597. pstate.s_fline= lnp->l_next ;
  598. newline(LINES) ;
  599. pstate.s_fline->instr_num= sp_fpseu ;
  600. pstate.s_fline->ad.ad_ln.ln_first= first ;
  601. pstate.s_fline->ad.ad_ln.ln_extra= extra ;
  602. lnp->l_next= pstate.s_fline ;
  603. pstate.s_fline= t_lnp; /* restore */
  604. }
  605. putval() {
  606. switch(valtype){
  607. case sp_cst2:
  608. extconst(argval);
  609. return ;
  610. case sp_ilb1:
  611. extloc(loclookup(tabval,OCCURRING));
  612. return ;
  613. case sp_dnam:
  614. extglob(glo2lookup(string,OCCURRING),(cons_t)0);
  615. return ;
  616. case sp_doff:
  617. extglob(glo2lookup(string,OCCURRING),argval);
  618. return ;
  619. case sp_pnam:
  620. extpro(prolookup(string,PRO_OCC));
  621. return ;
  622. case sp_scon:
  623. extstring() ;
  624. return ;
  625. case sp_fcon:
  626. extxcon(DATA_FCON) ;
  627. return ;
  628. case sp_icon:
  629. extvcon(DATA_ICON) ;
  630. return ;
  631. case sp_ucon:
  632. extvcon(DATA_UCON) ;
  633. return ;
  634. default:
  635. fatal("putval notreached") ;
  636. /* NOTREACHED */
  637. }
  638. }
  639. chkstart() {
  640. static int absout = 0 ;
  641. if ( absout ) return ;
  642. if ( !oksizes ) fatal("missing size specification") ;
  643. setmode(DATA_CONST) ;
  644. extconst((cons_t)0) ;
  645. databytes= wordsize ;
  646. setmode(DATA_REP) ;
  647. if ( wordsize<ABSSIZE ) {
  648. register factor = ABSSIZE/wordsize - 1 ;
  649. extadr( (cons_t) factor ) ;
  650. databytes += factor * wordsize ;
  651. }
  652. absout++ ;
  653. memtype= HOLBSS ;
  654. }
  655. typealign(new) enum m_type new ; {
  656. if ( memtype==new ) return ;
  657. align(wordsize);
  658. memtype=new ;
  659. }
  660. sizealign(size) cons_t size ; {
  661. align( size>wordsize ? wordsize : (int)size ) ;
  662. }
  663. align(size) int size ; {
  664. while ( databytes%size ) {
  665. setmode(DATA_BYTES) ;
  666. ext8(0) ;
  667. databytes++ ;
  668. }
  669. }
  670. extconst(n) cons_t n ; {
  671. setmode(DATA_CONST);
  672. extword(n);
  673. }
  674. extbss(n) cons_t n ; {
  675. cons_t objsize,amount ;
  676. cons_t sv_argval;
  677. int sv_tabval;
  678. if ( n<=0 ) {
  679. if ( n<0 ) werror("negative bss/hol size") ;
  680. if ( table2()==sp_cend || table2()==sp_cend) {
  681. werror("Unexpected end-of-line") ;
  682. }
  683. return ;
  684. }
  685. setmode(DATA_NUL) ; /* flush descriptor */
  686. objsize= valsize();
  687. if ( objsize==0 ) {
  688. werror("Unexpected end-of-line");
  689. return;
  690. }
  691. if ( n%objsize != 0 ) error("BSS/HOL incompatible sizes");
  692. sv_tabval = tabval;
  693. sv_argval = argval;
  694. getarg(sp_cst2);
  695. if ( argval<0 || argval>1 ) error("illegal last argument") ;
  696. databytes +=n ;
  697. if (argval == 1) {
  698. tabval = sv_tabval;
  699. argval = sv_argval;
  700. putval();
  701. amount= n/objsize ;
  702. if ( amount>1 ) {
  703. setmode(DATA_REP);
  704. extadr(amount-1) ;
  705. }
  706. }
  707. else {
  708. n = (n + wordsize - 1) / wordsize;
  709. while (n > MAXBYTE) {
  710. setmode(DATA_BSS);
  711. ext8(MAXBYTE);
  712. n -= MAXBYTE;
  713. }
  714. setmode(DATA_BSS);
  715. ext8((int) n);
  716. }
  717. }
  718. extloc(lbp) register locl_t *lbp; {
  719. /*
  720. * assemble a pointer constant from a local label.
  721. * For example con *1
  722. */
  723. setmode(DATA_IPTR);
  724. data_reloc( chp_cast lbp,dataoff,RELLOC);
  725. extadr((cons_t)0);
  726. }
  727. extglob(agbp,off) glob_t *agbp; cons_t off; {
  728. register glob_t *gbp;
  729. /*
  730. * generate a word of data that is defined by a global symbol.
  731. * Various relocation has to be prepared here in some cases
  732. */
  733. gbp=agbp;
  734. setmode(DATA_DPTR);
  735. if ( gbp->g_status&DEF ) {
  736. extadr(gbp->g_val.g_addr+off);
  737. } else {
  738. data_reloc( chp_cast gbp,dataoff,RELGLO);
  739. extadr(off);
  740. }
  741. }
  742. extpro(aprp) proc_t *aprp; {
  743. /*
  744. * generate a addres that is defined by a procedure descriptor.
  745. */
  746. consiz= ptrsize ; setmode(DATA_UCON);
  747. extarb((int)ptrsize,(long)(aprp->p_num));
  748. }
  749. extstring() {
  750. register char *s;
  751. register n ;
  752. /*
  753. * generate data for a string.
  754. */
  755. for(n=strlngth,s=string ; n--; ) {
  756. setmode(DATA_BYTES) ;
  757. ext8(*s++);
  758. }
  759. return ;
  760. }
  761. extxcon(header) {
  762. register char *s ;
  763. register n;
  764. /*
  765. * generate data for a floating constant initialized by a string.
  766. */
  767. setmode(header);
  768. s = string ;
  769. for (n=strlngth ; n-- ;) {
  770. if ( *s==0 ) error("Zero byte in initializer") ;
  771. ext8(*s++);
  772. }
  773. ext8(0);
  774. return ;
  775. }
  776. /* Added atol() that ignores overflow. --Ceriel */
  777. long atol(s)
  778. register char *s;
  779. {
  780. register long total = 0;
  781. register unsigned digit;
  782. int minus = 0;
  783. while (*s == ' ' || *s == '\t') s++;
  784. if (*s == '+') s++;
  785. else if (*s == '-') {
  786. s++;
  787. minus = 1;
  788. }
  789. while ((digit = *s++ - '0') < 10) {
  790. total *= 10;
  791. total += digit;
  792. }
  793. return(minus ? -total : total);
  794. }
  795. extvcon(header) {
  796. /*
  797. * generate data for a constant initialized by a string.
  798. */
  799. setmode(header);
  800. if ( consiz>4 ) {
  801. error("Size of initializer exceeds loader capability") ;
  802. }
  803. extarb((int)consiz,atol(string)) ;
  804. return ;
  805. }