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-2006 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) 1996
32
    		 Crown Copyright (c) 1996
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 115... Line 145...
115
/*
145
/*
116
    FIND THE EXTERNAL NAME OF AN OPERAND
146
    FIND THE EXTERNAL NAME OF AN OPERAND
117
 
147
 
118
    The expression e, representing an external, is looked up in the main_globals
148
    The expression e, representing an external, is looked up in the main_globals
119
    table, and its external name is returned.
149
    table, and its external name is returned.
120
*/
150
*/
121
 
151
 
122
static char *extname
152
static char *
123
    PROTO_N ( ( e ) )
-
 
124
    PROTO_T ( exp e )
153
extname(exp e)
125
{
154
{
126
    dec *d = brog ( e ) ;
155
	dec *d = brog(e);
127
#if 0
156
#if 0
128
    if ( d->dec_u.dec_val.external_register ) {
157
	if (d->dec_u.dec_val.external_register) {
129
	error ( "External registers not yet implemented" ) ;
158
		error("External registers not yet implemented");
130
	return ( "????" ) ;
159
		return ("????");
131
    }
160
	}
132
#endif
161
#endif
133
    return ( d->dec_u.dec_val.dec_id ) ;
162
	return (d->dec_u.dec_val.dec_id);
134
}
163
}
135
 
164
 
136
 
165
 
137
/*
166
/*
138
    MACROS
167
    MACROS
139
 
168
 
140
    These macros are used as convenient shorthands in operand.
169
    These macros are used as convenient shorthands in operand.
141
*/
170
*/
142
 
171
 
143
#define  make_ind( X, Y )	make_indirect ( reg ( X ), ( Y ) / 8 )
172
#define make_ind(X, Y)		make_indirect(reg(X), (Y) / 8)
144
#define  make_ext( X, Y )	make_extern ( extname ( X ), ( Y ) / 8 )
173
#define make_ext(X, Y)		make_extern(extname(X), (Y) / 8)
145
#define  make_ext_ind( X, Y )	make_extern_ind ( extname ( X ), ( Y ) / 8 )
174
#define make_ext_ind(X, Y)	make_extern_ind(extname(X), (Y) / 8)
146
 
175
 
147
 
176
 
148
/*
177
/*
149
    TRANSLATE AN INDEX OPERAND
178
    TRANSLATE AN INDEX OPERAND
150
 
179
 
151
    The operand corresponding to w1 indexed by w2 times sf is translated into
180
    The operand corresponding to w1 indexed by w2 times sf is translated into
152
    a mach_op.
181
    a mach_op.
153
*/
182
*/
154
 
183
 
155
static mach_op *index_opnd
184
static mach_op *
156
    PROTO_N ( ( w1, w2, sf ) )
-
 
157
    PROTO_T ( where w1 X where w2 X int sf )
185
index_opnd(where w1, where w2, int sf)
158
{
186
{
159
    mach_op *op1, *op2 ;
187
	mach_op *op1, *op2;
160
    if ( name ( w2.wh_exp ) != name_tag ) {
188
	if (name(w2.wh_exp) != name_tag) {
161
	error ( "Illegal index operand" ) ;
189
		error("Illegal index operand");
162
	return ( null ) ;
190
		return (null);
163
    }
191
	}
164
    op1 = operand ( L32, w1 ) ;
192
	op1 = operand(L32, w1);
165
    op2 = operand ( L32, w2 ) ;
193
	op2 = operand(L32, w2);
166
    return ( make_index_op ( op1, op2, sf ) ) ;
194
	return (make_index_op(op1, op2, sf));
167
}
195
}
168
 
196
 
169
 
197
 
170
/*
198
/*
171
    ERROR MESSAGE
199
    ERROR MESSAGE
172
 
200
 
173
    In debugging mode a little extra information is always useful.
201
    In debugging mode a little extra information is always useful.
174
*/
202
*/
175
 
203
 
176
#ifdef EBUG
204
#ifdef EBUG
177
static char *illegal_operand = "Illegal operand, case %d" ;
205
static char *illegal_operand = "Illegal operand, case %d";
178
#else
206
#else
179
static char *illegal_operand = "Illegal operand" ;
207
static char *illegal_operand = "Illegal operand";
180
#endif
208
#endif
181
 
209
 
182
 
210
 
183
/*
211
/*
184
    TRANSLATE A TDF OPERAND INTO A MACHINE OPERAND
212
    TRANSLATE A TDF OPERAND INTO A MACHINE OPERAND
185
 
213
 
186
    The value wh of size sz is converted into a mach_op.
214
    The value wh of size sz is converted into a mach_op.
187
*/
215
*/
188
 
216
 
189
mach_op *operand
217
mach_op *
190
    PROTO_N ( ( sz, wh ) )
-
 
191
    PROTO_T ( long sz X where wh )
