mach.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /* $Id$ */
  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. #if TBL68020
  12. #define SYNTAX_68020 1
  13. #endif
  14. #include <stb.h>
  15. con_part(sz,w) register sz; word w; {
  16. while (part_size % sz)
  17. part_size++;
  18. if (part_size == TEM_WSIZE)
  19. part_flush();
  20. if (sz == 1) {
  21. w &= 0xFF;
  22. #if WORD_SIZE==4
  23. w <<= 8*(3-part_size);
  24. part_word |= w;
  25. } else if (sz == 2) {
  26. w &= 0xFFFF;
  27. #endif
  28. if (part_size == 0) {
  29. /* Shift 8 for m68k2, 16 otherwise */
  30. w <<= 4 * TEM_WSIZE;
  31. }
  32. part_word |= w;
  33. } else {
  34. assert(sz == TEM_WSIZE);
  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,".data4 %s\n",str);
  43. }
  44. #define IEEEFLOAT
  45. #define CODE_GENERATOR
  46. #define FL_MSL_AT_LOW_ADDRESS 1
  47. #define FL_MSW_AT_LOW_ADDRESS 1
  48. #define FL_MSB_AT_LOW_ADDRESS 1
  49. #include <con_float>
  50. regscore(off,size,typ,score,totyp)
  51. long off;
  52. {
  53. if (score == 0) return -1;
  54. switch(typ) {
  55. case reg_float:
  56. return -1;
  57. case reg_pointer:
  58. if (size != 4 || totyp != reg_pointer) return -1;
  59. score += (score >> 1);
  60. break;
  61. case reg_loop:
  62. score += 5;
  63. /* fall through .. */
  64. case reg_any:
  65. if (size != TEM_WSIZE || totyp == reg_pointer) return -1;
  66. break;
  67. }
  68. if (off >= 0) {
  69. /* parameters must be initialised with an instruction
  70. * like "move.l 4(a6),d0", which costs 2 words.
  71. */
  72. score -= 2;
  73. }
  74. score--; /* save/restore */
  75. return score;
  76. }
  77. struct regsav_t {
  78. char *rs_reg; /* e.g. "a3" or "d5" */
  79. long rs_off; /* offset of variable */
  80. int rs_size; /* 2 or 4 bytes */
  81. } regsav[9];
  82. int regnr;
  83. i_regsave()
  84. {
  85. regnr = 0;
  86. }
  87. full nlocals;
  88. regreturn()
  89. {
  90. register struct regsav_t *p;
  91. if (regnr > 1) {
  92. #ifdef SYNTAX_68020
  93. fprintf(codefile,"movem.l (-%ld,a6),", nlocals);
  94. #else
  95. fprintf(codefile,"movem.l -%ld(a6),", nlocals);
  96. #endif
  97. for (p = regsav; ;) {
  98. fputs(p->rs_reg, codefile);
  99. if (++p == &regsav[regnr]) break;
  100. putc('/',codefile);
  101. }
  102. putc('\n',codefile);
  103. } else if (regnr == 1) {
  104. p = regsav;
  105. #ifdef SYNTAX_68020
  106. fprintf(codefile,"move.l (-%ld,a6),%s\n",nlocals, p->rs_reg);
  107. #else
  108. fprintf(codefile,"move.l -%ld(a6),%s\n",nlocals, p->rs_reg);
  109. #endif
  110. }
  111. fputs("unlk a6\nrts\n", codefile);
  112. }
  113. f_regsave()
  114. {
  115. register struct regsav_t *p;
  116. nlocals += regnr*4;
  117. #ifdef TBL68020
  118. fprintf(codefile,"link\ta6,#-%ld\n",nlocals);
  119. #else
  120. if (nlocals > 32768) {
  121. fprintf(codefile, "move.l a6,-(sp)\nmove.l sp,a6\nsub #%ld,sp\n", nlocals);
  122. }
  123. else fprintf(codefile,"link\ta6,#-%ld\n",nlocals);
  124. #endif
  125. #ifndef NOSTACKTEST
  126. fprintf(codefile, "tst.b %s\n",
  127. #ifdef SYNTAX_68020
  128. "(-40, sp)"
  129. #else
  130. "-40(sp)"
  131. #endif
  132. );
  133. #endif
  134. if (regnr > 1) {
  135. fputs("movem.l ", codefile);
  136. for (p = regsav; ;) {
  137. fputs(p->rs_reg, codefile);
  138. if (++p == &regsav[regnr]) break;
  139. putc('/',codefile);
  140. }
  141. fputs(",(sp)\n", codefile);
  142. } else if (regnr == 1) {
  143. p = regsav;
  144. fprintf(codefile,"move.l %s,(sp)\n",p->rs_reg);
  145. }
  146. /* initialise register-parameters */
  147. for (p = regsav; p < &regsav[regnr]; p++) {
  148. if (p->rs_off >= 0) {
  149. #ifdef SYNTAX_68020
  150. fprintf(codefile,"move.%c (%ld,a6),%s\n",
  151. #else
  152. fprintf(codefile,"move.%c %ld(a6),%s\n",
  153. #endif
  154. (p->rs_size == 4 ? 'l' : 'w'),
  155. p->rs_off,
  156. p->rs_reg);
  157. }
  158. }
  159. }
  160. regsave(s,off,size)
  161. char *s;
  162. long off;
  163. {
  164. assert (regnr < 9);
  165. regsav[regnr].rs_reg = s;
  166. regsav[regnr].rs_off = off;
  167. regsav[regnr++].rs_size = size;
  168. fprintf(codefile, "!Local %ld into %s\n",off,s);
  169. }
  170. prolog(n) full n; {
  171. nlocals = n;
  172. }
  173. #ifdef MACH_OPTIONS
  174. static int gdb_flag = 0;
  175. mach_option(s)
  176. char *s;
  177. {
  178. if (! strcmp(s, "-gdb")) {
  179. gdb_flag = 1;
  180. }
  181. else {
  182. error("Unknown flag %s", s);
  183. }
  184. }
  185. #endif /* MACH_OPTIONS */
  186. mes(type) word type ; {
  187. int argt, a1, a2 ;
  188. switch ( (int)type ) {
  189. case ms_ext :
  190. for (;;) {
  191. switch ( argt=getarg(
  192. ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
  193. case sp_cend :
  194. return ;
  195. default:
  196. strarg(argt) ;
  197. fprintf(codefile,".define %s\n",argstr) ;
  198. break ;
  199. }
  200. }
  201. case ms_stb:
  202. argt = getarg(str_ptyp | cst_ptyp);
  203. if (argt == sp_cstx)
  204. fputs(".symb \"\", ", codefile);
  205. else {
  206. fprintf(codefile, ".symb \"%s\", ", str);
  207. argt = getarg(cst_ptyp);
  208. }
  209. a1 = argval;
  210. argt = getarg(cst_ptyp);
  211. a2 = argval;
  212. argt = getarg(cst_ptyp|nof_ptyp|sof_ptyp|ilb_ptyp|pro_ptyp);
  213. #ifdef MACH_OPTIONS
  214. if (gdb_flag) {
  215. if (a1 == N_PSYM) {
  216. /* Change offset from AB into offset from
  217. the frame pointer.
  218. */
  219. argval += 8;
  220. }
  221. }
  222. #endif
  223. fprintf(codefile, "%s, 0x%x, %d\n", strarg(argt), a1, a2);
  224. argt = getarg(end_ptyp);
  225. break;
  226. case ms_std:
  227. argt = getarg(str_ptyp | cst_ptyp);
  228. if (argt == sp_cstx)
  229. str[0] = '\0';
  230. else {
  231. argt = getarg(cst_ptyp);
  232. }
  233. swtxt();
  234. if (argval == N_SLINE
  235. #ifdef MACH_OPTIONS
  236. && ! gdb_flag
  237. #endif
  238. ) {
  239. #ifdef SYNTAX_68020
  240. fputs("jsr (___u_LiB)\n", codefile);
  241. #else
  242. fputs("jsr ___u_LiB\n", codefile);
  243. #endif
  244. cleanregs(); /* debugger might change variables */
  245. }
  246. fprintf(codefile, ".symd \"%s\", 0x%x,", str, (int) argval);
  247. argt = getarg(cst_ptyp);
  248. fprintf(codefile, "%d\n", (int) argval);
  249. argt = getarg(end_ptyp);
  250. break;
  251. default :
  252. while ( getarg(any_ptyp) != sp_cend ) ;
  253. break ;
  254. }
  255. }
  256. char *segname[] = {
  257. ".sect .text", /* SEGTXT */
  258. ".sect .data", /* SEGCON */
  259. ".sect .rom", /* SEGROM */
  260. ".sect .bss" /* SEGBSS */
  261. };