Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /branches/tendra5/src/installers/alpha/common/dump_distr.c – Rev 2

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
/* 	$Id: dump_distr.c,v 1.1.1.1 1998/01/17 15:55:59 release Exp $	 */
32
 
33
#ifndef lint
34
static char vcid[] = "$Id: dump_distr.c,v 1.1.1.1 1998/01/17 15:55:59 release Exp $";
35
#endif /* lint */
36
/* 
37
   dump_distrib.c
38
*/
39
#include "config.h"
40
#include "common_types.h"
41
#include "exptypes.h"
42
#include "exp.h"
43
#include "expmacs.h"
44
#include "tags.h"
45
#include "bitsmacs.h"   
46
#include "new_tags.h"
47
#include "procrectypes.h"
48
#include "shapemacs.h"
49
#include "frames.h"
50
#include "regable.h"
51
#include "reg_defs.h"
52
#include "dump_distr.h"
53
 
54
bool do_dump_opt = 1;		/*  may be unset by -d flag */
55
 
56
static  space zsp = {
57
  0, 0
58
};				/* long fixed, long flt */
59
 
60
void maxsp
61
    PROTO_N ( ( a, b ) )
62
    PROTO_T ( space *a X space b )
63
{
64
  a -> fixed |= b.fixed;
65
  a -> flt |= b.flt;
66
}
67
 
68
 
69
/* 
70
   accumulate s regs used in e; pars gives bits indicating 
71
   which s-regs are used for the parameters of current proc; 
72
   incpars says dont ignore pars in registers 
73
*/
74
space suses
75
    PROTO_N ( ( e, pars, incpars ) )
76
    PROTO_T ( exp e X space *pars X int incpars )
77
{
78
 
79
  space ans;
80
  ans = zsp;
81
  if (e == nilexp)
82
    return ans;
83
  switch (name(e)) {
84
  case name_tag: {
85
    exp id = son (e);
86
    if (name (id) == ident_tag) {
87
      if (isglob (id) || (props (id) & inanyreg) == 0)
88
	return ans /* global or not in register */ ;
89
      if ((props (id) & defer_bit) != 0)
90
	return suses (son (id), pars, incpars);/*dec does not take space*/
91
      if (isparam(id) && no(id) !=0 && 
92
	  ((!incpars && props(son(id)) != 0) || no(id)==props(son(id)) ) )
93
	/* par in original reg (perhaps destined for sreg) */
94
	return ans;
95
      if ((props(id) & infreg_bits)!=0 ) {
96
	if (no (id) != NO_REG  && no(id)!=0) {/* uses floating s-reg */
97
	  if(isparam(id) && props(son(id))!=0 && props(son(id))>=incpars){
98
	    return ans;
99
	  }
100
	  else{
101
	    ans.flt = (1<<(no(id)));
102
	  }
103
	}
104
      }
105
      else
106
	if (no (id) != 0 && no (id) != 32) {
107
	  /* in s seg */
108
	  if (isparam(id) && props(son(id)) !=0 && 
109
	      props(son(id)) >= incpars) return ans;
110
	  ans.fixed = 1 << (no (id));
111
	}
112
    }
113
    break;
114
  }
115
  case case_tag: 
116
  {
117
    return suses (son (e), pars, incpars);
118
  }
119
  case seq_tag: {
120
    exp t = son (son (e));
121
    ans = suses (bro (son (e)), pars, incpars);
122
    for (;;) {
123
      maxsp (&ans, suses (t, pars,incpars));
124
      if (last (t)) {
125
	return ans;
126
      }
127
      t = bro (t);
128
    }
129
  }
130
  case env_offset_tag :
131
  case 0 : 
132
  case goto_tag : 
133
  case val_tag :
134
  case special_tag :
135
  case null_tag : 
136
  case real_tag : 
137
  case string_tag : 
138
  case clear_tag : 
139
  case current_env_tag :
140
  case top_tag : {
141
    break;
142
  }
143
  case apply_general_tag:
144
  case tail_call_tag:
145
  {
146
    maxsp(&ans,*pars);
147
    goto def1;
148
  }
149
 
150
  case apply_tag: {
151
    /* proc call preserves s-regs; however must make sure that any
152
	   pars destined for s-regs get there */
153
    exp dad = father(e);
154
    if (name(dad)==res_tag && props(dad)) {
155
      /* tl recursion  - don't have to dump link or later regs */
156
      int i;
157
      exp p = bro(son(e));
158
      if (last(son(e)) || name(p)==top_tag) return ans;
159
      for(i=(incpars>6)?incpars:6; ; i++) {
160
	if (!valregable(sh(p))) i=22;
161
	maxsp(&ans, suses(p, pars, i));
162
	if(last(p)) return ans;
163
	p = bro(p);
164
      }
165
    } else 	maxsp (&ans, *pars);
166
  }				/* else cont to default */
167
  FALL_THROUGH
168
  default: def1:{
169
    exp t = son (e);
170
    maxsp (&ans, suses (t, pars,incpars));
171
    while (t!=nilexp && !last (t)) {
172
      t = bro (t);
173
      maxsp (&ans, suses (t, pars,incpars));
174
    }
175
  }
176
  }
177
  return ans;
178
}
179
 
