Home | History | Annotate | Line # | Download | only in sh
      1   1.1  mrg /* Definitions of target machine for GNU compiler for Renesas / SuperH SH.
      2  1.13  mrg    Copyright (C) 1993-2022 Free Software Foundation, Inc.
      3   1.1  mrg    Contributed by Steve Chamberlain (sac (at) cygnus.com).
      4   1.1  mrg    Improved by Jim Wilson (wilson (at) cygnus.com).
      5   1.1  mrg 
      6   1.1  mrg This file is part of GCC.
      7   1.1  mrg 
      8   1.1  mrg GCC is free software; you can redistribute it and/or modify
      9   1.1  mrg it under the terms of the GNU General Public License as published by
     10   1.1  mrg the Free Software Foundation; either version 3, or (at your option)
     11   1.1  mrg any later version.
     12   1.1  mrg 
     13   1.1  mrg GCC is distributed in the hope that it will be useful,
     14   1.1  mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
     15   1.1  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16   1.1  mrg GNU General Public License for more details.
     17   1.1  mrg 
     18   1.1  mrg You should have received a copy of the GNU General Public License
     19   1.1  mrg along with GCC; see the file COPYING3.  If not see
     20   1.1  mrg <http://www.gnu.org/licenses/>.  */
     21   1.1  mrg 
     22   1.1  mrg #ifndef GCC_SH_PROTOS_H
     23   1.1  mrg #define GCC_SH_PROTOS_H
     24   1.1  mrg 
     25   1.1  mrg enum sh_function_kind {
     26   1.1  mrg   /* A function with normal C ABI  */
     27   1.1  mrg   FUNCTION_ORDINARY,
     28   1.1  mrg   /* A special function that guarantees that some otherwise call-clobbered
     29   1.1  mrg      registers are not clobbered.  These can't go through the SH5 resolver,
     30   1.1  mrg      because it only saves argument passing registers.  */
     31   1.1  mrg   SFUNC_GOT,
     32   1.1  mrg   /* A special function that should be linked statically.  These are typically
     33   1.1  mrg      smaller or not much larger than a PLT entry.
     34   1.1  mrg      Some also have a non-standard ABI which precludes dynamic linking.  */
     35   1.1  mrg   SFUNC_STATIC
     36   1.1  mrg };
     37   1.1  mrg 
     38   1.1  mrg #ifdef RTX_CODE
     39   1.1  mrg extern rtx sh_fsca_sf2int (void);
     40   1.1  mrg extern rtx sh_fsca_int2sf (void);
     41   1.1  mrg 
     42  1.13  mrg /* Declare functions defined in sh.cc and used in templates.  */
     43   1.5  mrg extern bool sh_lra_p (void);
     44   1.1  mrg 
     45   1.5  mrg extern const char *output_branch (int, rtx_insn *, rtx *);
     46   1.5  mrg extern const char *output_ieee_ccmpeq (rtx_insn *, rtx *);
     47   1.5  mrg extern const char *output_branchy_insn (enum rtx_code, const char *,
     48   1.5  mrg 					rtx_insn *, rtx *);
     49   1.5  mrg extern const char *output_movedouble (rtx, rtx[], machine_mode);
     50   1.5  mrg extern const char *output_movepcrel (rtx, rtx[], machine_mode);
     51   1.5  mrg extern const char *output_far_jump (rtx_insn *, rtx);
     52   1.5  mrg 
     53   1.5  mrg extern rtx sfunc_uses_reg (rtx_insn *);
     54   1.5  mrg extern int barrier_align (rtx_insn *);
     55   1.5  mrg extern int sh_loop_align (rtx_insn *);
     56   1.3  mrg extern bool fp_zero_operand (rtx);
     57   1.3  mrg extern bool fp_one_operand (rtx);
     58   1.5  mrg extern bool sh_legitimate_index_p (machine_mode, rtx, bool, bool);
     59   1.5  mrg extern bool sh_legitimize_reload_address (rtx *, machine_mode, int, int);
     60   1.5  mrg extern rtx legitimize_pic_address (rtx, machine_mode, rtx);
     61   1.3  mrg extern bool nonpic_symbol_mentioned_p (rtx);
     62   1.1  mrg extern void output_pic_addr_const (FILE *, rtx);
     63   1.3  mrg extern bool expand_block_move (rtx *);
     64   1.5  mrg extern void prepare_move_operands (rtx[], machine_mode mode);
     65   1.5  mrg extern bool sh_expand_cmpstr (rtx *);
     66   1.5  mrg extern bool sh_expand_cmpnstr (rtx *);
     67   1.5  mrg extern bool sh_expand_strlen  (rtx *);
     68   1.5  mrg extern void sh_expand_setmem (rtx *);
     69   1.5  mrg extern enum rtx_code prepare_cbranch_operands (rtx *, machine_mode mode,
     70   1.1  mrg 					       enum rtx_code comparison);
     71  1.10  mrg extern void expand_cbranchsi4 (rtx *operands, enum rtx_code comparison);
     72   1.1  mrg extern bool expand_cbranchdi4 (rtx *operands, enum rtx_code comparison);
     73   1.1  mrg extern void sh_emit_scc_to_t (enum rtx_code, rtx, rtx);
     74   1.5  mrg extern void sh_emit_compare_and_branch (rtx *, machine_mode);
     75   1.5  mrg extern void sh_emit_compare_and_set (rtx *, machine_mode);
     76   1.3  mrg extern bool sh_ashlsi_clobbers_t_reg_p (rtx);
     77   1.3  mrg extern bool sh_lshrsi_clobbers_t_reg_p (rtx);
     78   1.1  mrg extern void gen_shifty_op (int, rtx *);
     79   1.1  mrg extern void gen_shifty_hi_op (int, rtx *);
     80   1.3  mrg extern bool expand_ashiftrt (rtx *);
     81   1.3  mrg extern bool sh_dynamicalize_shift_p (rtx);
     82   1.1  mrg extern int shl_and_kind (rtx, rtx, int *);
     83   1.1  mrg extern int shl_and_length (rtx);
     84   1.1  mrg extern int shl_and_scr_length (rtx);
     85   1.3  mrg extern bool gen_shl_and (rtx, rtx, rtx, rtx);
     86   1.1  mrg extern int shl_sext_kind (rtx, rtx, int *);
     87   1.1  mrg extern int shl_sext_length (rtx);
     88   1.3  mrg extern bool gen_shl_sext (rtx, rtx, rtx, rtx);
     89   1.1  mrg extern int regs_used (rtx, int);
     90   1.5  mrg extern void fixup_addr_diff_vecs (rtx_insn *);
     91  1.11  mrg extern int get_dest_uid (rtx_insn *, int);
     92   1.5  mrg extern void final_prescan_insn (rtx_insn *, rtx *, int);
     93   1.5  mrg extern enum tls_model tls_symbolic_operand (rtx, machine_mode);
     94   1.5  mrg extern bool system_reg_operand (rtx, machine_mode);
     95   1.5  mrg extern bool reg_unused_after (rtx, rtx_insn *);
     96   1.5  mrg extern int sh_insn_length_adjustment (rtx_insn *);
     97   1.3  mrg extern bool sh_expand_t_scc (rtx *);
     98   1.5  mrg extern rtx sh_gen_truncate (machine_mode, rtx, int);
     99   1.5  mrg extern bool sh_vector_mode_supported_p (machine_mode);
    100   1.3  mrg extern bool sh_cfun_trap_exit_p (void);
    101   1.5  mrg extern rtx sh_find_equiv_gbr_addr (rtx_insn* cur_insn, rtx mem);
    102   1.3  mrg extern int sh_eval_treg_value (rtx op);
    103   1.3  mrg extern HOST_WIDE_INT sh_disp_addr_displacement (rtx mem_op);
    104   1.3  mrg extern int sh_max_mov_insn_displacement (machine_mode mode, bool consider_sh2a);
    105   1.5  mrg extern bool sh_movsf_ie_ra_split_p (rtx, rtx, rtx);
    106   1.6  mrg extern void sh_expand_sym_label2reg (rtx, rtx, rtx, bool);
    107   1.3  mrg 
    108   1.3  mrg /* Result value of sh_find_set_of_reg.  */
    109   1.3  mrg struct set_of_reg
    110   1.3  mrg {
    111   1.3  mrg   /* The insn where sh_find_set_of_reg stopped looking.
    112   1.3  mrg      Can be NULL_RTX if the end of the insn list was reached.  */
    113   1.5  mrg   rtx_insn* insn;
    114   1.3  mrg 
    115   1.3  mrg   /* The set rtx of the specified reg if found, NULL_RTX otherwise.  */
    116   1.3  mrg   const_rtx set_rtx;
    117   1.3  mrg 
    118   1.3  mrg   /* The set source rtx of the specified reg if found, NULL_RTX otherwise.
    119   1.3  mrg      Usually, this is the most interesting return value.  */
    120   1.3  mrg   rtx set_src;
    121   1.3  mrg };
    122   1.3  mrg 
    123  1.10  mrg /* Given a reg rtx and a start insn, try to find the insn that sets
    124  1.10  mrg    the specified reg by using the specified insn stepping function,
    125  1.10  mrg    such as 'prev_nonnote_nondebug_insn_bb'.  When the insn is found,
    126  1.10  mrg    try to extract the rtx of the reg set.  */
    127   1.5  mrg template <typename F> inline set_of_reg
    128   1.5  mrg sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
    129   1.5  mrg 		    bool ignore_reg_reg_copies = false)
    130   1.5  mrg {
    131   1.5  mrg   set_of_reg result;
    132   1.5  mrg   result.insn = insn;
    133   1.5  mrg   result.set_rtx = NULL_RTX;
    134   1.5  mrg   result.set_src = NULL_RTX;
    135   1.5  mrg 
    136   1.5  mrg   if (!REG_P (reg) || insn == NULL_RTX)
    137   1.5  mrg     return result;
    138   1.5  mrg 
    139   1.5  mrg   for (rtx_insn* i = stepfunc (insn); i != NULL_RTX; i = stepfunc (i))
    140   1.5  mrg     {
    141   1.5  mrg       if (BARRIER_P (i))
    142   1.5  mrg 	break;
    143   1.5  mrg       if (!INSN_P (i) || DEBUG_INSN_P (i))
    144   1.5  mrg 	  continue;
    145   1.5  mrg       if (reg_set_p (reg, i))
    146   1.5  mrg 	{
    147   1.5  mrg 	  if (CALL_P (i))
    148   1.5  mrg 	    break;
    149   1.5  mrg 
    150   1.5  mrg 	  result.insn = i;
    151   1.5  mrg 	  result.set_rtx = set_of (reg, i);
    152   1.5  mrg 
    153   1.5  mrg 	  if (result.set_rtx == NULL_RTX || GET_CODE (result.set_rtx) != SET)
    154   1.5  mrg 	    break;
    155   1.5  mrg 
    156   1.5  mrg 	  result.set_src = XEXP (result.set_rtx, 1);
    157   1.5  mrg 
    158   1.5  mrg 	  if (ignore_reg_reg_copies && REG_P (result.set_src))
    159   1.5  mrg 	    {
    160   1.5  mrg 	      reg = result.set_src;
    161   1.5  mrg 	      continue;
    162   1.5  mrg 	    }
    163   1.5  mrg 	  if (ignore_reg_reg_copies && SUBREG_P (result.set_src)
    164   1.5  mrg 	      && REG_P (SUBREG_REG (result.set_src)))
    165   1.5  mrg 	    {
    166   1.5  mrg 	      reg = SUBREG_REG (result.set_src);
    167   1.5  mrg 	      continue;
    168   1.5  mrg 	    }
    169   1.5  mrg 
    170   1.5  mrg 	  break;
    171   1.5  mrg 	}
    172   1.5  mrg     }
    173   1.5  mrg 
    174   1.7  mrg   /* If the searched reg is found inside a (mem (post_inc:SI (reg))), set_of
    175   1.7  mrg      will return NULL and set_rtx will be NULL.
    176   1.7  mrg      In this case report a 'not found'.  result.insn will always be non-null
    177   1.7  mrg      at this point, so no need to check it.  */
    178   1.7  mrg   if (result.set_src != NULL && result.set_rtx == NULL)
    179   1.7  mrg     result.set_src = NULL;
    180   1.9  mrg 
    181   1.5  mrg   return result;
    182   1.5  mrg }
    183   1.5  mrg 
    184   1.5  mrg /* Result value of sh_find_extending_set_of_reg.  */
    185   1.5  mrg struct sh_extending_set_of_reg : public set_of_reg
    186   1.5  mrg {
    187   1.5  mrg   /* The mode the set is extending from (QImode or HImode), or VOIDmode if
    188   1.5  mrg      this is not a zero/sign extending set.  */
    189   1.5  mrg   machine_mode from_mode;
    190   1.5  mrg 
    191   1.5  mrg   /* ZERO_EXTEND, SIGN_EXTEND or UNKNOWN.  */
    192   1.5  mrg   rtx_code ext_code;
    193   1.5  mrg 
    194   1.5  mrg   sh_extending_set_of_reg (rtx_insn* i)
    195   1.5  mrg   {
    196   1.5  mrg     insn = i;
    197   1.5  mrg     set_rtx = NULL;
    198   1.5  mrg     set_src = NULL;
    199   1.5  mrg     from_mode = VOIDmode;
    200   1.5  mrg     ext_code = UNKNOWN;
    201   1.5  mrg   }
    202   1.5  mrg 
    203   1.5  mrg   sh_extending_set_of_reg (const set_of_reg& rhs)
    204   1.5  mrg   {
    205   1.5  mrg     *((set_of_reg*)this) = rhs;
    206   1.5  mrg     from_mode = VOIDmode;
    207   1.5  mrg     ext_code = UNKNOWN;
    208   1.5  mrg   }
    209   1.5  mrg 
    210   1.5  mrg   /* Returns true if it's possible to use the source reg of the sign
    211   1.5  mrg      or zero extending set directly, bypassing the extension.  */
    212   1.5  mrg   bool can_use_as_unextended_reg (void) const;
    213   1.5  mrg 
    214   1.5  mrg   /* Returns the reg rtx of the sign or zero extending set source, that can
    215   1.5  mrg      be safely used at the specified insn in SImode.  */
    216   1.5  mrg   rtx use_as_unextended_reg (rtx_insn* use_at_insn) const;
    217   1.5  mrg 
    218   1.5  mrg   /* Returns the reg rtx of the sign or zero extending result, that can be
    219   1.5  mrg      safely used at the specified insn in SImode.  If the set source is an
    220   1.5  mrg      implicitly sign extending mem load, the mem load is converted into an
    221   1.5  mrg      explicitly sign extending mem load.  */
    222   1.5  mrg   rtx use_as_extended_reg (rtx_insn* use_at_insn) const;
    223   1.5  mrg };
    224   1.5  mrg 
    225   1.5  mrg extern sh_extending_set_of_reg sh_find_extending_set_of_reg (rtx reg,
    226   1.5  mrg 							     rtx_insn* insn);
    227   1.5  mrg 
    228   1.5  mrg extern bool sh_is_logical_t_store_expr (rtx op, rtx_insn* insn);
    229   1.5  mrg extern rtx sh_try_omit_signzero_extend (rtx extended_op, rtx_insn* insn);
    230   1.5  mrg extern bool sh_split_movrt_negc_to_movt_xor (rtx_insn* curr_insn,
    231   1.5  mrg 					     rtx operands[]);
    232   1.5  mrg extern void sh_split_tst_subregs (rtx_insn* curr_insn,
    233   1.5  mrg 				  machine_mode subreg_mode, int subreg_offset,
    234   1.5  mrg 				  rtx operands[]);
    235   1.5  mrg 
    236   1.5  mrg extern bool sh_is_nott_insn (const rtx_insn* i);
    237   1.5  mrg extern rtx sh_movt_set_dest (const rtx_insn* i);
    238   1.9  mrg extern rtx sh_movt_set_dest (const_rtx i);
    239   1.5  mrg extern rtx sh_movrt_set_dest (const rtx_insn* i);
    240   1.9  mrg extern rtx sh_movrt_set_dest (const_rtx i);
    241   1.5  mrg 
    242   1.5  mrg inline bool sh_is_movt_insn (const rtx_insn* i)
    243   1.5  mrg {
    244   1.5  mrg   return sh_movt_set_dest (i) != NULL;
    245   1.5  mrg }
    246   1.5  mrg 
    247   1.5  mrg inline bool sh_is_movrt_insn (const rtx_insn* i)
    248   1.5  mrg {
    249   1.5  mrg   return sh_movrt_set_dest (i) != NULL;
    250   1.5  mrg }
    251   1.5  mrg 
    252   1.5  mrg extern bool sh_insn_operands_modified_between_p (rtx_insn* operands_insn,
    253   1.5  mrg 						 const rtx_insn* from,
    254   1.5  mrg 						 const rtx_insn* to);
    255   1.5  mrg 
    256   1.5  mrg extern bool sh_reg_dead_or_unused_after_insn (const rtx_insn* i, int regno);
    257   1.5  mrg extern void sh_remove_reg_dead_or_unused_notes (rtx_insn* i, int regno);
    258   1.5  mrg extern rtx_insn* sh_check_add_incdec_notes (rtx_insn* i);
    259   1.5  mrg extern rtx sh_remove_overlapping_post_inc (rtx dst, rtx src);
    260   1.5  mrg extern rtx_insn* sh_peephole_emit_move_insn (rtx dst, rtx src);
    261   1.5  mrg 
    262   1.5  mrg extern bool sh_in_recog_treg_set_expr (void);
    263   1.5  mrg extern bool sh_recog_treg_set_expr (rtx op, machine_mode mode);
    264   1.5  mrg 
    265   1.5  mrg /* Result value of sh_split_treg_set_expr.  Contains the first insn emitted
    266   1.5  mrg    and the optional trailing nott insn.  */
    267   1.5  mrg class sh_treg_insns
    268   1.5  mrg {
    269   1.5  mrg public:
    270   1.5  mrg   sh_treg_insns (void) : m_first_insn (NULL), m_trailing_nott_insn (NULL) { }
    271   1.5  mrg   sh_treg_insns (rtx_insn* first_insn, rtx_insn* nott_insn)
    272   1.5  mrg   : m_first_insn (first_insn),
    273   1.5  mrg     m_trailing_nott_insn (nott_insn)
    274   1.5  mrg   { }
    275   1.5  mrg 
    276   1.5  mrg   bool was_treg_operand (void) const { return m_first_insn == NULL; }
    277   1.5  mrg   bool has_trailing_nott (void) const { return m_trailing_nott_insn != NULL; }
    278   1.5  mrg   rtx_insn* trailing_nott (void) const { return m_trailing_nott_insn; }
    279   1.5  mrg   rtx_insn* first_insn (void) const { return m_first_insn; }
    280   1.5  mrg 
    281   1.5  mrg   /* If there is a trailing nott, remove it from the emitted insns and
    282   1.5  mrg      return true.  Return false otherwise.  */
    283   1.5  mrg   bool
    284   1.5  mrg   remove_trailing_nott (void)
    285   1.5  mrg   {
    286   1.5  mrg     if (!has_trailing_nott ())
    287   1.5  mrg       return false;
    288   1.5  mrg 
    289   1.5  mrg     remove_insn (trailing_nott ());
    290   1.5  mrg     return true;
    291   1.5  mrg   }
    292   1.5  mrg 
    293   1.5  mrg private:
    294   1.5  mrg   rtx_insn* m_first_insn;
    295   1.5  mrg   rtx_insn* m_trailing_nott_insn;
    296   1.5  mrg };
    297   1.5  mrg 
    298   1.5  mrg extern sh_treg_insns sh_split_treg_set_expr (rtx x, rtx_insn* curr_insn);
    299   1.5  mrg 
    300   1.9  mrg enum
    301   1.9  mrg {
    302   1.9  mrg   /* An effective conditional branch distance of zero bytes is impossible.
    303   1.9  mrg      Hence we can use it to designate an unknown value.  */
    304   1.9  mrg   unknown_cbranch_distance = 0u,
    305   1.9  mrg   infinite_cbranch_distance = ~0u
    306   1.9  mrg };
    307   1.9  mrg 
    308   1.9  mrg unsigned int
    309   1.9  mrg sh_cbranch_distance (rtx_insn* cbranch_insn,
    310   1.9  mrg 		     unsigned int max_dist = infinite_cbranch_distance);
    311   1.9  mrg 
    312   1.1  mrg #endif /* RTX_CODE */
    313   1.1  mrg 
    314   1.3  mrg extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
    315   1.3  mrg 
    316   1.1  mrg extern const char *output_jump_label_table (void);
    317   1.3  mrg extern rtx get_t_reg_rtx (void);
    318   1.1  mrg extern void sh_expand_prologue (void);
    319   1.1  mrg extern void sh_expand_epilogue (bool);
    320   1.1  mrg extern void sh_set_return_address (rtx, rtx);
    321   1.1  mrg extern int initial_elimination_offset (int, int);
    322   1.3  mrg extern bool sh_hard_regno_rename_ok (unsigned int, unsigned int);
    323   1.3  mrg extern bool sh_cfun_interrupt_handler_p (void);
    324   1.3  mrg extern bool sh_cfun_resbank_handler_p (void);
    325   1.3  mrg extern bool sh_attr_renesas_p (const_tree);
    326   1.3  mrg extern bool sh_cfun_attr_renesas_p (void);
    327   1.5  mrg extern bool sh_small_register_classes_for_mode_p (machine_mode);
    328   1.1  mrg extern void sh_mark_label (rtx, int);
    329   1.5  mrg extern bool check_use_sfunc_addr (rtx_insn *, rtx);
    330   1.1  mrg 
    331   1.1  mrg #ifdef HARD_CONST
    332   1.1  mrg extern void fpscr_set_from_mem (int, HARD_REG_SET);
    333   1.1  mrg #endif
    334   1.1  mrg 
    335   1.1  mrg extern void sh_pr_interrupt (struct cpp_reader *);
    336   1.1  mrg extern void sh_pr_trapa (struct cpp_reader *);
    337   1.1  mrg extern void sh_pr_nosave_low_regs (struct cpp_reader *);
    338   1.6  mrg 
    339   1.6  mrg struct function_symbol_result
    340   1.6  mrg {
    341   1.6  mrg   function_symbol_result (void) : sym (NULL), lab (NULL) { }
    342   1.6  mrg   function_symbol_result (rtx s, rtx l) : sym (s), lab (l) { }
    343   1.6  mrg 
    344   1.6  mrg   rtx sym;
    345   1.6  mrg   rtx lab;
    346   1.6  mrg };
    347   1.6  mrg 
    348   1.6  mrg extern function_symbol_result function_symbol (rtx, const char *,
    349   1.6  mrg 					       sh_function_kind);
    350   1.6  mrg extern rtx sh_get_fdpic_reg_initial_val (void);
    351   1.1  mrg extern rtx sh_get_pr_initial_val (void);
    352   1.1  mrg 
    353   1.3  mrg extern void sh_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree,
    354   1.5  mrg 				     signed int, machine_mode);
    355   1.1  mrg extern rtx sh_dwarf_register_span (rtx);
    356   1.1  mrg 
    357   1.3  mrg extern bool sh_contains_memref_p (rtx);
    358   1.3  mrg extern bool sh_loads_bankedreg_p (rtx);
    359   1.1  mrg extern int sh2a_get_function_vector_number (rtx);
    360   1.3  mrg extern bool sh2a_is_function_vector_call (rtx);
    361   1.1  mrg extern void sh_fix_range (const char *);
    362   1.5  mrg extern machine_mode sh_hard_regno_caller_save_mode (unsigned int, unsigned int,
    363   1.5  mrg 						    machine_mode);
    364   1.3  mrg extern bool sh_can_use_simple_return_p (void);
    365   1.6  mrg extern rtx sh_load_function_descriptor (rtx);
    366   1.1  mrg #endif /* ! GCC_SH_PROTOS_H */
    367