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

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-amd64/src/installers/power/common/locate.c – Rev 6

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
/*
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:48:53 $
91
$Revision: 1.2 $
92
$Log: locate.c,v $
93
 * Revision 1.2  1998/02/04  15:48:53  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.2  1996/10/04  16:01:52  pwe
100
 * add banners and mod for PWE ownership
101
 *
102
**********************************************************************/
103
 
104
 
105
/* locate.c
106
     discovers "where" an "exp" is;
107
     The where coding of an address tells one whether the result of
108
      evaluating an exp is in a register or directly or literally in store,
109
*/
110
#include "config.h"
111
#include "memtdf.h"
112
#include "codegen.h"
113
#include "geninst.h"
114
 
115
#include "proc.h"
116
#include "myassert.h"
117
#include "comment.h"
118
#include "stack.h"
119
#include "locate.h"
120
#include "frames.h"
121
/******************************************************************************
122
For non globals, boff encodes things in the following way.
6 7u83 123
The number of bytes gives a displacement from different positions on
2 7u83 124
the stack depending on whether it is relative to R_SP R_FP or R_TP
125
 
6 7u83 126
The stack below gives the worst case of the stack i.e a general_proc with
2 7u83 127
alloca
128
  |           |
129
  |           | #
130
  |           | |  x relative to R_TP i.e caller parameters
131
  |-----------| |                     in input caller parameter area
132
  | STACK     | |
133
  | LINK      | | STACK_ARG_AREA
134
  | AREA      | |
135
  |-----------|<--------R_TP
136
  | Input     |
137
  | Callees   |
138
  |           |
139
  |           |
140
  |           |
141
  |           |
142
  |-----------|<--------R_FP
143
  |           | |
144
  |           | |
145
  |           | |                          #
146
  |           | |                          | displacement x relative to R_FP
147
  |           | |                          | coded like this in regalloc
148
  |           | | p_frame_size          #
149
  |           | |                          |
150
  |           | |                          | p_locals_offset
151
  |           | |                          |
152
  |           | |                          |
153
  |           | # <--initial R_SP was here
154
  |-----------|
155
  |           | #
156
  |           | | x relative to R_SP i.e output caller parameter construction
157
  |-----------| |
158
  | STACK     | |
159
  | LINK      | | STACK_ARG_AREA
160
  | AREA      | |
161
  |-----------|<--------R_SP
162
******************************************************************************/
163
 
