Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
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 56... Line 86...
56
 * Revision 1.8  1995/04/05  12:35:18  pwe
86
 * Revision 1.8  1995/04/05  12:35:18  pwe
57
 * operator precedence in eq_where_exp
87
 * operator precedence in eq_where_exp
58
 *
88
 *
59
 * Revision 1.7  1995/04/03  08:30:24  pwe
89
 * Revision 1.7  1995/04/03  08:30:24  pwe
60
 * invalidate regs if overlap, eg if bitfield on byte boundaries
90
 * invalidate regs if overlap, eg if bitfield on byte boundaries
61
 *
91
 *
62
 * Revision 1.6  1995/03/24  09:21:39  pwe
92
 * Revision 1.6  1995/03/24  09:21:39  pwe
63
 * global proc renaming avoided for SCO
93
 * global proc renaming avoided for SCO
64
 *
94
 *
65
 * Revision 1.5  1995/03/03  10:12:36  pwe
95
 * Revision 1.5  1995/03/03  10:12:36  pwe
66
 * makeval is legal but arbitrary operand (for C)
96
 * makeval is legal but arbitrary operand (for C)
Line 68... Line 98...
68
 * Revision 1.4  1995/02/24  16:11:12  pwe
98
 * Revision 1.4  1995/02/24  16:11:12  pwe
69
 * dynamic offsets, including mixed bit/byte representations
99
 * dynamic offsets, including mixed bit/byte representations
70
 *
100
 *
71
 * Revision 1.3  1995/02/21  11:47:59  pwe
101
 * Revision 1.3  1995/02/21  11:47:59  pwe
72
 * Corrected move(offset) for movecont
102
 * Corrected move(offset) for movecont
73
 *
103
 *
74
 * Revision 1.2  1995/01/30  12:56:36  pwe
104
 * Revision 1.2  1995/01/30  12:56:36  pwe
75
 * Ownership -> PWE, tidy banners
105
 * Ownership -> PWE, tidy banners
76
 *
106
 *
77
 * Revision 1.1  1994/10/27  14:15:22  jmf
107
 * Revision 1.1  1994/10/27  14:15:22  jmf
78
 * Initial revision
108
 * Initial revision
79
 *
109
 *
80
 * Revision 1.1  1994/07/12  14:38:12  jmf
110
 * Revision 1.1  1994/07/12  14:38:12  jmf
81
 * Initial revision
111
 * Initial revision
82
 *
112
 *
83
**********************************************************************/
113
**********************************************************************/
84
 
114
 
85
 
115
 
86
/*********************************************************************
116
/*********************************************************************
87
                              operand.c
117
                              operand.c
88
 
118
 
89
  operand outputs a 80386 operand, given a "where" and the number of
119
  operand outputs a 80386 operand, given a "where" and the number of
90
  bits the operand occupies.
120
  bits the operand occupies.
91
 
121
 
92
 
122
 
93
 
123
 
94
*********************************************************************/
124
*********************************************************************/
95
 
125
 
96
 
126
 
97
#include "config.h"
127
#include "config.h"
98
#include "common_types.h"
128
#include "common_types.h"
Line 117... Line 147...
117
#include "assembler.h"
147
#include "assembler.h"
118
#include "messages_8.h"
148
#include "messages_8.h"
119
#include "diag_fns.h"
149
#include "diag_fns.h"
120
#include "operand.h"
150
#include "operand.h"
121
 
151
 
122
 
152
 
123
/* VARIABLES */
153
/* VARIABLES */
124
/* All variables initialised */
154
/* All variables initialised */
125
 
155
 
126
int  crt_proc_id;	/* init by cproc */
156
int  crt_proc_id;	/* init by cproc */
127
int  stack_dec;		/* init by cproc */
157
int  stack_dec;		/* init by cproc */
Line 133... Line 163...
133
/* PROCEDURES */
163
/* PROCEDURES */
134
 
164
 
135
/* turns an exp and an offset (in bits)
165
/* turns an exp and an offset (in bits)
136
   into a where */
166
   into a where */
137
where mw
167
where mw
138
    PROTO_N ( (e, off) )
-
 
139
    PROTO_T ( exp e X int off )
168
(exp e, int off)
140
{
169
{
141
  where w;
170
  where w;
142
  w.where_exp = e;
171
  w.where_exp = e;
143
  w.where_off = off;
172
  w.where_off = off;
144
  return (w);
173
  return(w);
145
}
174
}
146
 
175
 
147
/* compares wheres for equality of operand.
176
/* compares wheres for equality of operand.
148
   This is also used by equiv_reg to detect
177
   This is also used by equiv_reg to detect
149
   invalidity of register copy, in which case
178
   invalidity of register copy, in which case
150
   we need to detect overlaps, this case
179
   we need to detect overlaps, this case
151
   determined by 'overlap' */
180
   determined by 'overlap' */
152
int eq_where_exp
181
int eq_where_exp
153
    PROTO_N ( (a, b, first, overlap) )
-
 
154
    PROTO_T ( exp a X exp b X int first X int overlap )
