Subversion Repositories tendra.SVN

Rev

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

Rev Author Line No. Line
2 7u83 1
/*
6 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
    Copyright (c) 1993 Open Software Foundation, Inc.
33
 
34
 
35
    All Rights Reserved
36
 
37
 
38
    Permission to use, copy, modify, and distribute this software
39
    and its documentation for any purpose and without fee is hereby
40
    granted, provided that the above copyright notice appears in all
41
    copies and that both the copyright notice and this permission
42
    notice appear in supporting documentation.
43
 
44
 
45
    OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING
46
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47
    PARTICULAR PURPOSE.
48
 
49
 
50
    IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
51
    CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
52
    LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
53
    NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
54
    WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
55
*/
56
 
57
/*
58
    		 Crown Copyright (c) 1997
6 7u83 59
 
2 7u83 60
    This TenDRA(r) Computer Program is subject to Copyright
61
    owned by the United Kingdom Secretary of State for Defence
62
    acting through the Defence Evaluation and Research Agency
63
    (DERA).  It is made available to Recipients with a
64
    royalty-free licence for its use, reproduction, transfer
65
    to other parties and amendment for any purpose not excluding
66
    product development provided that any such use et cetera
67
    shall be deemed to be acceptance of the following conditions:-
6 7u83 68
 
2 7u83 69
        (1) Its Recipients shall ensure that this Notice is
70
        reproduced upon any copies or amended versions of it;
6 7u83 71
 
2 7u83 72
        (2) Any amended version of it shall be clearly marked to
73
        show both the nature of and the organisation responsible
74
        for the relevant amendment or amendments;
6 7u83 75
 
2 7u83 76
        (3) Its onward transfer from a recipient to another
77
        party shall be deemed to be that party's acceptance of
78
        these conditions;
6 7u83 79
 
2 7u83 80
        (4) DERA gives no warranty or assurance as to its
81
        quality or suitability for any purpose and DERA accepts
82
        no liability whatsoever in relation to any use to which
83
        it may be put.
84
*/
85
 
86
 
87
 
88
/**********************************************************************
89
$Author: release $
90
$Date: 1998/02/04 15:49:08 $
91
$Revision: 1.2 $
92
$Log: regexps.c,v $
93
 * Revision 1.2  1998/02/04  15:49:08  release
94
 * Added OSF copyright message.
95
 *
96
 * Revision 1.1.1.1  1998/01/17  15:55:57  release
97
 * First version to be checked into rolling release.
98
 *
99
 * Revision 1.4  1996/11/18  15:50:28  pwe
100
 * correct alias with bitfields, and case odds
101
 *
102
 * Revision 1.3  1996/10/11  10:51:19  pwe
103
 * clear_dep_reg v current-env_tag
104
 *
105
 * Revision 1.2  1996/10/04  16:04:08  pwe
106
 * add banners and mod for PWE ownership
107
 *
108
**********************************************************************/
109
 
110
 
111
#include "config.h"
112
#include "memtdf.h"
113
#include "codegen.h"
114
#include "maxminmacs.h"		/* for absval() */
115
 
116
#include "myassert.h"
117
#include "comment.h"
118
 
119
#include "regexps.h"
120
#include "flags.h"
121
#include "check.h"
122
 
123
struct regpeept
124
{
125
  ans inans;
126
  exp keptexp;
127
  bool iscont;
128
};
129
 
130
typedef struct regpeept regpeep;
131
 
132
#define FR_OFFSET		KEPT_FREG_OFFSET	/* 32 */
133
#define	LAST_ALL_REGS		(FR_OFFSET+FR_LAST)	/* 63 */
134
 
135
regpeep regexps[LAST_ALL_REGS+1];	/* [0:31] fix pt - [32:63] floating pt */
136
 
6 7u83 137
static bool sim_exp(exp, exp);
2 7u83 138
 
139
 
140
/* both either floating or fixed and same size and alignment */
6 7u83 141
bool keep_eq_size(shape as, shape bs)
2 7u83 142
{
143
  bool as_flt = is_floating(name(as));
144
  bool bs_flt = is_floating(name(bs));
145
 
146
  if (as_flt != bs_flt)
147
    return 0;			/* dissimilar float/fixed */
148
 
6 7u83 149
  return(shape_size(as) == shape_size(bs) && shape_align(as) == shape_align(bs));
2 7u83 150
}
151
 
152
 
