Subversion Repositories tendra.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
 
32
 
33
/*
34
			    VERSION INFORMATION
35
			    ===================
36
 
37
--------------------------------------------------------------------------
38
$Header: /u/g/release/CVSROOT/Source/src/installers/sparc/common/regexps.c,v 1.2 1998/03/15 16:00:45 pwe Exp $
39
--------------------------------------------------------------------------
40
$Log: regexps.c,v $
41
 * Revision 1.2  1998/03/15  16:00:45  pwe
42
 * regtrack dwarf dagnostics added
43
 *
44
 * Revision 1.1.1.1  1998/01/17  15:55:55  release
45
 * First version to be checked into rolling release.
46
 *
47
 * Revision 1.4  1996/11/15  18:43:38  pwe
48
 * possible alias with bitfields
49
 *
50
 * Revision 1.3  1996/04/17  08:26:26  john
51
 * Fixed bug with mixed current envs
52
 *
53
 * Revision 1.2  1995/12/15  10:26:51  john
54
 * Fixed to handle current_env
55
 *
56
 * Revision 1.1.1.1  1995/03/13  10:18:54  john
57
 * Entered into CVS
58
 *
59
 * Revision 1.4  1994/11/21  14:29:46  djch
60
 * Added bug fix from ifc to couldbe where globals might not be noticed.
61
 *
62
 * Revision 1.3  1994/07/07  16:11:33  djch
63
 * Jul94 tape
64
 *
65
 * Revision 1.2  1994/05/13  13:07:58  djch
66
 * Incorporates improvements from expt version
67
 * added optimization not to forget things which are invariant.
68
 *
69
 * Revision 1.1  1994/05/03  14:49:52  djch
70
 * Initial revision
71
 *
72
 * Revision 1.3  93/08/27  11:37:27  11:37:27  ra (Robert Andrews)
73
 * A couple of lint-like changes.
74
 * 
75
 * Revision 1.2  93/08/13  14:45:27  14:45:27  ra (Robert Andrews)
76
 * Reformatted.
77
 * 
78
 * Revision 1.1  93/06/24  14:59:14  14:59:14  ra (Robert Andrews)
79
 * Initial revision
80
 * 
81
--------------------------------------------------------------------------
82
*/
83
 
84
 
85
#define SPARCTRANS_CODE
86
#include "config.h"
87
#include "expmacs.h"
88
#include "addrtypes.h"
89
#include "tags.h"
90
#include "move.h"
91
#include "bitsmacs.h"
92
#include "maxminmacs.h"
93
#include "shapemacs.h"
94
#include "common_types.h"
95
#include "regmacs.h"
96
#include "regexps.h"
97
#include "myassert.h"
98
#include "comment.h"
99
#include "flags.h"
100
#ifdef NEWDWARF
101
#include "dw2_config.h"
102
#include "dw2_extra.h"
103
#endif
104
 
105
 
106
/*
107
    ARRAY OF REGISTER-EXP ASSOCIATIONS
108
 
109
    0-31 represent the fixed point registers, 32-47 the floating point
110
    registers.
111
*/
112
 
113
regpeep regexps [48] ;
114
 
115
 
116
/*
117
    ARE TWO SHAPES OF THE SAME SIZE, ALIGNMENT AND FLOATING-POINT-NESS?
118
*/
119
 
120
bool eq_sze 
121
    PROTO_N ( ( as, bs ) )
122
    PROTO_T ( shape as X shape bs )
123
{
124
    if ( is_floating ( name ( as ) ) ) {
125
	return ( ( bool ) ( name ( as ) == name ( bs ) ) ) ;
126
    }
127
    if ( is_floating ( name ( bs ) ) ) {
128
	return ( 0 ) ;
129
    }
130
    return ( ( bool ) ( shape_size ( as ) == shape_size ( bs ) &&
131
			shape_align ( as ) == shape_align ( bs ) ) ) ;
132
}
133
 
134
 
135
/*
136
    ARE TWO LISTS OF EXPRESSIONS SIMILAR?
137
*/
138
 
