Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 243

Warning: Undefined variable $n in /usr/local/www/websvn.planix.org/include/diff_util.php on line 247

Warning: Undefined variable $m in /usr/local/www/websvn.planix.org/include/diff_util.php on line 251
WebSVN – tendra.SVN – Diff – /branches/tendra5/src/installers/680x0/common/coder.c – Rev 5 and 6

Subversion Repositories tendra.SVN

Rev

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

Rev 5 Rev 6
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-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) 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 145... Line 175...
145
 
175
 
146
#if have_diagnostics
176
#if have_diagnostics
147
#include "xdb_basics.h"
177
#include "xdb_basics.h"
148
#endif
178
#endif
149
 
179
 
150
extern int do_peephole ;
180
extern int do_peephole;
151
extern int normal_version ;
181
extern int normal_version;
152
static int extra_weight = 0 ;
182
static int extra_weight = 0;
153
 
183
 
154
 
184
 
155
/*
185
/*
156
    ADD A SHAPE TO A THE STACK
186
    ADD A SHAPE TO A THE STACK
157
 
187
 
158
    Given an ash p, representing the stack, and a shape s, this procedure
188
    Given an ash p, representing the stack, and a shape s, this procedure
159
    returns the ast correponding to the new stack formed by adding s to the
189
    returns the ast correponding to the new stack formed by adding s to the
160
    old stack.
190
    old stack.
161
*/
191
*/
162
 
192
 
163
ast add_shape_to_stack
193
ast
164
    PROTO_N ( ( p, s ) )
-
 
165
    PROTO_T ( ash p X shape s )
194
add_shape_to_stack(ash p, shape s)
166
{
195
{
167
    ast res ;
196
	ast res;
168
    char n = name ( s ) ;
197
	char n = name(s);
169
    long sz = shape_size ( s ) ;
198
	long sz = shape_size(s);
170
    long adj = 0 ;
199
	long adj = 0;
171
    if ( n == scharhd || n == ucharhd || n == swordhd || n == uwordhd ) {
200
	if (n == scharhd || n == ucharhd || n == swordhd || n == uwordhd) {
172
	adj = SLONG_SZ - sz ;
201
		adj = SLONG_SZ - sz;
173
	sz = SLONG_SZ ;
202
		sz = SLONG_SZ;
174
    }
203
	}
175
    if ( n == bitfhd ) sz = SLONG_SZ ;
204
	if (n == bitfhd) {
-
 
205
		sz = SLONG_SZ;
-
 
206
	}
176
    res.astoff = round ( p, param_align ) ;
207
	res.astoff = round(p, param_align);
177
    res.astadj = adj ;
208
	res.astadj = adj;
178
    res.astash = round ( res.astoff + sz, param_align ) ;
209
	res.astash = round(res.astoff + sz, param_align);
179
    return ( res ) ;
210
	return (res);
180
}
211
}
181
 
212
 
182
 
213
 
183
/*
214
/*
184
    REGISTER ALLOCATION ROUTINES
215
    REGISTER ALLOCATION ROUTINES
Line 187... Line 218...
187
    gives the breakpoint - the minimum number of registers which need to
218
    gives the breakpoint - the minimum number of registers which need to
188
    be free for it to be worth putting this value in a register.  The big
219
    be free for it to be worth putting this value in a register.  The big
189
    flag is true to indicate that a register which is preserved across
220
    flag is true to indicate that a register which is preserved across
190
    procedure calls is required.  If a register can be allocated, then
221
    procedure calls is required.  If a register can be allocated, then
191
    its bitpattern is returned.  Otherwise 0 is returned.
222
    its bitpattern is returned.  Otherwise 0 is returned.
192
*/
223
*/
193
 
224
 
194
static bitpattern alloc_reg
225
static bitpattern
195
    PROTO_N ( ( sha, br, big ) )
-
 
196
    PROTO_T ( shape sha X int br X bool big )
226
alloc_reg(shape sha, int br, bool big)
197
{
227
{
198
    int go = 1 ;
228
	int go = 1;
199
    bitpattern mask ;
229
	bitpattern mask;
200
    bitpattern rs = regsinuse ;
230
	bitpattern rs = regsinuse;
201
    int i, start, end, rev = 0 ;
231
	int i, start, end, rev = 0;
202
 
232
 
203
    int rg ;
233
	int rg;
204
    int r = shtype ( sha ) ;
234
	int r = shtype(sha);
205
 
235
 
206
    if ( r == Dreg ) {
236
	if (r == Dreg) {
207
	rg = bits_in ( ~rs & 0x00fc ) ;
237
		rg = bits_in(~rs & 0x00fc);
208
	mask = regmsk ( REG_D2 ) ;
238
		mask = regmsk(REG_D2);
209
	start =  REG_D2 ;
239
		start =  REG_D2;
210
	end = REG_D7 ;
240
		end = REG_D7;
211
    } else if ( r == Areg ) {
241
	} else if (r == Areg) {
212
	rg = bits_in ( ~rs & 0x3c00 ) ;
242
		rg = bits_in(~rs & 0x3c00);
213
	mask = regmsk ( REG_A2 ) ;
243
		mask = regmsk(REG_A2);
214
	start = REG_A2 ;
244
		start = REG_A2;
215
	end = REG_A5 ;
245
		end = REG_A5;
216
	if ( br > extra_weight ) br -= extra_weight ;
246
		if (br > extra_weight) {
-
 
247
			br -= extra_weight;
-
 
248
		}
217
    } else if ( r == Freg ) {
249
	} else if (r == Freg) {
218
	if ( round_after_flop ) return ( 0 ) ;
250
		if (round_after_flop) {
-
 
251
			return (0);
-
 
252
		}
219
	rg = bits_in ( ~rs & 0xfc0000 ) ;
253
		rg = bits_in(~rs & 0xfc0000);
220
	mask = regmsk ( REG_FP7 ) ;
254
		mask = regmsk(REG_FP7);
221
	start = REG_FP7 ;
255
		start = REG_FP7;
222
	end = REG_FP2 ;
256
		end = REG_FP2;
223
	rev = 1 ;
257
		rev = 1;
224
    } else {
258
	} else {
225
	error ( "Illegal register type" ) ;
259
		error("Illegal register type");
226
	return ( 0 ) ;
260
		return (0);
227
    }
261
	}
228
 
262
 
229
    if ( rg < br || rg == 0 ) return ( 0 ) ;
263
	if (rg < br || rg == 0) {
-
 
264
		return (0);
-
 
265
	}
230
 
266
 
231
    i = start ;
267
	i = start;
232
    while ( go ) {
268
	while (go) {
233
	if ( !( rs & mask ) ) {
269
		if (!(rs & mask)) {
234
	    if ( big ) {
270
			if (big) {
235
		bigregs |= mask ;
271
				bigregs |= mask;
-
 
272
				if (r == Freg) {
236
		if ( r == Freg ) normal_version = 0 ;
273
					normal_version = 0;
237
	    }
274
				}
-
 
275
			}
238
	    regsinproc |= mask ;
276
			regsinproc |= mask;
239
	    return ( mask ) ;
277
			return (mask);
240
	}
278
		}
241
	if ( i == end ) {
279
		if (i == end) {
242
	    go = 0 ;
280
			go = 0;
243
	} else {
281
		} else {
244
	    if ( rev ) {
282
			if (rev) {
245
		i-- ;
283
				i--;
246
		mask >>= 1 ;
284
				mask >>= 1;
247
	    } else {
285
			} else {
248
		i++ ;
286
				i++;
249
		mask <<= 1 ;
287
				mask <<= 1;
250
	    }
288
			}
251
	}
289
		}
252
    }
290
	}
253
    return ( 0 ) ;
291
	return (0);
254
}
292
}
255
 
293
 
256
 
294
 
257
/*
295
/*
258
    IS A GIVEN EXPRESSION A USE OF A REUSABLE REGISTER?
296
    IS A GIVEN EXPRESSION A USE OF A REUSABLE REGISTER?
259
 
297
 
260
    This routine returns 0 if the expression e is not a use of a reuseable
298
    This routine returns 0 if the expression e is not a use of a reuseable
261
    register, and the bitmask of the register otherwise.
299
    register, and the bitmask of the register otherwise.
262
*/
300
*/
263
 
301
 
264
static long reuse_check
-
 
265
    PROTO_N ( ( e ) )
-
 
266
    PROTO_T ( exp e )
-
 
267
{
-
 
268
    exp id ;
-
 
269
    if ( name ( e ) != name_tag ) return ( 0 ) ;
-
 
270
    id = son ( e ) ;
-
 
271
    if ( isglob ( id ) || pt ( id ) != reg_pl ) return ( 0 ) ;
-
 
272
    return ( reuseables & no ( id ) ) ;
-
 
273
}
-
 
274
 
-
 
275
 
-
 
276
/*
-
 
277
    CAN WE REUSE A REGISTER?
-
 
278
 
-
 
279
    This routine checks whether or not we can use a reuseable register to
-
 
280
    store def.  It returns the bitmask of a suitable register if so and 0
-
 
281
    otherwise.
-
 
282
*/
-
 
283
 
-
 
284
static long reuse
302
static long
285
    PROTO_N ( ( def ) )
-
 
286
    PROTO_T ( exp def )
303
reuse_check(exp e)
287
{
304
{
288
    switch ( name ( def ) ) {
305
	exp id;
289
 
-
 
290
	case name_tag : {
306
	if (name(e) != name_tag) {
291
	    return ( reuse_check ( def ) ) ;
307
		return (0);
292
	}
308
	}
-
 
309
	id = son(e);
-
 
310
	if (isglob(id) || pt(id) != reg_pl) {
-
 
311
		return (0);
-
 
312
	}
-
 
313
	return (reuseables & no(id));
-
 
314
}
-
 
315
 
-
 
316
 
-
 
317
/*
-
 
318
    CAN WE REUSE A REGISTER?
-
 
319
 
-
 
320
    This routine checks whether or not we can use a reuseable register to
-
 
321
    store def.  It returns the bitmask of a suitable register if so and 0
-
 
322
    otherwise.
-
 
323
*/
293
 
324
 
-
 
325
static long
-
 
326
reuse(exp def)
-
 
327
{
-
 
328
	switch (name(def)) {
-
 
329
	case name_tag:
-
 
330
		return (reuse_check(def));
294
	case plus_tag :
331
	case plus_tag:
295
	case and_tag :
332
	case and_tag:
296
	case or_tag :
333
	case or_tag:
297
	case xor_tag :
334
	case xor_tag:
298
	case mult_tag : {
335
	case mult_tag: {
299
	    /* Allow at most two arguments - check both */
336
		/* Allow at most two arguments - check both */
300
	    exp arg1 = son ( def ) ;
337
		exp arg1 = son(def);
301
	    exp arg2 = bro ( arg1 ) ;
338
		exp arg2 = bro(arg1);
302
	    if ( last ( arg1 ) ) {
339
		if (last(arg1)) {
303
		return ( reuse_check ( arg1 ) ) ;
340
			return (reuse_check(arg1));
304
	    }
341
		}
305
	    if ( last ( arg2 ) ) {
342
		if (last(arg2)) {
306
		return ( reuse_check ( arg1 ) || reuse_check ( arg2 ) ) ;
343
			return (reuse_check(arg1) || reuse_check(arg2));
307
	    }
344
		}
308
	    return ( 0 ) ;
345
		return (0);
309
	}
346
	}
310
 
-
 
311
	case chvar_tag :
347
	case chvar_tag:
312
	case neg_tag :
348
	case neg_tag:
313
	case not_tag : {
349
	case not_tag:
314
	    /* Check one argument */
350
		/* Check one argument */
315
	    return ( reuse_check ( son ( def ) ) ) ;
351
		return (reuse_check(son(def)));
-
 
352
	case minus_tag:
-
 
353
	case subptr_tag:
-
 
354
	case minptr_tag:
-
 
355
	case shl_tag:
-
 
356
	case shr_tag: {
-
 
357
		/* Check two arguments */
-
 
358
		exp arg1 = son(def);
-
 
359
		exp arg2 = bro(arg1);
-
 
360
		return (reuse_check(arg1) || reuse_check(arg2));
316
	}
361
	}
317
 
-
 
318
	case minus_tag :
-
 
319
	case subptr_tag :
-
 
320
	case minptr_tag :
-
 
321
	case shl_tag :
-
 
322
	case shr_tag : {
-
 
323
	    /* Check two arguments */
-
 
324
	    exp arg1 = son ( def ) ;
-
 
325
	    exp arg2 = bro ( arg1 ) ;
-
 
326
	    return ( reuse_check ( arg1 ) || reuse_check ( arg2 ) ) ;
-
 
327
	}
362
	}
328
    }
-
 
329
    return ( 0 ) ;
363
	return (0);
330
}
364
}
331
 
365
 
332
 
366
 
333
/*
367
/*
334
    IS AN EXPRESSION GUARANTEED NOT TO USE D0?
368
    IS AN EXPRESSION GUARANTEED NOT TO USE D0?
335
 
369
 
336
    Or if it is, are we really careful?
370
    Or if it is, are we really careful?
337
*/
371
*/
338
 
372
 
339
static bool nouse
373
static bool
340
    PROTO_N ( ( e ) )
-
 
341
    PROTO_T ( exp e )
374
nouse(exp e)
342
{
375
{
343
    char n = name ( e ) ;
376
	char n = name(e);
344
    if ( n == test_tag ) return ( 1 ) ;
377
	if (n == test_tag) {
-
 
378
		return (1);
-
 
379
	}
345
    return ( 0 ) ;
380
	return (0);
346
}
381
}
347
 
382
 
348
 
383
 
349
/*
384
/*
350
    WHERE IS A DECLARATION TO BE PUT?
385
    WHERE IS A DECLARATION TO BE PUT?
Line 358... Line 393...
358
    registers).  new_stack gives the ash of the stack after this declaration.
393
    registers).  new_stack gives the ash of the stack after this declaration.
359
    is_new is a flag indicating a new declaration or a reuse of an old
394
    is_new is a flag indicating a new declaration or a reuse of an old
360
    declaration.
395
    declaration.
361
*/
396
*/
362
 
397
 