182
(exp a, exp b, int first, int overlap)
155
{
183
{
156
  unsigned char  na;
184
  unsigned char  na;
157
  unsigned char  nb;
185
  unsigned char  nb;
158
 
186
 
159
rept:
187
rept:
160
  na = name(a);
188
  na = name(a);
161
  nb = name(b);
189
  nb = name(b);
162
 
190
 
163
  if (a == b)
191
  if (a == b)
164
    return (1);
192
    return(1);
165
  if (na == nb) {		/* same kind of operation "equal names" */
193
  if (na == nb) {		/* same kind of operation "equal names" */
166
    if (na == val_tag && !isbigval(a) && !isbigval(b))
194
    if (na == val_tag && !isbigval(a) && !isbigval(b))
167
      return (no (a) == no (b));
195
      return(no(a) == no(b));
168
    if (na == ident_tag) {
196
    if (na == ident_tag) {
169
      int good = son(a) != nilexp && son(b) != nilexp &&
197
      int good = son(a)!= nilexp && son(b)!= nilexp &&
170
          bro(son(a)) != nilexp && bro(son(b)) != nilexp;
198
          bro(son(a))!= nilexp && bro(son(b))!= nilexp;
171
      if (good) {
199
      if (good) {
172
        exp bsa = bro(son(a));
200
        exp bsa = bro(son(a));
173
        exp bsb = bro(son(b));
201
        exp bsb = bro(son(b));
174
        if (name (bsa) == name_tag && son (bsa) == a &&
202
        if (name(bsa) == name_tag && son(bsa) == a &&
175
	    name (bsb) == name_tag && son (bsb) == b) {
203
	    name(bsb) == name_tag && son(bsb) == b) {
176
	  a = son(a);
204
	  a = son(a);
177
	  b = son(b);
205
	  b = son(b);
178
	  first = 0;
206
	  first = 0;
179
	  goto rept;
207
	  goto rept;
180
        };
208
        };
181
        if (name (bsa) == reff_tag &&
209
        if (name(bsa) == reff_tag &&
182
	    name (bsb) == reff_tag &&
210
	    name(bsb) == reff_tag &&
183
	    (overlap ? (no (bsa) & -32) == (no (bsb) & -32) : no (bsa) == no (bsb)) &&
211
	   (overlap ?(no(bsa) & -32) == (no(bsb) & -32): no(bsa) == no(bsb)) &&
184
	    name (son (bsa)) == name_tag &&
212
	    name(son(bsa)) == name_tag &&
185
	    son (son (bsa)) == a &&
213
	    son(son(bsa)) == a &&
186
	    name (son (bsb)) == name_tag &&
214
	    name(son(bsb)) == name_tag &&
187
	    son (son (bsb)) == b) {
215
	    son(son(bsb)) == b) {
188
	  a = son(a);
216
	  a = son(a);
189
	  b = son(b);
217
	  b = son(b);
190
	  first = 0;
218
	  first = 0;
191
	  goto rept;
219
	  goto rept;
192
        };
220
        };
193
      };
221
      };
194
      if (isglob(a) || isglob(b))
222
      if (isglob(a) || isglob(b))
195
        return 0;
223
        return 0;
196
      return (pt (a) == pt (b) &&
224
      return(pt(a) == pt(b) &&
197
	      (overlap ? (no (a) & -32) == (no (b) & -32) : no (a) == no (b)));
225
	     (overlap ?(no(a) & -32) == (no(b) & -32): no(a) == no(b)));
198
    };
226
    };
199
    if (na == name_tag) {
227
    if (na == name_tag) {
200
      if ((overlap ? (no (a) & -32) != (no (b) & -32) : no (a) != no (b)) ||
228
      if ((overlap ?(no(a) & -32)!= (no(b) & -32): no(a)!= no(b)) ||
201
	  (isvar (son (a)) != isvar (son (b))))
229
	 (isvar(son(a))!= isvar(son(b))))
202
	return (0);
230
	return(0);
203
      a = son(a);
231
      a = son(a);
204
      b = son(b);
232
      b = son(b);
205
      first = 0;
233
      first = 0;
206
      goto rept;
234
      goto rept;
207
    };
235
    };
208
    if (na == cont_tag || na == ass_tag) {
236
    if (na == cont_tag || na == ass_tag) {
209
      a = son(a);
237
      a = son(a);
210
      b = son(b);
238
      b = son(b);
211
      first = 0;
239
      first = 0;
212
      goto rept;
240
      goto rept;
213
    };
241
    };
214
    if (na == field_tag || na == reff_tag) {
242
    if (na == field_tag || na == reff_tag) {
215
      if (overlap ? (no (a) & -32) != (no (b) & -32) : no (a) != no (b))
243
      if (overlap ?(no(a) & -32)!= (no(b) & -32): no(a)!= no(b))
216
	return (0);
244
	return(0);
217
      a = son(a);
245
      a = son(a);
218
      b = son(b);
246
      b = son(b);
219
      first = 0;
247
      first = 0;
220
      goto rept;
248
      goto rept;
221
    };
249
    };
222
    if (na == real_tag && name (sh (a)) == name (sh (b))) {
250
    if (na == real_tag && name(sh(a)) == name(sh(b))) {
223
      flt fa, fb;
251
      flt fa, fb;
224
      int  i;
252
      int  i;
225
      int is_zero = 1;
253
      int is_zero = 1;
226
      fa = flptnos[no (a)];
254
      fa = flptnos[no(a)];
227
      fb = flptnos[no (b)];
255
      fb = flptnos[no(b)];
228
 
256
 
229
      for (i = 0; i < MANT_SIZE && (fa.mant)[i] == (fb.mant)[i];
257
      for (i = 0; i < MANT_SIZE && (fa.mant)[i] == (fb.mant)[i];
230
	  i++) {
258
	  i++) {
231
	if ((fa.mant)[i] != 0)
259
	if ((fa.mant)[i]!= 0)
232
	  is_zero = 0;
260
	  is_zero = 0;
233
      };
261
      };
234
 
262
 
235
      return (i == MANT_SIZE &&
263
      return(i == MANT_SIZE &&
236
	  (is_zero || (fa.exp == fb.exp &&
264
	 (is_zero || (fa.exp == fb.exp &&
237
	      fa.sign == fb.sign)));
265
	      fa.sign == fb.sign)));
238
 
266
 
239
    };
267
    };
240
    return (0);
268
    return(0);
241
  };				/* end equal names */
269
  };				/* end equal names */
242
 
270
 
243
 
271
 
244
  if (na == name_tag && nb == ident_tag && first) {
272
  if (na == name_tag && nb == ident_tag && first) {
245
    if (overlap ? (no (a) & -32) != 0 : no (a) != 0)
273
    if (overlap ?(no(a) & -32)!= 0 : no(a)!= 0)
246
      return (0);
274
      return(0);
247
    a = son(a);
275
    a = son(a);
248
    first = 0;
276
    first = 0;
249
    goto rept;
277
    goto rept;
250
  };
278
  };
251
  if (na == ident_tag && nb == name_tag && first) {
279
  if (na == ident_tag && nb == name_tag && first) {
252
    if (overlap ? (no (b) & -32) != 0 : no (b) != 0)
280
    if (overlap ?(no(b) & -32)!= 0 : no(b)!= 0)
253
      return (0);
281
      return(0);
254
    b = son(b);
282
    b = son(b);
255
    first = 0;
283
    first = 0;
256
    goto rept;
284
    goto rept;
257
  };
285
  };
258
 
286
 
259
  if (na == cont_tag && name(son(a)) == name_tag &&
287
  if (na == cont_tag && name(son(a)) == name_tag &&
260
         isvar(son(son(a))) && nb == ident_tag && first) {
288
         isvar(son(son(a))) && nb == ident_tag && first) {
261
    if (overlap ? (no (son(a)) & -32) != 0 : no (son(a)) != 0)
289
    if (overlap ?(no(son(a)) & -32)!= 0 : no(son(a))!= 0)
262
      return (0);
290
      return(0);
263
    a = son(son(a));
291
    a = son(son(a));
264
    first = 0;
292
    first = 0;
265
    goto rept;
293
    goto rept;
266
  };
294
  };
267
  if (na == ident_tag && nb == cont_tag && name(son(b)) == name_tag
295
  if (na == ident_tag && nb == cont_tag && name(son(b)) == name_tag
268
            && isvar(son(son(b))) && first) {
296
            && isvar(son(son(b))) && first) {
269
    if (overlap ? (no (son(b)) & -32) != 0 : no (son(b)) != 0)
297
    if (overlap ?(no(son(b)) & -32)!= 0 : no(son(b))!= 0)
270
      return (0);
298
      return(0);
271
    b = son(b);
299
    b = son(b);
272
    first = 0;
300
    first = 0;
273
    goto rept;
301
    goto rept;
274
  };
302
  };
275
 
303
 
276
  if ((na == cont_tag || na == ass_tag) &&
304
  if ((na == cont_tag || na == ass_tag) &&
277
      name (son (a)) == name_tag &&
305
      name(son(a)) == name_tag &&
278
      isvar (son (son (a))) && nb == name_tag && !isvar (son (b))) {
306
      isvar(son(son(a))) && nb == name_tag && !isvar(son(b))) {
279
    if (overlap ? (no (son(a)) & -32) != (no (b) & -32) : no (son(a)) != no (b))
307
    if (overlap ?(no(son(a)) & -32)!= (no(b) & -32): no(son(a))!= no(b))
280
      return (0);
308
      return(0);
281
    a = son (son (a));
309
    a = son(son(a));
282
    b = son (b);
310
    b = son(b);
283
    first = 0;
311
    first = 0;
284
    goto rept;
312
    goto rept;
285
  };
313
  };
286
  if ((nb == cont_tag || nb == ass_tag) &&
314
  if ((nb == cont_tag || nb == ass_tag) &&
287
      name (son (b)) == name_tag &&
315
      name(son(b)) == name_tag &&
288
      isvar (son (son (b))) && na == name_tag && !isvar (son (a))) {
316
      isvar(son(son(b))) && na == name_tag && !isvar(son(a))) {
289
    if (overlap ? (no (son(b)) & -32) != (no (a) & -32) : no (son(b)) != no (a))
317
    if (overlap ?(no(son(b)) & -32)!= (no(a) & -32): no(son(b))!= no(a))
290
      return (0);
318
      return(0);
291
    a = son (a);
319
    a = son(a);
292
    b = son (son (b));
320
    b = son(son(b));
293
    first = 0;
321
    first = 0;
294
    goto rept;
322
    goto rept;
295
  };
323
  };
296
  if ((na == ass_tag && nb == cont_tag) ||
324
  if ((na == ass_tag && nb == cont_tag) ||
297
      (nb == ass_tag && na == cont_tag)) {
325
     (nb == ass_tag && na == cont_tag)) {
298
    a = son(a);
326
    a = son(a);
299
    b = son(b);
327
    b = son(b);
300
    first = 0;
328
    first = 0;
301
    goto rept;
329
    goto rept;
302
  };
330
  };
303
  return (0);
331
  return(0);
304
}
332
}
305
 