139
bool sim_explist 
140
    PROTO_N ( ( al, bl ) )
141
    PROTO_T ( exp al X exp bl )
142
{
143
    if ( al == nilexp && bl == nilexp ) return ( 1 ) ;
144
    if ( al == nilexp || bl == nilexp ) return ( 0 ) ;
145
    if ( !sim_exp ( al, bl ) ) return ( 0 ) ;
146
    if ( last ( al ) && last ( bl ) ) return ( 1 ) ;
147
    if ( last ( al ) || last ( bl ) ) return ( 0 ) ;
148
    return ( sim_explist ( bro ( al ), bro ( bl ) ) ) ;
149
}
150
 
151
 
152
/*
153
    ARE TWO EXPRESSIONS SIMILAR?
154
 
155
    Basically this is the same as eq_exp except that equal shapes requirement
156
    is weakened to equal size and alignment.
157
*/
158
 
159
bool sim_exp 
160
    PROTO_N ( ( a, b ) )
161
    PROTO_T ( exp a X exp b )
162
{
163
    if ( name ( a ) == name ( b ) ) {
164
	if ( name ( a ) == name_tag ) {
165
	    return ( ( bool ) ( son ( a ) == son ( b ) &&
166
				no ( a ) == no ( b ) &&
167
				eq_sze ( sh ( a ), sh ( b ) ) ) ) ;
168
	}
169
	if ( !is_a ( name ( a ) ) || !eq_sze ( sh ( a ), sh ( b ) ) ) {
170
	    return ( 0 ) ;
171
	}
172
	return ( ( bool ) ( no ( a ) == no ( b ) &&
173
			    sim_explist ( son ( a ), son ( b ) ) 
174
			    && ((name(a) != current_env_tag) || 
175
				(props(a) == props(b)))));
176
    }
177
    return ( 0 ) ;
178
}
179
 
180
 
181
/*
182
    FORGET ALL REGISTER-EXP ASSOCIATIONS
183
*/
184
 
185
void clear_all 
186
    PROTO_Z ()
187
{
188
    int i ;
189
    for ( i = 0 ; i < 48 ; i++ ) {
190
	regexps [i].keptexp = nilexp ;
191
	setregalt ( regexps [i].inans, 0 ) ;
192
#ifdef NEWDWARF
193
	if (dwarf2)
194
	  dw_close_regassn (i);
195
#endif
196
    }
197
    return ;
198
}
199
 
200
 
201
/*
202
    FORGET THE EXP ASSOCIATED WITH REGISTER i
203
*/
204
 
205
void clear_reg 
206
    PROTO_N ( ( i ) )
207
    PROTO_T ( int i )
208
{
209
    i = ABS_OF ( i ) ;
210
    if ( i >= 0 && i < 48 ) {
211
	regexps [i].keptexp = nilexp ;
212
	setregalt ( regexps [i].inans, 0 ) ;
213
#ifdef NEWDWARF
214
	if (dwarf2)
215
	  dw_close_regassn (i);
216
#endif
217
    }
218
    return ;
219
}
220
 
221
 
222
/*
223
    HAS AN EXPRESSION ALREADY BEEN EVALUATED INTO A REGISTER?
224
*/
225
 
226
ans iskept 
227
    PROTO_N ( ( e ) )
228
    PROTO_T ( exp e )
