Subversion Repositories tendra.SVN

Rev

Go to most recent revision | 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
$Log: regexps.c,v $
33
 * Revision 1.1.1.1  1998/01/17  15:56:03  release
34
 * First version to be checked into rolling release.
35
 *
36
 * Revision 1.4  1996/11/14  15:22:26  wfs
37
 *    Fixed a bug in regexps.c which was common to most of the installers and
38
 * has only just come to light due to PWE's work on powertrans. (There was
39
 * previously only a patch.) Cosmetic changes to other files.
40
 *
41
 * Revision 1.3  1996/01/23  15:26:07  wfs
42
 * "current_env_tag" in "dependson()".
43
 *
44
 * Revision 1.2  1995/12/18  13:12:30  wfs
45
 * Put hppatrans uder cvs control. Major Changes made since last release
46
 * include:
47
 * (i) PIC code generation.
48
 * (ii) Profiling.
49
 * (iii) Dynamic Initialization.
50
 * (iv) Debugging of Exception Handling and Diagnostics.
51
 *
52
 * Revision 5.2  1995/10/20  14:11:15  wfs
53
 * gcc compilation changes.
54
 *
55
 * Revision 5.1  1995/09/15  13:13:36  wfs
56
 * Mike Gerrard's bug fix incorporated.
57
 *
58
 * Revision 5.0  1995/08/25  13:42:58  wfs
59
 * Preperation for August 25 Glue release
60
 *
61
 * Revision 3.4  1995/08/25  10:29:56  wfs
62
 * Register synonyms changed
63
 *
64
 * Revision 3.4  1995/08/25  10:29:56  wfs
65
 * Register synonyms changed
66
 *
67
 * Revision 3.1  95/04/10  16:28:04  16:28:04  wfs (William Simmonds)
68
 * Apr95 tape version.
69
 * 
70
 * Revision 3.0  95/03/30  11:18:54  11:18:54  wfs (William Simmonds)
71
 * Mar95 tape version with CRCR95_178 bug fix.
72
 * 
73
 * Revision 2.0  95/03/15  15:28:43  15:28:43  wfs (William Simmonds)
74
 * spec 3.1 changes implemented, tests outstanding.
75
 * 
76
 * Revision 1.1  95/01/11  13:16:12  13:16:12  wfs (William Simmonds)
77
 * Initial revision
78
 * 
79
*/
80
 
81
 
82
#define HPPATRANS_CODE
83
/* regexps.c
84
 
85
For trivial 'peephole' optimisations
86
 
87
*/
88
 
89
 
90
 
91
#include "config.h"
92
#include "expmacs.h"
93
#include "addrtypes.h"
94
#include "tags.h"
95
#include "move.h"
96
#include "bitsmacs.h"
97
#include "maxminmacs.h"
98
#include "shapemacs.h"
99
#include "common_types.h"
100
#include "regmacs.h"
101
#include "myassert.h"
102
#include "comment.h"
103
#include "check.h"
104
#include "regexps.h"
105
 
106
/* 22.11.94. Corrected bug found by Ian Currie, i.e. isglob(s) assertion
107
   added to line 351 */
108
 
109
 
110
int line;
111
 
112
regpeep regexps[64];		/* [0:31] fix pt - [32:47] floating pt */
113
 
114
bool sim_exp PROTO_S ( ( exp, exp ) ) ;
115
 
116
/* Same size and alignment and "both float or both fixed". */
117
bool eq_sze 
118
    PROTO_N ( ( as, bs ) )
119
    PROTO_T ( shape as X shape bs )
120
{
121
  if (is_floating(name(as)))
122
    return (name(as) == name(bs));
123
  if (is_floating(name(bs)))
124
    return 0;
125
  return (shape_size(as) == shape_size(bs) && shape_align(as) == shape_align(bs));
126
}
127
 
128
bool sim_explist 
129
    PROTO_N ( ( al, bl ) )
130
    PROTO_T ( exp al X exp bl )
131
{
132
  if (al == nilexp && bl == nilexp)
133
    return (1);
134
  if (al == nilexp || bl == nilexp)
135
    return (0);
136
  if (!sim_exp(al, bl))
137
    return (0);
138
  if (last(al) && last(bl))
139
    return (1);
140
  if (last(al) || last(bl))
141
    return (0);
142
  return (sim_explist(bro(al), bro(bl)));
143
}
144
 
