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/locate.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: locate.c,v 1.1.1.1 1998/01/17 15:56:00 release Exp $	 */
32
 
33
#ifndef lint
34
static char vcid[] = "$Id: locate.c,v 1.1.1.1 1998/01/17 15:56:00 release Exp $";
35
#endif /* lint */
36
 
37
/* 
38
   locate.c
39
   This file provides functions to locate an exp.
40
*/
41
 
42
/*
43
$Log: locate.c,v $
44
 * Revision 1.1.1.1  1998/01/17  15:56:00  release
45
 * First version to be checked into rolling release.
46
 *
47
 * Revision 1.4  1995/08/21  08:45:04  john
48
 * Changed include files
49
 *
50
 * Revision 1.3  1995/07/27  10:09:06  john
51
 * Modified due to change in general proc handling
52
 *
53
 * Revision 1.2  1995/05/16  10:53:23  john
54
 * Changes for spec 3.1
55
 *
56
 * Revision 1.1.1.1  1995/03/23  10:39:12  john
57
 * Entered into CVS
58
 *
59
 * Revision 1.9  1995/03/23  10:21:00  john
60
 * Changes for bitfields & offsets
61
 *
62
 * Revision 1.8  1995/01/26  13:43:16  john
63
 * Removed some unused variables
64
 *
65
*/
66
 
67
#include "config.h"
68
#include "addresstypes.h"
69
#include "expmacs.h"
70
#include "tags.h"
71
#include "inst_fmt.h"
72
#include "alpha_ins.h"
73
#include "bitsmacs.h"
74
#include "exp.h"
75
#include "procrecs.h"
76
#include "guard.h"
77
#include "eval.h"
78
#include "regexps.h"
79
#include "shapemacs.h"
80
#include "pseudo.h"
81
#include "getregs.h"
82
#include "move.h"
83
#include "handle_sregs.h"
84
#include "common_types.h"
85
#include "frames.h"
86
#include "code_here.h"
87
#include "reg_defs.h"
88
#include "locate.h"
89
#include "fail.h"
90
extern  FILE * as_file;
91
 
92
int locals_offset; /* the offset in bits of start of current locals */
93
int frame_size;	/* the size of the current stack frame in bits */
94
 
95
 
96
baseoff boff
97
    PROTO_N ( ( id ) )
98
    PROTO_T ( exp id )
99
{
100
  baseoff an;
101
  if (isglob (id)) {		/* globals */
102
    dec * gl = brog(id);
103
    long sno = gl->dec_u.dec_val.sym_number;
104
    an.base = -(sno + 1);
105
    an.offset = 0;
106
  }
107
  else {
108
    int   x = no (id);
109
    int   b = x & 0x3f;
110
    if(name(son(id)) == caller_name_tag){
111
      an.base = SP;
112
      an.offset = (x-b)>>4;
113
    }
114
    else if (b == SP) {
115
      an.base = SP;
116
      an.offset = ((x - b) >> 4) + (locals_offset >> 3);
117
      /* locally declared things accessed by sp*/
118
    }
119
    else if (b==FP && Has_fp) {
120
      an.base = FP;
121
      an.offset = ((x - b) >> 4)+((locals_offset-callee_size-frame_size)>>3);
122
      /* locally declared things accessed by fp */
123
    }    	
124
    else if((b == local_reg && Has_vcallees)){
125
      an.base = b;
126
      an.offset = (((x-b))>>4)+ ((locals_offset-frame_size/*-callee_size*/)>>3);
127
    }
128
    else if (b <= 31) {
129
	an.base = b;
130
	an.offset = ((x - b) >> 4);
131
	/* other base offsets */
132
    }
133
    else if (b == 32) {
134
      an.base = -((x - b) >> 6);
135
      an.offset = 0;
136
	  /* global names  */
137
    }
138
    else if (b == 33) {
139
      an.base = (x - b) >> 6;
140
      an.offset = 0;
141
      /* global anonymous */
142
    }
143
    else {
144
      failer ("not a baseoff in boff ");
145
    }
146
  }
147
  return an;
148
}
149
 
