1 /* Copyright (C) 1988-2019 Free Software Foundation, Inc.
3 This file is part of GCC.
5 GCC is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3, or (at your option)
10 GCC is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GCC; see the file COPYING3. If not see
17 <http://www.gnu.org/licenses/>. */
19 #ifndef GCC_I386_FEATURES_H
20 #define GCC_I386_FEATURES_H
25 XLOGUE_STUB_RESTORE_TAIL
,
27 XLOGUE_STUB_RESTORE_HFP
,
28 XLOGUE_STUB_RESTORE_HFP_TAIL
,
33 enum xlogue_stub_sets
{
35 XLOGUE_SET_ALIGNED_PLUS_8
,
36 XLOGUE_SET_HFP_ALIGNED_OR_REALIGN
,
37 XLOGUE_SET_HFP_ALIGNED_PLUS_8
,
42 /* Register save/restore layout used by out-of-line stubs. */
48 HOST_WIDE_INT offset
; /* Offset used by stub base pointer (rax or
49 rsi) to where each register is stored. */
52 unsigned get_nregs () const {return m_nregs
;}
53 HOST_WIDE_INT
get_stack_align_off_in () const {return m_stack_align_off_in
;}
55 const reginfo
&get_reginfo (unsigned reg
) const
57 gcc_assert (reg
< m_nregs
);
61 static const char *get_stub_name (enum xlogue_stub stub
,
62 unsigned n_extra_args
);
64 /* Returns an rtx for the stub's symbol based upon
65 1.) the specified stub (save, restore or restore_ret) and
66 2.) the value of cfun->machine->call_ms2sysv_extra_regs and
67 3.) rather or not stack alignment is being performed. */
68 static rtx
get_stub_rtx (enum xlogue_stub stub
);
70 /* Returns the amount of stack space (including padding) that the stub
71 needs to store registers based upon data in the machine_function. */
72 HOST_WIDE_INT
get_stack_space_used () const
74 const struct machine_function
*m
= cfun
->machine
;
75 unsigned last_reg
= m
->call_ms2sysv_extra_regs
+ MIN_REGS
- 1;
77 gcc_assert (m
->call_ms2sysv_extra_regs
<= MAX_EXTRA_REGS
);
78 return m_regs
[last_reg
].offset
+ STUB_INDEX_OFFSET
;
81 /* Returns the offset for the base pointer used by the stub. */
82 HOST_WIDE_INT
get_stub_ptr_offset () const
84 return STUB_INDEX_OFFSET
+ m_stack_align_off_in
;
87 static const class xlogue_layout
&get_instance ();
88 static unsigned count_stub_managed_regs ();
89 static bool is_stub_managed_reg (unsigned regno
, unsigned count
);
91 static const HOST_WIDE_INT STUB_INDEX_OFFSET
= 0x70;
92 static const unsigned MIN_REGS
= NUM_X86_64_MS_CLOBBERED_REGS
;
93 static const unsigned MAX_REGS
= 18;
94 static const unsigned MAX_EXTRA_REGS
= MAX_REGS
- MIN_REGS
;
95 static const unsigned VARIANT_COUNT
= MAX_EXTRA_REGS
+ 1;
96 static const unsigned STUB_NAME_MAX_LEN
= 20;
97 static const char * const STUB_BASE_NAMES
[XLOGUE_STUB_COUNT
];
98 static const unsigned REG_ORDER
[MAX_REGS
];
99 static const unsigned REG_ORDER_REALIGN
[MAX_REGS
];
103 xlogue_layout (HOST_WIDE_INT stack_align_off_in
, bool hfp
);
104 xlogue_layout (const xlogue_layout
&);
106 /* True if hard frame pointer is used. */
109 /* Max number of register this layout manages. */
112 /* Incoming offset from 16-byte alignment. */
113 HOST_WIDE_INT m_stack_align_off_in
;
115 /* Register order and offsets. */
116 struct reginfo m_regs
[MAX_REGS
];
118 /* Lazy-inited cache of symbol names for stubs. */
119 static char s_stub_names
[2][XLOGUE_STUB_COUNT
][VARIANT_COUNT
]
122 static const xlogue_layout s_instances
[XLOGUE_SET_COUNT
];
130 scalar_chain (enum machine_mode
, enum machine_mode
);
131 virtual ~scalar_chain ();
133 static unsigned max_id
;
136 enum machine_mode smode
;
138 enum machine_mode vmode
;
141 unsigned int chain_id
;
142 /* A queue of instructions to be included into a chain. */
144 /* Instructions included into a chain. */
146 /* All registers defined by a chain. */
148 /* Registers used in both vector and sclar modes. */
151 void build (bitmap candidates
, unsigned insn_uid
);
152 virtual int compute_convert_gain () = 0;
156 void add_to_queue (unsigned insn_uid
);
157 void emit_conversion_insns (rtx insns
, rtx_insn
*pos
);
160 void add_insn (bitmap candidates
, unsigned insn_uid
);
161 void analyze_register_chain (bitmap candidates
, df_ref ref
);
162 virtual void mark_dual_mode_def (df_ref def
) = 0;
163 virtual void convert_insn (rtx_insn
*insn
) = 0;
164 virtual void convert_registers () = 0;
167 class general_scalar_chain
: public scalar_chain
170 general_scalar_chain (enum machine_mode smode_
, enum machine_mode vmode_
)
171 : scalar_chain (smode_
, vmode_
) {}
172 int compute_convert_gain ();
174 void mark_dual_mode_def (df_ref def
);
175 rtx
replace_with_subreg (rtx x
, rtx reg
, rtx subreg
);
176 void replace_with_subreg_in_insn (rtx_insn
*insn
, rtx reg
, rtx subreg
);
177 void convert_insn (rtx_insn
*insn
);
178 void convert_op (rtx
*op
, rtx_insn
*insn
);
179 void convert_reg (unsigned regno
);
180 void make_vector_copies (unsigned regno
);
181 void convert_registers ();
182 int vector_const_cost (rtx exp
);
185 class timode_scalar_chain
: public scalar_chain
188 timode_scalar_chain () : scalar_chain (TImode
, V1TImode
) {}
190 /* Convert from TImode to V1TImode is always faster. */
191 int compute_convert_gain () { return 1; }
194 void mark_dual_mode_def (df_ref def
);
195 void fix_debug_reg_uses (rtx reg
);
196 void convert_insn (rtx_insn
*insn
);
197 /* We don't convert registers to difference size. */
198 void convert_registers () {}
203 bool ix86_save_reg (unsigned int regno
, bool maybe_eh_return
, bool ignore_outlined
);
204 int ix86_compare_version_priority (tree decl1
, tree decl2
);
205 tree
ix86_generate_version_dispatcher_body (void *node_p
);
206 tree
ix86_get_function_versions_dispatcher (void *decl
);
207 tree
ix86_mangle_decl_assembler_name (tree decl
, tree id
);
210 #endif /* GCC_I386_FEATURES_H */