em.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* $Header$ */
  2. /* EM CODE OUTPUT ROUTINES */
  3. #define CMODE 0644
  4. #define MAX_ARG_CNT 32
  5. #include "em.h"
  6. #include "system.h"
  7. #include "bufsiz.h"
  8. #include "arith.h"
  9. #include "label.h"
  10. /*
  11. putbyte(), C_open() and C_close() are the basic routines for
  12. respectively write on, open and close the output file.
  13. The put_*() functions serve as formatting functions of the
  14. various EM language constructs.
  15. See "Description of a Machine Architecture for use with
  16. Block Structured Languages" par. 11.2 for the meaning of these
  17. names.
  18. */
  19. /* supply a kind of buffered output */
  20. #define flush(x) sys_write(ofd, &obuf[0], x);
  21. static char obuf[BUFSIZ];
  22. static char *opp = &obuf[0];
  23. int ofd = -1;
  24. putbyte(b) /* shouldn't putbyte() be a macro ??? (EB) */
  25. int b;
  26. {
  27. if (opp >= &obuf[BUFSIZ]) { /* flush if buffer overflows */
  28. flush(BUFSIZ);
  29. opp = &obuf[0];
  30. }
  31. *opp++ = (char) b;
  32. }
  33. C_open(nm) /* open file for compact code output */
  34. char *nm;
  35. {
  36. if (nm == 0)
  37. ofd = 1; /* standard output */
  38. else
  39. if ((ofd = sys_creat(nm, CMODE)) < 0)
  40. return 0;
  41. return 1;
  42. }
  43. C_close()
  44. {
  45. flush(opp - &obuf[0]);
  46. opp = obuf; /* reset opp */
  47. sys_close(ofd);
  48. ofd = -1;
  49. }
  50. C_busy()
  51. {
  52. return ofd >= 0; /* true if code is being generated */
  53. }
  54. /*** front end for generating long CON/ROM lists ***/
  55. static arg_count;
  56. static arg_rom;
  57. DC_start(rom){
  58. arg_count = 0;
  59. arg_rom = rom;
  60. }
  61. DC_check(){
  62. if (arg_count++ >= MAX_ARG_CNT) {
  63. switch (arg_rom) {
  64. case ps_con:
  65. C_con_end();
  66. C_con_begin();
  67. break;
  68. case ps_rom:
  69. C_rom_end();
  70. C_rom_begin();
  71. break;
  72. }
  73. }
  74. }
  75. /*** the compact code generating routines ***/
  76. #define fit16i(x) ((x) >= (long)0xFFFF8000 && (x) <= (long)0x00007FFF)
  77. #define fit8u(x) ((x) <= 0xFF) /* x is already unsigned */
  78. put_ilb(l)
  79. label l;
  80. {
  81. if (fit8u(l)) {
  82. put8(sp_ilb1);
  83. put8((int)l);
  84. }
  85. else {
  86. put8(sp_ilb2);
  87. put16(l);
  88. }
  89. }
  90. put_dlb(l)
  91. label l;
  92. {
  93. if (fit8u(l)) {
  94. put8(sp_dlb1);
  95. put8((int)l);
  96. }
  97. else {
  98. put8(sp_dlb2);
  99. put16(l);
  100. }
  101. }
  102. put_cst(l)
  103. arith l;
  104. {
  105. if (l >= (arith) -sp_zcst0 && l < (arith) (sp_ncst0 - sp_zcst0)) {
  106. /* we can convert 'l' to an int because its value
  107. can be stored in a byte.
  108. */
  109. put8((int) l + (sp_zcst0 + sp_fcst0));
  110. }
  111. else
  112. if (fit16i(l)) { /* the cast from long to int causes no trouble here */
  113. put8(sp_cst2);
  114. put16((int) l);
  115. }
  116. else {
  117. put8(sp_cst4);
  118. put32(l);
  119. }
  120. }
  121. put_doff(l, v)
  122. label l;
  123. arith v;
  124. {
  125. if (v == 0)
  126. put_dlb(l);
  127. else {
  128. put8(sp_doff);
  129. put_dlb(l);
  130. put_cst(v);
  131. }
  132. }
  133. put_noff(s, v)
  134. char *s;
  135. arith v;
  136. {
  137. if (v == 0)
  138. put_dnam(s);
  139. else {
  140. put8(sp_doff);
  141. put_dnam(s);
  142. put_cst(v);
  143. }
  144. }
  145. put_dnam(s)
  146. char *s;
  147. {
  148. put8(sp_dnam);
  149. put_str(s);
  150. }
  151. put_pnam(s)
  152. char *s;
  153. {
  154. put8(sp_pnam);
  155. put_str(s);
  156. }
  157. #ifdef ____
  158. put_fcon(s, sz)
  159. char *s;
  160. arith sz;
  161. {
  162. put8(sp_fcon);
  163. put_cst(sz);
  164. put_str(s);
  165. }
  166. #endif ____
  167. put_wcon(sp, v, sz) /* sp_icon, sp_ucon or sp_fcon with int repr */
  168. int sp;
  169. char *v;
  170. arith sz;
  171. {
  172. /* how 'bout signextension int --> long ??? */
  173. put8(sp);
  174. put_cst(sz);
  175. put_str(v);
  176. }
  177. put_str(s)
  178. char *s;
  179. {
  180. register int len;
  181. put_cst((arith) (len = strlen(s)));
  182. while (--len >= 0)
  183. put8(*s++);
  184. }
  185. put_cstr(s)
  186. char *s;
  187. {
  188. register int len = prepare_string(s);
  189. put8(sp_scon);
  190. put_cst((arith) len);
  191. while (--len >= 0)
  192. put8(*s++);
  193. }