Subversion Repositories tendra.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 7u83 1
/*
2
    		 Crown Copyright (c) 1997
3
 
4
    This TenDRA(r) Computer Program is subject to Copyright
5
    owned by the United Kingdom Secretary of State for Defence
6
    acting through the Defence Evaluation and Research Agency
7
    (DERA).  It is made available to Recipients with a
8
    royalty-free licence for its use, reproduction, transfer
9
    to other parties and amendment for any purpose not excluding
10
    product development provided that any such use et cetera
11
    shall be deemed to be acceptance of the following conditions:-
12
 
13
        (1) Its Recipients shall ensure that this Notice is
14
        reproduced upon any copies or amended versions of it;
15
 
16
        (2) Any amended version of it shall be clearly marked to
17
        show both the nature of and the organisation responsible
18
        for the relevant amendment or amendments;
19
 
20
        (3) Its onward transfer from a recipient to another
21
        party shall be deemed to be that party's acceptance of
22
        these conditions;
23
 
24
        (4) DERA gives no warranty or assurance as to its
25
        quality or suitability for any purpose and DERA accepts
26
        no liability whatsoever in relation to any use to which
27
        it may be put.
28
*/
29
 
30
 
31
/* 80x86/instr.c */
32
 
33
/**********************************************************************
34
$Author: pwe $
35
$Date: 1998/03/15 16:00:19 $
36
$Revision: 1.2 $
37
$Log: instr.c,v $
38
 * Revision 1.2  1998/03/15  16:00:19  pwe
39
 * regtrack dwarf dagnostics added
40
 *
41
 * Revision 1.1.1.1  1998/01/17  15:55:51  release
42
 * First version to be checked into rolling release.
43
 *
44
 * Revision 1.28  1997/04/17  11:55:47  pwe
45
 * dwarf2 improvements
46
 *
47
 * Revision 1.27  1997/03/24  11:15:13  pwe
48
 * dwarf2 option/default
49
 *
50
 * Revision 1.26  1997/03/20  16:23:41  pwe
51
 * dwarf2
52
 *
53
 * Revision 1.25  1997/02/18  11:42:52  pwe
54
 * NEWDIAGS for debugging optimised code
55
 *
56
 * Revision 1.24  1996/12/13  14:39:27  pwe
57
 * prep NEWDIAGS
58
 *
59
 * Revision 1.23  1996/07/09  09:43:39  pwe
60
 * caller env_offset if callees present, and tidy
61
 *
62
 * Revision 1.22  1996/05/20  14:30:11  pwe
63
 * improved 64-bit handling
64
 *
65
 * Revision 1.21  1996/05/13  12:51:55  pwe
66
 * undo premature commit
67
 *
68
 * Revision 1.19  1996/01/17  11:24:31  pwe
69
 * resurrect performance
70
 *
71
 * Revision 1.18  1995/11/01  18:41:14  pwe
72
 * PIC tail_call and exception handling
73
 *
74
 * Revision 1.17  1995/10/24  17:02:43  pwe
75
 * local calls to avoid PLT, Solaris constraint
76
 *
77
 * Revision 1.16  1995/10/16  14:55:19  pwe
78
 * stack change v fpucon
79
 *
80
 * Revision 1.15  1995/09/26  16:46:48  pwe
81
 * compare with zero to ignore previous overflow
82
 *
83
 * Revision 1.14  1995/09/15  17:39:13  pwe
84
 * tidy and correct fistp
85
 *
86
 * Revision 1.13  1995/09/08  12:51:07  pwe
87
 * exceptions improved
88
 *
89
 * Revision 1.12  1995/09/06  16:29:20  pwe
90
 * exceptions now OK
91
 *
92
 * Revision 1.11  1995/09/05  16:24:51  pwe
93
 * specials and exception changes
94
 *
95
 * Revision 1.10  1995/09/01  17:30:05  pwe
96
 * traps and Build scripts
97
 *
98
 * Revision 1.9  1995/08/30  16:06:33  pwe
99
 * prepare exception trapping
100
 *
101
 * Revision 1.8  1995/08/23  09:42:42  pwe
102
 * track fpu control word for trap etc
103
 *
104
 * Revision 1.7  1995/08/14  13:53:36  pwe
105
 * several corrections, tail calls and error jumps
106
 *
107
 * Revision 1.6  1995/08/04  08:29:23  pwe
108
 * 4.0 general procs implemented
109
 *
110
 * Revision 1.5  1995/04/12  17:05:54  pwe
111
 * name_prefix required for call_libfn
112
 *
113
 * Revision 1.4  1995/02/16  18:47:08  pwe
114
 * transformed subtract inverts, sets and adds carry in case of error_jump
115
 *
116
 * Revision 1.3  1995/01/30  12:56:18  pwe
117
 * Ownership -> PWE, tidy banners
118
 *
119
 * Revision 1.2  1994/11/08  09:55:03  jmf
120
 * Unknown?
121
 *
122
 * Revision 1.1  1994/10/27  14:15:22  jmf
123
 * Initial revision
124
 *
125
 * Revision 1.4  1994/08/08  15:54:29  jmf
126
 * Dont keep_short after label
127
 *
128
 * Revision 1.3  1994/07/15  13:59:23  jmf
129
 * Change fstack popping to use fstp st(0).
130
 *
131
 * Revision 1.2  1994/07/12  15:19:18  jmf
132
 * No change
133
 *
134
 * Revision 1.1  1994/07/12  14:33:55  jmf
135
 * Initial revision
136
 *
137
**********************************************************************/
138
 
139
 
140
/**********************************************************************
141
                           instr.c
142
 
143
 
144
   defines the general routines for outputting instructions and labels:
145
 
146
 
147
 
148
**********************************************************************/
149
 
150
 
151
#include "config.h"
152
#include "common_types.h"
153
#include "out.h"
154
#include "operand.h"
155
#include "instrmacs.h"
156
#include "expmacs.h"
157
#include "exp.h"
158
#include "instr386.h"
159
#include "flags.h"
160
#include "tags.h"
161
#include "shapemacs.h"
162
#include "flpt.h"
163
#include "flpttypes.h"
164
#include "coder.h"
165
#include "basicread.h"
166
#include "reg_record.h"
167
#include "installglob.h"
168
#include "table_fns.h"
169
#include "codermacs.h"
170
#include "install_fns.h"
171
#include "machine.h"
172
#include "localflags.h"
173
#include "assembler.h"
174
#include "messages_8.h"
175
#include "readglob.h"
176
#include "check.h"
177
#include "label_ops.h"
178
#include "externs.h"
179
#include "xalloc.h"
180
 
181
#include "instr.h"
182
 