180
bool sameregs
181
    PROTO_N ( ( a,b ) )
182
    PROTO_T ( space *a X space *b )
183
{
184
  return ((a -> fixed | b -> fixed) == b -> fixed && (a -> flt | b -> flt) == b -> flt);
185
}
186
 
187
space remd
188
    PROTO_N ( ( tobd,dmpd ) )
189
    PROTO_T ( space *tobd X space *dmpd )
190
{
191
  /* any regs left out of tobd after dmpd has been done */
192
  space ans;
193
  ans.fixed = tobd -> fixed & ~dmpd -> fixed;
194
  ans.flt = tobd -> flt & ~dmpd -> flt;
195
  return ans;
196
}
197
 
198
 
199
 
200
 
201
/* 
202
   replace exp in pe by new dump with props = fixeds and 
203
   no = flts to be dumped ; thread different dumps to same rsc 
204
   via pt; delivers bool to say whether all sregs have been 
205
   dumped 
206
*/
207
bool placedump
208
    PROTO_N ( ( pe, dmpd, tobd, nds ) )
209
    PROTO_T ( exp *pe X space *dmpd X space *tobd X space *nds )
210
{
211
  exp e = *pe;
212
  exp dflt = getexp(nilexp, nilexp, 1, nilexp,nilexp, 0, nds->flt & ~dmpd->flt, dump_tag);
213
  exp dump = getexp (sh (e), bro (e), last (e), e, dflt, 0, (nds -> fixed & ~dmpd -> fixed),
214
       dump_tag);
215
  bro (e) = dump;
216
  setlast (e);
217
  *(pe) = dump;
218
  (dmpd -> fixed) |= nds -> fixed;
219
  (dmpd -> flt) |= nds -> flt;
220
  return sameregs (tobd, dmpd);
221
}
222
 
223
 
224
 
225
/* 
226
   delivers last exp in seq first after all tests (to second) ; 
227
   beforeb is space up to end of tests; second only use beforeb;
228
   otherwise nilexp 
229
*/
230
exp goodcond
231
    PROTO_N ( ( first, second, beforeb, pars ) )
232
    PROTO_T ( exp first X exp second X space *beforeb X space *pars )
233
{
234
  exp t;
235
  space nds;
236
  int   n = no (son (second));	/* no of uses of labst second */
237
  if (name (first) != seq_tag)
238
    return nilexp;
239
  t = son (son (first));
240
  *beforeb = zsp;
241
  for (;;) {
242
    maxsp(beforeb, suses(t, pars, 0));
243
 
244
    if (name (t) == test_tag) {
245
      if (pt (t) != second)
246
	return nilexp;
247
      if (--n == 0) break;
248
    }
249
    if (last (t)) {
250
     	return nilexp;
251
    }
252
    t = bro (t);
253
  }
254
  nds = suses (second, pars, 0);
255
  if (sameregs (&nds, beforeb))
256
    return t;
257
  return nilexp;
258
}
259
 
260
bool alljumps
261
    PROTO_N ( ( e, slv, nol ) )
262
    PROTO_T ( exp e X exp slv X int *nol )
263
{
264
  /* all all branches to labsts of slove_tag slv in e ? */
265
  recurse:
266
  switch (name(e)) {
267
  case case_tag: {
268
    exp z = bro(son(e));
269
    for(;;) {
270
      if (father(pt(z))==slv) {
271
	if (--(*nol)==0) return 1;
272
      }
273
      if (last(z)) { e = son(e); goto recurse; }
274
      z = bro(z);
275
    }
276
  }
277
  case goto_tag: case test_tag: {
278
    if (father(pt(e))==slv) {
279
      if (--(*nol)==0) return 1;
280
    }
281
    if (name(e)== goto_tag) return 0;
282
    /* and continue */
283
  }
284
  FALL_THROUGH
285
  case name_tag: case val_tag: case float_tag: case string_tag:
286
    return 0;
287
  default: {
288
    exp se = son(e);
289
    if (se==nilexp) return 0;
290
    for(;;) {
291
      if (last(se)) { e = se; goto recurse; }
292
      if (alljumps(se, slv, nol)) return 1;
293
      se = bro(se);
294
    }
295
  }
296
  }
297
}
298
 
