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