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 – /trunk/src/installers/680x0/common/codec.c – Rev 2 and 7

Subversion Repositories tendra.SVN

Rev

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

Rev 2 Rev 7
Line -... Line 1...
-
 
1
/*
-
 
2
 * Copyright (c) 2002-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 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 87... Line 117...
87
 *
117
 *
88
 * Revision 1.1  93/02/22  17:15:17  17:15:17  ra (Robert Andrews)
118
 * Revision 1.1  93/02/22  17:15:17  17:15:17  ra (Robert Andrews)
89
 * Initial revision
119
 * Initial revision
90
 *
120
 *
91
--------------------------------------------------------------------------
121
--------------------------------------------------------------------------
92
*/
122
*/
93
 
123
 
94
 
124
 
95
#include "config.h"
125
#include "config.h"
96
#include "common_types.h"
126
#include "common_types.h"
97
#include "exp.h"
127
#include "exp.h"
98
#include "expmacs.h"
128
#include "expmacs.h"
Line 114... Line 144...
114
#include "me_fns.h"
144
#include "me_fns.h"
115
#include "evaluate.h"
145
#include "evaluate.h"
116
#include "ops_shared.h"
146
#include "ops_shared.h"
117
#include "mach_ins.h"
147
#include "mach_ins.h"
118
 
148
 
119
extern bool have_cond ;
149
extern bool have_cond;
120
 
150
 
121
 
151
 
122
/*
152
/*
123
    CONSTRUCT A SIMILAR EXP
153
    CONSTRUCT A SIMILAR EXP
124
 
154
 
125
    This routine, given a where, copies the corresponding exp, and sets
155
    This routine, given a where, copies the corresponding exp, and sets
126
    its sh equal to the given shape.
156
    its sh equal to the given shape.
127
*/
157
*/
128
 
158
 
129
exp sim_exp
159
exp
130
    PROTO_N ( ( sha, w ) )
-
 
131
    PROTO_T ( shape sha X where w )
160
sim_exp(shape sha, where w)
132
{
161
{
133
    exp e = copyexp ( w.wh_exp ) ;
162
	exp e = copyexp(w.wh_exp);
134
    sh ( e ) = sha ;
163
	sh(e) = sha;
135
    return ( e ) ;
164
	return (e);
136
}
165
}
137
 
166
 
138
 
167
 
139
/*
168
/*
140
    PROCESS A UNARY OPERATION
169
    PROCESS A UNARY OPERATION
141
 
170
 
142
    This routine processes the unary operation described by the routine
171
    This routine processes the unary operation described by the routine
143
    op.  The operand is given by a and the result, which is of shape
172
    op.  The operand is given by a and the result, which is of shape
144
    sha, is put into dest.  The stack argument describes the current
173
    sha, is put into dest.  The stack argument describes the current
145
    state of the stack.
174
    state of the stack.
146
*/
175
*/
147
 
176
 
148
static void uop
177
static void
149
    PROTO_N ( ( op, sha, a, dest, stack ) )
-
 
150
    PROTO_T ( void ( *op ) PROTO_S ( ( shape, where, where ) ) X
-
 
151
	      shape sha X exp a X where dest X ash stack )
178
uop(void(*op)(shape, where, where), shape sha, exp a, where dest, ash stack)
152
{
179
{
153
    int old_rmode ;
180
	int old_rmode;
154
    if ( !is_o ( name ( a ) ) ) {
181
	if (!is_o(name(a))) {
-
 
182
		/*
155
	/* If a is not an operand, we need to calculate its value first */
183
		 * If a is not an operand, we need to calculate its value
-
 
184
		 * first.
-
 
185
		 */
156
	if ( whereis ( dest ) == Dreg ) {
186
		if (whereis(dest) == Dreg) {
157
	    /* If dest is in a D register, code a into dest */
187
			/* If dest is in a D register, code a into dest */
158
	    old_rmode = crt_rmode ;
188
			old_rmode = crt_rmode;
159
	    coder ( dest, stack, a ) ;
189
			coder(dest, stack, a);
160
	    crt_rmode = old_rmode ;
190
			crt_rmode = old_rmode;
161
	    /* Now apply op to dest */
191
			/* Now apply op to dest */
162
	    ( *op ) ( sha, dest, dest ) ;
192
			(*op)(sha, dest, dest);
163
	    return ;
193
			return;
164
	} else {
194
		} else {
165
	    /* Code a into D1 */
195
			/* Code a into D1 */
166
	    where w ;
196
			where w;
167
	    exp e = sim_exp ( sha, D1 ) ;
197
			exp e = sim_exp(sha, D1);
168
	    w = zw ( e ) ;
198
			w = zw(e);
169
	    regsinproc |= regmsk ( REG_D1 ) ;
199
			regsinproc |= regmsk(REG_D1);
170
	    old_rmode = crt_rmode ;
200
			old_rmode = crt_rmode;
171
	    coder ( w, stack, a ) ;
201
			coder(w, stack, a);
172
	    crt_rmode = old_rmode ;
202
			crt_rmode = old_rmode;
173
	    /* Apply op to D1 */
203
			/* Apply op to D1 */
174
	    ( *op ) ( sha, w, dest ) ;
204
			(*op)(sha, w, dest);
175
	    retcell ( e ) ;
205
			retcell(e);
176
	    if ( have_cond == 3 ) have_cond = 1 ;
206
			if (have_cond == 3) {
-
 
207
				have_cond = 1;
-
 
208
			}
177
	    return ;
209
			return;
178
	}
210
		}
179
    }
211
	}
180
    /* If a is an operand, apply op directly to a */
212
	/* If a is an operand, apply op directly to a */
181
    ( *op ) ( sha, zw ( a ), dest ) ;
213
	(*op)(sha, zw(a), dest);
182
    return ;
214
	return;
183
}
215
}
184
 
216
 
185
 
217
 
186
/*
218
/*
187
    PROCESS A BINARY OPERATION
219
    PROCESS A BINARY OPERATION
188
 
220
 
189
    This routine processes the binary operation described by the routine
221
    This routine processes the binary operation described by the routine
190
    op.  The operands are given by a and b and the result, which is of
222
    op.  The operands are given by a and b and the result, which is of
191
    shape sha, is put into dest.  The stack argument describes the current
223
    shape sha, is put into dest.  The stack argument describes the current
192
    state of the stack.
224
    state of the stack.
193
*/
225
*/
194
 
226
 
195
static void bop
227
static void
196
    PROTO_N ( ( op, sha, a, b, dest, stack ) )
-
 
197
    PROTO_T ( void ( *op ) PROTO_S ( ( shape, where, where, where ) ) X
228
bop(void(*op)(shape, where, where, where), shape sha, exp a, exp b, where dest,
198
	      shape sha X exp a X exp b X where dest X ash stack )
229
    ash stack)
199
{
230
{
200
    where w, t ;
231
	where w, t;
201
    bool noa = !is_o ( name ( a ) ) ;
232
	bool noa = !is_o(name(a));
202
    bool nob = !is_o ( name ( b ) ) ;
233
	bool nob = !is_o(name(b));
203
    if ( noa ) {
234
	if (noa) {
-
 
235
		/*
204
	/* If a is not an operand, we need to calculate its value first */
236
		 * If a is not an operand, we need to calculate its value
-
 
237
		 * first.
-
 
238
		 */
205
	if ( nob ) {
239
		if (nob) {
206
	    /* a and b cannot both not be operands */
240
			/* a and b cannot both not be operands */
207
	    error ( "Illegal binary operation" ) ;
241
			error("Illegal binary operation");
208
	}
242
		}
209
	t = zw ( b ) ;
243
		t = zw(b);
210
	if ( whereis ( dest ) == Dreg && !interfere ( dest, t ) ) {
244
		if (whereis(dest) == Dreg && !interfere(dest, t)) {
-
 
245
			/*
211
	    /* If dest is in a D register which is not used in b,
246
			 * If dest is in a D register which is not used in b,
212
	       code a into dest */
247
			 * code a into dest.
-
 
248
			 */
213
	    coder ( dest, stack, a ) ;
249
			coder(dest, stack, a);
214
	    /* Apply op to dest and b */
250
			/* Apply op to dest and b */
215
	    ( *op ) ( sha, dest, t, dest ) ;
251
			(*op)(sha, dest, t, dest);
216
	    return ;
252
			return;
217
	} else {
253
		} else {
218
	    /* Code a into D1 */
254
			/* Code a into D1 */
219
	    exp e = sim_exp ( sha, D1 ) ;
255
			exp e = sim_exp(sha, D1);
220
	    w = zw ( e ) ;
256
			w = zw(e);
221
	    regsinproc |= regmsk ( REG_D1 ) ;
257
			regsinproc |= regmsk(REG_D1);
222
	    coder ( w, stack, a ) ;
258
			coder(w, stack, a);
223
	    /* Apply op to D1 and b */
259
			/* Apply op to D1 and b */
224
	    ( *op ) ( sha, w, t, dest ) ;
260
			(*op)(sha, w, t, dest);
225
	    retcell ( e ) ;
261
			retcell(e);
226
	    if ( have_cond == 3 ) have_cond = 1 ;
262
			if (have_cond == 3) {
-
 
263
				have_cond = 1;
-
 
264
			}
227
	    return ;
265
			return;
228
	}
266
		}
229
    }
267
	}
230
    if ( nob ) {
268
	if (nob) {
-
 
269
		/*
231
	/* If b is not an operand, we need to calculate its value first */
270
		 * If b is not an operand, we need to calculate its value
-
 
271
		 * first.
-
 
272
		 */
232
	t = zw ( a ) ;
273
		t = zw(a);
233
	if ( whereis ( dest ) == Dreg && !interfere ( dest, t ) ) {
274
		if (whereis(dest) == Dreg && !interfere(dest, t)) {
-
 
275
			/*
234
	    /* If dest is in a D register which is not used in a,
276
			 * If dest is in a D register which is not used in a,
235
	       code b into dest */
277
			 * code b into dest.
-
 
278
			 */
236
	    coder ( dest, stack, b ) ;
279
			coder(dest, stack, b);
237
	    /* Apply op to a and dest */
280
			/* Apply op to a and dest */
238
	    ( *op ) ( sha, t, dest, dest ) ;
281
			(*op)(sha, t, dest, dest);
239
	    return ;
282
			return;
240
	} else {
283
		} else {
241
	    /* Code b into D1 */
284
			/* Code b into D1 */
242
	    exp e = sim_exp ( sha, D1 ) ;
285
			exp e = sim_exp(sha, D1);
243
	    w = zw ( e ) ;
286
			w = zw(e);
244
	    regsinproc |= regmsk ( REG_D1 ) ;
287
			regsinproc |= regmsk(REG_D1);
245
	    coder ( w, stack, b ) ;
288
			coder(w, stack, b);
246
	    /* Apply op to a and D1 */
289
			/* Apply op to a and D1 */
247
	    ( *op ) ( sha, t, w, dest ) ;
290
			(*op)(sha, t, w, dest);
248
	    retcell ( e ) ;
291
			retcell(e);
249
	    if ( have_cond == 3 ) have_cond = 1 ;
292
			if (have_cond == 3) {
-
 
293
				have_cond = 1;
-
 
294
			}
250
	    return ;
295
			return;
-
 
296
		}
251
	}
297
	}
252
    }
-
 
253
    /* If a and b are both operands, apply op directly */
298
	/* If a and b are both operands, apply op directly */
254
    ( *op ) ( sha, zw ( a ), zw ( b ), dest ) ;
299
	(*op)(sha, zw(a), zw(b), dest);
255
    return ;
300
	return;
256
}
301
}
257
 
