Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
7 7u83 2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific, prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * $Id$
30
 */
31
/*
2 7u83 32
    		 Crown Copyright (c) 1997
7 7u83 33
 
2 7u83 34
    This TenDRA(r) Computer Program is subject to Copyright
35
    owned by the United Kingdom Secretary of State for Defence
36
    acting through the Defence Evaluation and Research Agency
37
    (DERA).  It is made available to Recipients with a
38
    royalty-free licence for its use, reproduction, transfer
39
    to other parties and amendment for any purpose not excluding
40
    product development provided that any such use et cetera
41
    shall be deemed to be acceptance of the following conditions:-
7 7u83 42
 
2 7u83 43
	(1) Its Recipients shall ensure that this Notice is
44
	reproduced upon any copies or amended versions of it;
7 7u83 45
 
2 7u83 46
	(2) Any amended version of it shall be clearly marked to
47
	show both the nature of and the organisation responsible
48
	for the relevant amendment or amendments;
7 7u83 49
 
2 7u83 50
	(3) Its onward transfer from a recipient to another
51
	party shall be deemed to be that party's acceptance of
52
	these conditions;
7 7u83 53
 
2 7u83 54
	(4) DERA gives no warranty or assurance as to its
55
	quality or suitability for any purpose and DERA accepts
56
	no liability whatsoever in relation to any use to which
57
	it may be put.
58
*/
59
 
60
 
61
/*
62
$Log: regexps.c,v $
63
 * Revision 1.1.1.1  1998/01/17  15:56:03  release
64
 * First version to be checked into rolling release.
65
 *
66
 * Revision 1.4  1996/11/14  15:22:26  wfs
67
 *    Fixed a bug in regexps.c which was common to most of the installers and
68
 * has only just come to light due to PWE's work on powertrans. (There was
69
 * previously only a patch.) Cosmetic changes to other files.
70
 *
71
 * Revision 1.3  1996/01/23  15:26:07  wfs
72
 * "current_env_tag" in "dependson()".
73
 *
74
 * Revision 1.2  1995/12/18  13:12:30  wfs
75
 * Put hppatrans uder cvs control. Major Changes made since last release
76
 * include:
77
 * (i) PIC code generation.
78
 * (ii) Profiling.
79
 * (iii) Dynamic Initialization.
80
 * (iv) Debugging of Exception Handling and Diagnostics.
81
 *
82
 * Revision 5.2  1995/10/20  14:11:15  wfs
83
 * gcc compilation changes.
84
 *
85
 * Revision 5.1  1995/09/15  13:13:36  wfs
86
 * Mike Gerrard's bug fix incorporated.
87
 *
88
 * Revision 5.0  1995/08/25  13:42:58  wfs
89
 * Preperation for August 25 Glue release
90
 *
91
 * Revision 3.4  1995/08/25  10:29:56  wfs
92
 * Register synonyms changed
93
 *
94
 * Revision 3.4  1995/08/25  10:29:56  wfs
95
 * Register synonyms changed
96
 *
97
 * Revision 3.1  95/04/10  16:28:04  16:28:04  wfs (William Simmonds)
98
 * Apr95 tape version.
7 7u83 99
 *
2 7u83 100
 * Revision 3.0  95/03/30  11:18:54  11:18:54  wfs (William Simmonds)
101
 * Mar95 tape version with CRCR95_178 bug fix.
7 7u83 102
 *
2 7u83 103
 * Revision 2.0  95/03/15  15:28:43  15:28:43  wfs (William Simmonds)
104
 * spec 3.1 changes implemented, tests outstanding.
7 7u83 105
 *
2 7u83 106
 * Revision 1.1  95/01/11  13:16:12  13:16:12  wfs (William Simmonds)
107
 * Initial revision
7 7u83 108
 *
2 7u83 109
*/
110
 
111
 
112
#define HPPATRANS_CODE
113
/* regexps.c
114
 
115
For trivial 'peephole' optimisations
116
 
117
*/
118
 
119
 
120
 
121
#include "config.h"
122
#include "expmacs.h"
123
#include "addrtypes.h"
124
#include "tags.h"
125
#include "move.h"
126
#include "bitsmacs.h"
127
#include "maxminmacs.h"
128
#include "shapemacs.h"
129
#include "common_types.h"
130
#include "regmacs.h"
131
#include "myassert.h"
132
#include "comment.h"
133
#include "check.h"
134
#include "regexps.h"
135
 
136
/* 22.11.94. Corrected bug found by Ian Currie, i.e. isglob(s) assertion
137
   added to line 351 */
138
 
139
 
140
int line;
141
 
142
regpeep regexps[64];		/* [0:31] fix pt - [32:47] floating pt */
143
 
7 7u83 144
bool sim_exp(exp, exp);
2 7u83 145
 