183
#ifdef NEWDWARF
184
#include "dw2_config.h"
185
#include "dw2_extra.h"
186
#endif
187
 
188
 
189
/* LOCAL TYPE */
190
 
191
typedef union eu_u {int i; exp e;} punner;
192
 
193
/* MACROS */
194
 
195
#define fstack_base 8
196
 
197
/* VARIABLES */
198
/* All variables initialised */
199
 
200
int  extra_stack = 0;	/* init by init_all */
201
int max_extra_stack = 0;	/* init by cproc */
202
int no_frame;		/* init by cproc */
203
#ifndef NEWDIAGS
204
static long  last_jump_pos;	/* set locally */
205
#endif
206
int  last_jump_label;	/* cleared to -1 by outnl */
207
 
208
static exp cont_err_handler = nilexp;
209
 
210
 
211
/* IDENTITIES */
212
 
213
char *margin = " ";		/* instruction left margin */
214
char *spx = " ";		/* separates instruction from operands */
215
char *sep = ",";		/* separates operands */
216
 
217
char *reg_name_long[8] = {
218
  "%eax", "%edx", "%ecx", "%ebx", "%edi", "%esi", "%ebp", "%esp"
219
};
220
char *reg_name_word[7] = {
221
  "%ax", "%dx", "%cx", "%bx", "%di", "%si", "%bp"
222
};
223
char *reg_name_byte[7] = {
224
  "%al", "%dl", "%cl", "%bl", "%??", "%??", "%??"
225
};
226
 
227
char *fl_reg_name[8] = {
228
  "%st", "%st(1)", "%st(2)", "%st(3)", "%st(4)", "%st(5)", "%st(6)",
229
  "%st(7)",
230
};
231
 
232
/* PROCEDURES */
233
 
234
void temp_push_fl
235
    PROTO_Z ()
236
{
237
  ++fstack_pos;
238
  return;
239
}
240
void temp_pop_fl
241
    PROTO_Z ()
242
{
243
  --fstack_pos;
244
  return;
245
}
246
 
247
 
248
/***************************************************************
249
 
250
outreal outputs a floating point number
251
 
252
****************************************************************/
253
 
254
void outreal
255
    PROTO_N ( (e) )
256
    PROTO_T ( exp e )
257
{
258
  flt * f = &flptnos[no(e)];
259
  int sw = name(sh(e)) - shrealhd;
260
  r2l longs;
261
 
262
  longs = real2longs_IEEE(f, sw);
263
 
264
  switch (sw) {
265
    case 0:
266
      outhex(longs.i1);
267
      outnl();
268
      break;
269
    case 1:
270
      outhex(longs.i1);
271
      outs(",");
272
      outhex(longs.i2);
273
      outnl();
274
      break;
275
    case 2:
276
      outhex(longs.i1);
277
      outs(",");
278
      outhex(longs.i2);
279
      outs(",");
280
      outhex(longs.i3);
281
      outnl();
282
      break;
283
  };
284
 
285
  return;
286
}
287
 
288
/* output operand i (in bytes) relative to
289
   stack pointer  uses address relative to
290
   frame pointer if it might be shorter */
291
void rel_sp
292
    PROTO_N ( (i, b) )
293
    PROTO_T ( int i X int b )
294
{
295
  int  n = i + (extra_stack / 8);
296
  if (!must_use_bp) {
297
				/* if we might use alloca all
298
				   displacements must be relative to frame
299
				   pointer */
300
    if (n == 0) {
301
      outs ("(%esp");
302
      if (b)
303
	outs (")");
304
      return;
305
    };
306
    if (n <= 127 || no_frame || stack_aligned_8byte) {
307
				/* use stack pointer if displacement from
308
				   it is small */
309
      outn ((long)n);
310
      outs ("(%esp");
311
      if (b)
312
	outs (")");
313
      return;
314
    };
315
  };
316
  /* otherwise use displacement from frame pointer */
317
  outn ((long)(i + (stack_dec / 8)));
318
  outs("-");
319
  outs(local_prefix);
320
  outs ("disp");
321
  outn ((long)crt_proc_id);
322
  outs ("(%ebp");
323
  if (b)
324
    outs (")");
325
  return;
326
}
327
 
328
/* output operand i (in bytes) relative to
329
   stack pointer */
330
void rel_cp
331
    PROTO_N ( (i, b) )
332
    PROTO_T ( int i X int b )
333
{
334
  int  n = i + (extra_stack / 8);
335
  if (n == 0) {
336
    outs ("(%esp");
337
    if (b)
338
      outs (")");
339
    return;
340
  };
341
  outn ((long)n);
342
  outs ("(%esp");
343
  if (b)
344
    outs (")");
345
  return;
346
}
347
 
348
/* output operand relative to frame
349
   pointer */
350
void rel_ap
351
    PROTO_N ( (i, b) )
352
    PROTO_T ( int i X int b )
353
{
354
  if (no_frame) {
355
    outn ((long)(i + ((extra_stack - stack_dec) / 8)));
356
    outs("+");
357
    outs(local_prefix);
358
    outs ("disp");
359
    outn ((long)crt_proc_id);
360
    outs ("(%esp");
361
    if (b)
362
      outs (")");
363
    return;
364
  }
365
  else {
366
    outn ((long)i + 4);
367
    outs ("(%ebp");
368
    if (b)
369
      outs (")");
370
    return;
371
  };
372
}
373
 
374
/* output operand relative to frame
375
   pointer and push space*/
376
void rel_ap1
377
    PROTO_N ( (i, b) )
378
    PROTO_T ( int i X int b )
379
{
380
  if (no_frame) {
381
    outn ((long)(i + ((extra_stack - stack_dec) / 8)));
382
    outs("+");
383
    outs(local_prefix);
384
    outs ("fcwdisp");
385
    outn ((long)crt_proc_id);
386
    outs ("(%esp");
387
    if (b)
388
      outs (")");
389
    return;
390
  }
391
  else {
392
    outn ((long)i);
393
    outs("-");
394
    outs(local_prefix);
395
    outs ("fcwdisp");
396
    outn ((long)crt_proc_id);
397
    outs ("(%ebp");
398
    if (b)
399
      outs (")");
400
    return;
401
  };
402
}
403
 
404
int  get_reg_no
405
    PROTO_N ( (regs) )
406
    PROTO_T ( int regs )
407
{
408
  frr fr;
409
  /* find the registers associated with the bit pattern regs */
410
 
411
  fr = first_reg (regs);
412
  if (regs == 0x10000 || fr.fr_no == (fstack_pos))
413
    return (fstack_pos);
414
  return (fr.fr_no);		/* this is the register number */
415
}
416
 