302
 
258
 
303
 
259
/*
304
/*
260
    PROCESS A LOGICAL OPERATION
305
    PROCESS A LOGICAL OPERATION
261
 
306
 
262
    This routine processes the logical operation described by the routine
307
    This routine processes the logical operation described by the routine
263
    op.  This operation will be binary, commutative and associative.  The
308
    op.  This operation will be binary, commutative and associative.  The
264
    operands are given by the bro-list starting at the son of e.  The
309
    operands are given by the bro-list starting at the son of e.  The
265
    result is put into dest.  The stack argument describes the current
310
    result is put into dest.  The stack argument describes the current
266
    state of the stack.
311
    state of the stack.
267
*/
312
*/
268
 
313
 
269
static void logop
314
static void
270
    PROTO_N ( ( op, e, dest, stack ) )
-
 
271
    PROTO_T ( void ( *op ) PROTO_S ( ( shape, where, where, where ) ) X
315
logop(void(*op)(shape, where, where, where), exp e, where dest, ash stack)
272
	      exp e X where dest X ash stack )
-
 
273
{
316
{
274
    exp arg1 = son ( e ) ;	/* First argument */
317
	exp arg1 = son(e);	/* First argument */
275
    exp arg2 = bro ( arg1 ) ;	/* Second argument */
318
	exp arg2 = bro(arg1);	/* Second argument */
276
    exp t, u, v ;
319
	exp t, u, v;
277
    where w ;
320
	where w;
278
 
321
 
279
    if ( last ( arg1 ) ) {
322
	if (last(arg1)) {
280
	/* If there is of one argument, code it into dest */
323
		/* If there is of one argument, code it into dest */
281
	coder ( dest, stack, arg1 ) ;
324
		coder(dest, stack, arg1);
282
	return ;
325
		return;
283
    }
326
	}
284
 
327
 
285
    if ( last ( arg2 ) ) {
328
	if (last(arg2)) {
286
	/* If there are two arguments, use bop */
329
		/* If there are two arguments, use bop */
287
	bop ( op, sh ( e ), arg1, arg2, dest, stack ) ;
330
		bop(op, sh(e), arg1, arg2, dest, stack);
288
	return ;
331
		return;
289
    }
332
	}
290
 
333
 
291
    /* Three or more arguments : need to take care about overlap between
334
	/* Three or more arguments : need to take care about overlap between
292
       dest and args, so use D1. */
335
	   dest and args, so use D1. */
293
 
336
 
294
    regsinproc |= regmsk ( REG_D1 ) ;
337
	regsinproc |= regmsk(REG_D1);
295
    v = sim_exp ( sh ( e ), D1 ) ;
338
	v = sim_exp(sh(e), D1);
296
    w = zw ( v ) ;
339
	w = zw(v);
297
    t = arg1 ;
340
	t = arg1;
298
 
341
 
299
    /* Scan the arguments.  t will hold either the first non-operand,
342
	/* Scan the arguments.  t will hold either the first non-operand,
300
       or nilexp if all the arguments are operands.  There should be
343
	   or nilexp if all the arguments are operands.  There should be
301
       at most one non-operand.  */
344
	   at most one non-operand.  */
302
 
345
 
303
    while ( 1 ) {
346
	while (1) {
304
	if ( !is_o ( name ( t ) ) ) break ;
347
		if (!is_o(name(t))) {
-
 
348
			break;
-
 
349
		}
305
	if ( last ( t ) ) {
350
		if (last(t)) {
306
	    t = nilexp ;
351
			t = nilexp;
307
	    break ;
352
			break;
308
	}
353
		}
309
	t = bro ( t ) ;
354
		t = bro(t);
310
    }
355
	}
311
 
356
 
312
    /*
357
	/*
313
       Deal with the case where all the arguments are operands.  This
358
	 * Deal with the case where all the arguments are operands. This does:
314
       does :
-
 
315
		D1 = op ( arg1, arg2 )
359
	 * D1 = op ( arg1, arg2 )
316
		D1 = op ( arg3, D1 )
360
	 * D1 = op ( arg3, D1 )
317
		D1 = op ( arg4, D1 )
361
	 * D1 = op ( arg4, D1 )
318
		....................
362
	 * ....................
319
		dest = op ( argn, D1 )
363
	 * dest = op ( argn, D1 )
320
    */
364
	 */
321
 
365
 
322
    if ( t == nilexp ) {
366
	if (t == nilexp) {
323
	/* Process the first two terms */
367
		/* Process the first two terms */
324
	( *op ) ( sh ( e ), zw ( arg1 ), zw ( arg2 ), w ) ;
368
		(*op)(sh(e), zw(arg1), zw(arg2), w);
325
	t = bro ( arg2 ) ;
369
		t = bro(arg2);
326
	while ( !last ( t ) ) {
370
		while (!last(t)) {
327
	    /* Process the third, fourth, ... terms */
371
			/* Process the third, fourth, ... terms */
328
	    ( *op ) ( sh ( e ), zw ( t ), w, w ) ;
372
			(*op)(sh(e), zw(t), w, w);
329
	    t = bro ( t ) ;
373
			t = bro(t);
330
	}
374
		}
331
	/* Process the last term */
375
		/* Process the last term */
332
	reuseables |= regmsk ( REG_D1 ) ;
376
		reuseables |= regmsk(REG_D1);
333
	( *op ) ( sh ( e ), zw ( t ), w, dest ) ;
377
		(*op)(sh(e), zw(t), w, dest);
334
	reuseables &= ~regmsk ( REG_D1 ) ;
378
		reuseables &= ~regmsk(REG_D1);
335
	retcell ( v ) ;
379
		retcell(v);
336
	if ( have_cond == 3 ) have_cond = 1 ;
380
		if (have_cond == 3) {
-
 
381
			have_cond = 1;
-
 
382
		}
337
	return ;
383
		return;
338
    }
384
	}
339
 
385
 
340
    /*
386
	/*
341
	Deal with the case where one argument, say arg2, is a non-operand.
387
	 * Deal with the case where one argument, say arg2, is a non-operand.
342
	This does :
388
	 * This does:
343
		D1 = arg2
389
	 * D1 = arg2
344
		D1 = op ( arg1, D1 )
390
	 * D1 = op ( arg1, D1 )
345
		D1 = op ( arg3, D1 )
391
	 * D1 = op ( arg3, D1 )
346
		....................
392
	 * ....................
347
		dest = op ( argn, D1 )
393
	 * dest = op ( argn, D1 )
348
    */
394
	 */
349
 
395
 
350
    coder ( w, stack, t ) ;
396
	coder(w, stack, t);
351
    u = arg1 ;
397
	u = arg1;
352
    while ( 1 ) {
398
	while (1) {
353
	if ( t != u ) {
399
		if (t != u) {
354
	    if ( last ( u ) || ( bro ( u ) == t && last ( bro ( u ) ) ) ) {
400
			if (last(u) || (bro(u) == t && last(bro(u)))) {
355
		( *op ) ( sh ( e ), zw ( u ), w, dest ) ;
401
				(*op)(sh(e), zw(u), w, dest);
356
	    } else {
402
			} else {
357
		( *op ) ( sh ( e ), zw ( u ), w, w ) ;
403
				(*op)(sh(e), zw(u), w, w);
358
	    }
404
			}
-
 
405
		}
-
 
406
		if (last(u)) {
-
 
407
			break;
-
 
408
		}
-
 
409
		u = bro(u);
-
 
410
	}
-
 
411
	retcell(v);
-
 
412
	if (have_cond == 3) {
-
 
413
		have_cond = 1;
359
	}
414
	}
360
	if ( last ( u ) ) break ;
-
 
361
	u = bro ( u ) ;
-
 
362
    }
-
 
363
    retcell ( v ) ;
-
 
364
    if ( have_cond == 3 ) have_cond = 1 ;
-
 
365
    return ;
415
	return;
366
}
416
}
367
 
417
 
368
 
418
 
369
/*
419
/*
370
  PROCESS ADD AND SUBTRACT
420
  PROCESS ADD AND SUBTRACT
371
 
421
 
372
  This routine processes the binary operation add.  It does dest = b + a.
422
  This routine processes the binary operation add.  It does dest = b + a.
373
  The second argument, a, may be of the form neg ( a1 ), in which case
423
  The second argument, a, may be of the form neg ( a1 ), in which case
374
  we use sub.
424
  we use sub.
375
*/
425
*/
376
 
426
 
377
static void addsub
427
static void
378
    PROTO_N ( ( sha, a, b, dest, stack ) )
-
 
379
    PROTO_T ( shape sha X where a X where b X where dest X ash stack )