363
static allocation alloc_variable
398
static allocation
364
    PROTO_N ( ( e, def, stack ) )
-
 
365
    PROTO_T ( exp e X exp def X ash stack )
399
alloc_variable(exp e, exp def, ash stack)
366
{
400
{
367
    ast locast ;
401
	ast locast;
368
    allocation dc ;
402
	allocation dc;
369
    bitpattern ru ;
403
	bitpattern ru;
370
 
404
 
371
    unsigned char n = name ( def ) ;
405
	unsigned char n = name(def);
372
    exp s = son ( def ) ;
406
	exp s = son(def);
373
    exp body = bro ( def ) ;
407
	exp body = bro(def);
374
    int br = ( int ) no ( e ) ;
408
	int br = (int)no(e);
375
 
409
 
376
    bool force_reg = isusereg ( e ) ;
410
	bool force_reg = isusereg(e);
377
    bool big = ( props ( e ) & 0x80 ? 1 : 0 ) ;
411
	bool big = (props(e) & 0x80 ? 1 : 0);
378
    bool in_reg1 = 0, in_reg2 = 0, in_reg3 = 1 ;
412
	bool in_reg1 = 0, in_reg2 = 0, in_reg3 = 1;
379
 
413
 
380
    dc.new_stack = stack ;
414
	dc.new_stack = stack;
381
    dc.is_new = 1 ;
415
	dc.is_new = 1;
382
 
416
 
383
    if ( name ( sh ( def ) ) == tophd && !isvis(e)) {
417
	if (name(sh(def)) == tophd && !isvis(e)) {
384
	dc.place = nowhere_pl ;
418
		dc.place = nowhere_pl;
385
	dc.num = 0 ;
419
		dc.num = 0;
386
	return ( dc ) ;
420
		return (dc);
387
    }
421
	}
388
 
422
 
389
    if ( n == name_tag ) {
423
	if (n == name_tag) {
390
	in_reg1 = ( !isvar ( s ) && ( no ( def ) == 0 || !isglob ( s ) ) ) ;
424
		in_reg1 = (!isvar(s) && (no(def) == 0 || !isglob(s)));
391
    } else if ( n == cont_tag && name ( s ) == name_tag ) {
425
	} else if (n == cont_tag && name(s) == name_tag) {
392
	exp t = son ( s ) ;
426
		exp t = son(s);
393
	in_reg2 = ( isvar ( t ) && ( no ( s ) == 0 || !isglob ( t ) ) &&
427
		in_reg2 = (isvar(t) && (no(s) == 0 || !isglob(t)) &&
394
		    no_side ( body ) ) ;
428
			   no_side(body));
395
    }
429
	}
396
 
430
 
397
    if ( !isvar ( e ) && ( in_reg1 || in_reg2 ) ) {
431
	if (!isvar(e) && (in_reg1 || in_reg2)) {
398
 
432
 
399
	/* Re-identification or contents of variable not altered in body */
433
		/* Re-identification or contents of variable not altered in
-
 
434
		 * body */
400
	if ( in_reg1 ) {
435
		if (in_reg1) {
401
	    dc.place = ptno ( s ) ;
436
			dc.place = ptno(s);
402
#ifndef tdf3
437
#ifndef tdf3
403
            switch ( ptno (s) ) {
438
			switch (ptno(s)) {
404
            case var_pl:
439
			case var_pl:
405
		dc.num = no ( s ) - no ( def ) ;
440
				dc.num = no(s) - no(def);
406
                break;
441
				break;
407
 
-
 
408
            case par3_pl:
442
			case par3_pl:
409
            case par2_pl:
443
			case par2_pl:
410
		dc.num = no ( s ) - no ( def ) ;
444
				dc.num = no(s) - no(def);
411
                break;
445
				break;
412
 
-
 
413
            default:
446
			default:
414
		dc.num = no ( s ) + no ( def ) ;
447
				dc.num = no(s) + no(def);
415
            }
448
			}
416
#else
449
#else
417
	    if ( ptno ( s ) == var_pl ) {
450
			if (ptno(s) == var_pl) {
418
		dc.num = no ( s ) - no ( def ) ;
451
				dc.num = no(s) - no(def);
419
	    } else {
452
			} else {
420
		dc.num = no ( s ) + no ( def ) ;
453
				dc.num = no(s) + no(def);
421
	    }
454
			}
422
#endif
455
#endif
423
 
-
 
424
	} else {
-
 
425
	    s = son ( s ) ;
-
 
426
	    dc.place = ptno ( s ) ;
-
 
427
	    if ( ptno ( s ) == var_pl ) {
-
 
428
		dc.num = no ( s ) - no ( son ( def ) ) ;
-
 
429
	    } else {
-
 
430
		dc.num = no ( s ) + no ( son ( def ) ) ;
-
 
431
	    }
-
 
432
	}
-
 
433
 
-
 
434
	/* We have a declaration */
-
 
435
	if ( dc.place == reg_pl ) {
-
 
436
	    /* If the old one was in registers, reuse it */
-
 
437
	    dc.is_new = 0 ;
-
 
438
	    return ( dc ) ;
-
 
439
	}
-
 
440
 
-
 
441
	if ( !force_reg ) {
-
 
442
	    if ( regable ( e ) ) {
-
 
443
		ru = alloc_reg ( sh ( def ), br, big ) ;
-
 
444
		if ( ru ) {
-
 
445
		    dc.place = reg_pl ;
-
 
446
		    dc.num = ru ;
-
 
447
		    return ( dc ) ;
-
 
448
		}
-
 
449
	    }
-
 
450
	    if ( isglob ( s ) ) {
-
 
451
		locast = add_shape_to_stack ( stack, sh ( def ) ) ;
-
 
452
		dc.new_stack = locast.astash ;
-
 
453
		dc.place = var_pl ;
-
 
454
		if ( locast.astadj ) {
-
 
455
		    dc.num = locast.astoff + locast.astadj ;
-
 
456
		} else {
456
		} else {
-
 
457
			s = son(s);
-
 
458
			dc.place = ptno(s);
-
 
459
			if (ptno(s) == var_pl) {
-
 
460
				dc.num = no(s) - no(son(def));
-
 
461
			} else {
-
 
462
				dc.num = no(s) + no(son(def));
-
 
463
			}
-
 
464
		}
-
 
465
 
-
 
466
		/* We have a declaration */
-
 
467
		if (dc.place == reg_pl) {
-
 
468
			/* If the old one was in registers, reuse it */
-
 
469
			dc.is_new = 0;
-
 
470
			return (dc);
-
 
471
		}
-
 
472
 
-
 
473
		if (!force_reg) {
-
 
474
			if (regable(e)) {
-
 
475
				ru = alloc_reg(sh(def), br, big);
-
 
476
				if (ru) {
-
 
477
					dc.place = reg_pl;
-
 
478
					dc.num = ru;
-
 
479
					return (dc);
-
 
480
				}
-
 
481
			}
-
 
482
			if (isglob(s)) {
-
 
483
				locast = add_shape_to_stack(stack, sh(def));
-
 
484
				dc.new_stack = locast.astash;
-
 
485
				dc.place = var_pl;
-
 
486
				if (locast.astadj) {
-
 
487
					dc.num = locast.astoff + locast.astadj;
-
 
488
				} else {
457
		    dc.num = locast.astash ;
489
					dc.num = locast.astash;
458
		}
490
				}
459
		return ( dc ) ;
491
				return (dc);
460
	    }
492
			}
461
	    /* If there was not room, reuse the old dec */
493
			/* If there was not room, reuse the old dec */
462
	    dc.is_new = 0 ;
494
			dc.is_new = 0;
463
	    return ( dc ) ;
495
			return (dc);
464
	}
496
		}
465
 
497
 
466
	if ( regable ( e ) ) {
498
		if (regable(e)) {
467
	    ru = alloc_reg ( sh ( def ), br, big ) ;
499
			ru = alloc_reg(sh(def), br, big);
468
	    if ( ru ) {
500
			if (ru) {
469
		dc.place = reg_pl ;
501
				dc.place = reg_pl;
470
		dc.num = ru ;
502
				dc.num = ru;
471
		return ( dc ) ;
503
				return (dc);
472
	    }
504
			}
473
	    if ( isglob ( s ) ) {
505
			if (isglob(s)) {
474
		locast = add_shape_to_stack ( stack, sh ( def ) ) ;
506
				locast = add_shape_to_stack(stack, sh(def));
475
		dc.new_stack = locast.astash ;
507
				dc.new_stack = locast.astash;
476
		dc.place = var_pl ;
508
				dc.place = var_pl;
477
		if ( locast.astadj ) {
509
				if (locast.astadj) {
478
		    dc.num = locast.astoff + locast.astadj ;
510
					dc.num = locast.astoff + locast.astadj;
479
		} else {
511
				} else {
480
		    dc.num = locast.astash ;
512
					dc.num = locast.astash;
-
 
513
				}
-
 
514
				return (dc);
-
 
515
			}
-
 
516
			dc.is_new = 0;
-
 
517
			return (dc);
-
 
518
		}
-
 
519
		return (dc);
-
 
520
	}
-
 
521
 
-
 
522
	if (n == apply_tag || n == apply_general_tag || n == tail_call_tag) {
-
 
523
		in_reg3 = result_in_reg(sh(def));
-
 
524
	}
-
 
525
 
-
 
526
	/* Try to allocate in registers */
-
 
527
	if (regable(e) && in_reg3) {
-
 
528
		if ((n == apply_tag || n == apply_general_tag ||
-
 
529
		     n == tail_call_tag) && shtype(sh(def)) != Freg &&
-
 
530
		    nouse(bro(def))) {
-
 
531
			dc.place = reg_pl;
-
 
532
			dc.num = regmsk(REG_D0);
-
 
533
			return (dc);
-
 
534
		}
-
 
535
		if (is_a(n)) {
-
 
536
			long rg = reuse(def) & 0x3cfc;
-
 
537
			if (rg) {
-
 
538
				reuseables &= ~rg;
-
 
539
				dc.place = reg_pl;
-
 
540
				dc.num = rg;
-
 
541
				return (dc);
-
 
542
			}
-
 
543
		}
-
 
544
		ru = alloc_reg(sh(def), br, big);
-
 
545
		if (ru) {
-
 
546
			dc.place = reg_pl;
-
 
547
			dc.num = ru;
-
 
548
			return (dc);
481
		}
549
		}
482
		return ( dc ) ;
-
 
483
	    }
-
 
484
	    dc.is_new = 0 ;
-
 
485
	    return ( dc ) ;
-
 
486
	}
550
	}
487
	return ( dc ) ;
-
 
488
    }
-
 
489
 
551
 
490
    if ( n == apply_tag || n == apply_general_tag || n == tail_call_tag )
-
 
491
    in_reg3 = result_in_reg ( sh ( def ) ) ;
-
 
492
 
-
 
493
    /* Try to allocate in registers */
552
	/* Otherwise allocate on the stack */
494
    if ( regable ( e ) && in_reg3 ) {
553
	locast = add_shape_to_stack(stack, sh(def));
495
	if ( ( n == apply_tag || n == apply_general_tag || n == tail_call_tag )
554
	dc.new_stack = locast.astash;
496
            && shtype ( sh ( def ) ) != Freg && nouse ( bro ( def ) ) ) {
-
 
497
	    dc.place = reg_pl ;
555
	dc.place = var_pl;
498
	    dc.num = regmsk ( REG_D0 ) ;
-
 
499
	    return ( dc ) ;
-
 
500
	}
-
 
501
	if ( is_a ( n ) ) {
556
	if (locast.astadj) {
502
	    long rg = reuse ( def ) & 0x3cfc ;
557
		dc.num = locast.astoff + locast.astadj;
503
	    if ( rg ) {
558
	} else {
504
		reuseables &= ~rg ;
-
 
505
		dc.place = reg_pl ;
-
 
506
		dc.num = rg ;
559
		dc.num = locast.astash;
507
		return ( dc ) ;
-
 
508
	    }
-
 
509
	}
560
	}
510
	ru = alloc_reg ( sh ( def ), br, big ) ;
-
 
511
	if ( ru ) {
-
 
512
	    dc.place = reg_pl ;
-
 
513
	    dc.num = ru ;
-
 
514
	    return ( dc ) ;
561
	return (dc);
515
	}
-
 
516
    }
-
 
517
 
-
 
518
    /* Otherwise allocate on the stack */
-
 
519
    locast = add_shape_to_stack ( stack, sh ( def ) ) ;
-
 
520
    dc.new_stack = locast.astash ;
-
 
521
    dc.place = var_pl ;
-
 
522
    if ( locast.astadj ) {
-
 
523
	dc.num = locast.astoff + locast.astadj ;
-
 
524
    } else {
-
 
525
	dc.num = locast.astash ;
-
 
526
    }
-
 
527
    return ( dc ) ;
-
 
528
}
562
}
529
 
563
 
530
 
564
 
531
/*
565
/*
532
    CURRENT SCOPES
566
    CURRENT SCOPES
533
 
567
 
534
    These variables are used for the scope and destination of inlined
568
    These variables are used for the scope and destination of inlined
535
    procedures.
569
    procedures.
536
*/
570
*/
537
 
571
 
538
static exp crt_rscope ;
572
static exp crt_rscope;
539
static where rscope_dest ;
573
static where rscope_dest;
540
 
574
 
541
 
575
 
542
 
576
 
543
 
577
 
544
/*
578
/*
Line 546... Line 580...
546
 
580
 
547
    The arguments are given by a bro-list starting with t.  They are
581
    The arguments are given by a bro-list starting with t.  They are
548
    coded in reverse order.
582
    coded in reverse order.
549
*/
583
*/
550
 
584
 
551
static void code_pars
585
static void
552
    PROTO_N ( ( w, stack, t ) )
-
 
553
    PROTO_T ( where w X ash stack X exp t )
