123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- *
- */
- #ifndef NORCSID
- static char rcs_m[]= "$Id$" ;
- static char rcs_mh[]= ID_MH ;
- #endif
- #include <stb.h>
- /*
- * machine dependent back end routines for the Intel 80386
- */
- con_part(sz,w) register sz; word w; {
- while (part_size % sz)
- part_size++;
- if (part_size == TEM_WSIZE)
- part_flush();
- if (sz == 1 || sz == 2) {
- w &= (sz == 1 ? 0xFF : 0xFFFF);
- w <<= 8 * part_size;
- part_word |= w;
- } else {
- assert(sz == 4);
- part_word = w;
- }
- part_size += sz;
- }
- con_mult(sz) word sz; {
- long l;
- if (sz != 4)
- fatal("bad icon/ucon size");
- l = atol(str);
- fprintf(codefile,"\t.data4 %ld\n", l);
- }
- #define CODE_GENERATOR
- #define IEEEFLOAT
- #define FL_MSL_AT_LOW_ADDRESS 0
- #define FL_MSW_AT_LOW_ADDRESS 0
- #define FL_MSB_AT_LOW_ADDRESS 0
- #include <con_float>
- /*
- string holstr(n) word n; {
- sprintf(str,hol_off,n,holno);
- return(mystrcpy(str));
- }
- */
- #ifdef REGVARS
- full lbytes;
- #endif
- prolog(nlocals) full nlocals; {
- fputs("push ebp\nmov ebp,esp\n", codefile);
- #ifdef REGVARS
- lbytes = nlocals;
- #else
- #ifdef NOTDEF
- probably not better on 386.
- switch(nlocals) {
- case 8:
- fputs("push eax\n", codefile);
- /* fall through */
- case 4:
- fputs("push eax\n", codefile);
- break;
- default:
- #endif
- fprintf(codefile, "sub\tesp,%ld\n",nlocals);
- #ifdef NOTDEF
- break;
- }
- #endif
- #endif
- }
- #ifdef REGVARS
- long si_off;
- long di_off;
- int firstreg;
- regscore(off, size, typ, score, totyp)
- long off;
- {
- if (size != 4) return -1;
- score -= 1;
- score += score;
- if (typ == reg_pointer || typ == reg_loop) score += (score >> 2);
- score -= 2; /* cost of saving */
- if (off >= 0) score -= 3;
- return score;
- }
- i_regsave()
- {
- si_off = -1;
- di_off = -1;
- firstreg = 0;
- }
- f_regsave()
- {
- if (si_off != di_off) {
- if (si_off == -lbytes) lbytes -= 4;
- if (di_off == -lbytes) lbytes -= 4;
- if (si_off == -lbytes) lbytes -= 4;
- }
- if (lbytes) fprintf(codefile, "sub\tesp,%ld\n",(long) lbytes);
- if (firstreg == 1) {
- fputs("push edi\n", codefile);
- if (si_off != -1) fputs("push esi\n", codefile);
- }
- else if (firstreg == -1) {
- fputs("push esi\n", codefile);
- if (di_off != -1) fputs("push edi\n", codefile);
- }
- if (si_off >= 0)
- fprintf(codefile, "mov esi,%ld(ebp)\n", si_off);
- if (di_off >= 0)
- fprintf(codefile, "mov edi,%ld(ebp)\n", di_off);
- }
- regsave(regstr, off, size)
- char *regstr;
- long off;
- {
- if (strcmp(regstr, "esi") == 0) {
- if (! firstreg) firstreg = -1;
- si_off = off;
- }
- else {
- if (! firstreg) firstreg = 1;
- di_off = off;
- }
- }
- regreturn()
- {
- if (firstreg == 1) {
- if (si_off != -1) fputs("pop esi\n", codefile);
- fputs("pop edi\n", codefile);
- }
- else if (firstreg == -1) {
- if (di_off != -1) fputs("pop edi\n", codefile);
- fputs("pop esi\n", codefile);
- }
- fputs("leave\nret\n", codefile);
- }
- #endif /* REGVARS */
- #ifdef MACH_OPTIONS
- static int gdb_flag = 0;
- static char *fp_hook_nam;
- mach_option(s)
- char *s;
- {
- if (! strcmp(s, "-gdb")) {
- gdb_flag = 1;
- }
- else if (s[1] == 'F') {
- fp_hook_nam = &s[2];
- }
- else {
- error("Unknown flag %s", s);
- }
- }
- #endif /* MACH_OPTIONS */
- mes(type) word type ; {
- int argt, a1, a2 ;
- switch ( (int)type ) {
- case ms_ext :
- for (;;) {
- switch ( argt=getarg(
- ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
- case sp_cend :
- return ;
- default:
- strarg(argt) ;
- fprintf(codefile, ".define %s\n",argstr) ;
- break ;
- }
- }
- case ms_stb:
- argt = getarg(str_ptyp | cst_ptyp);
- if (argt == sp_cstx)
- fputs(".symb \"\", ", codefile);
- else {
- fprintf(codefile, ".symb \"%s\", ", str);
- argt = getarg(cst_ptyp);
- }
- a1 = argval;
- argt = getarg(cst_ptyp);
- a2 = argval;
- argt = getarg(cst_ptyp|nof_ptyp|sof_ptyp|ilb_ptyp|pro_ptyp);
- #ifdef MACH_OPTIONS
- if (gdb_flag) {
- if (a1 == N_PSYM) {
- /* Change offset from AB into offset from
- the frame pointer (bp).
- */
- argval += 8;
- }
- }
- #endif
- fprintf(codefile, "%s, 0x%x, %d\n", strarg(argt), a1, a2);
- argt = getarg(end_ptyp);
- break;
- case ms_std:
- argt = getarg(str_ptyp | cst_ptyp);
- if (argt == sp_cstx)
- str[0] = '\0';
- else {
- argt = getarg(cst_ptyp);
- }
- swtxt();
- if (argval == N_SLINE
- #ifdef MACH_OPTIONS
- && ! gdb_flag
- #endif
- ) {
- fputs("call ___u_LiB\n", codefile);
- cleanregs(); /* debugger might change variables */
- }
- fprintf(codefile, ".symd \"%s\", 0x%x,", str, (int) argval);
- argt = getarg(cst_ptyp);
- fprintf(codefile, "%d\n", (int) argval);
- argt = getarg(end_ptyp);
- break;
- #ifdef MACH_OPTIONS
- case ms_flt:
- if (fp_hook_nam) {
- part_flush();
- ex_ap(fp_hook_nam);
- }
- /* fall through */
- #endif
- default :
- while ( getarg(any_ptyp) != sp_cend ) ;
- break ;
- }
- }
- char *segname[] = {
- ".sect .text", /* SEGTXT */
- ".sect .data", /* SEGCON */
- ".sect .rom", /* SEGROM */
- ".sect .bss" /* SEGBSS */
- };
|