417
/* output a register address, regs is a
418
   bit pattern, rdisp is an offset in bit
419
   units. le tells us how to refer to the
420
   register (eg al or ax or eax) */
421
void regn
422
    PROTO_N ( (regs, rdisp, ldname, le) )
423
    PROTO_T ( int regs X int rdisp X exp ldname X int le )
424
{
425
  int  z;
426
  char **rn;
427
  UNUSED(rdisp);
428
  z = get_reg_no (regs);
429
 
430
  if (name (ldname) == name_tag && islastuse(ldname))
431
    regsinuse = regsinuse & ~regs;
432
 
433
  if (z >= first_fl_reg) {
434
    if (z == first_fl_reg) {
435
      outs (fl_reg_name[0]);
436
      return;
437
    };
438
    if (fstack_pos > 16) {
439
      failer (BAD_FSTACK);
440
      exit(EXIT_FAILURE);
441
    };
442
    outs (fl_reg_name[fstack_pos - z]);
443
    /* variables held in the floating point registers have to be addressed
444
       relative to the current stack position, because the registers are a
445
       stack as well as a register bank */
446
    return;
447
  };
448
 
449
  switch (le) {
450
    case 8:
451
      rn = reg_name_byte;
452
      break;
453
    case 16:
454
      rn = reg_name_word;
455
      break;
456
    default:
457
      rn = reg_name_long;
458
      break;
459
  };
460
  outs (rn[z]);			/* this outputs the register name */
461
  return;
462
}
463
 
464
 
465
/* output a displacement from register operand */
466
void ind_reg
467
    PROTO_N ( (regs, rdisp, offset, ldname, b) )
468
    PROTO_T ( int regs X int rdisp X int offset X exp ldname X int b )
469
{
470
  if (regs == 128)
471
    offset += extra_stack;
472
 
473
  if (offset == 0) {
474
    outs ("(");
475
    regn (regs, rdisp, ldname, 32);
476
    if (b)
477
      outs (")");
478
  }
479
  else {
480
    outn ((long)offset / 8);
481
    outs ("(");
482
    regn (regs, rdisp, ldname, 32);
483
    if (b)
484
      outs (")");
485
  };
486
  return;
487
}
488
 
489
/* use indexed addressing */
490
void index_opnd
491
    PROTO_N ( (whmain, wh, sc) )
492
    PROTO_T ( where whmain X where wh X int sc )
493
{
494
  exp m = whmain.where_exp;
495
  if ((name (m) == name_tag && ptno (son (m)) == reg_pl) ||
496
      (name (m) == cont_tag && name (son (m)) == name_tag &&
497
	isvar (son (son (m))) && ptno (son (son (m))) == reg_pl))
498
    outs ("(");
499
  operand (32, whmain, 0, 0);
500
  outs (",");
501
  operand (32, wh, 1, 0);
502
  if (sc != 1) {
503
    outs (",");
504
    outn ((long)sc);
505
  };
506
  outs (")");
507
  return;
508
}
509
 
510
 
511
/* output an external operand */
512
void extn
513
    PROTO_N ( (id, off, b) )
514
    PROTO_T ( exp id X int off X int b )
515
{
516
  dec * et;
517
 
518
  et = brog (id);
519
 
520
  if (PIC_code)
521
   {
522
     char * got;
523
     if (et -> dec_u.dec_val.extnamed)
524
        got = "GOT";
525
     else
526
        got = "GOTOFF";
527
     outs (et -> dec_u.dec_val.dec_id);
528
     outs("@");
529
     outs(got);
530
     if (off != 0)
531
      {
532
        outs ("+");
533
        outn ((long)off / 8);
534
      };
535
     outs("(%ebx");
536
     if (b)
537
       outs(")");
538
     return;
539
   };
540
 
541
  if (off == 0)
542
    outs (et -> dec_u.dec_val.dec_id);
543
  else {
544
    outs (et -> dec_u.dec_val.dec_id);
545
    outs ("+");
546
    outn ((long)off / 8);
547
  };
548
  if (!b)
549
    outs ("(");
550
  return;
551
}
552
 
553
/* an integer constant */
554
void int_operand
555
    PROTO_N ( (k, l) )
556
    PROTO_T ( int k X int l )
557
{
558
  int  mask;
559
  switch (l) {
560
    case 8:
561
      mask = 0xff;
562
      break;
563
    case 16:
564
      mask = 0xffff;
565
      break;
566
    default:
567
      mask = 0xffffffff;
568
  };
569
  outs ("$");
570
  outn ((long)k & mask);
571
  return;
572
}
573
 
574
 
575
/* an external literal */
576
void const_extn
577
    PROTO_N ( (ident, noff) )
578
    PROTO_T ( exp ident X int noff )
579
{
580
  if (!PIC_code)
581
    outs ("$");
582
  extn (ident, noff, 1);
583
  return;
584
}
585
 
586
/* an external literal */
587
void proc_extn
588
    PROTO_N ( (id, off) )
589
    PROTO_T ( exp id X int off )
590
{
591
  if (PIC_code)
592
   {
593
     dec * et;
594
     et = brog (id);
595
     if (off == 0)
596
       outs (et -> dec_u.dec_val.dec_id);
597
     else {
598
        outn ((long)off / 8);
599
        outs ("+");
600
        outs (et -> dec_u.dec_val.dec_id);
601
     };
602
     if (et -> dec_u.dec_val.extnamed)
603
        outs("@PLT");
604
   }
605
  else
606
   {
607
     outs ("$");
608
     extn (id, off, 1);
609
   };
610
 
611
  return;
612
}
613
 
614
void ldisp
615
    PROTO_Z ()
616
{
617
   outs(local_prefix);
618
   outs("disp");
619
   outn((long)crt_proc_id);
620
}
621
 
622
void label_operand
623
    PROTO_N ( (e) )
624
    PROTO_T ( exp e )
625
{
626
  punner l;
627
  l.e = pt(e);
628
  outs("$");
629
  outs(local_prefix);
630
  outs("V");
631
  outn((long)l.i);
632
  return;
633
}
634
 
635
void set_lv_label
636
    PROTO_N ( (e) )
637
    PROTO_T ( exp e )
638
{
639
  punner l;
640
  l.e = e;
641
  min_rfree |= 0x78;  /* save all callee registers */
642
 
643
  outs(local_prefix);
644
  outs("V");
645
  outn((long)l.i);
646
  outs(":");
647
  outnl();
648
  return;
649
}
650
 
651
void set_env_off
652
    PROTO_N ( (s, n) )
653
    PROTO_T ( int s X exp n )