145
bool sim_exp 
146
    PROTO_N ( ( a, b ) )
147
    PROTO_T ( exp a X exp b )
148
 
149
 /*
150
  * basically eq_exp except equal shapes requirement  is weakened to equal
151
  * sizes and alignments
152
  */
153
{
154
   if (name(a) == name(b))
155
   {
156
      if (name(a) == name_tag)
157
      {
158
	 return (son(a) == son(b) && no(a) == no(b) &&
159
	      eq_sze(sh(a), sh(b)));
160
      }
161
      if (!is_a(name(a)) || !eq_sze(sh(a), sh(b)))
162
	 return (0);
163
      if(name(a)==float_tag)/* NEW bit */
164
      {
165
	return eq_exp(son(a),son(b));
166
      }
167
      return (no(a) == no(b) && sim_explist(son(a), son(b)));
168
  };
169
  return (0);
170
}
171
 
172
/* forget all register - exp associations */
173
void clear_all 
174
    PROTO_Z ()
175
{
176
  int i;
177
 
178
  for (i = 0; i < 48; i++)
179
  {
180
    regexps[i].keptexp = nilexp;
181
    setregalt(regexps[i].inans, 0);
182
  }
183
}
184
 
185
 
186
 
187
/* forget reg i - exp association */
188
void clear_reg 
189
    PROTO_N ( ( i ) )
190
    PROTO_T ( int i )
191
{
192
  i = ABS_OF(i);
193
  if (i >= 0 && i < 48)
194
  {
195
    regexps[i].keptexp = nilexp;
196
    setregalt(regexps[i].inans, 0);
197
  }
198
}
199
 
200
 
201
/* find if e has already been evaluated into a register */
202
ans iskept 
203
    PROTO_N ( ( e ) )
204
    PROTO_T ( exp e )
205
{
206
  int i;
207
  ans nilans;
208
 
209
  setregalt(nilans, 0);		/* init nilans */
210
 
211
#ifdef NO_KEPT_OPTS
212
  /* no reg tracking */
213
  return nilans;
214
#endif
215
 
216
  /* reg tracking of unions unsafe, as views of location can differ */
217
  /* +++ track on fields */
218
  /* +++ safe to allow structs but not unions */
219
  if (name(sh(e)) == cpdhd)
220
  {
221
    return nilans;
222
  }
223
 
224
  for (i = 0; i < 48; i++)
225
  {
226
    exp ke = regexps[i].keptexp;
227
    bool isc = regexps[i].iscont;
228
 
229
    if (ke != nilexp)
230
    {
231
      /* there is an accociation with reg i */
232
      if (
233
	  ((!isc && sim_exp(ke, e)) ||
234
	   (name(e) == cont_tag && isc && eq_sze(sh(ke), sh(e))
235
	    && sim_exp(ke, son(e)))
236
	   )
237
	)
238
      {
239
	ans aa ;
240
	aa = (regexps[i].inans);
241
 
242
#if 0
243
	FULLCOMMENT4("iskept found: reg=%d isc=%d name(e)=%d name(son(e))=%d", i, isc, name(e), name(son(e)));
244
	FULLCOMMENT3("	hd(e)=%d hd(son(e))=%d hd(ke)=%d", name(sh(e)), name(sh(son(e))), name(sh(ke)));
245
	FULLCOMMENT3("	sim_exp(ke, e)=%d sim_exp(ke, son(e))=%d eq_size(sh(ke), sh(e))=%d",
246
		sim_exp(ke, e), sim_exp(ke, son(e)), eq_size(sh(ke), sh(e)));
247
#endif
248
 
249
	switch (discrim ( aa ))
250
	{
251
	case notinreg:
252
	  {
253
	    if (!aa.val.instoreans.adval)
254
	    {
255
 
256
	      /*
257
	       * the expression is given indirectly - it may have also been
258
	       * loaded into a register
259
	       */
260
	      continue;
261
	    }
262
	  }
263
	  /* FALLTHROUGH */
264
 
265
	default:
266
	  return aa;
267
	}
268
      }
269
      else if (name(ke) == cont_tag && !isc)
270
      {
271
	ans aq;
272
 
273
	aq = regexps[i].inans;
274
	if (discrim ( aq ) == notinreg)
275
	{
276
	  instore is;
277
 
278
	  is = insalt(aq);
279
	  if (!is.adval && is.b.offset == 0 && IS_FIXREG(is.b.base)
280
	      && sim_exp(son(ke), e))
281
	  {
282
	    /* the contents of req expression is here as a reg-offset */
283
	    is.adval = 1;
284
	    setinsalt(aq, is);
285
	    return aq;
286
	  }
287
	}
288
      }
289
      else if (name(ke) == reff_tag && !isc)
290
      {
291
	ans aq;
292
 
293
	aq = regexps[i].inans;
294
	if (discrim ( aq ) == notinreg)
295
	{
296
	  instore is;
297
 
298
	  is = insalt(aq);
299
	  if (is.adval && is.b.offset == (no(ke) / 8)
300
	      && IS_FIXREG(is.b.base)
301
	      && sim_exp(son(ke), e))
302
	  {
303
	    /* a ref select of req expression is here as a reg-offset */
304
	    is.adval = 1;
305
	    is.b.offset = 0;
306
	    setinsalt(aq, is);
307
	    return aq;
308
	  }
309
	}
310
      }
311
    }
312
  }
313
  return nilans;
314
}
315
 