146
/* Same size and alignment and "both float or both fixed". */
7 7u83 147
bool eq_sze
148
(shape as, shape bs)
2 7u83 149
{
150
  if (is_floating(name(as)))
7 7u83 151
    return(name(as) == name(bs));
2 7u83 152
  if (is_floating(name(bs)))
153
    return 0;
7 7u83 154
  return(shape_size(as) == shape_size(bs) && shape_align(as) == shape_align(bs));
2 7u83 155
}
156
 
7 7u83 157
bool sim_explist
158
(exp al, exp bl)
2 7u83 159
{
160
  if (al == nilexp && bl == nilexp)
7 7u83 161
    return(1);
2 7u83 162
  if (al == nilexp || bl == nilexp)
7 7u83 163
    return(0);
2 7u83 164
  if (!sim_exp(al, bl))
7 7u83 165
    return(0);
2 7u83 166
  if (last(al) && last(bl))
7 7u83 167
    return(1);
2 7u83 168
  if (last(al) || last(bl))
7 7u83 169
    return(0);
170
  return(sim_explist(bro(al), bro(bl)));
2 7u83 171
}
172
 
7 7u83 173
bool sim_exp
174
(exp a, exp b)
2 7u83 175
 
176
 /*
177
  * basically eq_exp except equal shapes requirement  is weakened to equal
178
  * sizes and alignments
179
  */
180
{
181
   if (name(a) == name(b))
182
   {
183
      if (name(a) == name_tag)
184
      {
7 7u83 185
	 return(son(a) == son(b) && no(a) == no(b) &&
2 7u83 186
	      eq_sze(sh(a), sh(b)));
187
      }
188
      if (!is_a(name(a)) || !eq_sze(sh(a), sh(b)))
7 7u83 189
	 return(0);
2 7u83 190
      if(name(a)==float_tag)/* NEW bit */
191
      {
192
	return eq_exp(son(a),son(b));
193
      }
7 7u83 194
      return(no(a) == no(b) && sim_explist(son(a), son(b)));
2 7u83 195
  };
7 7u83 196
  return(0);
2 7u83 197
}
198
 
199
/* forget all register - exp associations */
7 7u83 200
void clear_all
201
(void)
2 7u83 202
{
203
  int i;
204
 
205
  for (i = 0; i < 48; i++)
206
  {
207
    regexps[i].keptexp = nilexp;
208
    setregalt(regexps[i].inans, 0);
209
  }
210
}
211
 
212
 
213
 
214
/* forget reg i - exp association */
7 7u83 215
void clear_reg
216
(int i)
2 7u83 217
{
218
  i = ABS_OF(i);
219
  if (i >= 0 && i < 48)
220
  {
221
    regexps[i].keptexp = nilexp;
222
    setregalt(regexps[i].inans, 0);
223
  }
224
}
225
 
226
 