654
{
655
  punner l;
656
  l.e = n;
657
  outs(".set ");
658
  outs(local_prefix);
659
  outs("O");
660
  outn((long)l.i);		/* produce an identifying number */
661
  outs(",");
662
  if (s<4)
663
   {
664
    outn((long)-s/8);
665
    outs("-");
666
    outs(local_prefix);
667
    outs ("disp");
668
    outn ((long)crt_proc_id);
669
   }
670
  else
671
   outn((long)s/8);
672
  outnl();
673
}
674
 
675
void envoff_operand
676
    PROTO_N ( (e, off) )
677
    PROTO_T ( exp e X int off )
678
{
679
  punner l;
680
  l.e = e;
681
  if (off != 0)
682
   {
683
    outn((long)off);
684
    outs("+");
685
   };
686
  outs(local_prefix);
687
  outs("O");
688
  outn((long)l.i);		/* produce an identifying number */
689
  return;
690
}
691
 
692
void envsize_operand
693
    PROTO_N ( (e) )
694
    PROTO_T ( exp e )
695
{
696
  dec * et = brog(e);
697
  outs (local_prefix);
698
  outs ("ESZ");
699
  outs (et -> dec_u.dec_val.dec_id);
700
  return;
701
}
702
 
703
/* 80386 instruction with no operands */
704
void ins0
705
    PROTO_N ( (i) )
706
    PROTO_T ( char *i )
707
{
708
  outs (margin);
709
  outs (i);
710
  outnl ();
711
  return;
712
}
713
 
714
/* one operand */
715
void ins1
716
    PROTO_N ( (i, le1, a1) )
717
    PROTO_T ( char *i X int le1 X where a1 )
718
{
719
  outs (margin);
720
  outs (i);
721
  outs (spx);
722
  operand (le1, a1, 1, 0);
723
  outnl ();
724
  return;
725
}
726
 
727
/* one operand, which is indirect */
728
void ins1ind
729
    PROTO_N ( (i, le1, a1) )
730
    PROTO_T ( char *i X int le1 X where a1 )
731
{
732
  outs (margin);
733
  outs (i);
734
  outs (spx);
735
  outs ("*");
736
  operand (le1, a1, 1, 0);
737
  outnl ();
738
  return;
739
}
740
 
741
/* one operand, which is immediate */
742
void ins1lit
743
    PROTO_N ( (i, le1, a1) )
744
    PROTO_T ( char *i X int le1 X where a1 )
745
{
746
  outs (margin);
747
  outs (i);
748
  outs (spx);
749
  operand (le1, a1, 1, 1);
750
  outnl ();
751
  return;
752
}
753
 
754
/* two operands */
755
void ins2
756
    PROTO_N ( (i, le1, le2, a1, a2) )
757
    PROTO_T ( char *i X int le1 X int le2 X where a1 X where a2 )
758
{
759
  outs (margin);
760
  outs (i);
761
  outs (spx);
762
  operand (le1, a1, 1, 0);
763
  outs (sep);
764
  operand (le2, a2, 1, 0);
765
  outnl ();
766
  return;
767
}
768
 
769
/* three operands */
770
void ins3
771
    PROTO_N ( (i, le1, le2, le3, a1, a2, a3) )
772
    PROTO_T ( char *i X int le1 X int le2 X int le3 X where a1 X where a2 X where a3 )
773
{
774
  outs (margin);
775
  outs (i);
776
  outs (spx);
777
  operand (le1, a1, 1, 0);
778
  outs (sep);
779
  operand (le2, a2, 1, 0);
780
  outs (sep);
781
  operand (le3, a3, 1, 0);
782
  outnl ();
783
  return;
784
}
785
 
786
 
787
void simplest_set_lab
788
    PROTO_N ( (labno) )
789
    PROTO_T ( int labno )
790
{
791
  outs(local_prefix);
792
  outn ((long)labno);
793
  outs (":");
794
  outnl ();
795
}
796
 
797
 
798
void simple_set_label
799
    PROTO_N ( (labno) )
800
    PROTO_T ( int labno )
801
{
802
#ifdef CHECKIMPROVE
803
  if (labno == last_jump_label)
804
    failer("redundant jump");
805
#endif
806
#ifndef NEWDIAGS
807
  int   st = 0;
808
  if (!diagnose && labno == last_jump_label) {
809
    st = fseek (fpout, last_jump_pos, 0);
810
  };
811
  /* eliminate immediately previous jump to this label */
812
  if (st == -1) {
813
    failer (SEEK_FAILURE);
814
    exit(EXIT_FAILURE);
815
  };
816
#endif
817
 
818
  cond1_set = 0;
819
  cond2_set = 0;
820
  outs(local_prefix);
821
  outn ((long)labno);		/* the label no is held in the ptr field
822
				*/
823
  outs (":");
824
  outnl ();
825
/* Removed for experiments: improves compress?
826
  keep_short = 1;
827
*/
828
  return;
829
}
830
 
831
/* set label described by the jump record jr */
832
void set_label
833
    PROTO_N ( (jr) )
834
    PROTO_T ( exp jr )
835
{
836
  simple_set_label (ptno (jr));
837
}
838
 
839
/*  jump record: exp
840
    pt - label;
841
    last - forward;
842
    son - stack_dec;
843
    prop - floating stack position
844
*/
845
 
846
void discard_fstack
847
    PROTO_Z ()
848
{
849
  outs (" fstp %st(0)");
850
  outnl ();
851
  pop_fl;
852
  return;
853
}
854
 
855
void discard_st1
856
    PROTO_Z ()
857
{
858
  outs (" fstp %st(1)");
859
  outnl ();
860
  pop_fl;
861
}
862
 
863
 
864
/* output a jump to the label described by
865
   jump record jr */
866
void jump
867
    PROTO_N ( (jr, with_fl_reg) )
868
    PROTO_T ( exp jr X int with_fl_reg )
869
{
870
  int  fs_dest = (int)fstack_pos_of (jr);
871
  int  good_fs = fstack_pos;
872
  int  good_sd = stack_dec;
873
  if (fs_dest < first_fl_reg)
874
    failer (FSTACK_UNSET);
875
  if (with_fl_reg) {		/* jumping with a floating value */
876
    /* clear off any unwanted stack registers */
877
    while (fstack_pos > (fs_dest + 1))
878
      discard_st1 ();
879
    fstack_pos = good_fs - 1;
880
  }
881
  else {
882
    /* clear off any unwanted stack registers */
883
    while (fstack_pos > fs_dest)
884
      discard_fstack ();
885
    fstack_pos = good_fs;
886
  };
887
 
888
  if (sonno(jr) > stack_dec) {
889
    add(slongsh, mw (zeroe, (sonno(jr)-stack_dec) / 8), sp, sp);
890
    stack_dec = sonno(jr);
891
  }
892
 
893
  reset_fpucon();
894
  stack_dec = good_sd;
895
 
896
#ifndef NEWDIAGS
897
  if (flush_before_tell)
898
    IGNORE fflush(fpout);
899
  last_jump_pos = ftell (fpout);
900
#endif
901
  outs (margin);
902
  outs (jmp);
903
  outs (spx);
904
  outs(local_prefix);
905
  outn ((long)ptno (jr));
906
  outnl ();
907
  last_jump_label = ptno (jr);
908
  return;
909
}
910
 
