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: locate.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.2  1995/12/18  13:11:48  wfs
67
 * Put hppatrans uder cvs control. Major Changes made since last release
68
 * include:
69
 * (i) PIC code generation.
70
 * (ii) Profiling.
71
 * (iii) Dynamic Initialization.
72
 * (iv) Debugging of Exception Handling and Diagnostics.
73
 *
74
 * Revision 5.1  1995/09/15  12:38:58  wfs
75
 * Minor changes to stop gcc compiler from complaining.
76
 *
77
 * Revision 5.0  1995/08/25  13:42:58  wfs
78
 * Preperation for August 25 Glue release
79
 *
80
 * Revision 3.4  1995/08/25  09:48:02  wfs
81
 * register synonyms changed. additional cases in "boff" to deal
82
 * with the offsets of callees
83
 *
84
 * Revision 3.4  1995/08/25  09:48:02  wfs
85
 * register synonyms changed. additional cases in "boff" to deal
86
 * with the offsets of callees
87
 *
88
 * Revision 3.1  95/04/10  16:27:08  16:27:08  wfs (William Simmonds)
89
 * Apr95 tape version.
7 7u83 90
 *
2 7u83 91
 * Revision 3.0  95/03/30  11:18:03  11:18:03  wfs (William Simmonds)
92
 * Mar95 tape version with CRCR95_178 bug fix.
7 7u83 93
 *
2 7u83 94
 * Revision 2.0  95/03/15  15:27:51  15:27:51  wfs (William Simmonds)
95
 * spec 3.1 changes implemented, tests outstanding.
7 7u83 96
 *
2 7u83 97
 * Revision 1.2  95/01/17  17:26:13  17:26:13  wfs (William Simmonds)
98
 * Changed name of an included header file
7 7u83 99
 *
2 7u83 100
 * Revision 1.1  95/01/11  13:11:08  13:11:08  wfs (William Simmonds)
101
 * Initial revision
7 7u83 102
 *
2 7u83 103
*/
104
 
105
 
106
#define HPPATRANS_CODE
107
/* locate.c
108
     discovers "where" an "exp" is;
109
     The where coding of an address tells one whether the result of
110
      evaluating an exp is in a register or directly or literally in store,
111
*/
112
 
113
#include "config.h"
114
#include "myassert.h"
115
#include "addrtypes.h"
116
#include "expmacs.h"
117
#include "tags.h"
118
#include "inst_fmt.h"
119
#include "regmacs.h"
120
#include "hppains.h"
121
#include "bitsmacs.h"
122
#include "exp.h"
123
#include "procrec.h"
124
#include "guard.h"
125
#include "eval.h"
126
#include "regexps.h"
127
#include "shapemacs.h"
128
#include "comment.h"
129
#include "getregs.h"
130
#include "move.h"
131
#include "regable.h"
132
#include "codehere.h"
133
#include "proc.h"
134
#include "frames.h"
135
 
136
#include "common_types.h"
137
 
138
#include "locate.h"
139
 
140
 
