putline.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #ifndef NORCSID
  2. static char rcsid[] = "$Id$";
  3. #endif
  4. #include "param.h"
  5. #include "types.h"
  6. #include "tes.h"
  7. #include "assert.h"
  8. #include <em_spec.h>
  9. #include <em_pseu.h>
  10. #include <em_mnem.h>
  11. #include <em_flag.h>
  12. #include "alloc.h"
  13. #include "line.h"
  14. #include "lookup.h"
  15. #include "proinf.h"
  16. #include "optim.h"
  17. #include "ext.h"
  18. /*
  19. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  20. * See the copyright notice in the ACK home directory, in the file "Copyright".
  21. *
  22. * Author: Hans van Staveren
  23. */
  24. #define outbyte(b) putc(b,outfile)
  25. putlines(lnp) register line_p lnp; {
  26. register arg_p ap;
  27. line_p temp;
  28. register instr;
  29. short curlin= -2;
  30. short thislin;
  31. while ( lnp != (line_p) 0) {
  32. instr = lnp->l_instr&BMASK;
  33. switch(lnp->l_optyp) {
  34. case OPSYMBOL:
  35. if ((lnp->l_instr&BMASK) == ps_sym)
  36. outdef(lnp->l_a.la_sp);
  37. else
  38. outocc(lnp->l_a.la_sp);
  39. break;
  40. case OPSVAL:
  41. outocc(lnp->l_a.la_sval.lasv_sp);
  42. break;
  43. #ifdef LONGOFF
  44. case OPLVAL:
  45. outocc(lnp->l_a.la_lval.lalv_sp);
  46. break;
  47. #endif
  48. case OPLIST:
  49. ap = lnp->l_a.la_arg;
  50. while (ap != (arg_p) 0) {
  51. switch(ap->a_typ) {
  52. case ARGSYM:
  53. outocc(ap->a_a.a_sp);
  54. break;
  55. case ARGVAL:
  56. outocc(ap->a_a.a_val.av_sp);
  57. break;
  58. }
  59. ap = ap->a_next;
  60. }
  61. break;
  62. }
  63. /*
  64. * global symbols now taken care of
  65. */
  66. switch(instr) {
  67. case ps_sym:
  68. break;
  69. case op_lni:
  70. if (curlin != -2)
  71. curlin++;
  72. outinst(instr);
  73. break;
  74. case op_lin:
  75. switch(lnp->l_optyp) {
  76. case OPNO:
  77. case OPOFFSET:
  78. case OPNUMLAB:
  79. case OPSYMBOL:
  80. case OPSVAL:
  81. case OPLVAL:
  82. case OPLIST:
  83. outinst(instr);
  84. goto processoperand;
  85. case OPSHORT:
  86. thislin = lnp->l_a.la_short;
  87. break;
  88. default:
  89. thislin = (lnp->l_optyp&BMASK)-Z_OPMINI;
  90. break;
  91. }
  92. if (thislin == curlin && !nflag) {
  93. temp = lnp->l_next;
  94. oldline(lnp);
  95. lnp = temp;
  96. OPTIM(O_LINGONE);
  97. continue;
  98. } else if (thislin == curlin+1 && !nflag) {
  99. instr = op_lni;
  100. outinst(instr);
  101. temp = lnp->l_next;
  102. oldline(lnp);
  103. OPTIM(O_LINLNI);
  104. lnp = newline(OPNO);
  105. lnp->l_next = temp;
  106. lnp->l_instr = instr;
  107. } else {
  108. outinst(instr);
  109. }
  110. curlin = thislin;
  111. break;
  112. case op_lab:
  113. curlin = -2;
  114. break;
  115. default:
  116. if ((em_flag[instr-sp_fmnem]&EM_FLO)==FLO_P)
  117. curlin = -2;
  118. outinst(instr);
  119. }
  120. processoperand:
  121. switch(lnp->l_optyp) {
  122. case OPNO:
  123. if ((em_flag[instr-sp_fmnem]&EM_PAR)!=PAR_NO)
  124. outbyte( (byte) sp_cend) ;
  125. break;
  126. default:
  127. outint((lnp->l_optyp&BMASK)-Z_OPMINI);
  128. break;
  129. case OPSHORT:
  130. outint(lnp->l_a.la_short);
  131. break;
  132. #ifdef LONGOFF
  133. case OPOFFSET:
  134. outoff(lnp->l_a.la_offset);
  135. break;
  136. #endif
  137. case OPNUMLAB:
  138. if (instr == op_lab)
  139. numlab(lnp->l_a.la_np->n_repl);
  140. else if (instr < sp_fpseu) /* plain instruction */
  141. outint((short) lnp->l_a.la_np->n_repl->n_number);
  142. else
  143. outnum(lnp->l_a.la_np->n_repl);
  144. break;
  145. case OPSYMBOL:
  146. outsym(lnp->l_a.la_sp);
  147. break;
  148. case OPSVAL:
  149. outbyte( (byte) sp_doff) ;
  150. outsym(lnp->l_a.la_sval.lasv_sp);
  151. outint(lnp->l_a.la_sval.lasv_short);
  152. break;
  153. #ifdef LONGOFF
  154. case OPLVAL:
  155. outbyte( (byte) sp_doff) ;
  156. outsym(lnp->l_a.la_lval.lalv_sp);
  157. outoff(lnp->l_a.la_lval.lalv_offset);
  158. break;
  159. #endif
  160. case OPLIST:
  161. putargs(lnp->l_a.la_arg);
  162. switch(instr) {
  163. case ps_con:
  164. case ps_rom:
  165. case ps_mes:
  166. outbyte( (byte) sp_cend) ;
  167. }
  168. }
  169. /*
  170. * instruction is output now.
  171. * remove its useless body
  172. */
  173. temp = lnp->l_next;
  174. oldline(lnp);
  175. lnp = temp;
  176. if (ferror(outfile))
  177. error("write error");
  178. }
  179. }
  180. putargs(ap) register arg_p ap; {
  181. while (ap != (arg_p) 0) {
  182. switch(ap->a_typ) {
  183. default:
  184. assert(FALSE);
  185. case ARGOFF:
  186. outoff(ap->a_a.a_offset);
  187. break;
  188. case ARGNUM:
  189. outnum(ap->a_a.a_np->n_repl);
  190. break;
  191. case ARGSYM:
  192. outsym(ap->a_a.a_sp);
  193. break;
  194. case ARGVAL:
  195. outbyte( (byte) sp_doff) ;
  196. outsym(ap->a_a.a_val.av_sp);
  197. outoff(ap->a_a.a_val.av_offset);
  198. break;
  199. case ARGSTR:
  200. outbyte( (byte) sp_scon) ;
  201. putstr(&ap->a_a.a_string);
  202. break;
  203. case ARGICN:
  204. outbyte( (byte) sp_icon) ;
  205. goto casecon;
  206. case ARGUCN:
  207. outbyte( (byte) sp_ucon) ;
  208. goto casecon;
  209. case ARGFCN:
  210. outbyte( (byte) sp_fcon) ;
  211. casecon:
  212. outint(ap->a_a.a_con.ac_length);
  213. putstr(&ap->a_a.a_con.ac_con);
  214. break;
  215. }
  216. ap = ap->a_next;
  217. }
  218. }
  219. putstr(abp) register argb_p abp; {
  220. register argb_p tbp;
  221. register length;
  222. length = 0;
  223. tbp = abp;
  224. while (tbp!= (argb_p) 0) {
  225. length += tbp->ab_index;
  226. tbp = tbp->ab_next;
  227. }
  228. outint(length);
  229. while (abp != (argb_p) 0) {
  230. for (length=0;length<abp->ab_index;length++)
  231. outbyte( (byte) abp->ab_contents[length] );
  232. abp = abp->ab_next;
  233. }
  234. }
  235. outdef(sp) register sym_p sp; {
  236. /*
  237. * The surrounding If statement is removed to be friendly
  238. * to Backend writers having to deal with assemblers
  239. * not following our conventions.
  240. if ((sp->s_flags&SYMOUT)==0) {
  241. */
  242. sp->s_flags |= SYMOUT;
  243. if (sp->s_flags&SYMGLOBAL) {
  244. outinst(sp->s_flags&SYMPRO ? ps_exp : ps_exa);
  245. outsym(sp);
  246. }
  247. /*
  248. }
  249. */
  250. }
  251. outocc(sp) register sym_p sp; {
  252. if ((sp->s_flags&SYMOUT)==0) {
  253. sp->s_flags |= SYMOUT;
  254. if ((sp->s_flags&SYMGLOBAL)==0) {
  255. outinst(sp->s_flags&SYMPRO ? ps_inp : ps_ina);
  256. outsym(sp);
  257. }
  258. }
  259. }
  260. outpro() {
  261. outdef(curpro.symbol);
  262. outinst(ps_pro);
  263. outsym(curpro.symbol);
  264. outoff(curpro.localbytes);
  265. }
  266. outend() {
  267. outinst(ps_end);
  268. outoff(curpro.localbytes);
  269. }
  270. outinst(m) {
  271. outbyte( (byte) m );
  272. }
  273. outoff(off) offset off; {
  274. #ifdef LONGOFF
  275. if ((short) off == off)
  276. #endif
  277. outint((short) off);
  278. #ifdef LONGOFF
  279. else {
  280. outbyte( (byte) sp_cst4) ;
  281. outshort( (short) (off&0177777L) );
  282. outshort( (short) (off>>16) );
  283. }
  284. #endif
  285. }
  286. outint(i) short i; {
  287. if (i>= -sp_zcst0 && i< sp_ncst0-sp_zcst0)
  288. outbyte( (byte) (i+sp_zcst0+sp_fcst0) );
  289. else {
  290. outbyte( (byte) sp_cst2) ;
  291. outshort(i);
  292. }
  293. }
  294. outshort(i) short i; {
  295. outbyte( (byte) (i&BMASK) );
  296. outbyte( (byte) (i>>8) );
  297. }
  298. numlab(np) register num_p np; {
  299. if (np->n_number < sp_nilb0)
  300. outbyte( (byte) (np->n_number + sp_filb0) );
  301. else
  302. outnum(np);
  303. }
  304. outnum(np) register num_p np; {
  305. if(np->n_number<256) {
  306. outbyte( (byte) sp_ilb1) ;
  307. outbyte( (byte) (np->n_number) );
  308. } else {
  309. outbyte( (byte) sp_ilb2) ;
  310. outshort((short) np->n_number);
  311. }
  312. }
  313. outsym(sp) register sym_p sp; {
  314. register byte *p;
  315. register unsigned num;
  316. if (sp->s_name[0] == '.') {
  317. num = atoi(&sp->s_name[1]);
  318. if (num < 256) {
  319. outbyte( (byte) sp_dlb1) ;
  320. outbyte( (byte) (num) );
  321. } else {
  322. outbyte( (byte) sp_dlb2) ;
  323. outshort((short) num);
  324. }
  325. } else {
  326. p= sp->s_name;
  327. while (*p && p < &sp->s_name[IDL])
  328. p++;
  329. num = p - sp->s_name;
  330. outbyte( (byte) (sp->s_flags&SYMPRO ? sp_pnam : sp_dnam) );
  331. outint((short) num);
  332. p = sp->s_name;
  333. while (num--)
  334. outbyte( (byte) *p++ );
  335. }
  336. }