911
static char* xse = "<=0";	/* no corresponding jump instruction */
912
static char* xnse = ">0";
913
 
914
 
915
/* output code for a branch instruction
916
   determined by test_no. The test is
917
   signed if sg is true */
918
static char *out_branch
919
    PROTO_N ( (sg, test_no, shnm) )
920
    PROTO_T ( int sg X int test_no X int shnm )
921
{
922
  if (shnm >= shrealhd && shnm <= doublehd) {
923
    switch (test_no) {
924
      case 1:
925
	return (jne);
926
 
927
      case 2:
928
	return (jne);
929
 
930
      case 3:
931
	return (jpe);
932
 
933
      case 4:
934
	return (jpe);
935
 
936
      case 5:
937
	return (jpe);
938
 
939
      case 6:
940
	return (jpo);
941
 
942
      case 7:
943
	return (jpo);
944
 
945
      case 8:
946
	return (jpo);
947
 
948
      case 9:
949
	return (je);
950
 
951
      case 10:
952
	return (je);
953
 
954
      case 11:
955
	return (jne);
956
 
957
      case 12:
958
	return (je);
959
 
960
      case 13:
961
	return (jne);
962
 
963
      case 14:
964
	return (je);
965
 
966
      default:
967
	failer (BAD_TESTNO);
968
    };
969
  };
970
 
971
  if (sg) {
972
    switch (test_no) {
973
      case 1:
974
	return (sg<0 ? xse : jle);
975
      case 2:
976
	return (sg<0 ? js : jl);
977
 
978
      case 3:
979
	return (sg<0 ? jns : jge);
980
 
981
      case 4:
982
	return (sg<0 ? xnse : jg);
983
 
984
      case 5:
985
	return (jne);
986
 
987
      case 6:
988
	return (je);
989
 
990
      default:
991
	failer (BAD_TESTNO);
992
    };
993
  }
994
  else {
995
    switch (test_no) {
996
      case 1:
997
	return (jbe);
998
 
999
      case 2:
1000
	return (jb);
1001
 
1002
      case 3:
1003
	return (jae);
1004
 
1005
      case 4:
1006
	return (ja);
1007
 
1008
      case 5:
1009
	return (jne);
1010
 
1011
      case 6:
1012
	return (je);
1013
 
1014
      default:
1015
	failer (BAD_TESTNO);
1016
    };
1017
  };
1018
  return ((char *) 0);
1019
}
1020
 
1021
void simple_branch
1022
    PROTO_N ( (j, labno) )
1023
    PROTO_T ( char *j X int labno )
1024
{
1025
  outs (margin);
1026
  outs (j);
1027
  outs (spx);
1028
  outs(local_prefix);
1029
  outn ((long)labno);
1030
  outnl ();
1031
 
1032
}
1033
 
1034
 
1035
/* output conditional jump to jr. testno
1036
   specifies kind of test. sg is 1 if
1037
   signed arithmetic, 0 unsigned, -1 if
1038
   signed vs zero (ignoring overflow).
1039
   shnm name of shape */
1040
void branch
1041
    PROTO_N ( (test_no, jr, sg, shnm) )
1042
    PROTO_T ( int test_no X exp jr X int sg X int shnm )
1043
{
1044
  int  fs_dest = (int)fstack_pos_of (jr);
1045
  int  good_fs = fstack_pos;
1046
  int  good_fpucon = fpucon;
1047
  if (fs_dest < first_fl_reg)
1048
    failer (FSTACK_UNSET);
1049
  if (fstack_pos > fs_dest || sonno(jr) != stack_dec || fpucon != normal_fpucon
1050
	|| cmp_64hilab >= 0) {
1051
	/* floating point stack or call stack need attention */
1052
    int  nl = next_lab ();
1053
    int inv_test_no = (flpt_always_comparable ||
1054
			 (shnm < shrealhd || shnm > doublehd))
1055
				? (int)int_inverse_ntest[test_no]
1056
				: (int)real_inverse_ntest[test_no];
1057
 
1058
    char* cj = out_branch ((cmp_64hilab >= 0 ? 0 : sg), inv_test_no, shnm);
1059
    if (*cj == 'j') {
1060
      simple_branch (cj, nl);
1061
    }
1062
    else	/* compare with zero, ignoring overflow */
1063
    if (*cj == '>') {
1064
      int nl1 = next_lab ();
1065
      simple_branch (js, nl1);
1066
      simple_branch (jne, nl);
1067
      simplest_set_lab (nl1);
1068
    }
1069
    else {
1070
      simple_branch (js, nl);
1071
      simple_branch (je, nl);
1072
    }
1073
 
1074
    if (cmp_64hilab >= 0) {
1075
      int nl2 = ptno (jr);
1076
      if (shnm != s64hd)
1077
	failer ("uncompleted 64-bit comparison");
1078
      if (fstack_pos > fs_dest || sonno(jr) != stack_dec || fpucon != normal_fpucon) {
1079
	nl2 = next_lab ();
1080
	simplest_set_lab (nl2);
1081
      }
1082
      jump (jr, 0);
1083
      simplest_set_lab (cmp_64hilab);
1084
      simple_branch (out_branch (1, test_no, shnm), nl2);
1085
      cmp_64hilab = -1;
1086
    }
1087
    else
1088
      jump (jr, 0);
1089
 
1090
    fstack_pos = good_fs;
1091
    fpucon = good_fpucon;
1092
    simplest_set_lab (nl);
1093
    return;
1094
  };
1095
 
1096
  {
1097
    char* cj = out_branch (sg, test_no, shnm);
1098
    if (*cj == 'j') {
1099
      simple_branch (cj, ptno (jr));
1100
    }
1101
    else	/* compare with zero, ignoring overflow */
1102
    if (*cj == '>') {
1103
      int nl1 = next_lab ();
1104
      simple_branch (js, nl1);
1105
      simple_branch (jne, ptno (jr));
1106
      simplest_set_lab (nl1);
1107
    }
1108
    else {
1109
      simple_branch (js, ptno (jr));
1110
      simple_branch (je, ptno (jr));
1111
    }
1112
  }
1113
  return;
1114
}
1115
 
