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