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