mach.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #ifndef NORCSID
  2. static char rcsid[] = "$Header$";
  3. #endif
  4. /*
  5. * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
  6. *
  7. * This product is part of the Amsterdam Compiler Kit.
  8. *
  9. * Permission to use, sell, duplicate or disclose this software must be
  10. * obtained in writing. Requests for such permissions may be sent to
  11. *
  12. * Dr. Andrew S. Tanenbaum
  13. * Wiskundig Seminarium
  14. * Vrije Universiteit
  15. * Postbox 7161
  16. * 1007 MC Amsterdam
  17. * The Netherlands
  18. *
  19. */
  20. /*
  21. * machine dependent back end routines for the Motorola 68000
  22. */
  23. con_part(sz,w) register sz; word w; {
  24. while (part_size % sz)
  25. part_size++;
  26. if (part_size == TEM_WSIZE)
  27. part_flush();
  28. if (sz == 1) {
  29. w &= 0xFF;
  30. if (part_size == 0)
  31. w <<= 8;
  32. part_word |= w;
  33. } else {
  34. assert(sz == 2);
  35. part_word = w;
  36. }
  37. part_size += sz;
  38. }
  39. con_mult(sz) word sz; {
  40. if (sz != 4)
  41. fatal("bad icon/ucon size");
  42. fprintf(codefile,".long %s\n",str);
  43. }
  44. con_float() {
  45. static int been_here;
  46. if (argval != 4 && argval != 8)
  47. fatal("bad fcon size");
  48. fprintf(codefile,".long\t");
  49. if (argval == 8)
  50. fprintf(codefile,"F_DUM,");
  51. fprintf(codefile,"F_DUM\n");
  52. if ( !been_here++)
  53. {
  54. fprintf(stderr,"Warning : dummy float-constant(s)\n");
  55. }
  56. }
  57. #ifdef REGVARS
  58. regscore(off,size,typ,score,totyp)
  59. long off;
  60. {
  61. if (score == 0) return -1;
  62. switch(typ) {
  63. case reg_float:
  64. return -1;
  65. case reg_pointer:
  66. if (size != 4 || totyp != reg_pointer) return -1;
  67. score *= 2;
  68. break;
  69. case reg_loop:
  70. score += 5;
  71. /* fall through .. */
  72. case reg_any:
  73. if (size != 2 || totyp == reg_pointer) return -1;
  74. break;
  75. }
  76. if (off >= 0) {
  77. /* parameters must be initialised with an instruction
  78. * like "move.w 4(a6),d0", which costs 2 words.
  79. */
  80. score -= 2;
  81. }
  82. score -= 1; /* take save/restore into account */
  83. return score;
  84. }
  85. struct regsav_t {
  86. char *rs_reg; /* e.g. "a3" or "d5" */
  87. long rs_off; /* offset of variable */
  88. int rs_size; /* 2 or 4 bytes */
  89. } regsav[9];
  90. int regnr;
  91. int nr_a_regs,nr_d_regs;
  92. int TEM_BSIZE;
  93. static long nlocals;
  94. prolog(n)
  95. { nlocals = n; }
  96. i_regsave()
  97. {
  98. regnr = 0;
  99. nr_a_regs = 0;
  100. nr_d_regs = 0;
  101. TEM_BSIZE = 0;
  102. }
  103. #define MOVEM_LIMIT 2
  104. /* If #registers to be saved exceeds MOVEM_LIMIT, we
  105. * use the movem instruction to save registers; else
  106. * we simply use several move.l's.
  107. */
  108. save()
  109. {
  110. register struct regsav_t *p;
  111. int i;
  112. if (regnr > MOVEM_LIMIT) {
  113. fprintf(codefile,"movem.l ");
  114. for (p = regsav; ;) {
  115. fprintf(codefile,"%s",p->rs_reg);
  116. if (++p == &regsav[regnr]) break;
  117. putc('/',codefile);
  118. }
  119. fprintf(codefile,",-(sp)\n");
  120. } else {
  121. /* Note that the order in which the registers are saved
  122. * is important; it is used by gto.s.
  123. */
  124. for (i = 0; i < nr_a_regs; i++) {
  125. fprintf(codefile,"move.l a%d,-(sp)\n",5-i);
  126. }
  127. for (i = 0; i < nr_d_regs; i++) {
  128. fprintf(codefile,"move.l d%d,-(sp)\n",7-i);
  129. }
  130. }
  131. /* Push a mask that indicates which registers were saved */
  132. assert(nr_d_regs < 8 && nr_a_regs < 8);
  133. if (nr_d_regs == 0 && nr_a_regs == 0) {
  134. fprintf(codefile,"clr.w -(sp)\n");
  135. } else {
  136. fprintf(codefile,"move.w #%d,-(sp)\n",
  137. nr_d_regs + (nr_a_regs<<3));
  138. }
  139. /* Compute AB - LB */
  140. TEM_BSIZE = 4 * (nr_d_regs + nr_a_regs) + 10;
  141. /* allocate space for local variables */
  142. fprintf(codefile,"tst.b -%D(sp)\nlink\ta6,#-%D\n",nlocals+40,nlocals);
  143. /* initialise register-parameters */
  144. for (p = regsav; p < &regsav[regnr]; p++) {
  145. if (p->rs_off >= 0) {
  146. fprintf(codefile,"move.%c %ld(a6),%s\n",
  147. (p->rs_size == 4 ? 'l' : 'w'),
  148. p->rs_off + TEM_BSIZE,
  149. p->rs_reg);
  150. }
  151. }
  152. }
  153. restr()
  154. {
  155. register struct regsav_t *p;
  156. int i;
  157. fprintf(codefile,"unlk a6\n");
  158. fprintf(codefile,"add.l #2,sp\n"); /* pop mask */
  159. if (regnr > MOVEM_LIMIT) {
  160. fprintf(codefile,"movem.l (sp)+,");
  161. for (p = regsav; ;) {
  162. fprintf(codefile,"%s",p->rs_reg);
  163. if (++p == &regsav[regnr]) break;
  164. putc('/',codefile);
  165. }
  166. putc('\n',codefile);
  167. } else {
  168. for (i = nr_d_regs - 1; i >= 0; i--) {
  169. fprintf(codefile,"move.l (sp)+,d%d\n",7-i);
  170. }
  171. for (i = nr_a_regs - 1; i >= 0; i--) {
  172. fprintf(codefile,"move.l (sp)+,a%d\n",5-i);
  173. }
  174. }
  175. fprintf(codefile,"rts\n");
  176. }
  177. f_regsave()
  178. {
  179. save();
  180. }
  181. regsave(str,off,size)
  182. char *str;
  183. long off;
  184. {
  185. assert (regnr < 9);
  186. regsav[regnr].rs_reg = str;
  187. if (str[0] == 'a') {
  188. nr_a_regs++;
  189. } else {
  190. assert(str[0] == 'd');
  191. nr_d_regs++;
  192. }
  193. regsav[regnr].rs_off = off;
  194. regsav[regnr++].rs_size = size;
  195. fprintf(codefile, "!Local %ld into %s\n",off,str);
  196. }
  197. regreturn()
  198. {
  199. restr();
  200. }
  201. #endif
  202. #ifndef REGVARS
  203. prolog(nlocals) full nlocals; {
  204. fprintf(codefile,"tst.b -%D(sp)\nlink\ta6,#-%D\n",nlocals+40,nlocals);
  205. }
  206. #endif
  207. mes(type) word type ; {
  208. int argt ;
  209. switch ( (int)type ) {
  210. case ms_ext :
  211. for (;;) {
  212. switch ( argt=getarg(
  213. ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
  214. case sp_cend :
  215. return ;
  216. default:
  217. strarg(argt) ;
  218. fprintf(codefile,".define %s\n",argstr) ;
  219. break ;
  220. }
  221. }
  222. default :
  223. while ( getarg(any_ptyp) != sp_cend ) ;
  224. break ;
  225. }
  226. }
  227. char *segname[] = {
  228. ".text", /* SEGTXT */
  229. ".data", /* SEGCON */
  230. ".data", /* SEGROM */
  231. ".bss" /* SEGBSS */
  232. };