218
operand(long sz, where wh)
192
{
219
{
193
    long d ;
220
	long d;
194
    mach_op *op ;
221
	mach_op *op;
195
    exp w = wh.wh_exp ;
222
	exp w = wh.wh_exp;
196
    long off = wh.wh_off ;
223
	long off = wh.wh_off;
197
 
224
 
198
    switch ( name ( w ) ) {
225
	switch (name(w)) {
199
 
-
 
200
	case val_tag : {
226
	case val_tag: {
201
	    long k = no ( w ) + off ;
227
		long k = no(w) + off;
202
	    if ( is_offset ( w ) ) k /= 8 ;
228
		if (is_offset(w)) {
-
 
229
			k /= 8;
-
 
230
		}
203
	    if ( sz == 8 ) k &= 0xff ;
231
		if (sz == 8) {
-
 
232
			k &= 0xff;
-
 
233
		}
204
	    if ( sz == 16 ) k &= 0xffff ;
234
		if (sz == 16) {
-
 
235
			k &= 0xffff;
-
 
236
		}
205
	    return ( make_value ( k ) ) ;
237
		return (make_value(k));
206
	}
238
	}
207
 
-
 
208
	case ident_tag :
239
	case ident_tag:
209
	case labst_tag : {
240
	case labst_tag:
210
	    switch ( ptno ( w ) ) {
241
		switch (ptno(w)) {
211
		case var_pl : {
242
		case var_pl:
212
		    d = no ( w ) - off ;
243
			d = no(w) - off;
213
		    return ( make_rel_ap ( -( d / 8 ) ) ) ;
244
			return (make_rel_ap(- (d / 8)));
214
		}
-
 
215
#ifndef tdf3
245
#ifndef tdf3
216
		case par2_pl : {
246
		case par2_pl:
217
		    d = no ( w ) + off ;
247
			d = no(w) + off;
218
		    return ( make_rel_ap2 ( d / 8 ) ) ;
248
			return (make_rel_ap2(d / 8));
219
		}
-
 
220
		case par3_pl : {
249
		case par3_pl:
221
		    d = no ( w ) + off ;
250
			d = no(w) + off;
222
		    return ( make_rel_sp ( d / 8 ) ) ;
251
			return (make_rel_sp(d / 8));
223
		}
-
 
224
#endif
252
#endif
225
		case par_pl : {
253
		case par_pl:
226
		    d = no ( w ) + off + 32 ;
254
			d = no(w) + off + 32;
227
		    return ( make_rel_ap ( d / 8 ) ) ;
255
			return (make_rel_ap(d / 8));
-
 
256
		case reg_pl:
-
 
257
			return (make_register(reg(no(w))));
-
 
258
		default:
-
 
259
			error(illegal_operand, 0);
-
 
260
			return (null);
228
		}
261
		}
229
		case reg_pl : {
-
 
230
		    return ( make_register ( reg ( no ( w ) ) ) ) ;
-
 
231
		}
-
 
232
		default : {
-
 
233
		    error ( illegal_operand, 0 ) ;
-
 
234
		    return ( null ) ;
-
 
235
		}
-
 
236
	    }
-
 
237
	}
-
 
238
 
-
 
239
	case name_tag : {
262
	case name_tag: {
240
	    exp id = son ( w ) ;
263
		exp id = son(w);
241
	    long d1 = no ( w ) + off ;
264
		long d1 = no(w) + off;
242
	    long d2 = no ( id ) ;
265
		long d2 = no(id);
243
 
266
 
244
	    if ( isglob ( id ) ) {
267
		if (isglob(id)) {
245
	      if(name(sh(w)) == prokhd){
268
			if (name(sh(w)) == prokhd) {
246
#if 1
269
#if 1
247
		  if(( son ( id ) == nilexp ||
270
				if ((son(id) == nilexp ||
248
		      name ( son ( id ) ) == proc_tag ||
271
				     name(son(id)) == proc_tag ||
249
                        name(son(id)) == general_proc_tag) )
272
				     name(son(id)) == general_proc_tag))
250
#endif
273
#endif
251
		    return ( make_ext ( id, d1 ) );
274
					return (make_ext(id, d1));
252
 
275
 
253
		}
276
			}
254
		return ( make_ext_ind ( id, d1 ) ) ;
277
			return (make_ext_ind(id, d1));
255
	    }
278
		}
256
 
279
 
-
 
280
		switch (ptno(id)) {
-
 
281
#ifndef tdf3
-
 
282
		case par2_pl:
-
 
283
			return (make_rel_ap2((d1 + d2 ) / 8));
-
 
284
		case par3_pl:
-
 
285
			return (make_rel_sp((d1 + d2 ) / 8));
-
 
286
#endif
-
 
287
		case par_pl:
-
 
288
			return (make_rel_ap((d1 + d2 + 32) / 8));
-
 
289
		case var_pl:
-
 
290
			return (make_rel_ap((d1 - d2) / 8));
-
 
291
		case reg_pl:
-
 
292
			return (make_register(reg(d2)));
-
 
293
		default:
-
 
294
			error(illegal_operand, 1);
-
 
295
			return (null);
-
 
296
		}
-
 
297
	}
-
 
298
	case cont_tag:
-
 
299
	case ass_tag: {
-
 
300
		exp r = son(w);
-
 
301
		switch (name(r)) {
-
 
302
		case name_tag: {
-
 
303
			exp id = son(r);
-
 
304
			if (!isvar(id)) {
-
 
305
				if (isglob(id)) {
-
 
306
					int ra;
-
 
307
					if (name(sh(w)) == prokhd) {
-
 
308
						if (off) {
-
 
309
							error(illegal_operand,
-
 
310
							      2);
-
 
311
						}
-
 
312
						return (make_ext_ind(id, no(r)));
-
 
313
					}
-
 
314
					op = make_ext_ind(id, off);
-
 
315
					ra = tmp_reg(m_movl, op);
-
 
316
					return (make_indirect(ra, no(r) / 8));
-
 
317
				}
257
	    switch ( ptno ( id ) ) {
318
				switch (ptno(id)) {
-
 
319
				case par_pl:
-
 
320
					d = no(id) + no(r) + 32;
-
 
321
					op = make_ind_rel_ap(d / 8, off / 8);
-
 
322
					return (op);
258
#ifndef tdf3
323
#ifndef tdf3
259
                case par2_pl : {
324
				case par2_pl:
-
 
325
					d = no(id) + no(r);
260
                    return ( make_rel_ap2 ( ( d1 + d2  ) / 8 ) ) ;
326
					op = make_ind_rel_ap2(d / 8, off / 8);
261
                }
327
					return (op);
262
                case par3_pl : {
328
				case par3_pl:
-
 
329
					d = no(id) + no(r);
263
                    return ( make_rel_sp ( ( d1 + d2  ) / 8 ) ) ;
330
					op = make_ind_rel_ap3(d / 8, off / 8);
264
                }
331
					return (op);
265
#endif
332
#endif
266
 
-
 
267
		case par_pl : {
-
 
268
		    return ( make_rel_ap ( ( d1 + d2 + 32 ) / 8 ) ) ;
-
 
269
		}
-
 
270
		case var_pl : {
333
				case var_pl:
271
		    return ( make_rel_ap ( ( d1 - d2 ) / 8 ) ) ;
-
 
272
		}
-
 
273
		case reg_pl : {
-
 
274
		    return ( make_register ( reg ( d2 ) ) ) ;
-
 
275
		}
-
 
276
		default : {
-
 
277
		    error ( illegal_operand, 1 ) ;
-
 
278
		    return ( null ) ;
-
 
279
		}
-
 
280
	    }
-
 
281
	}
-
 
282
 
-
 
283
	case cont_tag :
-
 
284
	case ass_tag : {
-
 
285
	    exp r = son ( w ) ;
-
 
286
	    switch ( name ( r ) ) {
-
 
287
 
-
 
288
		case name_tag : {
-
 
289
		    exp id = son ( r ) ;
-
 
290
		    if ( !isvar ( id ) ) {
-
 
291
			if ( isglob ( id ) ) {
-
 
292
			    int ra ;
-
 
293
			    if ( name ( sh ( w ) ) == prokhd ) {
-
 
294
				if ( off ) error ( illegal_operand, 2 ) ;
-
 
295
				return ( make_ext_ind ( id, no ( r ) ) ) ;
-
 
296
			    }
-
 
297
			    op = make_ext_ind ( id, off ) ;
-
 
298
			    ra = tmp_reg ( m_movl, op ) ;
-
 
299
			    return ( make_indirect ( ra, no ( r ) / 8 ) ) ;
-
 
300
			}
-
 
301
			switch ( ptno ( id ) ) {
-
 
302
			    case par_pl : {
-
 
303
				d = no ( id ) + no ( r ) + 32 ;
334
					d = - (no(id)) + no(r);
304
				op = make_ind_rel_ap ( d / 8, off / 8 ) ;
335
					op = make_ind_rel_ap(d / 8, off / 8);
305
				return ( op ) ;
336
					return (op);
306
			    }
-
 
307
#ifndef tdf3
-
 
308
			    case par2_pl : {
337
				case reg_pl:
309
				d = no ( id ) + no ( r ) ;
-
 
310
				op = make_ind_rel_ap2 ( d / 8, off / 8 ) ;
338
					return (make_ind(no(id), off));
311
				return ( op ) ;
-
 
312
			    }
339
				default:
313
			    case par3_pl : {
-
 
314
				d = no ( id ) + no ( r ) ;
340
					error(illegal_operand, 4);
315
				op = make_ind_rel_ap3 ( d / 8, off / 8 ) ;
-
 
316
				return ( op ) ;
341
					return (null);
317
			    }
342
				}
318
#endif
-
 
319
			    case var_pl : {
-
 
320
				d = -( no ( id ) ) + no ( r ) ;
-
 
321
				op = make_ind_rel_ap ( d / 8, off / 8 ) ;
-
 
322
				return ( op ) ;
-
 
323
			    }
343
			} else {
324
			    case reg_pl : {
344
				where new_w;
325
				return ( make_ind ( no ( id ), off ) ) ;
-
 
326
			    }
-
 
327
			    default : {
345
				new_w.wh_exp = r;
328
				error ( illegal_operand, 4 ) ;
346
				new_w.wh_off = off;
329
				return ( null ) ;
347
				return (operand(sz, new_w));
330
			    }
-
 
331
			}
348
			}
332
		    } else {
-
 
333
			where new_w ;
-
 
334
			new_w.wh_exp = r ;
-
 
335
			new_w.wh_off = off ;
-
 
336
			return ( operand ( sz, new_w ) ) ;
-
 
337
		    }
-
 
338
		}
349
		}
339
 
-
 
340
		case cont_tag : {
350
		case cont_tag: {
341
		    exp rr = son ( r ) ;
351
			exp rr = son(r);
342
                    int roff = 0;
352
			int roff = 0;
343
                    if (name (rr) == reff_tag){
353
			if (name(rr) == reff_tag) {
344
                      rr = son(rr);
354
				rr = son(rr);
345
                      roff = no(rr);
355
				roff = no(rr);
346
                    }
356
			}
347
		    switch ( name ( rr ) ) {
357
			switch (name(rr)) {
348
 
-
 
349
			case name_tag : {
358
			case name_tag: {
350
			    exp id = son ( rr ) ;
359
				exp id = son(rr);
351
#if 0
360
#if 0
352
			    if ( !isvar ( id ) ) {
361
				if (!isvar(id)) {
353
				error ( illegal_operand, 5 ) ;
362
					error(illegal_operand, 5);
354
				return ( null ) ;
363
					return (null);
355
			    }
364
				}
356
#endif
365
#endif
357
			    if ( isglob ( id ) ) {
366
				if (isglob(id)) {
358
				int ra ;
367
					int ra;
359
				op = make_ext_ind ( id, no ( rr ) ) ;
368
					op = make_ext_ind(id, no(rr));
360
				ra = tmp_reg ( m_movl, op ) ;
369
					ra = tmp_reg(m_movl, op);
361
				return ( make_indirect ( ra, off / 8 ) ) ;
370
					return (make_indirect(ra, off / 8));
362
			    }
-
 
363
			    switch ( ptno ( id ) ) {
-
 
364
				case par_pl : {
-
 
365
				    d = no ( id ) + no ( rr ) + 32 + roff ;
-
 
366
				    op = make_ind_rel_ap ( d / 8, off / 8 ) ;
-
 
367
				    return ( op ) ;
-
 
368
				}
371
				}
-
 
372
				switch (ptno(id)) {
-
 
373
				case par_pl:
-
 
374
					d = no(id) + no(rr) + 32 + roff;
-
 
375
					op = make_ind_rel_ap(d / 8, off / 8);
-
 
376
					return (op);
369
#ifndef tdf3
377
#ifndef tdf3
370
				case par2_pl : {
378
				case par2_pl:
371
				    d = no ( id ) + no ( rr ) ;
379
					d = no(id) + no(rr);
372
				    op = make_ind_rel_ap2 ( d / 8, off / 8 ) ;
380
					op = make_ind_rel_ap2(d / 8, off / 8);
373
				    return ( op ) ;
381
					return (op);
374
				}
-
 
375
				case par3_pl : {
382
				case par3_pl:
376
				    d = no ( id ) + no ( rr ) ;
383
					d = no(id) + no(rr);
377
				    op = make_ind_rel_ap3 ( d / 8, off / 8 ) ;
384
					op = make_ind_rel_ap3(d / 8, off / 8);
378
				    return ( op ) ;
385
					return (op);
379
				}
-
 
380
#endif
386
#endif
381
				case var_pl : {
387
				case var_pl:
382
				    d = -( no ( id ) ) + no ( rr ) + roff ;
388
					d = - (no(id)) + no(rr) + roff;
383
				    op = make_ind_rel_ap ( d / 8, off / 8 ) ;
389
					op = make_ind_rel_ap(d / 8, off / 8);
384
				    return ( op ) ;
390
					return (op);
-
 
391
				case reg_pl:
-
 
392
					return (make_ind(no(id), off));
-
 
393
				default:
-
 
394
					error(illegal_operand, 6);
-
 
395
					return (null);
-
 
396
				}
-
 
397
			}
-
 
398
			default:
-
 
399
				error(illegal_operand, 7);
-
 
400
				return (null);
-
 
401
			}
-
 
402
		}
-
 
403
		case reff_tag: {
-
 
404
			exp rr = son(r);
-
 
405
			switch (name(rr)) {
-
 
406
			case name_tag: {
-
 
407
				exp id = son(rr);
-
 
408
				if (isglob(id)) {
-
 
409
					int ra;
-
 
410
					op = make_ext_ind(id, 0);
-
 
411
					ra = tmp_reg(m_movl, op);
-
 
412
					return (make_indirect(ra, no(r) / 8));
385
				}
413
				}
-
 
414
				switch (ptno(id)) {
386
				case reg_pl : {
415
				case reg_pl:
-
 
416
					d = no(r) + off;
387
				    return ( make_ind ( no ( id ), off ) ) ;
417
					return (make_ind(no(id), d));
-
 
418
				case par2_pl:
-
 
419
				case par3_pl:
-
 
420
				case par_pl: {
-
 
421
					int ra;
-
 
422
					where new_w;
-
 
423
					new_w.wh_exp = id;
-
 
424
					new_w.wh_off = 0;
-
 
425
					op = operand(L32, new_w);
-
 
426
					ra = tmp_reg(m_movl, op);
-
 
427
					d = no(r) + off;
-
 
428
					return (make_indirect(ra, d / 8));
388
				}
429
				}
389
				default : {
430
				case var_pl: {
-
 
431
					int ra;
-
 
432
					where new_w;
-
 
433
					new_w.wh_exp = id;
-
 
434
					new_w.wh_off = 0;
-
 
435
					op = operand(L32, new_w);
390
				    error ( illegal_operand, 6 ) ;
436
					ra = tmp_reg(m_movl, op);
391
				    return ( null ) ;
437
					d = no(r) + off;
-
 
438
					return (make_indirect(ra, d / 8));
392
				}
439
				}
-
 
440
				default:
-
 
441
					error(illegal_operand, 8);
-
 
442
					return (null);
393
			    }
443
				}
-
 
444
			}
-
 
445
			case cont_tag: {
-
 
446
				exp rrr = son(rr);
-
 
447
				exp id = son(rrr);
-
 
448
				if (ptno(id) == reg_pl) {
-
 
449
					d = no(r) + off;
-
 
450
					return (make_ind(no(id), d));
-
 
451
				}
-
 
452
				if (ptno(id) == var_pl) {
-
 
453
					int ra;
-
 
454
					where new_w;
-
 
455
					new_w.wh_exp = id;
-
 
456
					new_w.wh_off = 0;
-
 
457
					op = operand(L32, new_w);
-
 
458
					ra = tmp_reg(m_movl, op);
-
 
459
					d = no(r) + off;
-
 
460
					return (make_indirect(ra, d / 8));
-
 
461
				}
-
 
462
				error(illegal_operand, 9);
-
 
463
				return (null);
394
			}
464
			}
-
 
465
			case addptr_tag: {
-
 
466
				where new_w;
-
 
467
				new_w.wh_exp = rr;
-
 
468
				new_w.wh_off = no(r) + off;
-
 
469
				return (operand(sz, new_w));
395
 
470
			}
396
			default : {
471
			default:
397
			    error ( illegal_operand, 7 ) ;
472
				error(illegal_operand, 10);
398
			    return ( null ) ;
473
				return (null);
399
			}
474
			}
400
		    }
-
 
401
		}
475
		}
-
 
476
		case addptr_tag: {
-
 
477
			where wb, wc;
-
 
478
			exp rr = son(r);
-
 
479
			exp eb = bro(rr);
-
 
480
			exp ec = simple_exp(cont_tag);
-
 
481
			son(ec) = rr;
-
 
482
			wb.wh_exp = eb;
-
 
483
			wb.wh_off = 0;
-
 
484
			wc.wh_exp = ec;
-
 
485
			wc.wh_off = off;
402
 
486
 
403
		case reff_tag : {
-
 
404
		    exp rr = son ( r ) ;
-
 
405
		    switch ( name ( rr ) ) {
487
			switch (name(eb)) {
406
 
-
 
407
			case name_tag : {
488
			case name_tag:
408
			    exp id = son ( rr ) ;
-
 
409
			    if ( isglob ( id ) ) {
-
 
410
				int ra ;
489
			case cont_tag:
411
				op = make_ext_ind ( id, 0 ) ;
490
				return (index_opnd(wc, wb, 1));
412
				ra = tmp_reg ( m_movl, op ) ;
491
			case offset_mult_tag: {
413
				return ( make_indirect ( ra, no ( r ) / 8 ) ) ;
492
				long k = no(bro(son(eb))) / 8;
414
			    }
-
 
415
			    switch ( ptno ( id ) ) {
493
				if (sz == 8 * k) {
416
				case reg_pl : {
494
					wb.wh_exp = son(eb);
417
				    d = no ( r ) + off ;
495
					wb.wh_off = 0;
418
				    return ( make_ind ( no ( id ), d ) ) ;
496
					return (index_opnd(wc, wb,(int)k));
419
				}
497
				}
420
                                case par2_pl:
-
 
421
                                case par3_pl:
-
 
422
                                case par_pl : {
-
 
423
				    int ra ;
-
 
424
				    where new_w ;
-
 
425
				    new_w.wh_exp = id ;
498
				error(illegal_operand, 11);
426
				    new_w.wh_off = 0 ;
-
 
427
				    op = operand ( L32, new_w ) ;
-
 
428
				    ra = tmp_reg ( m_movl, op ) ;
-
 
429
				    d = no ( r ) + off ;
-
 
430
				    return ( make_indirect ( ra, d / 8 ) ) ;
-
 
431
				}
-
 
432
				case var_pl : {
-
 
433
				    int ra ;
499
				return (null);
434
				    where new_w ;
-
 
435
				    new_w.wh_exp = id ;
-
 
436
				    new_w.wh_off = 0 ;
-
 
437
				    op = operand ( L32, new_w ) ;
-
 
438
				    ra = tmp_reg ( m_movl, op ) ;
-
 
439
				    d = no ( r ) + off ;
-
 
440
				    return ( make_indirect ( ra, d / 8 ) ) ;
-
 
441
				}
500
			}
442
				default : {
501
			default:
443
				    error ( illegal_operand, 8 ) ;
502
				error(illegal_operand, 12);
444
				    return ( null ) ;
503
				return (null);
445
				}
-
 
446
			    }
-
 
447
			}
504
			}
-
 
505
		}
-
 
506
		default:
-
 
507
			error(illegal_operand, 14);
-
 
508
			return (null);
-
 
509
		}
-
 
510
	}
-
 
511
	case dummy_tag: {
-
 
512
		exp r = son(w);
-
 
513
 
-
 
514
		switch (name(r)) {
-
 
515
		case ident_tag:
-
 
516
			/* This is used by m_lea */
-
 
517
			switch (ptno(r)) {
-
 
518
			case reg_pl:
-
 
519
				return (make_ind(no(r), no(w)));
-
 
520
			case var_pl: {
-
 
521
				int ra;
-
 
522
				where new_w;
-
 
523
				new_w.wh_exp = r;
-
 
524
				new_w.wh_off = 0;
-
 
525
				op = operand(L32, new_w);
-
 
526
				ra = tmp_reg(m_movl, op);
-
 
527
				d = no(w);
-
 
528
				return (make_indirect(ra, d / 8));
-
 
529
			}
-
 
530
			default:
-
 
531
				error(illegal_operand, 15);
-
 
532
				return (null);
-
 
533
			}
-
 
534
		case name_tag: {
-
 
535
			exp id = son(r);
-
 
536
			if (isglob(id)) {
-
 
537
				return (make_ext_ind(id, no(w)));
-
 
538
			}
-
 
539
			switch (ptno(id)) {
-
 
540
			case reg_pl:
-
 
541
				return (make_ind(no(id), no(w)));
-
 
542
			case var_pl: {
-
 
543
				int ra;
-
 
544
				where new_w;
-
 
545
				new_w.wh_exp = id;
-
 
546
				new_w.wh_off = 0;
-
 
547
				op = operand(L32, new_w);
-
 
548
				ra = tmp_reg(m_movl, op);
-
 
549
				d = no(w);
-
 
550
				return (make_indirect(ra, d / 8));
-
 
551
			}
-
 
552
			default:
-
 
553
				error(illegal_operand, 16);
-
 
554
				return (null);
-
 
555
			}
-
 
556
		}
-
 
557
		case cont_tag:
-
 
558
		case ass_tag: {
-
 
559
			exp rr = son(r);
-
 
560
			exp id = son(rr);
-
 
561
			if (isglob(id)) {
-
 
562
				return (make_ext_ind(id, no(w)));
-
 
563
			}
-
 
564
			switch (ptno(id)) {
-
 
565
			case reg_pl:
-
 
566
				return (make_ind(no(id), no(w)));
-
 
567
			case var_pl: {
-
 
568
				int ra;
-
 
569
				where new_w;
-
 
570
				new_w.wh_exp = id;
-
 
571
				new_w.wh_off = 0;
-
 
572
				op = operand(L32, new_w);
-
 
573
				ra = tmp_reg(m_movl, op);
-
 
574
				d = no(w);
-
 
575
				return (make_indirect(ra, d / 8));
-
 
576
			}
-
 
577
			default:
-
 
578
				error(illegal_operand, 17);
-
 
579
				return (null);
-
 
580
			}
-
 
581
		}
-
 
582
		case addptr_tag: {
-
 
583
			where new_w;
-
 
584
			new_w.wh_exp = r;
-
 
585
			new_w.wh_off = no(w) + off;
-
 
586
			return (operand(sz, new_w));
-
 
587
		}
-
 
588
		default:
-
 
589
			error(illegal_operand, 18);
-
 
590
			return (null);
-
 
591
		}
-
 
592
	}
-
 
593
	case reff_tag: {
-
 
594
		exp r = son(w);
448
 
595
 
449
			case cont_tag : {
596
		switch (name(r)) {
450
			    exp rrr = son ( rr ) ;
597
		case name_tag: {
451
			    exp id = son ( rrr ) ;
598
			exp id = son(r);
452
			    if ( ptno ( id ) == reg_pl ) {
-
 
453
				d = no ( r ) + off ;
-
 
454
				return ( make_ind ( no ( id ), d ) ) ;
-
 
455
			    }
-
 
456
			    if ( ptno ( id ) == var_pl ) {
599
			if (isglob(id)) {
457
				int ra ;
-
 
458
				where new_w ;
-
 
459
				new_w.wh_exp = id ;
-
 
460
				new_w.wh_off = 0 ;
-
 
461
				op = operand ( L32, new_w ) ;
-
 
462
				ra = tmp_reg ( m_movl, op ) ;
-
 
463
				d = no ( r ) + off ;
-
 
464
				return ( make_indirect ( ra, d / 8 ) ) ;
600
				return (make_ext(id, no(w)));
465
			    }
-
 
466
			    error ( illegal_operand, 9 ) ;
-
 
467
			    return ( null ) ;
-
 
468
			}
601
			}
469
 
-
 
470
			case addptr_tag : {
-
 
471
			    where new_w ;
-
 
472
			    new_w.wh_exp = rr ;
-
 
473
			    new_w.wh_off = no ( r ) + off ;
-
 
474
			    return ( operand ( sz, new_w ) ) ;
-
 
475
			}
-
 
476
 
-
 
477
			default : {
-
 
478
			    error ( illegal_operand, 10 ) ;
-
 
479
			    return ( null ) ;
-
 
480
			}
-
 
481
		    }
-
 
482
		}
-
 
483
 
-
 
484
		case addptr_tag : {
-
 
485
		    where wb, wc ;
-
 
486
		    exp rr = son ( r ) ;
-
 
487
		    exp eb = bro ( rr ) ;
-
 
488
		    exp ec = simple_exp ( cont_tag ) ;
-
 
489
		    son ( ec ) = rr ;
-
 
490
		    wb.wh_exp = eb ;
-
 
491
		    wb.wh_off = 0 ;
-
 
492
		    wc.wh_exp = ec ;
-
 
493
		    wc.wh_off = off ;
-
 
494
		    switch ( name ( eb ) ) {
-
 
495
 
-
 
496
			case name_tag :
-
 
497
			case cont_tag : {
-
 
498
			    return ( index_opnd ( wc, wb, 1 ) ) ;
-
 
499
			}
-
 
500
 
-
 
501
			case offset_mult_tag : {
-
 
502
			    long k = no ( bro ( son ( eb ) ) ) / 8 ;
-
 
503
			    if ( sz == 8 * k ) {
-
 
504
				wb.wh_exp = son ( eb ) ;
-
 
505
				wb.wh_off = 0 ;
-
 
506
				return ( index_opnd ( wc, wb, ( int ) k ) ) ;
-
 
507
			    }
-
 
508
			    error ( illegal_operand, 11 ) ;
-
 
509
			    return ( null ) ;
-
 
510
			}
-
 
511
 
-
 
512
			default : {
-
 
513
			    error ( illegal_operand, 12 ) ;
-
 
514
			    return ( null ) ;
-
 
515
			}
-
 
516
		    }
-
 
517
		}
-
 
518
 
-
 
519
		default : {
-
 
520
		    error ( illegal_operand, 14 ) ;
-
 
521
		    return ( null ) ;
-
 
522
		}
-
 
523
	    }
-
 
524
	}
-
 
525
 
-
 
526
	case dummy_tag : {
-
 
527
	    exp r = son ( w ) ;
-
 
528
	    switch ( name ( r ) ) {
-
 
529
 
-
 
530
		case ident_tag : {
-
 
531
		    /* This is used by m_lea */
-
 
532
		    switch ( ptno ( r ) ) {
602
			switch (ptno(id)) {
533
			case reg_pl : {
603
			case reg_pl:
534
			    return ( make_ind ( no ( r ), no ( w ) ) ) ;
-
 
535
			}
-
 
536
			case var_pl : {
-
 
537
			    int ra ;
604
				if (no(w)) {
538
			    where new_w ;
605
					int ra = reg(no(id));
539
			    new_w.wh_exp = r ;
606
					if (is_dreg(ra)) {
540
			    new_w.wh_off = 0 ;
-
 
541
			    op = operand ( L32, new_w ) ;
607
						op = make_register(ra);
542
			    ra = tmp_reg ( m_movl, op ) ;
608
						ra = tmp_reg(m_movl, op);
543
			    d = no ( w ) ;
-
 
544
			    return ( make_indirect ( ra, d / 8 ) ) ;
609
						add_to_reg(ra, no(w) / 8);
545
			}
-
 
546
			default : {
610
					} else {
547
			    error ( illegal_operand, 15 ) ;
-
 
548
			    return ( null ) ;
-
 
549
			}
-
 
550
		    }
-
 
551
		}
-
 
552
 
-
 
553
		case name_tag : {
-
 
554
		    exp id = son ( r ) ;
-
 
555
		    if ( isglob ( id ) ) {
-
 
556
			return ( make_ext_ind ( id, no ( w ) ) ) ;
611
						op = make_indirect(ra,
557
		    }
-
 
558
		    switch ( ptno ( id ) ) {
-
 
559
			case reg_pl : {
-
 
560
			    return ( make_ind ( no ( id ), no ( w ) ) ) ;
-
 
561
			}
-
 
562
			case var_pl : {
-
 
563
			    int ra ;
612
								   no(w) / 8);
564
			    where new_w ;
-
 
565
			    new_w.wh_exp = id ;
-
 
566
			    new_w.wh_off = 0 ;
-
 
567
			    op = operand ( L32, new_w ) ;
-
 
568
			    ra = tmp_reg ( m_movl, op ) ;
613
						ra = tmp_reg(m_lea, op);
569
			    d = no ( w ) ;
-
 
570
			    return ( make_indirect ( ra, d / 8 ) ) ;
-
 
571
			}
-
 
572
			default : {
-
 
573
			    error ( illegal_operand, 16 ) ;
-
 
574
			    return ( null ) ;
-
 
575
			}
614
					}
576
		    }
-
 
577
		}
-
 
578
 
-
 
579
		case cont_tag :
-
 
580
		case ass_tag : {
-
 
581
		    exp rr = son ( r ) ;
-
 
582
		    exp id = son ( rr ) ;
-
 
583
		    if ( isglob ( id ) ) {
-
 
584
			return ( make_ext_ind ( id, no ( w ) ) ) ;
615
					return (make_register(ra));
585
		    }
-
 
586
		    switch ( ptno ( id ) ) {
-
 
587
			case reg_pl : {
-
 
588
			    return ( make_ind ( no ( id ), no ( w ) ) ) ;
-
 
589
			}
616
				}
590
			case var_pl : {
-
 
591
			    int ra ;
-
 
592
			    where new_w ;
-
 
593
			    new_w.wh_exp = id ;
-
 
594
			    new_w.wh_off = 0 ;
-
 
595
			    op = operand ( L32, new_w ) ;
-
 
596
			    ra = tmp_reg ( m_movl, op ) ;
-
 
597
			    d = no ( w ) ;
617
				d = no(id);
598
			    return ( make_indirect ( ra, d / 8 ) ) ;
618
				return (make_register(reg(d)));
599
			}
-
 
600
			default : {
619
			default:
601
			    error ( illegal_operand, 17 ) ;
620
				error(illegal_operand, 19);
602
			    return ( null ) ;
621
				return (null);
603
			}
622
			}
604
		    }
-
 
605
		}
623
		}
606
 
-
 
607
		case addptr_tag : {
624
		case cont_tag:
608
		    where new_w ;
-
 
609
		    new_w.wh_exp = r ;
-
 
610
		    new_w.wh_off = no ( w ) + off ;
-
 
611
		    return ( operand ( sz, new_w ) ) ;
-
 
612
		}
-
 
613
 
-
 
614
		default : {
-
 
615
		    error ( illegal_operand, 18 ) ;
-
 
616
		    return ( null ) ;
-
 
617
		}
-
 
618
	    }
-
 
619
	}
-
 
620
 
-
 
621
	case reff_tag : {
625
		case ass_tag: {
622
	    exp r = son ( w ) ;
626
			exp rr = son(r);
623
	    switch ( name ( r ) ) {
-
 
624
 
-
 
625
		case name_tag : {
-
 
626
		    exp id = son ( r ) ;
627
			exp id = son(rr);
627
		    if ( isglob ( id ) ) {
628
			if (isglob(id)) {
628
			return ( make_ext ( id, no ( w ) ) ) ;
-
 
629
		    }
-
 
630
		    switch ( ptno ( id ) ) {
-
 
631
			case reg_pl : {
-
 
632
			    if ( no ( w ) ) {
629
				if (no(w)) {
633
				int ra = reg ( no ( id ) ) ;
-
 
634
				if ( is_dreg ( ra ) ) {
630
					int ra;
635
				    op = make_register ( ra ) ;
631
					op = make_ext_ind(id, 0);
636
				    ra = tmp_reg ( m_movl, op ) ;
632
					ra = tmp_reg(m_movl, op);
637
				    add_to_reg ( ra, no ( w ) / 8 ) ;
633
					add_to_reg(ra, no(w) / 8);
638
				} else {
-
 
639
				    op = make_indirect ( ra, no ( w ) / 8 ) ;
-
 
640
				    ra = tmp_reg ( m_lea, op ) ;
634
					return (make_register(ra));
641
				}
635
				}
642
				return ( make_register ( ra ) ) ;
636
				return (make_ext_ind(id, 0));
643
			    }
-
 
644
			    d = no ( id ) ;
-
 
645
			    return ( make_register ( reg ( d ) ) ) ;
-
 
646
			}
637
			}
647
			default : {
-
 
648
			    error ( illegal_operand, 19 ) ;
-
 
649
			    return ( null ) ;
-
 
650
			}
-
 
651
		    }
-
 
652
		}
-
 
653
 
-
 
654
		case cont_tag :
-
 
655
		case ass_tag : {
-
 
656
		    exp rr = son ( r ) ;
-
 
657
		    exp id = son ( rr ) ;
-
 
658
		    if ( isglob ( id ) ) {
-
 
659
			if ( no ( w ) ) {
-
 
660
			    int ra ;
-
 
661
			    op = make_ext_ind ( id, 0 ) ;
-
 
662
			    ra = tmp_reg ( m_movl, op ) ;
-
 
663
			    add_to_reg ( ra, no ( w ) / 8 ) ;
-
 
664
			    return ( make_register ( ra ) ) ;
-
 
665
			}
-
 
666
			return ( make_ext_ind ( id, 0 ) ) ;
-
 
667
		    }
-
 
668
		    switch ( ptno ( id ) ) {
638
			switch (ptno(id)) {
669
			case reg_pl : {
639
			case reg_pl:
670
			    debug_warning ( "reff - untested case" ) ;
640
				debug_warning("reff - untested case");
671
			    return ( make_ind ( no ( id ), no ( w ) ) ) ;
641
				return (make_ind(no(id), no(w)));
672
			}
-
 
673
			case var_pl : {
642
			case var_pl: {
674
			    int ra ;
643
				int ra;
675
			    where new_w ;
644
				where new_w;
676
			    new_w.wh_exp = id ;
645
				new_w.wh_exp = id;
677
			    new_w.wh_off = 0 ;
646
				new_w.wh_off = 0;
678
			    op = operand ( L32, new_w ) ;
647
				op = operand(L32, new_w);
679
			    ra = tmp_reg ( m_movl, op ) ;
648
				ra = tmp_reg(m_movl, op);
-
 
649
				if (no(w)) {
680
			    if ( no ( w ) ) add_to_reg ( ra, no ( w ) / 8 ) ;
650
					add_to_reg(ra, no(w) / 8);
-
 
651
				}
681
			    return ( make_register ( ra ) ) ;
652
				return (make_register(ra));
682
			}
653
			}
683
			default : {
654
			default:
684
			    error ( illegal_operand, 20 ) ;
655
				error(illegal_operand, 20);
685
			    return ( null ) ;
656
				return (null);
686
			}
657
			}
687
		    }
-
 
688
		}
658
		}
689
 
-
 
690
		case addptr_tag : {
659
		case addptr_tag: {
691
		    where new_w ;
660
			where new_w;
692
		    debug_warning ( "reff - untested case" ) ;
661
			debug_warning("reff - untested case");
693
		    new_w.wh_exp = r ;
662
			new_w.wh_exp = r;
694
		    new_w.wh_off = 0 ;
663
			new_w.wh_off = 0;
695
		    return ( operand ( sz, new_w ) ) ;
664
			return (operand(sz, new_w));
696
		}
665
		}
697
 
-
 
698
		default : {
666
		default:
699
		    error ( illegal_operand, 21 ) ;
667
			error(illegal_operand, 21);
700
		    return ( null ) ;
668
			return (null);
701
		}
669
		}
702
	    }
-
 
703
	}
670
	}
-
 
671
	case addptr_tag: {
-
 
672
		where wb, wc;
-
 
673
		exp r = son(w);
-
 
674
		exp eb = bro(r);
-
 
675
		exp ec = simple_exp(cont_tag);
-
 
676
		son(ec) = r;
-
 
677
		wb.wh_exp = eb;
-
 
678
		wb.wh_off = 0;
-
 
679
		wc.wh_exp = ec;
-
 
680
		wc.wh_off = off;
704
 
681
 
705
	case addptr_tag : {
-
 
706
	    where wb, wc ;
-
 
707
	    exp r = son ( w ) ;
-
 
708
	    exp eb = bro ( r ) ;
-
 
709
	    exp ec = simple_exp ( cont_tag ) ;
-
 
710
	    son ( ec ) = r ;
-
 
711
	    wb.wh_exp = eb ;
-
 
712
	    wb.wh_off = 0 ;
-
 
713
	    wc.wh_exp = ec ;
-
 
714
	    wc.wh_off = off ;
-
 
715
	    switch ( name ( eb ) ) {
682
		switch (name(eb)) {
716
 
-
 
717
		case name_tag :
683
		case name_tag:
718
		case cont_tag : {
684
		case cont_tag:
719
		    return ( index_opnd ( wc, wb, 1 ) ) ;
685
			return (index_opnd(wc, wb, 1));
720
		}
-
 
721
 
-
 
722
		case offset_mult_tag : {
686
		case offset_mult_tag: {
723
		    long k = no ( bro ( son ( eb ) ) ) / 8 ;
687
			long k = no(bro(son(eb))) / 8;
724
		    wb.wh_exp = son ( eb ) ;
688
			wb.wh_exp = son(eb);
725
		    wb.wh_off = 0 ;
689
			wb.wh_off = 0;
726
		    return ( index_opnd ( wc, wb, ( int ) k ) ) ;
690
			return (index_opnd(wc, wb,(int)k));
727
		}
691
		}
728
 
-
 
729
		default : {
692
		default:
730
		    error ( illegal_operand, 22 ) ;
693
			error(illegal_operand, 22);
731
		    return ( null ) ;
694
			return (null);
732
		}
695
		}
733
	    }
-
 
734
	}
696
	}
735
        case general_proc_tag:
697
	case general_proc_tag:
736
 
-
 
737
	case proc_tag : {
698
	case proc_tag: {
738
	    long lb = next_lab () ;
699
		long lb = next_lab();
739
	    make_constant ( lb, w ) ;
700
		make_constant(lb, w);
740
	    return ( make_lab ( lb, 0 ) ) ;
701
		return (make_lab(lb, 0));
741
	}
702
	}
742
 
-
 
743
	case real_tag :
703
	case real_tag:
744
	case string_tag : {
704
	case string_tag: {
745
	    long lb ;
705
		long lb;
746
	    if ( off == 0 ) {
706
		if (off == 0) {
747
		lb = next_lab () ;
707
			lb = next_lab();
748
		make_constant ( lb, w ) ;
708
			make_constant(lb, w);
749
		return ( make_lab_ind ( lb, 0 ) ) ;
709
			return (make_lab_ind(lb, 0));
750
	    }
710
		}
751
	    debug_warning ( "Offset from label" ) ;
711
		debug_warning("Offset from label");
752
	    return ( make_lab_ind ( no ( const_list ) + 1, off / 8 ) ) ;
712
		return (make_lab_ind(no(const_list) + 1, off / 8));
753
	}
-
 
754
 
-
 
755
	case res_tag : {
-
 
756
	    return ( make_lab_ind ( no ( w ), 0 ) ) ;
-
 
757
	}
-
 
758
 
-
 
759
	case null_tag : {
-
 
760
	    return ( make_value ( 0 ) ) ;
-
 
761
	}
713
	}
-
 
714
	case res_tag:
-
 
715
		return (make_lab_ind(no(w), 0));
-
 
716
	case null_tag:
-
 
717
		return (make_value(0));
762
#ifndef tdf3
718
#ifndef tdf3
763
        case apply_general_tag :
719
	case apply_general_tag:
764
        case tail_call_tag :
720
	case tail_call_tag:
765
#endif
721
#endif
766
	case apply_tag : {
722
	case apply_tag:
767
	    return ( make_dec_sp () ) ;
723
		return (make_dec_sp());
768
	}
-
 
769
 
-
 
770
	case field_tag : {
724
	case field_tag: {
771
	    where new_w ;
725
		where new_w;
772
	    new_w.wh_exp = son ( w ) ;
726
		new_w.wh_exp = son(w);
773
	    new_w.wh_off = no ( w ) + off ;
727
		new_w.wh_off = no(w) + off;
774
	    return ( operand ( sz, new_w ) ) ;
728
		return (operand(sz, new_w));
775
	}
729
	}
-
 
730
	case current_env_tag:
-
 
731
		return (make_register(REG_AP));
-
 
732
#ifndef tdf3
-
 
733
	case env_size_tag: {
-
 
734
		dec *dp = brog(son(son(w)));
-
 
735
		return (make_lab((long)dp, 0));
776
 
736
	}
777
	case current_env_tag : {
737
	case env_offset_tag: {
-
 
738
		exp ident_exp = son(w);
778
	    return ( make_register ( REG_AP ) ) ;
739
		return (make_lab((long)ident_exp, 0));
779
	}
740
	}
780
 
-
 
781
#ifndef tdf3
-
 
782
        case env_size_tag : {
-
 
783
           dec* dp = brog( son( son( w ) ) ) ;
-
 
784
           return  make_lab ( (long) dp, 0 ) ;
-
 
785
        }
-
 
786
 
-
 
787
        case env_offset_tag : {
-
 
788
           exp ident_exp = son ( w ) ;
-
 
789
           return  make_lab ( (long) ident_exp, 0 ) ;
-
 
790
        }
-
 
791
#else
741
#else
792
	case env_offset_tag : {
742
	case env_offset_tag: {
793
	    exp id = son ( w ) ;
743
		exp id = son(w);
794
	    switch ( ptno ( id ) ) {
744
		switch (ptno(id)) {
795
		case var_pl : {
745
		case var_pl:
796
		    d = no ( id ) - off ;
746
			d = no(id) - off;
797
		    return ( make_value ( -( d / 8 ) ) ) ;
747
			return (make_value(- (d / 8)));
798
		}
-
 
799
 
-
 
800
		case par2_pl :  {
748
		case par2_pl:
801
		    d = no ( id ) + off ;
749
			d = no(id) + off;
802
		    return ( make_value ( d / 8 ) ) ;
750
			return (make_value(d / 8));
803
		}
-
 
804
                case par3_pl :
751
		case par3_pl:
805
 
-
 
806
		case par_pl : {
752
		case par_pl:
807
		    d = no ( id ) + off + 32 ;
753
			d = no(id) + off + 32;
808
		    if(used_stack){
754
			if (used_stack) {
809
		      d += 32;
755
				d += 32;
810
		    }
756
			}
811
		    return ( make_value ( d / 8 ) ) ;
757
			return (make_value(d / 8));
812
		}
758
		}
813
	    }
-
 
814
	    error ( illegal_operand, 23 ) ;
759
		error(illegal_operand, 23);
815
	    return ( null ) ;
760
		return (null);
816
	}
761
	}
817
#endif
762
#endif
818
	case make_lv_tag : {
763
	case make_lv_tag:
819
	    return ( make_lab ( ptno ( pt ( son ( pt ( w ) ) ) ), 0 ) ) ;
764
		return (make_lab(ptno(pt(son(pt(w)))), 0));
-
 
765
	case local_free_all_tag:
-
 
766
		return (make_special_data("PA"));
-
 
767
	case internal_tag:
-
 
768
		return (make_lab_ind(no(w), off / 8));
-
 
769
	default:
-
 
770
		error(illegal_operand, 24);
-
 
771
		return (null);
820
	}
772
	}
-
 
773
}
-
 
774
 
821
 
775
 
822
	case local_free_all_tag : {
-
 
823
	    return ( make_special_data ( "PA" ) ) ;
-
 
824
	}
-
 
825
 
-
 
826
	case internal_tag : {
-
 
827
	    return ( make_lab_ind ( no ( w ), off / 8 ) ) ;
-
 
828
	}
-
 
829
 
-
 
830
	default : {
-
 
831
	    error ( illegal_operand, 24 ) ;
-
 
832
	    return ( null ) ;
-
 
833
	}
-
 
834
    }
-
 
835
}
-
 