6 7u83 153
static bool sim_explist(exp al, exp bl)
2 7u83 154
{
155
  if (al == nilexp && bl == nilexp)
6 7u83 156
    return(1);
2 7u83 157
  if (al == nilexp || bl == nilexp)
6 7u83 158
    return(0);
2 7u83 159
  if (!sim_exp(al, bl))
6 7u83 160
    return(0);
2 7u83 161
  if (last(al) && last(bl))
6 7u83 162
    return(1);
2 7u83 163
  if (last(al) || last(bl))
6 7u83 164
    return(0);
165
  return(sim_explist(bro(al), bro(bl)));
2 7u83 166
}
167
 
168
 
6 7u83 169
static bool sim_exp(exp a, exp b)
2 7u83 170
{
6 7u83 171
 
2 7u83 172
  /*
173
   * basically eq_exp except equal shapes requirement is weakened to equal
174
   * sizes and alignments
175
   */
176
  if (name(a) == name(b))
177
  {
178
    if (name(a) == name_tag)
179
    {
180
      /* See if both are name_tags for same ident
181
	 with same offsets and same size and alignment */
6 7u83 182
      return(son(a) == son(b) && no(a) == no(b) &&
2 7u83 183
	      keep_eq_size(sh(a), sh(b)));
184
    }
6 7u83 185
    /* If it is not is_a
186
       OR
2 7u83 187
       if they are not the same size and alignment and same
6 7u83 188
     register type
2 7u83 189
     */
190
    if (!is_a(name(a)) || !keep_eq_size(sh(a), sh(b)))
191
    {
6 7u83 192
      return(0);
2 7u83 193
    }
6 7u83 194
    if (name(a) ==float_tag)
2 7u83 195
    {
196
      return eq_exp(son(a),son(b));
197
      /* float_tag is special since we could have e.g float (-1 slongsh) float (-1 ulongsh) */
198
    }
6 7u83 199
 
200
    return(no(a) == no(b) && sim_explist(son(a), son(b)));
2 7u83 201
  }
6 7u83 202
  return(0);
2 7u83 203
}
204
 
205
 
6 7u83 206
void clear_all(void)
2 7u83 207
{
208
  /* forget all register<->exp associations */
209
  int i;
210
 
211
  for (i = 0; i <= LAST_ALL_REGS; i++)
212
  {
213
    regexps[i].keptexp = nilexp;
214
    setregalt(regexps[i].inans, 0);
215
  }
216
}
217
 
218
 
6 7u83 219
void clear_reg(int i)
2 7u83 220
{
221
  /* forget reg i - exp association */
222
  i = absval(i);
223
  if (i >= 0 && i <= LAST_ALL_REGS)
224
  {
225
    regexps[i].keptexp = nilexp;
226
    setregalt(regexps[i].inans, 0);
227
  }
228
}
229
 
230
 
6 7u83 231
/* find if e has already been evaluated into a register low_reg..hi_reg
232
 
2 7u83 233
   Register tracking:
234
   The array regexps[] is an array of regpeep structures
235
   The elements of the structure regpeep are :
6 7u83 236
 
237
   ans inans;     This helps specify where the exp came from
238
   exp keptexp;   The exp
2 7u83 239
   bool iscont;   This specifies whether or not
6 7u83 240
 
2 7u83 241
   */