227
/* find if e has already been evaluated into a register */
7 7u83 228
ans iskept
229
(exp e)
2 7u83 230
{
231
  int i;
232
  ans nilans;
233
 
234
  setregalt(nilans, 0);		/* init nilans */
235
 
236
#ifdef NO_KEPT_OPTS
237
  /* no reg tracking */
238
  return nilans;
239
#endif
240
 
241
  /* reg tracking of unions unsafe, as views of location can differ */
242
  /* +++ track on fields */
243
  /* +++ safe to allow structs but not unions */
244
  if (name(sh(e)) == cpdhd)
245
  {
246
    return nilans;
247
  }
248
 
249
  for (i = 0; i < 48; i++)
250
  {
251
    exp ke = regexps[i].keptexp;
252
    bool isc = regexps[i].iscont;
253
 
254
    if (ke != nilexp)
255
    {
256
      /* there is an accociation with reg i */
257
      if (
7 7u83 258
	 ((!isc && sim_exp(ke, e)) ||
259
	  (name(e) == cont_tag && isc && eq_sze(sh(ke), sh(e))
2 7u83 260
	    && sim_exp(ke, son(e)))
7 7u83 261
	  )
2 7u83 262
	)
263
      {
7 7u83 264
	ans aa;
2 7u83 265
	aa = (regexps[i].inans);
266
 
267
#if 0
7 7u83 268
	FULLCOMMENT4("iskept found: reg=%d isc=%d name(e) =%d name(son(e)) =%d", i, isc, name(e), name(son(e)));
269
	FULLCOMMENT3("	hd(e) =%d hd(son(e)) =%d hd(ke) =%d", name(sh(e)), name(sh(son(e))), name(sh(ke)));
270
	FULLCOMMENT3("	sim_exp(ke, e) =%d sim_exp(ke, son(e)) =%d eq_size(sh(ke), sh(e)) =%d",
2 7u83 271
		sim_exp(ke, e), sim_exp(ke, son(e)), eq_size(sh(ke), sh(e)));
272
#endif
273
 
7 7u83 274
	switch (discrim(aa))
2 7u83 275
	{
276
	case notinreg:
277
	  {
278
	    if (!aa.val.instoreans.adval)
279
	    {
280
 
281
	      /*
282
	       * the expression is given indirectly - it may have also been
283
	       * loaded into a register
284
	       */
285
	      continue;
286
	    }
287
	  }
288
	  /* FALLTHROUGH */
289
 
290
	default:
291
	  return aa;
292
	}
293
      }
294
      else if (name(ke) == cont_tag && !isc)
295
      {
296
	ans aq;
297
 
298
	aq = regexps[i].inans;
7 7u83 299
	if (discrim(aq) == notinreg)
2 7u83 300
	{
301
	  instore is;
302
 
303
	  is = insalt(aq);
304
	  if (!is.adval && is.b.offset == 0 && IS_FIXREG(is.b.base)
305
	      && sim_exp(son(ke), e))
306
	  {
307
	    /* the contents of req expression is here as a reg-offset */
308
	    is.adval = 1;
309
	    setinsalt(aq, is);
310
	    return aq;
311
	  }
312
	}
313
      }
314
      else if (name(ke) == reff_tag && !isc)
315
      {
316
	ans aq;
317
 
318
	aq = regexps[i].inans;
7 7u83 319
	if (discrim(aq) == notinreg)
2 7u83 320
	{
321
	  instore is;
322
 
323
	  is = insalt(aq);
324
	  if (is.adval && is.b.offset == (no(ke) / 8)
325
	      && IS_FIXREG(is.b.base)
326
	      && sim_exp(son(ke), e))
327
	  {
328
	    /* a ref select of req expression is here as a reg-offset */
329
	    is.adval = 1;
330
	    is.b.offset = 0;
331
	    setinsalt(aq, is);
332
	    return aq;
333
	  }
334
	}
335
      }
336
    }
337
  }
338
  return nilans;
339
}
340
 
341
/* set up exp - address association */
7 7u83 342
void keepexp
343
(exp e, ans loc)
2 7u83 344
{
345
  int reg=0;
346
 
7 7u83 347
  switch (discrim(loc))
2 7u83 348
  {
349
  case insomereg:
350
  case insomefreg:
351
    {
352
      fail("keep ? reg");
353
    }
354
#if USE_BITAD
355
  case bitad:
356
    {
357
      return;
358
    }
359
#endif
360
  case inreg:
361
    {
362
      reg = regalt(loc);
363
      break;
364
    }
365
  case infreg:
366
    {
367
      reg = fregalt(loc).fr + 32;
368
      break;
369
    }
370
  case notinreg:
371
    {
372
      reg = insalt(loc).b.base;
373
      if (!IS_FIXREG(reg))
374
	return;
375
      break;
376
    }
377
  default:{}
378
  }
379
 
380
  assert(reg >= 0 && reg < 48);
381
  assert(reg != GR1);
382
 
383
  regexps[reg].keptexp = e;
384
  regexps[reg].inans = loc;
385
  regexps[reg].iscont = 0;
386
}
387
 
388
/* set up cont(e)-reg association */
7 7u83 389
void keepcont
390
(exp e, int regcode)
2 7u83 391
{
392
  freg fr;
393
  int reg = ABS_OF(regcode);
394
 
395
  assert(reg >= 0 && reg < 48);
396
  assert(reg != GR1);
397
 
398
  if (reg > 31)
399
  {
7 7u83 400
    fr.dble = ((regcode < 0)? 1 : 0);
2 7u83 401
    fr.fr = reg - 32;
402
    setfregalt(regexps[reg].inans, fr);
403
  }
404
  else
405
  {
406
    instore is;
407
 
408
    is.b.base = regcode;
409
    is.b.offset = 0;
410
    is.adval = 1;
411
    setinsalt(regexps[reg].inans, is);
412
  }
413
 
414
  regexps[reg].keptexp = e;
415
  regexps[reg].iscont = 1;
416
}
417
 
418
/* set up e-reg association */
7 7u83 419
void keepreg
420
(exp e, int regcode)
2 7u83 421
{
422
  freg fr;
423
  int reg = ABS_OF(regcode);
424
 
425
  assert(reg >= 0 && reg < 48);
426
  assert(reg != GR1);
427
 
428
  if (reg > 31)
429
  {
7 7u83 430
    fr.dble = ((regcode < 0)? 1 : 0);
2 7u83 431
    fr.fr = reg - 32;
432
    setfregalt(regexps[reg].inans, fr);
433
  }
434
  else
435
  {
436
    instore is;
437
 
438
    is.b.base = regcode;
439
    is.b.offset = 0;
440
    is.adval = 1;
441
    setinsalt(regexps[reg].inans, is);
442
  }
443
 
444
  regexps[reg].keptexp = e;
445
  regexps[reg].iscont = 0;
446
}
447
 