836
 
-
 
837
 
-
 
838
/*
776
/*
839
    FIND WHICH REGISTERS ARE CHANGED IN AN OPERAND
777
    FIND WHICH REGISTERS ARE CHANGED IN AN OPERAND
840
 
778
 
841
    This routine returns the bitmask of all the registers changed in the
779
    This routine returns the bitmask of all the registers changed in the
842
    operand op.  c is true to indicate that the operand is being assigned
780
    operand op.  c is true to indicate that the operand is being assigned
843
    to.  If c is false, the only way op can change a register is if it is
781
    to.  If c is false, the only way op can change a register is if it is
844
    a pre-decrement or post-increment.
782
    a pre-decrement or post-increment.
845
*/
783
*/
846
 
784
 
847
bitpattern regs_changed
785
bitpattern
848
    PROTO_N ( ( op, c ) )
-
 
849
    PROTO_T ( mach_op *op X int c )
786
regs_changed(mach_op *op, int c)
850
{
787
{
851
    int t = op->type ;
788
	int t = op->type;
852
    if ( t == MACH_DEC || t == MACH_INC ) return ( regmsk ( op->def.num ) ) ;
789
	if (t == MACH_DEC || t == MACH_INC) {
-
 
790
		return (regmsk(op->def.num));
-
 
791
	}
-
 
792
	if (!c) {
853
    if ( !c ) return ( 0 ) ;
793
		return (0);
-
 
794
	}
-
 
795
	if (t == MACH_REG) {
854
    if ( t == MACH_REG ) return ( regmsk ( op->def.num ) ) ;
796
		return (regmsk(op->def.num));
-
 
797
	}
855
    if ( t == MACH_RPAIR ) {
798
	if (t == MACH_RPAIR) {
856
	return ( regmsk ( op->def.num ) | regmsk ( op->plus->def.num ) ) ;
799
		return (regmsk(op->def.num) | regmsk(op->plus->def.num));
857
    }
800
	}
858
    return ( 0 ) ;
801
	return (0);
859
}
802
}
860
 