299
 
300
 
301
bool goodsolve
302
    PROTO_N ( ( e ) )
303
    PROTO_T ( exp e )
304
{
305
  exp m = bro(son(e));
306
  int nol;
307
  for(nol=0;;nol++) {
308
    if (no(son(m))!=1) return 0; /* more than one branch to labst */
309
    if (last(m)) break;
310
    m = bro(m);
311
  }
312
  return alljumps(son(e), e, &nol);
313
}
314
 
315
static int  notregs;
316
static int  notfregs;
317
 /* use to make sure of enough t-regs which are not par regs; I reuse any
318
    par registers whose pars are put in s-regs as t-regs  */
319
 
320
void pushdumps
321
    PROTO_N ( ( pe, dmpd, tobd, pars ) )
322
    PROTO_T ( exp *pe X space *dmpd X space *tobd X space *pars )
323
{
324
  /* tries to delay the dumps of the s-regs as late as possible 
325
     ; pe is the place in the tree to insert any dump found
326
     necessary in this recursion; dmpd gives the sregs already dumped and
327
     tobd is all which may have to be dumped; pars give the registers
328
     containing the initial position of any parameters */
329
 
330
  space nds;
331
  exp e = *(pe);
332
  exp *arg;
333
 
334
  switch (name (e)) {
335
  case ident_tag: {
336
    nds = suses (son (e), pars,0);
337
    if ((props (e) & inanyreg) != 0 && no (e) == 0) {
338
      /*  This definition will be allocated into a t-reg so make sure
339
	  of enough t-regs which are not par regs; I reuse any par
340
	  registers whose pars are put in s-regs as t-regs  */
341
      if (is_floating (name (sh (son (e))))) {
342
	if (notfregs-- < 0) {
343
	  nds = remd (tobd, dmpd);
344
	  placedump ( pe, dmpd, tobd, &nds);
345
	  return;
346
	}
347
      }
348
      else {
349
	if (notregs-- < 0) {
350
	  nds = remd (tobd, dmpd);
351
	  placedump ( pe, dmpd, tobd, &nds);
352
	  return;
353
	}
354
      }
355
    }
356
    if (name (son (e)) != clear_tag || 
357
	(isparam(e) && props(son(e))==0 /* ie initially on stack */)  ) {
358
      /* id could be in s-reg; find from use */
359
      maxsp (&nds, suses (pt (e), pars, 0));
360
    }
361
    if (sameregs (&nds, dmpd) ||
362
	!placedump ( pe, dmpd, tobd, &nds)) {
363
      /* not all regs have been dumped - continue with body */
364
      arg = &bro(son (e));
365
      pushdumps ( arg, dmpd, tobd, pars);
366
    }	
367
    return;
368
  }
369
  case seq_tag: {
370
    exp prev;
371
    exp list = son (son (e));
372
    if (last(list) ) {
373
      nds = suses(bro(son(e)), pars, 22);
374
      if (nds.fixed==0 && nds.flt==0) {
375
	/* seq consists of two exps with last not using regs */
376
	pushdumps(&son(son(e)), dmpd, tobd, pars);
377
	return;
378
      }
379
    }
380
    nds = suses (list, pars, 0);
381
    if (!sameregs (&nds, dmpd)) {
382
      /* first statement uses undumped s-regs */
383
      if (placedump ( pe, dmpd, tobd, &nds)) {
384
	return;
385
      }
386
    }
387
    prev = list;
388
    while (!last (list)) {
389
      prev = list;
390
      list = bro (list);
391
      nds = suses (list, pars, 0);
392
      if (!sameregs (&nds, dmpd)) {
393
	/* uses undumped s-regs; construct new seq as result of this
394
	   one .... */
395
	exp s_hold = getexp (sh (e), bro (son (e)), 0, list, nilexp, 0, 0,
396
		name (son (e)));
397
	exp seq = getexp (sh (e), e, 1, s_hold, nilexp, 0, 0, seq_tag);
398
	bro (prev) = son (e);
399
	setlast (prev);
400
	bro (son (e)) = seq;
401
	bro (bro (s_hold)) = seq;
402
	while (!last (list)) {
403
	  list = bro (list);
404
	}
405
	bro (list) = s_hold;
406
	/* .... and continue with new result */
407
	arg = &bro(son (e));
408
	if (!placedump ( arg, dmpd, tobd, &nds)) {
409
	  pushdumps ( arg, dmpd, tobd, pars);
410
	}
411
	return;
412
      }
413
    }
414
    /* no new s-regs used - carry on with result */
415
    arg = &bro(son (e));
416
    pushdumps ( arg, dmpd, tobd, pars);
417
    return;
418
  }
419
  case cond_tag: {
420
    exp first = son (e);
421
    exp second = bro (first);
422
    exp t;
423
    bool same;
424
    space beforeb;
425
    nds = suses (first, pars, 0);
426
    same = sameregs (&nds, dmpd);
427
    if (!same && (t = goodcond (first, second, &beforeb, pars)) != nilexp) {
428
      /* worth looking further  into first part */
429
      if (!sameregs(&beforeb, dmpd) ) {
430
	if (placedump ( pe, dmpd, tobd, &beforeb)) {
431
	  return;
432
	}
433
      }	  	
434
      if (!last (t)) {
435
	exp seq_hold =
436
	  getexp (sh (first), bro (son (first)), 0, bro (t), nilexp, 0, 0,
437
		  name (son (first)));
438
	exp new =
439
	  getexp (sh (first), first, 1, seq_hold, nilexp, 0, 0, seq_tag);
440
	exp x = son (seq_hold);
441
	while (!last (x)) {
442
	  x = bro (x);
443
	}
444
	bro (x) = seq_hold;	/* set dad son seq_hold */
445
	bro (bro (seq_hold)) = new;
446
	setlast (bro (seq_hold));/* set dad of seq_hold */
447
	bro (son (first)) = new;
448
	setlast (t);
449
	bro (t) = son (first);
450
	/* first is now (t; (rest of first)) */
451
      }
452
      arg = &bro(son (first));
453
      pushdumps ( arg, dmpd, tobd, pars);
454
      return;
455
    }
456
    if (!same) {		/* new s-regs used in first part */
457
      if (placedump ( pe, dmpd, tobd, &nds)) {
458
	return;
459
      }
460
    }
461
    arg = &bro(son (e));
462
    pushdumps ( arg, dmpd, tobd, pars);
463
    return;
464
  }
465
 
466
/*    case diag_tag: 
467
    case fscope_tag: 
468
    case cscope_tag: {
469
	arg= &son(e);
470
	pushdumps ( arg, dmpd, tobd, pars);
471
	return;
472
      }
473
*/
474
  case labst_tag: {		/* can only arrive here from cond */
475
    arg = &bro(son (e));
476
    pushdumps ( arg, dmpd, tobd, pars);
477
    return;
478
  }
479
  case solve_tag: {
480
    if (goodsolve(e)) {
481
      exp m = bro(son(e));
482
      space old_dmpd;	
483
      nds = suses(son(e), pars, 0);
484
      if (!sameregs(&nds, dmpd)) {
485
	if (placedump(pe, dmpd,tobd, &nds) ) return;
486
      }
487
      old_dmpd = *dmpd;
488
      for(;;) {
489
	pushdumps(&bro(son(m)), dmpd, tobd, pars);
490
	if (last(m)) return;
491
	m = bro(m);
492
	*dmpd = old_dmpd;
493
      }
494
    } /* else continue ... */		
495
  }
496
    FALL_THROUGH
497
  default: {
498
      nds = suses(e, pars, 0);
499
      if (!sameregs(&nds, dmpd)) {
500
	placedump ( pe, dmpd, tobd, &nds);
501
      }
502
    }
503
  }	
504
}
505
 
506
 
507
void dump_opt
508
    PROTO_N ( ( rscope, tobd, pars ) )
509
    PROTO_T ( exp rscope X space *tobd X space *pars )
510
{
511
  /* rscope is proc-tag exp;  tobd is set of s-regs to be dumped; 
512
     pars is subset of tobd which will be used as  parameters of 
513
     proc */
514
  exp  * arg;
515
  space dmpd;
516
  dmpd = zsp;			/* those regs already dumped */
517
  arg = &son(rscope);
518
 
519
  notregs = 10;
520
  notfregs = 8;			/* no of t-regs != par regs */
521
  if (!do_dump_opt || No_S || sameregs (tobd, &dmpd)) {
522
    (void)placedump ( arg, &dmpd, tobd, tobd);
523
  }
524
  else {
525
    (void)pushdumps ( arg, &dmpd, tobd, pars);
526
  }
527
  return;
528
}