428
addsub(shape sha, where a, where b, where dest, ash stack)
380
{
429
{
381
    exp e = a.wh_exp ;
430
	exp e = a.wh_exp;
382
    if ( name ( e ) == neg_tag ) {
431
	if (name(e) == neg_tag) {
383
      bop ( sub, sha, son ( e ), b.wh_exp, dest, stack ) ;
432
		bop(sub, sha, son(e), b.wh_exp, dest, stack);
384
    }
433
	}
385
    else {
434
	else {
386
      bop ( add, sha, e, b.wh_exp, dest, stack ) ;
435
		bop(add, sha, e, b.wh_exp, dest, stack);
387
    }
436
	}
388
    return ;
437
	return;
389
}
438
}
390
 
439
 
391
 
440
 
392
/*
441
/*
393
  Some constructs only set the overflow bit for 32 bit results.
442
  Some constructs only set the overflow bit for 32 bit results.
394
  This checks values of other varieties to determine whether or not an
443
  This checks values of other varieties to determine whether or not an
395
  overflow has occured
444
  overflow has occured
396
*/
445
*/
397
void check_unset_overflow
446
void
398
    PROTO_N ( (dest,shp) )
-
 
399
    PROTO_T ( where dest X shape shp )
447
check_unset_overflow(where dest, shape shp)
400
{
448
{
401
  exp max_val = getexp(shp,nilexp,0,nilexp,nilexp,0,range_max(shp),
449
	exp max_val = getexp(shp, nilexp, 0, nilexp, nilexp, 0, range_max(shp),
402
		       val_tag);
450
			     val_tag);
403
  exp min_val = getexp(shp,nilexp,0,nilexp,nilexp,0,range_min(shp),
451
	exp min_val = getexp(shp, nilexp, 0, nilexp, nilexp, 0, range_min(shp),
404
		       val_tag);
452
			     val_tag);
405
  bool sw;
453
	bool sw;
406
  move(shp,dest,D0);
454
	move(shp,dest,D0);
407
  if(is_signed(shp) && (shape_size(shp) < 32)) {
455
	if (is_signed(shp) && (shape_size(shp) < 32)) {
408
    ins1((shape_size(shp) == 16)?m_extl : m_extbl,32,D0,1);
456
		ins1((shape_size(shp) == 16) ? m_extl : m_extbl, 32, D0, 1);
409
  }
457
	}
410
  sw = cmp(is_signed(shp)?slongsh:ulongsh,D0,zw(max_val),tst_gr);
458
	sw = cmp(is_signed(shp) ? slongsh : ulongsh, D0, zw(max_val), tst_gr);
411
  test_overflow2(branch_ins(tst_gr,sw,is_signed(shp),is_floating(name(shp))));
459
	test_overflow2(branch_ins(tst_gr, sw, is_signed(shp),
-
 
460
				  is_floating(name(shp))));
412
 
461
 
413
  sw = cmp(is_signed(shp)?slongsh:ulongsh,D0,zw(min_val),tst_ls);
462
	sw = cmp(is_signed(shp) ? slongsh : ulongsh, D0, zw(min_val), tst_ls);
414
  test_overflow2(branch_ins(tst_ls,sw,is_signed(shp), is_floating(name(shp))));
463
	test_overflow2(branch_ins(tst_ls, sw, is_signed(shp),
-
 
464
				  is_floating(name(shp))));
415
 
465
 
416
  kill_exp(max_val,max_val);
466
	kill_exp(max_val, max_val);
417
  kill_exp(min_val,min_val);
467
	kill_exp(min_val, min_val);
418
  return;
468
	return;
419
}
469
}
420
 
470
 
421
 
471
 
422
/*
472
/*
423
  MAIN OPERATION CODING ROUTINE
473
  MAIN OPERATION CODING ROUTINE
424
 
474
 
425
  This routine creates code to evaluate e, putting the result into dest.
475
  This routine creates code to evaluate e, putting the result into dest.
426
  The stack argument describes the current stack position.
476
  The stack argument describes the current stack position.
427
*/
477
*/
428
 
478
 
429
void codec
479
void
430
    PROTO_N ( ( dest, stack, e ) )
-
 
431
    PROTO_T ( where dest X ash stack X exp e )