803
 
861
 
804
 
862
/*
805
/*
863
    OUTPUT AN INSTRUCTION WITH NO OPERANDS
806
    OUTPUT AN INSTRUCTION WITH NO OPERANDS
864
 
807
 
865
    The instruction instr is created.
808
    The instruction instr is created.
866
*/
809
*/
867
 
810
 
868
void ins0
811
void
869
    PROTO_N ( ( instr ) )
-
 
870
    PROTO_T ( int instr )
812
ins0(int instr)
871
{
813
{
872
    make_instr ( instr, null, null, 0 ) ;
814
	make_instr(instr, null, null, 0);
873
    return ;
815
	return;
874
}
816
}
875
 
817
 
876
 
818
 
877
/*
819
/*
878
    OUTPUT AN INSTRUCTION WITH ONE OPERAND
820
    OUTPUT AN INSTRUCTION WITH ONE OPERAND
879
 
821
 
880
    The instruction instr with a single operand, a, of size asz is created.
822
    The instruction instr with a single operand, a, of size asz is created.
881
    a_changed is true to indicate that a is assigned to.
823
    a_changed is true to indicate that a is assigned to.
882
*/
824
*/
883
 
825
 
884
void ins1
826
void
885
    PROTO_N ( ( instr, asz, a, a_changed ) )
