Pristine Ack-5.5
[Ack-5.5.git] / mach / proto / ncg / fillem.c
1 #ifndef NORCSID
2 static char rcsid2[] = "$Id: fillem.c,v 0.19 1994/06/24 13:27:20 ceriel Exp $";
3 #endif
4
5 #include <stdio.h>
6 #include "assert.h"
7 #include <em_spec.h>
8 #include <em_pseu.h>
9 #include <em_flag.h>
10 #include <em_ptyp.h>
11 #include <em_mes.h>
12 #include "mach.h"
13 #include "param.h"
14 #include "tables.h"
15 #include "types.h"
16 #include <cgg_cg.h>
17 #include "data.h"
18 #include "result.h"
19 #ifdef REGVARS
20 #include "regvar.h"
21 #include <em_reg.h>
22 #endif
23 #include "extern.h"
24
25 /*
26  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
27  * See the copyright notice in the ACK home directory, in the file "Copyright".
28  *
29  * Author: Hans van Staveren
30  */
31
32 #ifndef newplb                  /* retrofit for older mach.h */
33 #define newplb newilb
34 #endif
35
36 #ifdef fmt_id
37 #ifdef id_first
38 It is an error to define both fmt_id and id_first.
39 Read the documentation.
40 #endif
41 #endif
42
43 #ifdef fmt_ilb
44 #ifdef ilb_fmt
45 It is an error to define both fmt_ilb and ilb_fmt.
46 Read the documentation.
47 #endif
48 #endif
49
50 /* segment types for switchseg() */
51 #define SEGTXT          0
52 #define SEGCON          1
53 #define SEGROM          2
54 #define SEGBSS          3
55
56 long con();
57
58 #define get8()  getc(emfile)
59
60 FILE *emfile;
61 extern FILE *codefile;
62 extern FILE *freopen();
63
64 int nextispseu,savetab1;
65 int opcode;
66 int offtyp;
67 long argval;
68 int dlbval;
69 char *str,argstr[128],labstr[128];
70 unsigned int maxstrsiz;
71 int strsiz;
72 int holno=0;
73 int procno=0;
74 int curseg= -1;
75 int part_size=0;
76 word part_word=0;
77 #ifdef REGVARS
78 int regallowed=0;
79 #endif
80
81 extern char em_flag[];
82 extern short em_ptyp[];
83 extern double atof();
84
85 /* Own version of atol that continues computing on overflow.
86    We don't know that about the ANSI C one.
87 */
88 long atol(s)
89 register char *s;
90 {
91   register long total = 0;
92   register unsigned digit;
93   int minus = 0;
94
95   while (*s == ' ' || *s == '\t') s++;
96   if (*s == '+') s++;
97   else if (*s == '-') {
98         s++;
99         minus = 1;
100   }
101   while ((digit = *s++ - '0') < 10) {
102         total *= 10;
103         total += digit;
104   }
105   return(minus ? -total : total);
106 }
107
108
109 #define sp_cstx sp_cst2
110
111 string tostring();
112 string holstr();
113 string strarg();
114 string mystrcpy();
115 string myalloc();
116 long get32();
117
118 in_init(filename) char *filename; {
119
120         emfile = stdin;
121         if (filename && (emfile=freopen(filename,"r",stdin))==NULL)
122                 error("Can't open %s",filename);
123         if (get16()!=sp_magic)
124                 error("Bad format %s",filename ? filename : "standard-input");
125         str = myalloc(maxstrsiz=256);
126 }
127
128 in_start() {
129 #ifdef modhead
130         fprintf(codefile,"%s",modhead) ;
131 #endif
132 }
133
134 in_finish() {
135 }
136
137 fillemlines() {
138         register int t,i;
139         register struct emline *lp;
140
141         while ((emlines+nemlines)-emp<MAXEMLINES-5) {
142                 assert(nemlines<MAXEMLINES);
143                 if (nextispseu) {
144                         emlines[nemlines].em_instr=0;
145                         return;
146                 }
147                 lp = &emlines[nemlines++];
148
149                 switch(t=table1()) {
150                 default:
151                         error("unknown instruction byte");
152                 case sp_ilb1:
153                 case sp_ilb2:
154 #ifdef USE_TES
155                         lp->em_instr = op_lab;
156                         lp->em_optyp = OPSYMBOL;
157                         lp->em_soper = strarg(t);
158                         lp->em_u.em_loper = argval;
159                         return;
160 #endif
161                 case sp_fpseu:
162                 case sp_dlb1:
163                 case sp_dlb2:
164                 case sp_dnam:
165                         nextispseu=1; savetab1=t;
166                         nemlines--;
167                         lp->em_instr = 0;
168                         return;
169                 case EOF:
170                         nextispseu=1; savetab1=t;
171                         nemlines--;
172                         lp->em_instr = 0;
173                         return;
174                 case sp_fmnem:
175                         lp->em_instr = opcode;
176                         break;
177                 }
178                 i=em_flag[lp->em_instr-sp_fmnem] & EM_PAR;
179                 if ( i == PAR_NO ) {
180                         lp->em_optyp = OPNO;
181                         lp->em_soper = 0;
182                         continue;
183                 }
184                 t= em_ptyp[i];
185                 t= getarg(t);
186                 switch(i) {
187                 case PAR_L:
188                         assert(t == sp_cstx);
189                         if (argval >= 0)
190                                 argval += TEM_BSIZE;
191                         lp->em_optyp = OPINT;
192                         lp->em_u.em_ioper = argval;
193                         lp->em_soper = tostring((word) argval);
194                         continue;
195                 case PAR_G:
196                         if (t != sp_cstx)
197                                 break;
198                         lp->em_optyp = OPSYMBOL;
199                         lp->em_soper = holstr((word) argval);
200                         continue;
201                 case PAR_B:
202                         t = sp_ilb2;
203 #ifdef USE_TES
204                         lp->em_optyp = OPSYMBOL;
205                         lp->em_u.em_loper = argval;
206                         lp->em_soper = strarg(t);
207 #endif
208                         break;
209                 case PAR_D:
210                         assert(t == sp_cstx);
211                         lp->em_optyp = OPSYMBOL;
212                         lp->em_soper = strarg(t);
213                         lp->em_u.em_loper = argval;
214                         continue;
215                 }
216                 lp->em_soper = strarg(t);
217                 if (t==sp_cend)
218                         lp->em_optyp = OPNO;
219                 else if (t==sp_cstx) {
220                         lp->em_optyp = OPINT;
221                         lp->em_u.em_ioper = argval;
222                 } else
223                         lp->em_optyp = OPSYMBOL;
224         }
225 }
226
227 dopseudo() {
228         register b,t;
229         register full n;
230         register long save;
231         word romcont[MAXROM+1];
232         int nromwords;
233         int rombit,rommask;
234         unsigned stackupto();
235
236         if (nextispseu==0 || nemlines>0)
237                 error("No table entry for %d",emlines[0].em_instr);
238         nextispseu=0;
239         switch(savetab1) {
240 #ifndef USE_TES
241         case sp_ilb1:
242         case sp_ilb2:
243                 swtxt();
244                 /* dummy = */stackupto(&fakestack[stackheight-1],maxply,TRUE);
245                 cleanregs();
246                 strarg(savetab1);
247                 newilb(argstr);
248 #ifndef NDEBUG
249                 { extern int Debug; extern char * strtdebug;
250                 if (strcmp(strtdebug,argstr)==0)
251                         Debug = strtdebug[-2]-'0';
252                 }
253 #endif
254                 return;
255 #endif
256         case sp_dlb1:
257         case sp_dlb2:
258         case sp_dnam:
259                 strarg(savetab1);
260                 savelab();
261                 return;
262         case sp_fpseu:
263                 break;
264         case EOF:
265                 swtxt();
266                 in_finish();
267                 out_finish();
268                 popstr(0);
269                 tstoutput();
270                 exit(0);
271         default:
272                 error("Unknown opcode %d",savetab1);
273         }
274         switch (opcode) {
275         case ps_hol:
276                 sprintf(labstr,hol_fmt,++holno);
277         case ps_bss:
278                 getarg(cst_ptyp);
279                 n = (full) argval;
280                 t = getarg(val_ptyp);
281                 save = argval;
282                 getarg(cst_ptyp);
283                 b = (int) argval;
284                 argval = save;
285                 bss(n,t,b);
286                 break;
287         case ps_con:
288                 switchseg(SEGCON);
289                 dumplab();
290                 con(getarg(val_ptyp));
291                 while ((t = getarg(any_ptyp)) != sp_cend)
292                         con(t);
293                 break;
294         case ps_rom:
295                 switchseg(SEGROM);
296                 xdumplab();
297                 nromwords=0;
298                 rommask=0;
299                 rombit=1;
300                 for (;;) {
301                         t=getarg(val_ptyp);
302                         while (t!=sp_cend) {
303                                 if (t==sp_cstx && nromwords<MAXROM) {
304                                         romcont[nromwords] = (word) argval;
305                                         rommask |= rombit;
306                                 }
307                                 nromwords++;
308                                 rombit <<= 1;
309                                 con(t);
310                                 t=getarg(any_ptyp);
311                         }
312                         {
313                                 int c = get8();
314
315                                 if (c == ps_rom) continue;
316                                 if (c != EOF) ungetc(c, emfile);
317                         }
318                         break;
319                 }
320                 if (nromwords != 0) {
321                         romcont[MAXROM]=rommask;
322                         enterglo(labstr,romcont);
323                 }
324                 labstr[0]=0;
325                 break;
326         case ps_mes:
327                 getarg(ptyp(sp_cst2));
328                 if (argval == ms_emx) {
329                         getarg(ptyp(sp_cst2));
330                         if (argval != TEM_WSIZE)
331                                 fatal("bad word size");
332                         getarg(ptyp(sp_cst2));
333                         if (argval != TEM_PSIZE)
334                                 fatal("bad pointer size");
335                         if ( getarg(any_ptyp)!=sp_cend )
336                                 fatal("too many parameters");
337 #ifdef USE_TES
338                 } else if (argval == ms_tes) {
339                         int lbl, size, flthr;
340                         getarg(ptyp(sp_cst2)); lbl = argval;
341                         getarg(ptyp(sp_cst2)); size = argval;
342                         getarg(ptyp(sp_cst2)); flthr = argval;
343                         if ( getarg(any_ptyp)!=sp_cend )
344                                 fatal("too many parameters");
345                         add_label(lbl,size, flthr);
346 #endif
347 #ifdef REGVARS
348                 } else if (argval == ms_gto) {
349                         getarg(ptyp(sp_cend));
350                         if (!regallowed)
351                                 error("mes 3 not allowed here");
352                         fixregvars(TRUE);
353                         regallowed=0;
354                 } else if (argval == ms_reg) {
355                         long r_off;
356                         int r_size,r_type,r_score;
357                         struct regvar *linkreg();
358
359                         if (!regallowed)
360                                 error("mes 3 not allowed here");
361                         if(getarg(ptyp(sp_cst2)|ptyp(sp_cend)) == sp_cend) {
362                                 fixregvars(FALSE);
363                                 regallowed=0;
364                         } else {
365                                 r_off = argval;
366                                 if (r_off >= 0)
367                                         r_off += TEM_BSIZE;
368                                 getarg(ptyp(sp_cst2));
369                                 r_size = argval;
370                                 getarg(ptyp(sp_cst2));
371                                 r_type = argval;
372                                 if (r_type<reg_any || r_type>reg_float)
373                                         fatal("Bad type in register message");
374                                 if(getarg(ptyp(sp_cst2)|ptyp(sp_cend)) == sp_cend)
375                                         r_score = 0;
376                                 else {
377                                         r_score = argval;
378                                         if ( getarg(any_ptyp)!=sp_cend )
379                                                 fatal("too many parameters");
380                                 }
381                                 tryreg(linkreg(r_off,r_size,r_type,r_score),r_type);
382                         }
383 #endif
384                 } else
385                         mes((word)argval);
386                 break;
387         case ps_exa:
388                 strarg(getarg(sym_ptyp));
389                 ex_ap(argstr);
390                 break;
391         case ps_ina:
392                 strarg(getarg(sym_ptyp));
393                 in_ap(argstr);
394                 break;
395         case ps_exp:
396                 strarg(getarg(ptyp(sp_pnam)));
397                 ex_ap(argstr);
398                 break;
399         case ps_inp:
400                 strarg(getarg(ptyp(sp_pnam)));
401                 in_ap(argstr);
402                 break;
403         case ps_pro:
404                 switchseg(SEGTXT);
405                 procno++;
406                 strarg(getarg(ptyp(sp_pnam)));
407                 newplb(argstr);
408                 getarg(cst_ptyp);
409                 prolog((full)argval);
410 #ifdef REGVARS
411                 regallowed++;
412 #endif
413                 break;
414         case ps_end:
415                 getarg(cst_ptyp | ptyp(sp_cend));
416 #ifdef USE_TES
417                 kill_labels();
418 #endif
419                 cleanregs();
420 #ifdef REGVARS
421                 unlinkregs();
422 #endif
423                 tstoutput();
424                 break;
425         default:
426                 error("No table entry for %d",savetab1);
427         }
428 }
429
430 /* ----- input ----- */
431
432 int getarg(typset) {
433         register t,argtyp;
434
435         argtyp = t = table2();
436         if (t == EOF)
437                 fatal("unexpected EOF");
438         t -= sp_fspec;
439         t = 1 << t;
440         if ((typset & t) == 0)
441                 error("bad argument type %d",argtyp);
442         return(argtyp);
443 }
444
445 int table1() {
446         register i;
447
448         i = get8();
449         if (i < sp_fmnem+sp_nmnem && i >= sp_fmnem) {
450                 opcode = i;
451                 return(sp_fmnem);
452         }
453         if (i < sp_fpseu+sp_npseu && i >= sp_fpseu) {
454                 opcode = i;
455                 return(sp_fpseu);
456         }
457         if (i < sp_filb0+sp_nilb0 && i >= sp_filb0) {
458                 argval = i - sp_filb0;
459                 return(sp_ilb2);
460         }
461         return(table3(i));
462 }
463
464 int table2() {
465         register i;
466
467         i = get8();
468         if (i < sp_fcst0+sp_ncst0 && i >= sp_fcst0) {
469                 argval = i - sp_zcst0;
470                 return(sp_cstx);
471         }
472         return(table3(i));
473 }
474
475 int table3(i) {
476         word consiz;
477
478         switch(i) {
479         case sp_ilb1:
480                 argval = get8();
481                 break;
482         case sp_dlb1:
483                 dlbval = get8();
484                 break;
485         case sp_dlb2:
486                 dlbval = get16();
487                 break;
488         case sp_cst2:
489                 i = sp_cstx;
490         case sp_ilb2:
491                 argval = get16();
492                 break;
493         case sp_cst4:
494                 i = sp_cstx;
495                 argval = get32();
496                 break;
497         case sp_dnam:
498         case sp_pnam:
499         case sp_scon:
500                 getstring();
501                 break;
502         case sp_doff:
503                 offtyp = getarg(sym_ptyp);
504                 getarg(cst_ptyp);
505                 break;
506         case sp_icon:
507         case sp_ucon:
508         case sp_fcon:
509                 getarg(cst_ptyp);
510                 consiz = (word) argval;
511                 getstring();
512                 argval = consiz;
513                 break;
514         }
515         return(i);
516 }
517
518 int get16() {
519         register int l_byte, h_byte;
520
521         l_byte = get8();
522         h_byte = get8();
523         if ( h_byte>=128 ) h_byte -= 256 ;
524         return l_byte | (h_byte*256) ;
525 }
526
527 long get32() {
528         register long l;
529         register int h_byte;
530
531         l = get8();
532         l |= ((unsigned) get8())*256 ;
533         l |= get8()*256L*256L ;
534         h_byte = get8() ;
535         if ( h_byte>=128 ) h_byte -= 256 ;
536         return l | (h_byte*256L*256*256L) ;
537 }
538
539 getstring() {
540         register char *p;
541         register n;
542
543         getarg(cst_ptyp);
544         if (argval < 0)
545                 fatal("string/identifier too long");
546         if (argval >= maxstrsiz) {
547                 myfree(str);
548                 str = myalloc((unsigned) argval + 1);
549                 maxstrsiz = argval + 1;
550         }
551         strsiz = n = (int) argval;
552         p = str;
553         while (--n >= 0)
554                 *p++ = get8();
555         *p++ = '\0';
556 }
557
558 char *strarg(t) {
559         register char *p;
560
561         switch (t) {
562         case sp_ilb1:
563         case sp_ilb2:
564 #ifdef fmt_ilb
565                 fmt_ilb(procno,((int) argval),argstr);
566 #else
567                 sprintf(argstr,ilb_fmt,procno,(int)argval);
568 #endif
569                 break;
570         case sp_dlb1:
571         case sp_dlb2:
572                 sprintf(argstr,dlb_fmt,dlbval);
573                 break;
574         case sp_cstx:
575                 sprintf(argstr,cst_fmt,(full)argval);
576                 break;
577         case sp_dnam:
578         case sp_pnam:
579 #ifdef fmt_id
580                 fmt_id(str,argstr);
581 #else
582                 p = argstr;
583                 if (strsiz < 8 || str[0] == id_first)
584                         *p++ = id_first;
585                 sprintf(p,"%.*s",strsiz,str);
586 #endif
587                 break;
588         case sp_doff:
589                 strarg(offtyp);
590                 for (p = argstr; *p; p++)
591                         ;
592                 if ((full) argval >= 0)
593                         *p++ = '+';
594                 else {
595                         *p++ = '-';
596                         argval = - (full) argval;
597                 }
598                 sprintf(p,off_fmt,(full)argval);
599                 break;
600         case sp_cend:
601                 return("");
602         }
603         return(mystrcpy(argstr));
604 }
605
606 bss(n,t,b) full n; {
607         register long s = 0;
608
609         if (n % TEM_WSIZE)
610                 fatal("bad BSS size");
611         if (b==0
612 #ifdef BSS_INIT
613             || (t==sp_cstx && argval==BSS_INIT)
614 #endif /* BSS_INIT */
615                 ) {
616                 switchseg(SEGBSS);
617                 newlbss(labstr,n);
618                 labstr[0]=0;
619                 return;
620         }
621         switchseg(SEGCON);
622         dumplab();
623         while (n > 0)
624                 n -= (s = con(t));
625         if (s % TEM_WSIZE)
626                 fatal("bad BSS initializer");
627 }
628
629 long con(t) {
630         register i;
631
632         strarg(t);
633         switch (t) {
634         case sp_ilb1:
635         case sp_ilb2:
636         case sp_pnam:
637                 part_flush();
638                 con_ilb(argstr);
639                 return((long)TEM_PSIZE);
640         case sp_dlb1:
641         case sp_dlb2:
642         case sp_dnam:
643         case sp_doff:
644                 part_flush();
645                 con_dlb(argstr);
646                 return((long)TEM_PSIZE);
647         case sp_cstx:
648                 con_part(TEM_WSIZE,(word)argval);
649                 return((long)TEM_WSIZE);
650         case sp_scon:
651                 for (i = 0; i < strsiz; i++)
652                         con_part(1,(word) str[i]);
653                 return((long)strsiz);
654         case sp_icon:
655         case sp_ucon:
656                 if (argval > TEM_WSIZE) {
657                         part_flush();
658                         con_mult((word)argval);
659                 } else {
660                         con_part((int)argval,(word)atol(str));
661                 }
662                 return(argval);
663         case sp_fcon:
664                 part_flush();
665                 con_float();
666                 return(argval);
667         }
668         assert(FALSE);
669         /* NOTREACHED */
670 }
671
672 extern char *segname[];
673
674 swtxt() {
675         switchseg(SEGTXT);
676 }
677
678 switchseg(s) {
679
680         if (s == curseg)
681                 return;
682         part_flush();
683         if ((curseg = s) >= 0)
684                 fprintf(codefile,"%s\n",segname[s]);
685 }
686
687 savelab() {
688         register char *p,*q;
689
690         part_flush();
691         if (labstr[0]) {
692                 dlbdlb(argstr,labstr);
693                 return;
694         }
695         p = argstr;
696         q = labstr;
697         while (*q++ = *p++)
698                 ;
699 }
700
701 dumplab() {
702
703         if (labstr[0] == 0)
704                 return;
705         assert(part_size == 0);
706         newdlb(labstr);
707         labstr[0] = 0;
708 }
709
710 xdumplab() {
711
712         if (labstr[0] == 0)
713                 return;
714         assert(part_size == 0);
715         newdlb(labstr);
716 }
717
718 part_flush() {
719
720         /*
721          * Each new data fragment and each data label starts at
722          * a new target machine word
723          */
724         if (part_size == 0)
725                 return;
726         con_cst(part_word);
727         part_size = 0;
728         part_word = 0;
729 }
730
731 string holstr(n) word n; {
732
733         sprintf(str,hol_off,n,holno);
734         return(mystrcpy(str));
735 }
736
737
738 /* ----- machine dependent routines ----- */
739
740 #include        "mach.c"