6 7u83 242
static ans iskept_regrange(exp e, int low_reg, int hi_reg)
2 7u83 243
{
244
  int i;
245
  ans aa;
246
  setregalt(aa, 0);		/* nilans until we know better */
247
 
248
  /* reg tracking of unions unsafe, as views of location can differ */
249
  /* +++ improve this */
250
  if (name(sh(e)) == cpdhd)
251
  {
252
    return aa;
253
  }
254
 
6 7u83 255
 
2 7u83 256
  for (i = low_reg; i <= hi_reg; i++)
257
  {
258
    exp ke = regexps[i].keptexp;
259
 
260
    if (ke != nilexp)
261
    {
262
      /* There is an association with register i */
263
      bool isc = regexps[i].iscont;
264
 
265
      ASSERT(!IS_R_TMP(i));	/* should not track R_TMP */
266
 
267
      if (
6 7u83 268
	 ((!isc && sim_exp(ke, e)) ||
269
	  (name(e) == cont_tag && isc && keep_eq_size(sh(ke), sh(e))
2 7u83 270
	    && sim_exp(ke, son(e)) && al1(sh(son(e))) == al1(sh(ke)))
6 7u83 271
	  )
2 7u83 272
	)
273
      {
274
	aa = (regexps[i].inans);
275
 
6 7u83 276
	FULLCOMMENT4("iskept found 1: reg=%d isc=%d name(e) =%d name(son(e)) =%d",
2 7u83 277
		     i, isc, name(e), name(son(e)));
278
	COMMENT1("iskept found: no = %d",no(e));
279
 
6 7u83 280
 
2 7u83 281
	switch (aa.discrim)
282
	{
283
	case notinreg:
284
	  {
285
	    if (!aa.val.instoreans.adval)
286
	    {
287
 
288
	      /*
289
	       * the expression is given indirectly - it may have also been
290
	       * loaded into a register
291
	       */
292
	      continue;
293
	    }
294
	    /* else ... */
295
	  }
296
	default:
297
	  return aa;
298
	}
299
      }
300
      else if (name(ke) == cont_tag && !isc)
301
      {
302
	ans aq;
303
 
304
	aq = regexps[i].inans;
305
 
306
	if (aq.discrim == notinreg)
307
	{
308
	  instore is;
309
 
310
	  is = insalt(aq);
311
	  if (!is.adval && is.b.offset == 0 && IS_FIXREG(is.b.base)
312
	      && sim_exp(son(ke), e))
313
	  {
314
 
315
	    /*
316
	     * the contents of req expression is here as a reg-offset
317
	     */
318
	    is.adval = 1;
319
	    setinsalt(aq, is);
320
 
6 7u83 321
	    FULLCOMMENT4("iskept found 2: reg=%d isc=%d name(e) =%d name(son(e)) =%d",
2 7u83 322
			 i, isc, name(e), name(son(e)));
323
 
324
	    return aq;
325
	  }
326
	}
327
      }
328
      else if (name(ke) == reff_tag && !isc)
329
      {
330
	ans aq;
331
 
332
	aq = regexps[i].inans;
333
	if (aq.discrim == notinreg)
334
	{
335
	  instore is;
336
 
337
	  is = insalt(aq);
338
	  if (is.adval && is.b.offset == (no(ke) / 8)
339
	      && IS_FIXREG(is.b.base)
340
	      && sim_exp(son(ke), e))
341
	  {
342
 
343
	    /*
344
	     * a ref select of req expression is here as a reg-offset
345
	     */
346
	    is.adval = 1;
347
	    is.b.offset = 0;
348
	    setinsalt(aq, is);
349
 
6 7u83 350
	    FULLCOMMENT4("iskept found 3: reg=%d isc=%d name(e) =%d name(son(e)) =%d",
2 7u83 351
			 i, isc, name(e), name(son(e)));
352
 
353
	    return aq;
354
	  }
355
	}
356
      }
357
    }
358
  }
359
  return aa;
360
}
361
 
362
 
363
/* find if e has already been evaluated into register 'reg' */
6 7u83 364
ans iskept_inreg(exp e, int reg)
2 7u83 365
{
366
  return iskept_regrange(e, reg, reg);
367
}
368
 
369
 
370
/* find if e has already been evaluated into a fixed point register */
6 7u83 371
ans iskept_reg(exp e)
2 7u83 372
{
373
  return iskept_regrange(e, 0, R_LAST);
374
}
375
 
376
 
377
/* find if e has already been evaluated into a floating point register */
6 7u83 378
ans iskept_freg(exp e)
2 7u83 379
{
380
  return iskept_regrange(e, FR_OFFSET, LAST_ALL_REGS);
381
}
382
 
383
 
384
/* find if e has already been evaluated into any register */
6 7u83 385
ans iskept(exp e)
2 7u83 386
{
387
  return iskept_regrange(e, 0, LAST_ALL_REGS);
388
}
389
 
390
 
391
/* return reg if 'a' can is in fixed reg */
6 7u83 392
int ans_reg(ans aa)
2 7u83 393
{
6 7u83 394
  if (aa.discrim == inreg && regalt(aa)!= 0)
2 7u83 395
  {
396
    /* the same expression has already been evaluated into a reg */
397
    return regalt(aa);
398
  }
399
 
400
  if (aa.discrim == notinreg)
401
  {
402
    instore is; is = insalt(aa);	/* no init to avoid IBM cc bug */
403
 
404
    if (is.adval && is.b.offset == 0)
405
    {
406
      /* the same expression has already been evaluated into a reg */
407
      return is.b.base;
408
    }
409
  }
410
 
411
  return R_NO_REG;
412
}
413
 
414
 