141
/* decodes x to give a baseoff suitable for xxxx_ins functions */
7 7u83 142
baseoff boff
143
(exp e)
2 7u83 144
{
145
 
146
  int n = no(e);
147
  int b = n & 0x3f;
148
  baseoff an;
149
 
150
  if (isglob(e))
151
  {
152
    /* bro() is index in main_globals */
153
    dec *gl = brog(e);
154
    long sno = gl->dec_u.dec_val.sym_number;
7 7u83 155
    an.base = - (sno + 1);
2 7u83 156
    an.offset = 0;
157
  }
7 7u83 158
  else if (name(son(e)) ==caller_name_tag)
2 7u83 159
  {
160
     int n = no(e);
161
     an.base = SP;
7 7u83 162
     an.offset = - (n>>3);
2 7u83 163
  }
164
  else if (isparam(e))
165
  {
166
     /* parameter */
167
     assert(name(son(e)) == clear_tag);
168
     if (Has_vcallees)
169
     {
170
	an.base = FP;
171
     }
172
     else
173
     {
174
	an.base = EP;
175
     }
7 7u83 176
     if (name(son(e)) ==formal_callee_tag)
2 7u83 177
     {
178
	an.offset=(no(son(e))-callees_offset)>>3;/* outermost ()'s for gcc */
179
     }
180
     else
181
     {
182
	an.offset=(-no(son(e))-params_offset)>>3;/* outermost ()'s for gcc */
183
     }
184
  }
185
  else if (b == GR17)
186
  {
187
     /* locally declared */
7 7u83 188
     an.base = EP;
189
     an.offset = ((n-b) >>4) - (locals_offset>>3);
2 7u83 190
  }
191
  else if (b == EP)
192
  {
193
    /* on stack temps (should not happen) */
194
    an.base = EP;
195
    an.offset = (n - b) >> 4;
196
  }
197
  else if (b <= 31)
198
  {
199
    /* other base reg and offset */
200
    an.base = b;
201
    an.offset = ((n - b) >> 4);
202
  }
203
#if 1
204
  /* +++ obsolete */
205
  else if (b == 32)
206
  {
207
    /* global names */
7 7u83 208
    an.base = - ((n - b) >> 6);
2 7u83 209
    an.offset = 0;
210
  }
211
  else if (b == 33)
212
  {
213
    /* local data label: LDNNNN */
214
    an.base = (n - b) >> 6;
215
    an.offset = 0;
216
  }
217
#endif
218
  else
219
  {
220
    comment3("baseoff: n=%lx, b=%d, n>>4=%ld", n, b, n >> 4);
221
    fail("not a baseoff in boff");
222
  }
223
  FULLCOMMENT2("baseoff: base=%d off=%d", an.base, an.offset);
224
  return an;
225
}
226
 
227
 
228
 /*
229
  * locate differs from locate1 only in that it looks to see e has already
230
  * been evaluated somehow
231
  */
7 7u83 232
where locate(exp, space, shape, int);
2 7u83 233
 
234
 
235
 /*
236
  * finds the address of e using shape s; sp gives available t-regs for any
237
  * inner evaluation. dreg is historical.
238
  */