586
code_pars(where w, ash stack, exp t)
554
{
587
{
555
    long sz = shape_size ( sh ( t ) ) ;
588
	long sz = shape_size(sh(t));
556
    if ( last ( t ) ) {
589
	if (last(t)) {
557
	/* Code last argument */
590
		/* Code last argument */
558
	coder ( w, stack, t ) ;
591
		coder(w, stack, t);
559
	stack_dec -= round ( sz, param_align ) ;
592
		stack_dec -= round(sz, param_align);
560
    } else {
593
	} else {
561
	/* Code the following arguments */
594
		/* Code the following arguments */
562
	code_pars ( w, stack, bro ( t ) ) ;
595
		code_pars(w, stack, bro(t));
563
	/* And then this one */
596
		/* And then this one */
564
	coder ( w, stack, t ) ;
597
		coder(w, stack, t);
565
	stack_dec -= round ( sz, param_align ) ;
598
		stack_dec -= round(sz, param_align);
566
    }
599
	}
567
    return ;
600
	return;
568
}
601
}
569
 
602
 
570
 
603
 
571
/*
604
/*
572
    PRODUCE CODE FOR A SOLVE STATEMENT
605
    PRODUCE CODE FOR A SOLVE STATEMENT
573
 
606
 
574
    The solve statement with starter s, labelled statements l, destination
607
    The solve statement with starter s, labelled statements l, destination
575
    dest and default jump jr is processed.
608
    dest and default jump jr is processed.
576
*/
609
*/
577
 
610
 
578
static void solve
611
static void
579
    PROTO_N ( ( s, l, dest, jr, stack ) )
-
 
580
    PROTO_T ( exp s X exp l X where dest X exp jr X ash stack )
612
solve(exp s, exp l, where dest, exp jr, ash stack)
581
{
613
{
582
    exp t ;
614
	exp t;
583
    long r1 ;
615
	long r1;
584
 
616
 
585
    while ( !last ( l ) ) {
617
	while (!last(l)) {
586
	allocation dc ;
618
		allocation dc;
587
	long lb = next_lab () ;
619
		long lb = next_lab();
588
	exp record = simple_exp ( 0 ) ;
620
		exp record = simple_exp(0);
589
	if ( props ( son ( bro ( l ) ) ) & 2 ) setlast ( record ) ;
621
		if (props(son(bro(l))) & 2) {
-
 
622
			setlast(record);
-
 
623
		}
590
	no ( record ) = stack ;
624
		no(record) = stack;
591
	sonno ( record ) = stack_dec ;
625
		sonno(record) = stack_dec;
592
	ptno ( record ) = lb ;
626
		ptno(record) = lb;
593
	pt ( son ( bro ( l ) ) ) = record ;
627
		pt(son(bro(l))) = record;
594
	dc = alloc_variable ( bro ( l ), son ( bro ( l ) ), stack ) ;
628
		dc = alloc_variable(bro(l), son(bro(l)), stack);
595
	ptno ( bro ( l ) ) = dc.place ;
629
		ptno(bro(l)) = dc.place;
596
	no ( bro ( l ) ) = dc.num ;
630
		no(bro(l)) = dc.num;
597
	l = bro ( l ) ;
631
		l = bro(l);
598
    }
632
	}
599
 
633
 
600
    r1 = regsinuse ;
634
	r1 = regsinuse;
601
 
635
 
602
    if ( name ( s ) != goto_tag || pt ( s ) != bro ( s ) ) {
636
	if (name(s) != goto_tag || pt(s) != bro(s)) {
603
	/* Code the starting expression */
637
		/* Code the starting expression */
604
	have_cond = 0 ;
638
		have_cond = 0;
605
	coder ( dest, stack, s ) ;
639
		coder(dest, stack, s);
606
    }
640
	}
607
    t = s ;
641
	t = s;
608
 
642
 
609
    do {
643
	do {
610
	regsinuse = r1 ;
644
		regsinuse = r1;
-
 
645
		if (name(sh(t)) != bothd) {
611
	if ( name ( sh ( t ) ) != bothd ) make_jump ( m_bra, ptno ( jr ) ) ;
646
			make_jump(m_bra, ptno(jr));
-
 
647
		}
612
	t = bro ( t ) ;
648
		t = bro(t);
613
	if ( no ( son ( t ) ) > 0 ) {
649
		if (no(son(t)) > 0) {
614
	    make_label ( ptno ( pt ( son ( t ) ) ) ) ;
650
			make_label(ptno(pt(son(t))));
615
	    coder ( dest, stack, t ) ;
651
			coder(dest, stack, t);
616
	}
652
		}
617
    } while ( !last ( t ) ) ;
653
	} while (!last(t));
618
 
654
 
619
    regsinuse = r1 ;
655
	regsinuse = r1;
620
    have_cond = 0 ;
656
	have_cond = 0;
621
    return ;
657
	return;
622
}
658
}
623
 
659
 
624
 
660
 
625
/*
661
/*
626
    PRODUCE CODE FOR A CASE STATEMENT
662
    PRODUCE CODE FOR A CASE STATEMENT
627
 
663
 
628
    The controlling number of the case statement is in the D1 register, from
664
    The controlling number of the case statement is in the D1 register, from
629
    which already has been deducted.  The list of options is given as a
665
    which already has been deducted.  The list of options is given as a
630
    bro-list in arg.  The routine returns the total number which has been
666
    bro-list in arg.  The routine returns the total number which has been
631
    deducted from D1 at the end.
667
    deducted from D1 at the end.
632
*/
668
*/
633
static long caser
669
static long
634
    PROTO_N ( ( arg, already ) )
-
 
635
    PROTO_T ( exp arg X long already )
670
caser(exp arg, long already)
636
{
671
{
637
    bool sw, go = 1, diff = 0 ;
672
	bool sw, go = 1, diff = 0;
638
    exp t, jr, jt, split_at ;
673
	exp t, jr, jt, split_at;
639
    shape sha = sh ( arg ) ;
674
	shape sha = sh(arg);
640
    double low, high ;
675
	double low, high;
641
    double lowest = LONG_MAX, highest = LONG_MIN ;
676
	double lowest = LONG_MAX, highest = LONG_MIN;
642
    long i, j, n, *jtab ;
677
	long i, j, n, *jtab;
643
    long worth = 0 ;
678
	long worth = 0;
644
 
-
 
645
    for ( t = bro ( arg ) ; go && ( t != nilexp ) ; t = bro ( t ) ) {
-
 
646
       if (is_signed(sh(t))) low = no (t) ;
-
 
647
       else low = (unsigned) no(t) ;
-
 
648
       if (son(t)) {
-
 
649
          if (is_signed(sh(son(t)))) high = no(son(t)) ;
-
 
650
          else high =(unsigned) no(son(t)) ;
-
 
651
       }
-
 
652
       else high = low ;
-
 
653
 
679
 
654
	if ( low != high ) diff = 1 ;
-
 
655
	if ( low < lowest ) lowest = low ;
-
 
656
	if ( high > highest ) highest = high ;
-
 
657
	worth += ( low == high ? 1 : 2 ) ;
-
 
658
	if ( bro ( t ) != nilexp ) {
680
	for (t = bro(arg); go && (t != nilexp); t = bro(t)) {
659
           double nextlow;
-
 
660
           if (is_signed(sh(bro(t)))) nextlow = no(bro(t));
681
		if (is_signed(sh(t))) {
661
           else nextlow = (unsigned) no(bro(t));
-
 
662
	    if ( ( nextlow / 2 ) > ( high / 2 ) + 20 ) {
-
 
663
		split_at = t ;
682
			low = no(t);
664
		go = 0 ;
683
		}
665
	    }
684
		else {
-
 
685
			low = (unsigned)no(t);
666
	}
686
		}
667
#ifndef tdf3
687
		if (son(t)) {
668
        if (high/2 > low/2 + 20) {
688
			if (is_signed(sh(son(t)))) {
669
           worth = 0 ;
689
				high = no(son(t));
670
        }
690
			} else {
-
 
691
				high = (unsigned)no(son(t));
671
#endif
692
			}
-
 
693
		} else {
-
 
694
			high = low;
672
    }
695
		}
673
 
696
 
-
 
697
		if (low != high) {
-
 
698
			diff = 1;
-
 
699
		}
-
 
700
		if (low < lowest) {
-
 
701
			lowest = low;
-
 
702
		}
-
 
703
		if (high > highest) {
-
 
704
			highest = high;
-
 
705
		}
-
 
706
		worth += (low == high ? 1 : 2);
-
 
707
		if (bro(t) != nilexp) {
-
 
708
			double nextlow;
-
 
709
			if (is_signed(sh(bro(t)))) {
-
 
710
				nextlow = no(bro(t));
-
 
711
			} else {
-
 
712
				nextlow = (unsigned)no(bro(t));
-
 
713
			}
-
 
714
			if ((nextlow / 2) > (high / 2) + 20) {
-
 
715
				split_at = t;
-
 
716
				go = 0;
-
 
717
			}
-
 
718
		}
-
 
719
#ifndef tdf3
-
 
720
		if (high / 2 > low / 2 + 20) {
-
 
721
			worth = 0;
-
 
722
		}
-
 
723
#endif
-
 
724
	}
-
 
725
 
674
    if ( !go ) {
726
	if (!go) {
675
	/* Split into two */
727
		/* Split into two */
676
	long a ;
728
		long a;
677
	exp new = copyexp ( arg ) ;
729
		exp new = copyexp(arg);
678
	exp old_bro = bro ( split_at ) ;
730
		exp old_bro = bro(split_at);
679
	bro ( new ) = old_bro ;
731
		bro(new) = old_bro;
680
	bro ( split_at ) = nilexp ;
732
		bro(split_at) = nilexp;
681
	setlast ( split_at ) ;
733
		setlast(split_at);
682
	/* Code the first half */
734
		/* Code the first half */
683
	a = caser ( arg, already ) ;
735
		a = caser(arg, already);
684
 
736
 
685
	/* Code the second half */
737
		/* Code the second half */
686
	return ( caser ( new, a ) ) ;
738
		return (caser(new, a));
687
    }
739
	}
688
 
740
 
689
    if ( worth > 2 ) {
741
	if (worth > 2) {
690
 
-
 
691
	/* Construct a jump table */
742
		/* Construct a jump table */
692
	mach_op *op1, *op2 ;
743
		mach_op *op1, *op2;
693
	long rlab = next_lab () ;
744
		long rlab = next_lab();
694
	long tlab = next_lab () ;
745
		long tlab = next_lab();
695
	long slab = next_lab () ;
746
		long slab = next_lab();
696
	n = highest - lowest + 1 ;
747
		n = highest - lowest + 1;
697
	jtab = ( long * ) xcalloc ( n, sizeof ( long ) ) ;
748
		jtab = (long *)xcalloc(n, sizeof(long));
698
 
749
 
699
	for ( i = 0 ; i < n ; i++ ) jtab [i] = rlab ;
750
		for (i = 0; i < n; i++) {
-
 
751
			jtab[i] = rlab;
-
 
752
		}
700
 
753
 
701
	for ( t = bro ( arg ) ; t != nilexp ; t = bro ( t ) ) {
754
		for (t = bro(arg); t != nilexp; t = bro(t)) {
702
           if (is_signed(sh(t))) low = no (t) ;
755
			if (is_signed(sh(t))) {
-
 
756
				low = no(t);
-
 
757
			} else {
703
           else low = (unsigned) no(t) ;
758
				low = (unsigned)no(t);
-
 
759
			}
704
           if (son(t)) {
760
			if (son(t)) {
705
              if (is_signed(sh(son(t)))) high = no(son(t)) ;
761
				if (is_signed(sh(son(t)))) {
-
 
762
					high = no(son(t));
-
 
763
				} else {
706
              else high =(unsigned) no(son(t)) ;
764
					high = (unsigned)no(son(t));
-
 
765
				}
707
           }
766
			} else {
708
           else high = low ;
767
				high = low;
-
 
768
			}
709
 
769
 
710
           j = ptno ( pt ( son ( pt ( t ) ) ) ) ;
770
			j = ptno(pt(son(pt(t))));
711
           for ( i = low ; i <= high ; i++ ) jtab [ i - (long)lowest ] = j ;
771
			for (i = low; i <= high; i++) {
-
 
772
				jtab[i - (long)lowest] = j;
-
 
773
			}
712
	}
774
		}
713
 
775
 
714
	/* Move offset into D1 */
776
		/* Move offset into D1 */
715
	jt = simple_exp ( 0 ) ;
777
		jt = simple_exp(0);
716
	ptno ( jt ) = rlab ;
778
		ptno(jt) = rlab;
-
 
779
		/*
717
	/* Subtract the lowest value (minus anything already deducted) */
780
		 * Subtract the lowest value (minus anything already deducted).
-
 
781
		 */
718
	sub ( slongsh, mnw ( lowest - already ), D1, D1 ) ;
782
		sub(slongsh, mnw(lowest - already), D1, D1);
719
	sw = cmp ( slongsh, D1, mnw ( highest - lowest ), tst_gr ) ;
783
		sw = cmp(slongsh, D1, mnw(highest - lowest), tst_gr);
720
	branch ( tst_gr, jt, 0, sw, 0 ) ;
784
		branch(tst_gr, jt, 0, sw, 0);
721
 
785
 
722
	/* Move displacement into D0 */
786
		/* Move displacement into D0 */
723
#if 0
787
#if 0
724
	op1 = make_reg_index ( REG_ZA0, REG_D1, 0, 4 ) ;
788
		op1 = make_reg_index(REG_ZA0, REG_D1, 0, 4);
725
	op1->of->plus->plus = make_lab ( slab, 0 ) ;
789
		op1->of->plus->plus = make_lab(slab, 0);
726
	regsinproc |= regmsk ( REG_A0 ) ;
790
		regsinproc |= regmsk(REG_A0);
727
	debug_warning ( "%%za0 used" ) ;
791
		debug_warning("%%za0 used");
728
#else
792
#else
729
	op1 = make_lab_ind ( slab, 0 ) ;
793
		op1 = make_lab_ind(slab, 0);
730
	i = tmp_reg ( m_lea, op1 ) ;
794
		i = tmp_reg(m_lea, op1);
731
	op1 = make_reg_index ( i, REG_D1, 0, 4 ) ;
795
		op1 = make_reg_index(i, REG_D1, 0, 4);
732
#endif
796
#endif
733
	op2 = make_register ( REG_D0 ) ;
797
		op2 = make_register(REG_D0);
734
	make_instr ( m_movl, op1, op2, regmsk ( REG_D0 ) ) ;
798
		make_instr(m_movl, op1, op2, regmsk(REG_D0));
735
 
-
 
736
	/* Do the jump */
-
 
737
	op1 = make_reg_index ( REG_PC, REG_D0, 2, 1 ) ;
-
 
738
	make_instr ( m_jmp, op1, null, 0 ) ;
-
 
739
 
799
 
740
	/* Print out table */
800
		/* Do the jump */
741
	make_label ( tlab ) ;
-
 
742
#ifndef no_align_directives
-
 
743
	make_instr ( m_as_align4, null, null, 0 ) ;
-
 
744
#endif
-
 
745
	make_label ( slab ) ;
-
 
746
	for ( i = 0 ; i < n ; i++ ) {
-
 
747
	    op1 = make_lab_diff ( jtab [i], tlab ) ;
801
		op1 = make_reg_index(REG_PC, REG_D0, 2, 1);
748
	    make_instr ( m_as_long, op1, null, 0 ) ;
802
		make_instr(m_jmp, op1, null, 0);
749
	}
-
 
750
	make_label ( rlab ) ;
-
 
751
 
803
 
-
 
804
		/* Print out table */
-
 
805
		make_label(tlab);
-
 
806
#ifndef no_align_directives
-
 
807
		make_instr(m_as_align4, null, null, 0);
-
 
808
#endif
-
 
809
		make_label(slab);
-
 
810
		for (i = 0; i < n; i++) {
-
 
811
			op1 = make_lab_diff(jtab[i], tlab);
-
 
812
			make_instr(m_as_long, op1, null, 0);
-
 
813
		}
-
 
814
		make_label(rlab);
-
 
815
 
752
	/* Return the total number deducted from D1 */
816
		/* Return the total number deducted from D1 */
753
	return ( lowest ) ;
817
		return (lowest);
754
    }
818
	}
755
 
819
 
756
    /* If 'high' is not always equal to 'low', restore value of D1 */
820
	/* If 'high' is not always equal to 'low', restore value of D1 */
757
    if ( diff ) {
821
	if (diff) {
758
	add ( slongsh, D1, mnw ( already ), D1 ) ;
822
		add(slongsh, D1, mnw(already), D1);
759
	already = 0 ;
823
		already = 0;
760
    }
-
 
761
 
824
	}
762
    /* A series of jumps/comparisons */
-
 
763
    for ( t = bro ( arg ) ; t != nilexp ; t = bro ( t ) ) {
-
 
764
       if (is_signed(sh(t))) low = no (t) ;
-
 
765
       else low = (unsigned) no(t) ;
-
 
766
       if (son(t)) {
-
 
767
          if (is_signed(sh(son(t)))) high = no(son(t)) ;
-
 
768
          else high =(unsigned) no(son(t)) ;
-
 
769
       }
-
 
770
       else high = low ;
-
 
771
 
825
 
-
 
826
	/* A series of jumps/comparisons */
-
 
827
	for (t = bro(arg); t != nilexp; t = bro(t)) {
-
 
828
		if (is_signed(sh(t))) {
-
 
829
			low = no(t);
-
 
830
		} else {
-
 
831
			low = (unsigned)no(t);
-
 
832
		}
-
 
833
		if (son(t)) {
-
 
834
			if (is_signed(sh(son(t)))) {
-
 
835
				high = no(son(t));
-
 
836
			} else {
-
 
837
				high = (unsigned)no(son(t));
-
 
838
			}
-
 
839
		} else {
-
 
840
			high = low;
-
 
841
		}
-
 
842
 
772
	jr = pt ( son ( pt ( t ) ) ) ;
843
		jr = pt(son(pt(t)));
773
	if ( low == high ) {
844
		if (low == high) {
774
	    sw = cmp ( sha, D1, mnw ( low - already ), tst_eq ) ;
845
			sw = cmp(sha, D1, mnw(low - already), tst_eq);
775
	    branch ( tst_eq, jr, 1, sw, 0 ) ;
846
			branch(tst_eq, jr, 1, sw, 0);
776
	} else {
847
		} else {
777
	    jt = simple_exp ( 0 ) ;
848
			jt = simple_exp(0);
778
	    ptno ( jt ) = next_lab () ;
849
			ptno(jt) = next_lab();
779
	    sw = cmp ( sha, D1, mnw ( low - already ), tst_ls ) ;
850
			sw = cmp(sha, D1, mnw(low - already), tst_ls);
780
	    branch ( tst_ls, jt, is_signed ( sh ( t ) ), sw, 0 ) ;
851
			branch(tst_ls, jt, is_signed(sh(t)), sw, 0);
781
	    sw = cmp ( sha, D1, mnw ( (unsigned)(high - already) ), tst_le ) ;
852
			sw = cmp(sha, D1, mnw((unsigned)(high - already)),
-
 
853
				 tst_le);
782
	    branch ( tst_le, jr, is_signed ( sh ( son ( t ) ) ), sw, 0 ) ;
854
			branch(tst_le, jr, is_signed(sh(son(t))), sw, 0);
783
	    make_label ( ptno ( jt ) ) ;
855
			make_label(ptno(jt));
-
 
856
		}
784
	}
857
	}
785
    }
-
 
786
    /* Return what has been subtracted from D1 */
858
	/* Return what has been subtracted from D1 */
787
    have_cond = 0 ;
859
	have_cond = 0;
788
    return ( already ) ;
860
	return (already);
789
}
861
}
790
 
