Subversion Repositories tendra.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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