-
 
886
    PROTO_T ( int instr X long asz X where a X int a_changed )
827
ins1(int instr, long asz, where a, int a_changed)
887
{
828
{
888
    mach_op *op = operand ( asz, a ) ;
829
	mach_op *op = operand(asz, a);
889
    bitpattern ch = regs_changed ( op, a_changed ) ;
830
	bitpattern ch = regs_changed(op, a_changed);
890
    make_instr ( instr, op, null, ch ) ;
831
	make_instr(instr, op, null, ch);
891
    return ;
832
	return;
892
}
833
}
893
 
834
 
894
 
835
 
895
/*
836
/*
896
    OUTPUT AN INSTRUCTION WITH TWO OPERANDS
837
    OUTPUT AN INSTRUCTION WITH TWO OPERANDS
897
 
838
 
898
    The instruction instr with a two operands, a of size asz and b of size bsz,
839
    The instruction instr with a two operands, a of size asz and b of size bsz,
899
    is created.  b_changed is true to indicate that b is assigned to.
840
    is created.  b_changed is true to indicate that b is assigned to.
900
*/
841
*/
901
 
842
 
902
void ins2
843
void
903
    PROTO_N ( ( instr, asz, bsz, a, b, b_changed ) )
-
 
904
    PROTO_T ( int instr X long asz X long bsz X where a X where b X int b_changed )