862
 
791
/*
863
/*
792
    RESET STACK POINTER FROM APPLICATIONS POINTER
864
    RESET STACK POINTER FROM APPLICATIONS POINTER
793
    sp = AP - (env_size - (sizeof(params) + sizeof(ret-addr) + sizeof(AP)))
865
    sp = AP - (env_size - (sizeof(params) + sizeof(ret-addr) + sizeof(AP)))
794
*/
866
*/
795
 
867
 
796
static void reset_stack_pointer
868
static void
797
    PROTO_Z ()
869
reset_stack_pointer(void)
798
{
870
{
799
    mach_op *op1, *op2, *op3 ;
871
	mach_op *op1, *op2, *op3;
800
    make_comment("reset stack pointer ...");
872
	make_comment("reset stack pointer ...");
801
    update_stack () ;
873
	update_stack();
802
 
874
 
803
    op1 = make_indirect ( REG_AP, 0 ) ;
875
	op1 = make_indirect(REG_AP, 0);
804
    op2 = op1->of->plus = new_mach_op() ;
876
	op2 = op1->of->plus = new_mach_op();
805
    op2->type = MACH_NEG ;
877
	op2->type = MACH_NEG;
806
    op2->plus = make_ldisp(4);
878
	op2->plus = make_ldisp(4);
807
 
879
 
808
    op2 = make_register ( REG_SP ) ;
880
	op2 = make_register(REG_SP);
809
    make_instr ( m_lea, op1, op2, regmsk ( REG_SP ) ) ;
881
	make_instr(m_lea, op1, op2, regmsk(REG_SP));
810
 
882
 
811
#if 0
883
#if 0
812
    /* gas misinterpret lea a6@( <label> ) if <label> isn't declared ?? */
884
	/* gas misinterpret lea a6@( <label> ) if <label> isn't declared ?? */
813
    op1 = make_indirect ( REG_AP, 0 ) ;
885
	op1 = make_indirect(REG_AP, 0);
814
    op2 = new_mach_op() ;
886
	op2 = new_mach_op();
815
    op1->of->plus = op2 ;
887
	op1->of->plus = op2;
816
    /* The address of cur_proc_dec is used to form the env_size label */
888
	/* The address of cur_proc_dec is used to form the env_size label */
817
    op3 = make_lab ((long)cur_proc_dec,8+(cur_proc_callers_size+cur_proc_callees_size)/8);
889
	op3 = make_lab((long)cur_proc_dec,8+ (cur_proc_callers_size+cur_proc_callees_size) /8);
818
    op2->type = MACH_NEG ;
890
	op2->type = MACH_NEG;
819
    op2->plus = op3 ;
891
	op2->plus = op3;
820
    op2 = make_register ( REG_SP ) ;
892
	op2 = make_register(REG_SP);
821
    make_instr ( m_lea, op1, op2, regmsk ( REG_SP ) ) ;
893
	make_instr(m_lea, op1, op2, regmsk(REG_SP));
822
#endif
894
#endif
823
    make_comment("reset stack pointer done");
895
	make_comment("reset stack pointer done");
824
}
896
}
825
 
897
 
826
/*
898
/*
827
    CHECK UP ON JUMPS
899
    CHECK UP ON JUMPS
828
 
900
 
829
    This routine checks for jumps to immediately following labels.
901
    This routine checks for jumps to immediately following labels.
830
*/
902
*/
831
 
903
 
832
static bool red_jump
904
static bool
833
    PROTO_N ( ( e, la ) )
-
 
834
    PROTO_T ( exp e X exp la )
905
red_jump(exp e, exp la)
835
{
906
{
836
    if ( !last ( la ) && pt ( e ) == bro ( la ) ) return ( 1 ) ;
907
	if (!last(la) && pt(e) == bro(la)) {
-
 
908
		return (1);
-
 
909
	}
837
    return ( 0 ) ;
910
	return (0);
838
}
911
}
839
 
912
 
840
 
913
 
841
/*
914
/*
842
    ALLOW SPACE ON STACK
915
    ALLOW SPACE ON STACK
843
*/
916
*/
844
 
917
 
845
static ash stack_room
918
static ash
846
    PROTO_N ( ( stack, dest, off ) )
-
 
847
    PROTO_T ( ash stack X where dest X long off )
919
stack_room(ash stack, where dest, long off)
848
{
920
{
849
    exp e = dest.wh_exp ;
921
	exp e = dest.wh_exp;
850
    if ( name ( e ) == ident_tag ) {
922
	if (name(e) == ident_tag) {
851
	if ( ptno ( e ) != var_pl ) return ( stack ) ;
923
		if (ptno(e) != var_pl) {
-
 
924
			return (stack);
-
 
925
		}
852
	if ( no ( e ) + off > stack ) stack = no ( e ) + off ;
926
		if (no(e) + off > stack) {
-
 
927
			stack = no(e) + off;
853
    }
928
		}
-
 
929
	}
854
    return ( stack ) ;
930
	return (stack);
855
}
931
}
856
 
932
 
857
 
933
 
858
/*
934
/*
859
    MAIN CODING ROUTINE
935
    MAIN CODING ROUTINE
Line 863... Line 939...
863
    evaluation is dealt with by codec.  The expression e is coded and
939
    evaluation is dealt with by codec.  The expression e is coded and
864
    the result put into dest.  The stack argument gives the current
940
    the result put into dest.  The stack argument gives the current
865
    structure of the stack.
941
    structure of the stack.
866
*/
942
*/
867
 
943
 
868
void coder
944
void
869
    PROTO_N ( ( dest, stack, e ) )
-
 
870
    PROTO_T ( where dest X ash stack X exp e )
945
coder(where dest, ash stack, exp e)
871
{
946
{
872
    bool sw ;
947
	bool sw;
873
 
948
 
927
		} else {
1880
		} else {
928
		    /* Encode the definition */
1881
			exp s_d0 = sim_exp(sh(offset),D0);
929
		    if ( ptno ( e ) == reg_pl ) regsindec |= dc.num ;
-
 
930
		    coder ( zw ( e ), stack, def ) ;
1882
			where w_d0;
931
		}
-
 
932
 
-
 
933
		/* Modify regsinuse if a register is being used */
-
 
934
		if ( ptno ( e ) == reg_pl ) {
1883
			w_d0 = zw(s_d0);
935
		    regsindec &= ~dc.num ;
1884
			coder(w_d0,stack,offset);
936
		    if ( used_once ) {
1885
			add(sh(offset),mnw(7),D0,D0);
937
			regsinuse |= dc.num ;
1886
			and(sh(offset),D0,mnw(~7),D0);
938
			reuseables |= dc.num ;
1887
			add(sh(offset),A0,D0,SP);
939
		    } else {
1888
		}
-
 
1889
 
940
			regsinuse |= dc.num ;
1890
		if (need_preserve_stack) {
941
			reuseables &= ~dc.num ;
1891
			save_stack();
942
		    }
-
 
943
		}
1892
		}
944
 
1893
 
945
		/* Modify max_stack is the stack is being used */
1894
		make_comment("local_free done");
946
		if ( ptno ( e ) == var_pl && sz > max_stack ) max_stack = sz ;
-
 
947
	    }
-
 
948
 
1895
 
949
	    /* Encode the body */
-
 
950
	    coder ( dest, dc.new_stack, body ) ;
-
 
951
	    extra_weight -= dw ;
1896
		return;
952
 
1897
	}
953
	    /* Look for peephole optimizations */
1898
	case local_free_all_tag: {
954
	    if ( dc.is_new && pt ( e ) == reg_pl ) {
1899
		mach_op *op1, *op2;
955
		regsinuse &= ~dc.num ;
1900
		must_use_bp = 1;
956
		if ( !output_immediately && p && do_peephole ) {
1901
		make_comment("local_free_all ...");
957
		    if ( used_twice && post_inc_check ( p, no ( e ) ) ) {
1902
		reset_stack_pointer();
958
			regsinproc = rg ;
1903
		if (need_preserve_stack) {
959
			return ;
1904
			save_stack();
960
		    }
-
 
961
		}
1905
		}
962
	    }
1906
		make_comment("local_free_all done");
963
	    return ;
1907
		return;
964
	}
1908
	}
965
#ifndef tdf3
-
 
966
#else
-
 
967
	case clear_tag : {
-
 
968
	    /* Clear means do nothing */
-
 
969
	    return ;
-
 
970
	}
-
 
971
#endif
-
 
972
	case seq_tag : {
-
 
973
	    /* Sequences */
-
 
974
	    bool no_bottom = 1 ;
-
 
975
	    exp t = son ( son ( e ) ) ;
-
 
976
	    /* Code each sub-expression */
-
 
977
	    while ( coder ( zero, stack, t ),
-
 
978
		    no_bottom = ( name ( sh ( t ) ) != bothd ),
-
 
979
		    !last ( t ) ) t = bro ( t ) ;
-
 
980
	    /* Code the result expression if necessary */
-
 
981
	    if ( no_bottom ) coder ( dest, stack, bro ( son ( e ) ) ) ;
-
 
982
	    return ;
-
 
983
	}