229
{
230
    int i ;
231
    ans nilans ;
232
    setregalt ( nilans, 0 ) ;
233
 
234
#ifdef NO_KEPT_OPTS
235
    /* no register tracking */
236
    return ( nilans ) ;
237
#endif
238
 
239
    if ( name ( sh ( e ) ) == cpdhd ) {
240
	/* Tracking of unions is unsafe */
241
	return ( nilans ) ;
242
    }
243
 
244
    for ( i = 0 ; i < 48 ; i++ ) {
245
	exp ke = regexps [i].keptexp ;
246
	bool isc = regexps [i].iscont ;
247
 
248
	if ( ke != nilexp ) {
249
	    /* there is an association with register i? */
250
	    if ( ( ( !isc && sim_exp ( ke, e ) ) ||
251
		 ( name ( e ) == cont_tag && isc &&
252
		   eq_sze ( sh ( ke ), sh ( e ) ) &&
253
		   sim_exp ( ke, son ( e ) )  && 
254
		   al1(sh(son(e))) == al1(sh(ke))  ) ) ) {
255
		ans aa ;
256
		aa = regexps [i].inans ;
257
 
258
		switch ( discrim ( aa ) ) {
259
 
260
		    case notinreg : {
261
			if ( !aa.val.instoreans.adval ) {
262
			    /* the expression is given indirectly, it may
263
			       also be in another register */
264
			    continue ;
265
			}
266
			/* FALL THROUGH */
267
		    }
268
 
269
		    default : {
270
#ifdef NEWDWARF
271
			if (dwarf2)
272
			  dw_used_regassn (i);
273
#endif
274
			return ( aa ) ;
275
		    }
276
		}
277
	    } else if ( name ( ke ) == cont_tag && !isc ) {
278
		ans aq ;
279
 
280
		aq = regexps [i].inans ;
281
		if ( discrim ( aq ) == notinreg ) {
282
		    instore is ;
283
		    is = insalt ( aq ) ;
284
		    if ( !is.adval && is.b.offset == 0 &&
285
			 IS_FIXREG ( is.b.base ) &&
286
			 sim_exp ( son ( ke ), e ) ) {
287
			/* the contents of required expression is here as
288
			   a register-offset */
289
#ifdef NEWDWARF
290
			if (dwarf2)
291
			  dw_used_regassn (i);
292
#endif
293
			is.adval = 1 ;
294
			setinsalt ( aq, is ) ;
295
			return ( aq ) ;
296
		    }
297
		}
298
	    } else if ( name ( ke ) == reff_tag && !isc ) {
299
		ans aq ;
300
		aq = regexps [i].inans ;
301
		if ( discrim ( aq ) == notinreg ) {
302
		    instore is ;
303
		    is = insalt ( aq ) ;
304
		    if ( is.adval && is.b.offset == ( no ( ke ) / 8 ) &&
305
			 IS_FIXREG ( is.b.base ) &&
306
			 sim_exp ( son ( ke ), e ) ) {
307
			/* a ref selection of required expression is here as
308
			   a register-offset */
309
#ifdef NEWDWARF
310
			if (dwarf2)
311
			  dw_used_regassn (i);
312
#endif
313
			is.adval = 1 ;
314
			is.b.offset = 0 ;
315
			setinsalt ( aq, is ) ;
316
			return ( aq ) ;
317
		    }
318
		}
319
	    }
320
	}
321
    }
322
    return ( nilans ) ;
323
}
324
 
325
 
326
/*
327
    SET UP AN EXP-LOCATION ASSOCIATION
328
*/
329
 
330
void keepexp 
331
    PROTO_N ( ( e, loc ) )
332
    PROTO_T ( exp e X ans loc )
333
{
334
    int reg ;
335
 
336
    /* Find the register number */
337
    switch ( discrim ( loc ) ) {
338
	case insomereg :
339
	case insomefreg : {
340
	    fail ( "Illegal location in keepexp" ) ;
341
	    return ;
342
	}
343
	case inreg : {
344
	    reg = regalt ( loc ) ;
345
	    break ;
346
	}
347
	case infreg : {
348
	    reg = fregalt ( loc ).fr + 32 ;
349
	    break ;
350
	}
351
	case notinreg : {
352
	    reg = insalt ( loc ).b.base ;
353
	    if ( !IS_FIXREG ( reg ) ) return ;
354
	    break ;
355
	}
356
    }
357
 
358
    assert ( reg >= 0 && reg < 48 ) ;
359
    assert ( reg != R_TMP ) ;
360
    regexps [ reg ].keptexp = e ;
361
    regexps [ reg ].inans = loc ;
362
    regexps [ reg ].iscont = 0 ;
363
#ifdef NEWDWARF
364
    if (dwarf2)
365
	dw_init_regassn (reg);
366
#endif
367
    return ;
368
}
369
 