316
/* set up exp - address association */
317
void keepexp 
318
    PROTO_N ( ( e, loc ) )
319
    PROTO_T ( exp e X ans loc )
320
{
321
  int reg=0;
322
 
323
  switch (discrim ( loc ))
324
  {
325
  case insomereg:
326
  case insomefreg:
327
    {
328
      fail("keep ? reg");
329
    }
330
#if USE_BITAD
331
  case bitad:
332
    {
333
      return;
334
    }
335
#endif
336
  case inreg:
337
    {
338
      reg = regalt(loc);
339
      break;
340
    }
341
  case infreg:
342
    {
343
      reg = fregalt(loc).fr + 32;
344
      break;
345
    }
346
  case notinreg:
347
    {
348
      reg = insalt(loc).b.base;
349
      if (!IS_FIXREG(reg))
350
	return;
351
      break;
352
    }
353
  default:{}
354
  }
355
 
356
  assert(reg >= 0 && reg < 48);
357
  assert(reg != GR1);
358
 
359
  regexps[reg].keptexp = e;
360
  regexps[reg].inans = loc;
361
  regexps[reg].iscont = 0;
362
}
363
 
364
/* set up cont(e)-reg association */
365
void keepcont 
366
    PROTO_N ( ( e, regcode ) )
367
    PROTO_T ( exp e X int regcode )
368
{
369
  freg fr;
370
  int reg = ABS_OF(regcode);
371
 
372
  assert(reg >= 0 && reg < 48);
373
  assert(reg != GR1);
374
 
375
  if (reg > 31)
376
  {
377
    fr.dble = ((regcode < 0) ? 1 : 0);
378
    fr.fr = reg - 32;
379
    setfregalt(regexps[reg].inans, fr);
380
  }
381
  else
382
  {
383
    instore is;
384
 
385
    is.b.base = regcode;
386
    is.b.offset = 0;
387
    is.adval = 1;
388
    setinsalt(regexps[reg].inans, is);
389
  }
390
 
391
  regexps[reg].keptexp = e;
392
  regexps[reg].iscont = 1;
393
}
394
 
395
/* set up e-reg association */
396
void keepreg 
397
    PROTO_N ( ( e, regcode ) )
398
    PROTO_T ( exp e X int regcode )
399
{
400
  freg fr;
401
  int reg = ABS_OF(regcode);
402
 
403
  assert(reg >= 0 && reg < 48);
404
  assert(reg != GR1);
405
 
406
  if (reg > 31)
407
  {
408
    fr.dble = ((regcode < 0) ? 1 : 0);
409
    fr.fr = reg - 32;
410
    setfregalt(regexps[reg].inans, fr);
411
  }
412
  else
413
  {
414
    instore is;
415
 
416
    is.b.base = regcode;
417
    is.b.offset = 0;
418
    is.adval = 1;
419
    setinsalt(regexps[reg].inans, is);
420
  }
421
 
422
  regexps[reg].keptexp = e;
423
  regexps[reg].iscont = 0;
424
}
425
 
426
 