-
 
984
 
-
 
985
	case cond_tag : {
-
 
986
	    /* Conditionals */
-
 
987
	    long lb, r1 ;
-
 
988
	    allocation dc ;
-
 
989
	    exp jr, record ;
-
 
990
	    bool is_condgoto = 0 ;
-
 
991
 
-
 
992
	    /* Find the first and alternative expressions */
-
 
993
	    exp first = son ( e ) ;
-
 
994
	    exp alt = bro ( first ) ;
-
 
995
 
-
 
996
	    /* Check for "if cond goto ..." */
-
 
997
	    if ( name ( bro ( son ( alt ) ) ) == goto_tag ) is_condgoto = 1 ;
-
 
998
 
-
 
999
	    /* Find or create the label */
-
 
1000
	    if ( is_condgoto ) {
-
 
1001
		record = pt ( son ( pt ( bro ( son ( alt ) ) ) ) ) ;
-
 
1002
	    } else {
-
 
1003
		lb = next_lab () ;
-
 
1004
		record = simple_exp ( 0 ) ;
-
 
1005
		no ( record ) = stack ;
-
 
1006
		sonno ( record ) = stack_dec ;
-
 
1007
		ptno ( record ) = lb ;
-
 
1008
	    }
-
 
1009
	    no(son(alt)) = ptno(record);
-
 
1010
	    pt ( son ( alt ) ) = record ;
-
 
1011
 
-
 
1012
	    /* Allocate space for the alternative expression */
-
 
1013
	    dc = alloc_variable ( alt, son ( alt ), stack ) ;
-
 
1014
	    ptno ( alt ) = dc.place ;
-
 
1015
	    no ( alt ) = dc.num ;
-
 
1016
 
-
 
1017
	    /* If first is just a jump to alt, just encode alt */
-
 
1018
	    if ( name ( first ) == goto_tag && pt ( first ) == alt &&
-
 
1019
		 son ( first ) != nilexp &&
-
 
1020
		 name ( sh ( son ( first ) ) ) == tophd ) {
-
 
1021
		coder ( dest, stack, bro ( son ( alt ) ) ) ;
-
 
1022
		return ;
-
 
1023
	    }
-
 
1024
 
-
 
1025
	    /* Code the first expression */
-
 
1026
	    reuseables = 0 ;
-
 
1027
	    r1 = regsinuse ;
-
 
1028
	    coder ( dest, stack, first ) ;
-
 
1029
 
-
 
1030
	    /* Restore regsinuse */
-
 
1031
	    regsinuse = r1 ;
-
 
1032
 
-
 
1033
	    /* If alt is trivial, no further action is required */
-
 
1034
	    if ( name ( bro ( son ( alt ) ) ) == top_tag ) {
-
 
1035
		bitpattern ch = last_jump_regs ;
-
 
1036
		make_label ( ptno ( record ) ) ;
-
 
1037
		if ( !is_condgoto && !output_immediately && last_jump == lb ) {
-
 
1038
		    current_ins->changed = ch ;
-
 
1039
		}
-
 
1040
		return ;
-
 
1041
	    }
-
 
1042
 
-
 
1043
	    /* No further action is required for conditional gotos */
-
 
1044
	    if ( is_condgoto ) return ;
-
 
1045
 
-
 
1046
	    /* If first doesn't end with a jump, add one */
-
 
1047
	    if ( name ( sh ( first ) ) != bothd ) {
-
 
1048
		long lb2 = next_lab () ;
-
 
1049
		jr = simple_exp ( 0 ) ;
-
 
1050
		ptno ( jr ) = lb2 ;
-
 
1051
		make_jump ( m_bra, lb2 ) ;
-
 
1052
	    }
-
 
1053
 
1909
 
1054
	    /* Encode the alternative expression */
-
 
1055
	    reuseables = 0 ;
-
 
1056
	    make_label ( ptno ( record ) ) ;
-
 
1057
	    coder ( dest, stack, alt ) ;
-
 
1058
	    regsinuse = r1 ;
-
 
1059
	    reuseables = 0 ;
-
 
1060
 
-
 
1061
	    /* Output the label for the jump added to first if necessary */
-
 
1062
	    if ( name ( sh ( first ) ) != bothd ) {
-
 
1063
		make_label ( ptno ( jr ) ) ;
-
 
1064
		retcell ( jr ) ;
-
 
1065
	    }
-
 
1066
	    have_cond = 0 ;
-
 
1067
	    retcell ( record ) ;
-
 
1068
	    return ;
1910
#ifndef tdf3
1069
	}
-
 
1070
 
-
 
1071
	case labst_tag : {
1911
	case untidy_return_tag:
1072
	    /* Labelled statements */
-
 
1073
	    allocation dc ;
-
 
1074
	    have_cond = 0 ;
-
 
1075
 
-
 
1076
            /* Is there long jump access to this label ? */
-
 
1077
            if ( is_loaded_lv(e) ) {
-
 
1078
               if ( need_preserve_stack )
-
 
1079
                  restore_stack ();
-
 
1080
               else if (!has_alloca)
-
 
1081
                  reset_stack_pointer() ;
-
 
1082
            };
-
 
1083
 
-
 
1084
	    /* Allocate space */
-
 
1085
	    dc = alloc_variable ( e, son ( e ), stack ) ;
-
 
1086
	    if ( dc.place == reg_pl ) {
-
 
1087
		regsinuse |= dc.num ;
-
 
1088
		reuseables &= ~dc.num ;
-
 
1089
	    }
-
 
1090
 
-
 
1091
	    /* Encode the body */
-
 
1092
	    coder ( dest, stack, bro ( son ( e ) ) ) ;
-
 
1093
 
-
 
1094
	    /* Update max_stack and regsinuse */
-
 
1095
	    if ( dc.place == var_pl ) {
-
 
1096
		if ( dc.new_stack > max_stack ) max_stack = dc.new_stack ;
-
 
1097
	    }
1912
#endif
1098
	    if ( dc.place == reg_pl ) regsinuse &= ( ~dc.num ) ;
-
 
1099
	    return ;
-
 
1100
	}
-
 
1101
 
-
 
1102
	case rep_tag : {
1913
	case res_tag:
1103
	    /* Loops */
-
 
1104
	    long lb ;
-
 
1105
	    exp record ;
-
 
1106
	    allocation dc ;
-
 
1107
 
-
 
1108
	    /* Find the starter and the body of the loop */
-
 
1109
	    exp start = son ( e ) ;
-
 
1110
	    exp body = bro ( start ) ;
-
 
1111
 
-
 
1112
	    /* Allocate space */
1914
		/* Procedure results */
1113
	    dc = alloc_variable ( body, son ( body ), stack ) ;
-
 
1114
	    ptno ( body ) = dc.place ;
-
 
1115
	    no ( body ) = dc.num ;
-
 
1116
 
-
 
1117
	    /* Code the starter of the loop */
-
 
1118
	    coder ( zw ( body ), stack, start ) ;
-
 
1119
 
-
 
1120
	    /* Create the repeat label */
-
 
1121
	    lb = next_lab () ;
-
 
1122
	    make_label ( lb ) ;
-
 
1123
	    record = simple_exp ( 0 ) ;
-
 
1124
	    setlast ( record ) ;
-
 
1125
	    no ( record ) = stack ;
-
 
1126
	    sonno ( record ) = stack_dec ;
-
 
1127
	    ptno ( record ) = lb ;
-
 
1128
	    pt ( son ( body ) ) = record ;
-
 
1129
	    reuseables = 0 ;
1915
		have_cond = 0;
1130
 
-
 
1131
	    /* Encode the body of the loop */
-
 
1132
	    coder ( dest, stack, body ) ;
-
 
1133
	    retcell ( record ) ;
-
 
1134
	    return ;
-
 
1135
	}
-
 
1136
 
1916
 
