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-2005 The TenDRA Project <http://www.tendra.org/>.
-
 
3
 * All rights reserved.
-
 
4
 *
-
 
5
 * Redistribution and use in source and binary forms, with or without
-
 
6
 * modification, are permitted provided that the following conditions are met:
-
 
7
 *
-
 
8
 * 1. Redistributions of source code must retain the above copyright notice,
-
 
9
 *    this list of conditions and the following disclaimer.
-
 
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
-
 
11
 *    this list of conditions and the following disclaimer in the documentation
-
 
12
 *    and/or other materials provided with the distribution.
-
 
13
 * 3. Neither the name of The TenDRA Project nor the names of its contributors
-
 
14
 *    may be used to endorse or promote products derived from this software
-
 
15
 *    without specific, prior written permission.
-
 
16
 *
-
 
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
-
 
18
 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-
 
19
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-
 
20
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
-
 
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-
 
22
 * EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-
 
23
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-
 
24
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-
 
25
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-
 
26
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-
 
27
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 
28
 *
-
 
29
 * $Id$
-
 
30
 */
1
/*
31
/*
2
    		 Crown Copyright (c) 1997
32
    		 Crown Copyright (c) 1997
3
 
33
 
4
    This TenDRA(r) Computer Program is subject to Copyright
34
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
35
    owned by the United Kingdom Secretary of State for Defence
Line 161... Line 191...
161
 
191
 
162
/* PROCEDURES */
192
/* PROCEDURES */
163
 
193
 
164
/* returns true if is_o(e) but not a possible 80386 operand */
194
/* returns true if is_o(e) but not a possible 80386 operand */
165
int is_crc
195
int is_crc
166
    PROTO_N ( (e) )
-
 
167
    PROTO_T ( exp e )
