mach.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* $Header$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. *
  6. */
  7. /*
  8. * machine dependent back end routines for the Motorola 68000, 68010 or 68020
  9. */
  10. #include "whichone.h"
  11. con_part(sz,w) register sz; word w; {
  12. while (part_size % sz)
  13. part_size++;
  14. if (part_size == 4)
  15. part_flush();
  16. if (sz == 1) {
  17. w &= 0xFF;
  18. w <<= 8*(3-part_size);
  19. part_word |= w;
  20. } else if (sz == 2) {
  21. w &= 0xFFFF;
  22. if (part_size == 0)
  23. w <<= 16;
  24. part_word |= w;
  25. } else {
  26. assert(sz == 4);
  27. part_word = w;
  28. }
  29. part_size += sz;
  30. }
  31. con_mult(sz) word sz; {
  32. if (sz != 4)
  33. fatal("bad icon/ucon size");
  34. fprintf(codefile,".data4 %s\n",str);
  35. }
  36. con_float() {
  37. static int been_here;
  38. if (argval != 4 && argval != 8)
  39. fatal("bad fcon size");
  40. fprintf(codefile,".data4\t");
  41. if (argval == 8)
  42. fprintf(codefile,"0,");
  43. fprintf(codefile,"0 !dummy float\n");
  44. if ( !been_here++)
  45. {
  46. fprintf(stderr,"Warning : dummy float-constant(s)\n");
  47. }
  48. }
  49. regscore(off,size,typ,score,totyp)
  50. long off;
  51. {
  52. if (score == 0) return -1;
  53. switch(typ) {
  54. case reg_float:
  55. return -1;
  56. case reg_pointer:
  57. if (size != 4 || totyp != reg_pointer) return -1;
  58. score *= 2;
  59. break;
  60. case reg_loop:
  61. score += 5;
  62. /* fall through .. */
  63. case reg_any:
  64. if (size != 4 || totyp == reg_pointer) return -1;
  65. break;
  66. }
  67. if (off >= 0) {
  68. /* parameters must be initialised with an instruction
  69. * like "move.l 4(a6),d0", which costs 2 words.
  70. */
  71. score -= 2;
  72. }
  73. score -= 1; /* take save/restore into account */
  74. return score;
  75. }
  76. struct regsav_t {
  77. char *rs_reg; /* e.g. "a3" or "d5" */
  78. long rs_off; /* offset of variable */
  79. int rs_size; /* 2 or 4 bytes */
  80. } regsav[9];
  81. int regnr;
  82. i_regsave()
  83. {
  84. regnr = 0;
  85. }
  86. #define MOVEM_LIMIT 2
  87. /* If #registers to be saved exceeds MOVEM_LIMIT, we
  88. * use the movem instruction to save registers; else
  89. * we simply use several move.l's.
  90. */
  91. save()
  92. {
  93. register struct regsav_t *p;
  94. if (regnr > MOVEM_LIMIT) {
  95. fprintf(codefile,"movem.l ");
  96. for (p = regsav; ;) {
  97. fprintf(codefile,"%s",p->rs_reg);
  98. if (++p == &regsav[regnr]) break;
  99. putc('/',codefile);
  100. }
  101. fprintf(codefile,",-(sp)\n");
  102. } else {
  103. for (p = regsav; p < &regsav[regnr]; p++) {
  104. fprintf(codefile,"move.l %s,-(sp)\n",p->rs_reg);
  105. }
  106. }
  107. /* initialise register-parameters */
  108. for (p = regsav; p < &regsav[regnr]; p++) {
  109. if (p->rs_off >= 0) {
  110. #ifdef TBL68020
  111. fprintf(codefile,"move.%c (%ld,a6),%s\n",
  112. #else
  113. fprintf(codefile,"move.%c %ld(a6),%s\n",
  114. #endif
  115. (p->rs_size == 4 ? 'l' : 'w'),
  116. p->rs_off,
  117. p->rs_reg);
  118. }
  119. }
  120. }
  121. restr()
  122. {
  123. register struct regsav_t *p;
  124. if (regnr > MOVEM_LIMIT) {
  125. fprintf(codefile,"movem.l (sp)+,");
  126. for (p = regsav; ;) {
  127. fprintf(codefile,"%s",p->rs_reg);
  128. if (++p == &regsav[regnr]) break;
  129. putc('/',codefile);
  130. }
  131. putc('\n',codefile);
  132. } else {
  133. for (p = &regsav[regnr-1]; p >= regsav; p--) {
  134. fprintf(codefile,"move.l (sp)+,%s\n",p->rs_reg);
  135. }
  136. }
  137. fprintf(codefile,"unlk a6\n");
  138. fprintf(codefile,"rts\n");
  139. }
  140. f_regsave()
  141. {
  142. save();
  143. }
  144. regsave(str,off,size)
  145. char *str;
  146. long off;
  147. {
  148. assert (regnr < 9);
  149. regsav[regnr].rs_reg = str;
  150. regsav[regnr].rs_off = off;
  151. regsav[regnr++].rs_size = size;
  152. fprintf(codefile, "!Local %ld into %s\n",off,str);
  153. }
  154. regreturn()
  155. {
  156. restr();
  157. }
  158. prolog(nlocals) full nlocals; {
  159. #ifdef TBL68020
  160. fprintf(codefile,"tst.b (-%ld,sp)\nlink\ta6,#-%ld\n",nlocals+40,nlocals);
  161. #else
  162. fprintf(codefile,"tst.b -%ld(sp)\nlink\ta6,#-%ld\n",nlocals+40,nlocals);
  163. #endif
  164. }
  165. mes(type) word type ; {
  166. int argt ;
  167. switch ( (int)type ) {
  168. case ms_ext :
  169. for (;;) {
  170. switch ( argt=getarg(
  171. ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
  172. case sp_cend :
  173. return ;
  174. default:
  175. strarg(argt) ;
  176. fprintf(codefile,".define %s\n",argstr) ;
  177. break ;
  178. }
  179. }
  180. default :
  181. while ( getarg(any_ptyp) != sp_cend ) ;
  182. break ;
  183. }
  184. }
  185. char *segname[] = {
  186. ".sect .text", /* SEGTXT */
  187. ".sect .data", /* SEGCON */
  188. ".sect .rom", /* SEGROM */
  189. ".sect .bss" /* SEGBSS */
  190. };