1137
	case goto_tag : {
1917
		/* Has the procedure been inlined? */
1138
	  /* Jumps */
-
 
1139
	  exp lab ;
1918
		if (crt_rscope == 0) {
1140
 
1919
 
1141
	  /* Try to avoid unnecessary jumps */
1920
			/* Non-inlined procedures */
1142
	  if ( last ( e ) && name ( bro ( e ) ) == seq_tag &&
-
 
1143
	       name ( bro ( bro ( e ) ) ) == labst_tag &&
-
 
1144
	       red_jump ( e, bro ( e ) ) ) return ;
1921
			shape rsha = sh(son(e));
1145
 
1922
 
-
 
1923
			/* Does the result go into a register? */
-
 
1924
			if (result_in_reg(rsha)) {
-
 
1925
				if (shape_size(rsha) <= 32) {
-
 
1926
					/* Small register results go into D0 */
-
 
1927
					coder(D0, stack, son(e));
-
 
1928
				} else {
-
 
1929
#ifdef SYSV_ABI
-
 
1930
					coder(FP0, stack, son(e));
-
 
1931
#else
-
 
1932
					/*
-
 
1933
					 * Larger register results go into D0
-
 
1934
					 * and D1.
-
 
1935
					 */
-
 
1936
					coder(D0_D1, stack, son(e));
-
 
1937
					regsinproc |= regmsk(REG_D1);
-
 
1938
#endif
-
 
1939
				}
1146
	  /* Output the jump */
1940
				/* Jump to the return label */
1147
	  lab = pt ( e ) ;
1941
				if (name(rsha) != bothd) {
-
 
1942
#ifndef tdf3
1148
	  make_jump ( m_bra, ptno ( pt ( son ( lab ) ) ) ) ;
1943
					if (name(e) == untidy_return_tag) {
1149
	  reuseables = 0 ;
1944
						untidy_return();
-
 
1945
					} else
-
 
1946
#endif
-
 
1947
						make_jump(m_bra, crt_ret_lab);
-
 
1948
				}
1150
	  return ;
1949
				return;
1151
	}
1950
			}
1152
 
1951
 
1153
	case goto_lv_tag : {
1952
			/* Otherwise the result has to be encoded into the
1154
	  exp dest_exp = son(e); /* destination label */
1953
			 * position pointed to by A1 at the start of the
1155
	  exp cont_exp = getexp(sh(dest_exp),nilexp,1,dest_exp,nilexp,0,0,
1954
			 * procedure. This value was stored in A6_4. The value
1156
				cont_tag);
1955
			 * of this pointer is returned in D0.
1157
	  where wh;
1956
			 */
1158
	  mach_op *op;
-
 
1159
	  wh = zw(cont_exp);
1957
			if (name(son(e)) == apply_tag ||
1160
	  wh.wh_is = RegInd;
1958
			    name(son(e)) == apply_general_tag) {
1161
	  op = operand(32,wh);
1959
				coder(A6_4_p, stack, son(e));
1162
	  /*epilogue(1);*/
1960
			} else {
1163
	  make_instr(m_jmp,op,null,~save_msk);
1961
				codec(A6_4_p, stack, son(e));
-
 
1962
			}
-
 
1963
#ifdef SYSV_ABI
1164
	  /*ins1(m_jmp,32,D0,0);*/
1964
			move(slongsh, A6_4, A1);
1165
	  return ;
1965
#else
-
 
1966
			move(slongsh, A6_4, D0);
1166
	}
1967
#endif
-
 
1968
			regsinproc |= regmsk(REG_A1);
1167
#ifndef tdf3
1969
#ifndef tdf3
1168
        case return_to_label_tag: {
1970
			if (name(e) == untidy_return_tag) {
1169
           exp dest_lab = son(e);
-
 
1170
 
-
 
1171
           make_comment("return_to_label ...");
-
 
1172
 
-
 
1173
           move(slongsh, zw(dest_lab), A0);
-
 
1174
           restore_regs(ALL);
-
 
1175
           make_instr(m_jmp,operand(32,A0_p),null,~save_msk);
-
 
1176
 
-
 
1177
           make_comment("return_to_label done");
-
 
1178
           return;
1971
				untidy_return();
1179
        };
1972
			} else
1180
#endif
1973
#endif
1181
	case long_jump_tag : {
-
 
1182
	  exp new_env = son(e);
-
 
1183
	  exp dest_lab = bro(new_env);
-
 
1184
          make_comment("long_jump");
-
 
1185
 
-
 
1186
	  move(sh(dest_lab),zw(dest_lab),A0);
1974
				make_jump(m_bra, crt_ret_lab);
1187
	  move(sh(new_env),zw(new_env),A1);
-
 
1188
 
-
 
1189
          /* restore all registers but A6 or SP */
-
 
1190
          restore_regs(NOT_A6_OR_SP);
-
 
1191
 
-
 
1192
	  move(sh(new_env),A1,AP);
-
 
1193
	  make_instr(m_jmp,operand(32,A0_p),null,~save_msk);
-
 
1194
	  return ;
1975
			return;
1195
	}
-
 
1196
	case test_tag : {
-
 
1197
	    /* Tests */
-
 
1198
	    exp qwe ;
1976
		} else {
1199
	    where qw ;
-
 
1200
	    bool sg = 1, sf = 0 ;
-
 
1201
            int shn ;
-
 
1202
 
1977
			/*
1203
	    /* Find the test number */
1978
			 * For inlined procedures, the result goes into
1204
	    long test_n = ( long ) props ( e ) ;
1979
			 * rscope_dest and a jump is made to crt_rscope.
1205
 
1980
			 */
1206
	    /* Find the expressions being compared */
-
 
1207
	    exp arg1 = son ( e ) ;
1981
			coder(rscope_dest, stack, son(e));
1208
	    exp arg2 = bro ( arg1 ) ;
-
 
1209
 
-
 
1210
	    /* Find the label to be jumped to */
-
 
1211
	    exp lab_exp = pt ( e ) ;
1982
#ifndef tdf3
1212
	    exp jr = pt ( son ( lab_exp ) ) ;
-
 
1213
 
-
 
1214
	    /* If arg1 is not an operand, code it into D1 */
-
 
1215
	    if ( !is_o ( name ( arg1 ) ) ) {
1983
			if (name(e) == untidy_return_tag) {
1216
		qwe = sim_exp ( sh ( arg1 ), D1 ) ;
1984
				untidy_return();
1217
		qw = zw ( qwe ) ;
1985
			} else
1218
		regsinproc |= regmsk ( REG_D1 ) ;
1986
#endif
1219
		coder ( qw, stack, arg1 ) ;
1987
				make_jump(m_bra, ptno(crt_rscope));
1220
		arg1 = qwe ;
1988
			return;
1221
	    }
1989
		}
1222
 
-
 
1223
	    /* If arg2 is not an operand, code it into D1 */
1990
#ifdef rscope_tag
1224
	    if ( !is_o ( name ( arg2 ) ) ) {
1991
	case rscope_tag: {
1225
		qwe = sim_exp ( sh ( arg2 ), D1 ) ;
1992
		/* Procedure scopes */
1226
		qw = zw ( qwe ) ;
1993
		exp record;
1227
		regsinproc |= regmsk ( REG_D1 ) ;
1994
		where old_rscope_dest;
1228
		coder ( qw, stack, arg2 ) ;
1995
		exp old_rscope = crt_rscope;
1229
		arg2 = qwe ;
1996
		old_rscope_dest = rscope_dest;
1230
	    }
-
 
1231
 
1997
 
1232
	    /* Look for unsigned or floating tests */
1998
		/* Check for inlined procedures */
1233
            shn = name ( sh ( arg1 ) ) ;
-
 
1234
 
-
 
1235
	    switch ( shn ) {
-
 
1236
	        case ucharhd :
-
 
1237
	        case uwordhd :
-
 
1238
	        case ulonghd :
-
 
1239
                case u64hd   :  sg = 0 ; break ;
-
 
1240
		case shrealhd :
-
 
1241
		case realhd :
-
 
1242
		case doublehd : sg = 0 ; sf = 1 ; break ;
-
 
1243
	    }
-
 
1244
 
-
 
1245
	    /* Certain comparisons with 1 or -1 can be changed */
-
 
1246
	    if ( name ( arg1 ) == val_tag ) {
-
 
1247
		long d = no ( arg1 ) ;
-
 
1248
		if ( is_offset ( arg1 ) ) d /= 8 ;
-
 
1249
		if ( d == 1 ) {
1999
		if (last(e) &&
1250
		    if ( test_n == tst_le ) {
-
 
1251
			/* 1 <= x becomes 0 < x */
-
 
1252
			test_n = tst_ls ;
-
 
1253
			no ( arg1 ) = 0 ;
-
 
1254
		    } else if ( test_n == tst_gr ) {
-
 
1255
			/* 1 > x becomes 0 >= x */
-
 
1256
			test_n = tst_ge ;
-
 
1257
			no ( arg1 ) = 0 ;
-
 
1258
		    }
-
 
1259
		} else if ( d == -1 && sg ) {
-
 
1260
		    if ( test_n == tst_ls ) {
2000
		    (name(bro(e)) == proc_tag ||
1261
			/* -1 < x becomes 0 <= x */
-
 
1262
			test_n = tst_le ;
-
 
1263
			no ( arg1 ) = 0 ;
-
 
1264
		    } else if ( test_n == tst_ge ) {
-
 
1265
			/* -1 >= x becomes 0 > x */
-
 
1266
			test_n = tst_gr ;
-
 
1267
			no ( arg1 ) = 0 ;
-
 
1268
		    }
-
 
1269
		}
-
 
1270
	    }
-
 
1271
 
-
 
1272
	    /* Certain other comparisons with 1 or -1 can be changed */
-
 
1273
	    if ( name ( arg2 ) == val_tag ) {
2001
		     name(bro(e)) == general_proc_tag)) {
1274
		long d = no ( arg2 ) ;
-
 
1275
		if ( is_offset ( arg2 ) ) d /= 8 ;
-
 
1276
		if ( d == 1 ) {
-
 
1277
		    if ( test_n == tst_ge ) {
-
 
1278
			/* x >= 1 becomes x > 0 */
-
 
1279
			test_n = tst_gr ;
-
 
1280
			no ( arg2 ) = 0 ;
-
 
1281
		    } else if ( test_n == tst_ls ) {
-
 
1282
			/* x < 1 becomes x <= 0 */
-
 
1283
			test_n = tst_le ;
-
 
1284
			no ( arg2 ) = 0 ;
-
 
1285
		    }
-
 
1286
		} else if ( d == -1 && sg ) {
-
 
1287
		    if ( test_n == tst_gr ) {
-
 
1288
			/* x > -1 becomes x >= 0 */
-
 
1289
			test_n = tst_ge ;
-
 
1290
			no ( arg2 ) = 0 ;
-
 
1291
		    } else if ( test_n == tst_le ) {
-
 
1292
			/* x <= 1 becomes x < 0 */
-
 
1293
			test_n = tst_ls ;
-
 
1294
			no ( arg2 ) = 0 ;
-
 
1295
		    }
-
 
1296
		}
-
 
1297
	    }
-
 
1298
            if ( shn == u64hd || shn == s64hd ) {
-
 
1299
	      where w1, w2 ;
-
 
1300
              w1 = zw ( arg1 ) ;
-
 
1301
	      w2 = zw ( arg2 ) ;
-
 
1302
 
-
 
1303
              /* compare low word (unsigned) */
-
 
1304
              sw = cmp ( ulongsh, w1, w2, test_n ) ;
-
 
1305
              branch ( test_n, jr, sg, sw, sf ) ;
-
 
1306
 
-
 
1307
              /* compare high word */
-
 
1308
              w1.wh_off += 32 ;
-
 
1309
              w2.wh_off += 32 ;
-
 
1310
              if ( sg )
-
 
1311
                sw = cmp ( slongsh, w1, w2, test_n ) ;
-
 
1312
              else
-
 
1313
                sw = cmp ( ulongsh, w1, w2, test_n ) ;
-
 
1314
              branch ( test_n, jr, sg, sw, sf ) ;
-
 
1315
 
-
 
1316
              return ;
-
 
1317
            }
-
 
1318
 
-
 
1319
	    /* Code the comparison */
-
 
1320
	    sw = cmp ( sh ( arg1 ), zw ( arg1 ), zw ( arg2 ), test_n ) ;
-
 
1321
 
-
 
1322
	    /* Output the condition jump */
-
 
1323
	    branch ( test_n, jr, sg, sw, sf ) ;
-
 
1324
	    return ;
-
 
1325
	}
-
 
1326
 
-
 
1327
	case testbit_tag : {
-
 
1328
	    /* Bit tests */
-
 
1329
	    exp qwe ;
-
 
1330
	    where qw ;
-
 
1331
 
-
 
1332
	    /* Find the arguments */
-
 
1333
	    exp arg1 = son ( e ) ;
-
 
1334
	    exp arg2 = bro ( arg1 ) ;
-
 
1335
 
-
 
1336
	    /* Find the label to be jumped to */
-
 
1337
	    exp lab_exp = pt ( e ) ;
-
 
1338
	    exp jr = pt ( son ( lab_exp ) ) ;
-
 
1339
 
-
 
1340
	    /* If arg1 is not an operand, code it into D1 */
-
 
1341
	    if ( !is_o ( name ( arg1 ) ) ) {
-
 
1342
		qwe = sim_exp ( sh ( arg1 ), D1 ) ;
-
 
1343
		qw = zw ( qwe ) ;
-
 
1344
		regsinproc |= regmsk ( REG_D1 ) ;
-
 
1345
		coder ( qw, stack, arg1 ) ;
-
 
1346
		arg1 = qwe ;
-
 
1347
	    }
-
 
1348
 
-
 
1349
	    /* If arg2 is not an operand, code it into D1 */
-
 
1350
	    if ( !is_o ( name( arg2 ) ) ) {
-
 
1351
		qwe = sim_exp ( sh ( arg2 ), D1 ) ;
-
 
1352
		qw = zw ( qwe ) ;
-
 
1353
		regsinproc |= regmsk ( REG_D1 ) ;
-
 
1354
		coder ( qw, stack, arg2 ) ;
-
 
1355
		arg2 = qwe ;
-
 
1356
	    }
-
 
1357
 
-
 
1358
	    /* Code the test */
-
 
1359
	    bit_test ( sh ( arg1 ), zw ( arg1 ), zw ( arg2 ) ) ;
-
 
1360
 
-
 
1361
	    /* Output the conditional jump */
2002
			/* Non-inlined procedures are simple */
1362
	    branch ( ( long ) props ( e ), jr, 1, 0, 0 ) ;
-
 
1363
	    return ;
-
 
1364
	}
-
 
1365
 
-
 
1366
	case ass_tag :
-
 
1367
	case assvol_tag : {
-
 
1368
	    /* Variable assignments */
-
 
1369
	    exp assdest = son ( e ) ;
-
 
1370
	    exp assval = bro ( assdest ) ;
-
 
1371
            make_comment("assign ...") ;
-
 
1372
	    if ( name ( sh ( assval ) ) == bitfhd ) {
-
 
1373
 
-
 
1374
		int_to_bitf ( assval, e, stack ) ;
-
 
1375
		return ;
-
 
1376
	    }
-
 
1377
	    codec (zw ( e ), stack, assval ) ;
-
 
1378
            make_comment("assign done") ;
-
 
1379
	    return ;
-
 
1380
	}
-
 
1381
 
-
 
1382
	case nof_tag : {
-
 
1383
	    shape sha ;
-
 
1384
	    long crt, off ;
-
 
1385
	    exp v = son ( e ) ;
-
 
1386
 
-
 
1387
	    if ( v == nilexp ) return ;
-
 
1388
	    if ( name ( dest.wh_exp ) == val_tag ) return ;
-
 
1389
 
-
 
1390
	    sha = sh ( v ) ;
-
 
1391
	    crt = dest.wh_off ;
-
 
1392
	    off = rounder ( shape_size ( sha ), shape_align ( sha ) ) ;
-
 
1393
 
-
 
1394
	    while ( 1 ) {
-
 
1395
		where wh ;
-
 
1396
		ash stack2 ;
-
 
1397
		wh = mw ( dest.wh_exp, crt ) ;
-
 
1398
		stack2 = stack_room ( stack, dest, off + crt ) ;
-
 
1399
		coder ( wh, stack2, v ) ;
-
 
1400
		if ( last ( v ) ) return ;
-
 
1401
		crt += off ;
2003
			crt_rscope = 0;
1402
		v = bro ( v ) ;
-
 
1403
	    }
-
 
1404
	    /* Not reached */
-
 
1405
	}
-
 
1406
 
-
 
1407
	case ncopies_tag : {
-
 
1408
	    where wh ;
-
 
1409
	    long n = no ( e ) ;
-
 
1410
	    shape sha = sh ( son ( e ) ) ;
-
 
1411
	    long sz = rounder ( shape_size ( sha ), shape_align ( sha ) ) ;
-
 
1412
	    if ( n == 0 ) return ;
-
 
1413
	    if ( name ( dest.wh_exp ) == val_tag ) return ;
-
 
1414
	    if ( n == 1 ) {
-
 
1415
		coder ( dest, stack, son ( e ) ) ;
2004
			coder(zero, stack, son(e));
1416
		return ;
-
 
1417
	    }
-
 
1418
	    if ( sz == 8 || sz == 16 || sz == 32 ) {
-
 
1419
		coder ( D1, stack, son ( e ) ) ;
-
 
1420
		regsinproc |= regmsk ( REG_D1 ) ;
-
 
1421
		if ( n <= 10 ) {
-
 
1422
		    long i ;
-
 
1423
		    for ( i = 0 ; i < n ; i++ ) {
-
 
1424
			wh = mw ( dest.wh_exp, dest.wh_off + i * sz ) ;
-
 
1425
			move ( sha, D1, wh ) ;
-
 
1426
		    }
-
 
1427
		    return ;
-
 
1428
		} else {
-
 
1429
		    mach_op *op1, *op2 ;
-
 
1430
		    long lab = next_lab () ;
-
 
1431
		    int instr = ins ( sz, ml_mov ) ;
-
 
1432
		    mova ( dest, A0 ) ;
-
 
1433
		    regsinproc |= regmsk ( REG_A0 ) ;
-
 
1434
		    move ( slongsh, mnw ( n - 1 ), D0 ) ;
-
 
1435
		    make_label ( lab ) ;
-
 
1436
		    op1 = make_register ( REG_D1 ) ;
-
 
1437
		    op2 = make_postinc ( REG_A0 ) ;
-
 
1438
		    make_instr ( instr, op1, op2, regmsk ( REG_A0 ) ) ;
-
 
1439
		    op1 = make_register ( REG_D0 ) ;
-
 
1440
		    op2 = make_lab_data ( lab, 0 ) ;
-
 
1441
		    make_instr ( m_dbf, op1, op2, regmsk ( REG_D0 ) ) ;
-
 
1442
		    return ;
-
 
1443
		}
-
 
1444
	    }
-
 
1445
	    coder ( dest, stack, son ( e ) ) ;
-
 
1446
	    wh = mw ( dest.wh_exp, dest.wh_off + sz ) ;
-
 
1447
	    move_bytes ( sz * ( n - 1 ), dest, wh, 0 ) ;
-
 
1448
	    return ;
-
 
1449
	}
-
 
1450
 
-
 
1451
	case concatnof_tag : {
-
 
1452
	    ash stack2 ;
-
 
1453
	    exp a1 = son ( e ) ;
-
 
1454
	    exp a2 = bro ( a1 ) ;
-
 
1455
	    long off = dest.wh_off + shape_size ( sh ( a1 ) ) ;
-
 
1456
	    coder ( dest, stack, a1 ) ;
-
 
1457
	    stack2 = stack_room ( stack, dest, off ) ;
-
 
1458
	    coder ( mw ( dest.wh_exp, off ), stack2, a2 ) ;
-
 
1459
	    return ;
-
 
1460
	}
-
 
1461
 
-
 
1462
#ifndef tdf3
-
 
1463
          case apply_tag :
-
 
1464
          case apply_general_tag : {
-
 
1465
             apply_general_proc(e, dest, stack);
-
 
1466
             return;
-
 
1467
          }
-
 
1468
 
-
 
1469
          case tail_call_tag : {
-
 
1470
             int old_stack_dec = stack_dec;
-
 
1471
             tail_call(e, dest, stack);
-
 
1472
             stack_dec = old_stack_dec;
-
 
1473
             return;
-
 
1474
          }
-
 
1475
 
-
 
1476
          case caller_tag : {
-
 
1477
             coder ( dest, stack, son ( e ) ) ;
-
 
1478
             return;
-
 
1479
          }
-
 
1480
          case trap_tag: {
-
 
1481
             trap_ins( no( e ) ) ;
-
 
1482
             return;
-
 
1483
          }
-
 
1484
#endif
-
 
1485
#if 0
-
 
1486
	case apply_tag : {
-
 
1487
	    /* Procedure applications */
-
 
1488
#ifndef tdf3
-
 
1489
#else
-
 
1490
          static int apply_tag_flag = 0 ;
-
 
1491
#endif
-
 
1492
	    exp t ;
-
 
1493
	    ash st ;
-
 
1494
	    long comp_room = 0 ;
-
 
1495
	    long longs = 0, stkdec ;
-
 
1496
	    long start_stack = stack_dec ;
-
 
1497
	    bool use_push = 1, reg_res ;
-
 
1498
 
-
 
1499
	    /* Find the procedure and the arguments */
-
 
1500
	    exp proc = son ( e ) ;
-
 
1501
	    exp arg = ( last ( proc ) ? nilexp : bro ( proc ) ) ;
-
 
1502
 
-
 
1503
 
-
 
1504
#if 0
-
 
1505
            /* not a normal procedure call, but a way to specify a debuger break point */
-
 
1506
          if ((brog(son(proc))->dec_u.dec_val.processed) &&
-
 
1507
              (brog(son(proc))->dec_u.dec_val.extnamed)  &&
-
 
1508
              (!strcmp( brog(son(proc))->dec_u.dec_val.dec_id, "_TESTPOINT"))) {
-
 
1509
               TESTPOINT();
-
 
1510
               return;
-
 
1511
            }
-
 
1512
#endif
-
 
1513
 
-
 
1514
   make_comment("Call Normal Proc");
-
 
1515
	    /* See if we can push all the arguments */
-
 
1516
	    st = 0 ;
-
 
1517
	    if ( arg != nilexp ) {
-
 
1518
		t = arg ;
-
 
1519
		while ( t != nilexp ) {
-
 
1520
		    ast a ;
-
 
1521
                    if ( cpd_param ( sh ( t ) ) ) use_push = 0 ;
-
 
1522
                    if ((name(sh(t)) == s64hd) || (name(sh(t)) == u64hd)){
-
 
1523
                      use_push = 0;
-
 
1524
                    }
-
 
1525
                    if ( !push_arg ( t ) ) use_push = 0 ;
-
 
1526
		    a = add_shape_to_stack ( st, sh ( t ) ) ;
-
 
1527
		    st = a.astash ;
-
 
1528
 
-
 
1529
		    t = ( last ( t ) ? nilexp : bro ( t ) ) ;
-
 
1530
		}
-
 
1531
	    }
-
 
1532
	    longs = st ;
-
 
1533
 
-
 
1534
	    /* Does the result go into a register? */
-
 
1535
	    reg_res = result_in_reg ( sh ( e ) ) ;
-
 
1536
	    if ( !reg_res ) {
-
 
1537
		if ( eq_where ( dest, zero ) ) {
-
 
1538
		    /* Calculate room for ignored compound result */
-
 
1539
/* todo: use symbol instead of 32 */
-
 
1540
		    comp_room = round ( shape_size ( sh ( e ) ), 32 ) ;
-
 
1541
		}
-
 
1542
	    }
-
 
1543
 
-
 
1544
	    /* Find total amount of stack decrease */
-
 
1545
	    stkdec = longs + comp_room ;
-
 
1546
 
-
 
1547
	    /* Put arguments onto stack */
-
 
1548
	    if ( use_push ) {
-
 
1549
              make_comment("Push callers");
-
 
1550
		if ( comp_room ) {
-
 
1551
		    /* Make room for unwanted compound result */
-
 
1552
		    dec_stack ( comp_room ) ;
-
 
1553
		    stack_dec -= comp_room ;
-
 
1554
		}
-
 
1555
		/* Push the arguments */
-
 
1556
		if ( arg != nilexp ) code_pars ( zw ( e ), stack, arg ) ;
-
 
1557
	    } else {
-
 
1558
              make_comment("Place callers");
-
 
1559
		/* Decrease stack */
-
 
1560
		if ( stkdec ) dec_stack ( stkdec ) ;
-
 
1561
		stack_dec -= stkdec ;
-
 
1562
		/* Indicate recursive calls */
-
 
1563
		apply_tag_flag++ ;
-
 
1564
		/* Encode the arguments onto the stack */
-
 
1565
		st = 0 ;
-
 
1566
		t = arg ;
-
 
1567
		while ( t != nilexp ) {
-
 
1568
		    ast a ;
-
 
1569
		    where stp ;
-
 
1570
		    long adj = 0 ;
-
 
1571
		    char nc = name ( sh ( t ) ) ;
-
 
1572
		    if ( nc == scharhd || nc == ucharhd ) adj = 24 ;
-
 
1573
		    if ( nc == swordhd || nc == uwordhd ) adj = 16 ;
-
 
1574
		    stp = mw ( SP_p.wh_exp, st + adj ) ;
-
 
1575
		    coder ( stp, stack, t ) ;
-
 
1576
		    a = add_shape_to_stack ( st, sh ( t ) ) ;
-
 
1577
		    st = a.astash ;
-
 
1578
		    t = ( last ( t ) ? nilexp : bro ( t ) ) ;
-
 
1579
		}
-
 
1580
		apply_tag_flag-- ;
-
 
1581
	    }
-
 
1582
	    start_stack -= stack_dec ;
-
 
1583
 
-
 
1584
	    /* For results which do not fit into registers a pointer to
-
 
1585
	       where the result is to be put is passed in in A1 */
-
 
1586
	    if ( !reg_res ) {
-
 
1587
		if ( comp_room ) {
-
 
1588
		    /* Find the space allocated for unwanted results */
-
 
1589
		    where w ;
-
 
1590
		    w = mnw ( longs / 8 ) ;
-
 
1591
		    add ( slongsh, SP, w, A1 ) ;
-
 
1592
		} else {
-
 
1593
		    /* Find the address of where the result is to be put */
-
 
1594
		    tmp_reg_prefer = REG_A1 ;
-
 
1595
		    if ( apply_tag_flag ) {
-
 
1596
			/* For recursive calls we need to be very careful
-
 
1597
			   if the result is itself to be a procedure argument
-
 
1598
			   to get the right stack offset. */
-
 
1599
			long ex = extra_stack ;
-
 
1600
			long doff = dest.wh_off ;
-
 
1601
			extra_stack += start_stack ;
-
 
1602
			dest.wh_off = 0 ;
-
 
1603
			if ( eq_where ( dest, SP_p ) ) {
-
 
1604
			    /* Careful! */
-
 
1605
			    dest.wh_off = doff + extra_stack ;
-
 
1606
			    mova ( dest, A1 ) ;
-
 
1607
			    dest.wh_off = doff ;
-
 
1608
			} else {
-
 
1609
			    /* Easy */
-
 
1610
			    dest.wh_off = doff ;
-
 
1611
			    mova ( dest, A1 ) ;
-
 
1612
			}
-
 
1613
			extra_stack = ex ;
-
 
1614
		    } else {
-
 
1615
			/* Otherwise (easy) ... */
-
 
1616
			mova ( dest, A1 ) ;
-
 
1617
		    }
-
 
1618
		}
-
 
1619
		/* Make sure we don't reuse A1 accidently */
-
 
1620
		avoid_tmp_reg ( REG_A1 ) ;
-
 
1621
		regsinproc |= regmsk ( REG_A1 ) ;
-
 
1622
	    }
-
 
1623
 
-
 
1624
	    /* Output the call instruction */
-
 
1625
	    callins ( longs, son ( e ) ) ;
-
 
1626
	    stack_dec += stkdec ;
-
 
1627
	    have_cond = 0 ;
-
 
1628
 
-
 
1629
	    /* Throw away unwanted compound result */
-
 
1630
	    if ( comp_room ) {
-
 
1631
		dec_stack ( -comp_room ) ;
-
 
1632
		return ;
-
 
1633
	    }
-
 
1634
 
-
 
1635
	    /* Throw away unwanted simple result */
-
 
1636
	    if ( eq_where ( dest, zero ) ) return ;
-
 
1637
 
-
 
1638
	    /* Now move the result into place */
-
 
1639
	    if ( reg_res ) {
-
 
1640
		if ( shape_size ( sh ( e ) ) <= 32 ) {
-
 
1641
		    /* Small register results are in D0 */
-
 
1642
		    move ( sh ( e ), D0, dest ) ;
-
 
1643
		    return ;
-
 
1644
		} else {
2005
		} else {
1645
		    /* Larger register results are in D0 and D1 */
-
 
1646
#ifdef SYSV_ABI
-
 
1647
		    move ( sh ( e ), FP0, dest ) ;
2006
			/* This is an inlined procedure */
1648
#else
-
 
1649
		    move ( sh ( e ), D0_D1, dest ) ;
2007
			long lb = next_lab();
1650
		    regsinproc |= regmsk ( REG_D1 ) ;
2008
			record = simple_exp(0);
1651
#endif
-
 
1652
		    return ;
2009
			ptno(record) = lb;
1653
		}
-
 
1654
	    } else {
2010
			crt_rscope = record;
1655
		/* Compound results should already have been copied to
-
 
1656
		   the position pointed to by A1 by the called procedure
-
 
1657
		   and returned by it in D0, so no further action should
-
 
1658
		   be required by the calling procedure.  Unfortunately
-
 
1659
		   cc doesn't always get this right for union results. */
-
 
1660
#ifdef OLD_SPEC
2011
			rscope_dest = dest;
1661
		if ( cc_conventions && name ( sh ( e ) ) == unhd ) {
-
 
1662
		    regsinproc |= regmsk ( REG_A0 ) ;
2012
			coder(zero, stack, son(e));
1663
		    move ( slongsh, D0, A0 ) ;
2013
			make_label(lb);
1664
		    move ( sh ( e ), A0_p, dest ) ;
2014
			retcell(record);
1665
		}
2015
		}
1666
#endif
2016
 
-
 
2017
		/* Restore the previous scopes */
-
 
2018
		rscope_dest = old_rscope_dest;
-
 
2019
		crt_rscope = old_rscope;
1667
		return ;
2020
		return;
1668
	    }
-
 
1669
	}
2021
	}