1116
void setcc
1117
    PROTO_N ( (test_no, sg, shnm) )
1118
    PROTO_T ( int test_no X int sg X int shnm )
1119
{
1120
  char * b;
1121
  if (cmp_64hilab >= 0) {
1122
    int chl = cmp_64hilab;
1123
    int nl = next_lab ();
1124
    if (shnm != s64hd)
1125
      failer ("uncompleted 64-bit comparison");
1126
    cmp_64hilab = -1;
1127
    setcc (test_no, 0, ulonghd);
1128
    simple_branch (jmp, nl);
1129
    simplest_set_lab (chl);
1130
    setcc (test_no, sg, slonghd);
1131
    simplest_set_lab (nl);
1132
  }
1133
 
1134
  b = out_branch (sg, test_no, shnm);
1135
  if (*b != 'j')
1136
    failer(NO_SETCC);
1137
  outs(margin);
1138
  outs("set");
1139
  outs(&b[1]);
1140
  outs(spx);
1141
  outs(reg_name_byte[0]);
1142
  outnl();
1143
  return;
1144
}
1145
 
1146
/* output conditional jump to jr if overflow
1147
   sg is 1 if signed arithmetic, 0 unsigned */
1148
void jmp_overflow
1149
    PROTO_N ( (jr, sg, inv) )
1150
    PROTO_T ( exp jr X int sg X int inv )
1151
{
1152
  int  fs_dest = (int)fstack_pos_of (jr);
1153
  int  good_fs = fstack_pos;
1154
  int  good_fpucon = fpucon;
1155
  if (fs_dest < first_fl_reg)
1156
    failer (FSTACK_UNSET);
1157
  if (fstack_pos > fs_dest || sonno(jr) != stack_dec || fpucon != normal_fpucon) {
1158
	/* floating point stack or call stack need attention */
1159
    int  nl = next_lab ();
1160
    if (sg)
1161
      simple_branch(jno, nl);
1162
    else
1163
      simple_branch((inv ? jb : jae), nl);
1164
    jump (jr, 0);
1165
    fstack_pos = good_fs;
1166
    fpucon = good_fpucon;
1167
    simplest_set_lab (nl);
1168
    return;
1169
  };
1170
  if (sg)
1171
    simple_branch(jo, ptno(jr));
1172
  else
1173
    simple_branch((inv ? jae : jb), ptno(jr));
1174
  return;
1175
}
1176
 
1177
 
1178
/* software interrupt */
1179
void trap_ins
1180
    PROTO_N ( (s) )
1181
    PROTO_T ( int s )
1182
{
1183
#ifndef AVOID_INTOV
1184
  if (s == f_overflow) {
1185
    ins0 ("int $4");	/* numeric interrupt */
1186
    return;
1187
  }
1188
#else
1189
#if (AVOID_INTOV == 16)
1190
  if (s == f_overflow) {
1191
    ins0 ("int $16");	/* mimic floating point interrupt */
1192
    return;
1193
  }
1194
#endif
1195
#endif
1196
  if (cont_err_handler == nilexp) {
1197
    cont_err_handler = make_extn ("__trans386_errhandler", f_proc, 1);
1198
    if (!PIC_code)
1199
      cont_err_handler = getexp (f_proc, nilexp, 1, cont_err_handler, nilexp, 0, 0, cont_tag);
1200
  }
1201
  ins1 (pushl, 32, mw (zeroe, s));
1202
#ifdef NEWDWARF
1203
  if (diagnose && dwarf2 && no_frame)
1204
    dw2_track_push();
1205
#endif
1206
  ins2 (movl, 32, 32, mw(cont_err_handler, 0), reg0);
1207
  if (PIC_code)
1208
    ins1ind (call, 32, ind_reg0);
1209
  else
1210
    ins1ind (call, 32, reg0);
1211
  return;
1212
}
1213
 
1214
 
1215
/* output software interrupt if overflow
1216
   sg is 1 if signed arithmetic, 0 unsigned */
1217
void trap_overflow
1218
    PROTO_N ( (sg, inv) )
1219
    PROTO_T ( int sg X int inv )
1220
{
1221
#ifdef AVOID_INTOV
1222
    int nl = next_lab ();
1223
    if (sg)
1224
      simple_branch(jno, nl);
1225
    else
1226
      simple_branch((inv ? jb : jae), nl);
1227
    trap_ins(f_overflow);
1228
    simplest_set_lab (nl);
1229
#else
1230
  if (sg)
1231
    ins0(into);
1232
  else {
1233
    int nl = next_lab ();
1234
    simple_branch((inv ? jb : jae), nl);
1235
    trap_ins(f_overflow);
1236
    simplest_set_lab (nl);
1237
  }
1238
#endif
1239
  return;
1240
}
1241
 
1242
 
1243
/* conditional software interrupt
1244
   sg is 1 if signed arithmetic
1245
   shnm name of shape */
1246
void test_trap
1247
    PROTO_N ( (test_no, sg, shnm) )
1248
    PROTO_T ( int test_no X int sg X int shnm )
1249
{
1250
  int nl = next_lab ();
1251
  int inv_test_no = (flpt_always_comparable ||
1252
			 (shnm < shrealhd || shnm > doublehd))
1253
				? (int)int_inverse_ntest[test_no]
1254
				: (int)real_inverse_ntest[test_no];
1255
  simple_branch (out_branch (sg, inv_test_no, shnm), nl);
1256
  trap_ins(f_overflow);
1257
  simplest_set_lab (nl);
1258
  return;
1259
}
1260
 
1261
 
1262
 
1263
/* special output for doing multiply by
1264
   using index instructions */
1265
void mult_op
1266
    PROTO_N ( (inc, rmain, rind, sc, dest) )
1267
    PROTO_T ( int inc X where rmain X where rind X int sc X where dest )
1268
{
1269
  outs (margin);
1270
  outs ("leal");
1271
  outs (spx);
1272
  if (inc != 0)
1273
    outn ((long)inc);
1274
  outs ("(");
1275
  if (name (rmain.where_exp) != val_tag ||
1276
      (no (rmain.where_exp) + rmain.where_off) != 0)
1277
    operand (32, rmain, 1, 0);
1278
  outs (",");
1279
  operand (32, rind, 1, 0);
1280
  if (sc != 1) {
1281
    outs (",");
1282
    outn ((long)sc);
1283
  };
1284
  outs ("),");
1285
 
1286
  if (inmem (dest)) {
1287
    operand (32, reg0, 1, 0);
1288
    outnl ();
1289
    invalidate_dest (reg0);
1290
    end_contop ();
1291
    move (slongsh, reg0, dest);
1292
  }
1293
  else {
1294
    operand (32, dest, 1, 0);
1295
    outnl ();
1296
    end_contop ();
1297
  };
1298
  return;
1299
}
1300
 
