1 /* C O D E G E N E R A T I O N R O U T I N E S */
27 C_fil_dlb((label) 1, (arith) 0);
31 register struct def * df;
33 df->prc_label = ++data_label;
34 C_df_dlb(df->prc_label);
35 C_rom_scon(df->df_idf->id_text, (arith)(strlen(df->df_idf->id_text) + 1));
39 register struct node *nd;
41 C_df_dlb(++data_label);
43 /* A string of the string_type is null-terminated. */
44 if( nd->nd_type == string_type )
45 C_rom_scon(nd->nd_STR, nd->nd_SLE + 1); /* with trailing '\0' */
47 C_rom_scon(nd->nd_STR, nd->nd_SLE); /* no trailing '\0' */
49 nd->nd_SLA = data_label;
53 register struct node *nd;
56 C_df_dlb(++data_label);
57 nd->nd_RLA = data_label;
58 C_rom_fcon(nd->nd_REL, nd->nd_type->tp_size);
64 /* generate bss segments for global variables */
65 register struct def *df = GlobalScope->sc_def;
68 if( df->df_kind == D_VARIABLE ) {
69 C_df_dnam(df->var_name);
71 /* ??? undefined value ??? */
72 C_bss_cst(df->df_type->tp_size, (arith) 0, 0);
74 df = df->df_nextinscope;
80 register struct scope *sc;
82 /* Create code for goto descriptors
85 register struct node *lb = sc->sc_lablist;
89 if( lb->nd_def->lab_descr ) {
91 /* create local for target SP */
92 sc->sc_off = -WA(pointer_size - sc->sc_off);
96 C_df_dlb(lb->nd_def->lab_descr);
97 C_rom_ilb(lb->nd_def->lab_no);
98 C_rom_cst(sc->sc_off);
110 register struct def *df;
112 /* Generate code at the beginning of the main program,
113 procedure or function.
116 arith StackAdjustment = 0;
117 arith offset = 0; /* offset to save StackPointer */
119 TmpOpen(df->prc_vis->sc_scope);
121 if ( df->df_kind == D_MODULE) /* nothing */ ;
122 else if (df->df_kind == D_PROGRAM ) {
124 C_pro_narg("_m_a_i_n");
126 offset = CodeGtoDescr(df->prc_vis->sc_scope);
129 /* initialize external files */
131 /* ignore floating point underflow */
133 C_loc((arith) (1 << EFUNFL));
137 else if (df->df_kind & (D_PROCEDURE | D_FUNCTION)) {
139 register struct paramlist *param;
141 C_pro_narg(df->prc_name);
142 C_ms_par(df->df_type->prc_nbpar);
144 offset = CodeGtoDescr(df->prc_vis->sc_scope);
148 C_lae_dlb(df->prc_label,(arith)0);
153 /* prc_bool is the local variable that indicates if the
154 * function result is assigned. This and can be disabled
155 * with the -R option. The variable, however, is always
156 * allocated and initialized.
159 C_zer((arith) int_size);
162 for( param = ParamList(df->df_type); param; param = param->next) {
163 if( !IsVarParam(param) ) {
164 tp = TypeOfParam(param);
166 if( IsConformantArray(tp) ) {
167 /* Here, we have to make a copy of the
168 array. We must also remember how much
169 room is reserved for copies, because
170 we have to adjust the stack pointer
174 if( !StackAdjustment ) {
175 /* First time we get here
177 StackAdjustment = NewInt(0);
179 C_stl(StackAdjustment);
181 /* Address of array */
182 C_lol(param->par_def->var_off);
184 /* First compute size of the array */
185 C_lol(tp->arr_cfdescr + word_size);
187 /* gives number of elements */
188 C_lol(tp->arr_cfdescr + 2 * word_size);
189 /* size of elements */
191 C_loc(word_size - 1);
193 C_loc(word_size - 1);
197 C_lol(StackAdjustment);
199 C_stl(StackAdjustment);
200 /* remember stack adjustments */
202 C_los(word_size); /* copy */
204 /* push new address of array
205 ... downwards ... ???
207 C_stl(param->par_def->var_off);
213 crash("(CodeBeginBlock)");
218 /* save SP for non-local jump */
222 return StackAdjustment;
225 CodeEndBlock(df, StackAdjustment)
226 register struct def *df;
227 arith StackAdjustment;
229 if( df->df_kind == D_PROGRAM) {
233 else if (df->df_kind & (D_PROCEDURE | D_FUNCTION)) {
236 if( StackAdjustment ) {
237 /* remove copies of conformant arrays */
238 C_lol(StackAdjustment);
240 FreeInt(StackAdjustment);
243 RegisterMessages(df->prc_vis->sc_scope->sc_def);
246 C_lae_dlb(df->prc_label,(arith)0);
250 if( tp = ResultType(df->df_type) ) {
251 if( !options['R'] ) {
252 C_lin((arith)LineNumber);
257 if( tp->tp_size == word_size )
259 else if( tp->tp_size == 2 * word_size )
272 crash("(CodeEndBlock)");
276 C_end(- df->prc_vis->sc_scope->sc_off);
280 CodeExpr(nd, ds, true_label)
281 register struct node *nd;
282 register struct desig *ds;
285 register struct type *tp = nd->nd_type;
287 if( tp->tp_fund == T_REAL ) fp_used = 1;
289 switch( nd->nd_class ) {
291 switch( nd->nd_symb ) {
297 C_lae_dlb(nd->nd_RLA, (arith) 0);
301 if( tp->tp_fund == T_CHAR )
304 C_lae_dlb(nd->nd_SLA, (arith) 0);
310 crash("(CodeExpr Value)");
313 ds->dsg_kind = DSG_LOADED;
318 ds->dsg_kind = DSG_LOADED;
322 CodeBoper(nd, true_label);
323 ds->dsg_kind = DSG_LOADED;
324 true_label = NO_LABEL;
328 register arith *st = nd->nd_set;
331 ds->dsg_kind = DSG_LOADED;
336 for( i = tp->tp_size / word_size, st += i; i > 0; i--)
344 ds->dsg_kind = DSG_LOADED;
349 ds->dsg_kind = DSG_LOADED;
353 /* actual procedure/function parameter */
354 struct node *left = nd->nd_left;
355 struct def *df = left->nd_def;
357 if( df->df_kind & D_ROUTINE ) {
358 int level = df->df_scope->sc_level;
360 if( level <= 0 || (df->df_flags & D_EXTERNAL) )
363 C_lxl((arith) (proclevel - level));
366 ds->dsg_kind = DSG_LOADED;
369 assert(df->df_kind == D_VARIABLE);
370 assert(df->df_type->tp_fund & T_ROUTINE);
384 /* convert integer to real */
385 struct node *right = nd->nd_right;
388 Int2Real(right->nd_type->tp_size);
389 ds->dsg_kind = DSG_LOADED;
393 /* convert integer to long integer */
394 struct node *right = nd->nd_right;
398 ds->dsg_kind = DSG_LOADED;
402 /* convert a long to an integer */
403 struct node *right = nd->nd_right;
407 ds->dsg_kind = DSG_LOADED;
411 crash("(CodeExpr : bad node type)");
416 /* Only for boolean expressions
424 register struct node *nd;
426 register struct type *tp = nd->nd_type;
428 CodePExpr(nd->nd_right);
430 switch( nd->nd_symb ) {
432 assert(tp->tp_fund & T_NUMERIC);
433 if( tp->tp_fund == T_INTEGER || tp->tp_fund == T_LONG )
447 crash("(CodeUoper)");
452 Operands(leftop, rightop)
453 register struct node *leftop, *rightop;
459 CodeBoper(expr, true_label)
460 register struct node *expr; /* the expression tree itself */
461 label true_label; /* label to jump to in logical exprs */
463 register struct node *leftop = expr->nd_left;
464 register struct node *rightop = expr->nd_right;
465 register struct type *tp = expr->nd_type;
467 switch( expr->nd_symb ) {
469 Operands(leftop, rightop);
470 switch( tp->tp_fund ) {
482 crash("(CodeBoper: bad type +)");
487 Operands(leftop, rightop);
488 switch( tp->tp_fund ) {
501 crash("(CodeBoper: bad type -)");
506 Operands(leftop, rightop);
507 switch( tp->tp_fund ) {
519 crash("(CodeBoper: bad type *)");
524 Operands(leftop, rightop);
525 if( tp->tp_fund == T_REAL )
528 crash("(CodeBoper: bad type /)");
533 Operands(leftop, rightop);
534 if( tp->tp_fund == T_INTEGER ) {
535 C_cal(expr->nd_symb == MOD ? "_mdi" : "_dvi");
536 C_asp(2 * tp->tp_size);
539 else if( tp->tp_fund == T_LONG) {
540 C_cal(expr->nd_symb == MOD ? "_mdil" : "_dvil");
541 C_asp(2 * tp->tp_size);
545 crash("(CodeBoper: bad type MOD)");
556 tp = BaseType(rightop->nd_type);
558 switch( tp->tp_fund ) {
575 if( expr->nd_symb == GREATEREQUAL ) {
576 /* A >= B is the same as A equals A + B
578 C_dup(2 * tp->tp_size);
583 else if( expr->nd_symb == LESSEQUAL ) {
584 /* A <= B is the same as A - B = []
596 C_loc((arith) IsString(tp));
598 C_asp(2 * pointer_size + word_size);
607 crash("(CodeBoper : bad type COMPARE)");
609 truthvalue(expr->nd_symb);
610 if( true_label != NO_LABEL )
615 /* In this case, evaluate right hand side first! The INN
616 instruction expects the bit number on top of the stack
620 if( rightop->nd_type == emptyset_type )
621 C_and(rightop->nd_type->tp_size);
623 C_inn(rightop->nd_type->tp_size);
625 if( true_label != NO_LABEL )
631 Operands(leftop, rightop);
632 if( expr->nd_symb == AND )
636 if( true_label != NO_LABEL )
640 crash("(CodeBoper Bad operator %s\n)",
641 symbol2str(expr->nd_symb));
645 /* truthvalue() serves as an auxiliary function of CodeBoper */
668 crash("(truthvalue)");
674 register struct node *nd;
676 register struct type *tp = nd->nd_type;
681 assert(nd->nd_class == Link && nd->nd_symb == ',');
683 CodeEl(nd->nd_left, tp);
689 register struct node *nd;
690 register struct type *tp;
692 if( nd->nd_class == Link && nd->nd_symb == UPTO ) {
693 Operands(nd->nd_left, nd->nd_right);
694 C_loc(tp->tp_size); /* push size */
695 C_cal("_bts"); /* library routine to fill set */
696 C_asp(3 * word_size);
706 CodeParameters(param, arg)
707 struct paramlist *param;
710 register struct type *tp, *left_tp, *last_tp = (struct type *) 0;
714 assert(param && arg);
717 last_tp = CodeParameters(param->next, arg->nd_right);
719 tp = TypeOfParam(param);
721 left_tp = left->nd_type;
723 if( IsConformantArray(tp) ) {
725 /* push descriptors only once */
726 CodeConfDescr(tp, left_tp);
731 if( IsVarParam(param) ) {
735 if( left_tp->tp_fund == T_STRINGCONST ) {
736 CodePString(left, tp);
741 CodeExpr(left, &ds, NO_LABEL);
742 CodeValue(&ds, left_tp);
744 RangeCheck(tp, left_tp);
745 if( tp == real_type && BaseType(left_tp) == int_type )
751 CodeConfDescr(ftp, atp)
752 register struct type *ftp, *atp;
754 struct type *elemtp = ftp->arr_elem;
756 if( IsConformantArray(elemtp) )
757 CodeConfDescr(elemtp, atp->arr_elem);
759 if( atp->tp_fund == T_STRINGCONST ) {
761 C_loc(atp->tp_psize - 1);
764 else if( IsConformantArray(atp) ) {
765 if( atp->arr_sclevel < proclevel ) {
766 C_lxa((arith) proclevel - atp->arr_sclevel);
767 C_adp(atp->arr_cfdescr);
770 C_lal(atp->arr_cfdescr);
772 C_loi(3 * word_size);
774 else { /* normal array */
775 assert(atp->tp_fund == T_ARRAY);
776 assert(!IsConformantArray(atp));
777 C_lae_dlb(atp->arr_ardescr, (arith) 0);
778 C_loi( 3 * word_size);
786 /* no null padding */
787 C_lae_dlb(nd->nd_SLA, (arith) 0);
792 register struct node *nd;
794 /* Generate code for a procedure call. Checking of parameters
795 and result is already done.
797 register struct node *left = nd->nd_left;
798 register struct node *right = nd->nd_right;
799 register struct def *df = left->nd_def;
800 register struct type *result_tp;
802 assert(IsProcCall(left));
804 if( left->nd_type == std_type ) {
810 (void) CodeParameters(ParamList(left->nd_type), right);
812 assert(left->nd_class == Def);
815 if( df->df_kind & D_ROUTINE ) {
816 int level = df->df_scope->sc_level;
818 if( level > 0 && !(df->df_flags & D_EXTERNAL) )
819 C_lxl((arith) (proclevel - level));
821 C_asp(left->nd_type->prc_nbpar);
824 label l1 = ++text_label;
825 label l2 = ++text_label;
827 assert(df->df_kind == D_VARIABLE);
829 /* Push value of procedure/function parameter */
832 /* Test if value is a global or local procedure/function */
839 /* At this point, on top of the stack the LB */
841 /* Now, the name of the procedure/function */
843 C_asp(pointer_size + left->nd_type->prc_nbpar);
846 /* value is a global procedure/function */
848 C_asp(pointer_size); /* no LB needed */
850 C_asp(left->nd_type->prc_nbpar);
854 if( result_tp = ResultType(left->nd_type) )
855 C_lfr(result_tp->tp_size);
861 register struct node *arg = nd->nd_right;
862 register struct node *left = arg->nd_left;
863 register struct type *tp = BaseType(left->nd_type);
864 int req = nd->nd_left->nd_def->df_value.df_reqname;
866 assert(arg->nd_class == Link && arg->nd_symb == ',');
873 else if ( tp == long_type )
884 if( tp == int_type || tp == long_type )
896 assert(tp == real_type);
926 assert(tp == real_type);
932 assert(tp == real_type);
953 if( tp == long_type) Int2Long();
960 if( bounded(left->nd_type) )
961 genrck(left->nd_type);
967 if( tp == long_type ) Int2Long();
969 if( tp == long_type ) Long2Int(); /* bool_size == int_size */
986 if( tp == text_type )
989 C_loc(tp->next->tp_psize);
990 /* ??? elements of packed size ??? */
991 if( req == R_REWRITE )
995 C_asp(pointer_size + word_size);
1005 C_asp(pointer_size);
1011 C_asp(pointer_size);
1015 label lba = tp->arr_ardescr;
1019 arg = arg->nd_right;
1020 left = arg->nd_left;
1022 arg = arg->nd_right;
1023 left = arg->nd_left;
1025 C_lae_dlb(left->nd_type->arr_ardescr, (arith) 0);
1026 C_lae_dlb(lba, (arith) 0);
1028 C_asp(4 * pointer_size + word_size);
1033 /* change sequence of arguments of the library routine
1034 _unp to merge code of R_PACK and R_UNPACK.
1036 label lba, lbz = tp->arr_ardescr;
1039 if (tp->tp_fund == T_SUBRANGE &&
1043 else C_loc((arith) 0);
1045 arg = arg->nd_right;
1046 left = arg->nd_left;
1048 lba = left->nd_type->arr_ardescr;
1049 arg = arg->nd_right;
1050 left = arg->nd_left;
1052 C_lae_dlb(lbz, (arith) 0);
1053 C_lae_dlb(lba, (arith) 0);
1055 C_asp(4 * pointer_size + 2 * word_size);
1062 C_loc(PointedtoType(tp)->tp_size);
1067 C_asp(pointer_size + word_size);
1077 C_asp(pointer_size);
1085 C_cal("_hlt"); /* can't return */
1086 C_asp(int_size); /* help the optimizer(s) */
1097 /* convert a long to integer */
1099 if (int_size == long_size) return;
1108 /* convert integer to long */
1110 if (int_size == long_size) return;
1116 Int2Real(size) /* size is different for integers and longs */
1119 /* convert integer to real */
1127 /* convert real to integer */
1133 RangeCheck(tpl, tpr)
1134 register struct type *tpl, *tpr;
1136 /* Generate a range check if neccessary
1139 arith llo, lhi, rlo, rhi;
1141 if( bounded(tpl) ) {
1142 /* in this case we might need a range check */
1144 /* yes, we need one */
1147 /* both types are restricted. check the bounds to see
1148 whether we need a range check. We don't need one
1149 if the range of values of the right hand side is a
1150 subset of the range of values of the left hand side.
1152 getbounds(tpl, &llo, &lhi);
1153 getbounds(tpr, &rlo, &rhi);
1154 if( llo > rlo || lhi < rhi )
1161 register struct type *tp;
1163 /* Generate a range check descriptor for type "tp" when
1164 necessary. Return its label.
1171 if( options['R'] ) return;
1173 getbounds(tp, &lb, &ub);
1175 if( tp->tp_fund == T_SUBRANGE ) {
1176 if( !(o1 = tp->sub_rck) ) {
1177 tp->sub_rck = o1 = ++data_label;
1181 else if( !(o1 = tp->enm_rck) ) {
1182 tp->enm_rck = o1 = ++data_label;
1190 C_lae_dlb(o1, (arith) 0);
1195 register struct node *nd;
1197 /* Generate code to push the value of the expression "nd"
1201 struct desig designator;
1202 struct type *tp = BaseType(nd->nd_type);
1204 designator = InitDesig;
1205 CodeExpr(nd, &designator, NO_LABEL);
1206 if( tp->tp_fund & (T_ARRAY | T_RECORD) )
1207 CodeAddress(&designator);
1209 CodeValue(&designator, nd->nd_type);
1215 /* Generate code to push the address of the designator "nd"
1219 struct desig designator;
1221 designator = InitDesig;
1222 CodeDesig(nd, &designator);
1223 CodeAddress(&designator);
1227 register struct node *nd;
1229 /* Generate code to store the expression on the stack
1230 into the designator "nd".
1233 struct desig designator;
1235 designator = InitDesig;
1236 CodeDesig(nd, &designator);
1237 CodeStore(&designator, nd->nd_type);
1240 RegisterMessages(df)
1241 register struct def *df;
1243 register struct type *tp;
1245 for( ; df; df = df->df_nextinscope ) {
1246 if( df->df_kind == D_VARIABLE && !(df->df_flags & D_NOREG) ) {
1247 /* Examine type and size
1249 tp = BaseType(df->df_type);
1250 if( df->df_flags & D_VARPAR || tp->tp_fund & T_POINTER )
1251 C_ms_reg(df->var_off, pointer_size,
1254 else if( df->df_flags & D_LOOPVAR )
1255 C_ms_reg(df->var_off, tp->tp_size, reg_loop,2);
1256 else if( tp->tp_fund & T_NUMERIC )
1257 C_ms_reg(df->var_off, tp->tp_size,
1258 tp->tp_fund == T_REAL ? reg_float : reg_any, 0);