333
 
306
/* compares wheres for equality of operand */
334
/* compares wheres for equality of operand */
307
int eq_where
335
int eq_where
308
    PROTO_N ( (wa, wb) )
-
 
309
    PROTO_T ( where wa X where wb )
336
(where wa, where wb)
310
{
337
{
311
  exp a = wa.where_exp;
338
  exp a = wa.where_exp;
312
  exp b = wb.where_exp;
339
  exp b = wb.where_exp;
313
  if (a == nilexp || b == nilexp)
340
  if (a == nilexp || b == nilexp)
314
     return 0;
341
     return 0;
315
  if (wa.where_off != wb.where_off)
342
  if (wa.where_off != wb.where_off)
316
    return (0);
343
    return(0);
317
  return eq_where_exp (a, b, 1, 0);
344
  return eq_where_exp(a, b, 1, 0);
318
}
345
}
319
 
346
 
320
 
347
 
321
/* find the first register in the register bit pattern r */
348
/* find the first register in the register bit pattern r */
322
frr first_reg
349
frr first_reg
323
    PROTO_N ( (r) )
-
 
324
    PROTO_T ( int r )
350
(int r)
325
{
351
{
326
  frr t;
352
  frr t;
327
  t.regno = 1;
353
  t.regno = 1;
328
  t.fr_no = 0;
354
  t.fr_no = 0;
329
  if (r == 0)
355
  if (r == 0)
330
    failer (BAD_REGISTER);
356
    failer(BAD_REGISTER);
331
  else {
357
  else {
332
    while (!(t.regno & r)) {
358
    while (!(t.regno & r)) {
333
      t.regno = t.regno << 1;
359
      t.regno = t.regno << 1;
334
      ++t.fr_no;
360
      ++t.fr_no;
335
    }
361
    }
336
  };
362
  };
337
  return (t);
363
  return(t);
338
}
364
}
339
 