480
codec(where dest, ash stack, exp e)
432
{
481
{
539
#ifndef tdf3
648
#ifndef tdf3
540
 
-
 
541
          case addptr_tag : {
649
	case make_stack_limit_tag:
542
             exp pointer = son ( e ) ;
-
 
543
             exp offset  = son ( pointer ) ;
-
 
544
 
-
 
545
             make_comment("addptr_tag ...") ;
-
 
546
             mova ( zw ( e ), dest ) ;
-
 
547
             make_comment("addptr_tag done") ;
-
 
548
             return ;
-
 
549
          }
-
 
550
#endif
650
#endif
-
 
651
	case subptr_tag:
-
 
652
	case minptr_tag:
-
 
653
		/* Minus, subtract pointer etc are binary operations */
-
 
654
		bop(sub, sh(e), bro(son(e)), son(e), dest, stack);
-
 
655
		return;
551
	case chvar_tag : {
656
	case mult_tag: {
552
	    /* Change variety, the son of e, a, gives the argument */
657
		/* Multiply is treated as a logical operation */
-
 
658
		int prev_ov = set_overflow(e);
-
 
659
		logop(mult, e, dest, stack);
-
 
660
		if (!optop(e) && (name(sh(e)) != slonghd) &&
553
	    exp a = son ( e ) ;
661
		    (name(sh(e)) != ulonghd)) {
-
 
662
			check_unset_overflow(dest,sh(e));
-
 
663
		}
-
 
664
		clear_overflow(prev_ov);
-
 
665
		return;
-
 
666
	}
-
 
667
	case div0_tag:
-
 
668
	case div2_tag: {
-
 
669
		/* Division is a binary operation */
554
	    int prev_ov = set_overflow(e);
670
		int prev_ov = set_overflow(e);
-
 
671
		bop(div2, sh(e), bro(son(e)), son(e),
-
 
672
		    dest, stack);
-
 
673
		if (!optop(e) && (name(sh(e)) != slonghd) &&
555
	    if ( !is_o ( name ( a ) ) ) {
674
		    (name(sh(e)) != ulonghd)) {
-
 
675
			check_unset_overflow(dest,sh(e));
-
 
676
		}
-
 
677
		clear_overflow(prev_ov);
-
 
678
		return;
-
 
679
	}
-
 
680
	case div1_tag: {
556
		/* If a is not an operand */
681
		/* Division is a binary operation */
-
 
682
		int prev_ov = set_overflow(e);
-
 
683
		bop(div1, sh(e), bro(son(e)), son(e), dest, stack);
-
 
684
		if (!optop(e) && (name(sh(e)) != slonghd) &&
557
		if ( whereis ( dest ) != Dreg ) {
685
		    (name(sh(e)) != ulonghd)) {
-
 
686
			check_unset_overflow(dest,sh(e));
-
 
687
		}
-
 
688
		clear_overflow(prev_ov);
-
 
689
		return;
-
 
690
	}
-
 
691
	case neg_tag: {
-
 
692
		/* Negation is a unary operation */
-
 
693
		int prev_ov = set_overflow(e);
-
 
694
		uop(negate, sh(e), son(e), dest, stack);
-
 
695
		clear_overflow(prev_ov);
-
 
696
		return;
-
 
697
	}
-
 
698
	case abs_tag: {
-
 
699
		/* Abs is a unary operation */
-
 
700
		int prev_ov = set_overflow(e);
-
 
701
		uop(absop, sh(e), son(e), dest, stack);
-
 
702
		clear_overflow(prev_ov);
-
 
703
		return;
-
 
704
	}
-
 
705
	case shl_tag: {
558
		    /* If dest is not a D register, code a into D1 */
706
		/* Shifting left is a binary operation */
-
 
707
		int prev_ov = set_overflow(e);
-
 
708
		bop(shift, sh(e), bro(son(e)), son(e), dest, stack);
-
 
709
		clear_overflow(prev_ov);
-
 
710
		return;
-
 
711
	}
-
 
712
	case shr_tag:
-
 
713
		/* Shifting right is a binary operation */
-
 
714
		bop(rshift, sh(e), bro(son(e)), son(e), dest, stack);
-
 
715
		return;
-
 
716
	case mod_tag: {
-
 
717
		/* Remainder is a binary operation */
-
 
718
		int prev_ov = set_overflow(e);
-
 
719
		bop(rem1, sh(e), bro(son(e)), son(e), dest, stack);
-
 
720
		clear_overflow(prev_ov);
-
 
721
		return;
-
 
722
	}
-
 
723
	case rem0_tag:
-
 
724
	case rem2_tag: {
-
 
725
		/* Remainder is a binary operation */
-
 
726
		int prev_ov = set_overflow(e);
-
 
727
		bop(rem2, sh(e), bro(son(e)), son(e), dest, stack);
-
 
728
		clear_overflow(prev_ov);
-
 
729
		return;
-
 
730
	}
-
 
731
	case round_tag: {
-
 
732
		/* Rounding a floating point number is a unary operation */
-
 
733
		int prev_ov = set_overflow(e);
-
 
734
		set_continue(e);
-
 
735
		crt_rmode = round_number(e);
-
 
736
		uop(round_float, sh(e), son(e), dest, stack);
-
 
737
		clear_overflow(prev_ov);
-
 
738
		clear_continue(e);
-
 
739
		return;
-
 
740
	}
-
 
741
	case fmult_tag: {
-
 
742
		/* Floating multiplication is a floating binary operation */
-
 
743
		exp f1 = son(e);
-
 
744
		exp f2 = bro(f1);
-
 
745
		int prev_ov = set_overflow(e);
-
 
746
		if (last(f2)) {
-
 
747
			/* two arguments */
-
 
748
			fl_binop(fmult_tag, sh(e), zw(f1), zw(f2), dest);
-
 
749
		} else {
-
 
750
			/*
-
 
751
			 * More than two arguments; use %fp1. Assumes that all
-
 
752
			 * parameters are operands.
-
 
753
			 */
559
		    where w ;
754
			where w;
560
		    exp s = sim_exp ( sh ( a ), D1 ) ;
755
			exp s = sim_exp(sh(e), FP1);
-
 
756
			regsinproc |= regmsk(REG_FP1);
561
		    w = zw ( s ) ;
757
			w = zw(s);
-
 
758
 
-
 
759
			fl_binop(fmult_tag,sh(e),zw(f1),zw(f2),w);
-
 
760
			while (!last(f2)) {
-
 
761
				f2 = bro(f2);
-
 
762
				fl_binop(fmult_tag, sh(e), w, zw(f2),
-
 
763
					 (last(f2) ? dest : w));
-
 
764
			}
-
 
765
		}
-
 
766
 
-
 
767
		clear_overflow(prev_ov);
-
 
768
		return;
-
 
769
	}
-
 
770
	case fminus_tag: {
-
 
771
		/* Floating subtraction is a floating binary operation */
-
 
772
		exp f1 = son(e);
-
 
773
		exp f2 = bro(f1);
-
 
774
		int prev_ov = set_overflow(e);
-
 
775
		fl_binop(fminus_tag, sh(e), zw(f2), zw(f1), dest);
-
 
776
		clear_overflow(prev_ov);
-
 
777
		return;
-
 
778
	}
-
 
779
	case fdiv_tag: {
-
 
780
		/* Floating division is a floating binary operation */
-
 
781
		exp f1 = son(e);
-
 
782
		exp f2 = bro(f1);
-
 
783
		int prev_ov = set_overflow(e);
-
 
784
		fl_binop(fdiv_tag, sh(e), zw(f2), zw(f1), dest);
-
 
785
		clear_overflow(prev_ov);
-
 
786
		return;
-
 
787
	}
-
 
788
	case fneg_tag: {
-
 
789
		/* Floating negation is simple */
-
 
790
		int prev_ov = set_overflow(e);
-
 
791
		negate_float(sh(e), zw(son(e)), dest);
-
 
792
		clear_overflow(prev_ov);
-
 
793
		return;
-
 
794
	}
-
 
795
	case fabs_tag: {
-
 
796
		/* Floating absolute value is simple */
-
 
797
		int prev_ov = set_overflow(e);
-
 
798
		abs_float(sh(e), zw(son(e)), dest);
-
 
799
		clear_overflow(prev_ov);
-
 
800
		return;
-
 
801
	}
-
 
802
	case float_tag: {
-
 
803
		/* Casting to a floating point number is simple */
562
		    regsinproc |= regmsk ( REG_D1 ) ;
804
		int prev_ov = set_overflow(e);
-
 
805
		int_to_float(sh(e), zw(son(e)), dest);
563
		    coder ( w, stack, a ) ;
806
		clear_overflow(prev_ov);
-
 
807
		return;
-
 
808
	}
-
 
809
	case chfl_tag: {
564
		    /* Preform the change variety on D1 */
810
		/* Changing a floating variety is simple */
-
 
811
		int prev_ov = set_overflow(e);
565
		    change_var ( sh ( e ), w, dest ) ;
812
		change_flvar(sh(e), zw(son(e)), dest);
-
 
813
		clear_overflow(prev_ov);
-
 
814
		return;
-
 
815
	}
-
 
816
	case and_tag:
-
 
817
		/* And is a logical operation */
-
 
818
		logop(and, e, dest, stack);
-
 
819
		return;
-
 
820
	case or_tag:
-
 
821
		/* Or is a logical operation */
-
 
822
		logop(or, e, dest, stack);
-
 
823
		return;
-
 
824
	case xor_tag:
-
 
825
		/* Xor is a logical operation */
-
 
826
		logop(xor, e, dest, stack);
-
 
827
		return;
-
 
828
	case not_tag:
-
 
829
		/* Not is a unary operation */
-
 
830
		uop(not, sh(e), son(e), dest, stack);
-
 
831
		return;
-
 
832
	case absbool_tag:
-
 
833
		/* The setcc instruction is not used */
-
 
834
		error("Not implemented");
-
 
835
		return;
-
 
836
	case fplus_tag: {
-
 
837
		/* Floating addition is similar to integer addition */
-
 
838
		exp f1 = son(e);	/* First argument */
-
 
839
		exp f2 = bro(f1);	/* Second argument */
-
 
840
		exp t;
-
 
841
		long count_dest = 2;
-
 
842
		exp de = dest.wh_exp;
-
 
843
 
-
 
844
		int prev_ov = set_overflow(e);
-
 
845
 
-
 
846
		if (last(f1)) {
-
 
847
			/* If there is only one argument things are simple */
-
 
848
			move(sh(e), zw(f1), dest);
-
 
849
			clear_overflow(prev_ov);
-
 
850
			return;
-
 
851
		}
-
 
852
 
-
 
853
		if (last(f2)) {
-
 
854
			/* If there are two arguments code directly */
-
 
855
			if (name(f2) == fneg_tag) {
-
 
856
				f2 = son(f2);
-
 
857
				fl_binop(fminus_tag, sh(e), zw(f2),
-
 
858
					 zw(f1), dest);
-
 
859
			} else {
-
 
860
				fl_binop(fplus_tag, sh(e), zw(f1),
566
		    retcell ( s ) ;
861
					 zw(f2), dest);
-
 
862
			}
-
 
863
			clear_overflow(prev_ov);
-
 
864
			return;
-
 
865
		}
-
 
866
 
-
 
867
		if (last(bro(f2)) && name(bro(f2)) == real_tag &&
-
 
868
		    name(dest.wh_exp) != apply_tag &&
567
		    if ( have_cond == 3 ) have_cond = 1 ;
869
		    name(dest.wh_exp) != tail_call_tag &&
-
 
870
		    name(dest.wh_exp) != apply_general_tag) {
-
 
871
			/*
-
 
872
			 * If there are 3 arguments, the last of which is
-
 
873
			 * constant.
-
 
874
			 */
-
 
875
			if (name(f2) == fneg_tag) {
-
 
876
				f2 = son(f2);
-
 
877
				fl_binop(fminus_tag, sh(e), zw(f2), zw(f1),
-
 
878
					 dest);
-
 
879
				fl_binop(fplus_tag, sh(e), zw(bro(f2)), dest,
-
 
880
					 dest);
-
 
881
			} else {
-
 
882
				fl_binop(fplus_tag, sh(e), zw(f1), zw(f2),
-
 
883
					 dest);
-
 
884
				fl_binop(fplus_tag, sh(e), zw(bro(f2)), dest,
-
 
885
					 dest);
-
 
886
			}
568
		    clear_overflow ( prev_ov ) ;
887
			clear_overflow(prev_ov);
569
		    return ;
888
			return;
-
 
889
		}
-
 
890
 
-
 
891
		if (name(de) == ass_tag && name(son(de)) == name_tag &&
-
 
892
		    ((props(son(son(de))) & 0x9) == 0x9)) {
-
 
893
			count_dest = 0;
-
 
894
			t = f1;
-
 
895
			if (eq_where(dest, zw(t))) {
-
 
896
				count_dest++;
-
 
897
			}
-
 
898
			while (!last(t)) {
-
 
899
				t = bro(t);
-
 
900
				if (name(t) == fneg_tag) {
-
 
901
					if (eq_where(zw(son(t)), dest)) {
-
 
902
						count_dest = 2;
-
 
903
					}
-
 
904
				} else {
-
 
905
					if (eq_where(zw(t), dest)) {
-
 
906
						count_dest++;
-
 
907
					}
-
 
908
				}
-
 
909
			}
-
 
910
		}
-
 
911
 
-
 
912
		if (count_dest < 2 &&
-
 
913
		    (name(dest.wh_exp) != apply_tag &&
-
 
914
		     name(dest.wh_exp) != tail_call_tag &&
-
 
915
		     name(dest.wh_exp) != apply_general_tag)) {
-
 
916
			if (count_dest == 1) {
-
 
917
				t = f1;
-
 
918
			} else {
-
 
919
				if (name(f2) == fneg_tag) {
-
 
920
					exp m = son(f2);
-
 
921
					fl_binop(fminus_tag, sh(e), zw(m),
-
 
922
						 zw(f1), dest);
-
 
923
				} else {
-
 
924
					fl_binop(fplus_tag, sh(e), zw(f1),
-
 
925
						 zw(f2), dest);
-
 
926
				}
-
 
927
				t = bro(f2);
-
 
928
			}
-
 
929
 
-
 
930
			for (;;) {
-
 
931
				where tw;
-
 
932
				if (name(t) == fneg_tag) {
-
 
933
					tw = zw(son(t));
-
 
934
					if (!eq_where(dest, tw)) {
-
 
935
						fl_binop(fminus_tag, sh(e), tw,
-
 
936
							 dest, dest);
-
 
937
					}
-
 
938
				} else {
-
 
939
					tw = zw(t);
-
 
940
					if (!eq_where(dest, tw)) {
-
 
941
						fl_binop(fplus_tag, sh(e), tw,
-
 
942
							 dest, dest);
-
 
943
					}
-
 
944
				}
-
 
945
				if (last(t)) {
-
 
946
					break;
-
 
947
				}
-
 
948
				t = bro(t);
-
 
949
			}
-
 
950
		} else {
-
 
951
			if (name(f2) == fneg_tag) {
-
 
952
				fl_binop(fminus_tag, sh(e), zw(son(f2)),
-
 
953
					 zw(f1), FP0);
-
 
954
			} else {
-
 
955
				fl_binop(fplus_tag, sh(e), zw(f1), zw(f2),
-
 
956
					 FP0);
-
 
957
			}
-
 
958
			t = bro(f2);
-
 
959
			while (!last(t)) {
-
 
960
				if (name(t) == fneg_tag) {
-
 
961
					fl_binop(fminus_tag, sh(e), zw(son(t)),
-
 
962
						 FP0, FP0);
-
 
963
				} else {
-
 
964
					fl_binop(fplus_tag, sh(e), zw(t), FP0,
-
 
965
						 FP0);
-
 
966
				}
-
 
967
				t = bro(t);
-
 
968
			}
-
 
969
			if (name(t) == fneg_tag) {
-
 
970
				fl_binop(fminus_tag, sh(e), zw(son(t)), FP0,
-
 
971
					 dest);
-
 
972
			} else {
-
 
973
				fl_binop(fplus_tag, sh(e), zw(t), FP0, dest);
-
 
974
			}
-
 
975
		}
-
 
976
		clear_overflow(prev_ov);
-
 
977
		return;
-
 
978
	}
-
 
979
 
-
 
980
		/*
-
 
981
Note: in the following offset operations I have put the
-
 
982
shape as slongsh rather than sh ( e ).  This is because
-
 
983
the system stddef.h wrongly says that ptrdiff_t is unsigned
-
 
984
and I don't trust people to put it right when making up
-
 
985
TDF libraries.  If this was right sh ( e ) would be slongsh.
-
 
986
		 */
-
 
987
 
-
 
988
	case offset_add_tag:
-
 
989
		make_comment("offset_add_tag...");
-
 
990
		/* Offset addition is a binary operation */
-
 
991
		bop(add, slongsh, son(e), bro(son(e)), dest, stack);
-
 
992
		make_comment("offset_add_tag done");
-
 
993
		return;
-
 
994
	case offset_subtract_tag:
-
 
995
		/* Offset subtraction is a binary operation */
-
 
996
		bop(sub, slongsh, bro(son(e)), son(e), dest, stack);
-
 
997
		return;
-
 
998
	case offset_mult_tag:
-
 
999
		make_comment("offset_mult_tag...");
-
 
1000
		/* Offset multiplication is a binary operation */
-
 
1001
		bop(mult, slongsh, son(e), bro(son(e)), dest, stack);
-
 
1002
		make_comment("offset_mult_tag done");
-
 
1003
		return;
-
 
1004
	case offset_negate_tag:
-
 
1005
		/* Offset negation is a unary operation */
-
 
1006
		uop(negate, slongsh, son(e), dest, stack);
-
 
1007
		return;
-
 
1008
	case offset_div_tag:
-
 
1009
	case offset_div_by_int_tag:
-
 
1010
		/* Offset division is a binary operation */
-
 
1011
		if (name(sh(bro(son(e)))) < slonghd) {
-
 
1012
			exp changer = me_u3(slongsh, bro(son(e)), chvar_tag);
-
 
1013
			bro(son(e)) = changer;
-
 
1014
		}
-
 
1015
		bop(div2, slongsh, bro(son(e)), son(e), dest, stack);
-
 
1016
		return;
-
 
1017
	case offset_pad_tag: {
-
 
1018
		/* Pad an operand */
-
 
1019
		exp  cur_offset = son(e);
-
 
1020
		long cur_align  = al2(sh(cur_offset));
-
 
1021
		long next_align = al2(sh(e));
-
 
1022
 
-
 
1023
		make_comment("offset_pad ...");
-
 
1024
 
-
 
1025
		/* does current alignment include next alignment? */
-
 
1026
 
-
 
1027
		if (cur_align  >= next_align) {
-
 
1028
			if ((next_align !=1) || (cur_align ==1)) {
-
 
1029
				coder(dest, stack, cur_offset);
-
 
1030
			} else {
-
 
1031
				/* left shift */
-
 
1032
				shift(sh(e), mnw(3), zw(cur_offset),dest);
-
 
1033
			}
-
 
1034
		} else {
-
 
1035
			/* cur_align < next_align */
-
 
1036
			where r;
-
 
1037
			if (whereis(dest) == Dreg) {
-
 
1038
				r = dest;
-
 
1039
			} else {
-
 
1040
				r = D1;
-
 
1041
				regsinproc |= regmsk(REG_D1);
-
 
1042
			}
-
 
1043
			codec(r, stack, cur_offset);
-
 
1044
 
-
 
1045
			if (cur_align == 1) {
-
 
1046
				add(slongsh, mnw(next_align - 1), r, r);
-
 
1047
				and(slongsh, mnw(-next_align), r, dest);
-
 
1048
				rshift(sh(e), mnw(3), dest, dest);
-
 
1049
			} else {
-
 
1050
				long al = next_align / 8;
-
 
1051
				add(slongsh, mnw(al - 1), r, r);
-
 
1052
				and(slongsh, mnw(-al), r, dest);
-
 
1053
			}
-
 
1054
		}
-
 
1055
		make_comment("offset_pad done");
-
 
1056
		return;
-
 
1057
	}
-
 
1058
	case bitf_to_int_tag: {
-
 
1059
		if (whereis(dest) == Dreg) {
-
 
1060
			coder(dest, stack, son(e));
-
 
1061
			change_var_sh(sh(e), sh(son(e)), dest, dest);
-
 
1062
		} else {
-
 
1063
			regsinproc |= regmsk(REG_D1);
-
 
1064
			coder(D1, stack, son(e));
-
 
1065
			change_var_sh(sh(e), sh(son(e)), D1, dest);
570
		}
1066
		}
571
		/* If dest is a D register, code a into dest */
-
 
572
		coder ( dest, stack, a ) ;
-
 
573
		/* Preform the change variety on dest */
-
 
574
		change_var_sh ( sh ( e ), sh ( a ), dest, dest ) ;
-
 
575
		clear_overflow ( prev_ov ) ;
-
 
576
		return ;
1067
		return;
577
	    }
-
 
578
	    /* If a is an operand, call change_var directly */
-
 
579
	    change_var ( sh ( e ), zw ( a ), dest ) ;
-
 
580
	    clear_overflow ( prev_ov ) ;
-
 
581
	    return ;
-
 
582
	}
1068
	}
583
 
-
 
584
	case minus_tag : {
-
 
585
	    /* Minus, subtract pointer etc are binary operations */
-
 
586
	    int prev_ov = set_overflow ( e ) ;
-
 
587
	    bop ( sub, sh ( e ), bro ( son ( e ) ), son ( e ),
-
 
588
		  dest, stack ) ;
-
 
589
	    clear_overflow ( prev_ov ) ;
-
 
590
	    return ;
-
 
591
	}
-
 
592
#ifndef tdf3
-
 
593
        case make_stack_limit_tag :
-
 
594
#endif
-
 
595
	case subptr_tag :
-
 
596
	case minptr_tag : {
1069
	case int_to_bitf_tag: {
597
	    /* Minus, subtract pointer etc are binary operations */
-
 
598
	    bop ( sub, sh ( e ), bro ( son ( e ) ), son ( e ),
-
 
599
		  dest, stack ) ;
-
 
600
	    return ;
1070
		where r;
601
	}
-
 
602
 
-
 
603
	case mult_tag : {
-
 
604
	    /* Multiply is treated as a logical operation */
-
 
605
	    int prev_ov = set_overflow ( e ) ;
-
 
606
	    logop ( mult, e, dest, stack ) ;
-
 
607
	    if (!optop(e)&&(name(sh(e))!=slonghd)&&(name(sh(e))!=ulonghd)) {
-
 
608
	      check_unset_overflow(dest,sh(e));
1071
		long nbits = shape_size(sh(e));
609
	    }
-
 
610
	    clear_overflow ( prev_ov ) ;
-
 
611
	    return ;
-
 
612
	}
-
 
613
 
-
 
614
	case div0_tag :
-
 
615
	case div2_tag : {
-
 
616
	    /* Division is a binary operation */
-
 
617
	  int prev_ov = set_overflow(e);
1072
		long mask = lo_bits[nbits];
618
	  bop ( div2, sh ( e ), bro ( son ( e ) ), son ( e ),
-
 
619
		  dest, stack ) ;
-
 
620
	  if (!optop(e)&&(name(sh(e))!=slonghd)&&(name(sh(e))!=ulonghd)) {
-
 
621
	    check_unset_overflow(dest,sh(e));
1073
		r = (whereis(dest) == Dreg ? dest : D0);
622
	  }
-
 
623
	  clear_overflow( prev_ov );
1074
		move(slongsh, zw(son(e)), r);
624
	  return ;
-
 
625
	}
-
 
626
 
-
 
627
	case div1_tag : {
-
 
628
	    /* Division is a binary operation */
-
 
629
	  int prev_ov = set_overflow(e);
-
 
630
	  bop ( div1, sh ( e ), bro ( son ( e ) ), son ( e ),
-
 
631
		  dest, stack ) ;
1075
		and(slongsh, mnw(mask), r, dest);
632
	  if (!optop(e)&&(name(sh(e))!=slonghd)&&(name(sh(e))!=ulonghd)) {
-
 
633
	    check_unset_overflow(dest,sh(e));
-
 
634
	  }
-
 
635
	  clear_overflow( prev_ov );
-
 
636
	  return ;
1076
		return;
637
	}
-
 
638
 
-
 
639
	case neg_tag : {
-
 
640
	    /* Negation is a unary operation */
-
 
641
	    int prev_ov = set_overflow ( e ) ;
-
 
642
	    uop ( negate, sh ( e ), son ( e ), dest, stack ) ;
-
 
643
	    clear_overflow ( prev_ov ) ;
-
 
644
	    return ;
-
 
645
	}
-
 
646
 
-
 
647
	case abs_tag : {
-
 
648
           /* Abs is a unary operation */
-
 
649
           int prev_ov = set_overflow(e);
-
 
650
           uop ( absop, sh ( e ), son ( e ), dest, stack ) ;
-
 
651
           clear_overflow( prev_ov ) ;
-
 
652
           return ;
-
 
653
	}
-
 
654
 
-
 
655
	case shl_tag : {
-
 
656
	    /* Shifting left is a binary operation */
-
 
657
	    int prev_ov = set_overflow ( e ) ;
-
 
658
	    bop ( shift, sh ( e ), bro ( son ( e ) ), son ( e ),
-
 
659
		  dest, stack ) ;
-
 
660
	    clear_overflow ( prev_ov ) ;
-
 
661
	    return ;
-
 
662
	}
1077
	}
-
 
1078
	case offset_max_tag:
-
 
1079
	case max_tag:
-
 
1080
		/* Maximum */
-
 
1081
		bop(maxop, sh(e), son(e), bro(son(e)), dest, stack);
-
 
1082
		return;
-
 
1083
	case min_tag:
-
 
1084
		/* Minimum */
-
 
1085
		bop(minop, sh(e), son(e), bro(son(e)), dest, stack);
-
 
1086
		return;
-
 
1087
	case cont_tag:
-
 
1088
		make_comment("cont_tag ...");
663
 
1089
 
-
 
1090
		if (name(sh(e)) == bitfhd) {
-
 
1091
			bitf_to_int(e, sh(e), dest, stack);
-
 
1092
			return;
-
 
1093
		}
-
 
1094
 
-
 
1095
		move(sh(e), zw(e), dest);
-
 
1096
 
-
 
1097
		make_comment("cont_tag done");
-
 
1098
		return;
-
 
1099
	default:
664
	case shr_tag : {
1100
		if (!is_o(name(e))) {
665
	    /* Shifting right is a binary operation */
1101
			/* If e is not an operand, code e into a register */
-
 
1102
			exp s;
-
 
1103
			where w;
-
 
1104
			if ( name(e) == apply_tag
666
	    bop ( rshift, sh ( e ), bro ( son ( e ) ), son ( e ),
1105
			     || name(e) == apply_general_tag
-
 
1106
			     || name(e) == tail_call_tag) {
667
		  dest, stack ) ;
1107
				s = sim_exp(sh(e), D0);
668
	    return ;
1108
			} else {
-
 
1109
				if (whereis(dest) == Dreg) {
-
 
1110
					/* error("Untested optimization"); */
-
 
1111
					s = sim_exp(sh(e), dest);
-
 
1112
				} else {
-
 
1113
					regsinproc |= regmsk(REG_D1);
-
 
1114
					s = sim_exp(sh(e), D1);
-
 
1115
				}
669
	}
1116
			}
-
 
1117
			w = zw(s);
-
 
1118
 
-
 
1119
			coder(w, stack, e);
670
 
1120
 
671
	case mod_tag : {
-
 
672
	    /* Remainder is a binary operation */
1121
			/* Move the value of this register into dest */
673
	    int prev_ov = set_overflow ( e ) ;
1122
			move(sh(e), w, dest);
674
	    bop ( rem1, sh ( e ), bro ( son ( e ) ), son ( e ),
1123
			retcell(s);
675
		  dest, stack ) ;
1124
			if (have_cond == 3) {
676
	    clear_overflow ( prev_ov ) ;
1125
				have_cond = 1;
-
 
1126
			}
677
	    return ;
1127
			return;
678
	}
1128
		}
679
 
1129
 
680
	case rem0_tag :
-
 
681
	case rem2_tag : {
-
 
682
	    /* Remainder is a binary operation */
-
 
683
	    int prev_ov = set_overflow ( e ) ;
1130
		if (name(e) == reff_tag && shape_size(sh(e)) != 32) {
684
	    bop ( rem2, sh ( e ), bro ( son ( e ) ), son ( e ),
1131
			/* Deal with pointers to bitfields */
685
		  dest, stack ) ;
1132
			exp s;
686
	    clear_overflow ( prev_ov ) ;
-
 
687
	    return ;
1133
			where d;
688
	}
-
 
689
 
-
 
690
	case round_tag : {
1134
			/* s = sim_exp(sh(e), D0); */
691
	    /* Rounding a floating point number is a unary operation */
-
 
692
	    int prev_ov = set_overflow ( e ) ;
1135
			d = mw(dest.wh_exp, dest.wh_off + 32);
693
	    set_continue(e);
1136
			if (shape_size(sh(son(e))) == 32) {
694
	    crt_rmode = round_number ( e ) ;
1137
				make_comment("Pointer to bitfield (32) ...");
695
	    uop ( round_float, sh ( e ), son ( e ), dest, stack ) ;
1138
				coder(dest, stack, son(e));
696
	    clear_overflow ( prev_ov ) ;
1139
				move(slongsh, mnw(no(e)), d);
697
	    clear_continue(e);
1140
				make_comment("Pointer to bitfield (32) done");
698
	    return ;
1141
				return;
699
	}
1142
			}
700
 
-
 
701
	case fmult_tag : {
-
 
702
	    /* Floating multiplication is a floating binary operation */
1143
			make_comment("Pointer to bitfield ...");
703
	    exp f1 = son ( e ) ;
1144
			coder(dest, stack, son(e));
704
	    exp f2 = bro ( f1 ) ;
1145
			add(slongsh, mnw(no(e)), d, d);
705
	    int prev_ov = set_overflow ( e ) ;
1146
			make_comment("Pointer to bitfield done");
706
	    if(last(f2)) {
1147
			return;
707
	      /* two arguments */
-
 
708
	      fl_binop ( fmult_tag, sh ( e ), zw ( f1 ), zw ( f2 ), dest ) ;
-
 
709
	    }
1148
		}
710
	    else {
-
 
711
	      /* more than two arguments; use %fp1.  Assumes that all
-
 
712
	       parameters are operands */
-
 
713
	      where w;
-
 
714
	      exp s = sim_exp(sh(e), FP1);
-
 
715
	      regsinproc |= regmsk(REG_FP1);
-
 
716
	      w = zw(s);
-
 
717
 
1149
 
-
 
1150
		if (name(e) == reff_tag &&
-
 
1151
		    (name(son(e)) == name_tag ||
718
	      fl_binop(fmult_tag,sh(e),zw(f1),zw(f2),w);
1152
		     (name(son(e)) == cont_tag &&
719
	      while(!last(f2)) {
1153
		      name(son(son(e))) == name_tag))) {
-
 
1154
			/* Deal with pointers with offsets */
720
		f2 = bro(f2);
1155
			long off = no(e) / 8;
-
 
1156
			make_comment("reff_tag ...");
721
		fl_binop(fmult_tag,sh(e),w,zw(f2),(last(f2)?dest:w));
1157
			add(slongsh, zw(son(e)), mnw(off), dest);
-
 
1158
			make_comment("reff_tag done");
722
	      }
1159
			return;
723
	    }
1160
		}
724
 
1161
 
-
 
1162
		if ((name(e) == name_tag && isvar(son(e))) ||
725
	    clear_overflow ( prev_ov ) ;
1163
		    name(e) == reff_tag) {
-
 
1164
			/* Deal with pointers */
-
 
1165
			mova(zw(e), dest);
726
	    return ;
1166
			return;
727
	}
1167
		}
728
 
1168
 
729
	case fminus_tag : {
-
 
730
	    /* Floating subtraction is a floating binary operation */
-
 
731
	    exp f1 = son ( e ) ;
-
 
732
	    exp f2 = bro ( f1 ) ;
-
 
733
	    int prev_ov = set_overflow ( e ) ;
-
 
734
	    fl_binop ( fminus_tag, sh ( e ), zw ( f2 ), zw ( f1 ), dest ) ;
-
 
735
	    clear_overflow ( prev_ov ) ;
-
 
736
	    return ;
-
 
737
	}
-
 
738
 
-
 
739
	case fdiv_tag : {
-
 
740
	    /* Floating division is a floating binary operation */
-
 
741
	    exp f1 = son ( e ) ;
-
 
742
	    exp f2 = bro ( f1 ) ;
-
 
743
	    int prev_ov = set_overflow ( e ) ;
-
 
744
	    fl_binop ( fdiv_tag, sh ( e ), zw ( f2 ), zw ( f1 ), dest ) ;
-
 
745
	    clear_overflow ( prev_ov ) ;
-
 
746
	    return ;
-
 
747
	}
-
 
748
 
-
 
749
	case fneg_tag : {
-
 
750
	    /* Floating negation is simple */
-
 
751
	    int prev_ov = set_overflow ( e ) ;
-
 
752
	    negate_float ( sh ( e ), zw ( son ( e ) ), dest ) ;
-
 
753
	    clear_overflow ( prev_ov ) ;
-
 
754
	    return ;
-
 
755
	}
-
 
756
 
-
 
757
	case fabs_tag : {
-
 
758
	    /* Floating absolute value is simple */
-
 
759
	    int prev_ov = set_overflow ( e ) ;
-
 
760
	    abs_float ( sh ( e ), zw ( son ( e ) ), dest ) ;
-
 
761
	    clear_overflow ( prev_ov ) ;
-
 
762
	    return ;
-
 
763
	}
-
 
764
 
-
 
765
	case float_tag : {
-
 
766
	    /* Casting to a floating point number is simple */
-
 
767
	    int prev_ov = set_overflow ( e ) ;
-
 
768
	    int_to_float ( sh ( e ), zw ( son ( e ) ), dest ) ;
-
 
769
	    clear_overflow ( prev_ov ) ;
-
 
770
	    return ;
-
 
771
	}
-
 
772
 
-
 
773
	case chfl_tag : {
-
 
774
	    /* Changing a floating variety is simple */
-
 
775
	    int prev_ov = set_overflow ( e ) ;
-
 
776
	    change_flvar ( sh ( e ), zw ( son ( e ) ), dest ) ;
-
 
777
	    clear_overflow ( prev_ov ) ;
-
 
778
	    return ;
-
 
779
	}
-
 
780
 
-
 
781
	case and_tag : {
-
 
782
	    /* And is a logical operation */
-
 
783
	    logop ( and, e, dest, stack ) ;
-
 
784
	    return ;
-
 
785
	}
-
 
786
 
-
 
787
	case or_tag : {
-
 
788
	    /* Or is a logical operation */
-
 
789
	    logop ( or, e, dest, stack ) ;
-
 
790
	    return ;
-
 
791
	}
-
 
792
 
-
 
793
	case xor_tag : {
-
 
794
	    /* Xor is a logical operation */
-
 
795
	    logop ( xor, e, dest, stack ) ;
-
 
796
	    return ;
-
 
797
	}
-
 
798
 
-
 
799
	case not_tag : {
-
 
800
	    /* Not is a unary operation */
-
 
801
	    uop ( not, sh ( e ), son ( e ), dest, stack ) ;
-
 
802
	    return ;
-
 
803
	}
-
 
804
 
-
 
805
	case absbool_tag : {
-
 
806
	    /* The setcc instruction is not used */
-
 
807
	    error ( "Not implemented" ) ;
-
 
808
	    return ;
-
 
809
	}
-
 
810
 
-
 
811
	case fplus_tag : {
-
 
812
	    /* Floating addition is similar to integer addition */
-
 
813
	    exp f1 = son ( e ) ;	/* First argument */
-
 
814
	    exp f2 = bro ( f1 ) ;	/* Second argument */
-
 
815
	    exp t ;
-
 
816
	    long count_dest = 2 ;
-
 
817
	    exp de = dest.wh_exp ;
-
 
818
 
-
 
819
	    int prev_ov = set_overflow ( e ) ;
-
 
820
 
-
 
821
	    if ( last ( f1 ) ) {
-
 
822
		/* If there is only one argument things are simple */
-
 
823
		move ( sh ( e ), zw ( f1 ), dest ) ;
-
 
824
		clear_overflow ( prev_ov ) ;
-
 
825
		return ;
-
 
826
	    }
-
 
827
 
-
 
828
	    if ( last ( f2 ) ) {
-
 
829
		/* If there are two arguments code directly */
-
 
830
		if ( name ( f2 ) == fneg_tag ) {
1169
		if (name(e) == clear_tag) {
831
		    f2 = son ( f2 ) ;
1170
			/* Deal with clear shapes */
832
		    fl_binop ( fminus_tag, sh ( e ), zw ( f2 ),
-
 
833
			       zw ( f1 ), dest ) ;
1171
			char sn = name(sh(e));
834
		} else {
-
 
835
		    fl_binop ( fplus_tag, sh ( e ), zw ( f1 ),
1172
			if (sn >= shrealhd && sn <= doublehd) {
836
			       zw ( f2 ), dest ) ;
1173
				move(sh(e), fzero, dest);
837
		}
1174
			}
838
		clear_overflow ( prev_ov ) ;
-
 
839
		return ;
1175
#ifndef tdf3
840
	    }
-
 
841
 
-
 
842
	    if ( last ( bro ( f2 ) ) &&
-
 
843
		 name ( bro ( f2 ) ) == real_tag &&
-
 
844
		 name ( dest.wh_exp ) != apply_tag
1176
			if (name(dest.wh_exp) == apply_tag ||
845
              && name ( dest.wh_exp ) != tail_call_tag
-
 
846
              && name ( dest.wh_exp ) != apply_general_tag ) {
1177
			    name(dest.wh_exp) == apply_general_tag ||
847
		/* If there are 3 arguments, the last of which is constant */
-
 
848
		if ( name ( f2 ) == fneg_tag ) {
1178
			    name(dest.wh_exp) == tail_call_tag) {
849
		    f2 = son ( f2 ) ;
-
 
850
		    fl_binop ( fminus_tag, sh ( e ), zw ( f2 ),
-
 
851
			       zw ( f1 ), dest ) ;
-
 
852
		    fl_binop ( fplus_tag, sh ( e ), zw ( bro ( f2 ) ),
-
 
853
			       dest, dest ) ;
-
 
854
		} else {
-
 
855
		    fl_binop ( fplus_tag, sh ( e ), zw ( f1 ),
-
 
856
			       zw ( f2 ), dest ) ;
1179
				move(sh(e), zero, dest);
857
		    fl_binop ( fplus_tag, sh ( e ), zw ( bro ( f2 ) ),
-
 
858
			       dest, dest ) ;
-
 
859
		}
1180
			}
860
		clear_overflow ( prev_ov ) ;
1181
#endif
861
		return ;
1182
			return;
862
	    }
1183
		}
863
 
1184
 
864
	    if ( name ( de ) == ass_tag &&
1185
		if (name(e) == val_tag &&
865
		 name ( son ( de ) ) == name_tag &&
-
 
866
		 ( ( props ( son ( son ( de ) ) ) & 0x9 ) == 0x9 ) ) {
1186
		    ((name(sh(e)) == s64hd) || name(sh(e)) == u64hd)) {
867
		count_dest = 0 ;
1187
			flt64 bval;
868
		t = f1 ;
1188
			where w;
869
		if ( eq_where ( dest, zw ( t ) ) ) count_dest++ ;
-
 
870
		while ( !last ( t ) ) {
-
 
871
		    t = bro ( t ) ;
1189
			bval = exp_to_f64(e);
872
		    if ( name ( t ) == fneg_tag ) {
1190
			if (eq_where(dest, D0_D1)) {
873
			if ( eq_where ( zw ( son ( t ) ), dest ) )
1191
				move_const(slongsh, 32, bval.big, D1);
874
			    count_dest = 2 ;
-
 
875
		    } else {
-
 
876
			if ( eq_where ( zw ( t ), dest ) ) count_dest++ ;
1192
				move_const(slongsh, 32, bval.small, D0);
877
		    }
-
 
878
		}
-
 
879
	    }
-
 
880
 
-
 
881
	    if ( count_dest < 2 && (name ( dest.wh_exp ) != apply_tag
-
 
882
                                &&  name ( dest.wh_exp ) != tail_call_tag
-
 
883
                                &&  name ( dest.wh_exp ) != apply_general_tag) ) {
-
 
884
		if ( count_dest == 1 ) {
-
 
885
		    t = f1 ;
-
 
886
		} else {
1193
			} else {
887
		    if ( name ( f2 ) == fneg_tag ) {
-
 
888
			exp m = son ( f2 ) ;
-
 
889
			fl_binop ( fminus_tag, sh ( e ), zw ( m ),
-
 
890
				   zw ( f1 ), dest ) ;
-
 
891
		    } else {
1194
				w = dest;
892
			fl_binop ( fplus_tag, sh ( e ), zw ( f1 ),
-
 
893
				   zw ( f2 ), dest ) ;
-
 
894
		    }
-
 
895
		    t = bro ( f2 ) ;
-
 
896
		}
-
 
897
 
-
 
898
		for ( ; ; ) {
-
 
899
		    where tw ;
-
 
900
		    if ( name ( t ) == fneg_tag ) {
-
 
901
			tw = zw ( son ( t ) ) ;
-
 
902
			if ( !eq_where ( dest, tw ) ) {
-
 
903
			    fl_binop ( fminus_tag, sh ( e ), tw, dest, dest ) ;
1195
				move_const(sh(e), 32, bval.small, w);
904
			}
-
 
905
		    } else {
-
 
906
			tw = zw ( t ) ;
1196
				w.wh_off += 32;
907
			if ( !eq_where ( dest, tw ) ) {
-
 
908
			    fl_binop ( fplus_tag, sh ( e ), tw, dest, dest ) ;
1197
				move_const(sh(e), 32, bval.big, w);
909
			}
1198
			}
910
		    }
1199
			return;
911
		    if ( last ( t ) ) break ;
-
 
912
		    t = bro ( t ) ;
-
 
913
		}
1200
		}
914
	    } else {
-
 
915
		if ( name ( f2 ) == fneg_tag ) {
-
 
916
		    fl_binop ( fminus_tag, sh ( e ), zw ( son ( f2 ) ),
-
 
917
			       zw ( f1 ), FP0 ) ;
-
 
918
		} else {
-
 
919
		    fl_binop ( fplus_tag, sh ( e ), zw ( f1 ),
-
 
920
			       zw ( f2 ), FP0 ) ;
-
 
921
		}
-
 
922
		t = bro ( f2 ) ;
-
 
923
		while ( !last ( t ) ) {
-
 
924
		    if ( name ( t ) == fneg_tag ) {
-
 
925
			fl_binop ( fminus_tag, sh ( e ), zw ( son ( t ) ),
-
 
926
				   FP0, FP0 ) ;
-
 
927
		    } else {
-
 
928
			fl_binop ( fplus_tag, sh ( e ), zw ( t ), FP0, FP0 ) ;
-
 
929
		    }
-
 
930
		    t = bro ( t ) ;
-
 
931
		}
-
 
932
		if ( name ( t ) == fneg_tag ) {
-
 
933
		    fl_binop ( fminus_tag, sh ( e ), zw ( son ( t ) ),
-
 
934
			       FP0, dest ) ;
-
 
935
		} else {
-
 
936
		    fl_binop ( fplus_tag, sh ( e ), zw ( t ), FP0, dest ) ;
-
 
937
		}
-
 
938
	    }
-
 
939
	    clear_overflow ( prev_ov ) ;
-
 
940
	    return ;
-
 
941
	}
-
 
942
 
-
 
943
	/*
-
 
944
	     Note : in the following offset operations I have put the
-
 
945
	     shape as slongsh rather than sh ( e ).  This is because
-
 
946
	     the system stddef.h wrongly says that ptrdiff_t is unsigned
-
 
947
	     and I don't trust people to put it right when making up
-
 
948
	     TDF libraries.  If this was right sh ( e ) would be slongsh.
-
 
949
	*/
-
 
950
 
-
 
951
	case offset_add_tag : {
-
 
952
           make_comment("offset_add_tag...");
-
 
953
	    /* Offset addition is a binary operation */
-
 
954
	    bop ( add, slongsh, son ( e ), bro ( son ( e ) ), dest, stack ) ;
-
 
955
           make_comment("offset_add_tag done");
-
 
956
	    return ;
-
 
957
	}
-
 
958
 
1201
 
959
	case offset_subtract_tag : {
-
 
960
	    /* Offset subtraction is a binary operation */
-
 
961
	    bop ( sub, slongsh, bro ( son ( e ) ), son ( e ), dest, stack ) ;
-
 
962
	    return ;
-
 
963
	}
-
 
964
 
-
 
965
	case offset_mult_tag : {
-
 
966
           make_comment("offset_mult_tag...");
-
 
967
	    /* Offset multiplication is a binary operation */
-
 
968
	    bop ( mult, slongsh, son ( e ), bro ( son ( e ) ), dest, stack ) ;
-
 
969
           make_comment("offset_mult_tag done");
-
 
970
	    return ;
-
 
971
	}
-
 
972
 
-
 
973
	case offset_negate_tag : {
-
 
974
	    /* Offset negation is a unary operation */
-
 
975
	    uop ( negate, slongsh, son ( e ), dest, stack ) ;
-
 
976
	    return ;
-
 
977
	}
-
 
978
 
-
 
979
	case offset_div_tag :
-
 
980
        case offset_div_by_int_tag : {
-
 
981
	  /* Offset division is a binary operation */
-
 
982
	  if(name(sh(bro(son(e)))) < slonghd){
-
 
983
	    exp changer = me_u3(slongsh,bro(son(e)),chvar_tag);
-
 
984
	    bro(son(e)) = changer;
-
 
985
	  }
-
 
986
	  bop ( div2, slongsh, bro ( son ( e ) ), son ( e ), dest, stack ) ;
-
 
987
	  return ;
-
 
988
	}
-
 
989
 
-
 
990
	case offset_pad_tag : {
-
 
991
           /* Pad an operand */
-
 
992
           exp  cur_offset = son ( e ) ;
-
 
993
           long cur_align  = al2 ( sh ( cur_offset ) ) ;
-
 
994
           long next_align = al2 ( sh ( e ) ) ;
-
 
995
 
-
 
996
           make_comment("offset_pad ...") ;
-
 
997
 
-
 
998
           /* does current alignment include next alignment? */
-
 
999
 
-
 
1000
           if ( cur_align  >= next_align ) {
-
 
1001
 
-
 
1002
	      if( ( next_align !=1 ) || ( cur_align ==1 ) ) {
-
 
1003
                 coder ( dest, stack, cur_offset ) ;
-
 
1004
	      }
-
 
1005
	      else {
-
 
1006
                 /* left shift */
-
 
1007
                 shift( sh(e), mnw(3), zw(cur_offset),dest);
-
 
1008
	      }
-
 
1009
 
-
 
1010
           } else {
-
 
1011
              /* cur_align  < next_align */
-
 
1012
              where r ;
-
 
1013
              if ( whereis ( dest ) == Dreg ) {
-
 
1014
                 r = dest ;
-
 
1015
              } else {
-
 
1016
                 r = D1 ;
-
 
1017
                 regsinproc |= regmsk ( REG_D1 ) ;
-
 
1018
              }
-
 
1019
              codec ( r, stack, cur_offset ) ;
-
 
1020
 
-
 
1021
              if( cur_align == 1){
-
 
1022
                 add ( slongsh, mnw ( next_align - 1 ), r, r ) ;
-
 
1023
                 and ( slongsh, mnw ( -next_align ), r, dest ) ;
-
 
1024
                 rshift(sh(e),mnw(3),dest,dest);
-
 
1025
              }
-
 
1026
              else {
-
 
1027
                 long al = next_align / 8 ;
-
 
1028
                 add ( slongsh, mnw ( al - 1 ), r, r ) ;
-
 
1029
                 and ( slongsh, mnw ( -al ), r, dest ) ;
-
 
1030
              }
-
 
1031
           }
-
 
1032
           make_comment("offset_pad done") ;
-
 
1033
           return ;
-
 
1034
	}
-
 
1035
 
-
 
1036
	case bitf_to_int_tag : {
-
 
1037
	    if ( whereis ( dest ) == Dreg ) {
-
 
1038
		coder ( dest, stack, son ( e ) ) ;
-
 
1039
		change_var_sh ( sh ( e ), sh ( son ( e ) ), dest, dest ) ;
-
 
1040
	    } else {
-
 
1041
		regsinproc |= regmsk ( REG_D1 ) ;
-
 
1042
		coder ( D1, stack, son ( e ) ) ;
-
 
1043
		change_var_sh ( sh ( e ), sh ( son ( e ) ), D1, dest ) ;
-
 
1044
	    }
-
 
1045
	    return ;
-
 
1046
	}
-
 
1047
 
-
 
1048
	case int_to_bitf_tag : {
-
 
1049
	    where r ;
-
 
1050
	    long nbits = shape_size ( sh ( e ) ) ;
-
 
1051
	    long mask = lo_bits [ nbits ] ;
-
 
1052
	    r = ( whereis ( dest ) == Dreg ? dest : D0 ) ;
-
 
1053
	    move ( slongsh, zw ( son ( e ) ), r ) ;
-
 
1054
	    and ( slongsh, mnw ( mask ), r, dest ) ;
-
 
1055
	    return ;
-
 
1056
	}
-
 
1057
	case offset_max_tag :
-
 
1058
	case max_tag : {
-
 
1059
	    /* Maximum */
-
 
1060
	    bop ( maxop, sh ( e ), son ( e ), bro ( son ( e ) ), dest, stack ) ;
-
 
1061
	    return ;
-
 
1062
	}
-
 
1063
 
-
 
1064
	case min_tag : {
-
 
1065
	    /* Minimum */
-
 
1066
	    bop ( minop, sh ( e ), son ( e ), bro ( son ( e ) ), dest, stack ) ;
-
 
1067
	    return ;
-
 
1068
	}
-
 
1069
 
-
 
1070
	case cont_tag : {
-
 
1071
           make_comment("cont_tag ...") ;
-
 
1072
 
-
 
1073
           if ( name ( sh ( e ) ) == bitfhd ) {
-
 
1074
              bitf_to_int ( e, sh ( e ), dest, stack ) ;
-
 
1075
              return ;
-
 
1076
           }
-
 
1077
 
-
 
1078
           move ( sh ( e ), zw ( e ), dest ) ;
-
 
1079
 
-
 
1080
           make_comment("cont_tag done") ;
-
 
1081
           return ;
-
 
1082
	}
-
 
1083
 
-
 
1084
	default : {
-
 
1085
 
-
 
1086
	    if ( !is_o ( name ( e ) ) ) {
-
 
1087
		/* If e is not an operand, code e into a register */
-
 
1088
		exp s ;
-
 
1089
		where w ;
-
 
1090
		if (   name ( e ) == apply_tag
-
 
1091
                    || name ( e ) == apply_general_tag
-
 
1092
                    || name ( e ) == tail_call_tag ) {
-
 
1093
		    s = sim_exp ( sh ( e ), D0 ) ;
-
 
1094
		} else {
-
 
1095
		    if ( whereis ( dest ) == Dreg ) {
-
 
1096
/*			error ( "Untested optimization" ) ;*/
-
 
1097
			s = sim_exp ( sh ( e ), dest ) ;
-
 
1098
		    } else {
-
 
1099
			regsinproc |= regmsk ( REG_D1 ) ;
-
 
1100
			s = sim_exp ( sh ( e ), D1 ) ;
-
 
1101
		    }
-
 
1102
		}
-
 
1103
		w = zw ( s ) ;
-
 
1104
 
-
 
1105
		coder ( w, stack, e ) ;
-
 
1106
 
1202
 
1107
		/* Move the value of this register into dest */
1203
		/* If all else fails, use move */
1108
		move ( sh ( e ), w, dest ) ;
-
 
1109
		retcell ( s ) ;
-
 
1110
		if ( have_cond == 3 ) have_cond = 1 ;
-
 
1111
		return ;
-
 
1112
	    }
-
 
1113
 
-
 
1114
	    if ( name ( e ) == reff_tag && shape_size ( sh ( e ) ) != 32 ) {
-
 
1115
		/* Deal with pointers to bitfields */
-
 
1116
                exp s ;
-
 
1117
		where d ;
-
 
1118
/*                s = sim_exp ( sh ( e ), D0 ) ; */
-
 
1119
		d = mw ( dest.wh_exp, dest.wh_off + 32 ) ;
-
 
1120
		if ( shape_size ( sh ( son ( e ) ) ) == 32 ) {
-
 
1121
                    make_comment("Pointer to bitfield (32) ...") ;
-
 
1122
		    coder ( dest, stack, son ( e ) ) ;
-
 
1123
		    move ( slongsh, mnw ( no ( e ) ), d ) ;
-
 
1124
                    make_comment("Pointer to bitfield (32) done") ;
-
 
1125
		    return ;
-
 
1126
		}
-
 
1127
		make_comment("Pointer to bitfield ...") ;
-
 
1128
		coder ( dest, stack, son ( e ) ) ;
-
 
1129
		add ( slongsh, mnw ( no ( e ) ), d, d ) ;
-
 
1130
		make_comment("Pointer to bitfield done") ;
-
 
1131
		return ;
-
 
1132
	    }
-
 
1133
 
-
 
1134
	    if ( name ( e ) == reff_tag &&
1204
		if (name(e) == top_tag) {
1135
		 ( name ( son ( e ) ) == name_tag ||
-
 
1136
		 ( name ( son ( e ) ) == cont_tag &&
-
 
1137
		   name ( son ( son ( e ) ) ) == name_tag ) ) ) {
-
 
1138
		/* Deal with pointers with offsets */
-
 
1139
		long off = no ( e ) / 8 ;
-
 
1140
                make_comment("reff_tag ...");
-
 
1141
		add ( slongsh, zw ( son ( e ) ), mnw ( off ), dest ) ;
-
 
1142
                make_comment("reff_tag done");
-
 
1143
		return ;
1205
			return;
1144
	    }
-
 
1145
 
-
 
1146
	    if ( ( name ( e ) == name_tag && isvar ( son ( e ) ) ) ||
-
 
1147
		 name ( e ) == reff_tag){
-
 
1148
	      /* Deal with pointers */
-
 
1149
	      mova ( zw ( e ), dest ) ;
-
 
1150
	      return ;
-
 
1151
	    }
-
 
1152
 
-
 
1153
	    if ( name ( e ) == clear_tag ) {
-
 
1154
		/* Deal with clear shapes */
-
 
1155
		char sn = name ( sh ( e ) ) ;
-
 
1156
		if ( sn >= shrealhd && sn <= doublehd ) {
-
 
1157
		    move ( sh ( e ), fzero, dest ) ;
-
 
1158
		}
1206
		}
1159
#ifndef tdf3
-
 
1160
                if(name (dest.wh_exp) == apply_tag ||
-
 
1161
                   name (dest.wh_exp) == apply_general_tag ||
-
 
1162
                   name (dest.wh_exp) == tail_call_tag ) {
-
 
1163
                   move ( sh ( e ), zero, dest ) ;
-
 
1164
                }
-
 
1165
#endif
-
 
1166
		return ;
-
 
1167
	    }
-
 
1168
 
-
 
1169
	    if (name(e) == val_tag && ((name(sh(e)) == s64hd) ||
-
 
1170
				      name(sh(e)) == u64hd)){
-
 
1171
	      flt64 bval;
-
 
1172
	      where w;
-
 
1173
	      bval = exp_to_f64(e);
-
 
1174
              if ( eq_where ( dest, D0_D1 ) ) {
-
 
1175
                 move_const(slongsh,32,bval.big, D1);
-
 
1176
                 move_const(slongsh,32,bval.small, D0);
-
 
1177
              }
-
 
1178
              else {
-
 
1179
                 w = dest;
-
 
1180
                 move_const(sh(e),32,bval.small,w);
-
 
1181
                 w.wh_off += 32;
-
 
1182
                 move_const(sh(e),32,bval.big,w);
-
 
1183
              }
-
 
1184
	      return;
-
 
1185
	    }
-
 
1186
 
-
 
1187
 
-
 
1188
	    /* If all else fails, use move */
-
 
1189
	    if ( name ( e ) == top_tag ) return ;
-
 
1190
 
1207
 
1191
	    move ( sh ( e ), zw ( e ), dest ) ;
1208
		move(sh(e), zw(e), dest);
1192
	    return ;
1209
		return;
1193
	}
1210
	}
1194
    }
-
 
1195
}
1211
}