7 7u83 239
where locate1
240
(exp e, space sp, shape s, int dreg)
2 7u83 241
{
242
  ash a;
243
  ans aa;
244
  where wans;
245
#if 0				/* causes core dump spec/espresso/set.c */
7 7u83 246
  FULLCOMMENT3("locate1: %s, %s, dreg=%d",(int)tag_name(name(e)), (int)sh_name(name(s)), dreg);
247
  FULLCOMMENT4("        space= (%ld,%ld) no(e) =%d no(son(e)) =%d", sp.fixed, sp.flt, no(e), no(son(e)));
2 7u83 248
#endif
7 7u83 249
 
2 7u83 250
  a = ashof(s);
251
 
252
/*
253
  while (name(e) == diag_tag || name(e) == fscope_tag || name(e) == cscope_tag)
254
  {
255
    e = son(e);
256
  }
257
*/
258
  switch (name(e))
259
  {
260
  case name_tag:
261
    {
262
      exp dc = son(e);
263
      bool var = isvar(dc);
264
 
265
      /* this a locally declared name ... */
266
      if (props(dc) & defer_bit)
267
      {
7 7u83 268
 
2 7u83 269
	/*
270
	 * ... it has been identified with a simple expression which is better
271
	 * evaluated every time
272
	 */
273
	where w;
274
 
275
	FULLCOMMENT("locate1: name_tag: defer_bit");
276
 
277
	w = locate(son(dc), sp, sh(son(dc)), dreg);
278
 
279
	if (no(e) == 0)
280
	{
281
	  aa = w.answhere;
282
	}
283
	else
284
	{
285
	  instore is;
286
 
7 7u83 287
	  switch (discrim(w.answhere))
2 7u83 288
	  {
289
	  case notinreg:
290
	    {
291
	      is = insalt(w.answhere);
292
	      is.b.offset += (no(e) / 8);
293
	      break;
294
	    }
295
	  default:
296
	    fail("name not deferable");
297
	  }
298
 
299
	  setinsalt(aa, is);
300
	}
301
      }
302
      else if (props(dc) & inreg_bits)
303
      {
304
	/* ... it has been allocated in a fixed point reg */
305
 
7 7u83 306
	FULLCOMMENT1("locate1: name_tag: fixed point reg%s",(int)(var?" var":""));
2 7u83 307
 
308
	if (var)
309
	{
310
	  setregalt(aa, no(dc));
311
	}
312
	else
313
	{
314
	  instore b;
315
 
316
	  b.b.base = no(dc);
317
	  b.b.offset = 0;
318
	  b.adval = 1;
319
	  setinsalt(aa, b);
320
	}
321
      }
322
      else if (props(dc) & infreg_bits)
323
      {
324
	/* ... it has been allocated in a floating point reg */
325
 
326
	freg fr;
327
 
328
	FULLCOMMENT("locate1: name_tag: fixed point reg");
329
 
330
	fr.fr = no(dc);
7 7u83 331
	fr.dble = (a.ashsize==64 ? 1 : 0);
2 7u83 332
	setfregalt(aa, fr);
333
      }
334
      else
335
      {
336
	/* ... it is in memory */
337
	instore is;
338
 
7 7u83 339
	if (var || (name(sh(e)) == prokhd &&
340
		   (son(dc) == nilexp || IS_A_PROC(son(dc)))))
2 7u83 341
	{
342
	  is.adval = 1;
343
	}
344
	else
345
	{
346
	  is.adval = 0;
347
	}
348
	is.b = boff(dc);
349
#if USE_BITAD
7 7u83 350
	if (a.ashalign == 1 && (var || name(sh(e))!= ptrhd))
2 7u83 351
	  /* some bit field */
352
	{
353
	  is.b.offset = (is.b.offset << 3) + no(e);
354
	  setbitadalt(aa, is);
355
	}
356
	else
357
#endif
358
	{
359
	  is.b.offset += (no(e) / 8);
360
	  setinsalt(aa, is);
361
	}
362
      }
363
      wans.answhere = aa;
364
      wans.ashwhere = a;
365
      return wans;
366
    }
367
 
368
  case addptr_tag:
369
    {
370
      exp sum = son(e);
371
      where wsum;
372
      int addend;
373
      space nsp;
374
      int reg;
375
      int ind = R_NO_REG;
376
      instore is;
377
      ans asum;
378
      int shift;
379
 
380
      wsum = locate(sum, sp, sh(sum), 0);
381
      asum = wsum.answhere;
382
 
383
      /*
384
       * answer is going to be wsum displaced by integer result of evaluating
385
       * bro(sum)
386
       */
387
 
7 7u83 388
      switch (discrim(asum))
2 7u83 389
      {
390
      case notinreg:
391
	{
392
	  is = insalt(asum);
393
	  if (is.adval)
394
	  {
395
	    /* wsum is a literal address in store ... */
396
	    baseoff b;
397
 
398
	    b = is.b;
399
	    if (!IS_FIXREG(b.base))
400
	    {
401
	      /* ... it is not a base-offset , so make it one */
402
 
403
	      reg = getreg(sp.fixed);
404
	      set_ins("",b, reg);
405
	      keepreg(sum, reg);
406
	      b.base = reg;
407
	      b.offset = 0;
408
 
409
	    }
410
 
411
	    nsp = guardreg(b.base, sp);
412
 
413
	    shift=no(bro(son(bro(sum))));
7 7u83 414
	    if (name(bro(sum)) ==offset_mult_tag && name(bro(son(bro(sum)))) ==val_tag && (shift==0 || shift==2 || shift==4))
2 7u83 415
	    {
416
	       addend=reg_operand(son(bro(sum)),nsp);
417
	       if (dreg == 0)
418
		  dreg = getreg(nsp.fixed);
7 7u83 419
	       rrr_ins(shift==0 ? i_add :(shift==2 ? i_sh1add : i_sh2add),                           c_,addend,b.base,dreg);
2 7u83 420
	    }
421
	    else
422
	    {
423
	       addend = reg_operand(bro(sum), nsp);
424
	       /* evaluate the displacement ... */
425
	       if (dreg == 0)
426
		  dreg = getreg(nsp.fixed);
427
	       rrr_ins(i_add,c_,b.base,addend,dreg);
428
	    }
429
 
430
	    clear_reg(dreg);
431
 
432
	    /* ... add it to the base register into new reg */
433
	    b.base = dreg;
434
	    is.b = b;
435
	    setinsalt(aa, is);
436
	    wans.answhere = aa;
437
	    wans.ashwhere = a;
438
 
439
	    /* ...and use it as base a literal base-offset result */
440
	    keepexp(e, aa);
441
	    return wans;
442
	  }
443
	  else
444
	  {
445
	     /* wsum represents an actual pointer in store... */
446
	     /* ... so load it into a good register */
447
	     ind = getreg(sp.fixed);
448
	     ld_ins(i_lw,1,is.b,ind);
449
	  }
450
	  break;
451
	}			/* end notinreg */
452
 
453
      case inreg:
454
	{
455
	  /* wsum is already in reg */
456
	  ind = regalt(asum);
457
	  break;
458
	}
459
 
460
      default:
461
	{
462
	  fail("locate ? reg");
463
	}
464
      }				/* end case */
465
 
466
      /* register ind contains the evaluation of 1st operand of addptr */
467
      nsp = guardreg(ind, sp);
468
      /* evaluate displacement, add it to ind in new reg */
469
      if (name(bro(sum)) == env_offset_tag ||
470
	  name(bro(sum)) == general_env_offset_tag)
471
      {
472
	  is.b.base = ind;
473
	  is.b.offset = frame_offset(son(bro(sum)));
7 7u83 474
      }
2 7u83 475
      else
476
      {
477
	 shift=no(bro(son(bro(sum))));
7 7u83 478
	 if (name(bro(sum)) ==offset_mult_tag && name(bro(son(bro(sum)))) ==val_tag && (shift==0 || shift==2 || shift==4))
2 7u83 479
	 {
480
	    addend=reg_operand(son(bro(sum)),nsp);
481
	    if (dreg == 0)
482
	       dreg = getreg(nsp.fixed);
7 7u83 483
	    rrr_ins(shift==0 ? i_add :(shift==2 ? i_sh1add : i_sh2add),                           c_,addend,ind,dreg);
2 7u83 484
	 }
485
	 else
486
	 {
487
	    addend = reg_operand(bro(sum), nsp);
488
 
489
	    if (dreg == 0)
490
	       dreg = getreg(nsp.fixed);
491
	    rrr_ins(i_add,c_,ind,addend,dreg);
492
	 }
493
	 is.b.base = dreg;
494
	 is.b.offset = 0;
495
      }
496
      is.adval = 1;
497
      setinsalt(aa, is);
498
      wans.answhere = aa;
499
      wans.ashwhere = a;
500
      /* ... and deliver literal base_offset */
501
      keepexp(e, aa);
502
      return wans;
503
    }				/* end add_ptr */
504
 
505
  case subptr_tag:		/* this is nugatory - previous transforms make
506
				 * it into addptr or reff */
507
    {
508
      exp sum = son(e);
509
      int ind = reg_operand(sum, sp);
510
      instore isa;
511
 
512
      isa.adval = 1;
513
      sum = bro(sum);
514
      if (name(sum) == val_tag)
515
      {
516
	instore isa;
517
 
518
	isa.b.base = ind;
519
	isa.b.offset = -no(e);
520
	setinsalt(aa, isa);
521
      }
522
      else
523
      {
524
	if (dreg == 0)
525
	   dreg = getreg(sp.fixed);
526
	rrr_ins(i_sub,c_,ind,reg_operand(sum,guardreg(ind,sp)),dreg);
527
	isa.b.base = dreg;
528
	isa.b.offset = 0;
529
      }
530
      setinsalt(aa, isa);
531
      wans.answhere = aa;
532
      wans.ashwhere = a;
533
      keepexp(e, aa);
534
      return wans;
535
    }				/* end subptr */
536
 
537
  case reff_tag:
538
    {
539
      instore isa;
540
#if USE_BITAD
541
      bool bitfield = 0;
542
#endif
543
 
544
      /* answer is going to be wans displaced by no(e) */
545
      wans = locate(son(e), sp, sh(son(e)), 0);
546
 
547
#if USE_BITAD
548
      bitfield = ((name(sh(e)) == ptrhd) && (al1(sh(e)) == 1));
549
#endif
7 7u83 550
      switch (discrim(wans.answhere))
2 7u83 551
      {
552
      case notinreg:
553
	{
554
	  isa = insalt(wans.answhere);
555
	  if (!isa.adval)
556
	  {
557
 
558
	    /*
559
	     * wans is an actual pointer  in store, so make it into a literal
560
	     * address....
561
	     */
562
	    int reg = getreg(sp.fixed);
563
 
564
	    ld_ins(i_lw,0,isa.b,reg);
565
	    isa.b.offset = 0;
566
	    isa.b.base = reg;
567
	    isa.adval = 1;
568
	  }
569
 
570
	  /*  ... and add appropriate displacement to give result  */
571
 
572
#if USE_BITAD
573
	  if (bitfield)
574
	  {
575
	    isa.b.offset <<= 3;
576
	    isa.b.offset += no(e);
577
	    setbitadalt(wans.answhere, isa);
578
	  }
579
	  else
580
#endif
581
	  {
582
	    isa.b.offset += no(e) / 8;
583
	    setinsalt(wans.answhere, isa);
584
	    keepexp(e, wans.answhere);
585
	  }
7 7u83 586
       	  break;
2 7u83 587
	}
588
#if USE_BITAD
589
      case bitad:
590
	{
591
	  isa = bitadalt(wans.answhere);
592
	  if (!isa.adval)
593
	  {
594
	    fail("no var bit selection");
595
	  }
596
	  /* wans is a literal bit address */
597
	  isa.b.offset += no(e);
598
	  setbitadalt(wans.answhere, isa);
599
	  break;
600
	}
601
#endif
602
      case inreg:
603
	{
604
	  /* wans is a pointer in a register */
605
	  isa.b.base = regalt(wans.answhere);
606
	  isa.adval = 1;
607
#if USE_BITAD
608
	  if (bitfield)
609
	  {
610
	    isa.b.offset = no(e);
611
	    setbitadalt(wans.answhere, isa);
612
	  }
613
	  else
614
#endif
615
	  {
616
	    isa.b.offset = BITS2BYTES(no(e));
617
	    setinsalt(wans.answhere, isa);
618
	  }
619
	  break;
620
	}
621
      default:
622
	{
623
	  fail("locate ? reg ");
624
	}
625
      }
626
      wans.ashwhere = a;
627
      return wans;
628
    }				/* end reff */
629
 
630
  case cont_tag:
631
  case contvol_tag:
632
    {
633
      exp s = son(e);
634
      ans ason;
635
      instore isa;
636
      int reg;
637
      where fc;
638
 
639
      fc = locate(s, sp, sh(e), 0);
640
      ason = fc.answhere;
641
 
642
      /*
643
       * answer is going to be the contents of address represented by fc
644
       */
645
 
7 7u83 646
      FULLCOMMENT1("locate1: cont[vol]_tag: %s",(int)ANSDISCRIM_NAME(discrim(ason)));
647
 
648
      switch (discrim(ason))
2 7u83 649
      {
650
      case notinreg:
651
	{
652
	  isa = insalt(ason);
653
	  if (isa.adval)
654
	  {
655
	    /* literal store address, so make it into a direct one */
656
	    FULLCOMMENT("locate1: cont[vol]_tag: literal store address");
657
	    isa.adval = 0;
658
	    setinsalt(aa, isa);
659
	  }
660
	  else
661
	  {
662
 
663
	    /*
664
	     * actual pointer in store so load it into reg and deliver direct
665
	     * base-offset (reg,0)
666
	     */
667
	    FULLCOMMENT("locate1: cont[vol]_tag: ptr in store");
668
	    reg = getreg(sp.fixed);
669
	    ld_ins(i_lw,1,isa.b,reg);
670
	    isa.b.base = reg;
671
	    isa.b.offset = 0;
672
	    setinsalt(aa, isa);
7 7u83 673
	    if (name(e)!= contvol_tag && fc.ashwhere.ashalign != 1)
2 7u83 674
	      keepexp(e, aa);
675
	  }
676
#if USE_BITAD
677
	  if (fc.ashwhere.ashalign == 1)	/* ... adjust for bit contents */
678
	  {
679
	    isa.b.offset <<= 3;
680
	    setbitadalt(aa, isa);
681
	  }
682
#endif
683
	  goto breakson;
684
 
685
	}			/* end notinrg */
686
 
687
      case inreg:
688
 
689
	/*
690
	 * this one is fraught - it depends on only being used in lh-value
691
	 * positions from vars - take care
692
	 */
693
	{
694
	  isa.b.base = regalt(ason);
695
	  isa.b.offset = 0;
696
	  isa.adval = 1;
697
#if USE_BITAD
698
	  if (a.ashalign == 1)
699
	  {
700
	    setbitadalt(aa, isa);
701
	  }
702
	  else
703
#endif
704
	  {
705
	    setinsalt(aa, isa);
706
	  }
707
	  /* fc is in register, so deliver literal(!? ) base-offset */
708
	  goto breakson;
709
	}
710
 
711
      case infreg:		/* ditto caveat above */
712
	{
713
	  aa = ason;
714
	  goto breakson;
715
	}
716
 
717
#if USE_BITAD
718
      case bitad:
719
	{
720
	  isa = bitadalt(ason);
721
	  if (!isa.adval)
722
	  {
723
	    fail("no ptr bits");
724
	  }
725
	  /* fc is a literal address of bits, so make it direct */
726
	  isa.adval = 0;
727
	  setbitadalt(aa, isa);
728
	  goto breakson;
729
	}
730
#endif
731
      default:
732
	{
733
	  fail("locate ? reg");
734
	}
735
      }
736
  breakson:
737
      wans.answhere = aa;
738
      wans.ashwhere = a;
739
      return wans;
740
 
741
    }				/* end cont */
742
 
743
  case top_tag:		/* does this ever happen ? */
744
    {
745
      setregalt(aa, 0);
746
      wans.answhere = aa;
747
      wans.ashwhere = a;
748
      return wans;
749
    }				/* end top */
750
 
751
  case field_tag:
752
    {
753
      instore isa;
754
 
755
      wans = locate(son(e), sp, sh(son(e)), 0);
756
 
757
      /*
758
       * answer is wans displace literally by no(e); it should always be a
759
       * literal store address
760
       */
761
 
7 7u83 762
      switch (discrim(wans.answhere))
2 7u83 763
      {
764
      case notinreg:
765
	{
766
	  isa = insalt(wans.answhere);
767
#if USE_BITAD
768
	  if (a.ashalign == 1)
769
	  {
770
	    isa.b.offset += no(e);
771
	    setbitadalt(wans.answhere, isa);
772
	  }
773
	  else
774
#endif
775
	  {
776
	    isa.b.offset += no(e) / 8;
777
	    setinsalt(wans.answhere, isa);
778
	  }
779
	  break;
780
	}
781
#if USE_BITAD
782
      case bitad:
783
	{
784
	  wans.answhere.val.instoreans.b.offset += no(e);
785
	  FULLCOMMENT1("locate field_tag: adjusting bitad offset to %d", wans.answhere.val.instoreans.b.offset);
786
	  break;
787
	}
788
#endif
789
      default:
790
	fail("field should be transformed");
791
      }
792
      wans.ashwhere = a;
793
      return wans;
794
    }				/* end field */
795
  default:
796
    {
797
 
798
      /*
799
       * general catch all; evaluate e into register and deliver it as a
800
       * literal store address
801
       */
802
      int r = reg_operand(e, sp);
803
      instore is;
804
 
805
      if (r == RET0)		/* guard possible result from proc - can do
806
				 * better */
807
      {
808
	FULLCOMMENT("guarding possible result");	/* +++ remove */
809
	r = getreg(sp.fixed);
810
	if (r != RET0)
811
	  rr_ins(i_copy,RET0,r);
812
      }
813
      is.b.base = r;
814
      is.b.offset = 0;
815
      is.adval = 1;
816
      setinsalt(aa, is);
817
      wans.answhere = aa;
818
      wans.ashwhere = a;
819
      return wans;
820
    }
821
  }
822
}
823
 
7 7u83 824
where locate
825
(exp e, space sp, shape s, int dreg)
2 7u83 826
{
827
  ans ak;
828
  where w;
829
 
830
  ak = iskept(e);
7 7u83 831
  if (discrim(ak) == inreg && (regalt(ak) == 0))
2 7u83 832
  {
833
    w = locate1(e, sp, s, dreg);
834
  }
835
  else
836
  {
837
    FULLCOMMENT("locate: iskept() found value");
838
    w.answhere = ak;
839
    w.ashwhere = ashof(s);
840
  }
841
  return w;
842
}
843
 
844
 
845
 
846
 
847
 
848
 
849
 
850
 
851
 
852
 
853
 
854
 
855
 
856
 
857