196
(exp e)
168
{
197
{
169
		/* make sure (is_o && is_crc -> !is_opnd) */
198
		/* make sure (is_o && is_crc -> !is_opnd) */
170
  if (name(e) == name_tag) {
199
  if (name(e) == name_tag) {
171
    if (isvar(son(e)))
200
    if (isvar(son(e)))
172
      return (!isglob(son(e)) || PIC_code);
201
      return(!isglob(son(e)) || PIC_code);
173
    /* else */
202
    /* else */
174
      return (son(son(e)) == nilexp ||
203
      return(son(son(e)) == nilexp ||
175
	(isglob(son(e)) && PIC_code && name(sh(son(e))) == prokhd &&
204
	(isglob(son(e)) && PIC_code && name(sh(son(e))) == prokhd &&
176
			!(brog(son(e)) -> dec_u.dec_val.extnamed)) ||
205
			!(brog(son(e)) -> dec_u.dec_val.extnamed)) ||
177
	(name(son(son(e))) == ident_tag && isparam(son(son(e))) ));
206
	(name(son(son(e))) == ident_tag && isparam(son(son(e)))));
178
  }
207
  }
179
 
208
 
180
  if (name(e) == reff_tag || name(e) == field_tag)
209
  if (name(e) == reff_tag || name(e) == field_tag)
181
    return 1;
210
    return 1;
182
 
211
 
183
  if (name(e) != cont_tag)
212
  if (name(e)!= cont_tag)
184
    return 0;
213
    return 0;
185
 
214
 
186
  if (name(son(e)) == cont_tag)
215
  if (name(son(e)) == cont_tag)
187
    return 1;
216
    return 1;
188
 
217
 
Line 199... Line 228...
199
   80386 operand, then uop produces code
228
   80386 operand, then uop produces code
200
   for a to put it into eax (reg0) and
229
   for a to put it into eax (reg0) and
201
   then applies op to eax, putting the
230
   then applies op to eax, putting the
202
   result into dest. */
231
   result into dest. */
203
void uop
232
void uop
204
    PROTO_N ( (op, sha, a, dest, stack) )
-
 
205
    PROTO_T ( void (*op) PROTO_S ((shape, where, where)) X shape sha X
233
(void(*op)(shape, where, where), shape sha, exp a, where dest, ash stack)
206
	      exp a X where dest X ash stack )
-
 
207
{
234
{
208
  if (!is_o (name (a)) || is_crc(a)) {
235
  if (!is_o(name(a)) || is_crc(a)) {
209
    where qw;
236
    where qw;
210
    if (!inmem(dest))
237
    if (!inmem(dest))
211
      qw.where_exp = copyexp (dest.where_exp);
238
      qw.where_exp = copyexp(dest.where_exp);
212
    else
239
    else
213
      qw.where_exp = copyexp (reg0.where_exp);
240
      qw.where_exp = copyexp(reg0.where_exp);
214
    sh (qw.where_exp) = sha;
241
    sh(qw.where_exp) = sha;
215
    qw.where_off = 0;
242
    qw.where_off = 0;
216
    coder (qw, stack, a);
243
    coder(qw, stack, a);
217
    (*op) (sha, qw, dest);
244
   (*op)(sha, qw, dest);
218
    retcell (qw.where_exp);
245
    retcell(qw.where_exp);
219
    cond1_set = 0;
246
    cond1_set = 0;
220
    return;
247
    return;
221
  };
248
  };
222
  (*op) (sha, mw (a, 0), dest);
249
 (*op)(sha, mw(a, 0), dest);
223
  return;
250
  return;
224
}
251
}
225
 
252
 
226
static int no_reg_needed
253
static int no_reg_needed
227
    PROTO_N ( (e) )
-
 
228
    PROTO_T ( exp e )
254
(exp e)
229
{
255
{
230
  if (name(e) == val_tag)
256
  if (name(e) == val_tag)
231
    return 1;
257
    return 1;
232
  if (name(e) == cont_tag &&
258
  if (name(e) == cont_tag &&
233
	name(son(e)) == name_tag &&
259
	name(son(e)) == name_tag &&
234
	isvar(son(son(e))) &&
260
	isvar(son(son(e))) &&
235
	ptno(son(son(e))) != reg_pl)
261
	ptno(son(son(e)))!= reg_pl)
236
    return 1;
262
    return 1;
237
  if (name(e) == name_tag &&
263
  if (name(e) == name_tag &&
238
	!isvar(son(e)) &&
264
	!isvar(son(e)) &&
239
	ptno(son(e)) != reg_pl)
265
	ptno(son(e))!= reg_pl)
240
    return 1;
266
    return 1;
241
  return 0;
267
  return 0;
242
}
268
}
243
 
269
 
244
/* op is a procedure for encoding a binary
270
/* op is a procedure for encoding a binary
Line 254... Line 280...
254
   for it to put it into eax (reg0) and
280
   for it to put it into eax (reg0) and
255
   then applies op to eax and the other
281
   then applies op to eax and the other
256
   operand, putting the result into dest.
282
   operand, putting the result into dest.
257
*/
283
*/
258
void bop
284
void bop
259
    PROTO_N ( (op, sha, a, b, dest, stack) )
-
 
260
    PROTO_T ( void (*op) PROTO_S ((shape, where, where, where)) X
-
 
261
	      shape sha X exp a X exp b X where dest X ash stack )
285
(void(*op)(shape, where, where, where), shape sha, exp a, exp b, where dest, ash stack)
262
{
286
{
263
  where qw;
287
  where qw;
264
 
288
 
265
  if (!is_o (name (a)) || is_crc(a)) {
289
  if (!is_o(name(a)) || is_crc(a)) {
266
    if (!inmem(dest) && no_reg_needed(b))
290
    if (!inmem(dest) && no_reg_needed(b))
267
      qw.where_exp = copyexp (dest.where_exp);
291
      qw.where_exp = copyexp(dest.where_exp);
268
    else
292
    else
269
      qw.where_exp = copyexp (reg0.where_exp);
293
      qw.where_exp = copyexp(reg0.where_exp);
270
    sh (qw.where_exp) = sha;
294
    sh(qw.where_exp) = sha;
271
    qw.where_off = 0;
295
    qw.where_off = 0;
272
    coder (qw, stack, a);
296
    coder(qw, stack, a);
273
    (*op) (sha, qw, mw (b, 0), dest);
297
   (*op)(sha, qw, mw(b, 0), dest);
274
    retcell (qw.where_exp);
298
    retcell(qw.where_exp);
275
    cond1_set = 0;
299
    cond1_set = 0;
276
    return;
300
    return;
277
  };
301
  };
278
  if (!is_o (name (b)) || is_crc(b)) {
302
  if (!is_o(name(b)) || is_crc(b)) {
279
    if (!inmem(dest) && no_reg_needed(a))
303
    if (!inmem(dest) && no_reg_needed(a))
280
      qw.where_exp = copyexp (dest.where_exp);
304
      qw.where_exp = copyexp(dest.where_exp);
281
    else
305
    else
282
      qw.where_exp = copyexp (reg0.where_exp);
306
      qw.where_exp = copyexp(reg0.where_exp);
283
    sh (qw.where_exp) = sha;
307
    sh(qw.where_exp) = sha;
284
    qw.where_off = 0;
308
    qw.where_off = 0;
285
    coder (qw, stack, b);
309
    coder(qw, stack, b);
286
    (*op) (sha, mw (a, 0), qw, dest);
310
   (*op)(sha, mw(a, 0), qw, dest);
287
    retcell (qw.where_exp);
311
    retcell(qw.where_exp);
288
    cond1_set = 0;
312
    cond1_set = 0;
289
    return;
313
    return;
290
  };
314
  };
291
 
315
 
292
  (*op) (sha, mw (a, 0), mw (b, 0), dest);
316
 (*op)(sha, mw(a, 0), mw(b, 0), dest);
293
  return;
317
  return;
294
}
318
}
295
 
319
 
296
/* process the binary logical operation
320
/* process the binary logical operation
297
   exp. op is the compiling procedure for
321
   exp. op is the compiling procedure for
Line 305... Line 329...
305
   the arguments will not be a possible
329
   the arguments will not be a possible
306
   80386 operand. If there is such an
330
   80386 operand. If there is such an
307
   argument, logop precomputes it, putting
331
   argument, logop precomputes it, putting
308
   the value into reg0. */
332
   the value into reg0. */
309
static void logop
333
static void logop
310
    PROTO_N ( (op, e, dest, stack) )
-
 
311
    PROTO_T ( void (*op) PROTO_S ((shape, where, where, where)) X
-
 
312
	      exp e X where dest X ash stack )
334
(void(*op)(shape, where, where, where), exp e, where dest, ash stack)
313
{
335
{
314
  exp arg1 = son (e);
336
  exp arg1 = son(e);
315
  exp arg2 = bro (arg1);
337
  exp arg2 = bro(arg1);
316
  shape sha = sh(e);
338
  shape sha = sh(e);
317
  exp t, u;
339
  exp t, u;
318
  where qw;
340
  where qw;
319
 
341
 
320
  if (last (arg1)) {
342
  if (last(arg1)) {
321
    coder (dest, stack, arg1);
343
    coder(dest, stack, arg1);
322
    return;
344
    return;
323
  };
345
  };
324
 
346
 
325
  if (last (arg2)) {		/* just two arguments. */
347
  if (last (arg2)) {		/* just two arguments. */
326
    bop (op, sha, arg1, arg2, dest, stack);
348
    bop(op, sha, arg1, arg2, dest, stack);
327
    return;
349
    return;
328
  };
350
  };
329
  /* need to take care about overlap between dest and args or to avoid
351
  /* need to take care about overlap between dest and args or to avoid
330
     extra push. So use reg0. */
352
     extra push. So use reg0. */
331
  qw.where_exp = copyexp (reg0.where_exp);
353
  qw.where_exp = copyexp(reg0.where_exp);
332
  sh (qw.where_exp) = sha;
354
  sh(qw.where_exp) = sha;
333
  qw.where_off = 0;
355
  qw.where_off = 0;
334
  t = arg1;
356
  t = arg1;
335
  /* now look for an argument which is not a possible 80386 operand */
357
  /* now look for an argument which is not a possible 80386 operand */
336
  while (1) {
358
  while (1) {
337
    if (!is_o (name (t)) || is_crc(t))
359
    if (!is_o(name(t)) || is_crc(t))
338
      break;
360
      break;
339
    if (last (t)) {
361
    if (last(t)) {
340
      t = nilexp;
362
      t = nilexp;
341
      break;
363
      break;
342
    };
364
    };
343
    t = bro (t);
365
    t = bro(t);
344
  };
366
  };
345
 
367
 
346
  if (t == nilexp) {		/* all arguments are possible 80386
368
  if (t == nilexp) {		/* all arguments are possible 80386
347
				   operands */
369
				   operands */
348
    (*op) (sha, mw (arg1, 0), mw (arg2, 0), qw);
370
   (*op)(sha, mw(arg1, 0), mw(arg2, 0), qw);
349
    t = bro (arg2);
371
    t = bro(arg2);
350
    while (!last (t)) {
372
    while (!last(t)) {
351
      (*op) (sha, mw (t, 0), qw, qw);/* encode operations in turn */
373
      (*op) (sha, mw (t, 0), qw, qw);/* encode operations in turn */
352
      t = bro (t);
374
      t = bro(t);
353
    };
375
    };
354
    (*op) (sha, mw (t, 0), qw, dest);/* encode final operation */
376
    (*op) (sha, mw (t, 0), qw, dest);/* encode final operation */
355
    retcell (qw.where_exp);
377
    retcell(qw.where_exp);
356
    cond1_set = 0;
378
    cond1_set = 0;
357
    return;
379
    return;
358
  };
380
  };
359
 
381
 
360
  coder (qw, stack, t);		/* encode the single argument which is not
382
  coder (qw, stack, t);		/* encode the single argument which is not
361
				   a possible 80386 operend */
383
				   a possible 80386 operend */
362
  u = arg1;
384
  u = arg1;
363
  /* now encode the remaining operations */
385
  /* now encode the remaining operations */
364
  while (1) {
386
  while (1) {
365
    if (t != u) {
387
    if (t != u) {
366
      if (last (u) || (bro (u) == t && last (bro (u))))
388
      if (last(u) || (bro(u) == t && last(bro(u))))
367
	(*op) (sha, mw (u, 0), qw, dest);
389
	(*op)(sha, mw(u, 0), qw, dest);
368
      else
390
      else
369
	(*op) (sha, mw (u, 0), qw, qw);
391
	(*op)(sha, mw(u, 0), qw, qw);
370
    };
392
    };
371
    if (last (u))
393
    if (last(u))
372
      break;
394
      break;
373
    u = bro (u);
395
    u = bro(u);
374
  };
396
  };
375
  retcell (qw.where_exp);
397
  retcell(qw.where_exp);
376
  cond1_set = 0;
398
  cond1_set = 0;
377
  return;
399
  return;
378
}
400
}
379
 
401
 
380
/* process the multiply operation
402
/* process the multiply operation
Line 389... Line 411...
389
   the arguments will not be a possible
411
   the arguments will not be a possible
390
   80386 operand. If there is such an
412
   80386 operand. If there is such an
391
   argument, it is precomputed, putting
413
   argument, it is precomputed, putting
392
   the value into reg0. */
414
   the value into reg0. */
393
static void multop
415
static void multop
394
    PROTO_N ( (op, e, dest, stack) )
-
 
395
    PROTO_T ( void (*op) PROTO_S ((shape, where, where, where)) X
-
 
396
	      exp e X where dest X ash stack )
416
(void(*op)(shape, where, where, where), exp e, where dest, ash stack)
397
{
417
{
398
  exp arg1 = son (e);
418
  exp arg1 = son(e);
399
  exp arg2 = bro (arg1);
419
  exp arg2 = bro(arg1);
400
  exp t, u;
420
  exp t, u;
401
  where qw;
421
  where qw;
402
 
422
 
403
  if (last (arg1)) {
423
  if (last(arg1)) {
404
    coder (dest, stack, arg1);
424
    coder(dest, stack, arg1);
405
    return;
425
    return;
406
  };
426
  };
407
 
427
 
408
  if (last (arg2)) {		/* just two arguments. */
428
  if (last (arg2)) {		/* just two arguments. */
409
    bop (op, sh (e), arg1, arg2, dest, stack);
429
    bop(op, sh(e), arg1, arg2, dest, stack);
410
    return;
430
    return;
411
  };
431
  };
412
  /* need to take care about overlap between dest and args or to avoid
432
  /* need to take care about overlap between dest and args or to avoid
413
     extra push. So use reg0. */
433
     extra push. So use reg0. */
414
  qw.where_exp = copyexp (reg0.where_exp);
434
  qw.where_exp = copyexp(reg0.where_exp);
415
  sh (qw.where_exp) = sh (e);
435
  sh(qw.where_exp) = sh(e);
416
  qw.where_off = 0;
436
  qw.where_off = 0;
417
  t = arg1;
437
  t = arg1;
418
  /* now look for an argument which is not a possible 80386 operand */
438
  /* now look for an argument which is not a possible 80386 operand */
419
  while (1) {
439
  while (1) {
420
    if (!is_o (name (t)) || is_crc(t))
440
    if (!is_o(name(t)) || is_crc(t))
421
      break;
441
      break;
422
    if (last (t)) {
442
    if (last(t)) {
423
      t = nilexp;
443
      t = nilexp;
424
      break;
444
      break;
425
    };
445
    };
426
    t = bro (t);
446
    t = bro(t);
427
  };
447
  };
428
 
448
 
429
  if (t == nilexp) {		/* all arguments are possible 80386
449
  if (t == nilexp) {		/* all arguments are possible 80386
430
				   operands */
450
				   operands */
431
    (*op) (sh (e), mw (arg1, 0), mw (arg2, 0), qw);
451
   (*op)(sh(e), mw(arg1, 0), mw(arg2, 0), qw);
432
    t = bro (arg2);
452
    t = bro(arg2);
433
    while (!last (t)) {
453
    while (!last(t)) {
434
      (*op) (sh (e), mw (t, 0), qw, qw);/* encode operations in turn */
454
      (*op) (sh (e), mw (t, 0), qw, qw);/* encode operations in turn */
435
      t = bro (t);
455
      t = bro(t);
436
    };
456
    };
437
    (*op) (sh (e), mw (t, 0), qw, dest);/* encode final operation */
457
    (*op) (sh (e), mw (t, 0), qw, dest);/* encode final operation */
438
    retcell (qw.where_exp);
458
    retcell(qw.where_exp);
439
    cond1_set = 0;
459
    cond1_set = 0;
440
    return;
460
    return;
441
  };
461
  };
442
 
462
 
443
  coder (qw, stack, t);		/* encode the single argument which is not
463
  coder (qw, stack, t);		/* encode the single argument which is not
444
				   a possible 80386 operend */
464
				   a possible 80386 operend */
445
  u = arg1;
465
  u = arg1;
446
  /* now encode the remaining operations */
466
  /* now encode the remaining operations */
447
  while (1) {
467
  while (1) {
448
    if (t != u) {
468
    if (t != u) {
449
      if (last (u) || (bro (u) == t && last (bro (u))))
469
      if (last(u) || (bro(u) == t && last(bro(u))))
450
	(*op) (sh (e), mw (u, 0), qw, dest);
470
	(*op)(sh(e), mw(u, 0), qw, dest);
451
      else
471
      else
452
	(*op) (sh (e), mw (u, 0), qw, qw);
472
	(*op)(sh(e), mw(u, 0), qw, qw);
453
    };
473
    };
454
    if (last (u))
474
    if (last(u))
455
      break;
475
      break;
456
    u = bro (u);
476
    u = bro(u);
457
  };
477
  };
458
  retcell (qw.where_exp);
478
  retcell(qw.where_exp);
459
  cond1_set = 0;
479
  cond1_set = 0;
460
  return;
480
  return;
461
}
481
}
462
 