427
bool couldeffect PROTO_S ( ( exp, exp ) ) ;
428
 
429
 
430
/* could e be lhs */
431
bool couldbe 
432
    PROTO_N ( ( e, lhs ) )
433
    PROTO_T ( exp e X exp lhs )
434
{
435
  int ne = name(e);
436
  exp s = son(e);
437
 
438
  if (ne == name_tag)
439
  {
440
    if (lhs != 0 && s == son(lhs))
441
    {
442
      return 1;
443
    }
444
    if (isvar(s))
445
    {
446
      return (lhs == 0 && (isvis(s) || isglob(s)));
447
    }
448
    if (IS_A_PROC(s))
449
      return (lhs == 0);
450
    if (son(s) == nilexp)
451
      return 1;
452
    return couldbe(son(s), lhs);
453
  }
454
  if (ne == cont_tag)
455
  {
456
    if (lhs != 0 && name(s) == name_tag && son(s) != nilexp)
457
    {
458
      return (son(s) == son(lhs) || isvis(son(lhs)) || isvis(son(s)));
459
    }
460
    return 1;
461
  }
462
  if (ne == reff_tag || ne == field_tag)
463
  {
464
    return couldbe(s, lhs);
465
  }
466
  if (ne == addptr_tag || ne == subptr_tag)
467
  {
468
    return (couldbe(s, lhs) || couldeffect(bro(s), lhs));
469
  }
470
 
471
  return 1;
472
 
473
}
474
 
475
/* could alteration to z effect e? */
476
bool couldeffect 
477
    PROTO_N ( ( e, z /* a name or zero */ ) )
478
    PROTO_T ( exp e X exp z /* a name or zero */ )
479
{
480
  int ne = name(e);
481
  if (ne == cont_tag)
482
  {
483
    return couldbe(son(e), z);
484
  }
485
  if (ne == name_tag)
486
  {
487
    if (isvar(son(e)))
488
      return (z == 0 && isvis(son(e)));
489
    if ( IS_A_PROC(son(e)) )
490
      return 0;
491
    if (son(son(e)) == nilexp)
492
      return 1 /* could it happen? */ ;
493
 
494
    return couldeffect(son(son(e)), z);
495
 
496
  }
497
  if (ne < plus_tag || ne == contvol_tag)
498
    return 1;
499
 
500
  e = son(e);
501
 
502
  while (e != nilexp)
503
  {
504
    if (couldeffect(e, z))
505
      return 1;
506
    if (last(e))
507
      return 0;
508
    e = bro(e);
509
  }
510
  return 0;
511
}
512
 
513
bool dependson 
514
    PROTO_N ( ( e, isc, z ) )
515
    PROTO_T ( exp e X bool isc X exp z )
516
{				/* does e depend on z */
517
  if (e == nilexp)
518
  {
519
    return 0;
520
  }
521
  for (;;)
522
  {
523
    if (name(z) == reff_tag || name(z) == addptr_tag ||
524
	name(z) == subptr_tag)
525
    {
526
      z = son(z);
527
    }
528
 
529
    if (name(z) != name_tag)
530
    {
531
      if (name(z) != cont_tag)
532
	return 1;
533
      z = 0;
534
      break;
535
    }
536
 
537
    if (isvar(son(z)))
538
      break;
539
    if ( IS_A_PROC(son(z)) )
540
    {
541
      z = 0;
542
      break;
543
    }
544
    if (son(son(z)) == nilexp)
545
      return 1;			/* can it happen? */
546
    z = son(son(z));
547
  }
548
 
549
  /* z is now unambiguous variable name or 0 meaning some contents */
550
 
551
  return ((isc) ? couldbe(e, z) : couldeffect(e, z));
552
}
553
 
554
 
555
/* remove association of any register which depends on lhs */
556
void clear_dep_reg 
557
    PROTO_N ( ( lhs ) )
558
    PROTO_T ( exp lhs )
559
{
560
  int i;
561
 
562
  for (i = 0; i < 48; i++)
563
  {
564
    if (dependson(regexps[i].keptexp, regexps[i].iscont, lhs))
565
    {
566
      regexps[i].keptexp = nilexp;
567
      setregalt(regexps[i].inans, 0);
568
    }
569
  }
570
}
571
 
572
 
573
 
574
 
575