365
 
340
/* output operand,  wh is a where Note
366
/* output operand,  wh is a where Note
341
   that the pt field of a declaration now
367
   that the pt field of a declaration now
342
   hold a code for the position of the
368
   hold a code for the position of the
Line 352... Line 378...
352
   operations. b is passed to extn to
378
   operations. b is passed to extn to
353
   control whether a bracket is output
379
   control whether a bracket is output
354
   (index instructions). addr is true if
380
   (index instructions). addr is true if
355
   we need a literal address. */
381
   we need a literal address. */
356
void operand
382
void operand
357
    PROTO_N ( (le, wh, b, addr) )
-
 
358
    PROTO_T ( int le X where wh X int b X int addr )
383
(int le, where wh, int b, int addr)
359
{
384
{
360
  exp w = wh.where_exp;
385
  exp w = wh.where_exp;
361
  int  off = wh.where_off;
386
  int  off = wh.where_off;
362
  unsigned char  n = name (w);
387
  unsigned char  n = name(w);
363
 
388
 
364
  if (n == val_tag && !isbigval(w)) {		/* integer constant */
389
  if (n == val_tag && !isbigval(w)) {		/* integer constant */
365
    int  k = no (w) + off;
390
    int  k = no(w) + off;
366
    if (name(sh(w)) == offsethd && al2(sh(w)) != 1)
391
    if (name(sh(w)) == offsethd && al2(sh(w))!= 1)
367
      k = k / 8;
392
      k = k / 8;
368
    int_operand (k, le);
393
    int_operand(k, le);
369
    return;
394
    return;
370
  };
395
  };
371
 
396
 
372
  if (n == ident_tag || n == labst_tag) {/* can only be dest */
397
  if (n == ident_tag || n == labst_tag) {/* can only be dest */
373
    switch (ptno (w)) {
398
    switch (ptno(w)) {
374
      case local_pl: {
399
      case local_pl: {
375
	  rel_sp ((no (w) + off - stack_dec) / 8, b);
400
	  rel_sp((no(w) + off - stack_dec) / 8, b);
376
	  return;
401
	  return;
377
	};
402
	};
378
      case reg_pl: {
403
      case reg_pl: {
379
	  regn (no (w), off, w, le);
404
	  regn(no(w), off, w, le);
380
	  return;
405
	  return;
381
	};
406
	};
382
      default: {
407
      default: {
383
	  failer (BAD_OPND);
408
	  failer(BAD_OPND);
384
	  return;
409
	  return;
385
	};
410
	};
386
    };
411
    };
387
  };
412
  };
388
 
413
 
389
  if (n == name_tag) {
414
  if (n == name_tag) {
390
    exp ident = son (w);
415
    exp ident = son(w);
391
    int  noff = no (w) + off;
416
    int  noff = no(w) + off;
392
    int  ni = no (ident);
417
    int  ni = no(ident);
393
 
418
 
394
    if (isglob (ident)) {
419
    if (isglob(ident)) {
395
      if (name (sh (w)) == prokhd)	/* special treatment for procedures */
420
      if (name (sh (w)) == prokhd)	/* special treatment for procedures */
396
        {
421
        {
397
          const_extn (ident, noff);
422
          const_extn(ident, noff);
398
          return;
423
          return;
399
        };
424
        };
400
 
425
 
401
      if (isvar (ident))
426
      if (isvar(ident))
402
	const_extn (ident, noff);
427
	const_extn(ident, noff);
403
      else
428
      else
404
	extn (ident, noff, b);
429
	extn(ident, noff, b);
405
      return;
430
      return;
406
    };
431
    };
407
 
432
 
408
    switch (ptno (ident)) {
433
    switch (ptno(ident)) {
409
      case local_pl: {		/* local so relative to stack pointer or fp */
434
      case local_pl: {		/* local so relative to stack pointer or fp */
410
	  rel_sp ((ni + noff - stack_dec) / 8, b);
435
	  rel_sp((ni + noff - stack_dec) / 8, b);
411
	  return;
436
	  return;
412
	};
437
	};
413
      case callstack_pl: {	/* caller arg so relative to stack pointer */
438
      case callstack_pl: {	/* caller arg so relative to stack pointer */
414
	  rel_cp ((ni + noff - stack_dec) / 8, b);
439
	  rel_cp((ni + noff - stack_dec) / 8, b);
415
	  return;
440
	  return;
416
	};
441
	};
417
      case par_pl: {		/* parameter so relative to fp */
442
      case par_pl: {		/* parameter so relative to fp */
418
	  rel_ap ((ni + noff + 32) / 8, b);
443
	  rel_ap((ni + noff + 32) / 8, b);
419
	  return;
444
	  return;
420
	};
445
	};
421
      case reg_pl: {		/* in a register */
446
      case reg_pl: {		/* in a register */
422
	  regn (ni, noff, w, le);
447
	  regn(ni, noff, w, le);
423
	  return;
448
	  return;
424
	};
449
	};
425
      case ferr_pl: {		/* relative to fp, depending on push space */
450
      case ferr_pl: {		/* relative to fp, depending on push space */
426
	  rel_ap1 ((ni + noff) / 8, b);
451
	  rel_ap1((ni + noff) / 8, b);
427
	  return;
452
	  return;
428
	};
453
	};
429
      default: {		/* doesnt happen */
454
      default: {		/* doesnt happen */
430
	  failer (BAD_OPND);
455
	  failer(BAD_OPND);
431
	  return;
456
	  return;
432
	};
457
	};
433
    };
458
    };
434
  };
459
  };
435
 
460
 
436
  if (n == cont_tag || n == ass_tag) {
461
  if (n == cont_tag || n == ass_tag) {
437
    exp ref = son (w);
462
    exp ref = son(w);
438
    unsigned char  s = name (ref);
463
    unsigned char  s = name(ref);
439
    if (addr) {
464
    if (addr) {
440
      operand (le, mw (son (w), 0), b, 0);
465
      operand(le, mw(son(w), 0), b, 0);
441
      return;
466
      return;
442
    };
467
    };
443
    if (s == name_tag) {	/* content of id */
468
    if (s == name_tag) {	/* content of id */
444
      if (!isvar (son (ref))) {
469
      if (!isvar(son(ref))) {
445
	exp ident = son (ref);
470
	exp ident = son(ref);
446
	if (ptno (ident) != reg_pl && off != 0) {
471
	if (ptno(ident)!= reg_pl && off != 0) {
447
	  failer (BAD_OPND);
472
	  failer(BAD_OPND);
448
	};
473
	};
449
	if (isglob (ident)) {
474
	if (isglob(ident)) {
450
	  if (name (sh (w)) != prokhd)
475
	  if (name(sh(w))!= prokhd)
451
	    failer (BAD_OPND);
476
	    failer(BAD_OPND);
452
	  else
477
	  else
453
           {
478
           {
454
	     if (PIC_code)
479
	     if (PIC_code)
455
	       proc_extn (ident, no(ref));
480
	       proc_extn(ident, no(ref));
456
             else
481
             else
457
               extn (ident, no (ref), b);
482
               extn(ident, no(ref), b);
458
           };
483
           };
459
	  return;
484
	  return;
460
	};
485
	};
461
	switch (ptno (ident)) {
486
	switch (ptno(ident)) {
462
	  case reg_pl: {	/* indirect from register */
487
	  case reg_pl: {	/* indirect from register */
463
	      ind_reg (no (ident), no (ref), off, ref, b);
488
	      ind_reg(no(ident), no(ref), off, ref, b);
464
	      return;
489
	      return;
465
	    };
490
	    };
466
	  default: {
491
	  default: {
467
	      failer (BAD_OPND);
492
	      failer(BAD_OPND);
468
	      return;
493
	      return;
469
	    };
494
	    };
470
	};
495
	};
471
      }
496
      }
472
      else {			/* variable */
497
      else {			/* variable */
473
 
498
 
474
	exp ident = son (ref);
499
	exp ident = son(ref);
475
	int  noff = no (ref) + off;
500
	int  noff = no(ref) + off;
476
	int  ni = no (ident);
501
	int  ni = no(ident);
477
 
502
 
478
	if (isglob (ident)) {
503
	if (isglob(ident)) {
479
	  extn (ident, noff, b);
504
	  extn(ident, noff, b);
480
	  return;
505
	  return;
481
	};
506
	};
482
	switch (ptno (ident)) {
507
	switch (ptno(ident)) {
483
	  case local_pl: {
508
	  case local_pl: {
484
	      /* local so relative to stack pointer or fp */
509
	      /* local so relative to stack pointer or fp */
485
	      rel_sp ((ni + noff - stack_dec) / 8, b);
510
	      rel_sp((ni + noff - stack_dec) / 8, b);
486
	      return;
511
	      return;
487
	    };
512
	    };
488
	  case callstack_pl: {
513
	  case callstack_pl: {
489
	      /* caller arg so relative to stack pointer */
514
	      /* caller arg so relative to stack pointer */
490
	      rel_cp ((ni + noff - stack_dec) / 8, b);
515
	      rel_cp((ni + noff - stack_dec) / 8, b);
491
	      return;
516
	      return;
492
	    };
517
	    };
493
	  case par_pl: {	/* parameter so relative to fp */
518
	  case par_pl: {	/* parameter so relative to fp */
494
	      rel_ap ((ni + noff + 32) / 8, b);
519
	      rel_ap((ni + noff + 32) / 8, b);
495
	      return;
520
	      return;
496
	    };
521
	    };
497
	  case reg_pl: {	/* in a register */
522
	  case reg_pl: {	/* in a register */
498
	      regn (ni, noff, ref, le);
523
	      regn(ni, noff, ref, le);
499
	      return;
524
	      return;
500
	    };
525
	    };
501
	  default: {		/* doesnt happen */
526
	  default: {		/* doesnt happen */
502
	      failer (BAD_OPND);
527
	      failer(BAD_OPND);
503
	      return;
528
	      return;
504
	    };
529
	    };
505
	};
530
	};
506
      };
531
      };
507
    };				/* end of cont(name) */
532
    };				/* end of cont(name) */
508
 
533
 
509
    if (s == cont_tag && name (son (ref)) == name_tag &&
534
    if (s == cont_tag && name(son(ref)) == name_tag &&
510
	isvar (son (son (ref)))) {
535
	isvar(son(son(ref)))) {
511
      exp ident = son (son (ref));
536
      exp ident = son(son(ref));
512
      if (ptno (ident) != reg_pl && off != 0) {
537
      if (ptno(ident)!= reg_pl && off != 0) {
513
	failer (BAD_OPND);
538
	failer(BAD_OPND);
514
      };
539
      };
515
      if (isglob (ident)) {
540
      if (isglob(ident)) {
516
	if (name (sh (w)) != prokhd)
541
	if (name(sh(w))!= prokhd)
517
	  failer (BAD_OPND);
542
	  failer(BAD_OPND);
518
	else
543
	else
519
	  extn (ident, no (son (ref)), b);
544
	  extn(ident, no(son(ref)), b);
520
	return;
545
	return;
521
      };
546
      };
522
      switch (ptno (ident)) {
547
      switch (ptno(ident)) {
523
	case reg_pl: {		/* indirect from register */
548
	case reg_pl: {		/* indirect from register */
524
	    ind_reg (no (ident), no (son (ref)), off, ref, b);
549
	    ind_reg(no(ident), no(son(ref)), off, ref, b);
525
	    return;
550
	    return;
526
	  };
551
	  };
527
	default: {
552
	default: {
528
	    failer (BAD_OPND);
553
	    failer(BAD_OPND);
529
	    return;
554
	    return;
530
	  };
555
	  };
531
      };
556
      };
532
    };				/* end of cont(cont(var)) */
557
    };				/* end of cont(cont(var)) */
533
 
558
 
534
 
559
 
535
    if (s == reff_tag) {
560
    if (s == reff_tag) {
536
      exp et = son (ref);
561
      exp et = son(ref);
537
      unsigned char  t = name (et);
562
      unsigned char  t = name(et);
538
      if (t == name_tag) {
563
      if (t == name_tag) {
539
	if (isglob (son (et))) {
564
	if (isglob(son(et))) {
540
	  extn (son (et), no (ref), b);
565
	  extn(son(et), no(ref), b);
541
	  return;
566
	  return;
542
	};
567
	};
543
	switch (ptno (son (et))) {
568
	switch (ptno(son(et))) {
544
	  case reg_pl: {
569
	  case reg_pl: {
545
	      ind_reg (no (son (et)), no (et), (no (ref) + off), et, b);
570
	      ind_reg(no(son(et)), no(et), (no(ref) + off), et, b);
546
	      return;
571
	      return;
547
	    };
572
	    };
548
	  default: {
573
	  default: {
549
	      failer (BAD_OPND);
574
	      failer(BAD_OPND);
550
	      return;
575
	      return;
551
	    };
576
	    };
552
	};
577
	};
553
      };			/* end of cont(reff(name)) */
578
      };			/* end of cont(reff(name)) */
554
 
579
 
555
      if (t == cont_tag) {
580
      if (t == cont_tag) {
556
	switch (ptno (son (son (et)))) {
581
	switch (ptno(son(son(et)))) {
557
	  case reg_pl: {
582
	  case reg_pl: {
558
	      ind_reg (no (son (son (et))), no (son (et)),
583
	      ind_reg(no(son(son(et))), no(son(et)),
559
		  (no (ref) + off), son (et), b);
584
		 (no(ref) + off), son(et), b);
560
	      return;
585
	      return;
561
	    };
586
	    };
562
	  default: {
587
	  default: {
563
	      failer (BAD_OPND);
588
	      failer(BAD_OPND);
564
	      return;
589
	      return;
565
	    };
590
	    };
566
	};
591
	};
567
      };			/* end of cont(ref(cont())) */
592
      };			/* end of cont(ref(cont())) */
568
 
593
 
569
      if (t == addptr_tag) {
594
      if (t == addptr_tag) {
570
	where new_w;
595
	where new_w;
571
	new_w.where_exp = et;
596
	new_w.where_exp = et;
572
	new_w.where_off = off + no (ref);
597
	new_w.where_off = off + no(ref);
573
	operand (le, new_w, b, 0);
598
	operand(le, new_w, b, 0);
574
	return;
599
	return;
575
      };			/* end of cont(reff(addptr())) */
600
      };			/* end of cont(reff(addptr())) */
576
      failer (BAD_OPND);
601
      failer(BAD_OPND);
577
    };				/* end of cont(reff()) */
602
    };				/* end of cont(reff()) */
578
 
603
 
579
    if (s == addptr_tag) {
604
    if (s == addptr_tag) {
580
      exp u = bro (son (ref));
605
      exp u = bro(son(ref));
581
      exp c = getexp (f_bottom, nilexp, 0, son (ref), nilexp,
606
      exp c = getexp(f_bottom, nilexp, 0, son(ref), nilexp,
582
	  0, 0, cont_tag);
607
	  0, 0, cont_tag);
583
      where wc, wu;
608
      where wc, wu;
584
      wc.where_exp = c;
609
      wc.where_exp = c;
585
      wc.where_off = off;
610
      wc.where_off = off;
586
      wu.where_exp = u;
611
      wu.where_exp = u;
587
      wu.where_off = 0;
612
      wu.where_off = 0;
588
      if (name (u) == name_tag || name (u) == cont_tag) {
613
      if (name(u) == name_tag || name(u) == cont_tag) {
589
	index_opnd (wc, wu, 1);
614
	index_opnd(wc, wu, 1);
590
	return;
615
	return;
591
      };			/* end of cont(addptr(-, name)) */
616
      };			/* end of cont(addptr(-, name)) */
592
 
617
 
593
      if (name (u) == offset_mult_tag) {
618
      if (name(u) == offset_mult_tag) {
594
	int  k = no (bro (son (u)))/8;	/* cannot be bitfield */
619
	int  k = no (bro (son (u)))/8;	/* cannot be bitfield */
595
	wu.where_exp = son (u);
620
	wu.where_exp = son(u);
596
	index_opnd (wc, wu, k);
621
	index_opnd(wc, wu, k);
597
	return;
622
	return;
598
      };			/* end of cont(addptr(-, mult)) */
623
      };			/* end of cont(addptr(-, mult)) */
599
    };				/* end of cont(addptr()) */
624
    };				/* end of cont(addptr()) */
600
 
625
 
601
 
626
 
602
  };				/* end of cont */
627
  };				/* end of cont */
603
 
628
 
604
 
629
 
605
  if (n == reff_tag) {
630
  if (n == reff_tag) {
606
    exp se = son (w);
631
    exp se = son(w);
607
    unsigned char  s = name (se);
632
    unsigned char  s = name(se);
608
    if (s == name_tag) {
633
    if (s == name_tag) {
609
      if (isglob (son (se))) {
634
      if (isglob(son(se))) {
610
	extn (son (se), no (w), b);
635
	extn(son(se), no(w), b);
611
	return;
636
	return;
612
      };
637
      };
613
      switch (ptno (son (se))) {
638
      switch (ptno(son(se))) {
614
	case reg_pl: {
639
	case reg_pl: {
615
	    ind_reg (no (son (se)), no (son (se)), no (w), se, b);
640
	    ind_reg(no(son(se)), no(son(se)), no(w), se, b);
616
	    return;
641
	    return;
617
	  };
642
	  };
618
	default: {
643
	default: {
619
	    failer (BAD_OPND);
644
	    failer(BAD_OPND);
620
	    return;
645
	    return;
621
	  };
646
	  };
622
      };
647
      };
623
    };				/* end of reff(name)  */
648
    };				/* end of reff(name)  */
624
 
649
 
625
    if (s == cont_tag) {
650
    if (s == cont_tag) {
626
      if (isglob (son (son (se)))) {
651
      if (isglob(son(son(se)))) {
627
	extn (son (son (se)), no (w), b);
652
	extn(son(son(se)), no(w), b);
628
	return;
653
	return;
629
      };
654
      };
630
      switch (ptno (son (son (se)))) {
655
      switch (ptno(son(son(se)))) {
631
	case reg_pl: {
656
	case reg_pl: {
632
	    ind_reg (no (son (son (se))), no (son (se)),
657
	    ind_reg(no(son(son(se))), no(son(se)),
633
		no (w), son (se), b);
658
		no(w), son(se), b);
634
	    return;
659
	    return;
635
	  };
660
	  };
636
	default: {
661
	default: {
637
	    failer (BAD_OPND);
662
	    failer(BAD_OPND);
638
	    return;
663
	    return;
639
	  };
664
	  };
640
      };
665
      };
641
    };				/* end of reff(cont()) */
666
    };				/* end of reff(cont()) */
642
 
667
 
643
    if (s == addptr_tag) {
668
    if (s == addptr_tag) {
644
      where ww;
669
      where ww;
645
      ww.where_exp = se;
670
      ww.where_exp = se;
646
      ww.where_off = off + no (w);
671
      ww.where_off = off + no(w);
647
      operand (le, ww, b, 0);
672
      operand(le, ww, b, 0);
648
      return;
673
      return;
649
    };				/* end of reff(addptr()) */
674
    };				/* end of reff(addptr()) */
650
  };				/* end of reff() */
675
  };				/* end of reff() */
651
 
676
 
652
  if (n == addptr_tag) {
677
  if (n == addptr_tag) {
653
    exp u = bro (son (w));
678
    exp u = bro(son(w));
654
    exp c = getexp (f_bottom, nilexp, 0, son (w), nilexp, 0, 0, cont_tag);
679
    exp c = getexp(f_bottom, nilexp, 0, son(w), nilexp, 0, 0, cont_tag);
655
    where wc, wu;
680
    where wc, wu;
656
    wc.where_exp = c;
681
    wc.where_exp = c;
657
    wc.where_off = off;
682
    wc.where_off = off;
658
    wu.where_exp = u;
683
    wu.where_exp = u;
659
    wu.where_off = 0;
684
    wu.where_off = 0;
660
    if (name (u) == name_tag || name (u) == cont_tag) {
685
    if (name(u) == name_tag || name(u) == cont_tag) {
661
      index_opnd (wc, wu, 1);
686
      index_opnd(wc, wu, 1);
662
      return;
687
      return;
663
    };				/* end of addptr(-, name)  */
688
    };				/* end of addptr(-, name)  */
664
 
689
 
665
    if (name (u) == offset_mult_tag) {
690
    if (name(u) == offset_mult_tag) {
666
      int  k = no (bro (son (u)))/8;	/* cannot be bitfield */
691
      int  k = no (bro (son (u)))/8;	/* cannot be bitfield */
667
      wu.where_exp = son (u);
692
      wu.where_exp = son(u);
668
      index_opnd (wc, wu, k);
693
      index_opnd(wc, wu, k);
669
      return;
694
      return;
670
    };				/* end of addptr(-, mult) */
695
    };				/* end of addptr(-, mult) */
671
  };				/* end of addptr() */
696
  };				/* end of addptr() */
672
 
697
 
673
  if (n == real_tag || n == val_tag || n == string_tag ||
698
  if (n == real_tag || n == val_tag || n == string_tag ||
674
	n == proc_tag || n == general_proc_tag) {
699
	n == proc_tag || n == general_proc_tag) {
675
    int  ln;
700
    int  ln;
676
    if (off == 0 || addr) {
701
    if (off == 0 || addr) {
677
      ln = next_lab ();
702
      ln = next_lab();
678
      const_list = getexp (f_bottom, const_list, 0, w, nilexp, 0, ln, 0);
703
      const_list = getexp(f_bottom, const_list, 0, w, nilexp, 0, ln, 0);
679
      const_intnl ((addr || n == proc_tag || n == general_proc_tag), ln, 0);
704
      const_intnl((addr || n == proc_tag || n == general_proc_tag), ln, 0);
680
      return;
705
      return;
681
    };
706
    };
682
    /* assumes this is only used just after using the first part of the
707
    /* assumes this is only used just after using the first part of the
683
       constant */
708
       constant */
684
    const_intnl (0, no (const_list), off);
709
    const_intnl(0, no(const_list), off);
685
    return;
710
    return;
686
  };
711
  };
687
 
712
 
688
  if (n == res_tag) {
713
  if (n == res_tag) {
689
    const_intnl (0, no (w), off);
714
    const_intnl(0, no(w), off);
690
    return;
715
    return;
691
  };
716
  };
692
 
717
 
693
  if (n == null_tag) {
718
  if (n == null_tag) {
694
    int_operand (no(w), le);
719
    int_operand(no(w), le);
695
    return;
720
    return;
696
  };
721
  };
697
 
722
 
698
  if (n == field_tag) {
723
  if (n == field_tag) {
699
    operand (le, mw (son (w), off + no (w)), b, addr);
724
    operand(le, mw(son(w), off + no(w)), b, addr);
700
    return;
725
    return;
701
  };
726
  };
702
 
727
 
703
  if (n == make_lv_tag) {
728
  if (n == make_lv_tag) {
704
    label_operand(w);
729
    label_operand(w);
Line 710... Line 735...
710
    return;
735
    return;
711
  };
736
  };
712
 
737
 
713
  if (n == env_offset_tag) {
738
  if (n == env_offset_tag) {
714
    if (name(son(w))==0) {	/* must be caller arg with var_callees */
739
    if (name(son(w))==0) {	/* must be caller arg with var_callees */
715
      int_operand(no(son(w))/8, le);
740
      int_operand(no(son(w)) /8, le);
716
      return;
741
      return;
717
    }
742
    }
718
    outs("$");
743
    outs("$");
719
    envoff_operand(son(w), no(w));
744
    envoff_operand(son(w), no(w));
720
    return;
745
    return;
Line 748... Line 773...
748
	outs("%eax");
773
	outs("%eax");
749
	return;
774
	return;
750
    };
775
    };
751
  };
776
  };
752
 
777
 
753
  failer (BAD_OPND);
778
  failer(BAD_OPND);
754
 
779
 
755
  return;
780
  return;
756
}
781
}
757
 
782