482
 
463
/* if a is a negation form b-son(a)
483
/* if a is a negation form b-son(a)
464
   otherwise b+a in dest */
484
   otherwise b+a in dest */
465
static void addsub
485
static void addsub
466
    PROTO_N ( (sha, a, b, dest, e) )
-
 
467
    PROTO_T ( shape sha X where a X where b X where dest X exp e )
486
(shape sha, where a, where b, where dest, exp e)
468
{
487
{
469
  UNUSED(e);
488
  UNUSED(e);
470
  if (name (a.where_exp) == neg_tag)
489
  if (name(a.where_exp) == neg_tag)
471
    sub (sha, mw (son (a.where_exp), 0), b, dest);
490
    sub(sha, mw(son(a.where_exp), 0), b, dest);
472
  else
491
  else
473
    add (sha, a, b, dest);
492
    add(sha, a, b, dest);
474
  return;
493
  return;
475
}
494
}
476
 
495
 
477
 
496
 
478
 
497
 
Line 483... Line 502...
483
 
502
 
484
 
503
 
485
/* encode e, putting the result into dest.
504
/* encode e, putting the result into dest.
486
   stack is the current stack level */
505
   stack is the current stack level */
487
void codec
506
void codec
488
    PROTO_N ( (dest, stack, e) )
-
 
489
    PROTO_T ( where dest X ash stack X exp e )
