1 /* Subroutines for insn-output.c for Intel 80386.
2 Copyright (C) 1988, 1992 Free Software Foundation, Inc.
4 This file is part of GNU CC.
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)
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.
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. */
24 #include "hard-reg-set.h"
26 #include "insn-config.h"
27 #include "conditions.h"
28 #include "insn-flags.h"
30 #include "insn-attr.h"
34 #ifdef EXTRA_CONSTRAINT
35 /* If EXTRA_CONSTRAINT is defined, then the 'S'
36 constraint in REG_CLASS_FROM_LETTER will no longer work, and various
37 asm statements that need 'S' for class SIREG will break. */
38 error EXTRA_CONSTRAINT conflicts with S constraint letter
39 /* The previous line used to be #error, but some compilers barf
40 even if the conditional was untrue. */
43 #define AT_BP(mode) (gen_rtx (MEM, (mode), frame_pointer_rtx))
45 extern FILE *asm_out_file
;
46 extern char *strcat ();
48 char *singlemove_string ();
49 char *output_move_const_single ();
50 char *output_fp_cc0_set ();
52 char *hi_reg_name
[] = HI_REGISTER_NAMES
;
53 char *qi_reg_name
[] = QI_REGISTER_NAMES
;
54 char *qi_high_reg_name
[] = QI_HIGH_REGISTER_NAMES
;
56 /* Array of the smallest class containing reg number REGNO, indexed by
57 REGNO. Used by REGNO_REG_CLASS in i386.h. */
59 enum reg_class regclass_map
[FIRST_PSEUDO_REGISTER
] =
62 AREG
, DREG
, CREG
, BREG
,
64 SIREG
, DIREG
, INDEX_REGS
, GENERAL_REGS
,
66 FP_TOP_REG
, FP_SECOND_REG
, FLOAT_REGS
, FLOAT_REGS
,
67 FLOAT_REGS
, FLOAT_REGS
, FLOAT_REGS
, FLOAT_REGS
,
72 /* Test and compare insns in i386.md store the information needed to
73 generate branch and scc insns here. */
75 struct rtx_def
*i386_compare_op0
, *i386_compare_op1
;
76 struct rtx_def
*(*i386_compare_gen
)(), *(*i386_compare_gen_eq
)();
78 /* Output an insn whose source is a 386 integer register. SRC is the
79 rtx for the register, and TEMPLATE is the op-code template. SRC may
80 be either SImode or DImode.
82 The template will be output with operands[0] as SRC, and operands[1]
83 as a pointer to the top of the 386 stack. So a call from floatsidf2
86 output_op_from_reg (operands[1], AS1 (fild%z0,%1));
88 where %z0 corresponds to the caller's operands[1], and is used to
89 emit the proper size suffix.
91 ??? Extend this to handle HImode - a 387 can load and store HImode
95 output_op_from_reg (src
, template)
102 xops
[1] = AT_SP (Pmode
);
103 xops
[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (src
)));
104 xops
[3] = stack_pointer_rtx
;
106 if (GET_MODE_SIZE (GET_MODE (src
)) > UNITS_PER_WORD
)
108 rtx high
= gen_rtx (REG
, SImode
, REGNO (src
) + 1);
109 output_asm_insn (AS1 (push
%L0
,%0), &high
);
111 output_asm_insn (AS1 (push
%L0
,%0), &src
);
113 output_asm_insn (template, xops
);
115 output_asm_insn (AS2 (add
%L3
,%2,%3), xops
);
118 /* Output an insn to pop an value from the 387 top-of-stack to 386
119 register DEST. The 387 register stack is popped if DIES is true. If
120 the mode of DEST is an integer mode, a `fist' integer store is done,
121 otherwise a `fst' float store is done. */
124 output_to_reg (dest
, dies
)
130 xops
[0] = AT_SP (Pmode
);
131 xops
[1] = stack_pointer_rtx
;
132 xops
[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (dest
)));
135 output_asm_insn (AS2 (sub
%L1
,%2,%1), xops
);
137 if (GET_MODE_CLASS (GET_MODE (dest
)) == MODE_INT
)
140 output_asm_insn (AS1 (fistp
%z3
,%y0
), xops
);
142 output_asm_insn (AS1 (fist
%z3
,%y0
), xops
);
144 else if (GET_MODE_CLASS (GET_MODE (dest
)) == MODE_FLOAT
)
147 output_asm_insn (AS1 (fstp
%z3
,%y0
), xops
);
149 output_asm_insn (AS1 (fst
%z3
,%y0
), xops
);
154 output_asm_insn (AS1 (pop
%L0
,%0), &dest
);
156 if (GET_MODE_SIZE (GET_MODE (dest
)) > UNITS_PER_WORD
)
158 dest
= gen_rtx (REG
, SImode
, REGNO (dest
) + 1);
159 output_asm_insn (AS1 (pop
%L0
,%0), &dest
);
164 singlemove_string (operands
)
168 if (GET_CODE (operands
[0]) == MEM
169 && GET_CODE (x
= XEXP (operands
[0], 0)) == PRE_DEC
)
171 if (XEXP (x
, 0) != stack_pointer_rtx
)
175 else if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
177 return output_move_const_single (operands
);
179 else if (GET_CODE (operands
[0]) == REG
|| GET_CODE (operands
[1]) == REG
)
180 return AS2 (mov
%L0
,%1,%0);
181 else if (CONSTANT_P (operands
[1]))
182 return AS2 (mov
%L0
,%1,%0);
185 output_asm_insn ("push%L1 %1", operands
);
190 /* Return a REG that occurs in ADDR with coefficient 1.
191 ADDR can be effectively incremented by incrementing REG. */
197 while (GET_CODE (addr
) == PLUS
)
199 if (GET_CODE (XEXP (addr
, 0)) == REG
)
200 addr
= XEXP (addr
, 0);
201 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
202 addr
= XEXP (addr
, 1);
203 else if (CONSTANT_P (XEXP (addr
, 0)))
204 addr
= XEXP (addr
, 1);
205 else if (CONSTANT_P (XEXP (addr
, 1)))
206 addr
= XEXP (addr
, 0);
210 if (GET_CODE (addr
) == REG
)
215 /* Output an insn to add the constant N to the register X. */
226 xops
[0] = GEN_INT (-n
);
227 output_asm_insn (AS2 (sub
%L0
,%0,%1), xops
);
231 xops
[0] = GEN_INT (n
);
232 output_asm_insn (AS2 (add
%L0
,%0,%1), xops
);
236 /* Output assembler code to perform a doubleword move insn
237 with operands OPERANDS. */
240 output_move_double (operands
)
243 enum {REGOP
, OFFSOP
, MEMOP
, PUSHOP
, POPOP
, CNSTOP
, RNDOP
} optype0
, optype1
;
245 rtx addreg0
= 0, addreg1
= 0;
246 int dest_overlapped_low
= 0;
248 /* First classify both operands. */
250 if (REG_P (operands
[0]))
252 else if (offsettable_memref_p (operands
[0]))
254 else if (GET_CODE (XEXP (operands
[0], 0)) == POST_INC
)
256 else if (GET_CODE (XEXP (operands
[0], 0)) == PRE_DEC
)
258 else if (GET_CODE (operands
[0]) == MEM
)
263 if (REG_P (operands
[1]))
265 else if (CONSTANT_P (operands
[1]))
267 else if (offsettable_memref_p (operands
[1]))
269 else if (GET_CODE (XEXP (operands
[1], 0)) == POST_INC
)
271 else if (GET_CODE (XEXP (operands
[1], 0)) == PRE_DEC
)
273 else if (GET_CODE (operands
[1]) == MEM
)
278 /* Check for the cases that the operand constraints are not
279 supposed to allow to happen. Abort if we get one,
280 because generating code for these cases is painful. */
282 if (optype0
== RNDOP
|| optype1
== RNDOP
)
285 /* If one operand is decrementing and one is incrementing
286 decrement the former register explicitly
287 and change that operand into ordinary indexing. */
289 if (optype0
== PUSHOP
&& optype1
== POPOP
)
291 operands
[0] = XEXP (XEXP (operands
[0], 0), 0);
292 asm_add (-8, operands
[0]);
293 operands
[0] = gen_rtx (MEM
, DImode
, operands
[0]);
296 if (optype0
== POPOP
&& optype1
== PUSHOP
)
298 operands
[1] = XEXP (XEXP (operands
[1], 0), 0);
299 asm_add (-8, operands
[1]);
300 operands
[1] = gen_rtx (MEM
, DImode
, operands
[1]);
304 /* If an operand is an unoffsettable memory ref, find a register
305 we can increment temporarily to make it refer to the second word. */
307 if (optype0
== MEMOP
)
308 addreg0
= find_addr_reg (XEXP (operands
[0], 0));
310 if (optype1
== MEMOP
)
311 addreg1
= find_addr_reg (XEXP (operands
[1], 0));
313 /* Ok, we can do one word at a time.
314 Normally we do the low-numbered word first,
315 but if either operand is autodecrementing then we
316 do the high-numbered word first.
318 In either case, set up in LATEHALF the operands to use
319 for the high-numbered word and in some cases alter the
320 operands in OPERANDS to be suitable for the low-numbered word. */
322 if (optype0
== REGOP
)
323 latehalf
[0] = gen_rtx (REG
, SImode
, REGNO (operands
[0]) + 1);
324 else if (optype0
== OFFSOP
)
325 latehalf
[0] = adj_offsettable_operand (operands
[0], 4);
327 latehalf
[0] = operands
[0];
329 if (optype1
== REGOP
)
330 latehalf
[1] = gen_rtx (REG
, SImode
, REGNO (operands
[1]) + 1);
331 else if (optype1
== OFFSOP
)
332 latehalf
[1] = adj_offsettable_operand (operands
[1], 4);
333 else if (optype1
== CNSTOP
)
335 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
336 split_double (operands
[1], &operands
[1], &latehalf
[1]);
337 else if (CONSTANT_P (operands
[1]))
339 if (GET_CODE (operands
[1]) == CONST_INT
&& INTVAL (operands
[1]) < 0)
340 latehalf
[1] = constm1_rtx
;
342 latehalf
[1] = const0_rtx
;
346 latehalf
[1] = operands
[1];
348 /* If insn is effectively movd N (sp),-(sp) then we will do the
349 high word first. We should use the adjusted operand 1 (which is N+4 (sp))
350 for the low word as well, to compensate for the first decrement of sp. */
351 if (optype0
== PUSHOP
352 && REGNO (XEXP (XEXP (operands
[0], 0), 0)) == STACK_POINTER_REGNUM
353 && reg_overlap_mentioned_p (stack_pointer_rtx
, operands
[1]))
354 operands
[1] = latehalf
[1];
356 /* For (set (reg:DI N) (mem:DI ... (reg:SI N) ...)),
357 if the upper part of reg N does not appear in the MEM, arrange to
358 emit the move late-half first. Otherwise, compute the MEM address
359 into the upper part of N and use that as a pointer to the memory
362 && (optype1
== OFFSOP
|| optype1
== MEMOP
))
364 if (reg_mentioned_p (operands
[0], XEXP (operands
[1], 0))
365 && reg_mentioned_p (latehalf
[0], XEXP (operands
[1], 0)))
367 /* If both halves of dest are used in the src memory address,
368 compute the address into latehalf of dest. */
370 xops
[0] = latehalf
[0];
371 xops
[1] = XEXP (operands
[1], 0);
372 output_asm_insn (AS2 (lea
%L0
,%a1
,%0), xops
);
373 operands
[1] = gen_rtx (MEM
, DImode
, latehalf
[0]);
374 latehalf
[1] = adj_offsettable_operand (operands
[1], 4);
376 else if (reg_mentioned_p (operands
[0], XEXP (operands
[1], 0)))
377 /* If the low half of dest is mentioned in the source memory
378 address, the arrange to emit the move late half first. */
379 dest_overlapped_low
= 1;
382 /* If one or both operands autodecrementing,
383 do the two words, high-numbered first. */
385 /* Likewise, the first move would clobber the source of the second one,
386 do them in the other order. This happens only for registers;
387 such overlap can't happen in memory unless the user explicitly
388 sets it up, and that is an undefined circumstance. */
390 if (optype0
== PUSHOP
|| optype1
== PUSHOP
391 || (optype0
== REGOP
&& optype1
== REGOP
392 && REGNO (operands
[0]) == REGNO (latehalf
[1]))
393 || dest_overlapped_low
)
395 /* Make any unoffsettable addresses point at high-numbered word. */
397 asm_add (4, addreg0
);
399 asm_add (4, addreg1
);
402 output_asm_insn (singlemove_string (latehalf
), latehalf
);
404 /* Undo the adds we just did. */
406 asm_add (-4, addreg0
);
408 asm_add (-4, addreg1
);
410 /* Do low-numbered word. */
411 return singlemove_string (operands
);
414 /* Normal case: do the two words, low-numbered first. */
416 output_asm_insn (singlemove_string (operands
), operands
);
418 /* Make any unoffsettable addresses point at high-numbered word. */
420 asm_add (4, addreg0
);
422 asm_add (4, addreg1
);
425 output_asm_insn (singlemove_string (latehalf
), latehalf
);
427 /* Undo the adds we just did. */
429 asm_add (-4, addreg0
);
431 asm_add (-4, addreg1
);
437 standard_80387_constant_p (x
)
440 union real_extract u
;
443 bcopy (&CONST_DOUBLE_LOW (x
), &u
, sizeof u
);
452 /* Note that on the 80387, other constants, such as pi,
453 are much slower to load as standard constants
454 than to load from doubles in memory! */
460 output_move_const_single (operands
)
463 if (FP_REG_P (operands
[0]))
465 int conval
= standard_80387_constant_p (operands
[1]);
473 if (GET_CODE (operands
[1]) == CONST_DOUBLE
)
475 union { int i
[2]; double d
;} u1
;
476 union { int i
; float f
;} u2
;
477 u1
.i
[0] = CONST_DOUBLE_LOW (operands
[1]);
478 u1
.i
[1] = CONST_DOUBLE_HIGH (operands
[1]);
480 operands
[1] = GEN_INT (u2
.i
);
482 return singlemove_string (operands
);
485 /* Returns 1 if OP is either a symbol reference or a sum of a symbol
486 reference and a constant. */
489 symbolic_operand (op
, mode
)
491 enum machine_mode mode
;
493 switch (GET_CODE (op
))
500 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
501 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
502 && GET_CODE (XEXP (op
, 1)) == CONST_INT
);
508 /* Returns 1 if OP contains a symbol reference */
511 symbolic_reference_mentioned_p (op
)
517 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
520 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
521 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
527 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
528 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
531 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
538 /* Return a legitimate reference for ORIG (an address) using the
539 register REG. If REG is 0, a new pseudo is generated.
541 There are three types of references that must be handled:
543 1. Global data references must load the address from the GOT, via
544 the PIC reg. An insn is emitted to do this load, and the reg is
547 2. Static data references must compute the address as an offset
548 from the GOT, whose base is in the PIC reg. An insn is emitted to
549 compute the address into a reg, and the reg is returned. Static
550 data objects have SYMBOL_REF_FLAG set to differentiate them from
553 3. Constant pool addresses must be handled special. They are
554 considered legitimate addresses, but only if not used with regs.
555 When printed, the output routines know to print the reference with the
556 PIC reg, even though the PIC reg doesn't appear in the RTL.
558 GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC
559 reg also appears in the address (except for constant pool references,
562 "switch" statements also require special handling when generating
563 PIC code. See comments by the `casesi' insn in i386.md for details. */
566 legitimize_pic_address (orig
, reg
)
573 if (GET_CODE (addr
) == SYMBOL_REF
|| GET_CODE (addr
) == LABEL_REF
)
575 if (GET_CODE (addr
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (addr
))
580 reg
= gen_reg_rtx (Pmode
);
582 if (GET_CODE (addr
) == SYMBOL_REF
&& SYMBOL_REF_FLAG (addr
))
583 new = gen_rtx (PLUS
, Pmode
, pic_offset_table_rtx
, orig
);
585 new = gen_rtx (MEM
, Pmode
,
586 gen_rtx (PLUS
, Pmode
,
587 pic_offset_table_rtx
, orig
));
589 emit_move_insn (reg
, new);
591 current_function_uses_pic_offset_table
= 1;
594 else if (GET_CODE (addr
) == CONST
|| GET_CODE (addr
) == PLUS
)
598 if (GET_CODE (addr
) == CONST
)
600 addr
= XEXP (addr
, 0);
601 if (GET_CODE (addr
) != PLUS
)
605 if (XEXP (addr
, 0) == pic_offset_table_rtx
)
609 reg
= gen_reg_rtx (Pmode
);
611 base
= legitimize_pic_address (XEXP (addr
, 0), reg
);
612 addr
= legitimize_pic_address (XEXP (addr
, 1),
613 base
== reg
? NULL_RTX
: reg
);
615 if (GET_CODE (addr
) == CONST_INT
)
616 return plus_constant (base
, INTVAL (addr
));
618 if (GET_CODE (addr
) == PLUS
&& CONSTANT_P (XEXP (addr
, 1)))
620 base
= gen_rtx (PLUS
, Pmode
, base
, XEXP (addr
, 0));
621 addr
= XEXP (addr
, 1);
623 return gen_rtx (PLUS
, Pmode
, base
, addr
);
628 /* Emit insns to move operands[1] into operands[0]. */
631 emit_pic_move (operands
, mode
)
633 enum machine_mode mode
;
635 rtx temp
= reload_in_progress
? operands
[0] : gen_reg_rtx (Pmode
);
637 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1]))
638 operands
[1] = (rtx
) force_reg (SImode
, operands
[1]);
640 operands
[1] = legitimize_pic_address (operands
[1], temp
);
643 /* This function generates the assembly code for function entry.
644 FILE is an stdio stream to output the code to.
645 SIZE is an int: how many units of temporary storage to allocate. */
648 function_prologue (file
, size
)
655 int pic_reg_used
= flag_pic
&& (current_function_uses_pic_offset_table
656 || current_function_uses_const_pool
);
658 xops
[0] = stack_pointer_rtx
;
659 xops
[1] = frame_pointer_rtx
;
660 xops
[2] = GEN_INT (size
);
661 if (frame_pointer_needed
)
663 output_asm_insn ("push%L1 %1", xops
);
664 output_asm_insn (AS2 (mov
%L0
,%0,%1), xops
);
668 output_asm_insn (AS2 (sub
%L0
,%2,%0), xops
);
670 /* Note If use enter it is NOT reversed args.
671 This one is not reversed from intel!!
672 I think enter is slower. Also sdb doesn't like it.
673 But if you want it the code is:
675 xops[3] = const0_rtx;
676 output_asm_insn ("enter %2,%3", xops);
679 limit
= (frame_pointer_needed
? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
680 for (regno
= limit
- 1; regno
>= 0; regno
--)
681 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
682 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
684 xops
[0] = gen_rtx (REG
, SImode
, regno
);
685 output_asm_insn ("push%L0 %0", xops
);
690 xops
[0] = pic_offset_table_rtx
;
691 xops
[1] = (rtx
) gen_label_rtx ();
693 output_asm_insn (AS1 (call
,%P1
), xops
);
694 ASM_OUTPUT_INTERNAL_LABEL (file
, "L", CODE_LABEL_NUMBER (xops
[1]));
695 output_asm_insn (AS1 (pop
%L0
,%0), xops
);
696 output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops
);
700 /* Return 1 if it is appropriate to emit `ret' instructions in the
701 body of a function. Do this only if the epilogue is simple, needing a
702 couple of insns. Prior to reloading, we can't tell how many registers
703 must be saved, so return 0 then.
705 If NON_SAVING_SETJMP is defined and true, then it is not possible
706 for the epilogue to be simple, so return 0. This is a special case
707 since NON_SAVING_SETJMP will not cause regs_ever_live to change until
708 final, but jump_optimize may need to know sooner if a `return' is OK. */
711 simple_386_epilogue ()
715 int reglimit
= (frame_pointer_needed
716 ? FRAME_POINTER_REGNUM
: STACK_POINTER_REGNUM
);
717 int pic_reg_used
= flag_pic
&& (current_function_uses_pic_offset_table
718 || current_function_uses_const_pool
);
720 #ifdef NON_SAVING_SETJMP
721 if (NON_SAVING_SETJMP
&& current_function_calls_setjmp
)
725 if (! reload_completed
)
728 for (regno
= reglimit
- 1; regno
>= 0; regno
--)
729 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
730 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
733 return nregs
== 0 || ! frame_pointer_needed
;
736 /* This function generates the assembly code for function exit.
737 FILE is an stdio stream to output the code to.
738 SIZE is an int: how many units of temporary storage to deallocate. */
741 function_epilogue (file
, size
)
746 register int nregs
, limit
;
749 int pic_reg_used
= flag_pic
&& (current_function_uses_pic_offset_table
750 || current_function_uses_const_pool
);
752 /* Compute the number of registers to pop */
754 limit
= (frame_pointer_needed
755 ? FRAME_POINTER_REGNUM
756 : STACK_POINTER_REGNUM
);
760 for (regno
= limit
- 1; regno
>= 0; regno
--)
761 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
762 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
765 /* sp is often unreliable so we must go off the frame pointer,
768 /* In reality, we may not care if sp is unreliable, because we can
769 restore the register relative to the frame pointer. In theory,
770 since each move is the same speed as a pop, and we don't need the
771 leal, this is faster. For now restore multiple registers the old
774 offset
= -size
- (nregs
* UNITS_PER_WORD
);
776 xops
[2] = stack_pointer_rtx
;
778 if (nregs
> 1 || ! frame_pointer_needed
)
780 if (frame_pointer_needed
)
782 xops
[0] = adj_offsettable_operand (AT_BP (Pmode
), offset
);
783 output_asm_insn (AS2 (lea
%L2
,%0,%2), xops
);
786 for (regno
= 0; regno
< limit
; regno
++)
787 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
788 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
790 xops
[0] = gen_rtx (REG
, SImode
, regno
);
791 output_asm_insn ("pop%L0 %0", xops
);
795 for (regno
= 0; regno
< limit
; regno
++)
796 if ((regs_ever_live
[regno
] && ! call_used_regs
[regno
])
797 || (regno
== PIC_OFFSET_TABLE_REGNUM
&& pic_reg_used
))
799 xops
[0] = gen_rtx (REG
, SImode
, regno
);
800 xops
[1] = adj_offsettable_operand (AT_BP (Pmode
), offset
);
801 output_asm_insn (AS2 (mov
%L0
,%1,%0), xops
);
805 if (frame_pointer_needed
)
807 /* On i486, mov & pop is faster than "leave". */
811 xops
[0] = frame_pointer_rtx
;
812 output_asm_insn (AS2 (mov
%L2
,%0,%2), xops
);
813 output_asm_insn ("pop%L0 %0", xops
);
816 output_asm_insn ("leave", xops
);
820 /* If there is no frame pointer, we must still release the frame. */
822 xops
[0] = GEN_INT (size
);
823 output_asm_insn (AS2 (add
%L2
,%0,%2), xops
);
826 if (current_function_pops_args
&& current_function_args_size
)
828 xops
[1] = GEN_INT (current_function_pops_args
);
830 /* i386 can only pop 32K bytes (maybe 64K? Is it signed?). If
831 asked to pop more, pop return address, do explicit add, and jump
832 indirectly to the caller. */
834 if (current_function_pops_args
>= 32768)
836 /* ??? Which register to use here? */
837 xops
[0] = gen_rtx (REG
, SImode
, 2);
838 output_asm_insn ("pop%L0 %0", xops
);
839 output_asm_insn (AS2 (add
%L2
,%1,%2), xops
);
840 output_asm_insn ("jmp %*%0", xops
);
843 output_asm_insn ("ret %1", xops
);
846 output_asm_insn ("ret", xops
);
849 /* Print an integer constant expression in assembler syntax. Addition
850 and subtraction are the only arithmetic that may appear in these
851 expressions. FILE is the stdio stream to write to, X is the rtx, and
852 CODE is the operand print code from the output string. */
855 output_pic_addr_const (file
, x
, code
)
862 switch (GET_CODE (x
))
873 if (GET_CODE (x
) == SYMBOL_REF
)
874 assemble_name (file
, XSTR (x
, 0));
877 ASM_GENERATE_INTERNAL_LABEL (buf
, "L",
878 CODE_LABEL_NUMBER (XEXP (x
, 0)));
879 assemble_name (asm_out_file
, buf
);
882 if (GET_CODE (x
) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (x
))
883 fprintf (file
, "@GOTOFF(%%ebx)");
884 else if (code
== 'P')
885 fprintf (file
, "@PLT");
886 else if (GET_CODE (x
) == LABEL_REF
|| ! SYMBOL_REF_FLAG (x
))
887 fprintf (file
, "@GOT");
889 fprintf (file
, "@GOTOFF");
894 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
895 assemble_name (asm_out_file
, buf
);
899 fprintf (file
, "%d", INTVAL (x
));
903 /* This used to output parentheses around the expression,
904 but that does not work on the 386 (either ATT or BSD assembler). */
905 output_pic_addr_const (file
, XEXP (x
, 0), code
);
909 if (GET_MODE (x
) == VOIDmode
)
911 /* We can use %d if the number is <32 bits and positive. */
912 if (CONST_DOUBLE_HIGH (x
) || CONST_DOUBLE_LOW (x
) < 0)
913 fprintf (file
, "0x%x%08x",
914 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
916 fprintf (file
, "%d", CONST_DOUBLE_LOW (x
));
919 /* We can't handle floating point constants;
920 PRINT_OPERAND must handle them. */
921 output_operand_lossage ("floating constant misused");
925 /* Some assemblers need integer constants to appear last (eg masm). */
926 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
928 output_pic_addr_const (file
, XEXP (x
, 1), code
);
929 if (INTVAL (XEXP (x
, 0)) >= 0)
931 output_pic_addr_const (file
, XEXP (x
, 0), code
);
935 output_pic_addr_const (file
, XEXP (x
, 0), code
);
936 if (INTVAL (XEXP (x
, 1)) >= 0)
938 output_pic_addr_const (file
, XEXP (x
, 1), code
);
943 output_pic_addr_const (file
, XEXP (x
, 0), code
);
945 output_pic_addr_const (file
, XEXP (x
, 1), code
);
949 output_operand_lossage ("invalid expression as operand");
954 f -- float insn (print a CONST_DOUBLE as a float rather than in hex).
955 D,L,W,B,Q,S -- print the opcode suffix for specified size of operand.
956 R -- print the prefix for register names.
957 z -- print the opcode suffix for the size of the current operand.
958 * -- print a star (in certain assembler syntax)
959 w -- print the operand as if it's a "word" (HImode) even if it isn't.
960 c -- don't print special prefixes before constant operands.
964 print_operand (file
, x
, code
)
979 PUT_OP_SIZE (code
, 'l', file
);
983 PUT_OP_SIZE (code
, 'w', file
);
987 PUT_OP_SIZE (code
, 'b', file
);
991 PUT_OP_SIZE (code
, 'l', file
);
995 PUT_OP_SIZE (code
, 's', file
);
999 /* 387 opcodes don't get size suffixes if the operands are
1002 if (STACK_REG_P (x
))
1005 /* this is the size of op from size of operand */
1006 switch (GET_MODE_SIZE (GET_MODE (x
)))
1009 PUT_OP_SIZE ('B', 'b', file
);
1013 PUT_OP_SIZE ('W', 'w', file
);
1017 if (GET_MODE (x
) == SFmode
)
1019 PUT_OP_SIZE ('S', 's', file
);
1023 PUT_OP_SIZE ('L', 'l', file
);
1027 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_INT
)
1029 #ifdef GAS_MNEMONICS
1030 PUT_OP_SIZE ('Q', 'q', file
);
1033 PUT_OP_SIZE ('Q', 'l', file
); /* Fall through */
1037 PUT_OP_SIZE ('Q', 'l', file
);
1053 sprintf (str
, "invalid operand code `%c'", code
);
1054 output_operand_lossage (str
);
1058 if (GET_CODE (x
) == REG
)
1060 PRINT_REG (x
, code
, file
);
1062 else if (GET_CODE (x
) == MEM
)
1064 PRINT_PTR (x
, file
);
1065 if (CONSTANT_ADDRESS_P (XEXP (x
, 0)))
1068 output_pic_addr_const (file
, XEXP (x
, 0), code
);
1070 output_addr_const (file
, XEXP (x
, 0));
1073 output_address (XEXP (x
, 0));
1075 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == SFmode
)
1077 union { double d
; int i
[2]; } u
;
1078 union { float f
; int i
; } u1
;
1079 u
.i
[0] = CONST_DOUBLE_LOW (x
);
1080 u
.i
[1] = CONST_DOUBLE_HIGH (x
);
1082 PRINT_IMMED_PREFIX (file
);
1083 fprintf (file
, "0x%x", u1
.i
);
1085 else if (GET_CODE (x
) == CONST_DOUBLE
&& GET_MODE (x
) == DFmode
)
1087 union { double d
; int i
[2]; } u
;
1088 u
.i
[0] = CONST_DOUBLE_LOW (x
);
1089 u
.i
[1] = CONST_DOUBLE_HIGH (x
);
1090 fprintf (file
, "%.22e", u
.d
);
1096 if (GET_CODE (x
) == CONST_INT
|| GET_CODE (x
) == CONST_DOUBLE
)
1097 PRINT_IMMED_PREFIX (file
);
1098 else if (GET_CODE (x
) == CONST
|| GET_CODE (x
) == SYMBOL_REF
1099 || GET_CODE (x
) == LABEL_REF
)
1100 PRINT_OFFSET_PREFIX (file
);
1103 output_pic_addr_const (file
, x
, code
);
1105 output_addr_const (file
, x
);
1109 /* Print a memory operand whose address is ADDR. */
1112 print_operand_address (file
, addr
)
1116 register rtx reg1
, reg2
, breg
, ireg
;
1119 switch (GET_CODE (addr
))
1123 fprintf (file
, "%se", RP
);
1124 fputs (hi_reg_name
[REGNO (addr
)], file
);
1134 if (CONSTANT_ADDRESS_P (XEXP (addr
, 0)))
1136 offset
= XEXP (addr
, 0);
1137 addr
= XEXP (addr
, 1);
1139 else if (CONSTANT_ADDRESS_P (XEXP (addr
, 1)))
1141 offset
= XEXP (addr
, 1);
1142 addr
= XEXP (addr
, 0);
1144 if (GET_CODE (addr
) != PLUS
) ;
1145 else if (GET_CODE (XEXP (addr
, 0)) == MULT
)
1147 reg1
= XEXP (addr
, 0);
1148 addr
= XEXP (addr
, 1);
1150 else if (GET_CODE (XEXP (addr
, 1)) == MULT
)
1152 reg1
= XEXP (addr
, 1);
1153 addr
= XEXP (addr
, 0);
1155 else if (GET_CODE (XEXP (addr
, 0)) == REG
)
1157 reg1
= XEXP (addr
, 0);
1158 addr
= XEXP (addr
, 1);
1160 else if (GET_CODE (XEXP (addr
, 1)) == REG
)
1162 reg1
= XEXP (addr
, 1);
1163 addr
= XEXP (addr
, 0);
1165 if (GET_CODE (addr
) == REG
|| GET_CODE (addr
) == MULT
)
1167 if (reg1
== 0) reg1
= addr
;
1173 if (addr
!= 0) abort ();
1176 if ((reg1
&& GET_CODE (reg1
) == MULT
)
1177 || (reg2
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2
))))
1182 else if (reg1
!= 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1
)))
1188 if (ireg
!= 0 || breg
!= 0)
1194 if (GET_CODE (addr
) == LABEL_REF
)
1195 output_asm_label (addr
);
1199 output_pic_addr_const (file
, addr
, 0);
1201 output_addr_const (file
, addr
);
1205 if (ireg
!= 0 && GET_CODE (ireg
) == MULT
)
1207 scale
= INTVAL (XEXP (ireg
, 1));
1208 ireg
= XEXP (ireg
, 0);
1211 /* The stack pointer can only appear as a base register,
1212 never an index register, so exchange the regs if it is wrong. */
1214 if (scale
== 1 && ireg
&& REGNO (ireg
) == STACK_POINTER_REGNUM
)
1223 /* output breg+ireg*scale */
1224 PRINT_B_I_S (breg
, ireg
, scale
, file
);
1231 if (GET_CODE (XEXP (addr
, 0)) == CONST_INT
)
1233 scale
= INTVAL (XEXP (addr
, 0));
1234 ireg
= XEXP (addr
, 1);
1238 scale
= INTVAL (XEXP (addr
, 1));
1239 ireg
= XEXP (addr
, 0);
1241 output_addr_const (file
, const0_rtx
);
1242 PRINT_B_I_S ((rtx
) 0, ireg
, scale
, file
);
1247 if (GET_CODE (addr
) == CONST_INT
1248 && INTVAL (addr
) < 0x8000
1249 && INTVAL (addr
) >= -0x8000)
1250 fprintf (file
, "%d", INTVAL (addr
));
1254 output_pic_addr_const (file
, addr
, 0);
1256 output_addr_const (file
, addr
);
1261 /* Set the cc_status for the results of an insn whose pattern is EXP.
1262 On the 80386, we assume that only test and compare insns, as well
1263 as SI, HI, & DI mode ADD, SUB, NEG, AND, IOR, XOR, ASHIFT, LSHIFT,
1264 ASHIFTRT, and LSHIFTRT instructions set the condition codes usefully.
1265 Also, we assume that jumps, moves and sCOND don't affect the condition
1266 codes. All else clobbers the condition codes, by assumption.
1268 We assume that ALL integer add, minus, etc. instructions effect the
1269 condition codes. This MUST be consistent with i386.md.
1271 We don't record any float test or compare - the redundant test &
1272 compare check in final.c does not handle stack-like regs correctly. */
1275 notice_update_cc (exp
)
1278 if (GET_CODE (exp
) == SET
)
1280 /* Jumps do not alter the cc's. */
1281 if (SET_DEST (exp
) == pc_rtx
)
1283 /* Moving register or memory into a register:
1284 it doesn't alter the cc's, but it might invalidate
1285 the RTX's which we remember the cc's came from.
1286 (Note that moving a constant 0 or 1 MAY set the cc's). */
1287 if (REG_P (SET_DEST (exp
))
1288 && (REG_P (SET_SRC (exp
)) || GET_CODE (SET_SRC (exp
)) == MEM
1289 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp
))) == '<'))
1291 if (cc_status
.value1
1292 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value1
))
1293 cc_status
.value1
= 0;
1294 if (cc_status
.value2
1295 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value2
))
1296 cc_status
.value2
= 0;
1299 /* Moving register into memory doesn't alter the cc's.
1300 It may invalidate the RTX's which we remember the cc's came from. */
1301 if (GET_CODE (SET_DEST (exp
)) == MEM
1302 && (REG_P (SET_SRC (exp
))
1303 || GET_RTX_CLASS (GET_CODE (SET_SRC (exp
))) == '<'))
1305 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == MEM
)
1306 cc_status
.value1
= 0;
1307 if (cc_status
.value2
&& GET_CODE (cc_status
.value2
) == MEM
)
1308 cc_status
.value2
= 0;
1311 /* Function calls clobber the cc's. */
1312 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
1317 /* Tests and compares set the cc's in predictable ways. */
1318 else if (SET_DEST (exp
) == cc0_rtx
)
1321 cc_status
.value1
= SET_SRC (exp
);
1324 /* Certain instructions effect the condition codes. */
1325 else if (GET_MODE (SET_SRC (exp
)) == SImode
1326 || GET_MODE (SET_SRC (exp
)) == HImode
1327 || GET_MODE (SET_SRC (exp
)) == QImode
)
1328 switch (GET_CODE (SET_SRC (exp
)))
1330 case ASHIFTRT
: case LSHIFTRT
:
1331 case ASHIFT
: case LSHIFT
:
1332 /* Shifts on the 386 don't set the condition codes if the
1333 shift count is zero. */
1334 if (GET_CODE (XEXP (SET_SRC (exp
), 1)) != CONST_INT
)
1339 /* We assume that the CONST_INT is non-zero (this rtx would
1340 have been deleted if it were zero. */
1342 case PLUS
: case MINUS
: case NEG
:
1343 case AND
: case IOR
: case XOR
:
1344 cc_status
.flags
= CC_NO_OVERFLOW
;
1345 cc_status
.value1
= SET_SRC (exp
);
1346 cc_status
.value2
= SET_DEST (exp
);
1357 else if (GET_CODE (exp
) == PARALLEL
1358 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
1360 if (SET_DEST (XVECEXP (exp
, 0, 0)) == pc_rtx
)
1362 if (SET_DEST (XVECEXP (exp
, 0, 0)) == cc0_rtx
)
1365 if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp
, 0, 0))))
1366 cc_status
.flags
|= CC_IN_80387
;
1368 cc_status
.value1
= SET_SRC (XVECEXP (exp
, 0, 0));
1379 /* Split one or more DImode RTL references into pairs of SImode
1380 references. The RTL can be REG, offsettable MEM, integer constant, or
1381 CONST_DOUBLE. "operands" is a pointer to an array of DImode RTL to
1382 split and "num" is its length. lo_half and hi_half are output arrays
1383 that parallel "operands". */
1386 split_di (operands
, num
, lo_half
, hi_half
)
1389 rtx lo_half
[], hi_half
[];
1393 if (GET_CODE (operands
[num
]) == REG
)
1395 lo_half
[num
] = gen_rtx (REG
, SImode
, REGNO (operands
[num
]));
1396 hi_half
[num
] = gen_rtx (REG
, SImode
, REGNO (operands
[num
]) + 1);
1398 else if (CONSTANT_P (operands
[num
]))
1400 split_double (operands
[num
], &lo_half
[num
], &hi_half
[num
]);
1402 else if (offsettable_memref_p (operands
[num
]))
1404 lo_half
[num
] = operands
[num
];
1405 hi_half
[num
] = adj_offsettable_operand (operands
[num
], 4);
1412 /* Return 1 if this is a valid binary operation on a 387.
1413 OP is the expression matched, and MODE is its mode. */
1416 binary_387_op (op
, mode
)
1418 enum machine_mode mode
;
1420 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
1423 switch (GET_CODE (op
))
1429 return GET_MODE_CLASS (GET_MODE (op
)) == MODE_FLOAT
;
1436 /* Return 1 if this is a valid conversion operation on a 387.
1437 OP is the expression matched, and MODE is its mode. */
1440 convert_387_op (op
, mode
)
1442 enum machine_mode mode
;
1444 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
1447 switch (GET_CODE (op
))
1450 return GET_MODE (XEXP (op
, 0)) == SImode
;
1453 return mode
== DFmode
&& GET_MODE (XEXP (op
, 0)) == SFmode
;
1460 /* Return 1 if this is a valid shift or rotate operation on a 386.
1461 OP is the expression matched, and MODE is its mode. */
1466 enum machine_mode mode
;
1468 rtx operand
= XEXP (op
, 0);
1470 if (mode
!= VOIDmode
&& mode
!= GET_MODE (op
))
1473 if (GET_MODE (operand
) != GET_MODE (op
)
1474 || GET_MODE_CLASS (GET_MODE (op
)) != MODE_INT
)
1477 return (GET_CODE (op
) == ASHIFT
1478 || GET_CODE (op
) == ASHIFTRT
1479 || GET_CODE (op
) == LSHIFTRT
1480 || GET_CODE (op
) == ROTATE
1481 || GET_CODE (op
) == ROTATERT
);
1484 /* Output code to perform a 387 binary operation in INSN, one of PLUS,
1485 MINUS, MULT or DIV. OPERANDS are the insn operands, where operands[3]
1486 is the expression of the binary operation. The output may either be
1487 emitted here, or returned to the caller, like all output_* functions.
1489 There is no guarantee that the operands are the same mode, as they
1490 might be within FLOAT or FLOAT_EXTEND expressions. */
1493 output_387_binary_op (insn
, operands
)
1499 static char buf
[100];
1501 switch (GET_CODE (operands
[3]))
1504 if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_INT
1505 || GET_MODE_CLASS (GET_MODE (operands
[2])) == MODE_INT
)
1512 if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_INT
1513 || GET_MODE_CLASS (GET_MODE (operands
[2])) == MODE_INT
)
1520 if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_INT
1521 || GET_MODE_CLASS (GET_MODE (operands
[2])) == MODE_INT
)
1528 if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_INT
1529 || GET_MODE_CLASS (GET_MODE (operands
[2])) == MODE_INT
)
1539 strcpy (buf
, base_op
);
1541 switch (GET_CODE (operands
[3]))
1545 if (REG_P (operands
[2]) && REGNO (operands
[0]) == REGNO (operands
[2]))
1548 operands
[2] = operands
[1];
1552 if (GET_CODE (operands
[2]) == MEM
)
1553 return strcat (buf
, AS1 (%z2
,%2));
1555 if (NON_STACK_REG_P (operands
[1]))
1557 output_op_from_reg (operands
[1], strcat (buf
, AS1 (%z0
,%1)));
1560 else if (NON_STACK_REG_P (operands
[2]))
1562 output_op_from_reg (operands
[2], strcat (buf
, AS1 (%z0
,%1)));
1566 if (find_regno_note (insn
, REG_DEAD
, REGNO (operands
[2])))
1567 return strcat (buf
, AS2 (p
,%2,%0));
1569 if (STACK_TOP_P (operands
[0]))
1570 return strcat (buf
, AS2 (,%y2
,%0));
1572 return strcat (buf
, AS2 (,%2,%0));
1576 if (GET_CODE (operands
[1]) == MEM
)
1577 return strcat (buf
, AS1 (r
%z1
,%1));
1579 if (GET_CODE (operands
[2]) == MEM
)
1580 return strcat (buf
, AS1 (%z2
,%2));
1582 if (NON_STACK_REG_P (operands
[1]))
1584 output_op_from_reg (operands
[1], strcat (buf
, AS1 (r
%z0
,%1)));
1587 else if (NON_STACK_REG_P (operands
[2]))
1589 output_op_from_reg (operands
[2], strcat (buf
, AS1 (%z0
,%1)));
1593 if (! STACK_REG_P (operands
[1]) || ! STACK_REG_P (operands
[2]))
1596 if (find_regno_note (insn
, REG_DEAD
, REGNO (operands
[2])))
1597 return strcat (buf
, AS2 (rp
,%2,%0));
1599 if (find_regno_note (insn
, REG_DEAD
, REGNO (operands
[1])))
1600 return strcat (buf
, AS2 (p
,%1,%0));
1602 if (STACK_TOP_P (operands
[0]))
1604 if (STACK_TOP_P (operands
[1]))
1605 return strcat (buf
, AS2 (,%y2
,%0));
1607 return strcat (buf
, AS2 (r
,%y1
,%0));
1609 else if (STACK_TOP_P (operands
[1]))
1610 return strcat (buf
, AS2 (,%1,%0));
1612 return strcat (buf
, AS2 (r
,%2,%0));
1619 /* Output code for INSN to convert a float to a signed int. OPERANDS
1620 are the insn operands. The output may be SFmode or DFmode and the
1621 input operand may be SImode or DImode. As a special case, make sure
1622 that the 387 stack top dies if the output mode is DImode, because the
1623 hardware requires this. */
1626 output_fix_trunc (insn
, operands
)
1630 int stack_top_dies
= find_regno_note (insn
, REG_DEAD
, FIRST_STACK_REG
) != 0;
1633 if (! STACK_TOP_P (operands
[1]) ||
1634 (GET_MODE (operands
[0]) == DImode
&& ! stack_top_dies
))
1637 xops
[0] = stack_pointer_rtx
;
1638 xops
[1] = AT_SP (SImode
);
1639 xops
[2] = adj_offsettable_operand (xops
[1], 2);
1640 xops
[3] = GEN_INT (4);
1641 xops
[4] = GEN_INT (0xc00);
1642 xops
[5] = operands
[2];
1644 output_asm_insn (AS2 (sub
%L0
,%3,%0), xops
);
1645 output_asm_insn (AS1 (fnstc
%W5
,%1), xops
);
1646 output_asm_insn (AS2 (mov
%W5
,%1,%5), xops
);
1647 output_asm_insn (AS2 (or%W5
,%4,%5), xops
);
1648 output_asm_insn (AS2 (mov
%W5
,%5,%2), xops
);
1649 output_asm_insn (AS1 (fldc
%W5
,%2), xops
);
1651 if (NON_STACK_REG_P (operands
[0]))
1652 output_to_reg (operands
[0], stack_top_dies
);
1653 else if (GET_CODE (operands
[0]) == MEM
)
1655 /* If frame pointer elimination is being done, the MEM reference
1656 might be an index off of the stack pointer. In that case,
1657 since we have already adjusted %esp above, adjust the operand
1658 address so it points where it should. */
1660 if (! frame_pointer_needed
1661 && reg_mentioned_p (stack_pointer_rtx
, operands
[0]))
1662 operands
[0] = adj_offsettable_operand (operands
[0], 4);
1665 output_asm_insn (AS1 (fistp
%z0
,%0), operands
);
1667 output_asm_insn (AS1 (fist
%z0
,%0), operands
);
1672 output_asm_insn (AS1 (fldc
%W5
,%1), xops
);
1673 output_asm_insn (AS2 (add
%L0
,%3,%0), xops
);
1678 /* Output code for INSN to compare OPERANDS. The two operands might
1679 not have the same mode: one might be within a FLOAT or FLOAT_EXTEND
1680 expression. If the compare is in mode CCFPEQmode, use an opcode that
1681 will not fault if a qNaN is present. */
1684 output_float_compare (insn
, operands
)
1689 rtx body
= XVECEXP (PATTERN (insn
), 0, 0);
1690 int unordered_compare
= GET_MODE (SET_SRC (body
)) == CCFPEQmode
;
1692 if (! STACK_TOP_P (operands
[0]))
1695 stack_top_dies
= find_regno_note (insn
, REG_DEAD
, FIRST_STACK_REG
) != 0;
1697 if (STACK_REG_P (operands
[1])
1699 && find_regno_note (insn
, REG_DEAD
, REGNO (operands
[1]))
1700 && REGNO (operands
[1]) != FIRST_STACK_REG
)
1702 /* If both the top of the 387 stack dies, and the other operand
1703 is also a stack register that dies, then this must be a
1704 `fcompp' float compare */
1706 if (unordered_compare
)
1707 output_asm_insn ("fucompp", operands
);
1709 output_asm_insn ("fcompp", operands
);
1713 static char buf
[100];
1715 /* Decide if this is the integer or float compare opcode, or the
1716 unordered float compare. */
1718 if (unordered_compare
)
1719 strcpy (buf
, "fucom");
1720 else if (GET_MODE_CLASS (GET_MODE (operands
[1])) == MODE_FLOAT
)
1721 strcpy (buf
, "fcom");
1723 strcpy (buf
, "ficom");
1725 /* Modify the opcode if the 387 stack is to be popped. */
1730 if (NON_STACK_REG_P (operands
[1]))
1731 output_op_from_reg (operands
[1], strcat (buf
, AS1 (%z0
,%1)));
1733 output_asm_insn (strcat (buf
, AS1 (%z1
,%y1
)), operands
);
1736 /* Now retrieve the condition code. */
1738 return output_fp_cc0_set (insn
);
1741 /* Output opcodes to transfer the results of FP compare or test INSN
1742 from the FPU to the CPU flags. If TARGET_IEEE_FP, ensure that if the
1743 result of the compare or test is unordered, no comparison operator
1744 succeeds except NE. Return an output template, if any. */
1747 output_fp_cc0_set (insn
)
1751 rtx unordered_label
;
1755 xops
[0] = gen_rtx (REG
, HImode
, 0);
1756 output_asm_insn (AS1 (fnsts
%W0
,%0), xops
);
1758 if (! TARGET_IEEE_FP
)
1761 next
= next_cc0_user (insn
);
1763 if (GET_CODE (next
) == JUMP_INSN
1764 && GET_CODE (PATTERN (next
)) == SET
1765 && SET_DEST (PATTERN (next
)) == pc_rtx
1766 && GET_CODE (SET_SRC (PATTERN (next
))) == IF_THEN_ELSE
)
1768 code
= GET_CODE (XEXP (SET_SRC (PATTERN (next
)), 0));
1770 else if (GET_CODE (PATTERN (next
)) == SET
)
1772 code
= GET_CODE (SET_SRC (PATTERN (next
)));
1777 xops
[0] = gen_rtx (REG
, QImode
, 0);
1782 xops
[1] = GEN_INT (0x45);
1783 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
1788 xops
[1] = GEN_INT (0x45);
1789 xops
[2] = GEN_INT (0x01);
1790 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
1791 output_asm_insn (AS2 (cmp
%B0
,%2,%h0
), xops
);
1796 xops
[1] = GEN_INT (0x05);
1797 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
1802 xops
[1] = GEN_INT (0x45);
1803 xops
[2] = GEN_INT (0x40);
1804 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
1805 output_asm_insn (AS1 (dec
%B0
,%h0
), xops
);
1806 output_asm_insn (AS2 (cmp
%B0
,%2,%h0
), xops
);
1811 xops
[1] = GEN_INT (0x45);
1812 xops
[2] = GEN_INT (0x40);
1813 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
1814 output_asm_insn (AS2 (cmp
%B0
,%2,%h0
), xops
);
1819 xops
[1] = GEN_INT (0x44);
1820 xops
[2] = GEN_INT (0x40);
1821 output_asm_insn (AS2 (and%B0
,%1,%h0
), xops
);
1822 output_asm_insn (AS2 (xor%B0
,%2,%h0
), xops
);