844
ins2(int instr, long asz, long bsz, where a, where b, int b_changed)
905
{
845
{
906
    bitpattern ch ;
846
	bitpattern ch;
907
    mach_op *opa = operand ( asz, a ) ;
847
	mach_op *opa = operand(asz, a);
908
    mach_op *opb = operand ( bsz, b ) ;
848
	mach_op *opb = operand(bsz, b);
909
    ch = ( regs_changed ( opa, 0 ) | regs_changed ( opb, b_changed ) ) ;
849
	ch = (regs_changed(opa, 0) | regs_changed(opb, b_changed));
910
    make_instr ( instr, opa, opb, ch ) ;
850
	make_instr(instr, opa, opb, ch);
911
    return ;
851
	return;
912
}
852
}
913
 
853
 
914
 
854
 
915
/*
855
/*
916
    OUTPUT AN INSTRUCTION WITH TWO OPERANDS, ONE A CONSTANT
856
    OUTPUT AN INSTRUCTION WITH TWO OPERANDS, ONE A CONSTANT
917
 
857
 
918
    The instruction instr with a two operands, a constant c and a of size asz,
858
    The instruction instr with a two operands, a constant c and a of size asz,
919
    is created.  a_changed is true to indicate that a is assigned to.
859
    is created.  a_changed is true to indicate that a is assigned to.
920
*/
860
*/
921
 
