Home | History | Annotate | Line # | Download | only in aarch64
aarch64-protos.h revision 1.3
      1 /* Machine description for AArch64 architecture.
      2    Copyright (C) 2009-2015 Free Software Foundation, Inc.
      3    Contributed by ARM Ltd.
      4 
      5    This file is part of GCC.
      6 
      7    GCC is free software; you can redistribute it and/or modify it
      8    under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    GCC is distributed in the hope that it will be useful, but
     13    WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15    General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GCC; see the file COPYING3.  If not see
     19    <http://www.gnu.org/licenses/>.  */
     20 
     21 
     22 #ifndef GCC_AARCH64_PROTOS_H
     23 #define GCC_AARCH64_PROTOS_H
     24 
     25 /*
     26   SYMBOL_CONTEXT_ADR
     27   The symbol is used in a load-address operation.
     28   SYMBOL_CONTEXT_MEM
     29   The symbol is used as the address in a MEM.
     30  */
     31 enum aarch64_symbol_context
     32 {
     33   SYMBOL_CONTEXT_MEM,
     34   SYMBOL_CONTEXT_ADR
     35 };
     36 
     37 /* SYMBOL_SMALL_ABSOLUTE: Generate symbol accesses through
     38    high and lo relocs that calculate the base address using a PC
     39    relative reloc.
     40    So to get the address of foo, we generate
     41    adrp x0, foo
     42    add  x0, x0, :lo12:foo
     43 
     44    To load or store something to foo, we could use the corresponding
     45    load store variants that generate an
     46    ldr x0, [x0,:lo12:foo]
     47    or
     48    str x1, [x0, :lo12:foo]
     49 
     50    This corresponds to the small code model of the compiler.
     51 
     52    SYMBOL_SMALL_GOT: Similar to the one above but this
     53    gives us the GOT entry of the symbol being referred to :
     54    Thus calculating the GOT entry for foo is done using the
     55    following sequence of instructions.  The ADRP instruction
     56    gets us to the page containing the GOT entry of the symbol
     57    and the got_lo12 gets us the actual offset in it.
     58 
     59    adrp  x0, :got:foo
     60    ldr   x0, [x0, :gotoff_lo12:foo]
     61 
     62    This corresponds to the small PIC model of the compiler.
     63 
     64    SYMBOL_SMALL_TLSGD
     65    SYMBOL_SMALL_TLSDESC
     66    SYMBOL_SMALL_GOTTPREL
     67    SYMBOL_SMALL_TPREL
     68    Each of of these represents a thread-local symbol, and corresponds to the
     69    thread local storage relocation operator for the symbol being referred to.
     70 
     71    SYMBOL_TINY_ABSOLUTE
     72 
     73    Generate symbol accesses as a PC relative address using a single
     74    instruction.  To compute the address of symbol foo, we generate:
     75 
     76    ADR x0, foo
     77 
     78    SYMBOL_TINY_GOT
     79 
     80    Generate symbol accesses via the GOT using a single PC relative
     81    instruction.  To compute the address of symbol foo, we generate:
     82 
     83    ldr t0, :got:foo
     84 
     85    The value of foo can subsequently read using:
     86 
     87    ldrb    t0, [t0]
     88 
     89    SYMBOL_FORCE_TO_MEM : Global variables are addressed using
     90    constant pool.  All variable addresses are spilled into constant
     91    pools.  The constant pools themselves are addressed using PC
     92    relative accesses.  This only works for the large code model.
     93  */
     94 enum aarch64_symbol_type
     95 {
     96   SYMBOL_SMALL_ABSOLUTE,
     97   SYMBOL_SMALL_GOT,
     98   SYMBOL_SMALL_TLSGD,
     99   SYMBOL_SMALL_TLSDESC,
    100   SYMBOL_SMALL_GOTTPREL,
    101   SYMBOL_SMALL_TPREL,
    102   SYMBOL_TINY_ABSOLUTE,
    103   SYMBOL_TINY_GOT,
    104   SYMBOL_FORCE_TO_MEM
    105 };
    106 
    107 /* A set of tuning parameters contains references to size and time
    108    cost models and vectors for address cost calculations, register
    109    move costs and memory move costs.  */
    110 
    111 /* Scaled addressing modes can vary cost depending on the mode of the
    112    value to be loaded/stored.  QImode values cannot use scaled
    113    addressing modes.  */
    114 
    115 struct scale_addr_mode_cost
    116 {
    117   const int hi;
    118   const int si;
    119   const int di;
    120   const int ti;
    121 };
    122 
    123 /* Additional cost for addresses.  */
    124 struct cpu_addrcost_table
    125 {
    126   const struct scale_addr_mode_cost addr_scale_costs;
    127   const int pre_modify;
    128   const int post_modify;
    129   const int register_offset;
    130   const int register_extend;
    131   const int imm_offset;
    132 };
    133 
    134 /* Additional costs for register copies.  Cost is for one register.  */
    135 struct cpu_regmove_cost
    136 {
    137   const int GP2GP;
    138   const int GP2FP;
    139   const int FP2GP;
    140   const int FP2FP;
    141 };
    142 
    143 /* Cost for vector insn classes.  */
    144 struct cpu_vector_cost
    145 {
    146   const int scalar_stmt_cost;		 /* Cost of any scalar operation,
    147 					    excluding load and store.  */
    148   const int scalar_load_cost;		 /* Cost of scalar load.  */
    149   const int scalar_store_cost;		 /* Cost of scalar store.  */
    150   const int vec_stmt_cost;		 /* Cost of any vector operation,
    151 					    excluding load, store,
    152 					    vector-to-scalar and
    153 					    scalar-to-vector operation.  */
    154   const int vec_to_scalar_cost;		 /* Cost of vec-to-scalar operation.  */
    155   const int scalar_to_vec_cost;		 /* Cost of scalar-to-vector
    156 					    operation.  */
    157   const int vec_align_load_cost;	 /* Cost of aligned vector load.  */
    158   const int vec_unalign_load_cost;	 /* Cost of unaligned vector load.  */
    159   const int vec_unalign_store_cost;	 /* Cost of unaligned vector store.  */
    160   const int vec_store_cost;		 /* Cost of vector store.  */
    161   const int cond_taken_branch_cost;	 /* Cost of taken branch.  */
    162   const int cond_not_taken_branch_cost;  /* Cost of not taken branch.  */
    163 };
    164 
    165 struct tune_params
    166 {
    167   const struct cpu_cost_table *const insn_extra_cost;
    168   const struct cpu_addrcost_table *const addr_cost;
    169   const struct cpu_regmove_cost *const regmove_cost;
    170   const struct cpu_vector_cost *const vec_costs;
    171   const int memmov_cost;
    172   const int issue_rate;
    173   const unsigned int fuseable_ops;
    174   const int function_align;
    175   const int jump_align;
    176   const int loop_align;
    177   const int int_reassoc_width;
    178   const int fp_reassoc_width;
    179   const int vec_reassoc_width;
    180 };
    181 
    182 HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
    183 int aarch64_get_condition_code (rtx);
    184 bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode);
    185 enum aarch64_symbol_type
    186 aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context);
    187 bool aarch64_cannot_change_mode_class (machine_mode,
    188 				       machine_mode,
    189 				       enum reg_class);
    190 bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
    191 bool aarch64_constant_address_p (rtx);
    192 bool aarch64_expand_movmem (rtx *);
    193 bool aarch64_float_const_zero_rtx_p (rtx);
    194 bool aarch64_function_arg_regno_p (unsigned);
    195 bool aarch64_gen_movmemqi (rtx *);
    196 bool aarch64_gimple_fold_builtin (gimple_stmt_iterator *);
    197 bool aarch64_is_extend_from_extract (machine_mode, rtx, rtx);
    198 bool aarch64_is_long_call_p (rtx);
    199 bool aarch64_label_mentioned_p (rtx);
    200 bool aarch64_legitimate_pic_operand_p (rtx);
    201 bool aarch64_modes_tieable_p (machine_mode mode1,
    202 			      machine_mode mode2);
    203 bool aarch64_zero_extend_const_eq (machine_mode, rtx, machine_mode, rtx);
    204 bool aarch64_move_imm (HOST_WIDE_INT, machine_mode);
    205 bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context,
    206 			    machine_mode);
    207 int aarch64_simd_attr_length_rglist (enum machine_mode);
    208 rtx aarch64_reverse_mask (enum machine_mode);
    209 bool aarch64_offset_7bit_signed_scaled_p (machine_mode, HOST_WIDE_INT);
    210 char *aarch64_output_scalar_simd_mov_immediate (rtx, machine_mode);
    211 char *aarch64_output_simd_mov_immediate (rtx, machine_mode, unsigned);
    212 bool aarch64_pad_arg_upward (machine_mode, const_tree);
    213 bool aarch64_pad_reg_upward (machine_mode, const_tree, bool);
    214 bool aarch64_regno_ok_for_base_p (int, bool);
    215 bool aarch64_regno_ok_for_index_p (int, bool);
    216 bool aarch64_simd_check_vect_par_cnst_half (rtx op, machine_mode mode,
    217 					    bool high);
    218 bool aarch64_simd_imm_scalar_p (rtx x, machine_mode mode);
    219 bool aarch64_simd_imm_zero_p (rtx, machine_mode);
    220 bool aarch64_simd_scalar_immediate_valid_for_move (rtx, machine_mode);
    221 bool aarch64_simd_shift_imm_p (rtx, machine_mode, bool);
    222 bool aarch64_simd_valid_immediate (rtx, machine_mode, bool,
    223 				   struct simd_immediate_info *);
    224 bool aarch64_symbolic_address_p (rtx);
    225 bool aarch64_uimm12_shift (HOST_WIDE_INT);
    226 bool aarch64_use_return_insn_p (void);
    227 const char *aarch64_mangle_builtin_type (const_tree);
    228 const char *aarch64_output_casesi (rtx *);
    229 const char *aarch64_rewrite_selected_cpu (const char *name);
    230 
    231 enum aarch64_symbol_type aarch64_classify_symbol (rtx, rtx,
    232 						  enum aarch64_symbol_context);
    233 enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx);
    234 enum reg_class aarch64_regno_regclass (unsigned);
    235 int aarch64_asm_preferred_eh_data_format (int, int);
    236 machine_mode aarch64_hard_regno_caller_save_mode (unsigned, unsigned,
    237 						       machine_mode);
    238 int aarch64_hard_regno_mode_ok (unsigned, machine_mode);
    239 int aarch64_hard_regno_nregs (unsigned, machine_mode);
    240 int aarch64_simd_attr_length_move (rtx_insn *);
    241 int aarch64_uxt_size (int, HOST_WIDE_INT);
    242 rtx aarch64_final_eh_return_addr (void);
    243 rtx aarch64_legitimize_reload_address (rtx *, machine_mode, int, int, int);
    244 const char *aarch64_output_move_struct (rtx *operands);
    245 rtx aarch64_return_addr (int, rtx);
    246 rtx aarch64_simd_gen_const_vector_dup (machine_mode, int);
    247 bool aarch64_simd_mem_operand_p (rtx);
    248 rtx aarch64_simd_vect_par_cnst_half (machine_mode, bool);
    249 rtx aarch64_tls_get_addr (void);
    250 tree aarch64_fold_builtin (tree, int, tree *, bool);
    251 unsigned aarch64_dbx_register_number (unsigned);
    252 unsigned aarch64_trampoline_size (void);
    253 void aarch64_asm_output_labelref (FILE *, const char *);
    254 void aarch64_elf_asm_named_section (const char *, unsigned, tree);
    255 void aarch64_expand_epilogue (bool);
    256 void aarch64_expand_mov_immediate (rtx, rtx);
    257 void aarch64_expand_prologue (void);
    258 void aarch64_expand_vector_init (rtx, rtx);
    259 void aarch64_init_cumulative_args (CUMULATIVE_ARGS *, const_tree, rtx,
    260 				   const_tree, unsigned);
    261 void aarch64_init_expanders (void);
    262 void aarch64_print_operand (FILE *, rtx, char);
    263 void aarch64_print_operand_address (FILE *, rtx);
    264 void aarch64_emit_call_insn (rtx);
    265 
    266 /* Initialize builtins for SIMD intrinsics.  */
    267 void init_aarch64_simd_builtins (void);
    268 
    269 void aarch64_simd_emit_reg_reg_move (rtx *, enum machine_mode, unsigned int);
    270 
    271 /* Emit code to place a AdvSIMD pair result in memory locations (with equal
    272    registers).  */
    273 void aarch64_simd_emit_pair_result_insn (machine_mode,
    274 					 rtx (*intfn) (rtx, rtx, rtx), rtx,
    275 					 rtx);
    276 
    277 /* Expand builtins for SIMD intrinsics.  */
    278 rtx aarch64_simd_expand_builtin (int, tree, rtx);
    279 
    280 void aarch64_simd_lane_bounds (rtx, HOST_WIDE_INT, HOST_WIDE_INT, const_tree);
    281 
    282 void aarch64_split_128bit_move (rtx, rtx);
    283 
    284 bool aarch64_split_128bit_move_p (rtx, rtx);
    285 
    286 void aarch64_split_simd_combine (rtx, rtx, rtx);
    287 
    288 void aarch64_split_simd_move (rtx, rtx);
    289 
    290 /* Check for a legitimate floating point constant for FMOV.  */
    291 bool aarch64_float_const_representable_p (rtx);
    292 
    293 #if defined (RTX_CODE)
    294 
    295 bool aarch64_legitimate_address_p (machine_mode, rtx, RTX_CODE, bool);
    296 machine_mode aarch64_select_cc_mode (RTX_CODE, rtx, rtx);
    297 rtx aarch64_gen_compare_reg (RTX_CODE, rtx, rtx);
    298 rtx aarch64_load_tp (rtx);
    299 
    300 void aarch64_expand_compare_and_swap (rtx op[]);
    301 void aarch64_split_compare_and_swap (rtx op[]);
    302 void aarch64_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx);
    303 
    304 bool aarch64_gen_adjusted_ldpstp (rtx *, bool, enum machine_mode, RTX_CODE);
    305 #endif /* RTX_CODE */
    306 
    307 void aarch64_init_builtins (void);
    308 rtx aarch64_expand_builtin (tree exp,
    309 			    rtx target,
    310 			    rtx subtarget ATTRIBUTE_UNUSED,
    311 			    machine_mode mode ATTRIBUTE_UNUSED,
    312 			    int ignore ATTRIBUTE_UNUSED);
    313 tree aarch64_builtin_decl (unsigned, bool ATTRIBUTE_UNUSED);
    314 
    315 tree
    316 aarch64_builtin_vectorized_function (tree fndecl,
    317 				     tree type_out,
    318 				     tree type_in);
    319 
    320 extern void aarch64_split_combinev16qi (rtx operands[3]);
    321 extern void aarch64_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
    322 extern bool aarch64_madd_needs_nop (rtx_insn *);
    323 extern void aarch64_final_prescan_insn (rtx_insn *);
    324 extern bool
    325 aarch64_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
    326 void aarch64_atomic_assign_expand_fenv (tree *, tree *, tree *);
    327 int aarch64_ccmp_mode_to_code (enum machine_mode mode);
    328 
    329 bool extract_base_offset_in_addr (rtx mem, rtx *base, rtx *offset);
    330 bool aarch64_operands_ok_for_ldpstp (rtx *, bool, enum machine_mode);
    331 bool aarch64_operands_adjust_ok_for_ldpstp (rtx *, bool, enum machine_mode);
    332 #endif /* GCC_AARCH64_PROTOS_H */
    333