1670
#endif
2022
#endif
1671
	case alloca_tag : {
2023
	case solve_tag: {
1672
	    /* Local memory allocation */
2024
		/* Solve statements */
1673
	    exp s = son ( e ) ;
2025
		long lb = next_lab();
1674
            where size_w ;
2026
		exp jr = simple_exp(0);
-
 
2027
		ptno(jr) = lb;
1675
            bool allocation_done = 0 ;
2028
		solve(son(e), son(e), dest, jr, stack);
1676
	    used_stack = 1 ;
2029
		make_label(lb);
-
 
2030
		retcell(jr);
-
 
2031
		return;
1677
 
2032
	}
-
 
2033
	case case_tag: {
1678
            make_comment("Allocate ...") ;
2034
		/* Case statements */
-
 
2035
		exp d1;
-
 
2036
		where w1;
-
 
2037
		bool old_D1_sp = D1_is_special;
-
 
2038
		exp arg1 = son(e);
-
 
2039
		exp t = arg1;
1679
 
2040
 
1680
            /* Create a where representing the value to be allocated */
2041
		/* Mark the end of the cases */
-
 
2042
		while (!last(t)) {
-
 
2043
			t = bro(t);
-
 
2044
		}
-
 
2045
		bro(t) = nilexp;
1681
 
2046
 
1682
	    if ( name ( s ) == val_tag ) {
2047
		d1 = sim_exp(sh(arg1), D1);
-
 
2048
		w1 = zw(d1);
1683
              long off = no ( s ) ;
2049
		D1_is_special = 1;
1684
              if ( ! is_offset ( s ) ) off *= 8 ;
2050
		regsinproc |= regmsk(REG_D1);
1685
              off = rounder(off, stack_align) ;
2051
		coder(w1, stack, arg1);
1686
 
2052
 
1687
              if ( checkalloc(e)) {
-
 
1688
                 size_w = mw(zeroe, off / 8);
2053
		change_var_sh(slongsh, sh(arg1), w1, D1);
1689
              }
-
 
1690
              else {
-
 
1691
                 /* simple allocation of constant */
-
 
1692
                 dec_stack ( off ) ;
-
 
1693
                 allocation_done = 1 ;
-
 
1694
              }
-
 
1695
	    }
-
 
1696
            else {
-
 
1697
               size_w = zw(s) ;
2054
		D1_is_special = old_D1_sp;
1698
            }
-
 
1699
 
2055
 
1700
            /* Allocate (checked or not) */
2056
		/* Output the case statement */
-
 
2057
		(void)caser(arg1, L0);
1701
 
2058
 
1702
            if ( ! allocation_done )
-
 
1703
            if (checkalloc(e)) checkalloc_stack (size_w, 1) ;
-
 
1704
            else sub ( slongsh, size_w, SP, SP ) ;
-
 
1705
 
-
 
1706
	    /* The result of the construct is SP */
-
 
1707
 
-
 
1708
	    if ( !eq_where ( dest, zero ) ) move ( sh ( e ), SP, dest ) ;
-
 
1709
 
-
 
1710
	    have_cond = 0 ;
-
 
1711
 
-
 
1712
            if (need_preserve_stack) save_stack ();
-
 
1713
 
-
 
1714
            make_comment("Allocate done") ;
-
 
1715
	    return ;
-
 
1716
	}
-
 
1717
 
-
 
1718
	case last_local_tag : {
-
 
1719
           make_comment("last_local ...");
-
 
1720
           move ( sh ( e ), SP, dest ) ;
-
 
1721
           make_comment("last_local done");
-
 
1722
           return ;
-
 
1723
	}
-
 
1724
 
-
 
1725
	case local_free_tag : {
-
 
1726
	  exp base = son(e);
-
 
1727
	  exp offset = bro(base);
-
 
1728
	  exp s_a0 = sim_exp(sh(base),A0);
-
 
1729
	  where w_a0;
-
 
1730
	  w_a0 = zw(s_a0);
-
 
1731
 
-
 
1732
          make_comment("local_free ...");
-
 
1733
 
-
 
1734
	  coder(w_a0,stack,base);
-
 
1735
 
-
 
1736
	  if(name(offset) == val_tag) {
-
 
1737
            long off = no ( offset ) ;
-
 
1738
            where size_w ;
-
 
1739
 
-
 
1740
            if ( ! is_offset ( offset ) ) off *= 8 ;
-
 
1741
            off = rounder(off, stack_align) / 8 ;
-
 
1742
            size_w = mw(zeroe, off);
-
 
1743
	    add(sh(offset),A0,zw(offset),SP);
-
 
1744
	  }
-
 
1745
	  else {
-
 
1746
	    exp s_d0 = sim_exp(sh(offset),D0);
-
 
1747
	    where w_d0;
-
 
1748
	    w_d0 = zw(s_d0);
-
 
1749
	    coder(w_d0,stack,offset);
-
 
1750
	    add(sh(offset),mnw(7),D0,D0);
-
 
1751
	    and(sh(offset),D0,mnw(~7),D0);
-
 
1752
	    add(sh(offset),A0,D0,SP);
-
 
1753
	  }
-
 
1754
 
-
 
1755
          if (need_preserve_stack)
-
 
1756
	  save_stack ();
-
 
1757
 
-
 
1758
          make_comment("local_free done");
-
 
1759
 
-
 
1760
	  return ;
-
 
1761
	}
-
 
1762
 
-
 
1763
	case local_free_all_tag : {
-
 
1764
           mach_op *op1, *op2 ;
-
 
1765
           must_use_bp = 1 ;
-
 
1766
           make_comment("local_free_all ...");
-
 
1767
           reset_stack_pointer();
-
 
1768
           if (need_preserve_stack)
-
 
1769
           save_stack ();
-
 
1770
           make_comment("local_free_all done");
-
 
1771
           return ;
-
 
1772
	}
-
 
1773
 
-
 
1774
#ifndef tdf3
-
 
1775
        case untidy_return_tag :
-
 
1776
#endif
-
 
1777
	case res_tag : {
-
 
1778
	    /* Procedure results */
-
 
1779
	    have_cond = 0 ;
-
 
1780
 
-
 
1781
	    /* Has the procedure been inlined? */
-
 
1782
	    if ( crt_rscope == 0 ) {
-
 
1783
 
-
 
1784
		/* Non-inlined procedures */
-
 
1785
		shape rsha = sh ( son ( e ) ) ;
-
 
1786
 
-
 
1787
		/* Does the result go into a register? */
-
 
1788
		if ( result_in_reg ( rsha ) ) {
-
 
1789
		    if ( shape_size ( rsha ) <= 32 ) {
-
 
1790
			/* Small register results go into D0 */
-
 
1791
			coder ( D0, stack, son ( e ) ) ;
-
 
1792
		    } else {
-
 
1793
#ifdef SYSV_ABI
-
 
1794
			coder ( FP0, stack, son ( e ) ) ;
-
 
1795
#else
-
 
1796
			/* Larger register results go into D0 and D1 */
-
 
1797
			coder ( D0_D1, stack, son ( e ) ) ;
-
 
1798
			regsinproc |= regmsk ( REG_D1 ) ;
-
 
1799
#endif
-
 
1800
		    }
-
 
1801
		    /* Jump to the return label */
-
 
1802
		    if ( name ( rsha ) != bothd ) {
-
 
1803
#ifndef tdf3
-
 
1804
                       if ( name ( e ) == untidy_return_tag ) {
-
 
1805
                          untidy_return() ;
-
 
1806
                       }
-
 
1807
                       else
-
 
1808
#endif
-
 
1809
			make_jump ( m_bra, crt_ret_lab ) ;
-
 
1810
		    }
-
 
1811
		    return ;
-
 
1812
		}
-
 
1813
 
-
 
1814
		/* Otherwise the result has to be encoded into the
-
 
1815
		   position pointed to by A1 at the start of the procedure.
-
 
1816
		   This value was stored in A6_4.  The value of this
-
 
1817
		   pointer is returned in D0. */
-
 
1818
		if (   name ( son ( e ) ) == apply_tag
-
 
1819
                    || name ( son ( e ) ) == apply_general_tag ) {
-
 
1820
		    coder ( A6_4_p, stack, son ( e ) ) ;
-
 
1821
		} else {
-
 
1822
		    codec ( A6_4_p, stack, son ( e ) ) ;
-
 
1823
		}
-
 
1824
#ifdef SYSV_ABI
-
 
1825
		move ( slongsh, A6_4, A1 ) ;
-
 
1826
#else
-
 
1827
		move ( slongsh, A6_4, D0 ) ;
-
 
1828
#endif
-
 
1829
		regsinproc |= regmsk ( REG_A1 ) ;
-
 
1830
#ifndef tdf3
-
 
1831
                if ( name ( e ) == untidy_return_tag ) {
-
 
1832
                   untidy_return() ;
-
 
1833
                }
-
 
1834
                else
-
 
1835
#endif
-
 
1836
		make_jump ( m_bra, crt_ret_lab ) ;
-
 
1837
		return ;
2059
		retcell(d1);
1838
 
-
 
1839
	    } else {
-
 
1840
		/* For inlined procedures, the result goes into rscope_dest
-
 
1841
		   and a jump is made to crt_rscope */
-
 
1842
		coder ( rscope_dest, stack, son ( e ) ) ;
-
 
1843
#ifndef tdf3
-
 
1844
                if ( name ( e ) == untidy_return_tag ) {
-
 
1845
                   untidy_return() ;
-
 
1846
                }
-
 
1847
                else
-
 
1848
#endif
-
 
1849
		make_jump ( m_bra, ptno ( crt_rscope ) ) ;
-
 
1850
		return ;
2060
		return;
1851
	    }
-
 
1852
	}
-
 
1853
 
-
 
1854
#ifdef rscope_tag
-
 
1855
	case rscope_tag : {
-
 
1856
	    /* Procedure scopes */
-
 
1857
	    exp record ;
-
 
1858
	    where old_rscope_dest ;
-
 
1859
	    exp old_rscope = crt_rscope ;
-
 
1860
	    old_rscope_dest = rscope_dest ;
-
 
1861
 
-
 
1862
	    /* Check for inlined procedures */
-
 
1863
	    if ( last ( e ) && ( name ( bro ( e ) ) == proc_tag
-
 
1864
                                || name ( bro ( e ) ) == general_proc_tag ) ) {
-
 
1865
		/* Non-inlined procedures are simple */
-
 
1866
		crt_rscope = 0 ;
-
 
1867
		coder ( zero, stack, son ( e ) ) ;
-
 
1868
	    } else {
-
 
1869
		/* This is an inlined procedure */
-
 
1870
		long lb = next_lab () ;
-
 
1871
		record = simple_exp ( 0 ) ;
-
 
1872
		ptno ( record ) = lb ;
-
 
1873
		crt_rscope = record ;
-
 
1874
		rscope_dest = dest ;
-
 
1875
		coder ( zero, stack, son ( e ) ) ;
-
 
1876
		make_label ( lb ) ;
-
 
1877
		retcell ( record ) ;
-
 
1878
	    }
-
 
1879
 
-
 
1880
	    /* Restore the previous scopes */
-
 
1881
	    rscope_dest = old_rscope_dest ;
-
 
1882
	    crt_rscope = old_rscope ;
-
 
1883
	    return ;
-
 
1884
	}
-
 
1885
#endif
-
 
1886
 
-
 
1887
	case solve_tag : {
-
 
1888
	    /* Solve statements */
-
 
1889
	    long lb = next_lab () ;
-
 
1890
	    exp jr = simple_exp ( 0 ) ;
-
 
1891
	    ptno ( jr ) = lb ;
-
 
1892
	    solve ( son ( e ), son ( e ), dest, jr, stack ) ;
-
 
1893
	    make_label ( lb ) ;
-
 
1894
	    retcell ( jr ) ;
-
 
1895
	    return ;
-
 
1896
	}
-
 
1897
 
-
 
1898
	case case_tag : {
-
 
1899
	    /* Case statements */
-
 
1900
	    exp d1 ;
-
 
1901
	    where w1 ;
-
 
1902
	    bool old_D1_sp = D1_is_special ;
-
 
1903
	    exp arg1 = son ( e ) ;
-
 
1904
	    exp t = arg1 ;
-
 
1905
 
-
 
1906
	    /* Mark the end of the cases */
-
 
1907
	    while ( !last ( t ) ) t = bro ( t ) ;
-
 
1908
	    bro ( t ) = nilexp ;
-
 
1909
 
-
 
1910
	    d1 = sim_exp ( sh ( arg1 ), D1 ) ;
-
 
1911
	    w1 = zw ( d1 ) ;
-
 
1912
	    D1_is_special = 1 ;
-
 
1913
	    regsinproc |= regmsk ( REG_D1 ) ;
-
 
1914
	    coder ( w1, stack, arg1 ) ;
-
 
1915
 
-
 
1916
	    change_var_sh ( slongsh, sh ( arg1 ), w1, D1 ) ;
-
 
1917
	    D1_is_special = old_D1_sp ;
-
 
1918
 
-
 
1919
	    /* Output the case statement */
-
 
1920
	    ( void ) caser ( arg1, L0 ) ;
-
 
1921
 
-
 
1922
	    retcell ( d1 ) ;
-
 
1923
	    return ;
-
 
1924
	}
2061
	}