150
 /* 
151
    locate differs from locate1 only in that it looks to 
152
    see if e has already been evaluated somehow 
153
*/
154
where locate PROTO_S ((exp e, space sp, shape s, int dreg));
155
 
156
where locate1
157
    PROTO_N ( ( e, sp, s, dreg ) )
158
    PROTO_T ( exp e X space sp X shape s X int dreg )
159
{
160
  /* finds the address of e using shape s;
161
     sp gives available t-regs for any inner
162
     evaluation. dreg is historical (carried over from mipstrans). */
163
  ash a;
164
  ans aa;
165
  where wans;
166
  source src;
167
 
168
  a = ashof (s);
169
 
170
  switch (name (e)) {
171
   case name_tag: 
172
    {
173
      exp decx = son (e);
174
      bool var = isvar (decx);
175
      /* this a locally declared name ... */
176
      if (props (decx) & defer_bit) {
177
	/* ... it has been identified with a
178
	   simple expression which is better
179
	   evaluated every time */
180
	where w;
181
	w = locate (son (decx), sp, sh (son (decx)), dreg);
182
 
183
	if (no (e) == 0) {
184
	  aa = w.answhere;
185
	}
186
	else {
187
	  instore is;
188
	  switch (w.answhere.discrim) {
189
	    case notinreg: {
190
	      is = insalt (w.answhere);
191
	      is.b.offset += (no (e) / 8);
192
	      break;
193
	    }
194
	    default: 
195
	    failer ("NOT deferable");
196
	  }
197
 
198
	  setinsalt (aa, is);
199
	}
200
      }
201
      else if (props (decx) & inreg_bits) {
202
	/* ... it has been allocated in a fixed
203
	   point reg */
204
	if (var) {
205
	  setregalt (aa, no (decx));
206
	}
207
	else {
208
	  instore b;
209
	  b.b.base = no (decx);
210
	  b.b.offset = 0;
211
	  b.adval = 1;
212
	  setinsalt (aa, b);
213
	}
214
      }
215
      else if (props (decx) & infreg_bits) {
216
	/* ... it has been allocated in a floating
217
	   point reg */
218
	freg fr;
219
	fr.fr = no (decx);
220
	if(a.ashsize==64) 
221
	  fr.type = IEEE_double;
222
	else
223
	  fr.type = IEEE_single;
224
	setfregalt (aa, fr);
225
      }
226
      else {		/* ... it is in memory */
227
	instore is;
228
	if (var || (name (sh (e)) == prokhd &&
229
		    (son (decx) == nilexp || name (son (decx)) == proc_tag
230
		     || name(son(decx)) == general_proc_tag))) {
231
	  is.adval = 1;
232
	}
233
	else {
234
	  is.adval = 0;
235
	}
236
	is.b = boff (decx);
237
	is.b.offset += (no (e) / 8);
238
	setinsalt (aa, is);
239
      }
240
      wans.answhere = aa;
241
      wans.ashwhere = a;
242
      return wans;
243
    }
244
 
245
    case addptr_tag: 
246
    {
247
      exp sum = son (e);
248
      where wsum;
249
      int   addend;
250
      space nsp;
251
      int   reg;
252
      int   ind;
253
      instore is;
254
      ans asum;
255
      int multiplier;
256
      wsum = locate (sum, sp, sh (sum), NO_REG);
257
      asum = wsum.answhere;
258
      /* answer is going to be wsum displaced by integer result of
259
	   evaluating bro(sum) */
260
 
261
      switch (asum.discrim) {
262
      case notinreg: 
263
      {
264
	instruction scale_ins;
265
	is = insalt (asum);
266
	if (is.adval) {	/* wsum is a literal address in store ... 
267
			 */
268
	  baseoff b;
269
	  b = is.b;
270
	  if (b.base < 0 || b.base > 31) {
271
	    /* ... it is not a base-offset , so make
272
	       it one */
273
	    reg = getreg (sp.fixed);
274
	    load_store (i_lda, reg, b);
275
	    keepreg (sum, reg);
276
	    b.base = reg;
277
	    b.offset = 0;
278
	  }
279
	  nsp = guardreg (b.base, sp);
280
 
281
	  /* choose the appropriate instruction based on the 
282
	     multiplier.  Not shure if this is any faster than
283
	     using two instructions : mult & add.
284
	     */
285
	  if(name(bro(sum)) == offset_mult_tag){
286
	    multiplier = no(bro(son(bro(sum))));
287
	    switch(multiplier){
288
	    case 4:
289
	      scale_ins=i_s4addq;
290
	      addend = reg_operand(son(bro(sum)),nsp);
291
	      break;
292
	    case 8:
293
	      scale_ins=i_s8addq;
294
	      addend = reg_operand(son(bro(sum)),nsp);
295
	      break;
296
	    default:
297
	      scale_ins=i_addq;
298
	      addend = reg_operand(bro(sum),nsp);
299
	    }
300
	  }
301
	  else{
302
	    scale_ins=i_addq;
303
	    addend = reg_operand (bro (sum), nsp);
304
	  }
305
 
306
	  /* evaluate the displacement ... */
307
	  if (dreg == NO_REG)
308
	    dreg = getreg (nsp.fixed);
309
	  src.reg=0;
310
	  src.value=addend;
311
	  operate_fmt(scale_ins,src.value,b.base,dreg);
312
	  /* ... add it to the base register into new reg */
313
	  b.base = dreg;
314
	  is.b = b;
315
	  setinsalt (aa, is);
316
	  wans.answhere = aa;
317
	  wans.ashwhere = a;
318
	  /* ...and use it as base a literal base-offset result */
319
	  keepexp (e, aa);
320
	  return wans;
321
	}
322
	else {		/* wsum represents an actual pointer in
323
			   store... */
324
	  ind = getreg (sp.fixed);
325
	  load_store(i_ldq,ind,is.b);
326
	  /* ... so load it into a good register */
327
	}
328
	goto breakpt;
329
	/* should be break - thought there was cc error */
330
 
331
      }			/* end notinreg */
332
 
333
      case inreg: 
334
	/* wsum is already in reg */
335
      {
336
	ind = regalt (asum);
337
	goto breakpt;
338
      }
339
 
340
      default: {
341
	failer ("Locate ? reg");
342
      }
343
      }			/* end case */
344
 
345
    breakpt: 		/* register ind contains the evaluation of
346
		        1st operand of addptr */
347
      nsp = guardreg (ind, sp);
348
      if (name(bro(sum)) == env_offset_tag || 
349
	  name(bro(sum))==general_env_offset_tag) {
350
	is.b.base = ind;
351
	is.b.offset = frame_offset(son(bro(sum)));
352
      } 
353
      else {
354
	instruction ins=i_addq;
355
	if(name(bro(sum)) == offset_mult_tag && 
356
	   name(bro(son(bro(sum))))==val_tag){
357
	  switch(no(bro(son(bro(sum))))){
358
	  case 4:
359
	    ins=i_s4addq;
360
	    addend = reg_operand(son(bro(sum)),nsp);
361
	    break;
362
	  case 8:
363
	    ins=i_s8addq;
364
	    addend = reg_operand(son(bro(sum)),nsp);
365
	    break;
366
	  default:
367
	    addend = reg_operand(bro(sum),nsp);
368
	    break;
369
	  }
370
	}
371
	else{
372
	  addend = reg_operand(bro(sum),nsp);
373
	}
374
	/*addend = reg_operand (bro (sum), nsp);*/
375
	/* evaluate displacement .... */
376
	if (dreg == NO_REG)
377
	  dreg = getreg (nsp.fixed);
378
	src.reg=0;
379
	src.value=addend;
380
	operate_fmt(ins,src.value,ind,dreg);
381
          /* ... add it to ind in new reg */
382
	is.b.base = dreg;
383
	is.b.offset = 0;
384
      }
385
      is.adval = 1;
386
      setinsalt (aa, is);
387
      wans.answhere = aa;
388
      wans.ashwhere = a;
389
      /* ... and deliver literal base_offset */
390
      keepexp (e, aa);
391
      return wans;
392
    }				/* end add_ptr */
393
 
394
    case subptr_tag: 		/* this is nugatory - previous transforms
395
			       make it into addptr or reff */
396
    {
397
      exp sum = son (e);
398
      int   ind = reg_operand (sum, sp);
399
      instore isa;
400
      isa.adval = 1;
401
      sum = bro (sum);
402
      if (name (sum) == val_tag) {
403
	instore isa;
404
	isa.b.base = ind;
405
	isa.b.offset = -no (e);
406
	setinsalt (aa, isa);
407
      }
408
      else {
409
	if (dreg == 0)
410
	  dreg = getreg (sp.fixed);
411
	src.reg=0;
412
	src.value=ind;
413
	operate_fmt(i_subq,reg_operand(sum,guardreg(ind,sp)),src.value,dreg);
414
	isa.b.base = dreg;
415
	isa.b.offset = 0;
416
      }
417
      setinsalt (aa, isa);
418
      wans.answhere = aa;
419
      wans.ashwhere = a;
420
      keepexp (e, aa);
421
      return wans;
422
    }				/* end subptr */
423
 
424
    case reff_tag: {
425
	instore isa;
426
	bool bitfield = 0;
427
	wans = locate (son (e), sp, sh (son (e)), NO_REG);
428
	/* answer is going to be wans displaced by no(e) */
429
 
430
	if (name (sh (e)) == ptrhd) {
431
	  if (al1(sh(e))  == 1)
432
	    bitfield = 1;
433
	}
434
 
435
	switch (wans.answhere.discrim) {
436
	  case notinreg: {
437
 
438
	    isa = insalt (wans.answhere);
439
	    if (!isa.adval) {
440
	      /* wans is an actual pointer  in store, so make it into a
441
		 literal address.... */
442
	      int   reg = getreg (sp.fixed);
443
	      load_store(i_ldq,reg,isa.b);
444
	      isa.b.offset = 0;
445
	      isa.b.base = reg;
446
	      isa.adval = 1;
447
	    }
448
	      /* ... and add appropriate displacement to 
449
		 give result */
450
 
451
	      /* make sure that alignment is correct.  
452
	       64 bit data needs to be placed on 64 bit boundaries */
453
	    isa.b.offset += no (e) / 8;
454
	    setinsalt (wans.answhere, isa);
455
	    keepexp (e, wans.answhere);
456
	    break;
457
	  }
458
	  case inreg: {
459
	    /* wans is a pointer in a register */
460
	    isa.b.base = regalt (wans.answhere);
461
	    isa.adval = 1;
462
	    isa.b.offset = no (e) / 8;
463
	    setinsalt (wans.answhere, isa);
464
	    break;
465
	  }
466
	  default: {
467
	    failer ("Locate ? reg ");
468
	  }
469
	}	
470
	wans.ashwhere = a;
471
	return wans;
472
      }				/* end reff */
473
 
474
   case cont_tag: 
475
   case contvol_tag: 
476
    {
477
      exp s = son (e);
478
      ans ason;
479
      instore isa;
480
      int   reg;
481
      where fc;
482
      fc = locate (s, sp, sh (e), NO_REG);
483
      ason = fc.answhere;
484
      /* answer is going to be the contents of address represented by fc
485
       */
486
 
487
      switch (ason.discrim) {
488
       case notinreg: 
489
	{
490
	  isa = insalt (ason);
491
	  if (isa.adval) {	/* fc is a literal store address, so make
492
				   it into a direct one */
493
	    isa.adval = 0;
494
	    setinsalt (aa, isa);
495
	  }
496
	  else {		/* fc is an actual pointer in store .... 
497
				 */
498
	    reg = getreg (sp.fixed);
499
	    load_store(i_ldq,reg,isa.b);
500
	    /*load_store(i_lda,reg,isa.b);*/
501
	    /* .... so load it into reg and deliver direct base-offset
502
	       (reg,0) */
503
	    isa.b.base = reg;
504
	    isa.b.offset = 0;
505
	    setinsalt (aa, isa);
506
	    if (name (e) != contvol_tag && fc.ashwhere.ashalign != 1)
507
	      keepexp (e, aa);
508
	  }
509
	  goto breakson;
510
 
511
	}			/* end notinrg */
512
 
513
       case inreg: 
514
	/* this one is fraught - it depends on only being used in
515
	   lh-value positions from vars- take care */
516
	{	/* This is very dubious indeed */
517
	  isa.b.base = regalt (ason);
518
	  isa.b.offset = 0;
519
	  isa.adval = 1;
520
	  aa = ason;
521
	  setinsalt (aa, isa);
522
	  /* fc is in register, so deliver literal(!? ) base-offset */
523
	  goto breakson;
524
	}
525
 
526
       case infreg: 		/* ditto caveat above */
527
	{
528
	  aa = ason;
529
	  goto breakson;
530
	}
531
 
532
       default: {
533
	 failer ("Locate ? reg");
534
       }
535
      }
536
     breakson: 
537
      wans.answhere = aa;
538
      wans.ashwhere = a;
539
      return wans;
540
 
541
    }				/* end cont */
542
 
543
   case top_tag: 		/* does this ever happen ? */
544
    {
545
      setregalt (aa, 0);
546
      wans.answhere = aa;
547
      wans.ashwhere = a;
548
      return wans;
549
    }				/* end top */
550
 
551
 
552
 
553
   case field_tag: {
554
     instore isa;
555
     wans = locate (son (e), sp, sh (son (e)), NO_REG);
556
     /* answer is wans displace literally by no(e); it should always be
557
	a literal store adress */
558
 
559
     switch (wans.answhere.discrim) {
560
      case notinreg: {
561
 
562
	isa = insalt (wans.answhere);
563
	isa.b.offset += no (e) / 8;
564
	setinsalt (wans.answhere, isa);
565
	break;
566
      }
567
      default: 
568
       failer (" field should be transformed ");
569
     }
570
     wans.ashwhere = a;
571
     return wans;
572
   }				/* end field */
573
 
574
 
575
 
576
 
577
 
578
 
579
 
580
   default: 
581
    /* general catch all; evaluate e into register and deliver it as a
582
       literal store address */
583
    {
584
      int   r = reg_operand (e, sp);
585
      instore is;
586
      if (r == 0) {		/* guard possible result from proc - can
587
				   do better */
588
	r = getreg (sp.fixed);
589
	operate_fmt (i_bis,0,0,r);
590
      }
591
      is.b.base = r;
592
      is.b.offset = 0;
593
      is.adval = 1;
594
      setinsalt (aa, is);
595
      wans.answhere = aa;
596
      wans.ashwhere = a;
597
      return wans;
598
    }
599
 
600
  }
601
}
602
 
603
where locate
604
    PROTO_N ( ( e, sp, s, dreg ) )
605
    PROTO_T ( exp e X space sp X shape s X int dreg )
606
{
607
  ans ak;
608
  where w;
609
  ak = iskept (e);
610
  if (ak.discrim == inreg && (regalt (ak) == NO_REG)) {
611
    where w;
612
    w = locate1 (e, sp, s, dreg);
613
    return w;
614
  }
615
  else {			/* e has been evaluated into a register */
616
    w.answhere = ak;
617
    w.ashwhere = ashof (s);
618
  }
619
  return w;
620
}