Subversion Repositories tendra.SVN

Rev

Rev 5 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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