11debfc3dSmrg /* Register to Stack convert for GNU compiler.
28feb0f0bSmrg Copyright (C) 1992-2020 Free Software Foundation, Inc.
31debfc3dSmrg
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it
71debfc3dSmrg under the terms of the GNU General Public License as published by
81debfc3dSmrg the Free Software Foundation; either version 3, or (at your option)
91debfc3dSmrg any later version.
101debfc3dSmrg
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT
121debfc3dSmrg ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
131debfc3dSmrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
141debfc3dSmrg License for more details.
151debfc3dSmrg
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3. If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>. */
191debfc3dSmrg
201debfc3dSmrg /* This pass converts stack-like registers from the "flat register
211debfc3dSmrg file" model that gcc uses, to a stack convention that the 387 uses.
221debfc3dSmrg
231debfc3dSmrg * The form of the input:
241debfc3dSmrg
251debfc3dSmrg On input, the function consists of insn that have had their
261debfc3dSmrg registers fully allocated to a set of "virtual" registers. Note that
271debfc3dSmrg the word "virtual" is used differently here than elsewhere in gcc: for
281debfc3dSmrg each virtual stack reg, there is a hard reg, but the mapping between
291debfc3dSmrg them is not known until this pass is run. On output, hard register
301debfc3dSmrg numbers have been substituted, and various pop and exchange insns have
311debfc3dSmrg been emitted. The hard register numbers and the virtual register
321debfc3dSmrg numbers completely overlap - before this pass, all stack register
331debfc3dSmrg numbers are virtual, and afterward they are all hard.
341debfc3dSmrg
351debfc3dSmrg The virtual registers can be manipulated normally by gcc, and their
361debfc3dSmrg semantics are the same as for normal registers. After the hard
371debfc3dSmrg register numbers are substituted, the semantics of an insn containing
381debfc3dSmrg stack-like regs are not the same as for an insn with normal regs: for
391debfc3dSmrg instance, it is not safe to delete an insn that appears to be a no-op
401debfc3dSmrg move. In general, no insn containing hard regs should be changed
411debfc3dSmrg after this pass is done.
421debfc3dSmrg
431debfc3dSmrg * The form of the output:
441debfc3dSmrg
451debfc3dSmrg After this pass, hard register numbers represent the distance from
461debfc3dSmrg the current top of stack to the desired register. A reference to
471debfc3dSmrg FIRST_STACK_REG references the top of stack, FIRST_STACK_REG + 1,
481debfc3dSmrg represents the register just below that, and so forth. Also, REG_DEAD
491debfc3dSmrg notes indicate whether or not a stack register should be popped.
501debfc3dSmrg
511debfc3dSmrg A "swap" insn looks like a parallel of two patterns, where each
521debfc3dSmrg pattern is a SET: one sets A to B, the other B to A.
531debfc3dSmrg
541debfc3dSmrg A "push" or "load" insn is a SET whose SET_DEST is FIRST_STACK_REG
551debfc3dSmrg and whose SET_DEST is REG or MEM. Any other SET_DEST, such as PLUS,
561debfc3dSmrg will replace the existing stack top, not push a new value.
571debfc3dSmrg
581debfc3dSmrg A store insn is a SET whose SET_DEST is FIRST_STACK_REG, and whose
591debfc3dSmrg SET_SRC is REG or MEM.
601debfc3dSmrg
611debfc3dSmrg The case where the SET_SRC and SET_DEST are both FIRST_STACK_REG
621debfc3dSmrg appears ambiguous. As a special case, the presence of a REG_DEAD note
631debfc3dSmrg for FIRST_STACK_REG differentiates between a load insn and a pop.
641debfc3dSmrg
651debfc3dSmrg If a REG_DEAD is present, the insn represents a "pop" that discards
661debfc3dSmrg the top of the register stack. If there is no REG_DEAD note, then the
671debfc3dSmrg insn represents a "dup" or a push of the current top of stack onto the
681debfc3dSmrg stack.
691debfc3dSmrg
701debfc3dSmrg * Methodology:
711debfc3dSmrg
721debfc3dSmrg Existing REG_DEAD and REG_UNUSED notes for stack registers are
731debfc3dSmrg deleted and recreated from scratch. REG_DEAD is never created for a
741debfc3dSmrg SET_DEST, only REG_UNUSED.
751debfc3dSmrg
761debfc3dSmrg * asm_operands:
771debfc3dSmrg
781debfc3dSmrg There are several rules on the usage of stack-like regs in
791debfc3dSmrg asm_operands insns. These rules apply only to the operands that are
801debfc3dSmrg stack-like regs:
811debfc3dSmrg
821debfc3dSmrg 1. Given a set of input regs that die in an asm_operands, it is
831debfc3dSmrg necessary to know which are implicitly popped by the asm, and
841debfc3dSmrg which must be explicitly popped by gcc.
851debfc3dSmrg
861debfc3dSmrg An input reg that is implicitly popped by the asm must be
871debfc3dSmrg explicitly clobbered, unless it is constrained to match an
881debfc3dSmrg output operand.
891debfc3dSmrg
901debfc3dSmrg 2. For any input reg that is implicitly popped by an asm, it is
911debfc3dSmrg necessary to know how to adjust the stack to compensate for the pop.
921debfc3dSmrg If any non-popped input is closer to the top of the reg-stack than
931debfc3dSmrg the implicitly popped reg, it would not be possible to know what the
941debfc3dSmrg stack looked like - it's not clear how the rest of the stack "slides
951debfc3dSmrg up".
961debfc3dSmrg
971debfc3dSmrg All implicitly popped input regs must be closer to the top of
981debfc3dSmrg the reg-stack than any input that is not implicitly popped.
991debfc3dSmrg
1001debfc3dSmrg All explicitly referenced input operands may not "skip" a reg.
1011debfc3dSmrg Otherwise we can have holes in the stack.
1021debfc3dSmrg
1031debfc3dSmrg 3. It is possible that if an input dies in an insn, reload might
1041debfc3dSmrg use the input reg for an output reload. Consider this example:
1051debfc3dSmrg
1061debfc3dSmrg asm ("foo" : "=t" (a) : "f" (b));
1071debfc3dSmrg
1081debfc3dSmrg This asm says that input B is not popped by the asm, and that
1091debfc3dSmrg the asm pushes a result onto the reg-stack, i.e., the stack is one
1101debfc3dSmrg deeper after the asm than it was before. But, it is possible that
1111debfc3dSmrg reload will think that it can use the same reg for both the input and
1121debfc3dSmrg the output, if input B dies in this insn.
1131debfc3dSmrg
1141debfc3dSmrg If any input operand uses the "f" constraint, all output reg
1151debfc3dSmrg constraints must use the "&" earlyclobber.
1161debfc3dSmrg
1171debfc3dSmrg The asm above would be written as
1181debfc3dSmrg
1191debfc3dSmrg asm ("foo" : "=&t" (a) : "f" (b));
1201debfc3dSmrg
1211debfc3dSmrg 4. Some operands need to be in particular places on the stack. All
1221debfc3dSmrg output operands fall in this category - there is no other way to
1231debfc3dSmrg know which regs the outputs appear in unless the user indicates
1241debfc3dSmrg this in the constraints.
1251debfc3dSmrg
1261debfc3dSmrg Output operands must specifically indicate which reg an output
1271debfc3dSmrg appears in after an asm. "=f" is not allowed: the operand
1281debfc3dSmrg constraints must select a class with a single reg.
1291debfc3dSmrg
1301debfc3dSmrg 5. Output operands may not be "inserted" between existing stack regs.
1311debfc3dSmrg Since no 387 opcode uses a read/write operand, all output operands
1321debfc3dSmrg are dead before the asm_operands, and are pushed by the asm_operands.
1331debfc3dSmrg It makes no sense to push anywhere but the top of the reg-stack.
1341debfc3dSmrg
1351debfc3dSmrg Output operands must start at the top of the reg-stack: output
1361debfc3dSmrg operands may not "skip" a reg.
1371debfc3dSmrg
1381debfc3dSmrg 6. Some asm statements may need extra stack space for internal
1391debfc3dSmrg calculations. This can be guaranteed by clobbering stack registers
1401debfc3dSmrg unrelated to the inputs and outputs.
1411debfc3dSmrg
1421debfc3dSmrg Here are a couple of reasonable asms to want to write. This asm
1431debfc3dSmrg takes one input, which is internally popped, and produces two outputs.
1441debfc3dSmrg
1451debfc3dSmrg asm ("fsincos" : "=t" (cos), "=u" (sin) : "0" (inp));
1461debfc3dSmrg
1471debfc3dSmrg This asm takes two inputs, which are popped by the fyl2xp1 opcode,
1481debfc3dSmrg and replaces them with one output. The user must code the "st(1)"
1491debfc3dSmrg clobber for reg-stack.c to know that fyl2xp1 pops both inputs.
1501debfc3dSmrg
1511debfc3dSmrg asm ("fyl2xp1" : "=t" (result) : "0" (x), "u" (y) : "st(1)");
1521debfc3dSmrg
1531debfc3dSmrg */
1541debfc3dSmrg
1551debfc3dSmrg #include "config.h"
1561debfc3dSmrg #include "system.h"
1571debfc3dSmrg #include "coretypes.h"
1581debfc3dSmrg #include "backend.h"
1591debfc3dSmrg #include "target.h"
1601debfc3dSmrg #include "rtl.h"
1611debfc3dSmrg #include "tree.h"
1621debfc3dSmrg #include "df.h"
1631debfc3dSmrg #include "insn-config.h"
1641debfc3dSmrg #include "memmodel.h"
165c0a68be4Smrg #include "regs.h"
1661debfc3dSmrg #include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */
1671debfc3dSmrg #include "recog.h"
1681debfc3dSmrg #include "varasm.h"
1691debfc3dSmrg #include "rtl-error.h"
1701debfc3dSmrg #include "cfgrtl.h"
1711debfc3dSmrg #include "cfganal.h"
1721debfc3dSmrg #include "cfgbuild.h"
1731debfc3dSmrg #include "cfgcleanup.h"
1741debfc3dSmrg #include "reload.h"
1751debfc3dSmrg #include "tree-pass.h"
1761debfc3dSmrg #include "rtl-iter.h"
1771debfc3dSmrg
1781debfc3dSmrg #ifdef STACK_REGS
1791debfc3dSmrg
1801debfc3dSmrg /* We use this array to cache info about insns, because otherwise we
1811debfc3dSmrg spend too much time in stack_regs_mentioned_p.
1821debfc3dSmrg
1831debfc3dSmrg Indexed by insn UIDs. A value of zero is uninitialized, one indicates
1841debfc3dSmrg the insn uses stack registers, two indicates the insn does not use
1851debfc3dSmrg stack registers. */
1861debfc3dSmrg static vec<char> stack_regs_mentioned_data;
1871debfc3dSmrg
1881debfc3dSmrg #define REG_STACK_SIZE (LAST_STACK_REG - FIRST_STACK_REG + 1)
1891debfc3dSmrg
1901debfc3dSmrg int regstack_completed = 0;
1911debfc3dSmrg
1921debfc3dSmrg /* This is the basic stack record. TOP is an index into REG[] such
1931debfc3dSmrg that REG[TOP] is the top of stack. If TOP is -1 the stack is empty.
1941debfc3dSmrg
1951debfc3dSmrg If TOP is -2, REG[] is not yet initialized. Stack initialization
1961debfc3dSmrg consists of placing each live reg in array `reg' and setting `top'
1971debfc3dSmrg appropriately.
1981debfc3dSmrg
1991debfc3dSmrg REG_SET indicates which registers are live. */
2001debfc3dSmrg
2011debfc3dSmrg typedef struct stack_def
2021debfc3dSmrg {
2031debfc3dSmrg int top; /* index to top stack element */
2041debfc3dSmrg HARD_REG_SET reg_set; /* set of live registers */
2051debfc3dSmrg unsigned char reg[REG_STACK_SIZE];/* register - stack mapping */
2061debfc3dSmrg } *stack_ptr;
2071debfc3dSmrg
2081debfc3dSmrg /* This is used to carry information about basic blocks. It is
2091debfc3dSmrg attached to the AUX field of the standard CFG block. */
2101debfc3dSmrg
2111debfc3dSmrg typedef struct block_info_def
2121debfc3dSmrg {
2131debfc3dSmrg struct stack_def stack_in; /* Input stack configuration. */
2141debfc3dSmrg struct stack_def stack_out; /* Output stack configuration. */
2151debfc3dSmrg HARD_REG_SET out_reg_set; /* Stack regs live on output. */
2161debfc3dSmrg int done; /* True if block already converted. */
2171debfc3dSmrg int predecessors; /* Number of predecessors that need
2181debfc3dSmrg to be visited. */
2191debfc3dSmrg } *block_info;
2201debfc3dSmrg
2211debfc3dSmrg #define BLOCK_INFO(B) ((block_info) (B)->aux)
2221debfc3dSmrg
2231debfc3dSmrg /* Passed to change_stack to indicate where to emit insns. */
2241debfc3dSmrg enum emit_where
2251debfc3dSmrg {
2261debfc3dSmrg EMIT_AFTER,
2271debfc3dSmrg EMIT_BEFORE
2281debfc3dSmrg };
2291debfc3dSmrg
2301debfc3dSmrg /* The block we're currently working on. */
2311debfc3dSmrg static basic_block current_block;
2321debfc3dSmrg
2331debfc3dSmrg /* In the current_block, whether we're processing the first register
2341debfc3dSmrg stack or call instruction, i.e. the regstack is currently the
2351debfc3dSmrg same as BLOCK_INFO(current_block)->stack_in. */
2361debfc3dSmrg static bool starting_stack_p;
2371debfc3dSmrg
2381debfc3dSmrg /* This is the register file for all register after conversion. */
2391debfc3dSmrg static rtx
2401debfc3dSmrg FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE];
2411debfc3dSmrg
2421debfc3dSmrg #define FP_MODE_REG(regno,mode) \
2431debfc3dSmrg (FP_mode_reg[(regno)-FIRST_STACK_REG][(int) (mode)])
2441debfc3dSmrg
2451debfc3dSmrg /* Used to initialize uninitialized registers. */
2461debfc3dSmrg static rtx not_a_num;
2471debfc3dSmrg
2481debfc3dSmrg /* Forward declarations */
2491debfc3dSmrg
2501debfc3dSmrg static int stack_regs_mentioned_p (const_rtx pat);
2511debfc3dSmrg static void pop_stack (stack_ptr, int);
2521debfc3dSmrg static rtx *get_true_reg (rtx *);
2531debfc3dSmrg
2541debfc3dSmrg static int check_asm_stack_operands (rtx_insn *);
2551debfc3dSmrg static void get_asm_operands_in_out (rtx, int *, int *);
2561debfc3dSmrg static rtx stack_result (tree);
2571debfc3dSmrg static void replace_reg (rtx *, int);
2581debfc3dSmrg static void remove_regno_note (rtx_insn *, enum reg_note, unsigned int);
2591debfc3dSmrg static int get_hard_regnum (stack_ptr, rtx);
2601debfc3dSmrg static rtx_insn *emit_pop_insn (rtx_insn *, stack_ptr, rtx, enum emit_where);
2611debfc3dSmrg static void swap_to_top (rtx_insn *, stack_ptr, rtx, rtx);
2621debfc3dSmrg static bool move_for_stack_reg (rtx_insn *, stack_ptr, rtx);
2631debfc3dSmrg static bool move_nan_for_stack_reg (rtx_insn *, stack_ptr, rtx);
2641debfc3dSmrg static int swap_rtx_condition_1 (rtx);
265*23f5f463Smrg static int swap_rtx_condition (rtx_insn *, int &);
266a2dc1f3fSmrg static void compare_for_stack_reg (rtx_insn *, stack_ptr, rtx, bool);
2671debfc3dSmrg static bool subst_stack_regs_pat (rtx_insn *, stack_ptr, rtx);
2681debfc3dSmrg static void subst_asm_stack_regs (rtx_insn *, stack_ptr);
2691debfc3dSmrg static bool subst_stack_regs (rtx_insn *, stack_ptr);
2701debfc3dSmrg static void change_stack (rtx_insn *, stack_ptr, stack_ptr, enum emit_where);
2711debfc3dSmrg static void print_stack (FILE *, stack_ptr);
272*23f5f463Smrg static rtx_insn *next_flags_user (rtx_insn *, int &);
2731debfc3dSmrg
2741debfc3dSmrg /* Return nonzero if any stack register is mentioned somewhere within PAT. */
2751debfc3dSmrg
2761debfc3dSmrg static int
stack_regs_mentioned_p(const_rtx pat)2771debfc3dSmrg stack_regs_mentioned_p (const_rtx pat)
2781debfc3dSmrg {
2791debfc3dSmrg const char *fmt;
2801debfc3dSmrg int i;
2811debfc3dSmrg
2821debfc3dSmrg if (STACK_REG_P (pat))
2831debfc3dSmrg return 1;
2841debfc3dSmrg
2851debfc3dSmrg fmt = GET_RTX_FORMAT (GET_CODE (pat));
2861debfc3dSmrg for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
2871debfc3dSmrg {
2881debfc3dSmrg if (fmt[i] == 'E')
2891debfc3dSmrg {
2901debfc3dSmrg int j;
2911debfc3dSmrg
2921debfc3dSmrg for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
2931debfc3dSmrg if (stack_regs_mentioned_p (XVECEXP (pat, i, j)))
2941debfc3dSmrg return 1;
2951debfc3dSmrg }
2961debfc3dSmrg else if (fmt[i] == 'e' && stack_regs_mentioned_p (XEXP (pat, i)))
2971debfc3dSmrg return 1;
2981debfc3dSmrg }
2991debfc3dSmrg
3001debfc3dSmrg return 0;
3011debfc3dSmrg }
3021debfc3dSmrg
3031debfc3dSmrg /* Return nonzero if INSN mentions stacked registers, else return zero. */
3041debfc3dSmrg
3051debfc3dSmrg int
stack_regs_mentioned(const_rtx insn)3061debfc3dSmrg stack_regs_mentioned (const_rtx insn)
3071debfc3dSmrg {
3081debfc3dSmrg unsigned int uid, max;
3091debfc3dSmrg int test;
3101debfc3dSmrg
3111debfc3dSmrg if (! INSN_P (insn) || !stack_regs_mentioned_data.exists ())
3121debfc3dSmrg return 0;
3131debfc3dSmrg
3141debfc3dSmrg uid = INSN_UID (insn);
3151debfc3dSmrg max = stack_regs_mentioned_data.length ();
3161debfc3dSmrg if (uid >= max)
3171debfc3dSmrg {
3181debfc3dSmrg /* Allocate some extra size to avoid too many reallocs, but
3191debfc3dSmrg do not grow too quickly. */
3201debfc3dSmrg max = uid + uid / 20 + 1;
3211debfc3dSmrg stack_regs_mentioned_data.safe_grow_cleared (max);
3221debfc3dSmrg }
3231debfc3dSmrg
3241debfc3dSmrg test = stack_regs_mentioned_data[uid];
3251debfc3dSmrg if (test == 0)
3261debfc3dSmrg {
3271debfc3dSmrg /* This insn has yet to be examined. Do so now. */
3281debfc3dSmrg test = stack_regs_mentioned_p (PATTERN (insn)) ? 1 : 2;
3291debfc3dSmrg stack_regs_mentioned_data[uid] = test;
3301debfc3dSmrg }
3311debfc3dSmrg
3321debfc3dSmrg return test == 1;
3331debfc3dSmrg }
3341debfc3dSmrg
3351debfc3dSmrg static rtx ix86_flags_rtx;
3361debfc3dSmrg
3371debfc3dSmrg static rtx_insn *
next_flags_user(rtx_insn * insn,int & debug_seen)338*23f5f463Smrg next_flags_user (rtx_insn *insn, int &debug_seen)
3391debfc3dSmrg {
3401debfc3dSmrg /* Search forward looking for the first use of this value.
3411debfc3dSmrg Stop at block boundaries. */
3421debfc3dSmrg
3431debfc3dSmrg while (insn != BB_END (current_block))
3441debfc3dSmrg {
3451debfc3dSmrg insn = NEXT_INSN (insn);
3461debfc3dSmrg
3471debfc3dSmrg if (INSN_P (insn) && reg_mentioned_p (ix86_flags_rtx, PATTERN (insn)))
348*23f5f463Smrg {
349*23f5f463Smrg if (DEBUG_INSN_P (insn) && debug_seen >= 0)
350*23f5f463Smrg {
351*23f5f463Smrg debug_seen = 1;
352*23f5f463Smrg continue;
353*23f5f463Smrg }
3541debfc3dSmrg return insn;
355*23f5f463Smrg }
3561debfc3dSmrg
3571debfc3dSmrg if (CALL_P (insn))
3581debfc3dSmrg return NULL;
3591debfc3dSmrg }
3601debfc3dSmrg return NULL;
3611debfc3dSmrg }
3621debfc3dSmrg
3631debfc3dSmrg /* Reorganize the stack into ascending numbers, before this insn. */
3641debfc3dSmrg
3651debfc3dSmrg static void
straighten_stack(rtx_insn * insn,stack_ptr regstack)3661debfc3dSmrg straighten_stack (rtx_insn *insn, stack_ptr regstack)
3671debfc3dSmrg {
3681debfc3dSmrg struct stack_def temp_stack;
3691debfc3dSmrg int top;
3701debfc3dSmrg
3711debfc3dSmrg /* If there is only a single register on the stack, then the stack is
3721debfc3dSmrg already in increasing order and no reorganization is needed.
3731debfc3dSmrg
3741debfc3dSmrg Similarly if the stack is empty. */
3751debfc3dSmrg if (regstack->top <= 0)
3761debfc3dSmrg return;
3771debfc3dSmrg
3788feb0f0bSmrg temp_stack.reg_set = regstack->reg_set;
3791debfc3dSmrg
3801debfc3dSmrg for (top = temp_stack.top = regstack->top; top >= 0; top--)
3811debfc3dSmrg temp_stack.reg[top] = FIRST_STACK_REG + temp_stack.top - top;
3821debfc3dSmrg
3831debfc3dSmrg change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
3841debfc3dSmrg }
3851debfc3dSmrg
3861debfc3dSmrg /* Pop a register from the stack. */
3871debfc3dSmrg
3881debfc3dSmrg static void
pop_stack(stack_ptr regstack,int regno)3891debfc3dSmrg pop_stack (stack_ptr regstack, int regno)
3901debfc3dSmrg {
3911debfc3dSmrg int top = regstack->top;
3921debfc3dSmrg
3931debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set, regno);
3941debfc3dSmrg regstack->top--;
3951debfc3dSmrg /* If regno was not at the top of stack then adjust stack. */
3961debfc3dSmrg if (regstack->reg [top] != regno)
3971debfc3dSmrg {
3981debfc3dSmrg int i;
3991debfc3dSmrg for (i = regstack->top; i >= 0; i--)
4001debfc3dSmrg if (regstack->reg [i] == regno)
4011debfc3dSmrg {
4021debfc3dSmrg int j;
4031debfc3dSmrg for (j = i; j < top; j++)
4041debfc3dSmrg regstack->reg [j] = regstack->reg [j + 1];
4051debfc3dSmrg break;
4061debfc3dSmrg }
4071debfc3dSmrg }
4081debfc3dSmrg }
4091debfc3dSmrg
4101debfc3dSmrg /* Return a pointer to the REG expression within PAT. If PAT is not a
4111debfc3dSmrg REG, possible enclosed by a conversion rtx, return the inner part of
4121debfc3dSmrg PAT that stopped the search. */
4131debfc3dSmrg
4141debfc3dSmrg static rtx *
get_true_reg(rtx * pat)4151debfc3dSmrg get_true_reg (rtx *pat)
4161debfc3dSmrg {
4171debfc3dSmrg for (;;)
4181debfc3dSmrg switch (GET_CODE (*pat))
4191debfc3dSmrg {
4201debfc3dSmrg case SUBREG:
4211debfc3dSmrg /* Eliminate FP subregister accesses in favor of the
4221debfc3dSmrg actual FP register in use. */
4231debfc3dSmrg {
424c0a68be4Smrg rtx subreg = SUBREG_REG (*pat);
425c0a68be4Smrg
426c0a68be4Smrg if (STACK_REG_P (subreg))
4271debfc3dSmrg {
4281debfc3dSmrg int regno_off = subreg_regno_offset (REGNO (subreg),
4291debfc3dSmrg GET_MODE (subreg),
4301debfc3dSmrg SUBREG_BYTE (*pat),
4311debfc3dSmrg GET_MODE (*pat));
4321debfc3dSmrg *pat = FP_MODE_REG (REGNO (subreg) + regno_off,
4331debfc3dSmrg GET_MODE (subreg));
4341debfc3dSmrg return pat;
4351debfc3dSmrg }
4361debfc3dSmrg pat = &XEXP (*pat, 0);
4371debfc3dSmrg break;
4381debfc3dSmrg }
439c0a68be4Smrg
440c0a68be4Smrg case FLOAT_TRUNCATE:
441c0a68be4Smrg if (!flag_unsafe_math_optimizations)
442c0a68be4Smrg return pat;
443c0a68be4Smrg /* FALLTHRU */
444c0a68be4Smrg
4451debfc3dSmrg case FLOAT:
4461debfc3dSmrg case FIX:
4471debfc3dSmrg case FLOAT_EXTEND:
4481debfc3dSmrg pat = &XEXP (*pat, 0);
4491debfc3dSmrg break;
4501debfc3dSmrg
4511debfc3dSmrg case UNSPEC:
4521debfc3dSmrg if (XINT (*pat, 1) == UNSPEC_TRUNC_NOOP
4531debfc3dSmrg || XINT (*pat, 1) == UNSPEC_FILD_ATOMIC)
4541debfc3dSmrg pat = &XVECEXP (*pat, 0, 0);
4551debfc3dSmrg return pat;
4561debfc3dSmrg
4571debfc3dSmrg default:
4581debfc3dSmrg return pat;
4591debfc3dSmrg }
4601debfc3dSmrg }
4611debfc3dSmrg
4621debfc3dSmrg /* Set if we find any malformed asms in a block. */
4631debfc3dSmrg static bool any_malformed_asm;
4641debfc3dSmrg
4651debfc3dSmrg /* There are many rules that an asm statement for stack-like regs must
4661debfc3dSmrg follow. Those rules are explained at the top of this file: the rule
4671debfc3dSmrg numbers below refer to that explanation. */
4681debfc3dSmrg
4691debfc3dSmrg static int
check_asm_stack_operands(rtx_insn * insn)4701debfc3dSmrg check_asm_stack_operands (rtx_insn *insn)
4711debfc3dSmrg {
4721debfc3dSmrg int i;
4731debfc3dSmrg int n_clobbers;
4741debfc3dSmrg int malformed_asm = 0;
4751debfc3dSmrg rtx body = PATTERN (insn);
4761debfc3dSmrg
4771debfc3dSmrg char reg_used_as_output[FIRST_PSEUDO_REGISTER];
4781debfc3dSmrg char implicitly_dies[FIRST_PSEUDO_REGISTER];
4791debfc3dSmrg char explicitly_used[FIRST_PSEUDO_REGISTER];
4801debfc3dSmrg
4811debfc3dSmrg rtx *clobber_reg = 0;
4821debfc3dSmrg int n_inputs, n_outputs;
4831debfc3dSmrg
4841debfc3dSmrg /* Find out what the constraints require. If no constraint
4851debfc3dSmrg alternative matches, this asm is malformed. */
4861debfc3dSmrg extract_constrain_insn (insn);
4871debfc3dSmrg
4881debfc3dSmrg preprocess_constraints (insn);
4891debfc3dSmrg
4901debfc3dSmrg get_asm_operands_in_out (body, &n_outputs, &n_inputs);
4911debfc3dSmrg
4921debfc3dSmrg if (which_alternative < 0)
4931debfc3dSmrg {
4941debfc3dSmrg /* Avoid further trouble with this insn. */
4951debfc3dSmrg PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
4961debfc3dSmrg return 0;
4971debfc3dSmrg }
4981debfc3dSmrg const operand_alternative *op_alt = which_op_alt ();
4991debfc3dSmrg
5001debfc3dSmrg /* Strip SUBREGs here to make the following code simpler. */
5011debfc3dSmrg for (i = 0; i < recog_data.n_operands; i++)
5021debfc3dSmrg if (GET_CODE (recog_data.operand[i]) == SUBREG
5031debfc3dSmrg && REG_P (SUBREG_REG (recog_data.operand[i])))
5041debfc3dSmrg recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
5051debfc3dSmrg
5061debfc3dSmrg /* Set up CLOBBER_REG. */
5071debfc3dSmrg
5081debfc3dSmrg n_clobbers = 0;
5091debfc3dSmrg
5101debfc3dSmrg if (GET_CODE (body) == PARALLEL)
5111debfc3dSmrg {
5121debfc3dSmrg clobber_reg = XALLOCAVEC (rtx, XVECLEN (body, 0));
5131debfc3dSmrg
5141debfc3dSmrg for (i = 0; i < XVECLEN (body, 0); i++)
5151debfc3dSmrg if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
5161debfc3dSmrg {
5171debfc3dSmrg rtx clobber = XVECEXP (body, 0, i);
5181debfc3dSmrg rtx reg = XEXP (clobber, 0);
5191debfc3dSmrg
5201debfc3dSmrg if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg)))
5211debfc3dSmrg reg = SUBREG_REG (reg);
5221debfc3dSmrg
5231debfc3dSmrg if (STACK_REG_P (reg))
5241debfc3dSmrg {
5251debfc3dSmrg clobber_reg[n_clobbers] = reg;
5261debfc3dSmrg n_clobbers++;
5271debfc3dSmrg }
5281debfc3dSmrg }
5291debfc3dSmrg }
5301debfc3dSmrg
5311debfc3dSmrg /* Enforce rule #4: Output operands must specifically indicate which
5321debfc3dSmrg reg an output appears in after an asm. "=f" is not allowed: the
5331debfc3dSmrg operand constraints must select a class with a single reg.
5341debfc3dSmrg
5351debfc3dSmrg Also enforce rule #5: Output operands must start at the top of
5361debfc3dSmrg the reg-stack: output operands may not "skip" a reg. */
5371debfc3dSmrg
5381debfc3dSmrg memset (reg_used_as_output, 0, sizeof (reg_used_as_output));
5391debfc3dSmrg for (i = 0; i < n_outputs; i++)
5401debfc3dSmrg if (STACK_REG_P (recog_data.operand[i]))
5411debfc3dSmrg {
5421debfc3dSmrg if (reg_class_size[(int) op_alt[i].cl] != 1)
5431debfc3dSmrg {
5441debfc3dSmrg error_for_asm (insn, "output constraint %d must specify a single register", i);
5451debfc3dSmrg malformed_asm = 1;
5461debfc3dSmrg }
5471debfc3dSmrg else
5481debfc3dSmrg {
5491debfc3dSmrg int j;
5501debfc3dSmrg
5511debfc3dSmrg for (j = 0; j < n_clobbers; j++)
5521debfc3dSmrg if (REGNO (recog_data.operand[i]) == REGNO (clobber_reg[j]))
5531debfc3dSmrg {
5548feb0f0bSmrg error_for_asm (insn, "output constraint %d cannot be "
5558feb0f0bSmrg "specified together with %qs clobber",
5561debfc3dSmrg i, reg_names [REGNO (clobber_reg[j])]);
5571debfc3dSmrg malformed_asm = 1;
5581debfc3dSmrg break;
5591debfc3dSmrg }
5601debfc3dSmrg if (j == n_clobbers)
5611debfc3dSmrg reg_used_as_output[REGNO (recog_data.operand[i])] = 1;
5621debfc3dSmrg }
5631debfc3dSmrg }
5641debfc3dSmrg
5651debfc3dSmrg
5661debfc3dSmrg /* Search for first non-popped reg. */
5671debfc3dSmrg for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
5681debfc3dSmrg if (! reg_used_as_output[i])
5691debfc3dSmrg break;
5701debfc3dSmrg
5711debfc3dSmrg /* If there are any other popped regs, that's an error. */
5721debfc3dSmrg for (; i < LAST_STACK_REG + 1; i++)
5731debfc3dSmrg if (reg_used_as_output[i])
5741debfc3dSmrg break;
5751debfc3dSmrg
5761debfc3dSmrg if (i != LAST_STACK_REG + 1)
5771debfc3dSmrg {
5788feb0f0bSmrg error_for_asm (insn, "output registers must be grouped at top of stack");
5791debfc3dSmrg malformed_asm = 1;
5801debfc3dSmrg }
5811debfc3dSmrg
5821debfc3dSmrg /* Enforce rule #2: All implicitly popped input regs must be closer
5831debfc3dSmrg to the top of the reg-stack than any input that is not implicitly
5841debfc3dSmrg popped. */
5851debfc3dSmrg
5861debfc3dSmrg memset (implicitly_dies, 0, sizeof (implicitly_dies));
5871debfc3dSmrg memset (explicitly_used, 0, sizeof (explicitly_used));
5881debfc3dSmrg for (i = n_outputs; i < n_outputs + n_inputs; i++)
5891debfc3dSmrg if (STACK_REG_P (recog_data.operand[i]))
5901debfc3dSmrg {
5911debfc3dSmrg /* An input reg is implicitly popped if it is tied to an
5921debfc3dSmrg output, or if there is a CLOBBER for it. */
5931debfc3dSmrg int j;
5941debfc3dSmrg
5951debfc3dSmrg for (j = 0; j < n_clobbers; j++)
5961debfc3dSmrg if (operands_match_p (clobber_reg[j], recog_data.operand[i]))
5971debfc3dSmrg break;
5981debfc3dSmrg
5991debfc3dSmrg if (j < n_clobbers || op_alt[i].matches >= 0)
6001debfc3dSmrg implicitly_dies[REGNO (recog_data.operand[i])] = 1;
6011debfc3dSmrg else if (reg_class_size[(int) op_alt[i].cl] == 1)
6021debfc3dSmrg explicitly_used[REGNO (recog_data.operand[i])] = 1;
6031debfc3dSmrg }
6041debfc3dSmrg
6051debfc3dSmrg /* Search for first non-popped reg. */
6061debfc3dSmrg for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
6071debfc3dSmrg if (! implicitly_dies[i])
6081debfc3dSmrg break;
6091debfc3dSmrg
6101debfc3dSmrg /* If there are any other popped regs, that's an error. */
6111debfc3dSmrg for (; i < LAST_STACK_REG + 1; i++)
6121debfc3dSmrg if (implicitly_dies[i])
6131debfc3dSmrg break;
6141debfc3dSmrg
6151debfc3dSmrg if (i != LAST_STACK_REG + 1)
6161debfc3dSmrg {
6171debfc3dSmrg error_for_asm (insn,
6188feb0f0bSmrg "implicitly popped registers must be grouped "
6198feb0f0bSmrg "at top of stack");
6201debfc3dSmrg malformed_asm = 1;
6211debfc3dSmrg }
6221debfc3dSmrg
6231debfc3dSmrg /* Search for first not-explicitly used reg. */
6241debfc3dSmrg for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
6251debfc3dSmrg if (! implicitly_dies[i] && ! explicitly_used[i])
6261debfc3dSmrg break;
6271debfc3dSmrg
6281debfc3dSmrg /* If there are any other explicitly used regs, that's an error. */
6291debfc3dSmrg for (; i < LAST_STACK_REG + 1; i++)
6301debfc3dSmrg if (explicitly_used[i])
6311debfc3dSmrg break;
6321debfc3dSmrg
6331debfc3dSmrg if (i != LAST_STACK_REG + 1)
6341debfc3dSmrg {
6351debfc3dSmrg error_for_asm (insn,
6368feb0f0bSmrg "explicitly used registers must be grouped "
6378feb0f0bSmrg "at top of stack");
6381debfc3dSmrg malformed_asm = 1;
6391debfc3dSmrg }
6401debfc3dSmrg
6411debfc3dSmrg /* Enforce rule #3: If any input operand uses the "f" constraint, all
6421debfc3dSmrg output constraints must use the "&" earlyclobber.
6431debfc3dSmrg
6441debfc3dSmrg ??? Detect this more deterministically by having constrain_asm_operands
6451debfc3dSmrg record any earlyclobber. */
6461debfc3dSmrg
6471debfc3dSmrg for (i = n_outputs; i < n_outputs + n_inputs; i++)
6481debfc3dSmrg if (STACK_REG_P (recog_data.operand[i]) && op_alt[i].matches == -1)
6491debfc3dSmrg {
6501debfc3dSmrg int j;
6511debfc3dSmrg
6521debfc3dSmrg for (j = 0; j < n_outputs; j++)
6531debfc3dSmrg if (operands_match_p (recog_data.operand[j], recog_data.operand[i]))
6541debfc3dSmrg {
6551debfc3dSmrg error_for_asm (insn,
6561debfc3dSmrg "output operand %d must use %<&%> constraint", j);
6571debfc3dSmrg malformed_asm = 1;
6581debfc3dSmrg }
6591debfc3dSmrg }
6601debfc3dSmrg
6611debfc3dSmrg if (malformed_asm)
6621debfc3dSmrg {
6631debfc3dSmrg /* Avoid further trouble with this insn. */
6641debfc3dSmrg PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx);
6651debfc3dSmrg any_malformed_asm = true;
6661debfc3dSmrg return 0;
6671debfc3dSmrg }
6681debfc3dSmrg
6691debfc3dSmrg return 1;
6701debfc3dSmrg }
6711debfc3dSmrg
6721debfc3dSmrg /* Calculate the number of inputs and outputs in BODY, an
6731debfc3dSmrg asm_operands. N_OPERANDS is the total number of operands, and
6741debfc3dSmrg N_INPUTS and N_OUTPUTS are pointers to ints into which the results are
6751debfc3dSmrg placed. */
6761debfc3dSmrg
6771debfc3dSmrg static void
get_asm_operands_in_out(rtx body,int * pout,int * pin)6781debfc3dSmrg get_asm_operands_in_out (rtx body, int *pout, int *pin)
6791debfc3dSmrg {
6801debfc3dSmrg rtx asmop = extract_asm_operands (body);
6811debfc3dSmrg
6821debfc3dSmrg *pin = ASM_OPERANDS_INPUT_LENGTH (asmop);
6831debfc3dSmrg *pout = (recog_data.n_operands
6841debfc3dSmrg - ASM_OPERANDS_INPUT_LENGTH (asmop)
6851debfc3dSmrg - ASM_OPERANDS_LABEL_LENGTH (asmop));
6861debfc3dSmrg }
6871debfc3dSmrg
6881debfc3dSmrg /* If current function returns its result in an fp stack register,
6891debfc3dSmrg return the REG. Otherwise, return 0. */
6901debfc3dSmrg
6911debfc3dSmrg static rtx
stack_result(tree decl)6921debfc3dSmrg stack_result (tree decl)
6931debfc3dSmrg {
6941debfc3dSmrg rtx result;
6951debfc3dSmrg
6961debfc3dSmrg /* If the value is supposed to be returned in memory, then clearly
6971debfc3dSmrg it is not returned in a stack register. */
6981debfc3dSmrg if (aggregate_value_p (DECL_RESULT (decl), decl))
6991debfc3dSmrg return 0;
7001debfc3dSmrg
7011debfc3dSmrg result = DECL_RTL_IF_SET (DECL_RESULT (decl));
7021debfc3dSmrg if (result != 0)
7031debfc3dSmrg result = targetm.calls.function_value (TREE_TYPE (DECL_RESULT (decl)),
7041debfc3dSmrg decl, true);
7051debfc3dSmrg
7061debfc3dSmrg return result != 0 && STACK_REG_P (result) ? result : 0;
7071debfc3dSmrg }
7081debfc3dSmrg
7091debfc3dSmrg
7101debfc3dSmrg /*
7111debfc3dSmrg * This section deals with stack register substitution, and forms the second
7121debfc3dSmrg * pass over the RTL.
7131debfc3dSmrg */
7141debfc3dSmrg
7151debfc3dSmrg /* Replace REG, which is a pointer to a stack reg RTX, with an RTX for
7161debfc3dSmrg the desired hard REGNO. */
7171debfc3dSmrg
7181debfc3dSmrg static void
replace_reg(rtx * reg,int regno)7191debfc3dSmrg replace_reg (rtx *reg, int regno)
7201debfc3dSmrg {
7211debfc3dSmrg gcc_assert (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG));
7221debfc3dSmrg gcc_assert (STACK_REG_P (*reg));
7231debfc3dSmrg
724c0a68be4Smrg gcc_assert (GET_MODE_CLASS (GET_MODE (*reg)) == MODE_FLOAT
7251debfc3dSmrg || GET_MODE_CLASS (GET_MODE (*reg)) == MODE_COMPLEX_FLOAT);
7261debfc3dSmrg
7271debfc3dSmrg *reg = FP_MODE_REG (regno, GET_MODE (*reg));
7281debfc3dSmrg }
7291debfc3dSmrg
7301debfc3dSmrg /* Remove a note of type NOTE, which must be found, for register
7311debfc3dSmrg number REGNO from INSN. Remove only one such note. */
7321debfc3dSmrg
7331debfc3dSmrg static void
remove_regno_note(rtx_insn * insn,enum reg_note note,unsigned int regno)7341debfc3dSmrg remove_regno_note (rtx_insn *insn, enum reg_note note, unsigned int regno)
7351debfc3dSmrg {
7361debfc3dSmrg rtx *note_link, this_rtx;
7371debfc3dSmrg
7381debfc3dSmrg note_link = ®_NOTES (insn);
7391debfc3dSmrg for (this_rtx = *note_link; this_rtx; this_rtx = XEXP (this_rtx, 1))
7401debfc3dSmrg if (REG_NOTE_KIND (this_rtx) == note
7411debfc3dSmrg && REG_P (XEXP (this_rtx, 0)) && REGNO (XEXP (this_rtx, 0)) == regno)
7421debfc3dSmrg {
7431debfc3dSmrg *note_link = XEXP (this_rtx, 1);
7441debfc3dSmrg return;
7451debfc3dSmrg }
7461debfc3dSmrg else
7471debfc3dSmrg note_link = &XEXP (this_rtx, 1);
7481debfc3dSmrg
7491debfc3dSmrg gcc_unreachable ();
7501debfc3dSmrg }
7511debfc3dSmrg
7521debfc3dSmrg /* Find the hard register number of virtual register REG in REGSTACK.
7531debfc3dSmrg The hard register number is relative to the top of the stack. -1 is
7541debfc3dSmrg returned if the register is not found. */
7551debfc3dSmrg
7561debfc3dSmrg static int
get_hard_regnum(stack_ptr regstack,rtx reg)7571debfc3dSmrg get_hard_regnum (stack_ptr regstack, rtx reg)
7581debfc3dSmrg {
7591debfc3dSmrg int i;
7601debfc3dSmrg
7611debfc3dSmrg gcc_assert (STACK_REG_P (reg));
7621debfc3dSmrg
7631debfc3dSmrg for (i = regstack->top; i >= 0; i--)
7641debfc3dSmrg if (regstack->reg[i] == REGNO (reg))
7651debfc3dSmrg break;
7661debfc3dSmrg
7671debfc3dSmrg return i >= 0 ? (FIRST_STACK_REG + regstack->top - i) : -1;
7681debfc3dSmrg }
7691debfc3dSmrg
7701debfc3dSmrg /* Emit an insn to pop virtual register REG before or after INSN.
7711debfc3dSmrg REGSTACK is the stack state after INSN and is updated to reflect this
7721debfc3dSmrg pop. WHEN is either emit_insn_before or emit_insn_after. A pop insn
7731debfc3dSmrg is represented as a SET whose destination is the register to be popped
7741debfc3dSmrg and source is the top of stack. A death note for the top of stack
7751debfc3dSmrg cases the movdf pattern to pop. */
7761debfc3dSmrg
7771debfc3dSmrg static rtx_insn *
emit_pop_insn(rtx_insn * insn,stack_ptr regstack,rtx reg,enum emit_where where)778c0a68be4Smrg emit_pop_insn (rtx_insn *insn, stack_ptr regstack, rtx reg,
779c0a68be4Smrg enum emit_where where)
7801debfc3dSmrg {
781c0a68be4Smrg machine_mode raw_mode = reg_raw_mode[FIRST_STACK_REG];
7821debfc3dSmrg rtx_insn *pop_insn;
7831debfc3dSmrg rtx pop_rtx;
7841debfc3dSmrg int hard_regno;
7851debfc3dSmrg
7861debfc3dSmrg /* For complex types take care to pop both halves. These may survive in
7871debfc3dSmrg CLOBBER and USE expressions. */
7881debfc3dSmrg if (COMPLEX_MODE_P (GET_MODE (reg)))
7891debfc3dSmrg {
790c0a68be4Smrg rtx reg1 = FP_MODE_REG (REGNO (reg), raw_mode);
791c0a68be4Smrg rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, raw_mode);
7921debfc3dSmrg
7931debfc3dSmrg pop_insn = NULL;
7941debfc3dSmrg if (get_hard_regnum (regstack, reg1) >= 0)
7951debfc3dSmrg pop_insn = emit_pop_insn (insn, regstack, reg1, where);
7961debfc3dSmrg if (get_hard_regnum (regstack, reg2) >= 0)
7971debfc3dSmrg pop_insn = emit_pop_insn (insn, regstack, reg2, where);
7981debfc3dSmrg gcc_assert (pop_insn);
7991debfc3dSmrg return pop_insn;
8001debfc3dSmrg }
8011debfc3dSmrg
8021debfc3dSmrg hard_regno = get_hard_regnum (regstack, reg);
8031debfc3dSmrg
8041debfc3dSmrg gcc_assert (hard_regno >= FIRST_STACK_REG);
8051debfc3dSmrg
806c0a68be4Smrg pop_rtx = gen_rtx_SET (FP_MODE_REG (hard_regno, raw_mode),
807c0a68be4Smrg FP_MODE_REG (FIRST_STACK_REG, raw_mode));
8081debfc3dSmrg
8091debfc3dSmrg if (where == EMIT_AFTER)
8101debfc3dSmrg pop_insn = emit_insn_after (pop_rtx, insn);
8111debfc3dSmrg else
8121debfc3dSmrg pop_insn = emit_insn_before (pop_rtx, insn);
8131debfc3dSmrg
814c0a68be4Smrg add_reg_note (pop_insn, REG_DEAD, FP_MODE_REG (FIRST_STACK_REG, raw_mode));
8151debfc3dSmrg
8161debfc3dSmrg regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
8171debfc3dSmrg = regstack->reg[regstack->top];
8181debfc3dSmrg regstack->top -= 1;
8191debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (reg));
8201debfc3dSmrg
8211debfc3dSmrg return pop_insn;
8221debfc3dSmrg }
8231debfc3dSmrg
8241debfc3dSmrg /* Emit an insn before or after INSN to swap virtual register REG with
8251debfc3dSmrg the top of stack. REGSTACK is the stack state before the swap, and
8261debfc3dSmrg is updated to reflect the swap. A swap insn is represented as a
8271debfc3dSmrg PARALLEL of two patterns: each pattern moves one reg to the other.
8281debfc3dSmrg
8291debfc3dSmrg If REG is already at the top of the stack, no insn is emitted. */
8301debfc3dSmrg
8311debfc3dSmrg static void
emit_swap_insn(rtx_insn * insn,stack_ptr regstack,rtx reg)8321debfc3dSmrg emit_swap_insn (rtx_insn *insn, stack_ptr regstack, rtx reg)
8331debfc3dSmrg {
8341debfc3dSmrg int hard_regno;
8351debfc3dSmrg int other_reg; /* swap regno temps */
8361debfc3dSmrg rtx_insn *i1; /* the stack-reg insn prior to INSN */
8371debfc3dSmrg rtx i1set = NULL_RTX; /* the SET rtx within I1 */
8381debfc3dSmrg
8391debfc3dSmrg hard_regno = get_hard_regnum (regstack, reg);
8401debfc3dSmrg
8411debfc3dSmrg if (hard_regno == FIRST_STACK_REG)
8421debfc3dSmrg return;
8431debfc3dSmrg if (hard_regno == -1)
8441debfc3dSmrg {
8451debfc3dSmrg /* Something failed if the register wasn't on the stack. If we had
8461debfc3dSmrg malformed asms, we zapped the instruction itself, but that didn't
8471debfc3dSmrg produce the same pattern of register sets as before. To prevent
8481debfc3dSmrg further failure, adjust REGSTACK to include REG at TOP. */
8491debfc3dSmrg gcc_assert (any_malformed_asm);
8501debfc3dSmrg regstack->reg[++regstack->top] = REGNO (reg);
8511debfc3dSmrg return;
8521debfc3dSmrg }
8531debfc3dSmrg gcc_assert (hard_regno >= FIRST_STACK_REG);
8541debfc3dSmrg
8551debfc3dSmrg other_reg = regstack->top - (hard_regno - FIRST_STACK_REG);
8561debfc3dSmrg std::swap (regstack->reg[regstack->top], regstack->reg[other_reg]);
8571debfc3dSmrg
8581debfc3dSmrg /* Find the previous insn involving stack regs, but don't pass a
8591debfc3dSmrg block boundary. */
8601debfc3dSmrg i1 = NULL;
8611debfc3dSmrg if (current_block && insn != BB_HEAD (current_block))
8621debfc3dSmrg {
8631debfc3dSmrg rtx_insn *tmp = PREV_INSN (insn);
8641debfc3dSmrg rtx_insn *limit = PREV_INSN (BB_HEAD (current_block));
8651debfc3dSmrg while (tmp != limit)
8661debfc3dSmrg {
8671debfc3dSmrg if (LABEL_P (tmp)
8681debfc3dSmrg || CALL_P (tmp)
8691debfc3dSmrg || NOTE_INSN_BASIC_BLOCK_P (tmp)
8701debfc3dSmrg || (NONJUMP_INSN_P (tmp)
8711debfc3dSmrg && stack_regs_mentioned (tmp)))
8721debfc3dSmrg {
8731debfc3dSmrg i1 = tmp;
8741debfc3dSmrg break;
8751debfc3dSmrg }
8761debfc3dSmrg tmp = PREV_INSN (tmp);
8771debfc3dSmrg }
8781debfc3dSmrg }
8791debfc3dSmrg
8801debfc3dSmrg if (i1 != NULL_RTX
8811debfc3dSmrg && (i1set = single_set (i1)) != NULL_RTX)
8821debfc3dSmrg {
8831debfc3dSmrg rtx i1src = *get_true_reg (&SET_SRC (i1set));
8841debfc3dSmrg rtx i1dest = *get_true_reg (&SET_DEST (i1set));
8851debfc3dSmrg
8861debfc3dSmrg /* If the previous register stack push was from the reg we are to
8871debfc3dSmrg swap with, omit the swap. */
8881debfc3dSmrg
8891debfc3dSmrg if (REG_P (i1dest) && REGNO (i1dest) == FIRST_STACK_REG
8901debfc3dSmrg && REG_P (i1src)
8911debfc3dSmrg && REGNO (i1src) == (unsigned) hard_regno - 1
8921debfc3dSmrg && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
8931debfc3dSmrg return;
8941debfc3dSmrg
8951debfc3dSmrg /* If the previous insn wrote to the reg we are to swap with,
8961debfc3dSmrg omit the swap. */
8971debfc3dSmrg
8981debfc3dSmrg if (REG_P (i1dest) && REGNO (i1dest) == (unsigned) hard_regno
8991debfc3dSmrg && REG_P (i1src) && REGNO (i1src) == FIRST_STACK_REG
9001debfc3dSmrg && find_regno_note (i1, REG_DEAD, FIRST_STACK_REG) == NULL_RTX)
9011debfc3dSmrg return;
9021debfc3dSmrg
9031debfc3dSmrg /* Instead of
9041debfc3dSmrg fld a
9051debfc3dSmrg fld b
9061debfc3dSmrg fxch %st(1)
9071debfc3dSmrg just use
9081debfc3dSmrg fld b
9091debfc3dSmrg fld a
9101debfc3dSmrg if possible. Similarly for fld1, fldz, fldpi etc. instead of any
9111debfc3dSmrg of the loads or for float extension from memory. */
9121debfc3dSmrg
9131debfc3dSmrg i1src = SET_SRC (i1set);
9141debfc3dSmrg if (GET_CODE (i1src) == FLOAT_EXTEND)
9151debfc3dSmrg i1src = XEXP (i1src, 0);
9161debfc3dSmrg if (REG_P (i1dest)
9171debfc3dSmrg && REGNO (i1dest) == FIRST_STACK_REG
9181debfc3dSmrg && (MEM_P (i1src) || GET_CODE (i1src) == CONST_DOUBLE)
9191debfc3dSmrg && !side_effects_p (i1src)
9201debfc3dSmrg && hard_regno == FIRST_STACK_REG + 1
9211debfc3dSmrg && i1 != BB_HEAD (current_block))
9221debfc3dSmrg {
9231debfc3dSmrg /* i1 is the last insn that involves stack regs before insn, and
9241debfc3dSmrg is known to be a load without other side-effects, i.e. fld b
9251debfc3dSmrg in the above comment. */
9261debfc3dSmrg rtx_insn *i2 = NULL;
9271debfc3dSmrg rtx i2set;
9281debfc3dSmrg rtx_insn *tmp = PREV_INSN (i1);
9291debfc3dSmrg rtx_insn *limit = PREV_INSN (BB_HEAD (current_block));
9301debfc3dSmrg /* Find the previous insn involving stack regs, but don't pass a
9311debfc3dSmrg block boundary. */
9321debfc3dSmrg while (tmp != limit)
9331debfc3dSmrg {
9341debfc3dSmrg if (LABEL_P (tmp)
9351debfc3dSmrg || CALL_P (tmp)
9361debfc3dSmrg || NOTE_INSN_BASIC_BLOCK_P (tmp)
9371debfc3dSmrg || (NONJUMP_INSN_P (tmp)
9381debfc3dSmrg && stack_regs_mentioned (tmp)))
9391debfc3dSmrg {
9401debfc3dSmrg i2 = tmp;
9411debfc3dSmrg break;
9421debfc3dSmrg }
9431debfc3dSmrg tmp = PREV_INSN (tmp);
9441debfc3dSmrg }
9451debfc3dSmrg if (i2 != NULL_RTX
9461debfc3dSmrg && (i2set = single_set (i2)) != NULL_RTX)
9471debfc3dSmrg {
9481debfc3dSmrg rtx i2dest = *get_true_reg (&SET_DEST (i2set));
9491debfc3dSmrg rtx i2src = SET_SRC (i2set);
9501debfc3dSmrg if (GET_CODE (i2src) == FLOAT_EXTEND)
9511debfc3dSmrg i2src = XEXP (i2src, 0);
9521debfc3dSmrg /* If the last two insns before insn that involve
9531debfc3dSmrg stack regs are loads, where the latter (i1)
9541debfc3dSmrg pushes onto the register stack and thus
9551debfc3dSmrg moves the value from the first load (i2) from
9561debfc3dSmrg %st to %st(1), consider swapping them. */
9571debfc3dSmrg if (REG_P (i2dest)
9581debfc3dSmrg && REGNO (i2dest) == FIRST_STACK_REG
9591debfc3dSmrg && (MEM_P (i2src) || GET_CODE (i2src) == CONST_DOUBLE)
9601debfc3dSmrg /* Ensure i2 doesn't have other side-effects. */
9611debfc3dSmrg && !side_effects_p (i2src)
9621debfc3dSmrg /* And that the two instructions can actually be
9631debfc3dSmrg swapped, i.e. there shouldn't be any stores
9641debfc3dSmrg in between i2 and i1 that might alias with
9651debfc3dSmrg the i1 memory, and the memory address can't
9661debfc3dSmrg use registers set in between i2 and i1. */
9671debfc3dSmrg && !modified_between_p (SET_SRC (i1set), i2, i1))
9681debfc3dSmrg {
9691debfc3dSmrg /* Move i1 (fld b above) right before i2 (fld a
9701debfc3dSmrg above. */
9711debfc3dSmrg remove_insn (i1);
9721debfc3dSmrg SET_PREV_INSN (i1) = NULL_RTX;
9731debfc3dSmrg SET_NEXT_INSN (i1) = NULL_RTX;
9741debfc3dSmrg set_block_for_insn (i1, NULL);
9751debfc3dSmrg emit_insn_before (i1, i2);
9761debfc3dSmrg return;
9771debfc3dSmrg }
9781debfc3dSmrg }
9791debfc3dSmrg }
9801debfc3dSmrg }
9811debfc3dSmrg
9821debfc3dSmrg /* Avoid emitting the swap if this is the first register stack insn
9831debfc3dSmrg of the current_block. Instead update the current_block's stack_in
9841debfc3dSmrg and let compensate edges take care of this for us. */
9851debfc3dSmrg if (current_block && starting_stack_p)
9861debfc3dSmrg {
9871debfc3dSmrg BLOCK_INFO (current_block)->stack_in = *regstack;
9881debfc3dSmrg starting_stack_p = false;
9891debfc3dSmrg return;
9901debfc3dSmrg }
9911debfc3dSmrg
992c0a68be4Smrg machine_mode raw_mode = reg_raw_mode[FIRST_STACK_REG];
993c0a68be4Smrg rtx op1 = FP_MODE_REG (hard_regno, raw_mode);
994c0a68be4Smrg rtx op2 = FP_MODE_REG (FIRST_STACK_REG, raw_mode);
995c0a68be4Smrg rtx swap_rtx
996c0a68be4Smrg = gen_rtx_PARALLEL (VOIDmode,
997c0a68be4Smrg gen_rtvec (2, gen_rtx_SET (op1, op2),
998c0a68be4Smrg gen_rtx_SET (op2, op1)));
9991debfc3dSmrg if (i1)
10001debfc3dSmrg emit_insn_after (swap_rtx, i1);
10011debfc3dSmrg else if (current_block)
10021debfc3dSmrg emit_insn_before (swap_rtx, BB_HEAD (current_block));
10031debfc3dSmrg else
10041debfc3dSmrg emit_insn_before (swap_rtx, insn);
10051debfc3dSmrg }
10061debfc3dSmrg
10071debfc3dSmrg /* Emit an insns before INSN to swap virtual register SRC1 with
10081debfc3dSmrg the top of stack and virtual register SRC2 with second stack
10091debfc3dSmrg slot. REGSTACK is the stack state before the swaps, and
10101debfc3dSmrg is updated to reflect the swaps. A swap insn is represented as a
10111debfc3dSmrg PARALLEL of two patterns: each pattern moves one reg to the other.
10121debfc3dSmrg
10131debfc3dSmrg If SRC1 and/or SRC2 are already at the right place, no swap insn
10141debfc3dSmrg is emitted. */
10151debfc3dSmrg
10161debfc3dSmrg static void
swap_to_top(rtx_insn * insn,stack_ptr regstack,rtx src1,rtx src2)10171debfc3dSmrg swap_to_top (rtx_insn *insn, stack_ptr regstack, rtx src1, rtx src2)
10181debfc3dSmrg {
10191debfc3dSmrg struct stack_def temp_stack;
10201debfc3dSmrg int regno, j, k;
10211debfc3dSmrg
10221debfc3dSmrg temp_stack = *regstack;
10231debfc3dSmrg
10241debfc3dSmrg /* Place operand 1 at the top of stack. */
10251debfc3dSmrg regno = get_hard_regnum (&temp_stack, src1);
10261debfc3dSmrg gcc_assert (regno >= 0);
10271debfc3dSmrg if (regno != FIRST_STACK_REG)
10281debfc3dSmrg {
10291debfc3dSmrg k = temp_stack.top - (regno - FIRST_STACK_REG);
10301debfc3dSmrg j = temp_stack.top;
10311debfc3dSmrg
10321debfc3dSmrg std::swap (temp_stack.reg[j], temp_stack.reg[k]);
10331debfc3dSmrg }
10341debfc3dSmrg
10351debfc3dSmrg /* Place operand 2 next on the stack. */
10361debfc3dSmrg regno = get_hard_regnum (&temp_stack, src2);
10371debfc3dSmrg gcc_assert (regno >= 0);
10381debfc3dSmrg if (regno != FIRST_STACK_REG + 1)
10391debfc3dSmrg {
10401debfc3dSmrg k = temp_stack.top - (regno - FIRST_STACK_REG);
10411debfc3dSmrg j = temp_stack.top - 1;
10421debfc3dSmrg
10431debfc3dSmrg std::swap (temp_stack.reg[j], temp_stack.reg[k]);
10441debfc3dSmrg }
10451debfc3dSmrg
10461debfc3dSmrg change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
10471debfc3dSmrg }
10481debfc3dSmrg
10491debfc3dSmrg /* Handle a move to or from a stack register in PAT, which is in INSN.
10501debfc3dSmrg REGSTACK is the current stack. Return whether a control flow insn
10511debfc3dSmrg was deleted in the process. */
10521debfc3dSmrg
10531debfc3dSmrg static bool
move_for_stack_reg(rtx_insn * insn,stack_ptr regstack,rtx pat)10541debfc3dSmrg move_for_stack_reg (rtx_insn *insn, stack_ptr regstack, rtx pat)
10551debfc3dSmrg {
10561debfc3dSmrg rtx *psrc = get_true_reg (&SET_SRC (pat));
10571debfc3dSmrg rtx *pdest = get_true_reg (&SET_DEST (pat));
10581debfc3dSmrg rtx src, dest;
10591debfc3dSmrg rtx note;
10601debfc3dSmrg bool control_flow_insn_deleted = false;
10611debfc3dSmrg
10621debfc3dSmrg src = *psrc; dest = *pdest;
10631debfc3dSmrg
10641debfc3dSmrg if (STACK_REG_P (src) && STACK_REG_P (dest))
10651debfc3dSmrg {
10661debfc3dSmrg /* Write from one stack reg to another. If SRC dies here, then
10671debfc3dSmrg just change the register mapping and delete the insn. */
10681debfc3dSmrg
10691debfc3dSmrg note = find_regno_note (insn, REG_DEAD, REGNO (src));
10701debfc3dSmrg if (note)
10711debfc3dSmrg {
10721debfc3dSmrg int i;
10731debfc3dSmrg
10741debfc3dSmrg /* If this is a no-op move, there must not be a REG_DEAD note. */
10751debfc3dSmrg gcc_assert (REGNO (src) != REGNO (dest));
10761debfc3dSmrg
10771debfc3dSmrg for (i = regstack->top; i >= 0; i--)
10781debfc3dSmrg if (regstack->reg[i] == REGNO (src))
10791debfc3dSmrg break;
10801debfc3dSmrg
10811debfc3dSmrg /* The destination must be dead, or life analysis is borked. */
10821debfc3dSmrg gcc_assert (get_hard_regnum (regstack, dest) < FIRST_STACK_REG);
10831debfc3dSmrg
10841debfc3dSmrg /* If the source is not live, this is yet another case of
10851debfc3dSmrg uninitialized variables. Load up a NaN instead. */
10861debfc3dSmrg if (i < 0)
10871debfc3dSmrg return move_nan_for_stack_reg (insn, regstack, dest);
10881debfc3dSmrg
10891debfc3dSmrg /* It is possible that the dest is unused after this insn.
10901debfc3dSmrg If so, just pop the src. */
10911debfc3dSmrg
10921debfc3dSmrg if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
10931debfc3dSmrg emit_pop_insn (insn, regstack, src, EMIT_AFTER);
10941debfc3dSmrg else
10951debfc3dSmrg {
10961debfc3dSmrg regstack->reg[i] = REGNO (dest);
10971debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
10981debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
10991debfc3dSmrg }
11001debfc3dSmrg
11011debfc3dSmrg control_flow_insn_deleted |= control_flow_insn_p (insn);
11021debfc3dSmrg delete_insn (insn);
11031debfc3dSmrg return control_flow_insn_deleted;
11041debfc3dSmrg }
11051debfc3dSmrg
11061debfc3dSmrg /* The source reg does not die. */
11071debfc3dSmrg
11081debfc3dSmrg /* If this appears to be a no-op move, delete it, or else it
11091debfc3dSmrg will confuse the machine description output patterns. But if
11101debfc3dSmrg it is REG_UNUSED, we must pop the reg now, as per-insn processing
11111debfc3dSmrg for REG_UNUSED will not work for deleted insns. */
11121debfc3dSmrg
11131debfc3dSmrg if (REGNO (src) == REGNO (dest))
11141debfc3dSmrg {
11151debfc3dSmrg if (find_regno_note (insn, REG_UNUSED, REGNO (dest)))
11161debfc3dSmrg emit_pop_insn (insn, regstack, dest, EMIT_AFTER);
11171debfc3dSmrg
11181debfc3dSmrg control_flow_insn_deleted |= control_flow_insn_p (insn);
11191debfc3dSmrg delete_insn (insn);
11201debfc3dSmrg return control_flow_insn_deleted;
11211debfc3dSmrg }
11221debfc3dSmrg
11231debfc3dSmrg /* The destination ought to be dead. */
1124a2dc1f3fSmrg if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
1125a2dc1f3fSmrg gcc_assert (any_malformed_asm);
1126a2dc1f3fSmrg else
1127a2dc1f3fSmrg {
11281debfc3dSmrg replace_reg (psrc, get_hard_regnum (regstack, src));
11291debfc3dSmrg
11301debfc3dSmrg regstack->reg[++regstack->top] = REGNO (dest);
11311debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
11321debfc3dSmrg replace_reg (pdest, FIRST_STACK_REG);
11331debfc3dSmrg }
1134a2dc1f3fSmrg }
11351debfc3dSmrg else if (STACK_REG_P (src))
11361debfc3dSmrg {
11371debfc3dSmrg /* Save from a stack reg to MEM, or possibly integer reg. Since
11381debfc3dSmrg only top of stack may be saved, emit an exchange first if
11391debfc3dSmrg needs be. */
11401debfc3dSmrg
11411debfc3dSmrg emit_swap_insn (insn, regstack, src);
11421debfc3dSmrg
11431debfc3dSmrg note = find_regno_note (insn, REG_DEAD, REGNO (src));
11441debfc3dSmrg if (note)
11451debfc3dSmrg {
11461debfc3dSmrg replace_reg (&XEXP (note, 0), FIRST_STACK_REG);
11471debfc3dSmrg regstack->top--;
11481debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (src));
11491debfc3dSmrg }
11501debfc3dSmrg else if ((GET_MODE (src) == XFmode)
11511debfc3dSmrg && regstack->top < REG_STACK_SIZE - 1)
11521debfc3dSmrg {
11531debfc3dSmrg /* A 387 cannot write an XFmode value to a MEM without
11541debfc3dSmrg clobbering the source reg. The output code can handle
11551debfc3dSmrg this by reading back the value from the MEM.
11561debfc3dSmrg But it is more efficient to use a temp register if one is
11571debfc3dSmrg available. Push the source value here if the register
11581debfc3dSmrg stack is not full, and then write the value to memory via
11591debfc3dSmrg a pop. */
11601debfc3dSmrg rtx push_rtx;
11611debfc3dSmrg rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, GET_MODE (src));
11621debfc3dSmrg
11631debfc3dSmrg push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
11641debfc3dSmrg emit_insn_before (push_rtx, insn);
11651debfc3dSmrg add_reg_note (insn, REG_DEAD, top_stack_reg);
11661debfc3dSmrg }
11671debfc3dSmrg
11681debfc3dSmrg replace_reg (psrc, FIRST_STACK_REG);
11691debfc3dSmrg }
11701debfc3dSmrg else
11711debfc3dSmrg {
11721debfc3dSmrg rtx pat = PATTERN (insn);
11731debfc3dSmrg
11741debfc3dSmrg gcc_assert (STACK_REG_P (dest));
11751debfc3dSmrg
11761debfc3dSmrg /* Load from MEM, or possibly integer REG or constant, into the
11771debfc3dSmrg stack regs. The actual target is always the top of the
11781debfc3dSmrg stack. The stack mapping is changed to reflect that DEST is
11791debfc3dSmrg now at top of stack. */
11801debfc3dSmrg
11811debfc3dSmrg /* The destination ought to be dead. However, there is a
11821debfc3dSmrg special case with i387 UNSPEC_TAN, where destination is live
11831debfc3dSmrg (an argument to fptan) but inherent load of 1.0 is modelled
11841debfc3dSmrg as a load from a constant. */
11851debfc3dSmrg if (GET_CODE (pat) == PARALLEL
11861debfc3dSmrg && XVECLEN (pat, 0) == 2
11871debfc3dSmrg && GET_CODE (XVECEXP (pat, 0, 1)) == SET
11881debfc3dSmrg && GET_CODE (SET_SRC (XVECEXP (pat, 0, 1))) == UNSPEC
11891debfc3dSmrg && XINT (SET_SRC (XVECEXP (pat, 0, 1)), 1) == UNSPEC_TAN)
11901debfc3dSmrg emit_swap_insn (insn, regstack, dest);
11911debfc3dSmrg else
1192a2dc1f3fSmrg gcc_assert (get_hard_regnum (regstack, dest) < FIRST_STACK_REG
1193a2dc1f3fSmrg || any_malformed_asm);
11941debfc3dSmrg
11951debfc3dSmrg gcc_assert (regstack->top < REG_STACK_SIZE);
11961debfc3dSmrg
11971debfc3dSmrg regstack->reg[++regstack->top] = REGNO (dest);
11981debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (dest));
11991debfc3dSmrg replace_reg (pdest, FIRST_STACK_REG);
12001debfc3dSmrg }
12011debfc3dSmrg
12021debfc3dSmrg return control_flow_insn_deleted;
12031debfc3dSmrg }
12041debfc3dSmrg
12051debfc3dSmrg /* A helper function which replaces INSN with a pattern that loads up
12061debfc3dSmrg a NaN into DEST, then invokes move_for_stack_reg. */
12071debfc3dSmrg
12081debfc3dSmrg static bool
move_nan_for_stack_reg(rtx_insn * insn,stack_ptr regstack,rtx dest)12091debfc3dSmrg move_nan_for_stack_reg (rtx_insn *insn, stack_ptr regstack, rtx dest)
12101debfc3dSmrg {
12111debfc3dSmrg rtx pat;
12121debfc3dSmrg
12131debfc3dSmrg dest = FP_MODE_REG (REGNO (dest), SFmode);
12141debfc3dSmrg pat = gen_rtx_SET (dest, not_a_num);
12151debfc3dSmrg PATTERN (insn) = pat;
12161debfc3dSmrg INSN_CODE (insn) = -1;
12171debfc3dSmrg
12181debfc3dSmrg return move_for_stack_reg (insn, regstack, pat);
12191debfc3dSmrg }
12201debfc3dSmrg
12211debfc3dSmrg /* Swap the condition on a branch, if there is one. Return true if we
12221debfc3dSmrg found a condition to swap. False if the condition was not used as
12231debfc3dSmrg such. */
12241debfc3dSmrg
12251debfc3dSmrg static int
swap_rtx_condition_1(rtx pat)12261debfc3dSmrg swap_rtx_condition_1 (rtx pat)
12271debfc3dSmrg {
12281debfc3dSmrg const char *fmt;
12291debfc3dSmrg int i, r = 0;
12301debfc3dSmrg
12311debfc3dSmrg if (COMPARISON_P (pat))
12321debfc3dSmrg {
12331debfc3dSmrg PUT_CODE (pat, swap_condition (GET_CODE (pat)));
12341debfc3dSmrg r = 1;
12351debfc3dSmrg }
12361debfc3dSmrg else
12371debfc3dSmrg {
12381debfc3dSmrg fmt = GET_RTX_FORMAT (GET_CODE (pat));
12391debfc3dSmrg for (i = GET_RTX_LENGTH (GET_CODE (pat)) - 1; i >= 0; i--)
12401debfc3dSmrg {
12411debfc3dSmrg if (fmt[i] == 'E')
12421debfc3dSmrg {
12431debfc3dSmrg int j;
12441debfc3dSmrg
12451debfc3dSmrg for (j = XVECLEN (pat, i) - 1; j >= 0; j--)
12461debfc3dSmrg r |= swap_rtx_condition_1 (XVECEXP (pat, i, j));
12471debfc3dSmrg }
12481debfc3dSmrg else if (fmt[i] == 'e')
12491debfc3dSmrg r |= swap_rtx_condition_1 (XEXP (pat, i));
12501debfc3dSmrg }
12511debfc3dSmrg }
12521debfc3dSmrg
12531debfc3dSmrg return r;
12541debfc3dSmrg }
12551debfc3dSmrg
1256*23f5f463Smrg /* This function swaps condition in cc users and returns true
1257*23f5f463Smrg if successful. It is invoked in 2 different modes, one with
1258*23f5f463Smrg DEBUG_SEEN set initially to 0. In this mode, next_flags_user
1259*23f5f463Smrg will skip DEBUG_INSNs that it would otherwise return and just
1260*23f5f463Smrg sets DEBUG_SEEN to 1 in that case. If DEBUG_SEEN is 0 at
1261*23f5f463Smrg the end of toplevel swap_rtx_condition which returns true,
1262*23f5f463Smrg it means no problematic DEBUG_INSNs were seen and all changes
1263*23f5f463Smrg have been applied. If it returns true but DEBUG_SEEN is 1,
1264*23f5f463Smrg it means some problematic DEBUG_INSNs were seen and no changes
1265*23f5f463Smrg have been applied so far. In that case one needs to call
1266*23f5f463Smrg swap_rtx_condition again with DEBUG_SEEN set to -1, in which
1267*23f5f463Smrg case it doesn't skip DEBUG_INSNs, but instead adjusts the
1268*23f5f463Smrg flags related condition in them or resets them as needed. */
1269*23f5f463Smrg
12701debfc3dSmrg static int
swap_rtx_condition(rtx_insn * insn,int & debug_seen)1271*23f5f463Smrg swap_rtx_condition (rtx_insn *insn, int &debug_seen)
12721debfc3dSmrg {
12731debfc3dSmrg rtx pat = PATTERN (insn);
12741debfc3dSmrg
12751debfc3dSmrg /* We're looking for a single set to cc0 or an HImode temporary. */
12761debfc3dSmrg
12771debfc3dSmrg if (GET_CODE (pat) == SET
12781debfc3dSmrg && REG_P (SET_DEST (pat))
12791debfc3dSmrg && REGNO (SET_DEST (pat)) == FLAGS_REG)
12801debfc3dSmrg {
1281*23f5f463Smrg insn = next_flags_user (insn, debug_seen);
12821debfc3dSmrg if (insn == NULL_RTX)
12831debfc3dSmrg return 0;
12841debfc3dSmrg pat = PATTERN (insn);
12851debfc3dSmrg }
12861debfc3dSmrg
12871debfc3dSmrg /* See if this is, or ends in, a fnstsw. If so, we're not doing anything
12881debfc3dSmrg with the cc value right now. We may be able to search for one
12891debfc3dSmrg though. */
12901debfc3dSmrg
12911debfc3dSmrg if (GET_CODE (pat) == SET
12921debfc3dSmrg && GET_CODE (SET_SRC (pat)) == UNSPEC
12931debfc3dSmrg && XINT (SET_SRC (pat), 1) == UNSPEC_FNSTSW)
12941debfc3dSmrg {
12951debfc3dSmrg rtx dest = SET_DEST (pat);
12961debfc3dSmrg
12971debfc3dSmrg /* Search forward looking for the first use of this value.
12981debfc3dSmrg Stop at block boundaries. */
12991debfc3dSmrg while (insn != BB_END (current_block))
13001debfc3dSmrg {
13011debfc3dSmrg insn = NEXT_INSN (insn);
13021debfc3dSmrg if (INSN_P (insn) && reg_mentioned_p (dest, insn))
1303*23f5f463Smrg {
1304*23f5f463Smrg if (DEBUG_INSN_P (insn))
1305*23f5f463Smrg {
1306*23f5f463Smrg if (debug_seen >= 0)
1307*23f5f463Smrg debug_seen = 1;
1308*23f5f463Smrg else
1309*23f5f463Smrg /* Reset the DEBUG insn otherwise. */
1310*23f5f463Smrg INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
1311*23f5f463Smrg continue;
1312*23f5f463Smrg }
13131debfc3dSmrg break;
1314*23f5f463Smrg }
13151debfc3dSmrg if (CALL_P (insn))
13161debfc3dSmrg return 0;
13171debfc3dSmrg }
13181debfc3dSmrg
13191debfc3dSmrg /* We haven't found it. */
13201debfc3dSmrg if (insn == BB_END (current_block))
13211debfc3dSmrg return 0;
13221debfc3dSmrg
13231debfc3dSmrg /* So we've found the insn using this value. If it is anything
13241debfc3dSmrg other than sahf or the value does not die (meaning we'd have
13251debfc3dSmrg to search further), then we must give up. */
13261debfc3dSmrg pat = PATTERN (insn);
13271debfc3dSmrg if (GET_CODE (pat) != SET
13281debfc3dSmrg || GET_CODE (SET_SRC (pat)) != UNSPEC
13291debfc3dSmrg || XINT (SET_SRC (pat), 1) != UNSPEC_SAHF
13301debfc3dSmrg || ! dead_or_set_p (insn, dest))
13311debfc3dSmrg return 0;
13321debfc3dSmrg
13331debfc3dSmrg /* Now we are prepared to handle this as a normal cc0 setter. */
1334*23f5f463Smrg insn = next_flags_user (insn, debug_seen);
13351debfc3dSmrg if (insn == NULL_RTX)
13361debfc3dSmrg return 0;
13371debfc3dSmrg pat = PATTERN (insn);
13381debfc3dSmrg }
13391debfc3dSmrg
13401debfc3dSmrg if (swap_rtx_condition_1 (pat))
13411debfc3dSmrg {
13421debfc3dSmrg int fail = 0;
1343*23f5f463Smrg if (DEBUG_INSN_P (insn))
1344*23f5f463Smrg gcc_assert (debug_seen < 0);
1345*23f5f463Smrg else
1346*23f5f463Smrg {
13471debfc3dSmrg INSN_CODE (insn) = -1;
13481debfc3dSmrg if (recog_memoized (insn) == -1)
13491debfc3dSmrg fail = 1;
1350*23f5f463Smrg }
13511debfc3dSmrg /* In case the flags don't die here, recurse to try fix
13521debfc3dSmrg following user too. */
1353*23f5f463Smrg if (!fail && !dead_or_set_p (insn, ix86_flags_rtx))
13541debfc3dSmrg {
1355*23f5f463Smrg insn = next_flags_user (insn, debug_seen);
1356*23f5f463Smrg if (!insn || !swap_rtx_condition (insn, debug_seen))
13571debfc3dSmrg fail = 1;
13581debfc3dSmrg }
1359*23f5f463Smrg if (fail || debug_seen == 1)
13601debfc3dSmrg swap_rtx_condition_1 (pat);
1361*23f5f463Smrg return !fail;
13621debfc3dSmrg }
13631debfc3dSmrg return 0;
13641debfc3dSmrg }
13651debfc3dSmrg
13661debfc3dSmrg /* Handle a comparison. Special care needs to be taken to avoid
13671debfc3dSmrg causing comparisons that a 387 cannot do correctly, such as EQ.
13681debfc3dSmrg
13691debfc3dSmrg Also, a pop insn may need to be emitted. The 387 does have an
13701debfc3dSmrg `fcompp' insn that can pop two regs, but it is sometimes too expensive
13711debfc3dSmrg to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to
13721debfc3dSmrg set up. */
13731debfc3dSmrg
13741debfc3dSmrg static void
compare_for_stack_reg(rtx_insn * insn,stack_ptr regstack,rtx pat_src,bool can_pop_second_op)1375a2dc1f3fSmrg compare_for_stack_reg (rtx_insn *insn, stack_ptr regstack,
1376a2dc1f3fSmrg rtx pat_src, bool can_pop_second_op)
13771debfc3dSmrg {
13781debfc3dSmrg rtx *src1, *src2;
13791debfc3dSmrg rtx src1_note, src2_note;
1380*23f5f463Smrg int debug_seen = 0;
13811debfc3dSmrg
13821debfc3dSmrg src1 = get_true_reg (&XEXP (pat_src, 0));
13831debfc3dSmrg src2 = get_true_reg (&XEXP (pat_src, 1));
13841debfc3dSmrg
13851debfc3dSmrg /* ??? If fxch turns out to be cheaper than fstp, give priority to
13861debfc3dSmrg registers that die in this insn - move those to stack top first. */
13871debfc3dSmrg if ((! STACK_REG_P (*src1)
13881debfc3dSmrg || (STACK_REG_P (*src2)
13891debfc3dSmrg && get_hard_regnum (regstack, *src2) == FIRST_STACK_REG))
1390*23f5f463Smrg && swap_rtx_condition (insn, debug_seen))
13911debfc3dSmrg {
1392*23f5f463Smrg /* If swap_rtx_condition succeeded but some debug insns
1393*23f5f463Smrg were seen along the way, it has actually reverted all the
1394*23f5f463Smrg changes. Rerun swap_rtx_condition in a mode where DEBUG_ISNSs
1395*23f5f463Smrg will be adjusted as well. */
1396*23f5f463Smrg if (debug_seen)
1397*23f5f463Smrg {
1398*23f5f463Smrg debug_seen = -1;
1399*23f5f463Smrg swap_rtx_condition (insn, debug_seen);
1400*23f5f463Smrg }
14011debfc3dSmrg std::swap (XEXP (pat_src, 0), XEXP (pat_src, 1));
14021debfc3dSmrg
14031debfc3dSmrg src1 = get_true_reg (&XEXP (pat_src, 0));
14041debfc3dSmrg src2 = get_true_reg (&XEXP (pat_src, 1));
14051debfc3dSmrg
14061debfc3dSmrg INSN_CODE (insn) = -1;
14071debfc3dSmrg }
14081debfc3dSmrg
14091debfc3dSmrg /* We will fix any death note later. */
14101debfc3dSmrg
14111debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
14121debfc3dSmrg
14131debfc3dSmrg if (STACK_REG_P (*src2))
14141debfc3dSmrg src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
14151debfc3dSmrg else
14161debfc3dSmrg src2_note = NULL_RTX;
14171debfc3dSmrg
14181debfc3dSmrg emit_swap_insn (insn, regstack, *src1);
14191debfc3dSmrg
14201debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
14211debfc3dSmrg
14221debfc3dSmrg if (STACK_REG_P (*src2))
14231debfc3dSmrg replace_reg (src2, get_hard_regnum (regstack, *src2));
14241debfc3dSmrg
14251debfc3dSmrg if (src1_note)
14261debfc3dSmrg {
1427a2dc1f3fSmrg if (*src2 == CONST0_RTX (GET_MODE (*src2)))
1428a2dc1f3fSmrg {
1429a2dc1f3fSmrg /* This is `ftst' insn that can't pop register. */
1430a2dc1f3fSmrg remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src1_note, 0)));
1431a2dc1f3fSmrg emit_pop_insn (insn, regstack, XEXP (src1_note, 0),
1432a2dc1f3fSmrg EMIT_AFTER);
1433a2dc1f3fSmrg }
1434a2dc1f3fSmrg else
1435a2dc1f3fSmrg {
14361debfc3dSmrg pop_stack (regstack, REGNO (XEXP (src1_note, 0)));
14371debfc3dSmrg replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
14381debfc3dSmrg }
1439a2dc1f3fSmrg }
14401debfc3dSmrg
14411debfc3dSmrg /* If the second operand dies, handle that. But if the operands are
14421debfc3dSmrg the same stack register, don't bother, because only one death is
14431debfc3dSmrg needed, and it was just handled. */
14441debfc3dSmrg
14451debfc3dSmrg if (src2_note
14461debfc3dSmrg && ! (STACK_REG_P (*src1) && STACK_REG_P (*src2)
14471debfc3dSmrg && REGNO (*src1) == REGNO (*src2)))
14481debfc3dSmrg {
14491debfc3dSmrg /* As a special case, two regs may die in this insn if src2 is
14501debfc3dSmrg next to top of stack and the top of stack also dies. Since
14511debfc3dSmrg we have already popped src1, "next to top of stack" is really
14521debfc3dSmrg at top (FIRST_STACK_REG) now. */
14531debfc3dSmrg
14541debfc3dSmrg if (get_hard_regnum (regstack, XEXP (src2_note, 0)) == FIRST_STACK_REG
1455a2dc1f3fSmrg && src1_note && can_pop_second_op)
14561debfc3dSmrg {
14571debfc3dSmrg pop_stack (regstack, REGNO (XEXP (src2_note, 0)));
14581debfc3dSmrg replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
14591debfc3dSmrg }
14601debfc3dSmrg else
14611debfc3dSmrg {
14621debfc3dSmrg /* The 386 can only represent death of the first operand in
14631debfc3dSmrg the case handled above. In all other cases, emit a separate
14641debfc3dSmrg pop and remove the death note from here. */
14651debfc3dSmrg remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0)));
14661debfc3dSmrg emit_pop_insn (insn, regstack, XEXP (src2_note, 0),
14671debfc3dSmrg EMIT_AFTER);
14681debfc3dSmrg }
14691debfc3dSmrg }
14701debfc3dSmrg }
14711debfc3dSmrg
14721debfc3dSmrg /* Substitute hardware stack regs in debug insn INSN, using stack
14731debfc3dSmrg layout REGSTACK. If we can't find a hardware stack reg for any of
14741debfc3dSmrg the REGs in it, reset the debug insn. */
14751debfc3dSmrg
14761debfc3dSmrg static void
subst_all_stack_regs_in_debug_insn(rtx_insn * insn,struct stack_def * regstack)14771debfc3dSmrg subst_all_stack_regs_in_debug_insn (rtx_insn *insn, struct stack_def *regstack)
14781debfc3dSmrg {
14791debfc3dSmrg subrtx_ptr_iterator::array_type array;
14801debfc3dSmrg FOR_EACH_SUBRTX_PTR (iter, array, &INSN_VAR_LOCATION_LOC (insn), NONCONST)
14811debfc3dSmrg {
14821debfc3dSmrg rtx *loc = *iter;
14831debfc3dSmrg rtx x = *loc;
14841debfc3dSmrg if (STACK_REG_P (x))
14851debfc3dSmrg {
14861debfc3dSmrg int hard_regno = get_hard_regnum (regstack, x);
14871debfc3dSmrg
14881debfc3dSmrg /* If we can't find an active register, reset this debug insn. */
14891debfc3dSmrg if (hard_regno == -1)
14901debfc3dSmrg {
14911debfc3dSmrg INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
14921debfc3dSmrg return;
14931debfc3dSmrg }
14941debfc3dSmrg
14951debfc3dSmrg gcc_assert (hard_regno >= FIRST_STACK_REG);
14961debfc3dSmrg replace_reg (loc, hard_regno);
14971debfc3dSmrg iter.skip_subrtxes ();
14981debfc3dSmrg }
14991debfc3dSmrg }
15001debfc3dSmrg }
15011debfc3dSmrg
15021debfc3dSmrg /* Substitute new registers in PAT, which is part of INSN. REGSTACK
15031debfc3dSmrg is the current register layout. Return whether a control flow insn
15041debfc3dSmrg was deleted in the process. */
15051debfc3dSmrg
15061debfc3dSmrg static bool
subst_stack_regs_pat(rtx_insn * insn,stack_ptr regstack,rtx pat)15071debfc3dSmrg subst_stack_regs_pat (rtx_insn *insn, stack_ptr regstack, rtx pat)
15081debfc3dSmrg {
15091debfc3dSmrg rtx *dest, *src;
15101debfc3dSmrg bool control_flow_insn_deleted = false;
15111debfc3dSmrg
15121debfc3dSmrg switch (GET_CODE (pat))
15131debfc3dSmrg {
15141debfc3dSmrg case USE:
15151debfc3dSmrg /* Deaths in USE insns can happen in non optimizing compilation.
15161debfc3dSmrg Handle them by popping the dying register. */
15171debfc3dSmrg src = get_true_reg (&XEXP (pat, 0));
15181debfc3dSmrg if (STACK_REG_P (*src)
15191debfc3dSmrg && find_regno_note (insn, REG_DEAD, REGNO (*src)))
15201debfc3dSmrg {
15211debfc3dSmrg /* USEs are ignored for liveness information so USEs of dead
15221debfc3dSmrg register might happen. */
15231debfc3dSmrg if (TEST_HARD_REG_BIT (regstack->reg_set, REGNO (*src)))
15241debfc3dSmrg emit_pop_insn (insn, regstack, *src, EMIT_AFTER);
15251debfc3dSmrg return control_flow_insn_deleted;
15261debfc3dSmrg }
15271debfc3dSmrg /* Uninitialized USE might happen for functions returning uninitialized
15281debfc3dSmrg value. We will properly initialize the USE on the edge to EXIT_BLOCK,
15291debfc3dSmrg so it is safe to ignore the use here. This is consistent with behavior
15301debfc3dSmrg of dataflow analyzer that ignores USE too. (This also imply that
15311debfc3dSmrg forcibly initializing the register to NaN here would lead to ICE later,
15321debfc3dSmrg since the REG_DEAD notes are not issued.) */
15331debfc3dSmrg break;
15341debfc3dSmrg
15351debfc3dSmrg case VAR_LOCATION:
15361debfc3dSmrg gcc_unreachable ();
15371debfc3dSmrg
15381debfc3dSmrg case CLOBBER:
15391debfc3dSmrg {
15401debfc3dSmrg rtx note;
15411debfc3dSmrg
15421debfc3dSmrg dest = get_true_reg (&XEXP (pat, 0));
15431debfc3dSmrg if (STACK_REG_P (*dest))
15441debfc3dSmrg {
15451debfc3dSmrg note = find_reg_note (insn, REG_DEAD, *dest);
15461debfc3dSmrg
15471debfc3dSmrg if (pat != PATTERN (insn))
15481debfc3dSmrg {
15491debfc3dSmrg /* The fix_truncdi_1 pattern wants to be able to
15501debfc3dSmrg allocate its own scratch register. It does this by
15511debfc3dSmrg clobbering an fp reg so that it is assured of an
15521debfc3dSmrg empty reg-stack register. If the register is live,
15531debfc3dSmrg kill it now. Remove the DEAD/UNUSED note so we
15541debfc3dSmrg don't try to kill it later too.
15551debfc3dSmrg
15561debfc3dSmrg In reality the UNUSED note can be absent in some
15571debfc3dSmrg complicated cases when the register is reused for
15581debfc3dSmrg partially set variable. */
15591debfc3dSmrg
15601debfc3dSmrg if (note)
15611debfc3dSmrg emit_pop_insn (insn, regstack, *dest, EMIT_BEFORE);
15621debfc3dSmrg else
15631debfc3dSmrg note = find_reg_note (insn, REG_UNUSED, *dest);
15641debfc3dSmrg if (note)
15651debfc3dSmrg remove_note (insn, note);
15661debfc3dSmrg replace_reg (dest, FIRST_STACK_REG + 1);
15671debfc3dSmrg }
15681debfc3dSmrg else
15691debfc3dSmrg {
15701debfc3dSmrg /* A top-level clobber with no REG_DEAD, and no hard-regnum
15711debfc3dSmrg indicates an uninitialized value. Because reload removed
15721debfc3dSmrg all other clobbers, this must be due to a function
15731debfc3dSmrg returning without a value. Load up a NaN. */
15741debfc3dSmrg
15751debfc3dSmrg if (!note)
15761debfc3dSmrg {
15771debfc3dSmrg rtx t = *dest;
15781debfc3dSmrg if (COMPLEX_MODE_P (GET_MODE (t)))
15791debfc3dSmrg {
15801debfc3dSmrg rtx u = FP_MODE_REG (REGNO (t) + 1, SFmode);
15811debfc3dSmrg if (get_hard_regnum (regstack, u) == -1)
15821debfc3dSmrg {
15831debfc3dSmrg rtx pat2 = gen_rtx_CLOBBER (VOIDmode, u);
15841debfc3dSmrg rtx_insn *insn2 = emit_insn_before (pat2, insn);
15851debfc3dSmrg control_flow_insn_deleted
15861debfc3dSmrg |= move_nan_for_stack_reg (insn2, regstack, u);
15871debfc3dSmrg }
15881debfc3dSmrg }
15891debfc3dSmrg if (get_hard_regnum (regstack, t) == -1)
15901debfc3dSmrg control_flow_insn_deleted
15911debfc3dSmrg |= move_nan_for_stack_reg (insn, regstack, t);
15921debfc3dSmrg }
15931debfc3dSmrg }
15941debfc3dSmrg }
15951debfc3dSmrg break;
15961debfc3dSmrg }
15971debfc3dSmrg
15981debfc3dSmrg case SET:
15991debfc3dSmrg {
16001debfc3dSmrg rtx *src1 = (rtx *) 0, *src2;
16011debfc3dSmrg rtx src1_note, src2_note;
16021debfc3dSmrg rtx pat_src;
16031debfc3dSmrg
16041debfc3dSmrg dest = get_true_reg (&SET_DEST (pat));
16051debfc3dSmrg src = get_true_reg (&SET_SRC (pat));
16061debfc3dSmrg pat_src = SET_SRC (pat);
16071debfc3dSmrg
16081debfc3dSmrg /* See if this is a `movM' pattern, and handle elsewhere if so. */
16091debfc3dSmrg if (STACK_REG_P (*src)
16101debfc3dSmrg || (STACK_REG_P (*dest)
16111debfc3dSmrg && (REG_P (*src) || MEM_P (*src)
16121debfc3dSmrg || CONST_DOUBLE_P (*src))))
16131debfc3dSmrg {
16141debfc3dSmrg control_flow_insn_deleted |= move_for_stack_reg (insn, regstack, pat);
16151debfc3dSmrg break;
16161debfc3dSmrg }
16171debfc3dSmrg
16181debfc3dSmrg switch (GET_CODE (pat_src))
16191debfc3dSmrg {
16201debfc3dSmrg case CALL:
16211debfc3dSmrg {
16221debfc3dSmrg int count;
16231debfc3dSmrg for (count = REG_NREGS (*dest); --count >= 0;)
16241debfc3dSmrg {
16251debfc3dSmrg regstack->reg[++regstack->top] = REGNO (*dest) + count;
16261debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest) + count);
16271debfc3dSmrg }
16281debfc3dSmrg }
16291debfc3dSmrg replace_reg (dest, FIRST_STACK_REG);
16301debfc3dSmrg break;
16311debfc3dSmrg
16321debfc3dSmrg case REG:
16331debfc3dSmrg /* This is a `tstM2' case. */
16341debfc3dSmrg gcc_assert (*dest == cc0_rtx);
16351debfc3dSmrg src1 = src;
16361debfc3dSmrg
16371debfc3dSmrg /* Fall through. */
16381debfc3dSmrg
16391debfc3dSmrg case FLOAT_TRUNCATE:
16401debfc3dSmrg case SQRT:
16411debfc3dSmrg case ABS:
16421debfc3dSmrg case NEG:
16431debfc3dSmrg /* These insns only operate on the top of the stack. DEST might
16441debfc3dSmrg be cc0_rtx if we're processing a tstM pattern. Also, it's
16451debfc3dSmrg possible that the tstM case results in a REG_DEAD note on the
16461debfc3dSmrg source. */
16471debfc3dSmrg
16481debfc3dSmrg if (src1 == 0)
16491debfc3dSmrg src1 = get_true_reg (&XEXP (pat_src, 0));
16501debfc3dSmrg
16511debfc3dSmrg emit_swap_insn (insn, regstack, *src1);
16521debfc3dSmrg
16531debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
16541debfc3dSmrg
16551debfc3dSmrg if (STACK_REG_P (*dest))
16561debfc3dSmrg replace_reg (dest, FIRST_STACK_REG);
16571debfc3dSmrg
16581debfc3dSmrg if (src1_note)
16591debfc3dSmrg {
16601debfc3dSmrg replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
16611debfc3dSmrg regstack->top--;
16621debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
16631debfc3dSmrg }
16641debfc3dSmrg
16651debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
16661debfc3dSmrg break;
16671debfc3dSmrg
16681debfc3dSmrg case MINUS:
16691debfc3dSmrg case DIV:
16701debfc3dSmrg /* On i386, reversed forms of subM3 and divM3 exist for
16711debfc3dSmrg MODE_FLOAT, so the same code that works for addM3 and mulM3
16721debfc3dSmrg can be used. */
16731debfc3dSmrg case MULT:
16741debfc3dSmrg case PLUS:
16751debfc3dSmrg /* These insns can accept the top of stack as a destination
16761debfc3dSmrg from a stack reg or mem, or can use the top of stack as a
16771debfc3dSmrg source and some other stack register (possibly top of stack)
16781debfc3dSmrg as a destination. */
16791debfc3dSmrg
16801debfc3dSmrg src1 = get_true_reg (&XEXP (pat_src, 0));
16811debfc3dSmrg src2 = get_true_reg (&XEXP (pat_src, 1));
16821debfc3dSmrg
16831debfc3dSmrg /* We will fix any death note later. */
16841debfc3dSmrg
16851debfc3dSmrg if (STACK_REG_P (*src1))
16861debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
16871debfc3dSmrg else
16881debfc3dSmrg src1_note = NULL_RTX;
16891debfc3dSmrg if (STACK_REG_P (*src2))
16901debfc3dSmrg src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
16911debfc3dSmrg else
16921debfc3dSmrg src2_note = NULL_RTX;
16931debfc3dSmrg
16941debfc3dSmrg /* If either operand is not a stack register, then the dest
16951debfc3dSmrg must be top of stack. */
16961debfc3dSmrg
16971debfc3dSmrg if (! STACK_REG_P (*src1) || ! STACK_REG_P (*src2))
16981debfc3dSmrg emit_swap_insn (insn, regstack, *dest);
16991debfc3dSmrg else
17001debfc3dSmrg {
17011debfc3dSmrg /* Both operands are REG. If neither operand is already
17021debfc3dSmrg at the top of stack, choose to make the one that is the
17031debfc3dSmrg dest the new top of stack. */
17041debfc3dSmrg
17051debfc3dSmrg int src1_hard_regnum, src2_hard_regnum;
17061debfc3dSmrg
17071debfc3dSmrg src1_hard_regnum = get_hard_regnum (regstack, *src1);
17081debfc3dSmrg src2_hard_regnum = get_hard_regnum (regstack, *src2);
17091debfc3dSmrg
17101debfc3dSmrg /* If the source is not live, this is yet another case of
17111debfc3dSmrg uninitialized variables. Load up a NaN instead. */
17121debfc3dSmrg if (src1_hard_regnum == -1)
17131debfc3dSmrg {
17141debfc3dSmrg rtx pat2 = gen_rtx_CLOBBER (VOIDmode, *src1);
17151debfc3dSmrg rtx_insn *insn2 = emit_insn_before (pat2, insn);
17161debfc3dSmrg control_flow_insn_deleted
17171debfc3dSmrg |= move_nan_for_stack_reg (insn2, regstack, *src1);
17181debfc3dSmrg }
17191debfc3dSmrg if (src2_hard_regnum == -1)
17201debfc3dSmrg {
17211debfc3dSmrg rtx pat2 = gen_rtx_CLOBBER (VOIDmode, *src2);
17221debfc3dSmrg rtx_insn *insn2 = emit_insn_before (pat2, insn);
17231debfc3dSmrg control_flow_insn_deleted
17241debfc3dSmrg |= move_nan_for_stack_reg (insn2, regstack, *src2);
17251debfc3dSmrg }
17261debfc3dSmrg
17271debfc3dSmrg if (src1_hard_regnum != FIRST_STACK_REG
17281debfc3dSmrg && src2_hard_regnum != FIRST_STACK_REG)
17291debfc3dSmrg emit_swap_insn (insn, regstack, *dest);
17301debfc3dSmrg }
17311debfc3dSmrg
17321debfc3dSmrg if (STACK_REG_P (*src1))
17331debfc3dSmrg replace_reg (src1, get_hard_regnum (regstack, *src1));
17341debfc3dSmrg if (STACK_REG_P (*src2))
17351debfc3dSmrg replace_reg (src2, get_hard_regnum (regstack, *src2));
17361debfc3dSmrg
17371debfc3dSmrg if (src1_note)
17381debfc3dSmrg {
17391debfc3dSmrg rtx src1_reg = XEXP (src1_note, 0);
17401debfc3dSmrg
17411debfc3dSmrg /* If the register that dies is at the top of stack, then
17421debfc3dSmrg the destination is somewhere else - merely substitute it.
17431debfc3dSmrg But if the reg that dies is not at top of stack, then
17441debfc3dSmrg move the top of stack to the dead reg, as though we had
17451debfc3dSmrg done the insn and then a store-with-pop. */
17461debfc3dSmrg
17471debfc3dSmrg if (REGNO (src1_reg) == regstack->reg[regstack->top])
17481debfc3dSmrg {
17491debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
17501debfc3dSmrg replace_reg (dest, get_hard_regnum (regstack, *dest));
17511debfc3dSmrg }
17521debfc3dSmrg else
17531debfc3dSmrg {
17541debfc3dSmrg int regno = get_hard_regnum (regstack, src1_reg);
17551debfc3dSmrg
17561debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
17571debfc3dSmrg replace_reg (dest, regno);
17581debfc3dSmrg
17591debfc3dSmrg regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
17601debfc3dSmrg = regstack->reg[regstack->top];
17611debfc3dSmrg }
17621debfc3dSmrg
17631debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set,
17641debfc3dSmrg REGNO (XEXP (src1_note, 0)));
17651debfc3dSmrg replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
17661debfc3dSmrg regstack->top--;
17671debfc3dSmrg }
17681debfc3dSmrg else if (src2_note)
17691debfc3dSmrg {
17701debfc3dSmrg rtx src2_reg = XEXP (src2_note, 0);
17711debfc3dSmrg if (REGNO (src2_reg) == regstack->reg[regstack->top])
17721debfc3dSmrg {
17731debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
17741debfc3dSmrg replace_reg (dest, get_hard_regnum (regstack, *dest));
17751debfc3dSmrg }
17761debfc3dSmrg else
17771debfc3dSmrg {
17781debfc3dSmrg int regno = get_hard_regnum (regstack, src2_reg);
17791debfc3dSmrg
17801debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
17811debfc3dSmrg replace_reg (dest, regno);
17821debfc3dSmrg
17831debfc3dSmrg regstack->reg[regstack->top - (regno - FIRST_STACK_REG)]
17841debfc3dSmrg = regstack->reg[regstack->top];
17851debfc3dSmrg }
17861debfc3dSmrg
17871debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set,
17881debfc3dSmrg REGNO (XEXP (src2_note, 0)));
17891debfc3dSmrg replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG);
17901debfc3dSmrg regstack->top--;
17911debfc3dSmrg }
17921debfc3dSmrg else
17931debfc3dSmrg {
17941debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
17951debfc3dSmrg replace_reg (dest, get_hard_regnum (regstack, *dest));
17961debfc3dSmrg }
17971debfc3dSmrg
17981debfc3dSmrg /* Keep operand 1 matching with destination. */
17991debfc3dSmrg if (COMMUTATIVE_ARITH_P (pat_src)
18001debfc3dSmrg && REG_P (*src1) && REG_P (*src2)
18011debfc3dSmrg && REGNO (*src1) != REGNO (*dest))
18021debfc3dSmrg {
18031debfc3dSmrg int tmp = REGNO (*src1);
18041debfc3dSmrg replace_reg (src1, REGNO (*src2));
18051debfc3dSmrg replace_reg (src2, tmp);
18061debfc3dSmrg }
18071debfc3dSmrg break;
18081debfc3dSmrg
18091debfc3dSmrg case UNSPEC:
18101debfc3dSmrg switch (XINT (pat_src, 1))
18111debfc3dSmrg {
18121debfc3dSmrg case UNSPEC_FIST:
18131debfc3dSmrg case UNSPEC_FIST_ATOMIC:
18141debfc3dSmrg
18151debfc3dSmrg case UNSPEC_FIST_FLOOR:
18161debfc3dSmrg case UNSPEC_FIST_CEIL:
18171debfc3dSmrg
18181debfc3dSmrg /* These insns only operate on the top of the stack. */
18191debfc3dSmrg
18201debfc3dSmrg src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
18211debfc3dSmrg emit_swap_insn (insn, regstack, *src1);
18221debfc3dSmrg
18231debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
18241debfc3dSmrg
18251debfc3dSmrg if (STACK_REG_P (*dest))
18261debfc3dSmrg replace_reg (dest, FIRST_STACK_REG);
18271debfc3dSmrg
18281debfc3dSmrg if (src1_note)
18291debfc3dSmrg {
18301debfc3dSmrg replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
18311debfc3dSmrg regstack->top--;
18321debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
18331debfc3dSmrg }
18341debfc3dSmrg
18351debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
18361debfc3dSmrg break;
18371debfc3dSmrg
18381debfc3dSmrg case UNSPEC_FXAM:
18391debfc3dSmrg
18401debfc3dSmrg /* This insn only operate on the top of the stack. */
18411debfc3dSmrg
18421debfc3dSmrg src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
18431debfc3dSmrg emit_swap_insn (insn, regstack, *src1);
18441debfc3dSmrg
18451debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
18461debfc3dSmrg
18471debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
18481debfc3dSmrg
18491debfc3dSmrg if (src1_note)
18501debfc3dSmrg {
18511debfc3dSmrg remove_regno_note (insn, REG_DEAD,
18521debfc3dSmrg REGNO (XEXP (src1_note, 0)));
18531debfc3dSmrg emit_pop_insn (insn, regstack, XEXP (src1_note, 0),
18541debfc3dSmrg EMIT_AFTER);
18551debfc3dSmrg }
18561debfc3dSmrg
18571debfc3dSmrg break;
18581debfc3dSmrg
18591debfc3dSmrg case UNSPEC_SIN:
18601debfc3dSmrg case UNSPEC_COS:
18611debfc3dSmrg case UNSPEC_FRNDINT:
18621debfc3dSmrg case UNSPEC_F2XM1:
18631debfc3dSmrg
18648feb0f0bSmrg case UNSPEC_FRNDINT_ROUNDEVEN:
18651debfc3dSmrg case UNSPEC_FRNDINT_FLOOR:
18661debfc3dSmrg case UNSPEC_FRNDINT_CEIL:
18671debfc3dSmrg case UNSPEC_FRNDINT_TRUNC:
18681debfc3dSmrg
18691debfc3dSmrg /* Above insns operate on the top of the stack. */
18701debfc3dSmrg
18711debfc3dSmrg case UNSPEC_SINCOS_COS:
18721debfc3dSmrg case UNSPEC_XTRACT_FRACT:
18731debfc3dSmrg
18741debfc3dSmrg /* Above insns operate on the top two stack slots,
18751debfc3dSmrg first part of one input, double output insn. */
18761debfc3dSmrg
18771debfc3dSmrg src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
18781debfc3dSmrg
18791debfc3dSmrg emit_swap_insn (insn, regstack, *src1);
18801debfc3dSmrg
18811debfc3dSmrg /* Input should never die, it is replaced with output. */
18821debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
18831debfc3dSmrg gcc_assert (!src1_note);
18841debfc3dSmrg
18851debfc3dSmrg if (STACK_REG_P (*dest))
18861debfc3dSmrg replace_reg (dest, FIRST_STACK_REG);
18871debfc3dSmrg
18881debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
18891debfc3dSmrg break;
18901debfc3dSmrg
18911debfc3dSmrg case UNSPEC_SINCOS_SIN:
18921debfc3dSmrg case UNSPEC_XTRACT_EXP:
18931debfc3dSmrg
18941debfc3dSmrg /* These insns operate on the top two stack slots,
18951debfc3dSmrg second part of one input, double output insn. */
18961debfc3dSmrg
18971debfc3dSmrg regstack->top++;
18981debfc3dSmrg /* FALLTHRU */
18991debfc3dSmrg
19001debfc3dSmrg case UNSPEC_TAN:
19011debfc3dSmrg
19021debfc3dSmrg /* For UNSPEC_TAN, regstack->top is already increased
19031debfc3dSmrg by inherent load of constant 1.0. */
19041debfc3dSmrg
19051debfc3dSmrg /* Output value is generated in the second stack slot.
19061debfc3dSmrg Move current value from second slot to the top. */
19071debfc3dSmrg regstack->reg[regstack->top]
19081debfc3dSmrg = regstack->reg[regstack->top - 1];
19091debfc3dSmrg
19101debfc3dSmrg gcc_assert (STACK_REG_P (*dest));
19111debfc3dSmrg
19121debfc3dSmrg regstack->reg[regstack->top - 1] = REGNO (*dest);
19131debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
19141debfc3dSmrg replace_reg (dest, FIRST_STACK_REG + 1);
19151debfc3dSmrg
19161debfc3dSmrg src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
19171debfc3dSmrg
19181debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
19191debfc3dSmrg break;
19201debfc3dSmrg
19211debfc3dSmrg case UNSPEC_FPATAN:
19221debfc3dSmrg case UNSPEC_FYL2X:
19231debfc3dSmrg case UNSPEC_FYL2XP1:
19241debfc3dSmrg /* These insns operate on the top two stack slots. */
19251debfc3dSmrg
19261debfc3dSmrg src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
19271debfc3dSmrg src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
19281debfc3dSmrg
19291debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
19301debfc3dSmrg src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
19311debfc3dSmrg
19321debfc3dSmrg swap_to_top (insn, regstack, *src1, *src2);
19331debfc3dSmrg
19341debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
19351debfc3dSmrg replace_reg (src2, FIRST_STACK_REG + 1);
19361debfc3dSmrg
19371debfc3dSmrg if (src1_note)
19381debfc3dSmrg replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
19391debfc3dSmrg if (src2_note)
19401debfc3dSmrg replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
19411debfc3dSmrg
19421debfc3dSmrg /* Pop both input operands from the stack. */
19431debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set,
19441debfc3dSmrg regstack->reg[regstack->top]);
19451debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set,
19461debfc3dSmrg regstack->reg[regstack->top - 1]);
19471debfc3dSmrg regstack->top -= 2;
19481debfc3dSmrg
19491debfc3dSmrg /* Push the result back onto the stack. */
19501debfc3dSmrg regstack->reg[++regstack->top] = REGNO (*dest);
19511debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
19521debfc3dSmrg replace_reg (dest, FIRST_STACK_REG);
19531debfc3dSmrg break;
19541debfc3dSmrg
19551debfc3dSmrg case UNSPEC_FSCALE_FRACT:
19561debfc3dSmrg case UNSPEC_FPREM_F:
19571debfc3dSmrg case UNSPEC_FPREM1_F:
19581debfc3dSmrg /* These insns operate on the top two stack slots,
19591debfc3dSmrg first part of double input, double output insn. */
19601debfc3dSmrg
19611debfc3dSmrg src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
19621debfc3dSmrg src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
19631debfc3dSmrg
19641debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
19651debfc3dSmrg src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
19661debfc3dSmrg
19671debfc3dSmrg /* Inputs should never die, they are
19681debfc3dSmrg replaced with outputs. */
19691debfc3dSmrg gcc_assert (!src1_note);
19701debfc3dSmrg gcc_assert (!src2_note);
19711debfc3dSmrg
19721debfc3dSmrg swap_to_top (insn, regstack, *src1, *src2);
19731debfc3dSmrg
19741debfc3dSmrg /* Push the result back onto stack. Empty stack slot
19751debfc3dSmrg will be filled in second part of insn. */
19761debfc3dSmrg if (STACK_REG_P (*dest))
19771debfc3dSmrg {
19781debfc3dSmrg regstack->reg[regstack->top] = REGNO (*dest);
19791debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
19801debfc3dSmrg replace_reg (dest, FIRST_STACK_REG);
19811debfc3dSmrg }
19821debfc3dSmrg
19831debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
19841debfc3dSmrg replace_reg (src2, FIRST_STACK_REG + 1);
19851debfc3dSmrg break;
19861debfc3dSmrg
19871debfc3dSmrg case UNSPEC_FSCALE_EXP:
19881debfc3dSmrg case UNSPEC_FPREM_U:
19891debfc3dSmrg case UNSPEC_FPREM1_U:
19901debfc3dSmrg /* These insns operate on the top two stack slots,
19911debfc3dSmrg second part of double input, double output insn. */
19921debfc3dSmrg
19931debfc3dSmrg src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
19941debfc3dSmrg src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
19951debfc3dSmrg
19961debfc3dSmrg /* Push the result back onto stack. Fill empty slot from
19971debfc3dSmrg first part of insn and fix top of stack pointer. */
19981debfc3dSmrg if (STACK_REG_P (*dest))
19991debfc3dSmrg {
20001debfc3dSmrg regstack->reg[regstack->top - 1] = REGNO (*dest);
20011debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
20021debfc3dSmrg replace_reg (dest, FIRST_STACK_REG + 1);
20031debfc3dSmrg }
20041debfc3dSmrg
20051debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
20061debfc3dSmrg replace_reg (src2, FIRST_STACK_REG + 1);
20071debfc3dSmrg break;
20081debfc3dSmrg
20091debfc3dSmrg case UNSPEC_C2_FLAG:
20101debfc3dSmrg /* This insn operates on the top two stack slots,
20111debfc3dSmrg third part of C2 setting double input insn. */
20121debfc3dSmrg
20131debfc3dSmrg src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
20141debfc3dSmrg src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
20151debfc3dSmrg
20161debfc3dSmrg replace_reg (src1, FIRST_STACK_REG);
20171debfc3dSmrg replace_reg (src2, FIRST_STACK_REG + 1);
20181debfc3dSmrg break;
20191debfc3dSmrg
20201debfc3dSmrg case UNSPEC_FNSTSW:
20211debfc3dSmrg /* Combined fcomp+fnstsw generated for doing well with
20221debfc3dSmrg CSE. When optimizing this would have been broken
20231debfc3dSmrg up before now. */
20241debfc3dSmrg
20251debfc3dSmrg pat_src = XVECEXP (pat_src, 0, 0);
2026a2dc1f3fSmrg if (GET_CODE (pat_src) == COMPARE)
2027a2dc1f3fSmrg goto do_compare;
20281debfc3dSmrg
2029a2dc1f3fSmrg /* Fall through. */
2030a2dc1f3fSmrg
2031a2dc1f3fSmrg case UNSPEC_NOTRAP:
2032a2dc1f3fSmrg
2033a2dc1f3fSmrg pat_src = XVECEXP (pat_src, 0, 0);
2034a2dc1f3fSmrg gcc_assert (GET_CODE (pat_src) == COMPARE);
2035a2dc1f3fSmrg goto do_compare;
20361debfc3dSmrg
20371debfc3dSmrg default:
20381debfc3dSmrg gcc_unreachable ();
20391debfc3dSmrg }
20401debfc3dSmrg break;
20411debfc3dSmrg
2042a2dc1f3fSmrg case COMPARE:
2043a2dc1f3fSmrg do_compare:
2044a2dc1f3fSmrg /* `fcomi' insn can't pop two regs. */
2045a2dc1f3fSmrg compare_for_stack_reg (insn, regstack, pat_src,
2046a2dc1f3fSmrg REGNO (*dest) != FLAGS_REG);
2047a2dc1f3fSmrg break;
2048a2dc1f3fSmrg
20491debfc3dSmrg case IF_THEN_ELSE:
20501debfc3dSmrg /* This insn requires the top of stack to be the destination. */
20511debfc3dSmrg
20521debfc3dSmrg src1 = get_true_reg (&XEXP (pat_src, 1));
20531debfc3dSmrg src2 = get_true_reg (&XEXP (pat_src, 2));
20541debfc3dSmrg
20551debfc3dSmrg src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
20561debfc3dSmrg src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
20571debfc3dSmrg
20581debfc3dSmrg /* If the comparison operator is an FP comparison operator,
20591debfc3dSmrg it is handled correctly by compare_for_stack_reg () who
20601debfc3dSmrg will move the destination to the top of stack. But if the
20611debfc3dSmrg comparison operator is not an FP comparison operator, we
20621debfc3dSmrg have to handle it here. */
20631debfc3dSmrg if (get_hard_regnum (regstack, *dest) >= FIRST_STACK_REG
20641debfc3dSmrg && REGNO (*dest) != regstack->reg[regstack->top])
20651debfc3dSmrg {
20661debfc3dSmrg /* In case one of operands is the top of stack and the operands
20671debfc3dSmrg dies, it is safe to make it the destination operand by
20681debfc3dSmrg reversing the direction of cmove and avoid fxch. */
20691debfc3dSmrg if ((REGNO (*src1) == regstack->reg[regstack->top]
20701debfc3dSmrg && src1_note)
20711debfc3dSmrg || (REGNO (*src2) == regstack->reg[regstack->top]
20721debfc3dSmrg && src2_note))
20731debfc3dSmrg {
20741debfc3dSmrg int idx1 = (get_hard_regnum (regstack, *src1)
20751debfc3dSmrg - FIRST_STACK_REG);
20761debfc3dSmrg int idx2 = (get_hard_regnum (regstack, *src2)
20771debfc3dSmrg - FIRST_STACK_REG);
20781debfc3dSmrg
20791debfc3dSmrg /* Make reg-stack believe that the operands are already
20801debfc3dSmrg swapped on the stack */
20811debfc3dSmrg regstack->reg[regstack->top - idx1] = REGNO (*src2);
20821debfc3dSmrg regstack->reg[regstack->top - idx2] = REGNO (*src1);
20831debfc3dSmrg
20841debfc3dSmrg /* Reverse condition to compensate the operand swap.
20851debfc3dSmrg i386 do have comparison always reversible. */
20861debfc3dSmrg PUT_CODE (XEXP (pat_src, 0),
20871debfc3dSmrg reversed_comparison_code (XEXP (pat_src, 0), insn));
20881debfc3dSmrg }
20891debfc3dSmrg else
20901debfc3dSmrg emit_swap_insn (insn, regstack, *dest);
20911debfc3dSmrg }
20921debfc3dSmrg
20931debfc3dSmrg {
20941debfc3dSmrg rtx src_note [3];
20951debfc3dSmrg int i;
20961debfc3dSmrg
20971debfc3dSmrg src_note[0] = 0;
20981debfc3dSmrg src_note[1] = src1_note;
20991debfc3dSmrg src_note[2] = src2_note;
21001debfc3dSmrg
21011debfc3dSmrg if (STACK_REG_P (*src1))
21021debfc3dSmrg replace_reg (src1, get_hard_regnum (regstack, *src1));
21031debfc3dSmrg if (STACK_REG_P (*src2))
21041debfc3dSmrg replace_reg (src2, get_hard_regnum (regstack, *src2));
21051debfc3dSmrg
21061debfc3dSmrg for (i = 1; i <= 2; i++)
21071debfc3dSmrg if (src_note [i])
21081debfc3dSmrg {
21091debfc3dSmrg int regno = REGNO (XEXP (src_note[i], 0));
21101debfc3dSmrg
21111debfc3dSmrg /* If the register that dies is not at the top of
21121debfc3dSmrg stack, then move the top of stack to the dead reg.
21131debfc3dSmrg Top of stack should never die, as it is the
21141debfc3dSmrg destination. */
21151debfc3dSmrg gcc_assert (regno != regstack->reg[regstack->top]);
21161debfc3dSmrg remove_regno_note (insn, REG_DEAD, regno);
21171debfc3dSmrg emit_pop_insn (insn, regstack, XEXP (src_note[i], 0),
21181debfc3dSmrg EMIT_AFTER);
21191debfc3dSmrg }
21201debfc3dSmrg }
21211debfc3dSmrg
21221debfc3dSmrg /* Make dest the top of stack. Add dest to regstack if
21231debfc3dSmrg not present. */
21241debfc3dSmrg if (get_hard_regnum (regstack, *dest) < FIRST_STACK_REG)
21251debfc3dSmrg regstack->reg[++regstack->top] = REGNO (*dest);
21261debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
21271debfc3dSmrg replace_reg (dest, FIRST_STACK_REG);
21281debfc3dSmrg break;
21291debfc3dSmrg
21301debfc3dSmrg default:
21311debfc3dSmrg gcc_unreachable ();
21321debfc3dSmrg }
21331debfc3dSmrg break;
21341debfc3dSmrg }
21351debfc3dSmrg
21361debfc3dSmrg default:
21371debfc3dSmrg break;
21381debfc3dSmrg }
21391debfc3dSmrg
21401debfc3dSmrg return control_flow_insn_deleted;
21411debfc3dSmrg }
21421debfc3dSmrg
21431debfc3dSmrg /* Substitute hard regnums for any stack regs in INSN, which has
21441debfc3dSmrg N_INPUTS inputs and N_OUTPUTS outputs. REGSTACK is the stack info
21451debfc3dSmrg before the insn, and is updated with changes made here.
21461debfc3dSmrg
21471debfc3dSmrg There are several requirements and assumptions about the use of
21481debfc3dSmrg stack-like regs in asm statements. These rules are enforced by
21491debfc3dSmrg record_asm_stack_regs; see comments there for details. Any
21501debfc3dSmrg asm_operands left in the RTL at this point may be assume to meet the
21511debfc3dSmrg requirements, since record_asm_stack_regs removes any problem asm. */
21521debfc3dSmrg
21531debfc3dSmrg static void
subst_asm_stack_regs(rtx_insn * insn,stack_ptr regstack)21541debfc3dSmrg subst_asm_stack_regs (rtx_insn *insn, stack_ptr regstack)
21551debfc3dSmrg {
21561debfc3dSmrg rtx body = PATTERN (insn);
21571debfc3dSmrg
21581debfc3dSmrg rtx *note_reg; /* Array of note contents */
21591debfc3dSmrg rtx **note_loc; /* Address of REG field of each note */
21601debfc3dSmrg enum reg_note *note_kind; /* The type of each note */
21611debfc3dSmrg
21621debfc3dSmrg rtx *clobber_reg = 0;
21631debfc3dSmrg rtx **clobber_loc = 0;
21641debfc3dSmrg
21651debfc3dSmrg struct stack_def temp_stack;
21661debfc3dSmrg int n_notes;
21671debfc3dSmrg int n_clobbers;
21681debfc3dSmrg rtx note;
21691debfc3dSmrg int i;
21701debfc3dSmrg int n_inputs, n_outputs;
21711debfc3dSmrg
21721debfc3dSmrg if (! check_asm_stack_operands (insn))
21731debfc3dSmrg return;
21741debfc3dSmrg
21751debfc3dSmrg /* Find out what the constraints required. If no constraint
21761debfc3dSmrg alternative matches, that is a compiler bug: we should have caught
21771debfc3dSmrg such an insn in check_asm_stack_operands. */
21781debfc3dSmrg extract_constrain_insn (insn);
21791debfc3dSmrg
21801debfc3dSmrg preprocess_constraints (insn);
21811debfc3dSmrg const operand_alternative *op_alt = which_op_alt ();
21821debfc3dSmrg
21831debfc3dSmrg get_asm_operands_in_out (body, &n_outputs, &n_inputs);
21841debfc3dSmrg
21851debfc3dSmrg /* Strip SUBREGs here to make the following code simpler. */
21861debfc3dSmrg for (i = 0; i < recog_data.n_operands; i++)
21871debfc3dSmrg if (GET_CODE (recog_data.operand[i]) == SUBREG
21881debfc3dSmrg && REG_P (SUBREG_REG (recog_data.operand[i])))
21891debfc3dSmrg {
21901debfc3dSmrg recog_data.operand_loc[i] = & SUBREG_REG (recog_data.operand[i]);
21911debfc3dSmrg recog_data.operand[i] = SUBREG_REG (recog_data.operand[i]);
21921debfc3dSmrg }
21931debfc3dSmrg
21941debfc3dSmrg /* Set up NOTE_REG, NOTE_LOC and NOTE_KIND. */
21951debfc3dSmrg
21961debfc3dSmrg for (i = 0, note = REG_NOTES (insn); note; note = XEXP (note, 1))
21971debfc3dSmrg i++;
21981debfc3dSmrg
21991debfc3dSmrg note_reg = XALLOCAVEC (rtx, i);
22001debfc3dSmrg note_loc = XALLOCAVEC (rtx *, i);
22011debfc3dSmrg note_kind = XALLOCAVEC (enum reg_note, i);
22021debfc3dSmrg
22031debfc3dSmrg n_notes = 0;
22041debfc3dSmrg for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
22051debfc3dSmrg {
22061debfc3dSmrg if (GET_CODE (note) != EXPR_LIST)
22071debfc3dSmrg continue;
22081debfc3dSmrg rtx reg = XEXP (note, 0);
22091debfc3dSmrg rtx *loc = & XEXP (note, 0);
22101debfc3dSmrg
22111debfc3dSmrg if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg)))
22121debfc3dSmrg {
22131debfc3dSmrg loc = & SUBREG_REG (reg);
22141debfc3dSmrg reg = SUBREG_REG (reg);
22151debfc3dSmrg }
22161debfc3dSmrg
22171debfc3dSmrg if (STACK_REG_P (reg)
22181debfc3dSmrg && (REG_NOTE_KIND (note) == REG_DEAD
22191debfc3dSmrg || REG_NOTE_KIND (note) == REG_UNUSED))
22201debfc3dSmrg {
22211debfc3dSmrg note_reg[n_notes] = reg;
22221debfc3dSmrg note_loc[n_notes] = loc;
22231debfc3dSmrg note_kind[n_notes] = REG_NOTE_KIND (note);
22241debfc3dSmrg n_notes++;
22251debfc3dSmrg }
22261debfc3dSmrg }
22271debfc3dSmrg
22281debfc3dSmrg /* Set up CLOBBER_REG and CLOBBER_LOC. */
22291debfc3dSmrg
22301debfc3dSmrg n_clobbers = 0;
22311debfc3dSmrg
22321debfc3dSmrg if (GET_CODE (body) == PARALLEL)
22331debfc3dSmrg {
22341debfc3dSmrg clobber_reg = XALLOCAVEC (rtx, XVECLEN (body, 0));
22351debfc3dSmrg clobber_loc = XALLOCAVEC (rtx *, XVECLEN (body, 0));
22361debfc3dSmrg
22371debfc3dSmrg for (i = 0; i < XVECLEN (body, 0); i++)
22381debfc3dSmrg if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
22391debfc3dSmrg {
22401debfc3dSmrg rtx clobber = XVECEXP (body, 0, i);
22411debfc3dSmrg rtx reg = XEXP (clobber, 0);
22421debfc3dSmrg rtx *loc = & XEXP (clobber, 0);
22431debfc3dSmrg
22441debfc3dSmrg if (GET_CODE (reg) == SUBREG && REG_P (SUBREG_REG (reg)))
22451debfc3dSmrg {
22461debfc3dSmrg loc = & SUBREG_REG (reg);
22471debfc3dSmrg reg = SUBREG_REG (reg);
22481debfc3dSmrg }
22491debfc3dSmrg
22501debfc3dSmrg if (STACK_REG_P (reg))
22511debfc3dSmrg {
22521debfc3dSmrg clobber_reg[n_clobbers] = reg;
22531debfc3dSmrg clobber_loc[n_clobbers] = loc;
22541debfc3dSmrg n_clobbers++;
22551debfc3dSmrg }
22561debfc3dSmrg }
22571debfc3dSmrg }
22581debfc3dSmrg
22591debfc3dSmrg temp_stack = *regstack;
22601debfc3dSmrg
22611debfc3dSmrg /* Put the input regs into the desired place in TEMP_STACK. */
22621debfc3dSmrg
22631debfc3dSmrg for (i = n_outputs; i < n_outputs + n_inputs; i++)
22641debfc3dSmrg if (STACK_REG_P (recog_data.operand[i])
22651debfc3dSmrg && reg_class_subset_p (op_alt[i].cl, FLOAT_REGS)
22661debfc3dSmrg && op_alt[i].cl != FLOAT_REGS)
22671debfc3dSmrg {
22681debfc3dSmrg /* If an operand needs to be in a particular reg in
22691debfc3dSmrg FLOAT_REGS, the constraint was either 't' or 'u'. Since
22701debfc3dSmrg these constraints are for single register classes, and
22711debfc3dSmrg reload guaranteed that operand[i] is already in that class,
22721debfc3dSmrg we can just use REGNO (recog_data.operand[i]) to know which
22731debfc3dSmrg actual reg this operand needs to be in. */
22741debfc3dSmrg
22751debfc3dSmrg int regno = get_hard_regnum (&temp_stack, recog_data.operand[i]);
22761debfc3dSmrg
22771debfc3dSmrg gcc_assert (regno >= 0);
22781debfc3dSmrg
22791debfc3dSmrg if ((unsigned int) regno != REGNO (recog_data.operand[i]))
22801debfc3dSmrg {
22811debfc3dSmrg /* recog_data.operand[i] is not in the right place. Find
22821debfc3dSmrg it and swap it with whatever is already in I's place.
22831debfc3dSmrg K is where recog_data.operand[i] is now. J is where it
22841debfc3dSmrg should be. */
22851debfc3dSmrg int j, k;
22861debfc3dSmrg
22871debfc3dSmrg k = temp_stack.top - (regno - FIRST_STACK_REG);
22881debfc3dSmrg j = (temp_stack.top
22891debfc3dSmrg - (REGNO (recog_data.operand[i]) - FIRST_STACK_REG));
22901debfc3dSmrg
22911debfc3dSmrg std::swap (temp_stack.reg[j], temp_stack.reg[k]);
22921debfc3dSmrg }
22931debfc3dSmrg }
22941debfc3dSmrg
22951debfc3dSmrg /* Emit insns before INSN to make sure the reg-stack is in the right
22961debfc3dSmrg order. */
22971debfc3dSmrg
22981debfc3dSmrg change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
22991debfc3dSmrg
23001debfc3dSmrg /* Make the needed input register substitutions. Do death notes and
23011debfc3dSmrg clobbers too, because these are for inputs, not outputs. */
23021debfc3dSmrg
23031debfc3dSmrg for (i = n_outputs; i < n_outputs + n_inputs; i++)
23041debfc3dSmrg if (STACK_REG_P (recog_data.operand[i]))
23051debfc3dSmrg {
23061debfc3dSmrg int regnum = get_hard_regnum (regstack, recog_data.operand[i]);
23071debfc3dSmrg
23081debfc3dSmrg gcc_assert (regnum >= 0);
23091debfc3dSmrg
23101debfc3dSmrg replace_reg (recog_data.operand_loc[i], regnum);
23111debfc3dSmrg }
23121debfc3dSmrg
23131debfc3dSmrg for (i = 0; i < n_notes; i++)
23141debfc3dSmrg if (note_kind[i] == REG_DEAD)
23151debfc3dSmrg {
23161debfc3dSmrg int regnum = get_hard_regnum (regstack, note_reg[i]);
23171debfc3dSmrg
23181debfc3dSmrg gcc_assert (regnum >= 0);
23191debfc3dSmrg
23201debfc3dSmrg replace_reg (note_loc[i], regnum);
23211debfc3dSmrg }
23221debfc3dSmrg
23231debfc3dSmrg for (i = 0; i < n_clobbers; i++)
23241debfc3dSmrg {
23251debfc3dSmrg /* It's OK for a CLOBBER to reference a reg that is not live.
23261debfc3dSmrg Don't try to replace it in that case. */
23271debfc3dSmrg int regnum = get_hard_regnum (regstack, clobber_reg[i]);
23281debfc3dSmrg
23291debfc3dSmrg if (regnum >= 0)
2330c0a68be4Smrg replace_reg (clobber_loc[i], regnum);
23311debfc3dSmrg }
23321debfc3dSmrg
23331debfc3dSmrg /* Now remove from REGSTACK any inputs that the asm implicitly popped. */
23341debfc3dSmrg
23351debfc3dSmrg for (i = n_outputs; i < n_outputs + n_inputs; i++)
23361debfc3dSmrg if (STACK_REG_P (recog_data.operand[i]))
23371debfc3dSmrg {
23381debfc3dSmrg /* An input reg is implicitly popped if it is tied to an
23391debfc3dSmrg output, or if there is a CLOBBER for it. */
23401debfc3dSmrg int j;
23411debfc3dSmrg
23421debfc3dSmrg for (j = 0; j < n_clobbers; j++)
23431debfc3dSmrg if (operands_match_p (clobber_reg[j], recog_data.operand[i]))
23441debfc3dSmrg break;
23451debfc3dSmrg
23461debfc3dSmrg if (j < n_clobbers || op_alt[i].matches >= 0)
23471debfc3dSmrg {
23481debfc3dSmrg /* recog_data.operand[i] might not be at the top of stack.
23491debfc3dSmrg But that's OK, because all we need to do is pop the
23501debfc3dSmrg right number of regs off of the top of the reg-stack.
23511debfc3dSmrg record_asm_stack_regs guaranteed that all implicitly
23521debfc3dSmrg popped regs were grouped at the top of the reg-stack. */
23531debfc3dSmrg
23541debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set,
23551debfc3dSmrg regstack->reg[regstack->top]);
23561debfc3dSmrg regstack->top--;
23571debfc3dSmrg }
23581debfc3dSmrg }
23591debfc3dSmrg
23601debfc3dSmrg /* Now add to REGSTACK any outputs that the asm implicitly pushed.
23611debfc3dSmrg Note that there isn't any need to substitute register numbers.
23621debfc3dSmrg ??? Explain why this is true. */
23631debfc3dSmrg
23641debfc3dSmrg for (i = LAST_STACK_REG; i >= FIRST_STACK_REG; i--)
23651debfc3dSmrg {
23661debfc3dSmrg /* See if there is an output for this hard reg. */
23671debfc3dSmrg int j;
23681debfc3dSmrg
23691debfc3dSmrg for (j = 0; j < n_outputs; j++)
23701debfc3dSmrg if (STACK_REG_P (recog_data.operand[j])
23711debfc3dSmrg && REGNO (recog_data.operand[j]) == (unsigned) i)
23721debfc3dSmrg {
23731debfc3dSmrg regstack->reg[++regstack->top] = i;
23741debfc3dSmrg SET_HARD_REG_BIT (regstack->reg_set, i);
23751debfc3dSmrg break;
23761debfc3dSmrg }
23771debfc3dSmrg }
23781debfc3dSmrg
23791debfc3dSmrg /* Now emit a pop insn for any REG_UNUSED output, or any REG_DEAD
23801debfc3dSmrg input that the asm didn't implicitly pop. If the asm didn't
23811debfc3dSmrg implicitly pop an input reg, that reg will still be live.
23821debfc3dSmrg
23831debfc3dSmrg Note that we can't use find_regno_note here: the register numbers
23841debfc3dSmrg in the death notes have already been substituted. */
23851debfc3dSmrg
23861debfc3dSmrg for (i = 0; i < n_outputs; i++)
23871debfc3dSmrg if (STACK_REG_P (recog_data.operand[i]))
23881debfc3dSmrg {
23891debfc3dSmrg int j;
23901debfc3dSmrg
23911debfc3dSmrg for (j = 0; j < n_notes; j++)
23921debfc3dSmrg if (REGNO (recog_data.operand[i]) == REGNO (note_reg[j])
23931debfc3dSmrg && note_kind[j] == REG_UNUSED)
23941debfc3dSmrg {
23951debfc3dSmrg insn = emit_pop_insn (insn, regstack, recog_data.operand[i],
23961debfc3dSmrg EMIT_AFTER);
23971debfc3dSmrg break;
23981debfc3dSmrg }
23991debfc3dSmrg }
24001debfc3dSmrg
24011debfc3dSmrg for (i = n_outputs; i < n_outputs + n_inputs; i++)
24021debfc3dSmrg if (STACK_REG_P (recog_data.operand[i]))
24031debfc3dSmrg {
24041debfc3dSmrg int j;
24051debfc3dSmrg
24061debfc3dSmrg for (j = 0; j < n_notes; j++)
24071debfc3dSmrg if (REGNO (recog_data.operand[i]) == REGNO (note_reg[j])
24081debfc3dSmrg && note_kind[j] == REG_DEAD
24091debfc3dSmrg && TEST_HARD_REG_BIT (regstack->reg_set,
24101debfc3dSmrg REGNO (recog_data.operand[i])))
24111debfc3dSmrg {
24121debfc3dSmrg insn = emit_pop_insn (insn, regstack, recog_data.operand[i],
24131debfc3dSmrg EMIT_AFTER);
24141debfc3dSmrg break;
24151debfc3dSmrg }
24161debfc3dSmrg }
24171debfc3dSmrg }
24181debfc3dSmrg
24191debfc3dSmrg /* Substitute stack hard reg numbers for stack virtual registers in
24201debfc3dSmrg INSN. Non-stack register numbers are not changed. REGSTACK is the
24211debfc3dSmrg current stack content. Insns may be emitted as needed to arrange the
24221debfc3dSmrg stack for the 387 based on the contents of the insn. Return whether
24231debfc3dSmrg a control flow insn was deleted in the process. */
24241debfc3dSmrg
24251debfc3dSmrg static bool
subst_stack_regs(rtx_insn * insn,stack_ptr regstack)24261debfc3dSmrg subst_stack_regs (rtx_insn *insn, stack_ptr regstack)
24271debfc3dSmrg {
24281debfc3dSmrg rtx *note_link, note;
24291debfc3dSmrg bool control_flow_insn_deleted = false;
24301debfc3dSmrg int i;
24311debfc3dSmrg
24321debfc3dSmrg if (CALL_P (insn))
24331debfc3dSmrg {
24341debfc3dSmrg int top = regstack->top;
24351debfc3dSmrg
24361debfc3dSmrg /* If there are any floating point parameters to be passed in
24371debfc3dSmrg registers for this call, make sure they are in the right
24381debfc3dSmrg order. */
24391debfc3dSmrg
24401debfc3dSmrg if (top >= 0)
24411debfc3dSmrg {
24421debfc3dSmrg straighten_stack (insn, regstack);
24431debfc3dSmrg
24441debfc3dSmrg /* Now mark the arguments as dead after the call. */
24451debfc3dSmrg
24461debfc3dSmrg while (regstack->top >= 0)
24471debfc3dSmrg {
24481debfc3dSmrg CLEAR_HARD_REG_BIT (regstack->reg_set, FIRST_STACK_REG + regstack->top);
24491debfc3dSmrg regstack->top--;
24501debfc3dSmrg }
24511debfc3dSmrg }
24521debfc3dSmrg }
24531debfc3dSmrg
24541debfc3dSmrg /* Do the actual substitution if any stack regs are mentioned.
24551debfc3dSmrg Since we only record whether entire insn mentions stack regs, and
24561debfc3dSmrg subst_stack_regs_pat only works for patterns that contain stack regs,
24571debfc3dSmrg we must check each pattern in a parallel here. A call_value_pop could
24581debfc3dSmrg fail otherwise. */
24591debfc3dSmrg
24601debfc3dSmrg if (stack_regs_mentioned (insn))
24611debfc3dSmrg {
24621debfc3dSmrg int n_operands = asm_noperands (PATTERN (insn));
24631debfc3dSmrg if (n_operands >= 0)
24641debfc3dSmrg {
24651debfc3dSmrg /* This insn is an `asm' with operands. Decode the operands,
24661debfc3dSmrg decide how many are inputs, and do register substitution.
24671debfc3dSmrg Any REG_UNUSED notes will be handled by subst_asm_stack_regs. */
24681debfc3dSmrg
24691debfc3dSmrg subst_asm_stack_regs (insn, regstack);
24701debfc3dSmrg return control_flow_insn_deleted;
24711debfc3dSmrg }
24721debfc3dSmrg
24731debfc3dSmrg if (GET_CODE (PATTERN (insn)) == PARALLEL)
24741debfc3dSmrg for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
24751debfc3dSmrg {
24761debfc3dSmrg if (stack_regs_mentioned_p (XVECEXP (PATTERN (insn), 0, i)))
24771debfc3dSmrg {
24781debfc3dSmrg if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == CLOBBER)
24791debfc3dSmrg XVECEXP (PATTERN (insn), 0, i)
24801debfc3dSmrg = shallow_copy_rtx (XVECEXP (PATTERN (insn), 0, i));
24811debfc3dSmrg control_flow_insn_deleted
24821debfc3dSmrg |= subst_stack_regs_pat (insn, regstack,
24831debfc3dSmrg XVECEXP (PATTERN (insn), 0, i));
24841debfc3dSmrg }
24851debfc3dSmrg }
24861debfc3dSmrg else
24871debfc3dSmrg control_flow_insn_deleted
24881debfc3dSmrg |= subst_stack_regs_pat (insn, regstack, PATTERN (insn));
24891debfc3dSmrg }
24901debfc3dSmrg
24911debfc3dSmrg /* subst_stack_regs_pat may have deleted a no-op insn. If so, any
24921debfc3dSmrg REG_UNUSED will already have been dealt with, so just return. */
24931debfc3dSmrg
24941debfc3dSmrg if (NOTE_P (insn) || insn->deleted ())
24951debfc3dSmrg return control_flow_insn_deleted;
24961debfc3dSmrg
24971debfc3dSmrg /* If this a noreturn call, we can't insert pop insns after it.
24981debfc3dSmrg Instead, reset the stack state to empty. */
24991debfc3dSmrg if (CALL_P (insn)
25001debfc3dSmrg && find_reg_note (insn, REG_NORETURN, NULL))
25011debfc3dSmrg {
25021debfc3dSmrg regstack->top = -1;
25031debfc3dSmrg CLEAR_HARD_REG_SET (regstack->reg_set);
25041debfc3dSmrg return control_flow_insn_deleted;
25051debfc3dSmrg }
25061debfc3dSmrg
25071debfc3dSmrg /* If there is a REG_UNUSED note on a stack register on this insn,
25081debfc3dSmrg the indicated reg must be popped. The REG_UNUSED note is removed,
25091debfc3dSmrg since the form of the newly emitted pop insn references the reg,
25101debfc3dSmrg making it no longer `unset'. */
25111debfc3dSmrg
25121debfc3dSmrg note_link = ®_NOTES (insn);
25131debfc3dSmrg for (note = *note_link; note; note = XEXP (note, 1))
25141debfc3dSmrg if (REG_NOTE_KIND (note) == REG_UNUSED && STACK_REG_P (XEXP (note, 0)))
25151debfc3dSmrg {
25161debfc3dSmrg *note_link = XEXP (note, 1);
25171debfc3dSmrg insn = emit_pop_insn (insn, regstack, XEXP (note, 0), EMIT_AFTER);
25181debfc3dSmrg }
25191debfc3dSmrg else
25201debfc3dSmrg note_link = &XEXP (note, 1);
25211debfc3dSmrg
25221debfc3dSmrg return control_flow_insn_deleted;
25231debfc3dSmrg }
25241debfc3dSmrg
25251debfc3dSmrg /* Change the organization of the stack so that it fits a new basic
25261debfc3dSmrg block. Some registers might have to be popped, but there can never be
25271debfc3dSmrg a register live in the new block that is not now live.
25281debfc3dSmrg
25291debfc3dSmrg Insert any needed insns before or after INSN, as indicated by
25301debfc3dSmrg WHERE. OLD is the original stack layout, and NEW is the desired
25311debfc3dSmrg form. OLD is updated to reflect the code emitted, i.e., it will be
25321debfc3dSmrg the same as NEW upon return.
25331debfc3dSmrg
25341debfc3dSmrg This function will not preserve block_end[]. But that information
25351debfc3dSmrg is no longer needed once this has executed. */
25361debfc3dSmrg
25371debfc3dSmrg static void
change_stack(rtx_insn * insn,stack_ptr old,stack_ptr new_stack,enum emit_where where)25381debfc3dSmrg change_stack (rtx_insn *insn, stack_ptr old, stack_ptr new_stack,
25391debfc3dSmrg enum emit_where where)
25401debfc3dSmrg {
25411debfc3dSmrg int reg;
2542c0a68be4Smrg machine_mode raw_mode = reg_raw_mode[FIRST_STACK_REG];
2543a2dc1f3fSmrg rtx_insn *update_end = NULL;
25441debfc3dSmrg int i;
25451debfc3dSmrg
25461debfc3dSmrg /* Stack adjustments for the first insn in a block update the
25471debfc3dSmrg current_block's stack_in instead of inserting insns directly.
25481debfc3dSmrg compensate_edges will add the necessary code later. */
25491debfc3dSmrg if (current_block
25501debfc3dSmrg && starting_stack_p
25511debfc3dSmrg && where == EMIT_BEFORE)
25521debfc3dSmrg {
25531debfc3dSmrg BLOCK_INFO (current_block)->stack_in = *new_stack;
25541debfc3dSmrg starting_stack_p = false;
25551debfc3dSmrg *old = *new_stack;
25561debfc3dSmrg return;
25571debfc3dSmrg }
25581debfc3dSmrg
25591debfc3dSmrg /* We will be inserting new insns "backwards". If we are to insert
25601debfc3dSmrg after INSN, find the next insn, and insert before it. */
25611debfc3dSmrg
25621debfc3dSmrg if (where == EMIT_AFTER)
25631debfc3dSmrg {
25641debfc3dSmrg if (current_block && BB_END (current_block) == insn)
2565a2dc1f3fSmrg update_end = insn;
25661debfc3dSmrg insn = NEXT_INSN (insn);
25671debfc3dSmrg }
25681debfc3dSmrg
25691debfc3dSmrg /* Initialize partially dead variables. */
25701debfc3dSmrg for (i = FIRST_STACK_REG; i < LAST_STACK_REG + 1; i++)
25711debfc3dSmrg if (TEST_HARD_REG_BIT (new_stack->reg_set, i)
25721debfc3dSmrg && !TEST_HARD_REG_BIT (old->reg_set, i))
25731debfc3dSmrg {
25741debfc3dSmrg old->reg[++old->top] = i;
25751debfc3dSmrg SET_HARD_REG_BIT (old->reg_set, i);
25761debfc3dSmrg emit_insn_before (gen_rtx_SET (FP_MODE_REG (i, SFmode), not_a_num),
25771debfc3dSmrg insn);
25781debfc3dSmrg }
25791debfc3dSmrg
25801debfc3dSmrg /* Pop any registers that are not needed in the new block. */
25811debfc3dSmrg
25821debfc3dSmrg /* If the destination block's stack already has a specified layout
25831debfc3dSmrg and contains two or more registers, use a more intelligent algorithm
25841debfc3dSmrg to pop registers that minimizes the number of fxchs below. */
25851debfc3dSmrg if (new_stack->top > 0)
25861debfc3dSmrg {
25871debfc3dSmrg bool slots[REG_STACK_SIZE];
25881debfc3dSmrg int pops[REG_STACK_SIZE];
25891debfc3dSmrg int next, dest, topsrc;
25901debfc3dSmrg
25911debfc3dSmrg /* First pass to determine the free slots. */
25921debfc3dSmrg for (reg = 0; reg <= new_stack->top; reg++)
25931debfc3dSmrg slots[reg] = TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[reg]);
25941debfc3dSmrg
25951debfc3dSmrg /* Second pass to allocate preferred slots. */
25961debfc3dSmrg topsrc = -1;
25971debfc3dSmrg for (reg = old->top; reg > new_stack->top; reg--)
25981debfc3dSmrg if (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[reg]))
25991debfc3dSmrg {
26001debfc3dSmrg dest = -1;
26011debfc3dSmrg for (next = 0; next <= new_stack->top; next++)
26021debfc3dSmrg if (!slots[next] && new_stack->reg[next] == old->reg[reg])
26031debfc3dSmrg {
26041debfc3dSmrg /* If this is a preference for the new top of stack, record
26051debfc3dSmrg the fact by remembering it's old->reg in topsrc. */
26061debfc3dSmrg if (next == new_stack->top)
26071debfc3dSmrg topsrc = reg;
26081debfc3dSmrg slots[next] = true;
26091debfc3dSmrg dest = next;
26101debfc3dSmrg break;
26111debfc3dSmrg }
26121debfc3dSmrg pops[reg] = dest;
26131debfc3dSmrg }
26141debfc3dSmrg else
26151debfc3dSmrg pops[reg] = reg;
26161debfc3dSmrg
26171debfc3dSmrg /* Intentionally, avoid placing the top of stack in it's correct
26181debfc3dSmrg location, if we still need to permute the stack below and we
26191debfc3dSmrg can usefully place it somewhere else. This is the case if any
26201debfc3dSmrg slot is still unallocated, in which case we should place the
26211debfc3dSmrg top of stack there. */
26221debfc3dSmrg if (topsrc != -1)
26231debfc3dSmrg for (reg = 0; reg < new_stack->top; reg++)
26241debfc3dSmrg if (!slots[reg])
26251debfc3dSmrg {
26261debfc3dSmrg pops[topsrc] = reg;
26271debfc3dSmrg slots[new_stack->top] = false;
26281debfc3dSmrg slots[reg] = true;
26291debfc3dSmrg break;
26301debfc3dSmrg }
26311debfc3dSmrg
26321debfc3dSmrg /* Third pass allocates remaining slots and emits pop insns. */
26331debfc3dSmrg next = new_stack->top;
26341debfc3dSmrg for (reg = old->top; reg > new_stack->top; reg--)
26351debfc3dSmrg {
26361debfc3dSmrg dest = pops[reg];
26371debfc3dSmrg if (dest == -1)
26381debfc3dSmrg {
26391debfc3dSmrg /* Find next free slot. */
26401debfc3dSmrg while (slots[next])
26411debfc3dSmrg next--;
26421debfc3dSmrg dest = next--;
26431debfc3dSmrg }
2644c0a68be4Smrg emit_pop_insn (insn, old, FP_MODE_REG (old->reg[dest], raw_mode),
26451debfc3dSmrg EMIT_BEFORE);
26461debfc3dSmrg }
26471debfc3dSmrg }
26481debfc3dSmrg else
26491debfc3dSmrg {
26501debfc3dSmrg /* The following loop attempts to maximize the number of times we
26511debfc3dSmrg pop the top of the stack, as this permits the use of the faster
26521debfc3dSmrg ffreep instruction on platforms that support it. */
26531debfc3dSmrg int live, next;
26541debfc3dSmrg
26551debfc3dSmrg live = 0;
26561debfc3dSmrg for (reg = 0; reg <= old->top; reg++)
26571debfc3dSmrg if (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[reg]))
26581debfc3dSmrg live++;
26591debfc3dSmrg
26601debfc3dSmrg next = live;
26611debfc3dSmrg while (old->top >= live)
26621debfc3dSmrg if (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[old->top]))
26631debfc3dSmrg {
26641debfc3dSmrg while (TEST_HARD_REG_BIT (new_stack->reg_set, old->reg[next]))
26651debfc3dSmrg next--;
2666c0a68be4Smrg emit_pop_insn (insn, old, FP_MODE_REG (old->reg[next], raw_mode),
26671debfc3dSmrg EMIT_BEFORE);
26681debfc3dSmrg }
26691debfc3dSmrg else
2670c0a68be4Smrg emit_pop_insn (insn, old, FP_MODE_REG (old->reg[old->top], raw_mode),
26711debfc3dSmrg EMIT_BEFORE);
26721debfc3dSmrg }
26731debfc3dSmrg
26741debfc3dSmrg if (new_stack->top == -2)
26751debfc3dSmrg {
26761debfc3dSmrg /* If the new block has never been processed, then it can inherit
26771debfc3dSmrg the old stack order. */
26781debfc3dSmrg
26791debfc3dSmrg new_stack->top = old->top;
26801debfc3dSmrg memcpy (new_stack->reg, old->reg, sizeof (new_stack->reg));
26811debfc3dSmrg }
26821debfc3dSmrg else
26831debfc3dSmrg {
26841debfc3dSmrg /* This block has been entered before, and we must match the
26851debfc3dSmrg previously selected stack order. */
26861debfc3dSmrg
26871debfc3dSmrg /* By now, the only difference should be the order of the stack,
26881debfc3dSmrg not their depth or liveliness. */
26891debfc3dSmrg
26908feb0f0bSmrg gcc_assert (old->reg_set == new_stack->reg_set);
26911debfc3dSmrg gcc_assert (old->top == new_stack->top);
26921debfc3dSmrg
26931debfc3dSmrg /* If the stack is not empty (new_stack->top != -1), loop here emitting
26941debfc3dSmrg swaps until the stack is correct.
26951debfc3dSmrg
26961debfc3dSmrg The worst case number of swaps emitted is N + 2, where N is the
26971debfc3dSmrg depth of the stack. In some cases, the reg at the top of
26981debfc3dSmrg stack may be correct, but swapped anyway in order to fix
26991debfc3dSmrg other regs. But since we never swap any other reg away from
27001debfc3dSmrg its correct slot, this algorithm will converge. */
27011debfc3dSmrg
27021debfc3dSmrg if (new_stack->top != -1)
27031debfc3dSmrg do
27041debfc3dSmrg {
27051debfc3dSmrg /* Swap the reg at top of stack into the position it is
27061debfc3dSmrg supposed to be in, until the correct top of stack appears. */
27071debfc3dSmrg
27081debfc3dSmrg while (old->reg[old->top] != new_stack->reg[new_stack->top])
27091debfc3dSmrg {
27101debfc3dSmrg for (reg = new_stack->top; reg >= 0; reg--)
27111debfc3dSmrg if (new_stack->reg[reg] == old->reg[old->top])
27121debfc3dSmrg break;
27131debfc3dSmrg
27141debfc3dSmrg gcc_assert (reg != -1);
27151debfc3dSmrg
27161debfc3dSmrg emit_swap_insn (insn, old,
2717c0a68be4Smrg FP_MODE_REG (old->reg[reg], raw_mode));
27181debfc3dSmrg }
27191debfc3dSmrg
27201debfc3dSmrg /* See if any regs remain incorrect. If so, bring an
27211debfc3dSmrg incorrect reg to the top of stack, and let the while loop
27221debfc3dSmrg above fix it. */
27231debfc3dSmrg
27241debfc3dSmrg for (reg = new_stack->top; reg >= 0; reg--)
27251debfc3dSmrg if (new_stack->reg[reg] != old->reg[reg])
27261debfc3dSmrg {
27271debfc3dSmrg emit_swap_insn (insn, old,
2728c0a68be4Smrg FP_MODE_REG (old->reg[reg], raw_mode));
27291debfc3dSmrg break;
27301debfc3dSmrg }
27311debfc3dSmrg } while (reg >= 0);
27321debfc3dSmrg
27331debfc3dSmrg /* At this point there must be no differences. */
27341debfc3dSmrg
27351debfc3dSmrg for (reg = old->top; reg >= 0; reg--)
27361debfc3dSmrg gcc_assert (old->reg[reg] == new_stack->reg[reg]);
27371debfc3dSmrg }
27381debfc3dSmrg
27391debfc3dSmrg if (update_end)
2740a2dc1f3fSmrg {
2741a2dc1f3fSmrg for (update_end = NEXT_INSN (update_end); update_end != insn;
2742a2dc1f3fSmrg update_end = NEXT_INSN (update_end))
2743a2dc1f3fSmrg {
2744a2dc1f3fSmrg set_block_for_insn (update_end, current_block);
2745a2dc1f3fSmrg if (INSN_P (update_end))
2746a2dc1f3fSmrg df_insn_rescan (update_end);
2747a2dc1f3fSmrg }
27481debfc3dSmrg BB_END (current_block) = PREV_INSN (insn);
27491debfc3dSmrg }
2750a2dc1f3fSmrg }
27511debfc3dSmrg
27521debfc3dSmrg /* Print stack configuration. */
27531debfc3dSmrg
27541debfc3dSmrg static void
print_stack(FILE * file,stack_ptr s)27551debfc3dSmrg print_stack (FILE *file, stack_ptr s)
27561debfc3dSmrg {
27571debfc3dSmrg if (! file)
27581debfc3dSmrg return;
27591debfc3dSmrg
27601debfc3dSmrg if (s->top == -2)
27611debfc3dSmrg fprintf (file, "uninitialized\n");
27621debfc3dSmrg else if (s->top == -1)
27631debfc3dSmrg fprintf (file, "empty\n");
27641debfc3dSmrg else
27651debfc3dSmrg {
27661debfc3dSmrg int i;
27671debfc3dSmrg fputs ("[ ", file);
27681debfc3dSmrg for (i = 0; i <= s->top; ++i)
27691debfc3dSmrg fprintf (file, "%d ", s->reg[i]);
27701debfc3dSmrg fputs ("]\n", file);
27711debfc3dSmrg }
27721debfc3dSmrg }
27731debfc3dSmrg
27741debfc3dSmrg /* This function was doing life analysis. We now let the regular live
27751debfc3dSmrg code do it's job, so we only need to check some extra invariants
27761debfc3dSmrg that reg-stack expects. Primary among these being that all registers
27771debfc3dSmrg are initialized before use.
27781debfc3dSmrg
27791debfc3dSmrg The function returns true when code was emitted to CFG edges and
27801debfc3dSmrg commit_edge_insertions needs to be called. */
27811debfc3dSmrg
27821debfc3dSmrg static int
convert_regs_entry(void)27831debfc3dSmrg convert_regs_entry (void)
27841debfc3dSmrg {
27851debfc3dSmrg int inserted = 0;
27861debfc3dSmrg edge e;
27871debfc3dSmrg edge_iterator ei;
27881debfc3dSmrg
27891debfc3dSmrg /* Load something into each stack register live at function entry.
27901debfc3dSmrg Such live registers can be caused by uninitialized variables or
27911debfc3dSmrg functions not returning values on all paths. In order to keep
27921debfc3dSmrg the push/pop code happy, and to not scrog the register stack, we
27931debfc3dSmrg must put something in these registers. Use a QNaN.
27941debfc3dSmrg
27951debfc3dSmrg Note that we are inserting converted code here. This code is
27961debfc3dSmrg never seen by the convert_regs pass. */
27971debfc3dSmrg
27981debfc3dSmrg FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
27991debfc3dSmrg {
28001debfc3dSmrg basic_block block = e->dest;
28011debfc3dSmrg block_info bi = BLOCK_INFO (block);
28021debfc3dSmrg int reg, top = -1;
28031debfc3dSmrg
28041debfc3dSmrg for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
28051debfc3dSmrg if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
28061debfc3dSmrg {
28071debfc3dSmrg rtx init;
28081debfc3dSmrg
28091debfc3dSmrg bi->stack_in.reg[++top] = reg;
28101debfc3dSmrg
28111debfc3dSmrg init = gen_rtx_SET (FP_MODE_REG (FIRST_STACK_REG, SFmode),
28121debfc3dSmrg not_a_num);
28131debfc3dSmrg insert_insn_on_edge (init, e);
28141debfc3dSmrg inserted = 1;
28151debfc3dSmrg }
28161debfc3dSmrg
28171debfc3dSmrg bi->stack_in.top = top;
28181debfc3dSmrg }
28191debfc3dSmrg
28201debfc3dSmrg return inserted;
28211debfc3dSmrg }
28221debfc3dSmrg
28231debfc3dSmrg /* Construct the desired stack for function exit. This will either
28241debfc3dSmrg be `empty', or the function return value at top-of-stack. */
28251debfc3dSmrg
28261debfc3dSmrg static void
convert_regs_exit(void)28271debfc3dSmrg convert_regs_exit (void)
28281debfc3dSmrg {
28291debfc3dSmrg int value_reg_low, value_reg_high;
28301debfc3dSmrg stack_ptr output_stack;
28311debfc3dSmrg rtx retvalue;
28321debfc3dSmrg
28331debfc3dSmrg retvalue = stack_result (current_function_decl);
28341debfc3dSmrg value_reg_low = value_reg_high = -1;
28351debfc3dSmrg if (retvalue)
28361debfc3dSmrg {
28371debfc3dSmrg value_reg_low = REGNO (retvalue);
28381debfc3dSmrg value_reg_high = END_REGNO (retvalue) - 1;
28391debfc3dSmrg }
28401debfc3dSmrg
28411debfc3dSmrg output_stack = &BLOCK_INFO (EXIT_BLOCK_PTR_FOR_FN (cfun))->stack_in;
28421debfc3dSmrg if (value_reg_low == -1)
28431debfc3dSmrg output_stack->top = -1;
28441debfc3dSmrg else
28451debfc3dSmrg {
28461debfc3dSmrg int reg;
28471debfc3dSmrg
28481debfc3dSmrg output_stack->top = value_reg_high - value_reg_low;
28491debfc3dSmrg for (reg = value_reg_low; reg <= value_reg_high; ++reg)
28501debfc3dSmrg {
28511debfc3dSmrg output_stack->reg[value_reg_high - reg] = reg;
28521debfc3dSmrg SET_HARD_REG_BIT (output_stack->reg_set, reg);
28531debfc3dSmrg }
28541debfc3dSmrg }
28551debfc3dSmrg }
28561debfc3dSmrg
28571debfc3dSmrg /* Copy the stack info from the end of edge E's source block to the
28581debfc3dSmrg start of E's destination block. */
28591debfc3dSmrg
28601debfc3dSmrg static void
propagate_stack(edge e)28611debfc3dSmrg propagate_stack (edge e)
28621debfc3dSmrg {
28631debfc3dSmrg stack_ptr src_stack = &BLOCK_INFO (e->src)->stack_out;
28641debfc3dSmrg stack_ptr dest_stack = &BLOCK_INFO (e->dest)->stack_in;
28651debfc3dSmrg int reg;
28661debfc3dSmrg
28671debfc3dSmrg /* Preserve the order of the original stack, but check whether
28681debfc3dSmrg any pops are needed. */
28691debfc3dSmrg dest_stack->top = -1;
28701debfc3dSmrg for (reg = 0; reg <= src_stack->top; ++reg)
28711debfc3dSmrg if (TEST_HARD_REG_BIT (dest_stack->reg_set, src_stack->reg[reg]))
28721debfc3dSmrg dest_stack->reg[++dest_stack->top] = src_stack->reg[reg];
28731debfc3dSmrg
28741debfc3dSmrg /* Push in any partially dead values. */
28751debfc3dSmrg for (reg = FIRST_STACK_REG; reg < LAST_STACK_REG + 1; reg++)
28761debfc3dSmrg if (TEST_HARD_REG_BIT (dest_stack->reg_set, reg)
28771debfc3dSmrg && !TEST_HARD_REG_BIT (src_stack->reg_set, reg))
28781debfc3dSmrg dest_stack->reg[++dest_stack->top] = reg;
28791debfc3dSmrg }
28801debfc3dSmrg
28811debfc3dSmrg
28821debfc3dSmrg /* Adjust the stack of edge E's source block on exit to match the stack
28831debfc3dSmrg of it's target block upon input. The stack layouts of both blocks
28841debfc3dSmrg should have been defined by now. */
28851debfc3dSmrg
28861debfc3dSmrg static bool
compensate_edge(edge e)28871debfc3dSmrg compensate_edge (edge e)
28881debfc3dSmrg {
28891debfc3dSmrg basic_block source = e->src, target = e->dest;
28901debfc3dSmrg stack_ptr target_stack = &BLOCK_INFO (target)->stack_in;
28911debfc3dSmrg stack_ptr source_stack = &BLOCK_INFO (source)->stack_out;
28921debfc3dSmrg struct stack_def regstack;
28931debfc3dSmrg int reg;
28941debfc3dSmrg
28951debfc3dSmrg if (dump_file)
28961debfc3dSmrg fprintf (dump_file, "Edge %d->%d: ", source->index, target->index);
28971debfc3dSmrg
28981debfc3dSmrg gcc_assert (target_stack->top != -2);
28991debfc3dSmrg
29001debfc3dSmrg /* Check whether stacks are identical. */
29011debfc3dSmrg if (target_stack->top == source_stack->top)
29021debfc3dSmrg {
29031debfc3dSmrg for (reg = target_stack->top; reg >= 0; --reg)
29041debfc3dSmrg if (target_stack->reg[reg] != source_stack->reg[reg])
29051debfc3dSmrg break;
29061debfc3dSmrg
29071debfc3dSmrg if (reg == -1)
29081debfc3dSmrg {
29091debfc3dSmrg if (dump_file)
29101debfc3dSmrg fprintf (dump_file, "no changes needed\n");
29111debfc3dSmrg return false;
29121debfc3dSmrg }
29131debfc3dSmrg }
29141debfc3dSmrg
29151debfc3dSmrg if (dump_file)
29161debfc3dSmrg {
29171debfc3dSmrg fprintf (dump_file, "correcting stack to ");
29181debfc3dSmrg print_stack (dump_file, target_stack);
29191debfc3dSmrg }
29201debfc3dSmrg
29211debfc3dSmrg /* Abnormal calls may appear to have values live in st(0), but the
29221debfc3dSmrg abnormal return path will not have actually loaded the values. */
29231debfc3dSmrg if (e->flags & EDGE_ABNORMAL_CALL)
29241debfc3dSmrg {
29251debfc3dSmrg /* Assert that the lifetimes are as we expect -- one value
29261debfc3dSmrg live at st(0) on the end of the source block, and no
29271debfc3dSmrg values live at the beginning of the destination block.
29281debfc3dSmrg For complex return values, we may have st(1) live as well. */
29291debfc3dSmrg gcc_assert (source_stack->top == 0 || source_stack->top == 1);
29301debfc3dSmrg gcc_assert (target_stack->top == -1);
29311debfc3dSmrg return false;
29321debfc3dSmrg }
29331debfc3dSmrg
29341debfc3dSmrg /* Handle non-call EH edges specially. The normal return path have
29351debfc3dSmrg values in registers. These will be popped en masse by the unwind
29361debfc3dSmrg library. */
29371debfc3dSmrg if (e->flags & EDGE_EH)
29381debfc3dSmrg {
29391debfc3dSmrg gcc_assert (target_stack->top == -1);
29401debfc3dSmrg return false;
29411debfc3dSmrg }
29421debfc3dSmrg
29431debfc3dSmrg /* We don't support abnormal edges. Global takes care to
29441debfc3dSmrg avoid any live register across them, so we should never
29451debfc3dSmrg have to insert instructions on such edges. */
29461debfc3dSmrg gcc_assert (! (e->flags & EDGE_ABNORMAL));
29471debfc3dSmrg
29481debfc3dSmrg /* Make a copy of source_stack as change_stack is destructive. */
29491debfc3dSmrg regstack = *source_stack;
29501debfc3dSmrg
29511debfc3dSmrg /* It is better to output directly to the end of the block
29521debfc3dSmrg instead of to the edge, because emit_swap can do minimal
29531debfc3dSmrg insn scheduling. We can do this when there is only one
29541debfc3dSmrg edge out, and it is not abnormal. */
29551debfc3dSmrg if (EDGE_COUNT (source->succs) == 1)
29561debfc3dSmrg {
29571debfc3dSmrg current_block = source;
29581debfc3dSmrg change_stack (BB_END (source), ®stack, target_stack,
29591debfc3dSmrg (JUMP_P (BB_END (source)) ? EMIT_BEFORE : EMIT_AFTER));
29601debfc3dSmrg }
29611debfc3dSmrg else
29621debfc3dSmrg {
29631debfc3dSmrg rtx_insn *seq;
29641debfc3dSmrg rtx_note *after;
29651debfc3dSmrg
29661debfc3dSmrg current_block = NULL;
29671debfc3dSmrg start_sequence ();
29681debfc3dSmrg
29691debfc3dSmrg /* ??? change_stack needs some point to emit insns after. */
29701debfc3dSmrg after = emit_note (NOTE_INSN_DELETED);
29711debfc3dSmrg
29721debfc3dSmrg change_stack (after, ®stack, target_stack, EMIT_BEFORE);
29731debfc3dSmrg
29741debfc3dSmrg seq = get_insns ();
29751debfc3dSmrg end_sequence ();
29761debfc3dSmrg
29778feb0f0bSmrg set_insn_locations (seq, e->goto_locus);
29781debfc3dSmrg insert_insn_on_edge (seq, e);
29791debfc3dSmrg return true;
29801debfc3dSmrg }
29811debfc3dSmrg return false;
29821debfc3dSmrg }
29831debfc3dSmrg
29841debfc3dSmrg /* Traverse all non-entry edges in the CFG, and emit the necessary
29851debfc3dSmrg edge compensation code to change the stack from stack_out of the
29861debfc3dSmrg source block to the stack_in of the destination block. */
29871debfc3dSmrg
29881debfc3dSmrg static bool
compensate_edges(void)29891debfc3dSmrg compensate_edges (void)
29901debfc3dSmrg {
29911debfc3dSmrg bool inserted = false;
29921debfc3dSmrg basic_block bb;
29931debfc3dSmrg
29941debfc3dSmrg starting_stack_p = false;
29951debfc3dSmrg
29961debfc3dSmrg FOR_EACH_BB_FN (bb, cfun)
29971debfc3dSmrg if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun))
29981debfc3dSmrg {
29991debfc3dSmrg edge e;
30001debfc3dSmrg edge_iterator ei;
30011debfc3dSmrg
30021debfc3dSmrg FOR_EACH_EDGE (e, ei, bb->succs)
30031debfc3dSmrg inserted |= compensate_edge (e);
30041debfc3dSmrg }
30051debfc3dSmrg return inserted;
30061debfc3dSmrg }
30071debfc3dSmrg
30081debfc3dSmrg /* Select the better of two edges E1 and E2 to use to determine the
30091debfc3dSmrg stack layout for their shared destination basic block. This is
30101debfc3dSmrg typically the more frequently executed. The edge E1 may be NULL
30111debfc3dSmrg (in which case E2 is returned), but E2 is always non-NULL. */
30121debfc3dSmrg
30131debfc3dSmrg static edge
better_edge(edge e1,edge e2)30141debfc3dSmrg better_edge (edge e1, edge e2)
30151debfc3dSmrg {
30161debfc3dSmrg if (!e1)
30171debfc3dSmrg return e2;
30181debfc3dSmrg
3019a2dc1f3fSmrg if (e1->count () > e2->count ())
30201debfc3dSmrg return e1;
3021a2dc1f3fSmrg if (e1->count () < e2->count ())
30221debfc3dSmrg return e2;
30231debfc3dSmrg
30241debfc3dSmrg /* Prefer critical edges to minimize inserting compensation code on
30251debfc3dSmrg critical edges. */
30261debfc3dSmrg
30271debfc3dSmrg if (EDGE_CRITICAL_P (e1) != EDGE_CRITICAL_P (e2))
30281debfc3dSmrg return EDGE_CRITICAL_P (e1) ? e1 : e2;
30291debfc3dSmrg
30301debfc3dSmrg /* Avoid non-deterministic behavior. */
30311debfc3dSmrg return (e1->src->index < e2->src->index) ? e1 : e2;
30321debfc3dSmrg }
30331debfc3dSmrg
30341debfc3dSmrg /* Convert stack register references in one block. Return true if the CFG
30351debfc3dSmrg has been modified in the process. */
30361debfc3dSmrg
30371debfc3dSmrg static bool
convert_regs_1(basic_block block)30381debfc3dSmrg convert_regs_1 (basic_block block)
30391debfc3dSmrg {
30401debfc3dSmrg struct stack_def regstack;
30411debfc3dSmrg block_info bi = BLOCK_INFO (block);
30421debfc3dSmrg int reg;
30431debfc3dSmrg rtx_insn *insn, *next;
30441debfc3dSmrg bool control_flow_insn_deleted = false;
30451debfc3dSmrg bool cfg_altered = false;
30461debfc3dSmrg int debug_insns_with_starting_stack = 0;
30471debfc3dSmrg
30481debfc3dSmrg any_malformed_asm = false;
30491debfc3dSmrg
30501debfc3dSmrg /* Choose an initial stack layout, if one hasn't already been chosen. */
30511debfc3dSmrg if (bi->stack_in.top == -2)
30521debfc3dSmrg {
30531debfc3dSmrg edge e, beste = NULL;
30541debfc3dSmrg edge_iterator ei;
30551debfc3dSmrg
30561debfc3dSmrg /* Select the best incoming edge (typically the most frequent) to
30571debfc3dSmrg use as a template for this basic block. */
30581debfc3dSmrg FOR_EACH_EDGE (e, ei, block->preds)
30591debfc3dSmrg if (BLOCK_INFO (e->src)->done)
30601debfc3dSmrg beste = better_edge (beste, e);
30611debfc3dSmrg
30621debfc3dSmrg if (beste)
30631debfc3dSmrg propagate_stack (beste);
30641debfc3dSmrg else
30651debfc3dSmrg {
30661debfc3dSmrg /* No predecessors. Create an arbitrary input stack. */
30671debfc3dSmrg bi->stack_in.top = -1;
30681debfc3dSmrg for (reg = LAST_STACK_REG; reg >= FIRST_STACK_REG; --reg)
30691debfc3dSmrg if (TEST_HARD_REG_BIT (bi->stack_in.reg_set, reg))
30701debfc3dSmrg bi->stack_in.reg[++bi->stack_in.top] = reg;
30711debfc3dSmrg }
30721debfc3dSmrg }
30731debfc3dSmrg
30741debfc3dSmrg if (dump_file)
30751debfc3dSmrg {
30761debfc3dSmrg fprintf (dump_file, "\nBasic block %d\nInput stack: ", block->index);
30771debfc3dSmrg print_stack (dump_file, &bi->stack_in);
30781debfc3dSmrg }
30791debfc3dSmrg
30801debfc3dSmrg /* Process all insns in this block. Keep track of NEXT so that we
30811debfc3dSmrg don't process insns emitted while substituting in INSN. */
30821debfc3dSmrg current_block = block;
30831debfc3dSmrg next = BB_HEAD (block);
30841debfc3dSmrg regstack = bi->stack_in;
30851debfc3dSmrg starting_stack_p = true;
30861debfc3dSmrg
30871debfc3dSmrg do
30881debfc3dSmrg {
30891debfc3dSmrg insn = next;
30901debfc3dSmrg next = NEXT_INSN (insn);
30911debfc3dSmrg
30921debfc3dSmrg /* Ensure we have not missed a block boundary. */
30931debfc3dSmrg gcc_assert (next);
30941debfc3dSmrg if (insn == BB_END (block))
30951debfc3dSmrg next = NULL;
30961debfc3dSmrg
30971debfc3dSmrg /* Don't bother processing unless there is a stack reg
30981debfc3dSmrg mentioned or if it's a CALL_INSN. */
3099a2dc1f3fSmrg if (DEBUG_BIND_INSN_P (insn))
31001debfc3dSmrg {
31011debfc3dSmrg if (starting_stack_p)
31021debfc3dSmrg debug_insns_with_starting_stack++;
31031debfc3dSmrg else
31041debfc3dSmrg {
31051debfc3dSmrg subst_all_stack_regs_in_debug_insn (insn, ®stack);
31061debfc3dSmrg
31071debfc3dSmrg /* Nothing must ever die at a debug insn. If something
31081debfc3dSmrg is referenced in it that becomes dead, it should have
31091debfc3dSmrg died before and the reference in the debug insn
31101debfc3dSmrg should have been removed so as to avoid changing code
31111debfc3dSmrg generation. */
31121debfc3dSmrg gcc_assert (!find_reg_note (insn, REG_DEAD, NULL));
31131debfc3dSmrg }
31141debfc3dSmrg }
31151debfc3dSmrg else if (stack_regs_mentioned (insn)
31161debfc3dSmrg || CALL_P (insn))
31171debfc3dSmrg {
31181debfc3dSmrg if (dump_file)
31191debfc3dSmrg {
31201debfc3dSmrg fprintf (dump_file, " insn %d input stack: ",
31211debfc3dSmrg INSN_UID (insn));
31221debfc3dSmrg print_stack (dump_file, ®stack);
31231debfc3dSmrg }
31241debfc3dSmrg control_flow_insn_deleted |= subst_stack_regs (insn, ®stack);
31251debfc3dSmrg starting_stack_p = false;
31261debfc3dSmrg }
31271debfc3dSmrg }
31281debfc3dSmrg while (next);
31291debfc3dSmrg
31301debfc3dSmrg if (debug_insns_with_starting_stack)
31311debfc3dSmrg {
31321debfc3dSmrg /* Since it's the first non-debug instruction that determines
31331debfc3dSmrg the stack requirements of the current basic block, we refrain
31341debfc3dSmrg from updating debug insns before it in the loop above, and
31351debfc3dSmrg fix them up here. */
31361debfc3dSmrg for (insn = BB_HEAD (block); debug_insns_with_starting_stack;
31371debfc3dSmrg insn = NEXT_INSN (insn))
31381debfc3dSmrg {
3139a2dc1f3fSmrg if (!DEBUG_BIND_INSN_P (insn))
31401debfc3dSmrg continue;
31411debfc3dSmrg
31421debfc3dSmrg debug_insns_with_starting_stack--;
31431debfc3dSmrg subst_all_stack_regs_in_debug_insn (insn, &bi->stack_in);
31441debfc3dSmrg }
31451debfc3dSmrg }
31461debfc3dSmrg
31471debfc3dSmrg if (dump_file)
31481debfc3dSmrg {
31491debfc3dSmrg fprintf (dump_file, "Expected live registers [");
31501debfc3dSmrg for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg)
31511debfc3dSmrg if (TEST_HARD_REG_BIT (bi->out_reg_set, reg))
31521debfc3dSmrg fprintf (dump_file, " %d", reg);
31531debfc3dSmrg fprintf (dump_file, " ]\nOutput stack: ");
31541debfc3dSmrg print_stack (dump_file, ®stack);
31551debfc3dSmrg }
31561debfc3dSmrg
31571debfc3dSmrg insn = BB_END (block);
31581debfc3dSmrg if (JUMP_P (insn))
31591debfc3dSmrg insn = PREV_INSN (insn);
31601debfc3dSmrg
31611debfc3dSmrg /* If the function is declared to return a value, but it returns one
31621debfc3dSmrg in only some cases, some registers might come live here. Emit
31631debfc3dSmrg necessary moves for them. */
31641debfc3dSmrg
31651debfc3dSmrg for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; ++reg)
31661debfc3dSmrg {
31671debfc3dSmrg if (TEST_HARD_REG_BIT (bi->out_reg_set, reg)
31681debfc3dSmrg && ! TEST_HARD_REG_BIT (regstack.reg_set, reg))
31691debfc3dSmrg {
31701debfc3dSmrg rtx set;
31711debfc3dSmrg
31721debfc3dSmrg if (dump_file)
31731debfc3dSmrg fprintf (dump_file, "Emitting insn initializing reg %d\n", reg);
31741debfc3dSmrg
31751debfc3dSmrg set = gen_rtx_SET (FP_MODE_REG (reg, SFmode), not_a_num);
31761debfc3dSmrg insn = emit_insn_after (set, insn);
31771debfc3dSmrg control_flow_insn_deleted |= subst_stack_regs (insn, ®stack);
31781debfc3dSmrg }
31791debfc3dSmrg }
31801debfc3dSmrg
31811debfc3dSmrg /* Amongst the insns possibly deleted during the substitution process above,
31821debfc3dSmrg might have been the only trapping insn in the block. We purge the now
31831debfc3dSmrg possibly dead EH edges here to avoid an ICE from fixup_abnormal_edges,
31841debfc3dSmrg called at the end of convert_regs. The order in which we process the
31851debfc3dSmrg blocks ensures that we never delete an already processed edge.
31861debfc3dSmrg
31871debfc3dSmrg Note that, at this point, the CFG may have been damaged by the emission
31881debfc3dSmrg of instructions after an abnormal call, which moves the basic block end
31891debfc3dSmrg (and is the reason why we call fixup_abnormal_edges later). So we must
31901debfc3dSmrg be sure that the trapping insn has been deleted before trying to purge
31911debfc3dSmrg dead edges, otherwise we risk purging valid edges.
31921debfc3dSmrg
31931debfc3dSmrg ??? We are normally supposed not to delete trapping insns, so we pretend
31941debfc3dSmrg that the insns deleted above don't actually trap. It would have been
31951debfc3dSmrg better to detect this earlier and avoid creating the EH edge in the first
31961debfc3dSmrg place, still, but we don't have enough information at that time. */
31971debfc3dSmrg
31981debfc3dSmrg if (control_flow_insn_deleted)
31991debfc3dSmrg cfg_altered |= purge_dead_edges (block);
32001debfc3dSmrg
32011debfc3dSmrg /* Something failed if the stack lives don't match. If we had malformed
32021debfc3dSmrg asms, we zapped the instruction itself, but that didn't produce the
32031debfc3dSmrg same pattern of register kills as before. */
32041debfc3dSmrg
32058feb0f0bSmrg gcc_assert (regstack.reg_set == bi->out_reg_set || any_malformed_asm);
32061debfc3dSmrg bi->stack_out = regstack;
32071debfc3dSmrg bi->done = true;
32081debfc3dSmrg
32091debfc3dSmrg return cfg_altered;
32101debfc3dSmrg }
32111debfc3dSmrg
32121debfc3dSmrg /* Convert registers in all blocks reachable from BLOCK. Return true if the
32131debfc3dSmrg CFG has been modified in the process. */
32141debfc3dSmrg
32151debfc3dSmrg static bool
convert_regs_2(basic_block block)32161debfc3dSmrg convert_regs_2 (basic_block block)
32171debfc3dSmrg {
32181debfc3dSmrg basic_block *stack, *sp;
32191debfc3dSmrg bool cfg_altered = false;
32201debfc3dSmrg
32211debfc3dSmrg /* We process the blocks in a top-down manner, in a way such that one block
32221debfc3dSmrg is only processed after all its predecessors. The number of predecessors
32231debfc3dSmrg of every block has already been computed. */
32241debfc3dSmrg
32251debfc3dSmrg stack = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
32261debfc3dSmrg sp = stack;
32271debfc3dSmrg
32281debfc3dSmrg *sp++ = block;
32291debfc3dSmrg
32301debfc3dSmrg do
32311debfc3dSmrg {
32321debfc3dSmrg edge e;
32331debfc3dSmrg edge_iterator ei;
32341debfc3dSmrg
32351debfc3dSmrg block = *--sp;
32361debfc3dSmrg
32371debfc3dSmrg /* Processing BLOCK is achieved by convert_regs_1, which may purge
32381debfc3dSmrg some dead EH outgoing edge after the deletion of the trapping
32391debfc3dSmrg insn inside the block. Since the number of predecessors of
32401debfc3dSmrg BLOCK's successors was computed based on the initial edge set,
32411debfc3dSmrg we check the necessity to process some of these successors
32421debfc3dSmrg before such an edge deletion may happen. However, there is
32431debfc3dSmrg a pitfall: if BLOCK is the only predecessor of a successor and
32441debfc3dSmrg the edge between them happens to be deleted, the successor
32451debfc3dSmrg becomes unreachable and should not be processed. The problem
32461debfc3dSmrg is that there is no way to preventively detect this case so we
32471debfc3dSmrg stack the successor in all cases and hand over the task of
32481debfc3dSmrg fixing up the discrepancy to convert_regs_1. */
32491debfc3dSmrg
32501debfc3dSmrg FOR_EACH_EDGE (e, ei, block->succs)
32511debfc3dSmrg if (! (e->flags & EDGE_DFS_BACK))
32521debfc3dSmrg {
32531debfc3dSmrg BLOCK_INFO (e->dest)->predecessors--;
32541debfc3dSmrg if (!BLOCK_INFO (e->dest)->predecessors)
32551debfc3dSmrg *sp++ = e->dest;
32561debfc3dSmrg }
32571debfc3dSmrg
32581debfc3dSmrg cfg_altered |= convert_regs_1 (block);
32591debfc3dSmrg }
32601debfc3dSmrg while (sp != stack);
32611debfc3dSmrg
32621debfc3dSmrg free (stack);
32631debfc3dSmrg
32641debfc3dSmrg return cfg_altered;
32651debfc3dSmrg }
32661debfc3dSmrg
32671debfc3dSmrg /* Traverse all basic blocks in a function, converting the register
32681debfc3dSmrg references in each insn from the "flat" register file that gcc uses,
32691debfc3dSmrg to the stack-like registers the 387 uses. */
32701debfc3dSmrg
32711debfc3dSmrg static void
convert_regs(void)32721debfc3dSmrg convert_regs (void)
32731debfc3dSmrg {
32741debfc3dSmrg bool cfg_altered = false;
32751debfc3dSmrg int inserted;
32761debfc3dSmrg basic_block b;
32771debfc3dSmrg edge e;
32781debfc3dSmrg edge_iterator ei;
32791debfc3dSmrg
32801debfc3dSmrg /* Initialize uninitialized registers on function entry. */
32811debfc3dSmrg inserted = convert_regs_entry ();
32821debfc3dSmrg
32831debfc3dSmrg /* Construct the desired stack for function exit. */
32841debfc3dSmrg convert_regs_exit ();
32851debfc3dSmrg BLOCK_INFO (EXIT_BLOCK_PTR_FOR_FN (cfun))->done = 1;
32861debfc3dSmrg
32871debfc3dSmrg /* ??? Future: process inner loops first, and give them arbitrary
32881debfc3dSmrg initial stacks which emit_swap_insn can modify. This ought to
32891debfc3dSmrg prevent double fxch that often appears at the head of a loop. */
32901debfc3dSmrg
32911debfc3dSmrg /* Process all blocks reachable from all entry points. */
32921debfc3dSmrg FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
32931debfc3dSmrg cfg_altered |= convert_regs_2 (e->dest);
32941debfc3dSmrg
32951debfc3dSmrg /* ??? Process all unreachable blocks. Though there's no excuse
32961debfc3dSmrg for keeping these even when not optimizing. */
32971debfc3dSmrg FOR_EACH_BB_FN (b, cfun)
32981debfc3dSmrg {
32991debfc3dSmrg block_info bi = BLOCK_INFO (b);
33001debfc3dSmrg
33011debfc3dSmrg if (! bi->done)
33021debfc3dSmrg cfg_altered |= convert_regs_2 (b);
33031debfc3dSmrg }
33041debfc3dSmrg
33051debfc3dSmrg /* We must fix up abnormal edges before inserting compensation code
33061debfc3dSmrg because both mechanisms insert insns on edges. */
33071debfc3dSmrg inserted |= fixup_abnormal_edges ();
33081debfc3dSmrg
33091debfc3dSmrg inserted |= compensate_edges ();
33101debfc3dSmrg
33111debfc3dSmrg clear_aux_for_blocks ();
33121debfc3dSmrg
33131debfc3dSmrg if (inserted)
33141debfc3dSmrg commit_edge_insertions ();
33151debfc3dSmrg
33161debfc3dSmrg if (cfg_altered)
33171debfc3dSmrg cleanup_cfg (0);
33181debfc3dSmrg
33191debfc3dSmrg if (dump_file)
33201debfc3dSmrg fputc ('\n', dump_file);
33211debfc3dSmrg }
33221debfc3dSmrg
33231debfc3dSmrg /* Convert register usage from "flat" register file usage to a "stack
33241debfc3dSmrg register file. FILE is the dump file, if used.
33251debfc3dSmrg
33261debfc3dSmrg Construct a CFG and run life analysis. Then convert each insn one
33271debfc3dSmrg by one. Run a last cleanup_cfg pass, if optimizing, to eliminate
33281debfc3dSmrg code duplication created when the converter inserts pop insns on
33291debfc3dSmrg the edges. */
33301debfc3dSmrg
33311debfc3dSmrg static bool
reg_to_stack(void)33321debfc3dSmrg reg_to_stack (void)
33331debfc3dSmrg {
33341debfc3dSmrg basic_block bb;
33351debfc3dSmrg int i;
33361debfc3dSmrg int max_uid;
33371debfc3dSmrg
33381debfc3dSmrg /* Clean up previous run. */
33391debfc3dSmrg stack_regs_mentioned_data.release ();
33401debfc3dSmrg
33411debfc3dSmrg /* See if there is something to do. Flow analysis is quite
33421debfc3dSmrg expensive so we might save some compilation time. */
33431debfc3dSmrg for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
33441debfc3dSmrg if (df_regs_ever_live_p (i))
33451debfc3dSmrg break;
33461debfc3dSmrg if (i > LAST_STACK_REG)
33471debfc3dSmrg return false;
33481debfc3dSmrg
33491debfc3dSmrg df_note_add_problem ();
33501debfc3dSmrg df_analyze ();
33511debfc3dSmrg
33521debfc3dSmrg mark_dfs_back_edges ();
33531debfc3dSmrg
33541debfc3dSmrg /* Set up block info for each basic block. */
33551debfc3dSmrg alloc_aux_for_blocks (sizeof (struct block_info_def));
33561debfc3dSmrg FOR_EACH_BB_FN (bb, cfun)
33571debfc3dSmrg {
33581debfc3dSmrg block_info bi = BLOCK_INFO (bb);
33591debfc3dSmrg edge_iterator ei;
33601debfc3dSmrg edge e;
33611debfc3dSmrg int reg;
33621debfc3dSmrg
33631debfc3dSmrg FOR_EACH_EDGE (e, ei, bb->preds)
33641debfc3dSmrg if (!(e->flags & EDGE_DFS_BACK)
33651debfc3dSmrg && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
33661debfc3dSmrg bi->predecessors++;
33671debfc3dSmrg
33681debfc3dSmrg /* Set current register status at last instruction `uninitialized'. */
33691debfc3dSmrg bi->stack_in.top = -2;
33701debfc3dSmrg
33711debfc3dSmrg /* Copy live_at_end and live_at_start into temporaries. */
33721debfc3dSmrg for (reg = FIRST_STACK_REG; reg <= LAST_STACK_REG; reg++)
33731debfc3dSmrg {
33741debfc3dSmrg if (REGNO_REG_SET_P (DF_LR_OUT (bb), reg))
33751debfc3dSmrg SET_HARD_REG_BIT (bi->out_reg_set, reg);
33761debfc3dSmrg if (REGNO_REG_SET_P (DF_LR_IN (bb), reg))
33771debfc3dSmrg SET_HARD_REG_BIT (bi->stack_in.reg_set, reg);
33781debfc3dSmrg }
33791debfc3dSmrg }
33801debfc3dSmrg
33811debfc3dSmrg /* Create the replacement registers up front. */
33821debfc3dSmrg for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
33831debfc3dSmrg {
33841debfc3dSmrg machine_mode mode;
3385a2dc1f3fSmrg FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
33861debfc3dSmrg FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
3387a2dc1f3fSmrg FOR_EACH_MODE_IN_CLASS (mode, MODE_COMPLEX_FLOAT)
33881debfc3dSmrg FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
33891debfc3dSmrg }
33901debfc3dSmrg
33911debfc3dSmrg ix86_flags_rtx = gen_rtx_REG (CCmode, FLAGS_REG);
33921debfc3dSmrg
33931debfc3dSmrg /* A QNaN for initializing uninitialized variables.
33941debfc3dSmrg
33951debfc3dSmrg ??? We can't load from constant memory in PIC mode, because
33961debfc3dSmrg we're inserting these instructions before the prologue and
33971debfc3dSmrg the PIC register hasn't been set up. In that case, fall back
33981debfc3dSmrg on zero, which we can get from `fldz'. */
33991debfc3dSmrg
34001debfc3dSmrg if ((flag_pic && !TARGET_64BIT)
34011debfc3dSmrg || ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)
34021debfc3dSmrg not_a_num = CONST0_RTX (SFmode);
34031debfc3dSmrg else
34041debfc3dSmrg {
34051debfc3dSmrg REAL_VALUE_TYPE r;
34061debfc3dSmrg
34071debfc3dSmrg real_nan (&r, "", 1, SFmode);
34081debfc3dSmrg not_a_num = const_double_from_real_value (r, SFmode);
34091debfc3dSmrg not_a_num = force_const_mem (SFmode, not_a_num);
34101debfc3dSmrg }
34111debfc3dSmrg
34121debfc3dSmrg /* Allocate a cache for stack_regs_mentioned. */
34131debfc3dSmrg max_uid = get_max_uid ();
34141debfc3dSmrg stack_regs_mentioned_data.create (max_uid + 1);
34151debfc3dSmrg memset (stack_regs_mentioned_data.address (),
34161debfc3dSmrg 0, sizeof (char) * (max_uid + 1));
34171debfc3dSmrg
34181debfc3dSmrg convert_regs ();
34191debfc3dSmrg
34201debfc3dSmrg free_aux_for_blocks ();
34211debfc3dSmrg return true;
34221debfc3dSmrg }
34231debfc3dSmrg #endif /* STACK_REGS */
34241debfc3dSmrg
34251debfc3dSmrg namespace {
34261debfc3dSmrg
34271debfc3dSmrg const pass_data pass_data_stack_regs =
34281debfc3dSmrg {
34291debfc3dSmrg RTL_PASS, /* type */
34301debfc3dSmrg "*stack_regs", /* name */
34311debfc3dSmrg OPTGROUP_NONE, /* optinfo_flags */
34321debfc3dSmrg TV_REG_STACK, /* tv_id */
34331debfc3dSmrg 0, /* properties_required */
34341debfc3dSmrg 0, /* properties_provided */
34351debfc3dSmrg 0, /* properties_destroyed */
34361debfc3dSmrg 0, /* todo_flags_start */
34371debfc3dSmrg 0, /* todo_flags_finish */
34381debfc3dSmrg };
34391debfc3dSmrg
34401debfc3dSmrg class pass_stack_regs : public rtl_opt_pass
34411debfc3dSmrg {
34421debfc3dSmrg public:
pass_stack_regs(gcc::context * ctxt)34431debfc3dSmrg pass_stack_regs (gcc::context *ctxt)
34441debfc3dSmrg : rtl_opt_pass (pass_data_stack_regs, ctxt)
34451debfc3dSmrg {}
34461debfc3dSmrg
34471debfc3dSmrg /* opt_pass methods: */
gate(function *)34481debfc3dSmrg virtual bool gate (function *)
34491debfc3dSmrg {
34501debfc3dSmrg #ifdef STACK_REGS
34511debfc3dSmrg return true;
34521debfc3dSmrg #else
34531debfc3dSmrg return false;
34541debfc3dSmrg #endif
34551debfc3dSmrg }
34561debfc3dSmrg
34571debfc3dSmrg }; // class pass_stack_regs
34581debfc3dSmrg
34591debfc3dSmrg } // anon namespace
34601debfc3dSmrg
34611debfc3dSmrg rtl_opt_pass *
make_pass_stack_regs(gcc::context * ctxt)34621debfc3dSmrg make_pass_stack_regs (gcc::context *ctxt)
34631debfc3dSmrg {
34641debfc3dSmrg return new pass_stack_regs (ctxt);
34651debfc3dSmrg }
34661debfc3dSmrg
34671debfc3dSmrg /* Convert register usage from flat register file usage to a stack
34681debfc3dSmrg register file. */
34691debfc3dSmrg static unsigned int
rest_of_handle_stack_regs(void)34701debfc3dSmrg rest_of_handle_stack_regs (void)
34711debfc3dSmrg {
34721debfc3dSmrg #ifdef STACK_REGS
34731debfc3dSmrg reg_to_stack ();
34741debfc3dSmrg regstack_completed = 1;
34751debfc3dSmrg #endif
34761debfc3dSmrg return 0;
34771debfc3dSmrg }
34781debfc3dSmrg
34791debfc3dSmrg namespace {
34801debfc3dSmrg
34811debfc3dSmrg const pass_data pass_data_stack_regs_run =
34821debfc3dSmrg {
34831debfc3dSmrg RTL_PASS, /* type */
34841debfc3dSmrg "stack", /* name */
34851debfc3dSmrg OPTGROUP_NONE, /* optinfo_flags */
34861debfc3dSmrg TV_REG_STACK, /* tv_id */
34871debfc3dSmrg 0, /* properties_required */
34881debfc3dSmrg 0, /* properties_provided */
34891debfc3dSmrg 0, /* properties_destroyed */
34901debfc3dSmrg 0, /* todo_flags_start */
34911debfc3dSmrg TODO_df_finish, /* todo_flags_finish */
34921debfc3dSmrg };
34931debfc3dSmrg
34941debfc3dSmrg class pass_stack_regs_run : public rtl_opt_pass
34951debfc3dSmrg {
34961debfc3dSmrg public:
pass_stack_regs_run(gcc::context * ctxt)34971debfc3dSmrg pass_stack_regs_run (gcc::context *ctxt)
34981debfc3dSmrg : rtl_opt_pass (pass_data_stack_regs_run, ctxt)
34991debfc3dSmrg {}
35001debfc3dSmrg
35011debfc3dSmrg /* opt_pass methods: */
execute(function *)35021debfc3dSmrg virtual unsigned int execute (function *)
35031debfc3dSmrg {
35041debfc3dSmrg return rest_of_handle_stack_regs ();
35051debfc3dSmrg }
35061debfc3dSmrg
35071debfc3dSmrg }; // class pass_stack_regs_run
35081debfc3dSmrg
35091debfc3dSmrg } // anon namespace
35101debfc3dSmrg
35111debfc3dSmrg rtl_opt_pass *
make_pass_stack_regs_run(gcc::context * ctxt)35121debfc3dSmrg make_pass_stack_regs_run (gcc::context *ctxt)
35131debfc3dSmrg {
35141debfc3dSmrg return new pass_stack_regs_run (ctxt);
35151debfc3dSmrg }
3516