861
 
922
void ins2n
862
void
923
    PROTO_N ( ( instr, c, asz, a, a_changed ) )
-
 
924
    PROTO_T ( int instr X long c X long asz X where a X int a_changed )
863
ins2n(int instr, long c, long asz, where a, int a_changed)
925
{
864
{
926
    mach_op *opc = make_value ( c ) ;
865
	mach_op *opc = make_value(c);
927
    mach_op *opa = operand ( asz, a ) ;
866
	mach_op *opa = operand(asz, a);
928
    bitpattern ch = regs_changed ( opa, a_changed ) ;
867
	bitpattern ch = regs_changed(opa, a_changed);
929
    make_instr ( instr, opc, opa, ch ) ;
868
	make_instr(instr, opc, opa, ch);
930
    return ;
869
	return;
931
}
870
}
932
 
871
 
933
 
872
 
934
/*
873
/*
935
    OUTPUT AN INSTRUCTION WITH TWO OPERANDS, ONE A HEX CONSTANT
874
    OUTPUT AN INSTRUCTION WITH TWO OPERANDS, ONE A HEX CONSTANT
936
 
875
 
937
    The instruction instr with a two operands, a constant c and a of size asz,
876
    The instruction instr with a two operands, a constant c and a of size asz,
938
    is created.  a_changed is true to indicate that a is assigned to.  This
877
    is created.  a_changed is true to indicate that a is assigned to.  This
939
    routine only differs from ins2n in that the constant will be output in
878
    routine only differs from ins2n in that the constant will be output in
940
    hex rather than decimal.
879
    hex rather than decimal.
941
*/
880
*/
942
 
