putline.c 6.7 KB

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