370
 
371
/*
372
    SET UP A CONTENTS-REGISTER ASSOCIATION
373
*/
374
 
375
void keepcont 
376
    PROTO_N ( ( e, regcode ) )
377
    PROTO_T ( exp e X int regcode )
378
{
379
    freg fr ;
380
    int reg = ABS_OF ( regcode ) ;
381
    assert ( reg >= 0 && reg < 48 ) ;
382
    assert ( reg != R_TMP ) ;
383
 
384
    if ( reg > 31 ) {
385
	fr.dble = ( bool ) ( regcode < 0 ) ;
386
	fr.fr = reg - 32 ;
387
	setfregalt ( regexps [ reg ].inans, fr ) ;
388
    } else {
389
	instore is ;
390
	is.b.base = regcode ;
391
	is.b.offset = 0 ;
392
	is.adval = 1 ;
393
	setinsalt ( regexps [ reg ].inans, is ) ;
394
    }
395
 
396
    regexps [ reg ].keptexp = e ;
397
    regexps [ reg ].iscont = 1 ;
398
#ifdef NEWDWARF
399
    if (dwarf2)
400
	dw_init_regassn (reg);
401
#endif
402
    return ;
403
}
404
 
405
 
406
/*
407
    SET UP AN EXP-REGISTER ASSOCIATION
408
*/
409
 
410
void keepreg 
411
    PROTO_N ( ( e, regcode ) )
412
    PROTO_T ( exp e X int regcode )
413
{
414
    freg fr ;
415
    int reg = ABS_OF ( regcode ) ;
416
    assert ( reg >= 0 && reg < 48 ) ;
417
    assert ( reg != R_TMP ) ;
418
 
419
    if ( reg > 31 ) {
420
	fr.dble = ( bool ) ( regcode < 0 ) ;
421
	fr.fr = reg - 32 ;
422
	setfregalt ( regexps [ reg ].inans, fr ) ;
423
    } else {
424
	instore is ;
425
	is.b.base = regcode ;
426
	is.b.offset = 0 ;
427
	is.adval = 1 ;
428
	setinsalt ( regexps [ reg ].inans, is ) ;
429
    }
430
 
431
    regexps [ reg ].keptexp = e ;
432
    regexps [ reg ].iscont = 0 ;
433
#ifdef NEWDWARF
434
    if (dwarf2)
435
	dw_init_regassn (reg);
436
#endif
437
    return ;
438
}
439
 
440
 
441
/*
442
    COULD e BE lhs?
443
*/
444
 
445
bool couldbe 
446
    PROTO_N ( ( e, lhs ) )
447
    PROTO_T ( exp e X exp lhs )
448
{
449
    unsigned char ne = name ( e ) ;
450
    exp s = son ( e ) ;
451
 
452
    if ( ne == name_tag ) {
453
	if ( lhs != 0 && s == son ( lhs ) ) return ( 1 ) ;
454
	if ( isvar ( s ) ) 
455
	  return ( ( bool ) ( lhs == 0 && 
456
			     (isvis ( s ) || isglob(s)))) ;
457
	if ( name ( s ) == proc_tag ) return ( ( bool ) ( lhs == 0 ) ) ;
458
	if ( son ( s ) == nilexp ) return ( 1 ) ;
459
	return ( couldbe ( son ( s ), lhs ) ) ;
460
    }
461
    if ( ne == cont_tag ) {
462
	if ( lhs != 0 && name ( s ) == name_tag && son ( s ) != nilexp ) {
463
	    return ( ( bool ) ( son ( s ) == son ( lhs ) ||
464
				isvis ( son ( lhs ) ) ||
465
				isvis ( son ( s ) ) ) ) ;
466
	}
467
	return ( 1 ) ;
468
    }
469
    if ( ne == reff_tag || ne == field_tag ) {
470
	return ( couldbe ( s, lhs ) ) ;
471
    }
472
    if ( ne == addptr_tag || ne == subptr_tag ) {
473
	return ( ( bool ) ( couldbe ( s, lhs ) ||
474
			    couldeffect ( bro ( s ), lhs ) ) ) ;
475
    }
476
    return ( 1 ) ;
477
 
478
}
479
 