881
 
943
void ins2h
882
void
944
    PROTO_N ( ( instr, c, asz, a, a_changed ) )
-
 
945
    PROTO_T ( int instr X long c X long asz X where a X int a_changed )
883
ins2h(int instr, long c, long asz, where a, int a_changed)
946
{
884
{
947
    mach_op *opc = make_hex_value ( c ) ;
885
	mach_op *opc = make_hex_value(c);
948
    mach_op *opa = operand ( asz, a ) ;
886
	mach_op *opa = operand(asz, a);
949
    bitpattern ch = regs_changed ( opa, a_changed ) ;
887
	bitpattern ch = regs_changed(opa, a_changed);
950
    make_instr ( instr, opc, opa, ch ) ;
888
	make_instr(instr, opc, opa, ch);
951
    return ;
889
	return;
-
 
890
}
-
 
891
 
-
 
892
void
-
 
893
save_stack(void)
-
 
894
{
-
 
895
	if (extra_stack || stack_dec) {
-
 
896
		error("unclean stack");
-
 
897
	}
-
 
898
	make_comment("Save stack pointer");
-
 
899
	ins2(m_movl, 32, 32, SP, firstlocal, 1);
952
}
900
}
953
 
901
 
954
void save_stack
902
void
955
    PROTO_Z ()
903
restore_stack(void)
956
{
904
{
957
  if (extra_stack || stack_dec)
905
	if (extra_stack || stack_dec) {
958
    error ("unclean stack");
906
		error("unclean stack");
959
  make_comment("Save stack pointer");
-
 
960
  ins2 (m_movl, 32, 32, SP, firstlocal, 1);
-
 
961
}
907
	}
962
 
-
 
963
void restore_stack
-
 
964
    PROTO_Z ()
-
 
965
{
-
 
966
  if (extra_stack || stack_dec)
-
 
967
    error ("unclean stack");
-
 
968
  make_comment("Restore stack pointer");
908
	make_comment("Restore stack pointer");
969
  ins2 (m_movl, 32, 32, firstlocal, SP, 1);
909
	ins2(m_movl, 32, 32, firstlocal, SP, 1);
970
}
910
}
971
 
911