Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom / code.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  */
5 /* $Id: code.c,v 3.51 1997/07/01 08:33:13 ceriel Exp $ */
6 /*      C O D E - G E N E R A T I N G   R O U T I N E S         */
7
8 #include        "lint.h"
9 #include        "dbsymtab.h"
10 #ifndef LINT
11 #include        <em.h>
12 #else
13 #include        "l_em.h"
14 #include        "l_lint.h"
15 #endif  /* LINT */
16 #include        "botch_free.h"
17 #include        <alloc.h>
18 #include        "dataflow.h"
19 #include        "use_tmp.h"
20 #include        "arith.h"
21 #include        "type.h"
22 #include        "idf.h"
23 #include        "label.h"
24 #include        "code.h"
25 #include        "stmt.h"
26 #include        "def.h"
27 #include        "expr.h"
28 #include        "sizes.h"
29 #include        "stack.h"
30 #include        "level.h"
31 #include        "decspecs.h"
32 #include        "declar.h"
33 #include        "Lpars.h"
34 #include        "specials.h"
35 #include        "atw.h"
36 #include        "assert.h"
37 #include        "noRoption.h"
38 #include        "LLlex.h"
39 #ifdef DBSYMTAB
40 #include        <stb.h>
41 #endif /* DBSYMTAB */
42
43 label lab_count = 1;
44 label datlab_count = 1;
45
46 #ifndef NOFLOAT
47 int fp_used;
48 #endif /* NOFLOAT */
49
50 /* global function info */
51 char *func_name;
52 struct type *func_type;
53 int func_notypegiven;
54
55 #ifdef USE_TMP
56 static int      tmp_id;
57 static int      pro_id;
58 #endif /* USE_TMP */
59
60 extern char options[];
61 extern char *symbol2str();
62
63 #ifndef LINT
64 init_code(dst_file)
65         char *dst_file;
66 {
67         /*      init_code() initialises the output file on which the
68                 compact EM code is written
69         */
70         C_init(word_size, pointer_size); /* initialise EM module */
71         if (C_open(dst_file) == 0)
72                 fatal("cannot write to %s\n", dst_file);
73         C_magic();
74         C_ms_emx(word_size, pointer_size);
75 #ifdef DBSYMTAB
76         if (options['g']) {
77                 extern char *source;
78
79                 C_ms_std(source, N_SO, 0);
80                 stb_typedef(int_type, "int");
81                 stb_typedef(char_type, "char");
82                 stb_typedef(long_type, "long");
83                 stb_typedef(short_type, "short");
84                 stb_typedef(uchar_type, "unsigned char");
85                 stb_typedef(ushort_type, "unsigned short");
86                 stb_typedef(ulong_type, "unsigned long");
87                 stb_typedef(uint_type, "unsigned int");
88                 stb_typedef(float_type, "float");
89                 stb_typedef(double_type, "double");
90                 stb_typedef(void_type, "void");
91         }
92 #endif /* DBSYMTAB */
93 #ifdef USE_TMP
94 #ifdef PREPEND_SCOPES
95         C_insertpart(tmp_id = C_getid());
96 #endif  /* USE_TMP */
97 #endif  /* PREPEND_SCOPES */
98 }
99 #endif  /* LINT */
100
101 struct string_cst *str_list = 0;
102
103 code_string(val, len, dlb)
104         char *val;
105         int len;
106         label dlb;
107 {
108         register struct string_cst *sc = new_string_cst();
109
110         C_ina_dlb(dlb);
111         sc->next = str_list;
112         str_list = sc;
113         sc->sc_value = val;
114         sc->sc_len = len;
115         sc->sc_dlb = dlb;
116 }
117
118 def_strings(sc)
119         register struct string_cst *sc;
120 {
121         while (sc) {
122                 struct string_cst *sc1 = sc;
123
124                 C_df_dlb(sc->sc_dlb);
125                 str_cst(sc->sc_value, sc->sc_len);
126                 sc = sc->next;
127                 free_string_cst(sc1);
128         }
129 }
130
131 #ifndef LINT
132 end_code()
133 {
134         /*      end_code() performs the actions to be taken when closing
135                 the output stream.
136         */
137 #ifndef NOFLOAT
138         if (fp_used) {
139                 /* floating point used  */
140                 C_ms_flt();
141         }
142 #endif /* NOFLOAT */
143         def_strings(str_list);
144         str_list = 0;
145         C_ms_src((int)(LineNumber - 2), FileName);
146         C_close();
147 }
148 #endif  /* LINT */
149
150 #ifdef  PREPEND_SCOPES
151 prepend_scopes()
152 {
153         /*      prepend_scopes() runs down the list of global idf's
154                 and generates those exa's, exp's, ina's and inp's
155                 that superior hindsight has provided.
156         */
157         register struct stack_entry *se = local_level->sl_entry;
158
159 #ifdef USE_TMP
160         C_beginpart(tmp_id);
161 #endif /* USE_TMP */
162         while (se != 0) {
163                 register struct idf *id = se->se_idf;
164                 register struct def *df = id->id_def;
165
166                 if (df && (df->df_initialized || df->df_used || df->df_alloc))
167                         code_scope(id->id_text, df);
168                 se = se->next;
169         }
170 #ifdef USE_TMP
171         C_endpart(tmp_id);
172 #endif /* USE_TMP */
173 }
174 #endif  /* PREPEND_SCOPES */
175
176 code_scope(text, def)
177         char *text;
178         register struct def *def;
179 {
180         /*      generates code for one name, text, of the storage class
181                 as given by def, if meaningful.
182         */
183         int fund = def->df_type->tp_fund;
184
185         switch (def->df_sc)     {
186         case EXTERN:
187         case GLOBAL:
188         case IMPLICIT:
189                 if (fund == FUNCTION)
190                         C_exp(text);
191                 else
192                         C_exa_dnam(text);
193                 break;
194         case STATIC:
195                 if (fund == FUNCTION)
196                         C_inp(text);
197                 else
198                         C_ina_dnam(text);
199                 break;
200         }
201 }
202
203 static label return_label, return2_label;
204 static char return_expr_occurred;
205 static arith func_size;
206 static label func_res_label;
207 static char *last_fn_given = "";
208 static label file_name_label;
209
210 begin_proc(ds, idf)             /* to be called when entering a procedure */
211         struct decspecs *ds;
212         struct idf *idf;
213 {
214         /*      begin_proc() is called at the entrance of a new function
215                 and performs the necessary code generation:
216                 -       a scope indicator (if needed) exp/inp
217                 -       the procedure entry pro $name
218                 -       reserves some space if the result of the function
219                         does not fit in the return area
220                 -       a fil pseudo instruction
221         */
222         register char *name = idf->id_text;
223         register struct def *def = idf->id_def;
224
225         while (def->df_level > L_GLOBAL) def = def->next;
226                 /* idf->id_def does not indicate the right def structure
227                    when the function being defined has a parameter of the
228                    same name.
229                 */
230 #ifndef PREPEND_SCOPES
231         code_scope(name, def);
232 #endif  /* PREPEND_SCOPES */
233 #ifdef  DATAFLOW
234         if (options['d'])
235                 DfaStartFunction(name);
236 #endif  /* DATAFLOW */
237
238         /* set global function info */
239         func_name = name;
240         if (def->df_type->tp_fund != FUNCTION) {
241                 error("making function body for non-function");
242                 func_type = error_type;
243         }
244         else {
245                 func_type = def->df_type->tp_up;
246         }
247         func_notypegiven = ds->ds_notypegiven;
248         func_size = ATW(func_type->tp_size);
249
250 #ifndef USE_TMP
251         C_pro_narg(name);
252 #else
253         C_insertpart(pro_id = C_getid());
254 #endif
255         if (is_struct_or_union(func_type->tp_fund))     {
256                 C_df_dlb(func_res_label = data_label());
257                 C_bss_cst(func_size, (arith)0, 1);
258         }
259         else
260                 func_res_label = 0;
261         /*      Special arrangements if the function result doesn't fit in
262                 the function return area of the EM machine.  The size of
263                 the function return area is implementation dependent.
264         */
265         lab_count = (label) 1;
266         return_label = text_label();
267         return2_label = text_label();
268         return_expr_occurred = 0;
269         LocalInit();
270         prc_entry(name);
271         if (! options['L'])     {       /* profiling */
272                 if (strcmp(last_fn_given, FileName) != 0)       {
273                         /* previous function came from other file */
274                         C_df_dlb(file_name_label = data_label());
275                         C_con_scon(last_fn_given = FileName,
276                                 (arith)(strlen(FileName) + 1));
277                 }
278                 /* enable debug trace of EM source */
279                 C_fil_dlb(file_name_label, (arith)0);
280                 C_lin((arith)LineNumber);
281         }
282 #ifdef DBSYMTAB
283         if (options['g']) {
284                 stb_string(def, FUNCTION, name);
285                 if (! strcmp(name, "main")) {
286                         C_ms_stb_cst(name, N_MAIN, 0, (arith) 0);
287                 }
288         }
289 #endif
290 }
291
292 end_proc(fbytes)
293         arith fbytes;
294 {
295         /*      end_proc() deals with the code to be generated at the end of
296                 a function, as there is:
297                 -       the EM ret instruction: "ret 0"
298                 -       loading of the function result in the function
299                         result area if there has been a return <expr>
300                         in the function body (see do_return_expr())
301                 -       indication of the use of floating points
302                 -       indication of the number of bytes used for
303                         formal parameters
304                 -       use of special identifiers such as "setjmp"
305                 -       "end" + number of bytes used for local variables
306         */
307         arith nbytes;
308         char optionsn = options['n'];
309
310 #ifdef  DATAFLOW
311         if (options['d'])
312                 DfaEndFunction();
313 #endif  /* DATAFLOW */
314         C_df_ilb(return2_label);
315         if (return_expr_occurred) C_asp(-func_size);
316         C_df_ilb(return_label);
317         prc_exit();
318 #ifndef LINT
319         if (return_expr_occurred) {
320                 if (func_res_label != 0)        {
321                         C_lae_dlb(func_res_label, (arith)0);
322                         store_block(func_type->tp_size, func_type->tp_align);
323                         C_lae_dlb(func_res_label, (arith)0);
324                         C_ret(pointer_size);
325                 }
326                 else
327                         C_ret(func_size);
328         }
329         else    C_ret((arith) 0);
330 #endif  /* LINT */
331
332         /* getting the number of "local" bytes is posponed until here,
333            because copying the function result in "func_res_label" may
334            need temporaries! However, local_level is now L_FORMAL2, because
335            L_LOCAL is already unstacked. Therefore, "unstack_level" must
336            also pass "sl_max_block" to the level above L_LOCAL.
337         */
338         nbytes = ATW(- local_level->sl_max_block);
339 #ifdef USE_TMP
340         C_beginpart(pro_id);
341         C_pro(func_name, nbytes);
342 #endif
343         if (fbytes > max_int) {
344                 error("%s has more than %ld parameter bytes",
345                         func_name, (long) max_int);
346         }
347         C_ms_par(fbytes);               /* # bytes for formals          */
348         if (sp_occurred[SP_SETJMP]) {   /* indicate use of "setjmp"     */
349                 options['n'] = 1;
350                 C_ms_gto();
351                 sp_occurred[SP_SETJMP] = 0;
352         }
353 #ifdef USE_TMP
354         C_endpart(pro_id);
355 #endif
356         LocalFinish();
357         C_end(nbytes);
358         if (nbytes > max_int) {
359                 error("%s has more than %ld bytes of local variables",
360                         func_name, (long) max_int);
361         }
362         options['n'] = optionsn;
363 }
364
365 do_return()
366 {
367         /*      do_return handles the case of a return without expression.
368                 This version branches to the return label, which is
369                 probably smarter than generating a direct return.
370                 Return sequences may be expensive.
371         */
372 #ifdef DBSYMTAB
373         if (options['g']) db_line(dot.tk_file, dot.tk_line);
374 #endif /* DBSYMTAB */
375         C_bra(return2_label);
376 }
377
378 do_return_expr(expr)
379         struct expr *expr;
380 {
381         /*      do_return_expr() generates the expression and the jump for
382                 a return statement with an expression.
383         */
384         ch7cast(&expr, RETURN, func_type);
385         code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
386         C_bra(return_label);
387         return_expr_occurred = 1;
388 }
389
390 code_declaration(idf, expr, lvl, sc)
391         register struct idf *idf;       /* idf to be declared   */
392         struct expr *expr;      /* initialisation; NULL if absent       */
393         int lvl;                /* declaration level    */
394         int sc;                 /* storage class, as in the declaration */
395 {
396         /*      code_declaration() does the actual declaration of the
397                 variable indicated by "idf" on declaration level "lvl".
398                 If the variable is initialised, the expression is given
399                 in "expr", but for global and static initialisations it
400                 is just non-zero, as the expression is not parsed yet.
401                 There are some cases to be considered:
402                 -       filter out typedefs, they don't correspond to code;
403                 -       global variables, coded only if initialized;
404                 -       local static variables;
405                 -       local automatic variables;
406                 Since the expression may be modified in the process,
407                 code_declaration() frees it after use, as the caller can
408                 no longer do so.
409
410                 If there is a storage class indication (EXTERN/STATIC),
411                 code_declaration() will generate an exa or ina.
412                 The sc is the actual storage class, as given in the
413                 declaration.  This is to allow:
414                         extern int a;
415                         int a = 5;
416                 while at the same time forbidding
417                         extern int a = 5;
418         */
419         register struct def *def = idf->id_def;
420         register arith size = def->df_type->tp_size;
421         int def_sc = def->df_sc;
422
423         if (def_sc == TYPEDEF)  {       /* no code for typedefs         */
424 #ifdef DBSYMTAB
425                 if (options['g']) {
426                         stb_typedef(def->df_type, idf->id_text);
427                 }
428 #endif /* DBSYMTAB */
429                 return;
430         }
431         if (sc == EXTERN && expr && !is_anon_idf(idf))
432                 error("%s is extern; cannot initialize", idf->id_text);
433         if (lvl == L_GLOBAL)    {       /* global variable      */
434                 /* is this an allocating declaration? */
435                 if (    (sc == 0 || sc == STATIC)
436                         && def->df_type->tp_fund != FUNCTION
437                         && size >= 0
438                 )
439                         def->df_alloc = ALLOC_SEEN;
440                 if (expr) {     /* code only if initialized */
441 #ifndef PREPEND_SCOPES
442                         code_scope(idf->id_text, def);
443 #endif /* PREPEND_SCOPES */
444                         def->df_alloc = ALLOC_DONE;
445                         C_df_dnam(idf->id_text);
446                 }
447         }
448         else
449         if (lvl >= L_LOCAL)     {       /* local variable       */
450                 /* STATIC, EXTERN, GLOBAL, IMPLICIT, AUTO or REGISTER */
451                 switch (def_sc) {
452                 case STATIC:
453                         if (def->df_type->tp_fund == FUNCTION) {
454                                 /* should produce "inp $function" ??? */
455                                 break;
456                         }
457                         /*      they are handled on the spot and get an
458                                 integer label in EM.
459                         */
460 #ifdef DBSYMTAB
461                         if (options['g'] && ! expr) {
462                                 stb_string(def, sc, idf->id_text);
463                         }
464 #endif /* DBSYMTAB */
465                         C_df_dlb((label)def->df_address);
466                         if (expr) { /* there is an initialisation */
467                         }
468                         else {  /* produce blank space */
469                                 if (size <= 0) {
470                                         error("size of %s unknown", idf->id_text);
471                                         size = (arith)0;
472                                 }
473                                 C_bss_cst(ATW(size), (arith)0, 1);
474                         }
475                         break;
476                 case EXTERN:
477                 case GLOBAL:
478                 case IMPLICIT:
479                         /* we are sure there is no expression */
480                         break;
481                 case AUTO:
482                 case REGISTER:
483 #ifdef DBSYMTAB
484                         if (options['g']) {
485                                 stb_string(def, sc, idf->id_text);
486                         }
487 #endif /* DBSYMTAB */
488                         if (expr)
489                                 loc_init(expr, idf);
490                         break;
491                 default:
492                         crash("bad local storage class");
493                         /*NOTREACHED*/
494                 }
495         }
496 }
497
498 loc_init(expr, id)
499         struct expr *expr;
500         register struct idf *id;
501 {
502         /*      loc_init() generates code for the assignment of
503                 expression expr to the local variable described by id.
504                 It frees the expression afterwards.
505         */
506         register struct expr *e = expr;
507         register struct type *tp = id->id_def->df_type;
508
509         ASSERT(id->id_def->df_sc != STATIC);
510         switch (tp->tp_fund)    {
511         case ARRAY:
512         case STRUCT:
513         case UNION:
514                 error("automatic %s cannot be initialized in declaration",
515                         symbol2str(tp->tp_fund));
516                 free_expression(e);
517                 return;
518         }
519         if (ISCOMMA(e)) {       /* embraced: int i = {12};      */
520 #ifndef NOROPTION
521                 if (options['R'])       {
522                         if (ISCOMMA(e->OP_LEFT)) /* int i = {{1}} */
523                                 expr_error(e, "extra braces not allowed");
524                         else
525                         if (e->OP_RIGHT != 0) /* int i = {1 , 2} */
526                                 expr_error(e, "too many initializers");
527                 }
528 #endif /* NOROPTION */
529                 while (e)       {
530                         loc_init(e->OP_LEFT, id);
531                         e = e->OP_RIGHT;
532                 }
533         }
534         else    {       /* not embraced */
535                 ch7cast(&expr, '=', tp);        /* may modify expr */
536 #ifndef LINT
537                 {
538                         struct value vl;
539
540                         EVAL(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
541                         vl.vl_class = Name;
542                         vl.vl_data.vl_idf = id;
543                         vl.vl_value = (arith)0;
544                         store_val(&vl, tp);
545                 }
546 #else   /* LINT */
547                 id->id_def->df_set = 1;
548 #endif  /* LINT */
549                 free_expression(expr);
550         }
551 }
552
553 bss(idf)
554         register struct idf *idf;
555 {
556         /*      bss() allocates bss space for the global idf.
557         */
558         arith size = idf->id_def->df_type->tp_size;
559
560 #ifndef PREPEND_SCOPES
561         code_scope(idf->id_text, idf->id_def);
562 #endif  /* PREPEND_SCOPES */
563 #ifdef DBSYMTAB
564         if (options['g']) {
565                 stb_string(idf->id_def, idf->id_def->df_sc, idf->id_text);
566         }
567 #endif /* DBSYMTAB */
568         /*      Since bss() is only called if df_alloc is non-zero, and
569                 since df_alloc is only non-zero if size >= 0, we have:
570         */
571         /*      but we already gave a warning at the declaration of the
572                 array. Besides, the message given here does not apply to
573                 voids
574
575         if (options['R'] && size == 0)
576                 warning("actual array of size 0");
577         */
578         C_df_dnam(idf->id_text);
579         C_bss_cst(ATW(size), (arith)0, 1);
580 }
581
582 formal_cvt(df)
583         register struct def *df;
584 {
585         /*      formal_cvt() converts a formal parameter of type char or
586                 short from int to that type.
587         */
588         register struct type *tp = df->df_type;
589
590         if (tp->tp_size != int_size &&
591                 (tp->tp_fund == CHAR || tp->tp_fund == SHORT)
592         ) {
593                 LoadLocal(df->df_address, int_size);
594                 /* conversion(int_type, df->df_type); ???
595                    No, you can't do this on the stack! (CJ)
596                 */
597                 StoreLocal(df->df_address, tp->tp_size);
598         }
599 }
600
601 #ifdef  LINT
602 /*ARGSUSED*/
603 #endif  /* LINT */
604 code_expr(expr, val, code, tlbl, flbl)
605         struct expr *expr;
606         label tlbl, flbl;
607 {
608         /*      code_expr() is the parser's interface to the expression code
609                 generator.  If line number trace is wanted, it generates a
610                 lin instruction.  EVAL() is called directly.
611         */
612 #ifndef LINT
613         if (! options['L'])     /* profiling    */
614                 C_lin((arith)(expr->ex_line));
615 #ifdef DBSYMTAB
616         if (options['g']) db_line(expr->ex_file, (unsigned int)expr->ex_line);
617 #endif
618         EVAL(expr, val, code, tlbl, flbl);
619 #else   /* LINT */
620         lint_expr(expr, code ? USED : IGNORED);
621 #endif  /* LINT */
622 }
623
624 /*      The FOR/WHILE/DO/SWITCH stacking mechanism:
625         stack_stmt() has to be called at the entrance of a
626         for, while, do or switch statement to indicate the
627         EM labels where a subsequent break or continue causes
628         the program to jump to.
629 */
630 static struct stmt_block *stmt_stack;   /* top of statement stack */
631
632 /*      code_break() generates EM code needed at the occurrence of "break":
633         it generates a branch instruction to the break label of the
634         innermost statement in which break has a meaning.
635         As "break" is legal in any of 'while', 'do', 'for' or 'switch',
636         which are the only ones that are stacked, only the top of
637         the stack is interesting.
638 */
639 code_break()
640 {
641         register struct stmt_block *stmt_block = stmt_stack;
642
643 #ifdef DBSYMTAB
644         if (options['g']) db_line(dot.tk_file, dot.tk_line);
645 #endif /* DBSYMTAB */
646         if (stmt_block)
647                 C_bra(stmt_block->st_break);
648         else
649                 error("break not inside for, while, do or switch");
650 }
651
652 /*      code_continue() generates EM code needed at the occurrence of
653         "continue":
654         it generates a branch instruction to the continue label of the
655         innermost statement in which continue has a meaning.
656 */
657 code_continue()
658 {
659         register struct stmt_block *stmt_block = stmt_stack;
660
661         while (stmt_block)      {
662                 if (stmt_block->st_continue)    {
663 #ifdef DBSYMTAB
664                         if (options['g']) db_line(dot.tk_file, dot.tk_line);
665 #endif /* DBSYMTAB */
666                         C_bra(stmt_block->st_continue);
667                         return;
668                 }
669                 stmt_block = stmt_block->next;
670         }
671         error("continue not inside for, while or do");
672 }
673
674 stack_stmt(break_label, cont_label)
675         label break_label, cont_label;
676 {
677         register struct stmt_block *stmt_block = new_stmt_block();
678
679         stmt_block->next = stmt_stack;
680         stmt_block->st_break = break_label;
681         stmt_block->st_continue = cont_label;
682         stmt_stack = stmt_block;
683 }
684
685 unstack_stmt()
686 {
687         /*      unstack_stmt() unstacks the data of a statement
688                 which may contain break or continue
689         */
690         register struct stmt_block *sbp = stmt_stack;
691         stmt_stack = sbp->next;
692         free_stmt_block(sbp);
693 }
694
695 static label prc_name;
696
697 prc_entry(name)
698         char *name;
699 {
700         if (options['p']) {
701                 C_df_dlb(prc_name = data_label());
702                 C_rom_scon(name, (arith) (strlen(name) + 1));
703                 C_lae_dlb(prc_name, (arith) 0);
704                 C_cal("procentry");
705                 C_asp(pointer_size);
706         }
707 }
708
709 prc_exit()
710 {
711         if (options['p']) {
712                 C_lae_dlb(prc_name, (arith) 0);
713                 C_cal("procexit");
714                 C_asp(pointer_size);
715         }
716 }
717
718 #ifdef DBSYMTAB
719 db_line(file, line)
720         char            *file;
721         unsigned int    line;
722 {
723         static unsigned oldline;
724         static char     *oldfile;
725
726         if (file != oldfile || line != oldline) {
727                 C_ms_std((char *) 0, N_SLINE, (int) line);
728                 oldline = line;
729                 oldfile = file;
730         }
731 }
732 #endif /* DBSYMTAB */