1925
 
-
 
1926
	case movecont_tag : {
2062
	case movecont_tag: {
1927
	  /* This is done by a library call to memmove */
2063
		/* This is done by a library call to memmove */
1928
	  exp from_exp = son(e);
2064
		exp from_exp = son(e);
1929
	  exp to_exp = bro(from_exp);
2065
		exp to_exp = bro(from_exp);
1930
	  exp num_bytes = bro(to_exp);
2066
		exp num_bytes = bro(to_exp);
1931
#if defined(SUN)
2067
#if defined(SUN)
1932
          mach_op *op = make_extern_ind("_bcopy",0);
2068
		mach_op *op = make_extern_ind("_bcopy",0);
1933
#else
2069
#else
1934
          mach_op *op = make_extern_ind("_memmove",0);
2070
		mach_op *op = make_extern_ind("_memmove",0);
1935
#endif
2071
#endif
1936
          make_comment("move_some ...");
2072
		make_comment("move_some ...");
1937
	  push(slongsh,L32,D0);
2073
		push(slongsh,L32,D0);
1938
	  push(slongsh,L32,D1);
2074
		push(slongsh,L32,D1);
1939
	  push(slongsh,L32,zw(num_bytes));
2075
		push(slongsh,L32,zw(num_bytes));
1940
#if defined(SUN)
2076
#if defined(SUN)
1941
	  push(slongsh,L32,zw(to_exp));
2077
		push(slongsh,L32,zw(to_exp));
1942
	  push(slongsh,L32,zw(from_exp));
2078
		push(slongsh,L32,zw(from_exp));
1943
#else
2079
#else
1944
	  push(slongsh,L32,zw(from_exp));
2080
		push(slongsh,L32,zw(from_exp));
1945
	  push(slongsh,L32,zw(to_exp));
2081
		push(slongsh,L32,zw(to_exp));
1946
#endif
2082
#endif
1947
	  make_instr(m_call,op,null,0);
2083
		make_instr(m_call,op,null,0);
1948
	  dec_stack(-96);
2084
		dec_stack(-96);
1949
	  pop(slongsh,L32,D1);
2085
		pop(slongsh,L32,D1);
1950
	  pop(slongsh,L32,D0);
2086
		pop(slongsh,L32,D0);
1951
          make_comment("move_some done");
2087
		make_comment("move_some done");
1952
	  return ;
2088
		return;
1953
	}
2089
	}
1954
 
-
 
1955
	case diagnose_tag : {
2090
	case diagnose_tag:
1956
#if have_diagnostics
2091
#if have_diagnostics
1957
	    diag_start ( dno ( e ), e ) ;
2092
		diag_start(dno(e), e);
1958
	    coder ( dest, stack, son ( e ) ) ;
2093
		coder(dest, stack, son(e));
1959
	    diag_end ( dno ( e ), e ) ;
2094
		diag_end(dno(e), e);
1960
#else
2095
#else
1961
	    coder ( dest, stack, son ( e ) ) ;
2096
		coder(dest, stack, son(e));
1962
#endif
2097
#endif
1963
	    return ;
2098
		return;
1964
	}
-
 
1965
	case prof_tag :{
2099
	case prof_tag:
1966
	  return;
2100
		return;
1967
	}
-
 
1968
 
-
 
1969
	default :  {
2101
	default:
1970
	    if ( !is_a ( name ( e ) ) ) {
2102
		if (!is_a(name(e))) {
1971
		error ( "Bad operation" ) ;
2103
			error("Bad operation");
1972
		return ;
2104
			return;
1973
	    }
2105
		}
1974
	    if ( name ( dest.wh_exp ) != val_tag){
2106
		if (name(dest.wh_exp) != val_tag) {
1975
               /* All other cases are passed to codec */
2107
			/* All other cases are passed to codec */
1976
               codec ( dest, stack, e ) ;
2108
			codec(dest, stack, e);
1977
               return ;
2109
			return;
1978
	    }
-
 
1979
	    else if (!optop(e)){
2110
		} else if (!optop(e)) {
-
 
2111
			/*
1980
               /* An operation with an error jump must always be performed,
2112
			 * An operation with an error jump must always be
1981
                  even if the result is discarded.  */
2113
			 * performed, even if the result is discarded.
-
 
2114
			 */
1982
               codec (zero,stack,e);
2115
			codec(zero,stack,e);
1983
               return ;
2116
			return;
1984
	    }
2117
		}
1985
	}
2118
	}
1986
    }
-
 
1987
}
2119
}