xref: /386bsd/usr/src/usr.bin/gcc/cc1/config/i386/i386.c (revision a2142627)
1 /* Subroutines for insn-output.c for Intel 80386.
2    Copyright (C) 1988, 1992 Free Software Foundation, Inc.
3 
4 This file is part of GNU CC.
5 
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
19 
20 #include <stdio.h>
21 #include <setjmp.h>
22 #include "config.h"
23 #include "rtl.h"
24 #include "regs.h"
25 #include "hard-reg-set.h"
26 #include "real.h"
27 #include "insn-config.h"
28 #include "conditions.h"
29 #include "insn-flags.h"
30 #include "output.h"
31 #include "insn-attr.h"
32 #include "tree.h"
33 #include "flags.h"
34 
35 #ifdef EXTRA_CONSTRAINT
36 /* If EXTRA_CONSTRAINT is defined, then the 'S'
37    constraint in REG_CLASS_FROM_LETTER will no longer work, and various
38    asm statements that need 'S' for class SIREG will break.  */
39  error EXTRA_CONSTRAINT conflicts with S constraint letter
40 /* The previous line used to be #error, but some compilers barf
41    even if the conditional was untrue.  */
42 #endif
43 
44 #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
45 
46 extern FILE *asm_out_file;
47 extern char *strcat ();
48 
49 char *singlemove_string ();
50 char *output_move_const_single ();
51 char *output_fp_cc0_set ();
52 
53 char *hi_reg_name[] = HI_REGISTER_NAMES;
54 char *qi_reg_name[] = QI_REGISTER_NAMES;
55 char *qi_high_reg_name[] = QI_HIGH_REGISTER_NAMES;
56 
57 /* Array of the smallest class containing reg number REGNO, indexed by
58    REGNO.  Used by REGNO_REG_CLASS in i386.h. */
59 
60 enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
61 {
62   /* ax, dx, cx, bx */
63   AREG, DREG, CREG, BREG,
64   /* si, di, bp, sp */
65   SIREG, DIREG, INDEX_REGS, GENERAL_REGS,
66   /* FP registers */
67   FP_TOP_REG, FP_SECOND_REG, FLOAT_REGS, FLOAT_REGS,
68   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
69   /* arg pointer */
70   INDEX_REGS
71 };
72 
73 /* Test and compare insns in i386.md store the information needed to
74    generate branch and scc insns here.  */
75 
76 struct rtx_def *i386_compare_op0, *i386_compare_op1;
77 struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
78 
79 /* Output an insn whose source is a 386 integer register.  SRC is the
80    rtx for the register, and TEMPLATE is the op-code template.  SRC may
81    be either SImode or DImode.
82 
83    The template will be output with operands[0] as SRC, and operands[1]
84    as a pointer to the top of the 386 stack.  So a call from floatsidf2
85    would look like this:
86 
87       output_op_from_reg (operands[1], AS1 (fild%z0,%1));
88 
89    where %z0 corresponds to the caller's operands[1], and is used to
90    emit the proper size suffix.
91 
92    ??? Extend this to handle HImode - a 387 can load and store HImode
93    values directly. */
94 
95 void
output_op_from_reg(src,template)96 output_op_from_reg (src, template)
97      rtx src;
98      char *template;
99 {
100   rtx xops[4];
101 
102   xops[0] = src;
103   xops[1] = AT_SP (Pmode);
104   xops[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (src)));
105   xops[3] = stack_pointer_rtx;
106 
107   if (GET_MODE_SIZE (GET_MODE (src)) > UNITS_PER_WORD)
108     {
109       rtx high = gen_rtx (REG, SImode, REGNO (src) + 1);
110       output_asm_insn (AS1 (push%L0,%0), &high);
111     }
112   output_asm_insn (AS1 (push%L0,%0), &src);
113 
114   output_asm_insn (template, xops);
115 
116   output_asm_insn (AS2 (add%L3,%2,%3), xops);
117 }
118 
119 /* Output an insn to pop an value from the 387 top-of-stack to 386
120    register DEST. The 387 register stack is popped if DIES is true.  If
121    the mode of DEST is an integer mode, a `fist' integer store is done,
122    otherwise a `fst' float store is done. */
123 
124 void
output_to_reg(dest,dies)125 output_to_reg (dest, dies)
126      rtx dest;
127      int dies;
128 {
129   rtx xops[4];
130 
131   xops[0] = AT_SP (Pmode);
132   xops[1] = stack_pointer_rtx;
133   xops[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (dest)));
134   xops[3] = dest;
135 
136   output_asm_insn (AS2 (sub%L1,%2,%1), xops);
137 
138   if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
139     {
140       if (dies)
141 	output_asm_insn (AS1 (fistp%z3,%y0), xops);
142       else
143 	output_asm_insn (AS1 (fist%z3,%y0), xops);
144     }
145   else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
146     {
147       if (dies)
148 	output_asm_insn (AS1 (fstp%z3,%y0), xops);
149       else
150 	output_asm_insn (AS1 (fst%z3,%y0), xops);
151     }
152   else
153     abort ();
154 
155   output_asm_insn (AS1 (pop%L0,%0), &dest);
156 
157   if (GET_MODE_SIZE (GET_MODE (dest)) > UNITS_PER_WORD)
158     {
159       dest = gen_rtx (REG, SImode, REGNO (dest) + 1);
160       output_asm_insn (AS1 (pop%L0,%0), &dest);
161     }
162 }
163 
164 char *
singlemove_string(operands)165 singlemove_string (operands)
166      rtx *operands;
167 {
168   rtx x;
169   if (GET_CODE (operands[0]) == MEM
170       && GET_CODE (x = XEXP (operands[0], 0)) == PRE_DEC)
171     {
172       if (XEXP (x, 0) != stack_pointer_rtx)
173 	abort ();
174       return "push%L1 %1";
175     }
176   else if (GET_CODE (operands[1]) == CONST_DOUBLE)
177     {
178       return output_move_const_single (operands);
179     }
180   else if (GET_CODE (operands[0]) == REG || GET_CODE (operands[1]) == REG)
181     return AS2 (mov%L0,%1,%0);
182   else if (CONSTANT_P (operands[1]))
183     return AS2 (mov%L0,%1,%0);
184   else
185     {
186       output_asm_insn ("push%L1 %1", operands);
187       return "pop%L0 %0";
188     }
189 }
190 
191 /* Return a REG that occurs in ADDR with coefficient 1.
192    ADDR can be effectively incremented by incrementing REG.  */
193 
194 static rtx
find_addr_reg(addr)195 find_addr_reg (addr)
196      rtx addr;
197 {
198   while (GET_CODE (addr) == PLUS)
199     {
200       if (GET_CODE (XEXP (addr, 0)) == REG)
201 	addr = XEXP (addr, 0);
202       else if (GET_CODE (XEXP (addr, 1)) == REG)
203 	addr = XEXP (addr, 1);
204       else if (CONSTANT_P (XEXP (addr, 0)))
205 	addr = XEXP (addr, 1);
206       else if (CONSTANT_P (XEXP (addr, 1)))
207 	addr = XEXP (addr, 0);
208       else
209 	abort ();
210     }
211   if (GET_CODE (addr) == REG)
212     return addr;
213   abort ();
214 }
215 
216 /* Output an insn to add the constant N to the register X.  */
217 
218 static void
asm_add(n,x)219 asm_add (n, x)
220      int n;
221      rtx x;
222 {
223   rtx xops[2];
224   xops[1] = x;
225   if (n < 0)
226     {
227       xops[0] = GEN_INT (-n);
228       output_asm_insn (AS2 (sub%L0,%0,%1), xops);
229     }
230   else if (n > 0)
231     {
232       xops[0] = GEN_INT (n);
233       output_asm_insn (AS2 (add%L0,%0,%1), xops);
234     }
235 }
236 
237 /* Output assembler code to perform a doubleword move insn
238    with operands OPERANDS.  */
239 
240 char *
output_move_double(operands)241 output_move_double (operands)
242      rtx *operands;
243 {
244   enum {REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
245   rtx latehalf[2];
246   rtx addreg0 = 0, addreg1 = 0;
247   int dest_overlapped_low = 0;
248 
249   /* First classify both operands.  */
250 
251   if (REG_P (operands[0]))
252     optype0 = REGOP;
253   else if (offsettable_memref_p (operands[0]))
254     optype0 = OFFSOP;
255   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
256     optype0 = POPOP;
257   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
258     optype0 = PUSHOP;
259   else if (GET_CODE (operands[0]) == MEM)
260     optype0 = MEMOP;
261   else
262     optype0 = RNDOP;
263 
264   if (REG_P (operands[1]))
265     optype1 = REGOP;
266   else if (CONSTANT_P (operands[1]))
267     optype1 = CNSTOP;
268   else if (offsettable_memref_p (operands[1]))
269     optype1 = OFFSOP;
270   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
271     optype1 = POPOP;
272   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
273     optype1 = PUSHOP;
274   else if (GET_CODE (operands[1]) == MEM)
275     optype1 = MEMOP;
276   else
277     optype1 = RNDOP;
278 
279   /* Check for the cases that the operand constraints are not
280      supposed to allow to happen.  Abort if we get one,
281      because generating code for these cases is painful.  */
282 
283   if (optype0 == RNDOP || optype1 == RNDOP)
284     abort ();
285 
286   /* If one operand is decrementing and one is incrementing
287      decrement the former register explicitly
288      and change that operand into ordinary indexing.  */
289 
290   if (optype0 == PUSHOP && optype1 == POPOP)
291     {
292       operands[0] = XEXP (XEXP (operands[0], 0), 0);
293       asm_add (-8, operands[0]);
294       operands[0] = gen_rtx (MEM, DImode, operands[0]);
295       optype0 = OFFSOP;
296     }
297   if (optype0 == POPOP && optype1 == PUSHOP)
298     {
299       operands[1] = XEXP (XEXP (operands[1], 0), 0);
300       asm_add (-8, operands[1]);
301       operands[1] = gen_rtx (MEM, DImode, operands[1]);
302       optype1 = OFFSOP;
303     }
304 
305   /* If an operand is an unoffsettable memory ref, find a register
306      we can increment temporarily to make it refer to the second word.  */
307 
308   if (optype0 == MEMOP)
309     addreg0 = find_addr_reg (XEXP (operands[0], 0));
310 
311   if (optype1 == MEMOP)
312     addreg1 = find_addr_reg (XEXP (operands[1], 0));
313 
314   /* Ok, we can do one word at a time.
315      Normally we do the low-numbered word first,
316      but if either operand is autodecrementing then we
317      do the high-numbered word first.
318 
319      In either case, set up in LATEHALF the operands to use
320      for the high-numbered word and in some cases alter the
321      operands in OPERANDS to be suitable for the low-numbered word.  */
322 
323   if (optype0 == REGOP)
324     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
325   else if (optype0 == OFFSOP)
326     latehalf[0] = adj_offsettable_operand (operands[0], 4);
327   else
328     latehalf[0] = operands[0];
329 
330   if (optype1 == REGOP)
331     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
332   else if (optype1 == OFFSOP)
333     latehalf[1] = adj_offsettable_operand (operands[1], 4);
334   else if (optype1 == CNSTOP)
335     {
336       if (GET_CODE (operands[1]) == CONST_DOUBLE)
337 	split_double (operands[1], &operands[1], &latehalf[1]);
338       else if (CONSTANT_P (operands[1]))
339 	{
340 	  if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
341 	    latehalf[1] = constm1_rtx;
342 	  else
343 	    latehalf[1] = const0_rtx;
344 	}
345     }
346   else
347     latehalf[1] = operands[1];
348 
349   /* If insn is effectively movd N (sp),-(sp) then we will do the
350      high word first.  We should use the adjusted operand 1 (which is N+4 (sp))
351      for the low word as well, to compensate for the first decrement of sp.  */
352   if (optype0 == PUSHOP
353       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
354       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
355     operands[1] = latehalf[1];
356 
357   /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
358      if the upper part of reg N does not appear in the MEM, arrange to
359      emit the move late-half first.  Otherwise, compute the MEM address
360      into the upper part of N and use that as a pointer to the memory
361      operand.  */
362   if (optype0 == REGOP
363       && (optype1 == OFFSOP || optype1 == MEMOP))
364     {
365       if (reg_mentioned_p (operands[0], XEXP (operands[1], 0))
366 	  && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0)))
367 	{
368 	  /* If both halves of dest are used in the src memory address,
369 	     compute the address into latehalf of dest.  */
370 	  rtx xops[2];
371 	  xops[0] = latehalf[0];
372 	  xops[1] = XEXP (operands[1], 0);
373 	  output_asm_insn (AS2 (lea%L0,%a1,%0), xops);
374 	  operands[1] = gen_rtx (MEM, DImode, latehalf[0]);
375 	  latehalf[1] = adj_offsettable_operand (operands[1], 4);
376 	}
377       else if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)))
378 	/* If the low half of dest is mentioned in the source memory
379 	   address, the arrange to emit the move late half first.  */
380 	dest_overlapped_low = 1;
381     }
382 
383   /* If one or both operands autodecrementing,
384      do the two words, high-numbered first.  */
385 
386   /* Likewise,  the first move would clobber the source of the second one,
387      do them in the other order.  This happens only for registers;
388      such overlap can't happen in memory unless the user explicitly
389      sets it up, and that is an undefined circumstance.  */
390 
391   if (optype0 == PUSHOP || optype1 == PUSHOP
392       || (optype0 == REGOP && optype1 == REGOP
393 	  && REGNO (operands[0]) == REGNO (latehalf[1]))
394       || dest_overlapped_low)
395     {
396       /* Make any unoffsettable addresses point at high-numbered word.  */
397       if (addreg0)
398 	asm_add (4, addreg0);
399       if (addreg1)
400 	asm_add (4, addreg1);
401 
402       /* Do that word.  */
403       output_asm_insn (singlemove_string (latehalf), latehalf);
404 
405       /* Undo the adds we just did.  */
406       if (addreg0)
407          asm_add (-4, addreg0);
408       if (addreg1)
409 	asm_add (-4, addreg1);
410 
411       /* Do low-numbered word.  */
412       return singlemove_string (operands);
413     }
414 
415   /* Normal case: do the two words, low-numbered first.  */
416 
417   output_asm_insn (singlemove_string (operands), operands);
418 
419   /* Make any unoffsettable addresses point at high-numbered word.  */
420   if (addreg0)
421     asm_add (4, addreg0);
422   if (addreg1)
423     asm_add (4, addreg1);
424 
425   /* Do that word.  */
426   output_asm_insn (singlemove_string (latehalf), latehalf);
427 
428   /* Undo the adds we just did.  */
429   if (addreg0)
430     asm_add (-4, addreg0);
431   if (addreg1)
432     asm_add (-4, addreg1);
433 
434   return "";
435 }
436 
437 int
standard_80387_constant_p(x)438 standard_80387_constant_p (x)
439      rtx x;
440 {
441 #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
442   REAL_VALUE_TYPE d;
443   jmp_buf handler;
444   int is0, is1;
445 
446   if (setjmp (handler))
447     return 0;
448 
449   set_float_handler (handler);
450   REAL_VALUE_FROM_CONST_DOUBLE (d, x);
451   is0 = REAL_VALUES_EQUAL (d, dconst0);
452   is1 = REAL_VALUES_EQUAL (d, dconst1);
453   set_float_handler (NULL_PTR);
454 
455   if (is0)
456     return 1;
457 
458   if (is1)
459     return 2;
460 
461   /* Note that on the 80387, other constants, such as pi,
462      are much slower to load as standard constants
463      than to load from doubles in memory!  */
464 #endif
465 
466   return 0;
467 }
468 
469 char *
output_move_const_single(operands)470 output_move_const_single (operands)
471      rtx *operands;
472 {
473   if (FP_REG_P (operands[0]))
474     {
475       int conval = standard_80387_constant_p (operands[1]);
476 
477       if (conval == 1)
478 	return "fldz";
479 
480       if (conval == 2)
481 	return "fld1";
482     }
483   if (GET_CODE (operands[1]) == CONST_DOUBLE)
484     {
485       union { int i[2]; double d;} u1;
486       union { int i; float f;} u2;
487       u1.i[0] = CONST_DOUBLE_LOW (operands[1]);
488       u1.i[1] = CONST_DOUBLE_HIGH (operands[1]);
489       u2.f = u1.d;
490       operands[1] = GEN_INT (u2.i);
491     }
492   return singlemove_string (operands);
493 }
494 
495 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
496    reference and a constant.  */
497 
498 int
symbolic_operand(op,mode)499 symbolic_operand (op, mode)
500      register rtx op;
501      enum machine_mode mode;
502 {
503   switch (GET_CODE (op))
504     {
505     case SYMBOL_REF:
506     case LABEL_REF:
507       return 1;
508     case CONST:
509       op = XEXP (op, 0);
510       return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
511 	       || GET_CODE (XEXP (op, 0)) == LABEL_REF)
512 	      && GET_CODE (XEXP (op, 1)) == CONST_INT);
513     default:
514       return 0;
515     }
516 }
517 
518 /* Test for a valid operand for a call instruction.
519    Don't allow the arg pointer register or virtual regs
520    since they may change into reg + const, which the patterns
521    can't handle yet.  */
522 
523 int
call_insn_operand(op,mode)524 call_insn_operand (op, mode)
525      rtx op;
526      enum machine_mode mode;
527 {
528   if (GET_CODE (op) == MEM
529       && ((CONSTANT_ADDRESS_P (XEXP (op, 0))
530 	   /* This makes a difference for PIC.  */
531 	   && general_operand (XEXP (op, 0), Pmode))
532 	  || (GET_CODE (XEXP (op, 0)) == REG
533 	      && XEXP (op, 0) != arg_pointer_rtx
534 	      && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
535 		   && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
536     return 1;
537   return 0;
538 }
539 
540 /* Like call_insn_operand but allow (mem (symbol_ref ...))
541    even if pic.  */
542 
543 int
expander_call_insn_operand(op,mode)544 expander_call_insn_operand (op, mode)
545      rtx op;
546      enum machine_mode mode;
547 {
548   if (GET_CODE (op) == MEM
549       && (CONSTANT_ADDRESS_P (XEXP (op, 0))
550 	  || (GET_CODE (XEXP (op, 0)) == REG
551 	      && XEXP (op, 0) != arg_pointer_rtx
552 	      && !(REGNO (XEXP (op, 0)) >= FIRST_PSEUDO_REGISTER
553 		   && REGNO (XEXP (op, 0)) <= LAST_VIRTUAL_REGISTER))))
554     return 1;
555   return 0;
556 }
557 
558 /* Returns 1 if OP contains a symbol reference */
559 
560 int
symbolic_reference_mentioned_p(op)561 symbolic_reference_mentioned_p (op)
562      rtx op;
563 {
564   register char *fmt;
565   register int i;
566 
567   if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
568     return 1;
569 
570   fmt = GET_RTX_FORMAT (GET_CODE (op));
571   for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
572     {
573       if (fmt[i] == 'E')
574 	{
575 	  register int j;
576 
577 	  for (j = XVECLEN (op, i) - 1; j >= 0; j--)
578 	    if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
579 	      return 1;
580 	}
581       else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
582 	return 1;
583     }
584 
585   return 0;
586 }
587 
588 /* Return a legitimate reference for ORIG (an address) using the
589    register REG.  If REG is 0, a new pseudo is generated.
590 
591    There are three types of references that must be handled:
592 
593    1. Global data references must load the address from the GOT, via
594       the PIC reg.  An insn is emitted to do this load, and the reg is
595       returned.
596 
597    2. Static data references must compute the address as an offset
598       from the GOT, whose base is in the PIC reg.  An insn is emitted to
599       compute the address into a reg, and the reg is returned.  Static
600       data objects have SYMBOL_REF_FLAG set to differentiate them from
601       global data objects.
602 
603    3. Constant pool addresses must be handled special.  They are
604       considered legitimate addresses, but only if not used with regs.
605       When printed, the output routines know to print the reference with the
606       PIC reg, even though the PIC reg doesn't appear in the RTL.
607 
608    GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
609    reg also appears in the address (except for constant pool references,
610    noted above).
611 
612    "switch" statements also require special handling when generating
613    PIC code.  See comments by the `casesi' insn in i386.md for details.  */
614 
615 rtx
legitimize_pic_address(orig,reg)616 legitimize_pic_address (orig, reg)
617      rtx orig;
618      rtx reg;
619 {
620   rtx addr = orig;
621   rtx new = orig;
622 
623   if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
624     {
625       if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr))
626 	reg = new = orig;
627       else
628 	{
629 	  if (reg == 0)
630 	    reg = gen_reg_rtx (Pmode);
631 
632 	  if (GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr))
633 	    new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig);
634 	  else
635 	    new = gen_rtx (MEM, Pmode,
636 			   gen_rtx (PLUS, Pmode,
637 				    pic_offset_table_rtx, orig));
638 
639 	  emit_move_insn (reg, new);
640 	}
641       current_function_uses_pic_offset_table = 1;
642       return reg;
643     }
644   else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
645     {
646       rtx base;
647 
648       if (GET_CODE (addr) == CONST)
649 	{
650 	  addr = XEXP (addr, 0);
651 	  if (GET_CODE (addr) != PLUS)
652 	    abort ();
653 	}
654 
655       if (XEXP (addr, 0) == pic_offset_table_rtx)
656 	return orig;
657 
658       if (reg == 0)
659 	reg = gen_reg_rtx (Pmode);
660 
661       base = legitimize_pic_address (XEXP (addr, 0), reg);
662       addr = legitimize_pic_address (XEXP (addr, 1),
663 				     base == reg ? NULL_RTX : reg);
664 
665       if (GET_CODE (addr) == CONST_INT)
666 	return plus_constant (base, INTVAL (addr));
667 
668       if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1)))
669 	{
670 	  base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0));
671 	  addr = XEXP (addr, 1);
672 	}
673 	return gen_rtx (PLUS, Pmode, base, addr);
674     }
675   return new;
676 }
677 
678 /* Emit insns to move operands[1] into operands[0].  */
679 
680 void
emit_pic_move(operands,mode)681 emit_pic_move (operands, mode)
682      rtx *operands;
683      enum machine_mode mode;
684 {
685   rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode);
686 
687   if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]))
688     operands[1] = (rtx) force_reg (SImode, operands[1]);
689   else
690     operands[1] = legitimize_pic_address (operands[1], temp);
691 }
692 
693 /* This function generates the assembly code for function entry.
694    FILE is an stdio stream to output the code to.
695    SIZE is an int: how many units of temporary storage to allocate. */
696 
697 void
function_prologue(file,size)698 function_prologue (file, size)
699      FILE *file;
700      int size;
701 {
702   register int regno;
703   int limit;
704   rtx xops[4];
705   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
706 				  || current_function_uses_const_pool);
707 
708   xops[0] = stack_pointer_rtx;
709   xops[1] = frame_pointer_rtx;
710   xops[2] = GEN_INT (size);
711   if (frame_pointer_needed)
712     {
713       output_asm_insn ("push%L1 %1", xops);
714       output_asm_insn (AS2 (mov%L0,%0,%1), xops);
715     }
716 
717   if (size)
718     output_asm_insn (AS2 (sub%L0,%2,%0), xops);
719 
720   /* Note If use enter it is NOT reversed args.
721      This one is not reversed from intel!!
722      I think enter is slower.  Also sdb doesn't like it.
723      But if you want it the code is:
724      {
725      xops[3] = const0_rtx;
726      output_asm_insn ("enter %2,%3", xops);
727      }
728      */
729   limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
730   for (regno = limit - 1; regno >= 0; regno--)
731     if ((regs_ever_live[regno] && ! call_used_regs[regno])
732 	|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
733       {
734 	xops[0] = gen_rtx (REG, SImode, regno);
735 	output_asm_insn ("push%L0 %0", xops);
736       }
737 
738   if (pic_reg_used)
739     {
740       xops[0] = pic_offset_table_rtx;
741       xops[1] = (rtx) gen_label_rtx ();
742 
743       output_asm_insn (AS1 (call,%P1), xops);
744       ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (xops[1]));
745       output_asm_insn (AS1 (pop%L0,%0), xops);
746       output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops);
747     }
748 }
749 
750 /* Return 1 if it is appropriate to emit `ret' instructions in the
751    body of a function.  Do this only if the epilogue is simple, needing a
752    couple of insns.  Prior to reloading, we can't tell how many registers
753    must be saved, so return 0 then.
754 
755    If NON_SAVING_SETJMP is defined and true, then it is not possible
756    for the epilogue to be simple, so return 0.  This is a special case
757    since NON_SAVING_SETJMP will not cause regs_ever_live to change until
758    final, but jump_optimize may need to know sooner if a `return' is OK.  */
759 
760 int
simple_386_epilogue()761 simple_386_epilogue ()
762 {
763   int regno;
764   int nregs = 0;
765   int reglimit = (frame_pointer_needed
766 		  ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
767   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
768 				  || current_function_uses_const_pool);
769 
770 #ifdef NON_SAVING_SETJMP
771   if (NON_SAVING_SETJMP && current_function_calls_setjmp)
772     return 0;
773 #endif
774 
775   if (! reload_completed)
776     return 0;
777 
778   for (regno = reglimit - 1; regno >= 0; regno--)
779     if ((regs_ever_live[regno] && ! call_used_regs[regno])
780 	|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
781       nregs++;
782 
783   return nregs == 0 || ! frame_pointer_needed;
784 }
785 
786 /* This function generates the assembly code for function exit.
787    FILE is an stdio stream to output the code to.
788    SIZE is an int: how many units of temporary storage to deallocate. */
789 
790 void
function_epilogue(file,size)791 function_epilogue (file, size)
792      FILE *file;
793      int size;
794 {
795   register int regno;
796   register int nregs, limit;
797   int offset;
798   rtx xops[3];
799   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
800 				  || current_function_uses_const_pool);
801 
802   /* Compute the number of registers to pop */
803 
804   limit = (frame_pointer_needed
805 	   ? FRAME_POINTER_REGNUM
806 	   : STACK_POINTER_REGNUM);
807 
808   nregs = 0;
809 
810   for (regno = limit - 1; regno >= 0; regno--)
811     if ((regs_ever_live[regno] && ! call_used_regs[regno])
812 	|| (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
813       nregs++;
814 
815   /* sp is often  unreliable so we must go off the frame pointer,
816    */
817 
818   /* In reality, we may not care if sp is unreliable, because we can
819      restore the register relative to the frame pointer.  In theory,
820      since each move is the same speed as a pop, and we don't need the
821      leal, this is faster.  For now restore multiple registers the old
822      way. */
823 
824   offset = -size - (nregs * UNITS_PER_WORD);
825 
826   xops[2] = stack_pointer_rtx;
827 
828   if (nregs > 1 || ! frame_pointer_needed)
829     {
830       if (frame_pointer_needed)
831 	{
832 	  xops[0] = adj_offsettable_operand (AT_BP (Pmode), offset);
833 	  output_asm_insn (AS2 (lea%L2,%0,%2), xops);
834 	}
835 
836       for (regno = 0; regno < limit; regno++)
837 	if ((regs_ever_live[regno] && ! call_used_regs[regno])
838 	    || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
839 	  {
840 	    xops[0] = gen_rtx (REG, SImode, regno);
841 	    output_asm_insn ("pop%L0 %0", xops);
842 	  }
843     }
844   else
845     for (regno = 0; regno < limit; regno++)
846       if ((regs_ever_live[regno] && ! call_used_regs[regno])
847 	  || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
848 	{
849 	  xops[0] = gen_rtx (REG, SImode, regno);
850 	  xops[1] = adj_offsettable_operand (AT_BP (Pmode), offset);
851 	  output_asm_insn (AS2 (mov%L0,%1,%0), xops);
852 	  offset += 4;
853 	}
854 
855   if (frame_pointer_needed)
856     {
857       /* On i486, mov & pop is faster than "leave". */
858 
859       if (TARGET_486)
860 	{
861 	  xops[0] = frame_pointer_rtx;
862 	  output_asm_insn (AS2 (mov%L2,%0,%2), xops);
863 	  output_asm_insn ("pop%L0 %0", xops);
864 	}
865       else
866 	output_asm_insn ("leave", xops);
867     }
868   else if (size)
869     {
870       /* If there is no frame pointer, we must still release the frame. */
871 
872       xops[0] = GEN_INT (size);
873       output_asm_insn (AS2 (add%L2,%0,%2), xops);
874     }
875 
876   if (current_function_pops_args && current_function_args_size)
877     {
878       xops[1] = GEN_INT (current_function_pops_args);
879 
880       /* i386 can only pop 32K bytes (maybe 64K?  Is it signed?).  If
881 	 asked to pop more, pop return address, do explicit add, and jump
882 	 indirectly to the caller. */
883 
884       if (current_function_pops_args >= 32768)
885 	{
886 	  /* ??? Which register to use here? */
887 	  xops[0] = gen_rtx (REG, SImode, 2);
888 	  output_asm_insn ("pop%L0 %0", xops);
889 	  output_asm_insn (AS2 (add%L2,%1,%2), xops);
890 	  output_asm_insn ("jmp %*%0", xops);
891 	}
892       else
893 	  output_asm_insn ("ret %1", xops);
894     }
895   else
896     output_asm_insn ("ret", xops);
897 }
898 
899 /* Print an integer constant expression in assembler syntax.  Addition
900    and subtraction are the only arithmetic that may appear in these
901    expressions.  FILE is the stdio stream to write to, X is the rtx, and
902    CODE is the operand print code from the output string.  */
903 
904 static void
output_pic_addr_const(file,x,code)905 output_pic_addr_const (file, x, code)
906      FILE *file;
907      rtx x;
908      int code;
909 {
910   char buf[256];
911 
912   switch (GET_CODE (x))
913     {
914     case PC:
915       if (flag_pic)
916 	putc ('.', file);
917       else
918 	abort ();
919       break;
920 
921     case SYMBOL_REF:
922     case LABEL_REF:
923       if (GET_CODE (x) == SYMBOL_REF)
924 	assemble_name (file, XSTR (x, 0));
925       else
926 	{
927 	  ASM_GENERATE_INTERNAL_LABEL (buf, "L",
928 				       CODE_LABEL_NUMBER (XEXP (x, 0)));
929 	  assemble_name (asm_out_file, buf);
930 	}
931 
932       if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x))
933 	fprintf (file, "@GOTOFF(%%ebx)");
934       else if (code == 'P')
935 	fprintf (file, "@PLT");
936       else if (GET_CODE (x) == LABEL_REF || ! SYMBOL_REF_FLAG (x))
937 	fprintf (file, "@GOT");
938       else
939 	fprintf (file, "@GOTOFF");
940 
941       break;
942 
943     case CODE_LABEL:
944       ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
945       assemble_name (asm_out_file, buf);
946       break;
947 
948     case CONST_INT:
949       fprintf (file, "%d", INTVAL (x));
950       break;
951 
952     case CONST:
953       /* This used to output parentheses around the expression,
954 	 but that does not work on the 386 (either ATT or BSD assembler).  */
955       output_pic_addr_const (file, XEXP (x, 0), code);
956       break;
957 
958     case CONST_DOUBLE:
959       if (GET_MODE (x) == VOIDmode)
960 	{
961 	  /* We can use %d if the number is <32 bits and positive.  */
962 	  if (CONST_DOUBLE_HIGH (x) || CONST_DOUBLE_LOW (x) < 0)
963 	    fprintf (file, "0x%x%08x",
964 		     CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
965 	  else
966 	    fprintf (file, "%d", CONST_DOUBLE_LOW (x));
967 	}
968       else
969 	/* We can't handle floating point constants;
970 	   PRINT_OPERAND must handle them.  */
971 	output_operand_lossage ("floating constant misused");
972       break;
973 
974     case PLUS:
975       /* Some assemblers need integer constants to appear last (eg masm).  */
976       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
977 	{
978 	  output_pic_addr_const (file, XEXP (x, 1), code);
979 	  if (INTVAL (XEXP (x, 0)) >= 0)
980 	    fprintf (file, "+");
981 	  output_pic_addr_const (file, XEXP (x, 0), code);
982 	}
983       else
984 	{
985 	  output_pic_addr_const (file, XEXP (x, 0), code);
986 	  if (INTVAL (XEXP (x, 1)) >= 0)
987 	    fprintf (file, "+");
988 	  output_pic_addr_const (file, XEXP (x, 1), code);
989 	}
990       break;
991 
992     case MINUS:
993       output_pic_addr_const (file, XEXP (x, 0), code);
994       fprintf (file, "-");
995       output_pic_addr_const (file, XEXP (x, 1), code);
996       break;
997 
998     default:
999       output_operand_lossage ("invalid expression as operand");
1000     }
1001 }
1002 
1003 /* Meaning of CODE:
1004    f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
1005    D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
1006    R -- print the prefix for register names.
1007    z -- print the opcode suffix for the size of the current operand.
1008    * -- print a star (in certain assembler syntax)
1009    w -- print the operand as if it's a "word" (HImode) even if it isn't.
1010    c -- don't print special prefixes before constant operands.
1011 */
1012 
1013 void
print_operand(file,x,code)1014 print_operand (file, x, code)
1015      FILE *file;
1016      rtx x;
1017      int code;
1018 {
1019   if (code)
1020     {
1021       switch (code)
1022 	{
1023 	case '*':
1024 	  if (USE_STAR)
1025 	    putc ('*', file);
1026 	  return;
1027 
1028 	case 'L':
1029 	  PUT_OP_SIZE (code, 'l', file);
1030 	  return;
1031 
1032 	case 'W':
1033 	  PUT_OP_SIZE (code, 'w', file);
1034 	  return;
1035 
1036 	case 'B':
1037 	  PUT_OP_SIZE (code, 'b', file);
1038 	  return;
1039 
1040 	case 'Q':
1041 	  PUT_OP_SIZE (code, 'l', file);
1042 	  return;
1043 
1044 	case 'S':
1045 	  PUT_OP_SIZE (code, 's', file);
1046 	  return;
1047 
1048 	case 'z':
1049 	  /* 387 opcodes don't get size suffixes if the operands are
1050 	     registers. */
1051 
1052 	  if (STACK_REG_P (x))
1053 	    return;
1054 
1055 	  /* this is the size of op from size of operand */
1056 	  switch (GET_MODE_SIZE (GET_MODE (x)))
1057 	    {
1058 	    case 1:
1059 	      PUT_OP_SIZE ('B', 'b', file);
1060 	      return;
1061 
1062 	    case 2:
1063 	      PUT_OP_SIZE ('W', 'w', file);
1064 	      return;
1065 
1066 	    case 4:
1067 	      if (GET_MODE (x) == SFmode)
1068 		{
1069 		  PUT_OP_SIZE ('S', 's', file);
1070 		  return;
1071 		}
1072 	      else
1073 		PUT_OP_SIZE ('L', 'l', file);
1074 	      return;
1075 
1076 	    case 8:
1077 	      if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
1078 		{
1079 #ifdef GAS_MNEMONICS
1080 		  PUT_OP_SIZE ('Q', 'q', file);
1081 		  return;
1082 #else
1083 		  PUT_OP_SIZE ('Q', 'l', file);	/* Fall through */
1084 #endif
1085 		}
1086 
1087 	      PUT_OP_SIZE ('Q', 'l', file);
1088 	      return;
1089 	    }
1090 
1091 	case 'b':
1092 	case 'w':
1093 	case 'k':
1094 	case 'h':
1095 	case 'y':
1096 	case 'P':
1097 	  break;
1098 
1099 	default:
1100 	  {
1101 	    char str[50];
1102 
1103 	    sprintf (str, "invalid operand code `%c'", code);
1104 	    output_operand_lossage (str);
1105 	  }
1106 	}
1107     }
1108   if (GET_CODE (x) == REG)
1109     {
1110       PRINT_REG (x, code, file);
1111     }
1112   else if (GET_CODE (x) == MEM)
1113     {
1114       PRINT_PTR (x, file);
1115       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
1116 	{
1117 	  if (flag_pic)
1118 	    output_pic_addr_const (file, XEXP (x, 0), code);
1119 	  else
1120 	    output_addr_const (file, XEXP (x, 0));
1121 	}
1122       else
1123 	output_address (XEXP (x, 0));
1124     }
1125   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == SFmode)
1126     {
1127       union { double d; int i[2]; } u;
1128       union { float f; int i; } u1;
1129       u.i[0] = CONST_DOUBLE_LOW (x);
1130       u.i[1] = CONST_DOUBLE_HIGH (x);
1131       u1.f = u.d;
1132       PRINT_IMMED_PREFIX (file);
1133       fprintf (file, "0x%x", u1.i);
1134     }
1135   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) == DFmode)
1136     {
1137       union { double d; int i[2]; } u;
1138       u.i[0] = CONST_DOUBLE_LOW (x);
1139       u.i[1] = CONST_DOUBLE_HIGH (x);
1140       fprintf (file, "%.22e", u.d);
1141     }
1142   else
1143     {
1144       if (code != 'P')
1145 	{
1146 	  if (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE)
1147 	    PRINT_IMMED_PREFIX (file);
1148 	  else if (GET_CODE (x) == CONST || GET_CODE (x) == SYMBOL_REF
1149 		   || GET_CODE (x) == LABEL_REF)
1150 	    PRINT_OFFSET_PREFIX (file);
1151 	}
1152       if (flag_pic)
1153 	output_pic_addr_const (file, x, code);
1154       else
1155 	output_addr_const (file, x);
1156     }
1157 }
1158 
1159 /* Print a memory operand whose address is ADDR.  */
1160 
1161 void
print_operand_address(file,addr)1162 print_operand_address (file, addr)
1163      FILE *file;
1164      register rtx addr;
1165 {
1166   register rtx reg1, reg2, breg, ireg;
1167   rtx offset;
1168 
1169   switch (GET_CODE (addr))
1170     {
1171     case REG:
1172       ADDR_BEG (file);
1173       fprintf (file, "%se", RP);
1174       fputs (hi_reg_name[REGNO (addr)], file);
1175       ADDR_END (file);
1176       break;
1177 
1178     case PLUS:
1179       reg1 = 0;
1180       reg2 = 0;
1181       ireg = 0;
1182       breg = 0;
1183       offset = 0;
1184       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))
1185 	{
1186 	  offset = XEXP (addr, 0);
1187 	  addr = XEXP (addr, 1);
1188 	}
1189       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))
1190 	{
1191 	  offset = XEXP (addr, 1);
1192 	  addr = XEXP (addr, 0);
1193 	}
1194       if (GET_CODE (addr) != PLUS) ;
1195       else if (GET_CODE (XEXP (addr, 0)) == MULT)
1196 	{
1197 	  reg1 = XEXP (addr, 0);
1198 	  addr = XEXP (addr, 1);
1199 	}
1200       else if (GET_CODE (XEXP (addr, 1)) == MULT)
1201 	{
1202 	  reg1 = XEXP (addr, 1);
1203 	  addr = XEXP (addr, 0);
1204 	}
1205       else if (GET_CODE (XEXP (addr, 0)) == REG)
1206 	{
1207 	  reg1 = XEXP (addr, 0);
1208 	  addr = XEXP (addr, 1);
1209 	}
1210       else if (GET_CODE (XEXP (addr, 1)) == REG)
1211 	{
1212 	  reg1 = XEXP (addr, 1);
1213 	  addr = XEXP (addr, 0);
1214 	}
1215       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT)
1216 	{
1217 	  if (reg1 == 0) reg1 = addr;
1218 	  else reg2 = addr;
1219 	  addr = 0;
1220 	}
1221       if (offset != 0)
1222 	{
1223 	  if (addr != 0) abort ();
1224 	  addr = offset;
1225 	}
1226       if ((reg1 && GET_CODE (reg1) == MULT)
1227 	  || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))
1228 	{
1229 	  breg = reg2;
1230 	  ireg = reg1;
1231 	}
1232       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))
1233 	{
1234 	  breg = reg1;
1235 	  ireg = reg2;
1236 	}
1237 
1238       if (ireg != 0 || breg != 0)
1239 	{
1240 	  int scale = 1;
1241 
1242 	  if (addr != 0)
1243 	    {
1244 	      if (GET_CODE (addr) == LABEL_REF)
1245 		output_asm_label (addr);
1246 	      else
1247 		{
1248 		  if (flag_pic)
1249 		    output_pic_addr_const (file, addr, 0);
1250 		  else
1251 		    output_addr_const (file, addr);
1252 		}
1253 	    }
1254 
1255   	  if (ireg != 0 && GET_CODE (ireg) == MULT)
1256 	    {
1257 	      scale = INTVAL (XEXP (ireg, 1));
1258 	      ireg = XEXP (ireg, 0);
1259 	    }
1260 
1261 	  /* The stack pointer can only appear as a base register,
1262 	     never an index register, so exchange the regs if it is wrong. */
1263 
1264 	  if (scale == 1 && ireg && REGNO (ireg) == STACK_POINTER_REGNUM)
1265 	    {
1266 	      rtx tmp;
1267 
1268 	      tmp = breg;
1269 	      breg = ireg;
1270 	      ireg = tmp;
1271 	    }
1272 
1273 	  /* output breg+ireg*scale */
1274 	  PRINT_B_I_S (breg, ireg, scale, file);
1275 	  break;
1276 	}
1277 
1278     case MULT:
1279       {
1280 	int scale;
1281 	if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
1282 	  {
1283 	    scale = INTVAL (XEXP (addr, 0));
1284 	    ireg = XEXP (addr, 1);
1285 	  }
1286 	else
1287 	  {
1288 	    scale = INTVAL (XEXP (addr, 1));
1289 	    ireg = XEXP (addr, 0);
1290 	  }
1291 	output_addr_const (file, const0_rtx);
1292 	PRINT_B_I_S ((rtx) 0, ireg, scale, file);
1293       }
1294       break;
1295 
1296     default:
1297       if (GET_CODE (addr) == CONST_INT
1298 	  && INTVAL (addr) < 0x8000
1299 	  && INTVAL (addr) >= -0x8000)
1300 	fprintf (file, "%d", INTVAL (addr));
1301       else
1302 	{
1303 	  if (flag_pic)
1304 	    output_pic_addr_const (file, addr, 0);
1305 	  else
1306 	    output_addr_const (file, addr);
1307 	}
1308     }
1309 }
1310 
1311 /* Set the cc_status for the results of an insn whose pattern is EXP.
1312    On the 80386, we assume that only test and compare insns, as well
1313    as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, LSHIFT,
1314    ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
1315    Also, we assume that jumps, moves and sCOND don't affect the condition
1316    codes.  All else clobbers the condition codes, by assumption.
1317 
1318    We assume that ALL integer add, minus, etc. instructions effect the
1319    condition codes.  This MUST be consistent with i386.md.
1320 
1321    We don't record any float test or compare - the redundant test &
1322    compare check in final.c does not handle stack-like regs correctly. */
1323 
1324 void
notice_update_cc(exp)1325 notice_update_cc (exp)
1326      rtx exp;
1327 {
1328   if (GET_CODE (exp) == SET)
1329     {
1330       /* Jumps do not alter the cc's.  */
1331       if (SET_DEST (exp) == pc_rtx)
1332 	return;
1333       /* Moving register or memory into a register:
1334 	 it doesn't alter the cc's, but it might invalidate
1335 	 the RTX's which we remember the cc's came from.
1336 	 (Note that moving a constant 0 or 1 MAY set the cc's).  */
1337       if (REG_P (SET_DEST (exp))
1338 	  && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM
1339 	      || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
1340 	{
1341 	  if (cc_status.value1
1342 	      && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1343 	    cc_status.value1 = 0;
1344 	  if (cc_status.value2
1345 	      && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1346 	    cc_status.value2 = 0;
1347 	  return;
1348 	}
1349       /* Moving register into memory doesn't alter the cc's.
1350 	 It may invalidate the RTX's which we remember the cc's came from.  */
1351       if (GET_CODE (SET_DEST (exp)) == MEM
1352 	  && (REG_P (SET_SRC (exp))
1353 	      || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<'))
1354 	{
1355 	  if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1356 	    cc_status.value1 = 0;
1357 	  if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1358 	    cc_status.value2 = 0;
1359 	  return;
1360 	}
1361       /* Function calls clobber the cc's.  */
1362       else if (GET_CODE (SET_SRC (exp)) == CALL)
1363 	{
1364 	  CC_STATUS_INIT;
1365 	  return;
1366 	}
1367       /* Tests and compares set the cc's in predictable ways.  */
1368       else if (SET_DEST (exp) == cc0_rtx)
1369 	{
1370 	  CC_STATUS_INIT;
1371 	  cc_status.value1 = SET_SRC (exp);
1372 	  return;
1373 	}
1374       /* Certain instructions effect the condition codes. */
1375       else if (GET_MODE (SET_SRC (exp)) == SImode
1376 	       || GET_MODE (SET_SRC (exp)) == HImode
1377 	       || GET_MODE (SET_SRC (exp)) == QImode)
1378 	switch (GET_CODE (SET_SRC (exp)))
1379 	  {
1380 	  case ASHIFTRT: case LSHIFTRT:
1381 	  case ASHIFT: case LSHIFT:
1382 	    /* Shifts on the 386 don't set the condition codes if the
1383 	       shift count is zero. */
1384 	    if (GET_CODE (XEXP (SET_SRC (exp), 1)) != CONST_INT)
1385 	      {
1386 		CC_STATUS_INIT;
1387 		break;
1388 	      }
1389 	    /* We assume that the CONST_INT is non-zero (this rtx would
1390 	       have been deleted if it were zero. */
1391 
1392 	  case PLUS: case MINUS: case NEG:
1393 	  case AND: case IOR: case XOR:
1394 	    cc_status.flags = CC_NO_OVERFLOW;
1395 	    cc_status.value1 = SET_SRC (exp);
1396 	    cc_status.value2 = SET_DEST (exp);
1397 	    break;
1398 
1399 	  default:
1400 	    CC_STATUS_INIT;
1401 	  }
1402       else
1403 	{
1404 	  CC_STATUS_INIT;
1405 	}
1406     }
1407   else if (GET_CODE (exp) == PARALLEL
1408 	   && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1409     {
1410       if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1411 	return;
1412       if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1413 	{
1414 	  CC_STATUS_INIT;
1415 	  if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0))))
1416 	    cc_status.flags |= CC_IN_80387;
1417 	  else
1418 	    cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1419 	  return;
1420 	}
1421       CC_STATUS_INIT;
1422     }
1423   else
1424     {
1425       CC_STATUS_INIT;
1426     }
1427 }
1428 
1429 /* Split one or more DImode RTL references into pairs of SImode
1430    references.  The RTL can be REG, offsettable MEM, integer constant, or
1431    CONST_DOUBLE.  "operands" is a pointer to an array of DImode RTL to
1432    split and "num" is its length.  lo_half and hi_half are output arrays
1433    that parallel "operands". */
1434 
1435 void
split_di(operands,num,lo_half,hi_half)1436 split_di (operands, num, lo_half, hi_half)
1437      rtx operands[];
1438      int num;
1439      rtx lo_half[], hi_half[];
1440 {
1441   while (num--)
1442     {
1443       if (GET_CODE (operands[num]) == REG)
1444 	{
1445 	  lo_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]));
1446 	  hi_half[num] = gen_rtx (REG, SImode, REGNO (operands[num]) + 1);
1447 	}
1448       else if (CONSTANT_P (operands[num]))
1449 	{
1450 	  split_double (operands[num], &lo_half[num], &hi_half[num]);
1451 	}
1452       else if (offsettable_memref_p (operands[num]))
1453 	{
1454 	  lo_half[num] = operands[num];
1455 	  hi_half[num] = adj_offsettable_operand (operands[num], 4);
1456 	}
1457       else
1458 	abort();
1459     }
1460 }
1461 
1462 /* Return 1 if this is a valid binary operation on a 387.
1463    OP is the expression matched, and MODE is its mode. */
1464 
1465 int
binary_387_op(op,mode)1466 binary_387_op (op, mode)
1467     register rtx op;
1468     enum machine_mode mode;
1469 {
1470   if (mode != VOIDmode && mode != GET_MODE (op))
1471     return 0;
1472 
1473   switch (GET_CODE (op))
1474     {
1475     case PLUS:
1476     case MINUS:
1477     case MULT:
1478     case DIV:
1479       return GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT;
1480 
1481     default:
1482       return 0;
1483     }
1484 }
1485 
1486 /* Return 1 if this is a valid conversion operation on a 387.
1487    OP is the expression matched, and MODE is its mode. */
1488 
1489 int
convert_387_op(op,mode)1490 convert_387_op (op, mode)
1491     register rtx op;
1492     enum machine_mode mode;
1493 {
1494   if (mode != VOIDmode && mode != GET_MODE (op))
1495     return 0;
1496 
1497   switch (GET_CODE (op))
1498     {
1499     case FLOAT:
1500       return GET_MODE (XEXP (op, 0)) == SImode;
1501 
1502     case FLOAT_EXTEND:
1503       return mode == DFmode && GET_MODE (XEXP (op, 0)) == SFmode;
1504 
1505     default:
1506       return 0;
1507     }
1508 }
1509 
1510 /* Return 1 if this is a valid shift or rotate operation on a 386.
1511    OP is the expression matched, and MODE is its mode. */
1512 
1513 int
shift_op(op,mode)1514 shift_op (op, mode)
1515     register rtx op;
1516     enum machine_mode mode;
1517 {
1518   rtx operand = XEXP (op, 0);
1519 
1520   if (mode != VOIDmode && mode != GET_MODE (op))
1521     return 0;
1522 
1523   if (GET_MODE (operand) != GET_MODE (op)
1524       || GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
1525     return 0;
1526 
1527   return (GET_CODE (op) == ASHIFT
1528 	  || GET_CODE (op) == ASHIFTRT
1529 	  || GET_CODE (op) == LSHIFTRT
1530 	  || GET_CODE (op) == ROTATE
1531 	  || GET_CODE (op) == ROTATERT);
1532 }
1533 
1534 /* Return 1 if OP is COMPARE rtx with mode VOIDmode.
1535    MODE is not used.  */
1536 
1537 int
VOIDmode_compare_op(op,mode)1538 VOIDmode_compare_op (op, mode)
1539     register rtx op;
1540     enum machine_mode mode;
1541 {
1542   return GET_CODE (op) == COMPARE && GET_MODE (op) == VOIDmode;
1543 }
1544 
1545 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
1546    MINUS, MULT or DIV.  OPERANDS are the insn operands, where operands[3]
1547    is the expression of the binary operation.  The output may either be
1548    emitted here, or returned to the caller, like all output_* functions.
1549 
1550    There is no guarantee that the operands are the same mode, as they
1551    might be within FLOAT or FLOAT_EXTEND expressions. */
1552 
1553 char *
output_387_binary_op(insn,operands)1554 output_387_binary_op (insn, operands)
1555      rtx insn;
1556      rtx *operands;
1557 {
1558   rtx temp;
1559   char *base_op;
1560   static char buf[100];
1561 
1562   switch (GET_CODE (operands[3]))
1563     {
1564     case PLUS:
1565       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1566 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1567 	base_op = "fiadd";
1568       else
1569 	base_op = "fadd";
1570       break;
1571 
1572     case MINUS:
1573       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1574 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1575 	base_op = "fisub";
1576       else
1577 	base_op = "fsub";
1578       break;
1579 
1580     case MULT:
1581       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1582 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1583 	base_op = "fimul";
1584       else
1585 	base_op = "fmul";
1586       break;
1587 
1588     case DIV:
1589       if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT
1590 	  || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT)
1591 	base_op = "fidiv";
1592       else
1593 	base_op = "fdiv";
1594       break;
1595 
1596     default:
1597       abort ();
1598     }
1599 
1600   strcpy (buf, base_op);
1601 
1602   switch (GET_CODE (operands[3]))
1603     {
1604     case MULT:
1605     case PLUS:
1606       if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
1607 	{
1608 	  temp = operands[2];
1609 	  operands[2] = operands[1];
1610 	  operands[1] = temp;
1611 	}
1612 
1613       if (GET_CODE (operands[2]) == MEM)
1614 	return strcat (buf, AS1 (%z2,%2));
1615 
1616       if (NON_STACK_REG_P (operands[1]))
1617 	{
1618 	  output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
1619 	  RET;
1620 	}
1621       else if (NON_STACK_REG_P (operands[2]))
1622 	{
1623 	  output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
1624 	  RET;
1625 	}
1626 
1627       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
1628 	return strcat (buf, AS2 (p,%2,%0));
1629 
1630       if (STACK_TOP_P (operands[0]))
1631 	return strcat (buf, AS2 (,%y2,%0));
1632       else
1633 	return strcat (buf, AS2 (,%2,%0));
1634 
1635     case MINUS:
1636     case DIV:
1637       if (GET_CODE (operands[1]) == MEM)
1638 	return strcat (buf, AS1 (r%z1,%1));
1639 
1640       if (GET_CODE (operands[2]) == MEM)
1641 	return strcat (buf, AS1 (%z2,%2));
1642 
1643       if (NON_STACK_REG_P (operands[1]))
1644 	{
1645 	  output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1)));
1646 	  RET;
1647 	}
1648       else if (NON_STACK_REG_P (operands[2]))
1649 	{
1650 	  output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1)));
1651 	  RET;
1652 	}
1653 
1654       if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
1655 	abort ();
1656 
1657       if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
1658 	return strcat (buf, AS2 (rp,%2,%0));
1659 
1660       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
1661 	return strcat (buf, AS2 (p,%1,%0));
1662 
1663       if (STACK_TOP_P (operands[0]))
1664 	{
1665 	  if (STACK_TOP_P (operands[1]))
1666 	    return strcat (buf, AS2 (,%y2,%0));
1667 	  else
1668 	    return strcat (buf, AS2 (r,%y1,%0));
1669 	}
1670       else if (STACK_TOP_P (operands[1]))
1671 	return strcat (buf, AS2 (,%1,%0));
1672       else
1673 	return strcat (buf, AS2 (r,%2,%0));
1674 
1675     default:
1676       abort ();
1677     }
1678 }
1679 
1680 /* Output code for INSN to convert a float to a signed int.  OPERANDS
1681    are the insn operands.  The output may be SFmode or DFmode and the
1682    input operand may be SImode or DImode.  As a special case, make sure
1683    that the 387 stack top dies if the output mode is DImode, because the
1684    hardware requires this.  */
1685 
1686 char *
output_fix_trunc(insn,operands)1687 output_fix_trunc (insn, operands)
1688      rtx insn;
1689      rtx *operands;
1690 {
1691   int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1692   rtx xops[2];
1693 
1694   if (! STACK_TOP_P (operands[1]) ||
1695       (GET_MODE (operands[0]) == DImode && ! stack_top_dies))
1696     abort ();
1697 
1698   xops[0] = GEN_INT (12);
1699   xops[1] = operands[4];
1700 
1701   output_asm_insn (AS1 (fnstc%W2,%2), operands);
1702   output_asm_insn (AS2 (mov%L2,%2,%4), operands);
1703   output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
1704   output_asm_insn (AS2 (mov%L4,%4,%3), operands);
1705   output_asm_insn (AS1 (fldc%W3,%3), operands);
1706 
1707   if (NON_STACK_REG_P (operands[0]))
1708     output_to_reg (operands[0], stack_top_dies);
1709   else if (GET_CODE (operands[0]) == MEM)
1710     {
1711       if (stack_top_dies)
1712 	output_asm_insn (AS1 (fistp%z0,%0), operands);
1713       else
1714 	output_asm_insn (AS1 (fist%z0,%0), operands);
1715     }
1716   else
1717     abort ();
1718 
1719   return AS1 (fldc%W2,%2);
1720 }
1721 
1722 /* Output code for INSN to compare OPERANDS.  The two operands might
1723    not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
1724    expression.  If the compare is in mode CCFPEQmode, use an opcode that
1725    will not fault if a qNaN is present. */
1726 
1727 char *
output_float_compare(insn,operands)1728 output_float_compare (insn, operands)
1729      rtx insn;
1730      rtx *operands;
1731 {
1732   int stack_top_dies;
1733   rtx body = XVECEXP (PATTERN (insn), 0, 0);
1734   int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
1735 
1736   if (! STACK_TOP_P (operands[0]))
1737     abort ();
1738 
1739   stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
1740 
1741   if (STACK_REG_P (operands[1])
1742       && stack_top_dies
1743       && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
1744       && REGNO (operands[1]) != FIRST_STACK_REG)
1745     {
1746       /* If both the top of the 387 stack dies, and the other operand
1747 	 is also a stack register that dies, then this must be a
1748 	 `fcompp' float compare */
1749 
1750       if (unordered_compare)
1751 	output_asm_insn ("fucompp", operands);
1752       else
1753 	output_asm_insn ("fcompp", operands);
1754     }
1755   else
1756     {
1757       static char buf[100];
1758 
1759       /* Decide if this is the integer or float compare opcode, or the
1760 	 unordered float compare. */
1761 
1762       if (unordered_compare)
1763 	strcpy (buf, "fucom");
1764       else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT)
1765 	strcpy (buf, "fcom");
1766       else
1767 	strcpy (buf, "ficom");
1768 
1769       /* Modify the opcode if the 387 stack is to be popped. */
1770 
1771       if (stack_top_dies)
1772 	strcat (buf, "p");
1773 
1774       if (NON_STACK_REG_P (operands[1]))
1775 	output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1)));
1776       else
1777         output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
1778     }
1779 
1780   /* Now retrieve the condition code. */
1781 
1782   return output_fp_cc0_set (insn);
1783 }
1784 
1785 /* Output opcodes to transfer the results of FP compare or test INSN
1786    from the FPU to the CPU flags.  If TARGET_IEEE_FP, ensure that if the
1787    result of the compare or test is unordered, no comparison operator
1788    succeeds except NE.  Return an output template, if any.  */
1789 
1790 char *
output_fp_cc0_set(insn)1791 output_fp_cc0_set (insn)
1792      rtx insn;
1793 {
1794   rtx xops[3];
1795   rtx unordered_label;
1796   rtx next;
1797   enum rtx_code code;
1798 
1799   xops[0] = gen_rtx (REG, HImode, 0);
1800   output_asm_insn (AS1 (fnsts%W0,%0), xops);
1801 
1802   if (! TARGET_IEEE_FP)
1803     return "sahf";
1804 
1805   next = next_cc0_user (insn);
1806   if (next == NULL_RTX)
1807     abort ();
1808 
1809   if (GET_CODE (next) == JUMP_INSN
1810       && GET_CODE (PATTERN (next)) == SET
1811       && SET_DEST (PATTERN (next)) == pc_rtx
1812       && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE)
1813     {
1814       code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0));
1815     }
1816   else if (GET_CODE (PATTERN (next)) == SET)
1817     {
1818       code = GET_CODE (SET_SRC (PATTERN (next)));
1819     }
1820   else
1821     abort ();
1822 
1823   xops[0] = gen_rtx (REG, QImode, 0);
1824 
1825   switch (code)
1826     {
1827     case GT:
1828       xops[1] = GEN_INT (0x45);
1829       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1830       /* je label */
1831       break;
1832 
1833     case LT:
1834       xops[1] = GEN_INT (0x45);
1835       xops[2] = GEN_INT (0x01);
1836       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1837       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1838       /* je label */
1839       break;
1840 
1841     case GE:
1842       xops[1] = GEN_INT (0x05);
1843       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1844       /* je label */
1845       break;
1846 
1847     case LE:
1848       xops[1] = GEN_INT (0x45);
1849       xops[2] = GEN_INT (0x40);
1850       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1851       output_asm_insn (AS1 (dec%B0,%h0), xops);
1852       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1853       /* jb label */
1854       break;
1855 
1856     case EQ:
1857       xops[1] = GEN_INT (0x45);
1858       xops[2] = GEN_INT (0x40);
1859       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1860       output_asm_insn (AS2 (cmp%B0,%2,%h0), xops);
1861       /* je label */
1862       break;
1863 
1864     case NE:
1865       xops[1] = GEN_INT (0x44);
1866       xops[2] = GEN_INT (0x40);
1867       output_asm_insn (AS2 (and%B0,%1,%h0), xops);
1868       output_asm_insn (AS2 (xor%B0,%2,%h0), xops);
1869       /* jne label */
1870       break;
1871 
1872     case GTU:
1873     case LTU:
1874     case GEU:
1875     case LEU:
1876     default:
1877       abort ();
1878     }
1879   RET;
1880 }
1881 
1882 #define MAX_386_STACK_LOCALS 2
1883 
1884 static rtx i386_stack_locals[(int) MAX_MACHINE_MODE][MAX_386_STACK_LOCALS];
1885 
1886 /* Clear stack slot assignments remembered from previous functions.
1887    This is called from INIT_EXPANDERS once before RTL is emitted for each
1888    function. */
1889 
1890 void
clear_386_stack_locals()1891 clear_386_stack_locals ()
1892 {
1893   enum machine_mode mode;
1894   int n;
1895 
1896   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
1897        mode = (enum machine_mode) ((int) mode + 1))
1898     for (n = 0; n < MAX_386_STACK_LOCALS; n++)
1899       i386_stack_locals[(int) mode][n] = NULL_RTX;
1900 }
1901 
1902 /* Return a MEM corresponding to a stack slot with mode MODE.
1903    Allocate a new slot if necessary.
1904 
1905    The RTL for a function can have several slots available: N is
1906    which slot to use.  */
1907 
1908 rtx
assign_386_stack_local(mode,n)1909 assign_386_stack_local (mode, n)
1910      enum machine_mode mode;
1911      int n;
1912 {
1913   if (n < 0 || n >= MAX_386_STACK_LOCALS)
1914     abort ();
1915 
1916   if (i386_stack_locals[(int) mode][n] == NULL_RTX)
1917     i386_stack_locals[(int) mode][n]
1918       = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
1919 
1920   return i386_stack_locals[(int) mode][n];
1921 }
1922