164
/* decodes e to give a baseoff suitable for xxx_ins functions */
6 7u83 165
baseoff boff(exp e)
2 7u83 166
{
167
  baseoff an;
168
 
169
  if (isglob(e))
170
  {
171
    dec *gl = brog(e);
172
    long sno = gl->dec_u.dec_val.sym_number;
173
 
174
    /* an.base is negated global sym number, positive used for base reg number */
6 7u83 175
    an.base = - (sno + 1);
2 7u83 176
    an.offset = 0;
177
  }
178
  else
179
  {
180
    return boff_location(no(e));
181
  }
182
  return an;
183
}
6 7u83 184
baseoff boff_location(int n)
185
{
2 7u83 186
  baseoff an;
187
  int br = n & 0x3f;		/* base reg in bottom 6 bits */
188
  long off = (n>>6);		/* offset in bytes from br in rest */
6 7u83 189
 
2 7u83 190
  ASSERT((n<0)==(off<0));	/* any sign propagated */
6 7u83 191
  if (br<0)
2 7u83 192
    br = -br;
6 7u83 193
 
2 7u83 194
  /* There are three possiblilities for br */
195
  /* i.e R_TP R_FP R_SP */
196
  /* R_TP|
197
     -----
198
     if something is relative to R_TP it is a caller of the previous proc
199
     since R_TP is the top of the frame
200
     R_FP|
201
     -----
202
     This is all locals to the current procedure
203
     R_SP|
204
     -----
205
     This is used for constructing argument lists for calling parameters
6 7u83 206
 
2 7u83 207
     It is possible that all three are the same
208
     i.e they are all calculated from the stack pointer.
209
     However in a general_proc
210
     things get nasty and all three will point to different places
211
     */
212
  if (br == R_SP)
213
  {
214
    an.base = R_SP;
215
    an.offset = off;
216
    ASSERT(off >= 0);
217
  }
6 7u83 218
  else if (br == R_FP)
2 7u83 219
  {
6 7u83 220
    if (p_has_fp)
2 7u83 221
    {
222
      an.base = R_FP;
223
      an.offset = p_locals_offset + off - p_frame_size;
224
    }
225
    else
226
    {
227
      an.base = R_SP;
228
      an.offset = p_locals_offset + off;
229
    }
230
  }
6 7u83 231
  else if (br == R_TP)
2 7u83 232
  {
233
    if (p_has_tp)
234
    {
235
      an.base = R_TP;
236
      an.offset = off;
237
    }
6 7u83 238
    else if (p_has_fp)
2 7u83 239
    {
240
      an.base = R_FP;
241
      an.offset = off;
242
    }
6 7u83 243
    else
2 7u83 244
    {
245
      an.base = R_SP;
246
      an.offset = off + p_frame_size;
247
    }
248
  }
249
  else
250
  {
251
    fail("Error:boff_location: Unknown base");
252
  }
253
  return an;
254
}
6 7u83 255
int ENCODE_FOR_BOFF(int off, int type)
2 7u83 256
{
6 7u83 257
 
2 7u83 258
  /* type is either */
259
  /* INPUT_CALLER_PARAMETER, INPUT_CALLEE_PARAMETER, OUTPUT_CALLER_PARAMETER */
260
  /* offset shoulb be in bytes */
261
  int encode_offset;
262
  int encode_base;
6 7u83 263
 
264
  switch (type)
2 7u83 265
  {
266
   case INPUT_CALLER_PARAMETER:
267
    {
268
      encode_base = R_TP;
269
      encode_offset = off + STACK_ARG_AREA;
270
      break;
271
    }
272
   case INPUT_CALLEE_PARAMETER:
273
    {
274
      encode_base = R_FP;
275
      encode_offset = p_frame_size - p_locals_offset + EXTRA_CALLEE_BYTES + off;
276
      break;
277
    }
278
   case OUTPUT_CALLER_PARAMETER:
279
    {
280
      encode_base = R_SP;
281
      encode_offset = STACK_ARG_AREA + off;
282
      break;
283
    }
284
   default:
285
    fail("Unknown encodeing for ENCODE_FOR_BOFF");
286
  }
6 7u83 287
  return(encode_offset<<6) + encode_base;
2 7u83 288
}
289
 
290
 
6 7u83 291
 
2 7u83 292
/* mutual recursion between locate1() and locate() */
6 7u83 293
where locate(exp, space, shape, int);
2 7u83 294
 
295
 
296
 /*
297
  * finds the address of e using shape s; sp gives available t-regs for any
298
  * inner evaluation. dreg is historical.
299
  */