448
 
7 7u83 449
bool couldeffect(exp, exp);
2 7u83 450
 
451
 
452
/* could e be lhs */
7 7u83 453
bool couldbe
454
(exp e, exp lhs)
2 7u83 455
{
456
  int ne = name(e);
457
  exp s = son(e);
458
 
459
  if (ne == name_tag)
460
  {
461
    if (lhs != 0 && s == son(lhs))
462
    {
463
      return 1;
464
    }
465
    if (isvar(s))
466
    {
7 7u83 467
      return(lhs == 0 && (isvis(s) || isglob(s)));
2 7u83 468
    }
469
    if (IS_A_PROC(s))
7 7u83 470
      return(lhs == 0);
2 7u83 471
    if (son(s) == nilexp)
472
      return 1;
473
    return couldbe(son(s), lhs);
474
  }
475
  if (ne == cont_tag)
476
  {
7 7u83 477
    if (lhs != 0 && name(s) == name_tag && son(s)!= nilexp)
2 7u83 478
    {
7 7u83 479
      return(son(s) == son(lhs) || isvis(son(lhs)) || isvis(son(s)));
2 7u83 480
    }
481
    return 1;
482
  }
483
  if (ne == reff_tag || ne == field_tag)
484
  {
485
    return couldbe(s, lhs);
486
  }
487
  if (ne == addptr_tag || ne == subptr_tag)
488
  {
7 7u83 489
    return(couldbe(s, lhs) || couldeffect(bro(s), lhs));
2 7u83 490
  }
491
 
492
  return 1;
493
 
494
}
495
 
496
/* could alteration to z effect e? */
7 7u83 497
bool couldeffect
2 7u83 498
    PROTO_N ( ( e, z /* a name or zero */ ) )
499
    PROTO_T ( exp e X exp z /* a name or zero */ )
500
{
501
  int ne = name(e);
502
  if (ne == cont_tag)
503
  {
504
    return couldbe(son(e), z);
505
  }
506
  if (ne == name_tag)
507
  {
508
    if (isvar(son(e)))
7 7u83 509
      return(z == 0 && isvis(son(e)));
510
    if (IS_A_PROC(son(e)))
2 7u83 511
      return 0;
512
    if (son(son(e)) == nilexp)
513
      return 1 /* could it happen? */ ;
514
 
515
    return couldeffect(son(son(e)), z);
516
 
517
  }
518
  if (ne < plus_tag || ne == contvol_tag)
519
    return 1;
520
 
521
  e = son(e);
522
 
523
  while (e != nilexp)
524
  {
525
    if (couldeffect(e, z))
526
      return 1;
527
    if (last(e))
528
      return 0;
529
    e = bro(e);
530
  }
531
  return 0;
532
}
533
 
7 7u83 534
bool dependson
535
(exp e, bool isc, exp z)
2 7u83 536
{				/* does e depend on z */
537
  if (e == nilexp)
538
  {
539
    return 0;
540
  }
541
  for (;;)
542
  {
543
    if (name(z) == reff_tag || name(z) == addptr_tag ||
544
	name(z) == subptr_tag)
545
    {
546
      z = son(z);
547
    }
548
 
7 7u83 549
    if (name(z)!= name_tag)
2 7u83 550
    {
7 7u83 551
      if (name(z)!= cont_tag)
2 7u83 552
	return 1;
553
      z = 0;
554
      break;
555
    }
556
 
557
    if (isvar(son(z)))
558
      break;
7 7u83 559
    if (IS_A_PROC(son(z)))
2 7u83 560
    {
561
      z = 0;
562
      break;
563
    }
564
    if (son(son(z)) == nilexp)
565
      return 1;			/* can it happen? */
566
    z = son(son(z));
567
  }
568
 
569
  /* z is now unambiguous variable name or 0 meaning some contents */
570
 
7 7u83 571
  return((isc)? couldbe(e, z): couldeffect(e, z));
2 7u83 572
}
573
 
574
 
575
/* remove association of any register which depends on lhs */
7 7u83 576
void clear_dep_reg
577
(exp lhs)
2 7u83 578
{
579
  int i;
580
 
581
  for (i = 0; i < 48; i++)
582
  {
583
    if (dependson(regexps[i].keptexp, regexps[i].iscont, lhs))
584
    {
585
      regexps[i].keptexp = nilexp;
586
      setregalt(regexps[i].inans, 0);
587
    }
588
  }
589
}
590
 
591
 
592
 
593
 
594