415
/* set up exp - address association */
6 7u83 416
void keepexp(exp e, ans loc)
2 7u83 417
{
418
  int pos=0;
419
 
420
  switch (loc.discrim)
421
  {
422
  case insomereg:
423
  case insomefreg:
424
    {
425
      fail("Keep ? reg");
426
    }
427
  case inreg:
428
    {
429
      pos = regalt(loc);
430
      break;
431
    }
432
  case infreg:
433
    {
434
      pos = fregalt(loc).fr + FR_OFFSET;
435
      break;
436
    }
437
  case notinreg:
438
    {
439
      pos = insalt(loc).b.base;
440
      if (!IS_FIXREG(pos))
441
	return;
442
    }
443
 
444
  }
445
 
446
  ASSERT(pos >= 0 && pos <= LAST_ALL_REGS);
447
 
448
  if (IS_R_TMP(pos))
449
    return;			/* don't track R_TMP which is used outside
450
				 * tracking scheme */
451
 
452
  regexps[pos].keptexp = e;
453
  regexps[pos].inans = loc;
454
  regexps[pos].iscont = 0;
455
  COMMENT2("keepexp : reg %d kept name is %d",pos,name(e));
456
}
457
 
458
 
459
/* set up cont(e)-reg association */
460
/* if 0=<reg<=31  this means a fixed point register
461
   if 31<reg<=63  this means a float point register single precision
462
   if -63<=reg<-31 this means a float point register double precision
463
   */
6 7u83 464
void keepcont(exp e, int reg)
2 7u83 465
{
466
  freg fr;
467
  int z = absval(reg);
468
 
469
  if (z >= FR_OFFSET)
470
  {
471
    fr.dble = (reg < 0);
472
    fr.fr = z - FR_OFFSET;
473
    setfregalt(regexps[z].inans, fr);
474
  }
475
  else
476
  {
477
    instore is;
478
 
479
    if (IS_R_TMP(z))
480
      return;			/* don't track R_TMP which is used outside
481
				 * tracking scheme */
482
 
483
    is.b.base = reg;
484
    is.b.offset = 0;
485
    is.adval = 1;
486
    setinsalt(regexps[z].inans, is);
487
  }
488
 
489
  ASSERT(z >= 0 && z <= LAST_ALL_REGS);
490
  regexps[z].keptexp = e;
491
  regexps[z].iscont = 1;
492
  COMMENT2("keepcont : reg %d kept name is %d",z,name(e));
493
 
494
}
495
 
496
 
497
/* keepreg keeps the exp e */
498
/* if 0=<reg<=31  this means a fixed point register
499
   if 31<reg<=63  this means a float point register single precision
500
   if -63<=reg<-31 this means a float point register double precision
501
   */
6 7u83 502
void keepreg(exp e, int reg)
2 7u83 503
{
504
  freg fr;
505
  int z = absval(reg);
506
 
507
  if (z >= FR_OFFSET)
508
  {
509
    /* It is a float register */
6 7u83 510
    /* HACK: if reg <0 then it is double
2 7u83 511
       otherwise it is single precision */
512
    fr.dble = (reg < 0);
513
    fr.fr = z - FR_OFFSET;
514
    setfregalt(regexps[z].inans, fr);
515
  }
516
  else
517
  {
518
    instore is;
519
    if (IS_R_TMP(z))
520
    {
521
      return;			/* don't track R_TMP which is used outside
522
				 * tracking scheme */
523
    }
524
    is.b.base = reg;
525
    is.b.offset = 0;
526
    is.adval = 1;
527
    setinsalt(regexps[z].inans, is);
528
  }
6 7u83 529
 
2 7u83 530
  ASSERT(z >= 0 && z <= LAST_ALL_REGS);
531
  regexps[z].keptexp = e;
532
  regexps[z].iscont = 0;
533
  COMMENT3("keepreg : reg %d kept name is %d no %d",z,name(e),no(e));
534
}
535
 
6 7u83 536
bool couldeffect(exp , exp);
2 7u83 537
 
