1 /* D E S I G N A T O R E V A L U A T I O N */
3 /* Code generation for designators.
4 This file contains some routines that generate code common to address
5 as well as value computations, and leave a description in a "desig"
6 structure. It also contains routines to load an address, load a value
25 struct desig InitDesig = {DSG_INIT, 0, 0, NULLDEF, 0};
26 struct withdesig *WithDesigs;
30 properly(ds, size, al)
31 register struct desig *ds;
34 /* Check if it is allowed to load or store the value indicated
36 - if the size is not either a multiple or a dividor of the
38 - if the alignment is at least "word" then OK.
39 - if size is dividor of word_size and alignment >= size then OK.
40 - otherwise check alignment of address. This can only be done
44 arith szmodword = size % word_size; /* 0 if multiple of wordsize */
45 arith wordmodsz = word_size % size; /* 0 if dividor of wordsize */
47 if( szmodword && wordmodsz ) return 0;
48 if( al >= word_align ) return 1;
49 if( szmodword && al >= szmodword ) return 1;
51 return ds->dsg_kind == DSG_FIXED &&
52 ((! szmodword && ds->dsg_offset % word_align == 0) ||
53 (! wordmodsz && ds->dsg_offset % size == 0));
56 CodeCopy(lhs, rhs, sz, psize)
57 register struct desig *lhs, *rhs;
65 lhs->dsg_offset += sz;
66 rhs->dsg_offset += sz;
73 CodeMove(rhs, left, rtp)
74 register struct desig *rhs;
75 register struct node *left;
79 register struct desig *lhs = &dsl;
80 register struct type *ltp = left->nd_type;
83 /* Generate code for an assignment. Testing of type
84 compatibility and the like is already done.
85 Go through some (considerable) trouble to see if
86 a BLM can be generated.
89 switch( rhs->dsg_kind ) {
92 if( rtp->tp_fund == T_STRINGCONST ) {
94 C_blm(lhs->dsg_packed ? ltp->tp_psize : ltp->tp_size);
110 CodeDesig(left, lhs);
111 tpsize = lhs->dsg_packed ? ltp->tp_psize : ltp->tp_size;
112 if( lhs->dsg_kind == DSG_FIXED &&
113 lhs->dsg_offset % word_size == rhs->dsg_offset % word_size
117 if( size > 6 * word_size ) {
131 for( sz = 2 * word_size; sz; sz -= word_size) {
133 /* Then copy dwords, words.
134 Depend on peephole optimizer
136 CodeCopy(lhs, rhs, sz, &size);
141 if( lhs->dsg_kind == DSG_PLOADED ||
142 lhs->dsg_kind == DSG_INDEXED ) {
153 register struct desig *ds;
154 register struct type *tp;
156 /* Generate code to load the value of the designator described
159 arith size = ds->dsg_packed ? tp->tp_psize : tp->tp_size;
160 int algn = ds->dsg_packed ? tp->tp_palign : tp->tp_align;
162 switch( ds->dsg_kind ) {
167 if( ds->dsg_offset % word_size == 0 ) {
168 if ( size == word_size ) {
170 C_loe_dnam(ds->dsg_name, ds->dsg_offset);
172 C_lol(ds->dsg_offset);
174 } else if ( size == word_size * 2) {
176 C_lde_dnam(ds->dsg_name, ds->dsg_offset);
178 C_ldl(ds->dsg_offset);
185 if( properly(ds, size, algn) ) {
190 crash("(CodeValue)");
198 crash("(CodeValue)");
202 if (size < word_size && tp->tp_fund == T_SUBRANGE &&
203 BaseType(tp)->tp_fund == T_INTEGER && tp->sub_lb < 0) {
208 ds->dsg_kind = DSG_LOADED;
212 register struct desig *ds;
213 register struct type *tp;
215 /* Generate code to store the value on the stack in the designator
219 arith size = ds->dsg_packed ? tp->tp_psize : tp->tp_size;
220 int algn = ds->dsg_packed ? tp->tp_palign : tp->tp_align;
224 switch( ds->dsg_kind ) {
226 if( ds->dsg_offset % word_size == 0 ) {
227 if ( size == word_size ) {
229 C_ste_dnam(ds->dsg_name, ds->dsg_offset);
231 C_stl(ds->dsg_offset);
233 } else if ( size == word_size * 2) {
235 C_sde_dnam(ds->dsg_name, ds->dsg_offset);
237 C_sdl(ds->dsg_offset);
245 if( properly(ds, size, algn) ) {
249 crash("(CodeStore)");
257 crash("(CodeStore)");
261 ds->dsg_kind = DSG_INIT;
265 register struct desig *ds;
267 /* Generate code to load the address of the designator described
271 switch( ds->dsg_kind ) {
274 C_adp(ds->dsg_offset);
279 C_lae_dnam(ds->dsg_name, ds->dsg_offset);
282 C_lal(ds->dsg_offset);
284 ds->dsg_def->df_flags |= D_NOREG;
288 if ( word_size == pointer_size ) {
290 C_loe_dnam(ds->dsg_name, ds->dsg_offset);
292 C_lol(ds->dsg_offset);
296 C_lde_dnam(ds->dsg_name, ds->dsg_offset);
298 C_ldl(ds->dsg_offset);
307 crash("(CodeAddress)");
312 ds->dsg_kind = DSG_PLOADED;
315 CodeFieldDesig(df, ds)
316 register struct def *df;
317 register struct desig *ds;
319 /* Generate code for a field designator. Only the code common for
320 address as well as value computation is generated, and the
321 resulting information on where to find the designator is placed
322 in "ds". "df" indicates the definition of the field.
325 if( ds->dsg_kind == DSG_INIT ) {
326 /* In a WITH statement. We must find the designator in the
327 WITH statement, and act as if the field is a selection
329 So, first find the right WITH statement, which is the
330 first one of the proper record type, which is
331 recognized by its scope indication.
333 register struct withdesig *wds = WithDesigs;
337 while( wds->w_scope != df->df_scope ) {
342 /* Found it. Now, act like it was a selection.
345 assert(ds->dsg_kind == DSG_PFIXED);
348 switch( ds->dsg_kind ) {
351 ds->dsg_offset += df->fld_off;
357 ds->dsg_kind = DSG_PLOADED;
358 ds->dsg_offset = df->fld_off;
362 crash("(CodeFieldDesig)");
365 ds->dsg_packed = df->fld_flags & F_PACKED;
369 register struct def *df;
370 register struct desig *ds;
372 /* Generate code for a variable represented by a "def" structure.
373 Of course, there are numerous cases: the variable is local,
374 it is a value parameter, it is a var parameter, it is one of
375 those of an enclosing procedure, or it is global.
377 register struct scope *sc = df->df_scope;
379 assert(ds->dsg_kind == DSG_INIT);
382 /* this variable has been given a name, so it is global.
383 It is directly accessible.
385 ds->dsg_name = df->var_name;
387 ds->dsg_kind = DSG_FIXED;
391 if( sc->sc_level != proclevel ) {
392 /* the variable is local to a statically enclosing procedure.
394 assert(proclevel > sc->sc_level);
396 df->df_flags |= D_NOREG;
397 if( df->df_flags & (D_VARPAR|D_VALPAR) ) {
398 /* value or var parameter
400 C_lxa((arith) (proclevel - sc->sc_level));
401 if( (df->df_flags & D_VARPAR) ||
402 IsConformantArray(df->df_type) ) {
403 /* var parameter or conformant array.
404 For conformant array's, the address is
410 ds->dsg_kind = DSG_PLOADED;
415 C_lxl((arith) (proclevel - sc->sc_level));
417 ds->dsg_kind = DSG_PLOADED;
418 ds->dsg_offset = df->var_off;
422 /* Now, finally, we have a local variable or a local parameter
424 if( (df->df_flags & D_VARPAR) || IsConformantArray(df->df_type) )
425 /* a var parameter; address directly accessible. */
426 ds->dsg_kind = DSG_PFIXED;
428 ds->dsg_kind = DSG_FIXED;
430 ds->dsg_offset = df->var_off;
434 CodeBoundDesig(df, ds)
435 register struct def *df;
436 register struct desig *ds;
438 /* Generate code for the lower- and upperbound of a conformant array */
440 assert(ds->dsg_kind == DSG_INIT);
442 if( df->df_scope->sc_level < proclevel ) {
443 C_lxa((arith) (proclevel - df->df_scope->sc_level));
444 C_lof(df->bnd_type->arr_cfdescr);
445 if( df->df_kind == D_UBOUND ) {
446 C_lxa((arith) (proclevel - df->df_scope->sc_level));
447 C_lof(df->bnd_type->arr_cfdescr+word_size);
452 C_lol(df->bnd_type->arr_cfdescr);
453 if( df->df_kind == D_UBOUND ) {
454 C_lol(df->bnd_type->arr_cfdescr+word_size);
459 ds->dsg_kind = DSG_LOADED;
462 CodeFuncDesig(df, ds)
463 register struct def *df;
464 register struct desig *ds;
466 /* generate code to store the function result */
468 if( df->df_scope->sc_level + 1 < proclevel ) {
469 /* Assignment to function-identifier in the declaration-part of
470 the function (i.e. in the statement-part of a nested function
473 if( !options['R'] ) {
475 C_lxl((arith) (proclevel - df->df_scope->sc_level - 1));
480 C_lxl((arith) (proclevel - df->df_scope->sc_level - 1));
481 ds->dsg_kind = DSG_PLOADED;
484 /* Assignment to function-identifier in the statement-part of
487 if( !options['R'] ) {
492 ds->dsg_kind = DSG_FIXED;
494 assert(df->prc_res < 0);
495 ds->dsg_offset = df->prc_res;
499 register struct node *nd;
500 register struct desig *ds;
502 /* Generate code for a designator. Use divide and conquer
505 register struct def *df;
507 switch( nd->nd_class ) { /* Divide */
511 switch( (int) df->df_kind ) {
513 CodeFieldDesig(df, ds);
517 CodeVarDesig(df, ds);
522 CodeBoundDesig(df, ds);
526 CodeFuncDesig(df, ds);
530 crash("(CodeDesig) Def");
535 assert(nd->nd_symb == '.');
537 CodeDesig(nd->nd_left, ds);
538 CodeFieldDesig(nd->nd_def, ds);
544 assert(nd->nd_symb == '[');
546 CodeDesig(nd->nd_left, ds);
548 CodePExpr(nd->nd_right);
550 /* Now load address of descriptor
552 tp = nd->nd_left->nd_type;
553 if( IsConformantArray(tp) ) {
554 if( tp->arr_sclevel < proclevel ) {
555 C_lxa((arith) (proclevel - tp->arr_sclevel));
556 C_adp(tp->arr_cfdescr);
559 C_lal(tp->arr_cfdescr);
562 C_lae_dlb(tp->arr_ardescr, (arith) 0);
567 ds->dsg_kind = DSG_INDEXED;
568 ds->dsg_packed = IsPacked(tp);
573 assert(nd->nd_symb == '^');
575 if( nd->nd_right->nd_type->tp_fund == T_FILE ) {
576 CodeDAddress(nd->nd_right);
580 ds->dsg_kind = DSG_PLOADED;
585 CodeDesig(nd->nd_right, ds);
586 switch(ds->dsg_kind) {
588 ds->dsg_kind = DSG_PLOADED;
594 CodeValue(ds, nd->nd_right->nd_type);
595 ds->dsg_kind = DSG_PLOADED;
600 ds->dsg_kind = DSG_PFIXED;
604 crash("(CodeDesig) Uoper");
609 crash("(CodeDesig) class");