Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – tendra.SVN – Blame – /trunk/src/installers/amd64/common/instr.c – Rev 6

Subversion Repositories tendra.SVN

Rev

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

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