538
/* could 'e' be 'lhs' */
539
bool couldbe PROTO_N ((e,lhs)) PROTO_T (exp e X exp lhs )/* is var name_tag exp or 0 meaning cont */
540
{
541
  int ne = name(e);
542
  exp s = son(e);
543
 
544
  if (ne == name_tag)
545
  {
546
    if (lhs != 0 && s == son(lhs))
547
    {
548
      return 1;
549
    }
550
    if (isvar(s))
551
    {
6 7u83 552
      return(lhs == 0 && (isglob(s) || isvis(s)));
2 7u83 553
    }
554
    if (IS_A_PROC(s))
6 7u83 555
      return(lhs == 0);
2 7u83 556
    if (son(s) == nilexp)
557
      return 1;
558
    return couldbe(son(s), lhs);
559
  }
560
  if (ne == cont_tag)
561
  {
6 7u83 562
    if (lhs != 0 && name(s) == name_tag && son(s)!= nilexp)
2 7u83 563
    {
6 7u83 564
      return(son(s) == son(lhs) || isvis(son(lhs)) || isvis(son(s)));
2 7u83 565
    }
566
    return 1;
567
  }
568
  if (ne == reff_tag || ne == field_tag)
569
  {
570
    return couldbe(s, lhs);
571
  }
572
  if (ne == addptr_tag || ne == subptr_tag)
573
  {
6 7u83 574
    return(couldbe(s, lhs) || couldeffect(bro(s), lhs));
2 7u83 575
  }
576
 
577
  return 1;
578
 
579
}
580
 
581
 
582
/* could alteration to z effect e? */
6 7u83 583
bool couldeffect PROTO_N ((e,z)) PROTO_T (exp e X exp z )/* a name or zero */
2 7u83 584
{
585
  int ne = name(e);
586
 
587
  if (ne == cont_tag)
588
  {
589
    return couldbe(son(e), z);
590
  }
591
  if (ne == name_tag)
592
  {
593
    if (isvar(son(e)))
6 7u83 594
      return(z == 0 && isvis(son(e)));
2 7u83 595
    if (IS_A_PROC(son(e)))
596
      return 0;
597
    if (son(son(e)) == nilexp)
598
      return 1 /* could it happen? */ ;
599
 
600
    return couldeffect(son(son(e)), z);
601
 
602
  }
603
  if (ne < plus_tag || ne == contvol_tag)
604
    return 1;
605
 
606
  e = son(e);
607
 
608
  while (e != nilexp)
609
  {
610
    if (couldeffect(e, z))
611
      return 1;
612
    if (last(e))
613
      return 0;
614
    e = bro(e);
615
  }
616
  return 0;
617
}
618
 
619
 
620
/* does e depend on z */
6 7u83 621
bool dependson(exp e, bool isc, exp z)
2 7u83 622
{
623
  if (e == nilexp)
624
  {
625
    return 0;
626
  }
627
  for (;;)
628
  {
629
    if (name(z) == reff_tag || name(z) == addptr_tag ||
630
	name(z) == subptr_tag)
631
    {
632
      z = son(z);
633
    }
634
 
6 7u83 635
    if (name(z)!= name_tag)
2 7u83 636
    {
6 7u83 637
      if (name(z)!= cont_tag)
2 7u83 638
	return 1;
639
      z = 0;
640
      break;
641
    }
642
 
643
    if (isvar(son(z)))
644
      break;
645
    if (IS_A_PROC(son(z)))
646
    {
647
      z = 0;
648
      break;
649
    }
650
    if (son(son(z)) == nilexp)
651
      return 1;			/* can it happen? */
652
    z = son(son(z));
653
  }
654
 
655
  /* z is now unambiguous variable name or 0 meaning some contents */
656
 
6 7u83 657
  return((isc)? couldbe(e, z): couldeffect(e, z));
2 7u83 658
}
659
 
660
 
661
/* remove association of any register which depends on lhs */
6 7u83 662
void clear_dep_reg(exp lhs)
2 7u83 663
{
664
  int i;
665
 
666
  for (i = 0; i <= LAST_ALL_REGS; i++)
667
  {
668
    if (regexps[i].keptexp != nilexp)
669
    {
6 7u83 670
      switch (name(regexps[i].keptexp))
2 7u83 671
      {
672
      case val_tag:
673
      case null_tag:
674
      case real_tag:
675
      case string_tag:
676
      case name_tag:
677
      case current_env_tag:
678
	{
679
	  if (!regexps[i].iscont)
680
	  {
681
	    /* constant value, cannot be changed by assign */
682
	    continue;
683
	  }
684
	}
685
	/*FALLTHROUGH*/
686
 
687
      default:
688
	{
689
          if (dependson(regexps[i].keptexp, regexps[i].iscont, lhs))
690
          {
691
            FULLCOMMENT2("clear_dep_reg: reg=%d iscont=%d", i, regexps[i].iscont);
692
            regexps[i].keptexp = nilexp;
693
            setregalt(regexps[i].inans, 0);
694
          }
695
	}
696
      }
697
    }
698
  }
699
}