507
(where dest, ash stack, exp e)
490
{
508
{
491
  switch (name (e)) {
509
  switch (name(e)) {
492
    case plus_tag:
510
    case plus_tag:
493
      {				/* at most one of the arguments will not
511
      {				/* at most one of the arguments will not
494
				   be a possible 80386 operand */
512
				   be a possible 80386 operand */
495
	exp arg1 = son (e);
513
	exp arg1 = son(e);
496
	exp arg2 = bro (arg1);
514
	exp arg2 = bro(arg1);
497
	exp t, u, v;
515
	exp t, u, v;
498
	where qw;
516
	where qw;
499
	exp old_overflow_e = overflow_e;
517
	exp old_overflow_e = overflow_e;
500
 
518
 
501
	if (last (arg1)) {	/* there is only one argument */
519
	if (last (arg1)) {	/* there is only one argument */
502
	  coder (dest, stack, arg1);
520
	  coder(dest, stack, arg1);
503
	  return;
521
	  return;
504
	};
522
	};
505
 
523
 
506
	if (!optop(e))
524
	if (!optop(e))
507
          overflow_e = e;
525
          overflow_e = e;
508
 
526
 
509
	if (last (arg2) && is_o (name (arg1)) && !is_crc(arg1) &&
527
	if (last(arg2) && is_o(name(arg1)) && !is_crc(arg1) &&
510
	    ((is_o (name (arg2)) && !is_crc(arg2))||
528
	   ((is_o(name(arg2)) && !is_crc(arg2)) ||
511
	      (name (arg2) == neg_tag &&
529
	     (name(arg2) == neg_tag &&
512
	       !is_crc(son(arg2)) &&
530
	       !is_crc(son(arg2)) &&
513
	       is_o (name (son (arg2)))))) {
531
	       is_o(name(son(arg2)))))) {
514
	  /* just two arguments. */
532
	  /* just two arguments. */
515
	  addsub (sh (e), mw (arg2, 0), mw (arg1, 0), dest, e);
533
	  addsub(sh(e), mw(arg2, 0), mw(arg1, 0), dest, e);
516
          overflow_e = old_overflow_e;
534
          overflow_e = old_overflow_e;
517
	  return;
535
	  return;
518
	};
536
	};
519
	/* need to take care about overlap between dest and args or to
537
	/* need to take care about overlap between dest and args or to
520
	   avoid extra push. So use reg0. */
538
	   avoid extra push. So use reg0. */
521
	t = arg1;
539
	t = arg1;
522
	qw.where_exp = copyexp (reg0.where_exp);
540
	qw.where_exp = copyexp(reg0.where_exp);
523
	sh (qw.where_exp) = sh (e);
541
	sh(qw.where_exp) = sh(e);
524
	qw.where_off = 0;
542
	qw.where_off = 0;
525
 
543
 
526
	/* now look for argument which is not a possible 80386 operand */
544
	/* now look for argument which is not a possible 80386 operand */
527
	while (1) {
545
	while (1) {
528
	  if ((!is_o (name (t)) || is_crc(t)) &&
546
	  if ((!is_o(name(t)) || is_crc(t)) &&
529
	      (name (t) != neg_tag || !is_o (name (son (t))) ||
547
	     (name(t)!= neg_tag || !is_o(name(son(t))) ||
530
	       is_crc(son(t))))
548
	       is_crc(son(t))))
531
	    break;
549
	    break;
532
	  if (last (t)) {
550
	  if (last(t)) {
533
	    t = nilexp;
551
	    t = nilexp;
534
	    break;
552
	    break;
535
	  };
553
	  };
536
	  t = bro (t);
554
	  t = bro(t);
537
	};
555
	};
538
 
556
 
539
	if (t == nilexp && name (arg1) == neg_tag &&
557
	if (t == nilexp && name(arg1) == neg_tag &&
540
	    name (arg2) == neg_tag)
558
	    name(arg2) == neg_tag)
541
	  t = arg1;
559
	  t = arg1;
542
 
560
 
543
	if (t == nilexp) {	/* all arguments are possible 80386
561
	if (t == nilexp) {	/* all arguments are possible 80386
544
				   operands */
562
				   operands */
545
	  t = bro (arg2);
563
	  t = bro(arg2);
546
	  if (name (arg1) == neg_tag)
564
	  if (name(arg1) == neg_tag)
547
	    addsub (sh (e), mw (arg1, 0), mw (arg2, 0),
565
	    addsub(sh(e), mw(arg1, 0), mw(arg2, 0),
548
		(t == e) ? dest : qw, e);
566
		(t == e)? dest : qw, e);
549
	  else
567
	  else
550
	    addsub (sh (e), mw (arg2, 0), mw (arg1, 0),
568
	    addsub(sh(e), mw(arg2, 0), mw(arg1, 0),
551
		(t == e) ? dest : qw, e);
569
		(t == e)? dest : qw, e);
552
	  if (t == e)
570
	  if (t == e)
553
           {
571
           {
554
             overflow_e = old_overflow_e;
572
             overflow_e = old_overflow_e;
555
	     return;
573
	     return;
556
           };
574
           };
557
	  while (!last (t)) {
575
	  while (!last(t)) {
558
	    u = bro (t);
576
	    u = bro(t);
559
	    addsub (sh (e), mw (t, 0), qw, qw, e);
577
	    addsub(sh(e), mw(t, 0), qw, qw, e);
560
	    t = u;
578
	    t = u;
561
	  };
579
	  };
562
	  addsub (sh (e), mw (t, 0), qw, dest, e);
580
	  addsub(sh(e), mw(t, 0), qw, dest, e);
563
          overflow_e = old_overflow_e;
581
          overflow_e = old_overflow_e;
564
	  return;
582
	  return;
565
	};
583
	};
566
 
584
 
567
	coder (qw, stack, t);	/* encode the argument which is not a
585
	coder (qw, stack, t);	/* encode the argument which is not a
568
				   possible 80386 operand */
586
				   possible 80386 operand */
569
	u = arg1;
587
	u = arg1;
570
	/* now encode the remaining operations */
588
	/* now encode the remaining operations */
571
	while (1) {
589
	while (1) {
572
	  v = bro (u);
590
	  v = bro(u);
573
	  if (t != u) {
591
	  if (t != u) {
574
	    if (last (u) || (v == t && last (v)))
592
	    if (last(u) || (v == t && last(v)))
575
	      addsub (sh (e), mw (u, 0), qw, dest, e);
593
	      addsub(sh(e), mw(u, 0), qw, dest, e);
576
	    else
594
	    else
577
	      addsub (sh (e), mw (u, 0), qw, qw, e);
595
	      addsub(sh(e), mw(u, 0), qw, qw, e);
578
	  };
596
	  };
579
	  if (last (u))
597
	  if (last(u))
580
	    break;
598
	    break;
581
	  u = v;
599
	  u = v;
582
	};
600
	};
583
	retcell (qw.where_exp);
601
	retcell(qw.where_exp);
584
        cond1_set = 0;
602
        cond1_set = 0;
585
        overflow_e = old_overflow_e;
603
        overflow_e = old_overflow_e;
586
	return;
604
	return;
587
      };
605
      };
588
    case addptr_tag: {		/* use index operation */
606
    case addptr_tag: {		/* use index operation */
589
	mova (mw (e, 0), dest);
607
	mova(mw(e, 0), dest);
590
	return;
608
	return;
591
      };
609
      };
592
    case chvar_tag: {
610
    case chvar_tag: {
593
	exp a = son (e);
611
	exp a = son(e);
594
	exp old_overflow_e = overflow_e;
612
	exp old_overflow_e = overflow_e;
595
        if (!optop(e))
613
        if (!optop(e))
596
          overflow_e = e;
614
          overflow_e = e;
597
	if (!is_o (name (a)) || is_crc(a)) {
615
	if (!is_o(name(a)) || is_crc(a)) {
598
				/* argument is not a possible 80386
616
				/* argument is not a possible 80386
599
				   operand, so evaluate it in reg0 */
617
				   operand, so evaluate it in reg0 */
600
	  if (inmem (dest) ||
618
	  if (inmem(dest) ||
601
		(shape_size(sh(a)) == 8 && bad_from_reg(dest)) ||
619
		(shape_size(sh(a)) == 8 && bad_from_reg(dest)) ||
602
		shape_size(sh(a)) == 64) {
620
		shape_size(sh(a)) == 64) {
603
	    where qw;
621
	    where qw;
604
	    qw.where_exp = copyexp (reg0.where_exp);
622
	    qw.where_exp = copyexp(reg0.where_exp);
605
	    sh (qw.where_exp) = sh (a);
623
	    sh(qw.where_exp) = sh(a);
606
	    qw.where_off = 0;
624
	    qw.where_off = 0;
607
	    coder (qw, stack, a);
625
	    coder(qw, stack, a);
608
	    change_var_check (sh (e), qw, dest);
626
	    change_var_check(sh(e), qw, dest);
609
	    overflow_e = old_overflow_e;
627
	    overflow_e = old_overflow_e;
610
	    retcell (qw.where_exp);
628
	    retcell(qw.where_exp);
611
            cond1_set = 0;
629
            cond1_set = 0;
612
	    return;
630
	    return;
613
	  };
631
	  };
614
	  coder (dest, stack, a);
632
	  coder(dest, stack, a);
615
	  if (name(sh(e)) > name(sh(a)))
633
	  if (name(sh(e)) > name(sh(a)))
616
	    change_var_sh (sh (e), sh (a), dest, dest);
634
	    change_var_sh(sh(e), sh(a), dest, dest);
617
	  overflow_e = old_overflow_e;
635
	  overflow_e = old_overflow_e;
618
	  return;
636
	  return;
619
	};
637
	};
620
	change_var_check (sh (e), mw (a, 0), dest);
638
	change_var_check(sh(e), mw(a, 0), dest);
621
	overflow_e = old_overflow_e;
639
	overflow_e = old_overflow_e;
622
	return;
640
	return;
623
      };
641
      };
624
    case minus_tag:
642
    case minus_tag:
625
      {
643
      {
626
	exp old_overflow_e = overflow_e;
644
	exp old_overflow_e = overflow_e;
627
        if (!optop(e))
645
        if (!optop(e))
628
          overflow_e = e;
646
          overflow_e = e;
629
	bop (sub, sh (e), bro (son (e)), son (e), dest, stack);
647
	bop(sub, sh(e), bro(son(e)), son(e), dest, stack);
630
	overflow_e = old_overflow_e;
648
	overflow_e = old_overflow_e;
631
	return;
649
	return;
632
      };
650
      };
633
    case subptr_tag:
651
    case subptr_tag:
634
    case minptr_tag:
652
    case minptr_tag:
635
    case make_stack_limit_tag:
653
    case make_stack_limit_tag:
636
      {
654
      {
637
	bop (sub, sh (e), bro (son (e)), son (e), dest, stack);
655
	bop(sub, sh(e), bro(son(e)), son(e), dest, stack);
638
	return;
656
	return;
639
      };
657
      };
640
    case mult_tag:
658
    case mult_tag:
641
      {
659
      {
642
        if (!optop(e))
660
        if (!optop(e))
643
          {
661
          {
644
	    exp old_overflow_e = overflow_e;
662
	    exp old_overflow_e = overflow_e;
645
            overflow_e = e;
663
            overflow_e = e;
646
	    multop (multiply, e, dest, stack);
664
	    multop(multiply, e, dest, stack);
647
            overflow_e = old_overflow_e;
665
            overflow_e = old_overflow_e;
648
          }
666
          }
649
        else
667
        else
650
	  multop (mult, e, dest, stack);
668
	  multop(mult, e, dest, stack);
651
	return;
669
	return;
652
      };
670
      };
653
    case div2_tag:
671
    case div2_tag:
654
      {
672
      {
655
	exp old_overflow_e = overflow_e;
673
	exp old_overflow_e = overflow_e;
656
        if (errhandle(e))
674
        if (errhandle(e))
657
          overflow_e = e;
675
          overflow_e = e;
658
	bop (div2, sh (e), bro (son (e)), son (e), dest, stack);
676
	bop(div2, sh(e), bro(son(e)), son(e), dest, stack);
659
	overflow_e = old_overflow_e;
677
	overflow_e = old_overflow_e;
660
	return;
678
	return;
661
      };
679
      };
662
    case div1_tag:
680
    case div1_tag:
663
      {
681
      {
664
	exp old_overflow_e = overflow_e;
682
	exp old_overflow_e = overflow_e;
665
        if (errhandle(e))
683
        if (errhandle(e))
666
          overflow_e = e;
684
          overflow_e = e;
667
	bop (div1, sh (e), bro (son (e)), son (e), dest, stack);
685
	bop(div1, sh(e), bro(son(e)), son(e), dest, stack);
668
	overflow_e = old_overflow_e;
686
	overflow_e = old_overflow_e;
669
	return;
687
	return;
670
      };
688
      };
671
    case div0_tag:
689
    case div0_tag:
672
      {
690
      {
673
	exp old_overflow_e = overflow_e;
691
	exp old_overflow_e = overflow_e;
674
        if (errhandle(e))
692
        if (errhandle(e))
675
          overflow_e = e;
693
          overflow_e = e;
676
	bop (div0, sh (e), bro (son (e)), son (e), dest, stack);
694
	bop(div0, sh(e), bro(son(e)), son(e), dest, stack);
677
	overflow_e = old_overflow_e;
695
	overflow_e = old_overflow_e;
678
	return;
696
	return;
679
      };
697
      };
680
    case neg_tag:
698
    case neg_tag:
681
      {
699
      {
682
	exp old_overflow_e = overflow_e;
700
	exp old_overflow_e = overflow_e;
683
        if (!optop(e))
701
        if (!optop(e))
684
          overflow_e = e;
702
          overflow_e = e;
685
	uop (negate, sh (e), son (e), dest, stack);
703
	uop(negate, sh(e), son(e), dest, stack);
686
	overflow_e = old_overflow_e;
704
	overflow_e = old_overflow_e;
687
	return;
705
	return;
688
      };
706
      };
689
    case shl_tag:
707
    case shl_tag:
690
      {
708
      {
691
	exp old_overflow_e = overflow_e;
709
	exp old_overflow_e = overflow_e;
692
	overflow_e = e;
710
	overflow_e = e;
693
        if (!optop(e))
711
        if (!optop(e))
694
          overflow_e = e;
712
          overflow_e = e;
695
	bop (shiftl, sh (e), bro (son (e)), son (e), dest, stack);
713
	bop(shiftl, sh(e), bro(son(e)), son(e), dest, stack);
696
	overflow_e = old_overflow_e;
714
	overflow_e = old_overflow_e;
697
	return;
715
	return;
698
      };
716
      };
699
    case shr_tag:
717
    case shr_tag:
700
      {
718
      {
701
	bop (shiftr, sh (e), bro (son (e)), son (e), dest, stack);
719
	bop(shiftr, sh(e), bro(son(e)), son(e), dest, stack);
702
	return;
720
	return;
703
      };
721
      };
704
    case rotl_tag:
722
    case rotl_tag:
705
      {
723
      {
706
	bop (rotatel, sh (e), bro (son (e)), son (e), dest, stack);
724
	bop(rotatel, sh(e), bro(son(e)), son(e), dest, stack);
707
	return;
725
	return;
708
      };
726
      };
709
    case rotr_tag:
727
    case rotr_tag:
710
      {
728
      {
711
	bop (rotater, sh (e), bro (son (e)), son (e), dest, stack);
729
	bop(rotater, sh(e), bro(son(e)), son(e), dest, stack);
712
	return;
730
	return;
713
      };
731
      };
714
    case mod_tag:
732
    case mod_tag:
715
      {
733
      {
716
	exp old_overflow_e = overflow_e;
734
	exp old_overflow_e = overflow_e;
717
        if (errhandle(e))
735
        if (errhandle(e))
718
          overflow_e = e;
736
          overflow_e = e;
719
	bop (mod, sh (e), bro (son (e)), son (e), dest, stack);
737
	bop(mod, sh(e), bro(son(e)), son(e), dest, stack);
720
	overflow_e = old_overflow_e;
738
	overflow_e = old_overflow_e;
721
	return;
739
	return;
722
      };
740
      };
723
    case rem2_tag:
741
    case rem2_tag:
724
      {
742
      {
725
	exp old_overflow_e = overflow_e;
743
	exp old_overflow_e = overflow_e;
726
        if (errhandle(e))
744
        if (errhandle(e))
727
          overflow_e = e;
745
          overflow_e = e;
728
	bop (rem2, sh (e), bro (son (e)), son (e), dest, stack);
746
	bop(rem2, sh(e), bro(son(e)), son(e), dest, stack);
729
	overflow_e = old_overflow_e;
747
	overflow_e = old_overflow_e;
730
	return;
748
	return;
731
      };
749
      };
732
    case rem0_tag:
750
    case rem0_tag:
733
      {
751
      {
734
	exp old_overflow_e = overflow_e;
752
	exp old_overflow_e = overflow_e;
735
        if (errhandle(e))
753
        if (errhandle(e))
736
          overflow_e = e;
754
          overflow_e = e;
737
	bop (rem0, sh (e), bro (son (e)), son (e), dest, stack);
755
	bop(rem0, sh(e), bro(son(e)), son(e), dest, stack);
738
	overflow_e = old_overflow_e;
756
	overflow_e = old_overflow_e;
739
	return;
757
	return;
740
      };
758
      };
741
    case round_tag:
759
    case round_tag:
742
      {
760
      {
743
	shape s = sh (e);
761
	shape s = sh(e);
744
	where d;
762
	where d;
745
	d = dest;
763
	d = dest;
746
	if (shape_size(s) < 32) {
764
	if (shape_size(s) < 32) {
747
	  s = slongsh;
765
	  s = slongsh;
748
	  if (inmem(dest))
766
	  if (inmem(dest))
749
	    d = reg0;
767
	    d = reg0;
750
	}
768
	}
751
        setup_fl_ovfl(e);
769
        setup_fl_ovfl(e);
752
	switch (round_number(e)) {
770
	switch (round_number(e)) {
753
	  case 0:
771
	  case 0:
754
		uop (frnd0, s, son (e), d, stack);
772
		uop(frnd0, s, son(e), d, stack);
755
		break;
773
		break;
756
	  case 1:
774
	  case 1:
757
		uop (frnd1, s, son (e), d, stack);
775
		uop(frnd1, s, son(e), d, stack);
758
		break;
776
		break;
759
	  case 2:
777
	  case 2:
760
		uop (frnd2, s, son (e), d, stack);
778
		uop(frnd2, s, son(e), d, stack);
761
		break;
779
		break;
762
	  case 3:
780
	  case 3:
763
		uop (frnd3, s, son (e), d, stack);
781
		uop(frnd3, s, son(e), d, stack);
764
		break;
782
		break;
765
	  case 4:
783
	  case 4:
766
		uop (frnd4, s, son (e), d, stack);
784
		uop(frnd4, s, son(e), d, stack);
767
		break;
785
		break;
768
	};
786
	};
769
        test_fl_ovfl(e, d);
787
        test_fl_ovfl(e, d);
770
	if (name(s) != name(sh(e))) {
788
	if (name(s)!= name(sh(e))) {
771
	  exp old_overflow_e = overflow_e;
789
	  exp old_overflow_e = overflow_e;
772
          if (!optop(e))
790
          if (!optop(e))
773
            overflow_e = e;
791
            overflow_e = e;
774
	  change_var_sh (sh(e), s, d, dest);
792
	  change_var_sh(sh(e), s, d, dest);
775
	  overflow_e = old_overflow_e;
793
	  overflow_e = old_overflow_e;
776
	}
794
	}
777
	return;
795
	return;
778
      };
796
      };
779
    case fplus_tag:
797
    case fplus_tag:
780
      {
798
      {
781
        setup_fl_ovfl(e);
799
        setup_fl_ovfl(e);
782
	fl_multop (fplus_tag, sh (e), son (e), dest);
800
	fl_multop(fplus_tag, sh(e), son(e), dest);
783
        test_fl_ovfl(e, dest);
801
        test_fl_ovfl(e, dest);
784
	return;
802
	return;
785
      };
803
      };
786
    case fmult_tag:
804
    case fmult_tag:
787
      {
805
      {
788
        setup_fl_ovfl(e);
806
        setup_fl_ovfl(e);
789
	fl_multop (fmult_tag, sh (e), son (e), dest);
807
	fl_multop(fmult_tag, sh(e), son(e), dest);
790
        test_fl_ovfl(e, dest);
808
        test_fl_ovfl(e, dest);
791
	return;
809
	return;
792
      };
810
      };
793
    case fminus_tag:
811
    case fminus_tag:
794
      {
812
      {
795
        setup_fl_ovfl(e);
813
        setup_fl_ovfl(e);
796
	fl_binop (fminus_tag, sh (e), mw (bro (son (e)), 0),
814
	fl_binop(fminus_tag, sh(e), mw(bro(son(e)), 0),
797
	    mw (son (e), 0), dest, bro (son (e)));
815
	    mw(son(e), 0), dest, bro(son(e)));
798
        test_fl_ovfl(e, dest);
816
        test_fl_ovfl(e, dest);
799
	return;
817
	return;
800
      };
818
      };
801
    case fdiv_tag:
819
    case fdiv_tag:
802
      {
820
      {
803
        setup_fl_ovfl(e);
821
        setup_fl_ovfl(e);
804
	fl_binop (fdiv_tag, sh (e), mw (bro (son (e)), 0),
822
	fl_binop(fdiv_tag, sh(e), mw(bro(son(e)), 0),
805
	      mw (son (e), 0), dest, bro (son (e)));
823
	      mw(son(e), 0), dest, bro(son(e)));
806
        test_fl_ovfl(e, dest);
824
        test_fl_ovfl(e, dest);
807
	return;
825
	return;
808
      };
826
      };
809
    case fneg_tag: {
827
    case fneg_tag: {
810
        setup_fl_ovfl(e);
828
        setup_fl_ovfl(e);
811
	fl_neg (sh (e), mw (son (e), 0), dest);
829
	fl_neg(sh(e), mw(son(e), 0), dest);
812
        test_fl_ovfl(e, dest);
830
        test_fl_ovfl(e, dest);
813
	return;
831
	return;
814
      };
832
      };
815
    case fabs_tag: {
833
    case fabs_tag: {
816
        setup_fl_ovfl(e);
834
        setup_fl_ovfl(e);
817
	fl_abs (sh (e), mw (son (e), 0), dest);
835
	fl_abs(sh(e), mw(son(e), 0), dest);
818
        test_fl_ovfl(e, dest);
836
        test_fl_ovfl(e, dest);
819
	return;
837
	return;
820
      };
838
      };
821
    case float_tag: {
839
    case float_tag: {
822
        setup_fl_ovfl(e);
840
        setup_fl_ovfl(e);
823
	floater (sh (e), mw (son (e), 0), dest);
841
	floater(sh(e), mw(son(e), 0), dest);
824
        test_fl_ovfl(e, dest);
842
        test_fl_ovfl(e, dest);
825
	return;
843
	return;
826
      };
844
      };
827
    case chfl_tag: {
845
    case chfl_tag: {
828
	if (name(sh(e)) < name(sh(son(e))))
846
	if (name(sh(e)) < name(sh(son(e))))
829
	  setup_fl_ovfl(e);
847
	  setup_fl_ovfl(e);
830
	changefl (sh (e), mw (son (e), 0), dest);
848
	changefl(sh(e), mw(son(e), 0), dest);
831
	if (name(sh(e)) < name(sh(son(e))))
849
	if (name(sh(e)) < name(sh(son(e))))
832
	  test_fl_ovfl(e, dest);
850
	  test_fl_ovfl(e, dest);
833
	return;
851
	return;
834
      };
852
      };
835
    case and_tag: {
853
    case and_tag: {
836
	logop (and, e, dest, stack);
854
	logop(and, e, dest, stack);
837
	return;
855
	return;
838
      };
856
      };
839
    case or_tag: {
857
    case or_tag: {
840
	logop (or, e, dest, stack);
858
	logop(or, e, dest, stack);
841
	return;
859
	return;
842
      };
860
      };
843
    case xor_tag: {
861
    case xor_tag: {
844
	logop (xor, e, dest, stack);
862
	logop(xor, e, dest, stack);
845
	return;
863
	return;
846
      };
864
      };
847
    case not_tag: {
865
    case not_tag: {
848
	uop (not, sh (e), son (e), dest, stack);
866
	uop(not, sh(e), son(e), dest, stack);
849
	return;
867
	return;
850
      };
868
      };
851
    case offset_pad_tag:
869
    case offset_pad_tag:
852
      if (al2(sh(son(e))) >= al2(sh(e)))
870
      if (al2(sh(son(e))) >= al2(sh(e)))
853
	{
871
	{
854
	  if (al2(sh(e)) != 1 || al2(sh(son(e))) == 1)
872
	  if (al2(sh(e))!= 1 || al2(sh(son(e))) == 1)
855
            coder(dest, stack, son(e));
873
            coder(dest, stack, son(e));
856
	  else {
874
	  else {
857
	    coder(reg0, stack, son(e));
875
	    coder(reg0, stack, son(e));
858
	    shiftl (slongsh, mw(zeroe, 3), reg0, dest);
876
	    shiftl(slongsh, mw(zeroe, 3), reg0, dest);
859
	  }
877
	  }
860
	}
878
	}
861
      else
879
      else
862
        {
880
        {
863
          int al = al2(sh(e))/8;
881
          int al = al2(sh(e)) /8;
864
          coder(reg0, stack, son(e));
882
          coder(reg0, stack, son(e));
865
	  if (al2(sh(son(e))) == 1) {
883
	  if (al2(sh(son(e))) == 1) {
866
            add (slongsh, mw(zeroe, al*8 -1), reg0, reg0);
884
            add(slongsh, mw(zeroe, al*8 -1), reg0, reg0);
867
	    shiftr (slongsh, mw(zeroe, 3), reg0, reg0);
885
	    shiftr(slongsh, mw(zeroe, 3), reg0, reg0);
868
	  }
886
	  }
869
	  else
887
	  else
870
            add (slongsh, mw(zeroe, al-1), reg0, reg0);
888
            add(slongsh, mw(zeroe, al-1), reg0, reg0);
871
          and (slongsh, mw(zeroe, -al), reg0, dest);
889
          and(slongsh, mw(zeroe, -al), reg0, dest);
872
        };
890
        };
873
      return;
891
      return;
874
    case offset_add_tag:
892
    case offset_add_tag:
875
      {
893
      {
876
	bop (add, sh (e), son (e), bro (son (e)), dest, stack);
894
	bop(add, sh(e), son(e), bro(son(e)), dest, stack);
877
	return;
895
	return;
878
      };
896
      };
879
    case abs_tag:
897
    case abs_tag:
880
      {
898
      {
881
	exp old_overflow_e = overflow_e;
899
	exp old_overflow_e = overflow_e;
882
        if (!optop(e))
900
        if (!optop(e))
883
          overflow_e = e;
901
          overflow_e = e;
884
	uop (absop, sh(e), son (e), dest, stack);
902
	uop(absop, sh(e), son(e), dest, stack);
885
	overflow_e = old_overflow_e;
903
	overflow_e = old_overflow_e;
886
	return;
904
	return;
887
      };
905
      };
888
    case offset_max_tag:
906
    case offset_max_tag:
889
    case max_tag:
907
    case max_tag:
890
      {
908
      {
891
	bop (maxop, sh(e), son (e), bro (son (e)), dest, stack);
909
	bop(maxop, sh(e), son(e), bro(son(e)), dest, stack);
892
	return;
910
	return;
893
      };
911
      };
894
    case min_tag:
912
    case min_tag:
895
      {
913
      {
896
	bop (minop, sh(e), son (e), bro (son (e)), dest, stack);
914
	bop(minop, sh(e), son(e), bro(son(e)), dest, stack);
897
	return;
915
	return;
898
      };
916
      };
899
   case offset_subtract_tag:
917
   case offset_subtract_tag:
900
      {
918
      {
901
	bop (sub, sh(e), bro(son (e)), son (e), dest, stack);
919
	bop(sub, sh(e), bro(son(e)), son(e), dest, stack);
902
	return;
920
	return;
903
      };
921
      };
904
    case offset_mult_tag:
922
    case offset_mult_tag:
905
      {
923
      {
906
	bop (mult, slongsh, son (e), bro (son (e)), dest, stack);
924
	bop(mult, slongsh, son(e), bro(son(e)), dest, stack);
907
	return;
925
	return;
908
      };
926
      };
909
    case offset_negate_tag: {
927
    case offset_negate_tag: {
910
	uop (negate, sh (e), son (e), dest, stack);
928
	uop(negate, sh(e), son(e), dest, stack);
911
	return;
929
	return;
912
      };
930
      };
913
    case offset_div_by_int_tag:
931
    case offset_div_by_int_tag:
914
      {
932
      {
915
	bop (div0, sh (e), bro (son (e)), son (e), dest, stack);
933
	bop(div0, sh(e), bro(son(e)), son(e), dest, stack);
916
	return;
934
	return;
917
      };
935
      };
918
    case offset_div_tag:
936
    case offset_div_tag:
919
      {
937
      {
920
	if (shape_size (sh (e)) == 32)
938
	if (shape_size(sh(e)) == 32)
921
	  bop (div0, sh (e), bro (son (e)), son (e), dest, stack);
939
	  bop(div0, sh(e), bro(son(e)), son(e), dest, stack);
922
	else
940
	else
923
	if (inmem(dest)) {
941
	if (inmem(dest)) {
924
	  bop (div0, sh (son(e)), bro (son (e)), son (e), reg0, stack);
942
	  bop(div0, sh(son(e)), bro(son(e)), son(e), reg0, stack);
925
	  change_var (sh (e), reg0, dest);
943
	  change_var(sh(e), reg0, dest);
926
	}
944
	}
927
	else {
945
	else {
928
	  bop (div0, sh (son(e)), bro (son (e)), son (e), dest, stack);
946
	  bop(div0, sh(son(e)), bro(son(e)), son(e), dest, stack);
929
	  change_var (sh (e), dest, dest);
947
	  change_var(sh(e), dest, dest);
930
	}
948
	}
931
	return;
949
	return;
932
      };
950
      };
933
    case absbool_tag:
951
    case absbool_tag:
934
      {
952
      {
Line 943... Line 961...
943
       and(slongsh, mw(zeroe, mask), dest, dest);
961
       and(slongsh, mw(zeroe, mask), dest, dest);
944
       return;
962
       return;
945
     };
963
     };
946
    case bitf_to_int_tag:
964
    case bitf_to_int_tag:
947
      coder(reg0, stack, son(e));
965
      coder(reg0, stack, son(e));
948
      change_var_sh (sh (e), sh(son(e)), reg0, dest);
966
      change_var_sh(sh(e), sh(son(e)), reg0, dest);
949
      return;
967
      return;
950
    case alloca_tag:
968
    case alloca_tag:
951
      coder(dest, stack, e);
969
      coder(dest, stack, e);
952
      return;
970
      return;
953
    case power_tag:
971
    case power_tag:
Line 964... Line 982...
964
      {
982
      {
965
	if (!is_o (name (e))) {	/* e is not a possible 80386 operand,
983
	if (!is_o (name (e))) {	/* e is not a possible 80386 operand,
966
				   precompute it into reg0 and move to
984
				   precompute it into reg0 and move to
967
				   dest */
985
				   dest */
968
	  where qw;
986
	  where qw;
969
	  qw.where_exp = copyexp (reg0.where_exp);
987
	  qw.where_exp = copyexp(reg0.where_exp);
970
	  sh (qw.where_exp) = sh (e);
988
	  sh(qw.where_exp) = sh(e);
971
	  qw.where_off = 0;
989
	  qw.where_off = 0;
972
	  coder (qw, stack, e);
990
	  coder(qw, stack, e);
973
	  move (sh (e), qw, dest);
991
	  move(sh(e), qw, dest);
974
	  retcell (qw.where_exp);
992
	  retcell(qw.where_exp);
975
          cond1_set = 0;
993
          cond1_set = 0;
976
	  return;
994
	  return;
977
	};
995
	};
978
 
996
 
979
	if (is_crc(e) && name(e) != name_tag
997
	if (is_crc(e) && name(e)!= name_tag
980
		 && name(e) != reff_tag && name(e) != field_tag) {
998
		 && name(e)!= reff_tag && name(e)!= field_tag) {
981
	  exp s = son(e);
999
	  exp s = son(e);
982
	  exp ss = son(s);
1000
	  exp ss = son(s);
983
	  exp sss = ss;
1001
	  exp sss = ss;
984
	  exp * p = & son(e);
1002
	  exp * p = & son(e);
985
 
1003
 
Line 1002... Line 1020...
1002
	    return;
1020
	    return;
1003
	  }
1021
	  }
1004
	}
1022
	}
1005
 
1023
 
1006
 
1024
 
1007
	if (name (e) == reff_tag &&
1025
	if (name(e) == reff_tag &&
1008
	    (name (son (e)) == name_tag ||
1026
	   (name(son(e)) == name_tag ||
1009
	      (name (son (e)) == cont_tag &&
1027
	     (name(son(e)) == cont_tag &&
1010
		name (son (son (e))) == name_tag))) {
1028
		name(son(son(e))) == name_tag))) {
1011
	  /* look for case when reff should be done by add */
1029
	  /* look for case when reff should be done by add */
1012
	  add (slongsh, mw (son (e), 0), mw (zeroe, no (e) / 8), dest);
1030
	  add(slongsh, mw(son(e), 0), mw(zeroe, no(e) / 8), dest);
1013
	  return;
1031
	  return;
1014
	};
1032
	};
1015
 
1033
 
1016
	if ((name (e) == name_tag && isvar (son (e))) ||
1034
	if ((name(e) == name_tag && isvar(son(e))) ||
1017
	    name (e) == reff_tag ||
1035
	    name(e) == reff_tag ||
1018
            (PIC_code && name(e) == name_tag && isglob(son(e)) &&
1036
           (PIC_code && name(e) == name_tag && isglob(son(e)) &&
1019
               name(sh(son(e))) == prokhd &&
1037
               name(sh(son(e))) == prokhd &&
1020
               !brog(son(e)) ->  dec_u.dec_val.extnamed)) {
1038
               !brog(son(e)) ->  dec_u.dec_val.extnamed)) {
1021
          if (ptno(son(e)) != nowhere_pl)
1039
          if (ptno(son(e))!= nowhere_pl)
1022
	    mova (mw (e, 0), dest);
1040
	    mova(mw(e, 0), dest);
1023
	  return;
1041
	  return;
1024
	};
1042
	};
1025
 
1043
 
1026
        if (name(e) == clear_tag)
1044
        if (name(e) == clear_tag)
1027
          {
1045
          {
1028
            if ((name (sh (e)) >= shrealhd && name (sh (e)) <= doublehd &&
1046
            if ((name(sh(e)) >= shrealhd && name(sh(e)) <= doublehd &&
1029
		!inmem(dest)) || name (dest.where_exp) == apply_tag)
1047
		!inmem(dest)) || name(dest.where_exp) == apply_tag)
1030
              move(sh(e), fzero, dest);
1048
              move(sh(e), fzero, dest);
1031
            return;
1049
            return;
1032
          };
1050
          };
1033
 
1051
 
1034
 
1052
 
1035
	/* other values */
1053
	/* other values */
1036
 
1054
 
1037
	if (name (e) != top_tag && name(e) != prof_tag)
1055
	if (name(e)!= top_tag && name(e)!= prof_tag)
1038
	  move (sh (e), mw (e, 0), dest);
1056
	  move(sh(e), mw(e, 0), dest);
1039
	else
1057
	else
1040
	  top_regsinuse = regsinuse;
1058
	  top_regsinuse = regsinuse;
1041
	return;
1059
	return;
1042
      };
1060
      };
1043
  };
1061
  };