1301
/* output the case switch jump and the jump table */
1302
void caseins
1303
    PROTO_N ( (sz, arg, min, max, v, exhaustive, in_eax, case_exp) )
1304
    PROTO_T ( int sz X exp arg X int min X int max X int *v X int exhaustive X int in_eax X exp case_exp )
1305
{
1306
  int tab;
1307
  int absent;
1308
  where a;
1309
  int need_label_flag=0;
1310
  exp next= short_next_jump(case_exp);
1311
  if (next != nilexp && name(next)==goto_tag)
1312
  {
1313
    exp lab=final_dest(pt(next));
1314
    absent=ptno(pt(son(lab)));
1315
  }
1316
  else
1317
  {
1318
    absent = (exhaustive) ? -1 : next_lab ();
1319
    need_label_flag=1;
1320
  }
1321
 
1322
  tab = next_lab ();
1323
  a = mw (arg, 0);
1324
 
1325
  if (inmem (mw (arg, 0)) || sz != 32) {
1326
    if (!in_eax)
1327
      change_var (slongsh, a, reg0);
1328
    a = reg0;
1329
  }
1330
 
1331
  /* the switch jump */
1332
  out_switch_jump(tab, a, min);
1333
 
1334
  /* table of offsets */
1335
  out_switch_table(tab, min, max, v, absent);
1336
 
1337
  if (!exhaustive && need_label_flag==1) {
1338
    /*  label for default of switch; continue here */
1339
    outs(local_prefix);
1340
    outn ((long)absent);
1341
    outs (":");
1342
    outnl ();
1343
#ifdef NEWDWARF
1344
    START_BB ();
1345
#endif
1346
  };
1347
  return;
1348
}
1349
 
1350
 
1351
void const_intnl
1352
    PROTO_N ( (addr, lab, off) )
1353
    PROTO_T ( int addr X int lab X int off )
1354
{
1355
  if (PIC_code)
1356
   {
1357
    outs(local_prefix);
1358
    outn ((long)lab);
1359
    outs("@GOTOFF");
1360
    if (off != 0) {
1361
      outs ("+");
1362
      outn ((long)off / 8);
1363
    };
1364
    outs("(%ebx)");
1365
    return;
1366
   }
1367
  else
1368
   {
1369
    if (addr)
1370
      outs ("$");
1371
    outs(local_prefix);
1372
    outn ((long)lab);
1373
    if (off != 0) {
1374
      outs ("+");
1375
      outn ((long)off / 8);
1376
    };
1377
    return;
1378
  };
1379
}
1380
 
1381
void load_stack0
1382
    PROTO_Z ()
1383
{
1384
  outs (" fld %st(0)");
1385
  outnl ();
1386
  return;
1387
}
1388
 
1389
void outbp
1390
    PROTO_Z ()
1391
{
1392
  outs("%ebp");
1393
}
1394
 
1395
void set_stack_from_bp
1396
    PROTO_Z ()
1397
{
1398
  outs (margin);
1399
  outs (leal);
1400
  outs (spx);
1401
  outn((long)stack_dec/8);
1402
  outs("-");
1403
  outs(local_prefix);
1404
  outs("disp");
1405
  outn((long)crt_proc_id);
1406
  outs ("(%ebp)");
1407
  outs (sep);
1408
  outs("%esp");
1409
  outnl ();
1410
  return;
1411
}
1412
 
1413
void testah
1414
    PROTO_N ( (mask) )
1415
    PROTO_T ( int mask )
1416
{
1417
  outs(" testb $");
1418
  outn((long)mask);
1419
  outs(",%ah");
1420
  outnl();
1421
  return;
1422
}
1423
 
1424
exp make_extn
1425
    PROTO_N ( (n, s, v) )
1426
    PROTO_T ( char * n X shape s X int v )
1427
{
1428
  dec * g = (dec *) (xmalloc (sizeof(dec)));
1429
  exp id = getexp (s, nilexp, 1, nilexp, nilexp, 0, 0, ident_tag);
1430
  exp nme = getexp (s, nilexp, 1, id, nilexp, 0, 0, name_tag);
1431
  setglob (id);
1432
  if (v) {
1433
#if keep_PIC_vars
1434
        setvar(id);
1435
#else
1436
        if (PIC_code)
1437
          sh(id) = f_pointer(f_alignment(s));
1438
        else
1439
          setvar(id);
1440
#endif
1441
  }
1442
  brog(id) = g;
1443
  if (prefix_length != 0) {
1444
    int nl = (int) strlen (n);
1445
    int j;
1446
    char * newn = (char *) xcalloc ((nl + prefix_length + 1), sizeof (char));
1447
    for (j = 0; j < prefix_length; ++j)
1448
      newn[j] = name_prefix[j];
1449
    for (j = 0; j < nl; ++j)
1450
      newn[j+prefix_length] = n[j];
1451
    newn[nl+prefix_length] = 0;
1452
    n = newn;
1453
  }
1454
  g -> dec_u.dec_val.dec_exp = id;
1455
  g -> dec_u.dec_val.dec_id = n;
1456
  g -> dec_u.dec_val.extnamed = 1;
1457
  return (nme);
1458
}
1459
 
1460
 
1461
 
1462
/* shift or rotate 64 bits in reg0/reg1 */
1463
void rotshift64
1464
    PROTO_N ( (shft, sig, wshift) )
1465
    PROTO_T ( int shft X int sig X where wshift )