480
/*
481
    COULD AN ALTERATION TO z EFFECT e?
482
*/
483
 
484
bool couldeffect 
485
    PROTO_N ( ( e, z ) )
486
    PROTO_T ( exp e X exp z )
487
{
488
    unsigned char ne = name ( e ) ;
489
 
490
    if ( ne == cont_tag ) return ( couldbe ( son ( e ), z ) ) ;
491
    if ( ne == name_tag ) {
492
	if ( isvar ( son ( e ) ) ) {
493
	    return ( ( bool ) ( z == 0 && isvis ( son ( e ) ) ) ) ;
494
	}
495
	if ( name ( son ( e ) ) == proc_tag ) return ( 0 ) ;
496
	if ( son ( son ( e ) ) == nilexp ) return ( 1 ) ;
497
	return ( couldeffect ( son ( son ( e ) ), z ) ) ;
498
 
499
    }
500
    if ( ne < plus_tag || ne == contvol_tag ) return ( 1 ) ;
501
 
502
    e = son ( e ) ;
503
    while ( e != nilexp ) {
504
	if ( couldeffect ( e, z ) ) return ( 1 ) ;
505
	if ( last ( e ) ) return ( 0 ) ;
506
	e = bro ( e ) ;
507
    }
508
    return ( 0 ) ;
509
}
510
 
511
 
512
/*
513
    DOES e DEPEND ON z?
514
*/
515
 
516
bool dependson 
517
    PROTO_N ( ( e, isc, z ) )
518
    PROTO_T ( exp e X bool isc X exp z )
519
{
520
    if (e == nilexp) {
521
	return 0;
522
    }
523
    for ( ; ; ) {
524
	if ( name ( z ) == reff_tag || name ( z ) == addptr_tag ||
525
	     name ( z ) == subptr_tag ) {
526
	    z = son ( z ) ;
527
	}
528
	if ( name ( z ) != name_tag ) {
529
	    if ( name ( z ) != cont_tag ) return ( 1 ) ;
530
	    z = 0 ;
531
	    break ;
532
	}
533
 
534
	if ( isvar ( son ( z ) ) ) break ;
535
	if ( name ( son ( z ) ) == proc_tag ) {
536
	    z = 0 ;
537
	    break ;
538
	}
539
	if ( son ( son ( z ) ) == nilexp ) {
540
	    /* can it happen? */
541
	    return ( 1 ) ;
542
	}
543
	z = son ( son ( z ) ) ;
544
    }
545
 
546
    /* z is now unambiguous variable name or 0 (meaning some contents) */
547
    return ( ( bool ) ( isc ? couldbe ( e, z ) : couldeffect ( e, z ) ) ) ;
548
}
549
 
550
 
551
/*
552
    REMOVE ASSOCATIONS OF ANY REGISTERS DEPENDING ON lhs
553
*/
554
 
555
void clear_dep_reg 
556
    PROTO_N ( ( lhs ) )
557
    PROTO_T ( exp lhs )
558
{
559
  int i ;
560
  for ( i = 0 ; i < 48 ; i++ )
561
  {
562
    if (regexps[i].keptexp != nilexp)
563
      switch(name(regexps[i].keptexp))
564
      {
565
       case val_tag:
566
       case null_tag:
567
       case real_tag:
568
       case string_tag:
569
       case name_tag:
570
	if (!regexps[i].iscont)
571
	{			/* constant value, cannot be changed
572
				   by assign */
573
	  continue;
574
	}
575
       default:
576
	if ( dependson ( regexps [i].keptexp, regexps [i].iscont, lhs ) ) 
577
	{	
578
	  regexps [i].keptexp = nilexp ;
579
	  setregalt ( regexps [i].inans, 0 ) ;
580
#ifdef NEWDWARF
581
	  if (dwarf2)
582
	    dw_close_regassn (i);
583
#endif
584
	}
585
      }
586
  }
587
  return ;
588
}