6 7u83 300
static where locate1(exp e, space sp, shape s, int dreg)
2 7u83 301
{
302
  ash a;
303
  ans aa;
304
  where wans;
6 7u83 305
 
306
  FULLCOMMENT3("locate1: name(e) =%d, name(s) =%d, dreg=%d", name(e), name(s), dreg);
307
 
2 7u83 308
  a = ashof(s);
6 7u83 309
 
2 7u83 310
  switch (name(e))
311
  {
312
    /***********************************************/
313
   case name_tag:
6 7u83 314
    {
2 7u83 315
      /* NAME_TAG */
316
      exp dc = son(e);
317
      bool var = isvar(dc);
318
 
6 7u83 319
      FULLCOMMENT2("locate1 name_tag: name(dc) =%d, var=%d", name(dc), var);
2 7u83 320
 
321
      if (props(dc) & defer_bit)
322
      {
323
	/*
324
	 * ... it has been identified with a simple expression which is
325
	 * better evaluated every time
326
	 */
327
	where w;
6 7u83 328
 
2 7u83 329
	w = locate(son(dc), sp, sh(son(dc)), dreg);
6 7u83 330
 
2 7u83 331
	if (no(e) == 0)
332
	{
333
	  aa = w.answhere;
334
	}
335
	else
336
	{
337
	  instore is;
6 7u83 338
 
2 7u83 339
	  switch (w.answhere.discrim)
340
	  {
341
	   case notinreg:
342
	    {
343
	      is = insalt(w.answhere);
344
	      is.b.offset += (no(e) / 8);
345
	      break;
346
	    }
347
	   default:
348
	    fail("name not deferable");
349
	  }
6 7u83 350
 
2 7u83 351
	  setinsalt(aa, is);
352
	}
353
      }
354
      else if (props(dc) & inreg_bits)
355
      {
356
	/* ... it has been allocated in a fixed point reg */
357
	if (var)
358
	{
359
	  setregalt(aa, no(dc));
360
	}
361
	else
362
	{
363
	  instore b;
6 7u83 364
 
2 7u83 365
	  b.b.base = no(dc);
366
	  b.b.offset = 0;
367
	  b.adval = 1;
368
	  setinsalt(aa, b);
369
	}
370
      }
371
      else if (props(dc) & infreg_bits)
372
      {
373
	/* ... it has been allocated in a floating point reg */
374
	freg fr;
6 7u83 375
 
2 7u83 376
	fr.fr = no(dc);
6 7u83 377
	fr.dble = (a.ashsize == 64)? 1 : 0;
2 7u83 378
	setfregalt(aa, fr);
379
      }
380
      else
381
      {
382
	/* ... it is in memory */
383
	instore is;
6 7u83 384
 
2 7u83 385
	if (var|| (name(sh(e)) == prokhd &&
6 7u83 386
		     (son(dc) == nilexp || IS_A_PROC(son(dc)))))
2 7u83 387
	{
388
	  is.adval = 1;
389
	  /* If it is a var tag you can get address of it */
390
	}
391
	else
392
	{
393
	  is.adval = 0;
394
	}
395
	is.b = boff(dc);
6 7u83 396
 
2 7u83 397
	is.b.offset += (no(e) / 8);
6 7u83 398
 
2 7u83 399
#if 1
6 7u83 400
	if (var && name(sh(e))!= prokhd && !IS_FIXREG(is.b.base) && is.b.offset == 0)
2 7u83 401
	{
402
	  /*
403
	   * A global which has to be accessed via TOC.
404
	   * We load it explicitly into reg here so we can
405
	   * use the reg contents tracking mechanism for
406
	   * addresses found in the TOC.
407
	   * If we did not do this, we would still generate correct code,
408
	   * but needlessly reload from TOC.
409
	   * +++ offset != 0 -> keepglob for 0 offset & keepreg for offset
410
	   */
411
	  if (dreg == 0)
412
	    dreg = getreg(sp.fixed);
6 7u83 413
 
2 7u83 414
	  set_ins(is.b, dreg);
415
	  keepreg(e, dreg);
416
	  FULLCOMMENT3("locate1 name_tag: keepreg glob adval=%d bo={%d,%d}", is.adval, is.b.base, is.b.offset);
417
	  is.b.base = dreg;
418
	  is.b.offset = 0;
419
	}
420
#endif
421
	setinsalt(aa, is);
6 7u83 422
 
2 7u83 423
      }
6 7u83 424
 
2 7u83 425
      wans.answhere = aa;
426
      wans.ashwhere = a;
427
      return wans;
428
    }
429
    /***********************************************/
430
  case addptr_tag:
431
    {
432
      exp sum = son(e);
433
      where wsum;
434
      int addend;
435
      space nsp;
436
      int reg;
437
      int ind = R_NO_REG;
438
      instore is;
439
      ans asum;
440
 
441
      wsum = locate(sum, sp, sh(sum), 0);
442
      asum = wsum.answhere;
443
 
444
      /*
445
       * answer is going to be wsum displaced by integer result of evaluating
446
       * bro(sum)
447
       */
448
 
449
      switch (asum.discrim)
450
      {
451
      case notinreg:
452
	{
453
	  is = insalt(asum);
454
	  if (is.adval)
455
	  {
456
	    /* wsum is a literal address in store ... */
457
	    baseoff b;
458
 
459
	    b = is.b;
460
	    if (!IS_FIXREG(b.base))
461
	    {
462
	      /* ... it is not a base-offset, so make it one */
463
	      reg = getreg(sp.fixed);
464
	      set_ins(b, reg);
465
	      keepreg(sum, reg);
466
	      b.base = reg;
467
	      b.offset = 0;
468
	    }
469
	    nsp = guardreg(b.base, sp);
470
 
471
	    addend = reg_operand(bro(sum), nsp);
472
 
473
	    /* evaluate the displacement ... */
474
	    if (dreg == 0)
475
	      dreg = getreg(nsp.fixed);
476
	    rrr_ins(i_a, b.base, addend, dreg);
477
 
478
	    /* ... add it to the base register into new reg */
479
	    b.base = dreg;
480
	    is.b = b;
481
	    setinsalt(aa, is);
482
	    wans.answhere = aa;
483
	    wans.ashwhere = a;
484
 
485
	    /* ...and use it as base a literal base-offset result */
486
	    keepexp(e, aa);
487
	    return wans;
488
	  }
489
	  else
490
	  {
491
	    /* wsum represents an actual pointer in store... */
492
	    /* ... so load it into a good register */
493
	    ind = getreg(sp.fixed);
494
	    ld_ins(i_l, is.b, ind);
495
	  }
496
	  break;
497
	}			/* end notinreg */
498
 
499
      case inreg:
500
	{
501
	  /* wsum is already in reg */
502
	  ind = regalt(asum);
503
	  break;
504
	}
505
 
506
      default:
507
	{
508
	  fail("locate ? reg");
509
	}
510
      }				/* end case */
511
 
512
      /* register ind contains the evaluation of 1st operand of addptr */
513
      nsp = guardreg(ind, sp);
514
 
6 7u83 515
      if (name(bro(sum)) == env_offset_tag || name(bro(sum)) ==general_env_offset_tag)
2 7u83 516
      {
517
	is.b.base = ind;
518
	is.b.offset = frame_offset(son(bro(sum)));
519
      }
520
      else
521
      {
522
	addend = reg_operand(bro(sum), nsp);
523
 
524
	/* evaluate displacement, add it to ind in new reg */
525
	if (dreg == 0)
526
	  dreg = getreg(nsp.fixed);
527
	rrr_ins(i_a, ind, addend, dreg);
528
 
529
	is.b.base = dreg;
530
	is.b.offset = 0;
531
      }
532
 
533
      is.adval = 1;
534
      setinsalt(aa, is);
535
 
536
      wans.answhere = aa;
537
      wans.ashwhere = a;
538
      /* ... and deliver literal base_offset */
539
      keepexp(e, aa);
540
      return wans;
541
    }				/* end add_ptr */
542
 
543
  case subptr_tag:		/* this is nugatory - previous transforms make
544
				 * it into addptr or reff */
545
    {
546
      exp sum = son(e);
547
      int ind = reg_operand(sum, sp);
548
      instore isa;
549
 
550
      isa.adval = 1;
551
      sum = bro(sum);
552
      if (name(sum) == val_tag)
553
      {
554
	instore isa;
555
 
556
	isa.b.base = ind;
557
	isa.b.offset = -no(e);
558
	setinsalt(aa, isa);
559
      }
560
      else
561
      {
562
	if (dreg == 0)
563
	  dreg = getreg(sp.fixed);
564
	rrr_ins(i_s, ind, reg_operand(sum, guardreg(ind, sp)), dreg);
565
	isa.b.base = dreg;
566
	isa.b.offset = 0;
567
      }
568
      setinsalt(aa, isa);
569
      wans.answhere = aa;
570
      wans.ashwhere = a;
571
      keepexp(e, aa);
572
      return wans;
573
    }				/* end subptr */
574
 
575
  case reff_tag:
576
    {
577
      instore isa;
578
      bool bitfield;
579
 
580
      /* answer is going to be wans displaced by no(e) */
581
 
582
      wans = locate(son(e), sp, sh(son(e)), 0);
583
 
584
      bitfield = ((name(sh(e)) == ptrhd) && (al1(sh(e)) == 1));
585
 
586
      switch (wans.answhere.discrim)
587
      {
588
      case notinreg:
589
	{
590
	  isa = insalt(wans.answhere);
591
	  if (!isa.adval)
592
	  {
593
 
594
	    /*
595
	     * wans is an actual pointer  in store, so make it into a literal
596
	     * address....
597
	     */
598
	    int reg = getreg(sp.fixed);
599
 
600
	    ld_ins(i_l, isa.b, reg);
601
	    isa.b.offset = 0;
602
	    isa.b.base = reg;
603
	    isa.adval = 1;
604
	  }
605
 
606
	  /*
607
	   * ... and add appropriate displacement to give result
608
	   */
609
 
610
	  isa.b.offset += no(e) / 8;
611
	  setinsalt(wans.answhere, isa);
612
	  keepexp(e, wans.answhere);
613
	  break;
614
	}
615
      case inreg:
616
	{
617
	  /* wans is a pointer in a register */
618
	  isa.b.base = regalt(wans.answhere);
619
	  isa.adval = 1;
620
 
621
	  isa.b.offset = no(e) / 8;
622
	  setinsalt(wans.answhere, isa);
623
	  break;
624
	}
625
      default:
626
	{
627
	  fail("locate ? reg ");
628
	}
629
      }
630
      wans.ashwhere = a;
631
      return wans;
632
    }				/* end reff */
6 7u83 633
 
2 7u83 634
   case cont_tag:
635
   case contvol_tag:
636
    {
637
      exp p = son(e);
638
      ans ason;
639
      instore isa;
640
      int reg;
641
      where fc;
642
 
6 7u83 643
      fc = locate(p, sp, sh(e), 0);
2 7u83 644
      ason = fc.answhere;
645
 
646
 
647
      /*
648
       * answer is going to be the contents of address represented by fc
649
       */
650
 
651
      switch (ason.discrim)
652
      {
653
       case notinreg:
654
	{
655
	  isa = insalt(ason);
656
	  FULLCOMMENT3("locate1 cont_tag: adval=%d bo={%d,%d}", isa.adval, isa.b.base, isa.b.offset);
657
	  if (isa.adval)
658
	  {
659
	    /* literal store address, so make it into a direct one */
660
	    isa.adval = 0;
661
	    setinsalt(aa, isa);
662
	  }
663
	  else
664
	  {
665
	    /*
666
	     * actual pointer in store
667
	     * so load it into reg and deliver direct base-offset (reg,0)
668
	     */
669
	    reg = getreg(sp.fixed);
670
	    ld_ins(i_l, isa.b, reg);
671
	    isa.b.base = reg;
672
	    isa.b.offset = 0;
673
	    setinsalt(aa, isa);
6 7u83 674
	    if (name(e)!= contvol_tag && fc.ashwhere.ashalign != 1)
2 7u83 675
	      keepexp(e, aa);
676
	  }
677
	  goto breakson;
678
 
679
	}			/* end notinrg */
680
 
681
      case inreg:
682
 
683
	/*
684
	 * this one is fraught
685
	 * - it depends on only being used in lh-value positions from vars
686
	 * - take care
687
	 */
688
	{
689
	  isa.b.base = regalt(ason);
690
	  isa.b.offset = 0;
691
	  isa.adval = 1;
692
	  setinsalt(aa, isa);
693
	  /* fc is in register, so deliver literal(!? ) base-offset */
694
	  goto breakson;
695
	}
696
 
697
      case infreg:		/* ditto caveat above */
698
	{
699
	  aa = ason;
700
	  goto breakson;
701
	}
702
      default:
703
	{
704
	  fail("locate ? reg");
705
	}
706
      }
707
  breakson:
708
      wans.answhere = aa;
709
      wans.ashwhere = a;
710
      return wans;
711
 
712
    }				/* end cont */
713
 
714
  case top_tag:		/* does this ever happen ? */
715
    {
716
      setregalt(aa, 0);
717
      wans.answhere = aa;
718
      wans.ashwhere = a;
719
      return wans;
720
    }				/* end top */
721
 
722
  case field_tag:
723
    {
724
      instore isa;
725
 
726
      wans = locate(son(e), sp, sh(son(e)), 0);
727
 
728
      /*
729
       * answer is wans displace literally by no(e);
730
       * it should always be a literal store address
731
       */
732
 
733
      switch (wans.answhere.discrim)
734
      {
735
      case notinreg:
736
	{
737
	  isa = insalt(wans.answhere);
738
	  isa.b.offset += no(e) / 8;
739
	  setinsalt(wans.answhere, isa);
740
	  FULLCOMMENT1("locate field_tag: adjusting byte offset to %d", isa.b.offset);
741
	  break;
742
	}
743
       default:
744
	fail("field should be transformed");
745
      }
746
      wans.ashwhere = a;
747
      return wans;
748
    }				/* end field */
749
 
750
  default:
751
    {
752
      /*
6 7u83 753
       * general catch all;
2 7u83 754
       * evaluate e into register and deliver it as a literal
755
       * store address
756
       */
757
      int r = reg_operand(e, sp);
758
      instore is;
759
 
760
      if (r == R_RESULT)
761
      {
762
	/* guard possible result from proc - can do better +++ */
763
	FULLCOMMENT("guarding possible result");
764
	r = getreg(sp.fixed);
765
	if (r != R_RESULT)
766
	{
767
	  mov_rr_ins(R_RESULT, r);comment("move R_RESULT to reg");
768
	}
769
      }
770
      is.b.base = r;
771
      is.b.offset = 0;
772
      is.adval = 1;
773
      setinsalt(aa, is);
774
      wans.answhere = aa;
775
      wans.ashwhere = a;
776
      return wans;
777
    }
778
  }
779
}
780
 
781
 
782
 /*
783
  * locate differs from locate1 only in that it looks to see if e has already
784
  * been evaluated and remembered by register contents tracking scheme
785
  */
6 7u83 786
where locate(exp e, space sp, shape s, int dreg)
2 7u83 787
{
788
  ans ak;
789
  where w;
6 7u83 790
 
2 7u83 791
  /* Check to see if e has already been evaluated and remembered */
792
  if (!IS_R_NO_REG(dreg))
793
  {
794
    /* first try for exact reg */
795
    ak = iskept_inreg(e, dreg);
796
    if (ak.discrim == inreg && (regalt(ak) == 0))
797
      ak = iskept(e);			/* no luck, try anywhere */
798
  }
799
  else
800
  {
801
    ak = iskept(e);
802
  }
803
 
804
  if (ak.discrim == inreg && (regalt(ak) == 0))	/* See if we found a register */
805
  {
806
    w = locate1(e, sp, s, dreg);/* No register found so we must use locate1 */
807
  }
808
  else
809
  {
810
    FULLCOMMENT2("locate: iskept() found value inreg=%d [reg=%d]", ak.discrim == inreg, regalt(ak));
811
    w.answhere = ak;
812
    w.ashwhere = ashof(s);
813
  }
814
  return w;
815
}