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