1466
{
1467
  if (name(wshift.where_exp) == val_tag) {	/* no of places is constant */
1468
    int places = no (wshift.where_exp) + wshift.where_off;
1469
    if (places >= 32) {
1470
      places -= 32;
1471
      switch (shft) {
1472
	case 0:
1473
	  if (places)
1474
	    ins2 (shll, 8, 32, mw(zeroe,places), reg0);
1475
	  move (ulongsh, reg0, reg1);
1476
	  move (ulongsh, zero, reg0);
1477
	  return;
1478
	case 1:
1479
	  move (ulongsh, reg1, reg0);
1480
	  if (places)
1481
	    ins2 ((sig ? sarl : shrl), 8, 32, mw(zeroe,places), reg0);
1482
	  if (sig)
1483
	    ins2 (sarl, 8, 32, mw(zeroe,31), reg1);
1484
	  else
1485
	    move (ulongsh, zero, reg1);
1486
	  return;
1487
	default: {
1488
	  if (!places) {
1489
	    ins2 (xchg, 32, 32, reg0, reg1);
1490
	    return;
1491
	  }
1492
	  places = 32 - places;
1493
	  shft = 5 - shft;	/* reverse rotate */
1494
	}
1495
      }
1496
    };
1497
    if (places == 0)
1498
      return;
1499
    switch (shft) {	/* between 1 and 31 places */
1500
      case 0:
1501
	ins3 (shldl, 8, 32, 32, mw(zeroe,places), reg0, reg1);
1502
	ins2 (shll, 8, 32, mw(zeroe,places), reg0);
1503
	return;
1504
      case 1:
1505
	ins3 (shrdl, 8, 32, 32, mw(zeroe,places), reg1, reg0);
1506
	ins2 ((sig ? sarl : shrl), 8, 32, mw(zeroe,places), reg1);
1507
	return;
1508
      default: {
1509
	char * dsh = (shft == 2 ? shrdl : shldl);
1510
        extra_stack += 64;
1511
	check_stack_max;
1512
	ins0 (pushedx);
1513
#ifdef NEWDWARF
1514
	if (diagnose && dwarf2 && no_frame)
1515
	  dw2_track_push();
1516
#endif
1517
	ins0 (pusheax);
1518
#ifdef NEWDWARF
1519
	if (diagnose && dwarf2 && no_frame)
1520
	  dw2_track_push();
1521
#endif
1522
	ins3 (dsh, 8, 32, 32, mw(zeroe,places),
1523
		reg1, mw(ind_sp.where_exp,-32));
1524
	ins3 (dsh, 8, 32, 32, mw(zeroe,places),
1525
		reg0, mw(ind_sp.where_exp,-64));
1526
	ins0 (popeax);
1527
#ifdef NEWDWARF
1528
	if (diagnose && dwarf2 && no_frame)
1529
	  dw2_track_pop();
1530
#endif
1531
	ins0 (popedx);
1532
#ifdef NEWDWARF
1533
	if (diagnose && dwarf2 && no_frame)
1534
	  dw2_track_pop();
1535
#endif
1536
	invalidate_dest (ind_sp);
1537
        extra_stack -= 64;
1538
	return;
1539
      }
1540
    }
1541
  };
1542
  {				/* number of places in reg2 */
1543
    int lablow = next_lab ();
1544
    int labend = next_lab ();
1545
    ins2 (cmpl, 32, 32, mw(zeroe,32), reg2);
1546
    simple_branch (jl, lablow);
1547
    switch (shft) {
1548
      case 0:
1549
	ins2 (subl, 32, 32, mw(zeroe,32), reg2);
1550
	ins2 (shll, 8, 32, reg2, reg0);
1551
	move (ulongsh, reg0, reg1);
1552
	move (ulongsh, zero, reg0);
1553
	break;
1554
      case 1:
1555
	ins2 (subl, 32, 32, mw(zeroe,32), reg2);
1556
	move (ulongsh, reg1, reg0);
1557
	ins2 ((sig ? sarl : shrl), 8, 32, reg2, reg0);
1558
	if (sig)
1559
	  ins2 (sarl, 8, 32, mw(zeroe,31), reg1);
1560
	else
1561
	  move (ulongsh, zero, reg1);
1562
	break;
1563
      default: {
1564
	int labx = next_lab ();
1565
	char * dsh = (shft == 2 ? shldl : shrdl);	/* reversed rotate */
1566
	simple_branch (je, labx);
1567
	ins2 (subl, 32, 32, mw(zeroe,64), reg2);
1568
	ins1 (negl, 32, reg2);
1569
        extra_stack += 64;
1570
	check_stack_max;
1571
	ins0 (pushedx);
1572
#ifdef NEWDWARF
1573
	if (diagnose && dwarf2 && no_frame)
1574
	  dw2_track_push();
1575
#endif
1576
	ins0 (pusheax);
1577
#ifdef NEWDWARF
1578
	if (diagnose && dwarf2 && no_frame)
1579
	  dw2_track_push();
1580
#endif
1581
	ins3 (dsh, 8, 32, 32, reg2, reg1, mw(ind_sp.where_exp,-32));
1582
	ins3 (dsh, 8, 32, 32, reg2, reg0, mw(ind_sp.where_exp,-64));
1583
	ins0 (popeax);
1584
#ifdef NEWDWARF
1585
	if (diagnose && dwarf2 && no_frame)
1586
	  dw2_track_pop();
1587
#endif
1588
	ins0 (popedx);
1589
#ifdef NEWDWARF
1590
	if (diagnose && dwarf2 && no_frame)
1591
	  dw2_track_pop();
1592
#endif
1593
	invalidate_dest (ind_sp);
1594
        extra_stack -= 64;
1595
	simple_branch (jmp, labend);
1596
	simplest_set_lab (labx);
1597
	ins2 (xchg, 32, 32, reg0, reg1);
1598
      }
1599
    }
1600
    simple_branch (jmp, labend);
1601
    simplest_set_lab (lablow);
1602
    switch (shft) {	/* between 0 and 31 places */
1603
      case 0:
1604
	ins3 (shldl, 8, 32, 32, reg2, reg0, reg1);
1605
	ins2 (shll, 8, 32, reg2, reg0);
1606
	break;
1607
      case 1:
1608
	ins3 (shrdl, 8, 32, 32, reg2, reg1, reg0);
1609
	ins2 ((sig ? sarl : shrl), 8, 32, reg2, reg1);
1610
	break;
1611
      default: {
1612
	char * dsh = (shft == 2 ? shrdl : shldl);
1613
        extra_stack += 64;
1614
	check_stack_max;
1615
	ins0 (pushedx);
1616
#ifdef NEWDWARF
1617
	if (diagnose && dwarf2 && no_frame)
1618
	  dw2_track_push();
1619
#endif
1620
	ins0 (pusheax);
1621
#ifdef NEWDWARF
1622
	if (diagnose && dwarf2 && no_frame)
1623
	  dw2_track_push();
1624
#endif
1625
	ins3 (dsh, 8, 32, 32, reg2, reg1, mw(ind_sp.where_exp,-32));
1626
	ins3 (dsh, 8, 32, 32, reg2, reg0, mw(ind_sp.where_exp,-64));
1627
	ins0 (popeax);
1628
#ifdef NEWDWARF
1629
	if (diagnose && dwarf2 && no_frame)
1630
	  dw2_track_pop();
1631
#endif
1632
	ins0 (popedx);
1633
#ifdef NEWDWARF
1634
	if (diagnose && dwarf2 && no_frame)
1635
	  dw2_track_pop();
1636
#endif
1637
	invalidate_dest (ind_sp);
1638
        extra_stack -= 64;
1639
      }
1640
    }
1641
    simplest_set_lab (labend);
1642
  };
1643
  return;
1644
}