targhooks.c revision 220150
1139825Simp/* Default target hook functions. 21541Srgrimes Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. 31541Srgrimes 41541SrgrimesThis file is part of GCC. 51541Srgrimes 61541SrgrimesGCC is free software; you can redistribute it and/or modify it under 71541Srgrimesthe terms of the GNU General Public License as published by the Free 81541SrgrimesSoftware Foundation; either version 2, or (at your option) any later 91541Srgrimesversion. 101541Srgrimes 111541SrgrimesGCC is distributed in the hope that it will be useful, but WITHOUT ANY 121541SrgrimesWARRANTY; without even the implied warranty of MERCHANTABILITY or 131541SrgrimesFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 141541Srgrimesfor more details. 151541Srgrimes 161541SrgrimesYou should have received a copy of the GNU General Public License 171541Srgrimesalong with GCC; see the file COPYING. If not, write to the Free 181541SrgrimesSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 191541Srgrimes02110-1301, USA. */ 201541Srgrimes 211541Srgrimes/* The migration of target macros to target hooks works as follows: 221541Srgrimes 231541Srgrimes 1. Create a target hook that uses the existing target macros to 241541Srgrimes implement the same functionality. 251541Srgrimes 261541Srgrimes 2. Convert all the MI files to use the hook instead of the macro. 271541Srgrimes 281541Srgrimes 3. Repeat for a majority of the remaining target macros. This will 291541Srgrimes take some time. 301541Srgrimes 311541Srgrimes 4. Tell target maintainers to start migrating. 321817Sdg 331541Srgrimes 5. Eventually convert the backends to override the hook instead of 341541Srgrimes defining the macros. This will take some time too. 351541Srgrimes 361541Srgrimes 6. TBD when, poison the macros. Unmigrated targets will break at 371541Srgrimes this point. 381541Srgrimes 395455Sdg Note that we expect steps 1-3 to be done by the people that 401541Srgrimes understand what the MI does with each macro, and step 5 to be done 411541Srgrimes by the target maintainers for their respective targets. 421541Srgrimes 431541Srgrimes Note that steps 1 and 2 don't have to be done together, but no 441541Srgrimes target can override the new hook until step 2 is complete for it. 455455Sdg 465455Sdg Once the macros are poisoned, we will revert to the old migration 475455Sdg rules - migrate the macro, callers, and targets all at once. This 481541Srgrimes comment can thus be removed at that point. */ 495455Sdg 501541Srgrimes#include "config.h" 511541Srgrimes#include "system.h" 521541Srgrimes#include "coretypes.h" 531541Srgrimes#include "tm.h" 541541Srgrimes#include "machmode.h" 551541Srgrimes#include "rtl.h" 561541Srgrimes#include "tree.h" 571541Srgrimes#include "expr.h" 581541Srgrimes#include "output.h" 591541Srgrimes#include "toplev.h" 601541Srgrimes#include "function.h" 611541Srgrimes#include "target.h" 621541Srgrimes#include "tm_p.h" 631541Srgrimes#include "target-def.h" 641541Srgrimes#include "ggc.h" 65116226Sobrien#include "hard-reg-set.h" 66116226Sobrien#include "reload.h" 67116226Sobrien#include "optabs.h" 681541Srgrimes#include "recog.h" 691541Srgrimes 7087157Sluigi 71168395Spjdvoid 7276166Smarkmdefault_external_libcall (rtx fun ATTRIBUTE_UNUSED) 7376166Smarkm{ 742112Swollman#ifdef ASM_OUTPUT_EXTERNAL_LIBCALL 756129Sdg ASM_OUTPUT_EXTERNAL_LIBCALL(asm_out_file, fun); 76188964Srwatson#endif 771541Srgrimes} 781541Srgrimes 7912662Sdgenum machine_mode 8012662Sdgdefault_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2) 8112662Sdg{ 8212662Sdg if (m1 == m2) 831541Srgrimes return m1; 841541Srgrimes return VOIDmode; 8512726Sbde} 86168395Spjd 871541Srgrimesbool 8819830Sdysondefault_return_in_memory (tree type, 8919830Sdyson tree fntype ATTRIBUTE_UNUSED) 9019830Sdyson{ 91118764Ssilby#ifndef RETURN_IN_MEMORY 9219830Sdyson return (TYPE_MODE (type) == BLKmode); 932112Swollman#else 941541Srgrimes return RETURN_IN_MEMORY (type); 9547841Sdt#endif 9647841Sdt} 97118317Salc 98118317Salcrtx 99118317Salcdefault_expand_builtin_saveregs (void) 100118317Salc{ 101118317Salc error ("__builtin_saveregs not supported by this target"); 10247841Sdt return const0_rtx; 10347841Sdt} 10447841Sdt 10547841Sdtvoid 10670480Salfreddefault_setup_incoming_varargs (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, 10747841Sdt enum machine_mode mode ATTRIBUTE_UNUSED, 10847841Sdt tree type ATTRIBUTE_UNUSED, 10970480Salfred int *pretend_arg_size ATTRIBUTE_UNUSED, 11047841Sdt int second_time ATTRIBUTE_UNUSED) 11147841Sdt{ 11247841Sdt} 113178933Salc 114178933Salc/* The default implementation of TARGET_BUILTIN_SETJMP_FRAME_VALUE. */ 11547841Sdt 11647841Sdtrtx 11747841Sdtdefault_builtin_setjmp_frame_value (void) 11847841Sdt{ 11947841Sdt return virtual_stack_vars_rtx; 12047841Sdt} 12147841Sdt 122206819Sjmallett/* Generic hook that takes a CUMULATIVE_ARGS pointer and returns false. */ 123206819Sjmallett 124206819Sjmallettbool 125206819Sjmalletthook_bool_CUMULATIVE_ARGS_false (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) 126206819Sjmallett{ 127206819Sjmallett return false; 128206819Sjmallett} 129206819Sjmallett 130206819Sjmallettbool 131206819Sjmallettdefault_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) 132206819Sjmallett{ 133206819Sjmallett return (targetm.calls.setup_incoming_varargs 134206819Sjmallett != default_setup_incoming_varargs); 135206819Sjmallett} 136206819Sjmallett 137206819Sjmallettenum machine_mode 138206819Sjmallettdefault_eh_return_filter_mode (void) 139206819Sjmallett{ 140206819Sjmallett return word_mode; 141206819Sjmallett} 142206819Sjmallett 143206819Sjmallett/* The default implementation of TARGET_SHIFT_TRUNCATION_MASK. */ 144206819Sjmallett 145206819Sjmallettunsigned HOST_WIDE_INT 146206819Sjmallettdefault_shift_truncation_mask (enum machine_mode mode) 147206819Sjmallett{ 148206819Sjmallett return SHIFT_COUNT_TRUNCATED ? GET_MODE_BITSIZE (mode) - 1 : 0; 149206819Sjmallett} 150206819Sjmallett 1511541Srgrimes/* The default implementation of TARGET_MIN_DIVISIONS_FOR_RECIP_MUL. */ 1521541Srgrimes 1531541Srgrimesunsigned int 1548876Srgrimesdefault_min_divisions_for_recip_mul (enum machine_mode mode ATTRIBUTE_UNUSED) 1555455Sdg{ 15670480Salfred return have_insn_for (DIV, mode) ? 3 : 2; 15770480Salfred} 1581541Srgrimes 1595455Sdg/* The default implementation of TARGET_MODE_REP_EXTENDED. */ 16070480Salfred 1615455Sdgint 1621541Srgrimesdefault_mode_rep_extended (enum machine_mode mode ATTRIBUTE_UNUSED, 1631541Srgrimes enum machine_mode mode_rep ATTRIBUTE_UNUSED) 1641541Srgrimes{ 1651541Srgrimes return UNKNOWN; 1665455Sdg} 1675455Sdg 1681541Srgrimes/* Generic hook that takes a CUMULATIVE_ARGS pointer and returns true. */ 1691541Srgrimes 1701541Srgrimesbool 1715455Sdghook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED) 1725455Sdg{ 1735455Sdg return true; 1741541Srgrimes} 1751541Srgrimes 17633758Sdyson 1771541Srgrimes/* The generic C++ ABI specifies this is a 64-bit value. */ 1781541Srgrimestree 1791541Srgrimesdefault_cxx_guard_type (void) 1801541Srgrimes{ 1811541Srgrimes return long_long_integer_type_node; 18213490Sdyson} 18313490Sdyson 1841541Srgrimes 1851541Srgrimes/* Returns the size of the cookie to use when allocating an array 1861541Srgrimes whose elements have the indicated TYPE. Assumes that it is already 1875455Sdg known that a cookie is needed. */ 188122383Smini 1895455Sdgtree 1908876Srgrimesdefault_cxx_get_cookie_size (tree type) 1915455Sdg{ 1925455Sdg tree cookie_size; 193122383Smini 1945455Sdg /* We need to allocate an additional max (sizeof (size_t), alignof 1955455Sdg (true_type)) bytes. */ 1965455Sdg tree sizetype_size; 1975455Sdg tree type_align; 1985455Sdg 1998876Srgrimes sizetype_size = size_in_bytes (sizetype); 2005455Sdg type_align = size_int (TYPE_ALIGN_UNIT (type)); 201122383Smini if (INT_CST_LT_UNSIGNED (type_align, sizetype_size)) 2021541Srgrimes cookie_size = sizetype_size; 203120761Salc else 2045455Sdg cookie_size = type_align; 2055455Sdg 2061541Srgrimes return cookie_size; 20733109Sdyson} 208136923Salc 209120761Salc/* Return true if a parameter must be passed by reference. This version 210166964Salc of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ 211166964Salc 2121541Srgrimesbool 213120761Salchook_pass_by_reference_must_pass_in_stack (CUMULATIVE_ARGS *c ATTRIBUTE_UNUSED, 2145455Sdg enum machine_mode mode ATTRIBUTE_UNUSED, tree type ATTRIBUTE_UNUSED, 2151541Srgrimes bool named_arg ATTRIBUTE_UNUSED) 2165455Sdg{ 2171541Srgrimes return targetm.calls.must_pass_in_stack (mode, type); 218118771Sbms} 219118771Sbms 2201541Srgrimes/* Return true if a parameter follows callee copies conventions. This 2215455Sdg version of the hook is true for all named arguments. */ 2221541Srgrimes 2231541Srgrimesbool 2241541Srgrimeshook_callee_copies_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, 2251541Srgrimes enum machine_mode mode ATTRIBUTE_UNUSED, 2261541Srgrimes tree type ATTRIBUTE_UNUSED, bool named) 2271541Srgrimes{ 2281541Srgrimes return named; 2291541Srgrimes} 23042957Sdillon 23142957Sdillon/* Emit any directives required to unwind this instruction. */ 2321541Srgrimes 2338876Srgrimesvoid 2345455Sdgdefault_unwind_emit (FILE * stream ATTRIBUTE_UNUSED, 2355455Sdg rtx insn ATTRIBUTE_UNUSED) 23670480Salfred{ 2375455Sdg /* Should never happen. */ 2381541Srgrimes gcc_unreachable (); 23971571Sjhb} 2401541Srgrimes 2411541Srgrimes/* True if MODE is valid for the target. By "valid", we mean able to 2421541Srgrimes be manipulated in non-trivial ways. In particular, this means all 2431541Srgrimes the arithmetic is supported. 2441541Srgrimes 2451541Srgrimes By default we guess this means that any C type is supported. If 2461541Srgrimes we can't map the mode back to a type that would be available in C, 2471541Srgrimes then reject it. Special case, here, is the double-word arithmetic 2481541Srgrimes supported by optabs.c. */ 2491541Srgrimes 2501541Srgrimesbool 2511541Srgrimesdefault_scalar_mode_supported_p (enum machine_mode mode) 25270480Salfred{ 2531541Srgrimes int precision = GET_MODE_PRECISION (mode); 254178933Salc 2551541Srgrimes switch (GET_MODE_CLASS (mode)) 2568876Srgrimes { 257178933Salc case MODE_PARTIAL_INT: 258178933Salc case MODE_INT: 2591541Srgrimes if (precision == CHAR_TYPE_SIZE) 26070478Salfred return true; 2615455Sdg if (precision == SHORT_TYPE_SIZE) 2621541Srgrimes return true; 2631541Srgrimes if (precision == INT_TYPE_SIZE) 2641541Srgrimes return true; 265178637Salc if (precision == LONG_TYPE_SIZE) 266178933Salc return true; 267194766Skib if (precision == LONG_LONG_TYPE_SIZE) 268194766Skib return true; 269177762Salc if (precision == 2 * BITS_PER_WORD) 270177762Salc return true; 2711541Srgrimes return false; 27232702Sdyson 2731541Srgrimes case MODE_FLOAT: 2741541Srgrimes if (precision == FLOAT_TYPE_SIZE) 27570478Salfred return true; 2761541Srgrimes if (precision == DOUBLE_TYPE_SIZE) 2775455Sdg return true; 2781541Srgrimes if (precision == LONG_DOUBLE_TYPE_SIZE) 2791541Srgrimes return true; 2801541Srgrimes return false; 28142957Sdillon 2821541Srgrimes case MODE_DECIMAL_FLOAT: 28342957Sdillon return false; 28442957Sdillon 28542957Sdillon default: 28642957Sdillon gcc_unreachable (); 2871541Srgrimes } 28842957Sdillon} 28942957Sdillon 29042957Sdillon/* True if the target supports decimal floating point. */ 2911541Srgrimes 29242957Sdillonbool 29342957Sdillondefault_decimal_float_supported_p (void) 29442957Sdillon{ 29578592Sbmilekic return ENABLE_DECIMAL_FLOAT; 29678592Sbmilekic} 2971541Srgrimes 2981541Srgrimes/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns 29942957Sdillon an error message. 30070480Salfred 30170480Salfred This function checks whether a given INSN is valid within a low-overhead 30242957Sdillon loop. If INSN is invalid it returns the reason for that, otherwise it 3031541Srgrimes returns NULL. A called function may clobber any special registers required 30470480Salfred for low-overhead looping. Additionally, some targets (eg, PPC) use the count 305189015Skib register for branch on table instructions. We reject the doloop pattern in 3065455Sdg these cases. */ 3075455Sdg 30898455Sjeffconst char * 3091541Srgrimesdefault_invalid_within_doloop (rtx insn) 3101541Srgrimes{ 3111541Srgrimes if (CALL_P (insn)) 3121541Srgrimes return "Function call in loop."; 3131541Srgrimes 3145455Sdg if (JUMP_P (insn) 3155455Sdg && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC 3165455Sdg || GET_CODE (PATTERN (insn)) == ADDR_VEC)) 3171541Srgrimes return "Computed branch in the loop."; 3181541Srgrimes 31933758Sdyson return NULL; 3201541Srgrimes} 321175210Spjd 322175210Spjdbool 323175210Spjdhook_bool_CUMULATIVE_ARGS_mode_tree_bool_false ( 324175210Spjd CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, 325175210Spjd enum machine_mode mode ATTRIBUTE_UNUSED, 326175210Spjd tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) 327175210Spjd{ 328175210Spjd return false; 329175210Spjd} 330168395Spjd 331175210Spjdbool 332175210Spjdhook_bool_CUMULATIVE_ARGS_mode_tree_bool_true ( 333175210Spjd CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, 334168395Spjd enum machine_mode mode ATTRIBUTE_UNUSED, 335175210Spjd tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) 336168395Spjd{ 337168395Spjd return true; 338168395Spjd} 339168395Spjd 3401541Srgrimesint 34115367Sdysonhook_int_CUMULATIVE_ARGS_mode_tree_bool_0 ( 3421541Srgrimes CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED, 34313490Sdyson enum machine_mode mode ATTRIBUTE_UNUSED, 34413490Sdyson tree type ATTRIBUTE_UNUSED, bool named ATTRIBUTE_UNUSED) 3451541Srgrimes{ 34698455Sjeff return 0; 347108351Salc} 34898455Sjeff 349108351Salcvoid 35098455Sjeffhook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED) 35198455Sjeff{ 35298455Sjeff} 35398455Sjeff 354113489Salcconst char * 3551541Srgrimeshook_invalid_arg_for_unprototyped_fn ( 35615809Sdyson tree typelist ATTRIBUTE_UNUSED, 35798450Sjeff tree funcdecl ATTRIBUTE_UNUSED, 35898450Sjeff tree val ATTRIBUTE_UNUSED) 3591541Srgrimes{ 3605455Sdg return NULL; 3615455Sdg} 3625455Sdg 3631541Srgrimes/* Initialize the stack protection decls. */ 3641541Srgrimes 36542957Sdillon/* Stack protection related decls living in libgcc. */ 366113489Salcstatic GTY(()) tree stack_chk_guard_decl; 36744793Salc 36815809Sdysontree 36944793Salcdefault_stack_protect_guard (void) 370113489Salc{ 37115809Sdyson tree t = stack_chk_guard_decl; 37215809Sdyson 37391946Stegge if (t == NULL) 37491946Stegge { 37591946Stegge t = build_decl (VAR_DECL, get_identifier ("__stack_chk_guard"), 37691946Stegge ptr_type_node); 37791946Stegge TREE_STATIC (t) = 1; 37891946Stegge TREE_PUBLIC (t) = 1; 37991946Stegge DECL_EXTERNAL (t) = 1; 38091946Stegge TREE_USED (t) = 1; 38191946Stegge TREE_THIS_VOLATILE (t) = 1; 38291946Stegge DECL_ARTIFICIAL (t) = 1; 383100796Salc DECL_IGNORED_P (t) = 1; 384108351Salc 38591946Stegge stack_chk_guard_decl = t; 386100796Salc } 38791946Stegge 388113489Salc return t; 389189015Skib} 3901541Srgrimes 391113418Salcstatic GTY(()) tree stack_chk_fail_decl; 3921541Srgrimes 39398455Sjefftree 394102382Salcdefault_external_stack_protect_fail (void) 395120761Salc{ 396166964Salc tree t = stack_chk_fail_decl; 397166964Salc 3981541Srgrimes if (t == NULL_TREE) 399113489Salc { 4001541Srgrimes t = build_function_type_list (void_type_node, NULL_TREE); 4011541Srgrimes t = build_decl (FUNCTION_DECL, get_identifier ("__stack_chk_fail"), t); 4025455Sdg TREE_STATIC (t) = 1; 4035455Sdg TREE_PUBLIC (t) = 1; 4045455Sdg DECL_EXTERNAL (t) = 1; 4055455Sdg TREE_USED (t) = 1; 4061541Srgrimes TREE_THIS_VOLATILE (t) = 1; 4071541Srgrimes TREE_NOTHROW (t) = 1; 4081541Srgrimes DECL_ARTIFICIAL (t) = 1; 40944793Salc DECL_IGNORED_P (t) = 1; 4101541Srgrimes DECL_VISIBILITY (t) = VISIBILITY_DEFAULT; 41144793Salc DECL_VISIBILITY_SPECIFIED (t) = 1; 4121541Srgrimes 413124048Salc stack_chk_fail_decl = t; 414124048Salc } 415124048Salc 416124048Salc return build_function_call_expr (t, NULL_TREE); 417124048Salc} 41820993Sdyson 41920993Sdysontree 4201541Srgrimesdefault_hidden_stack_protect_fail (void) 421164234Salc{ 4221541Srgrimes#ifndef HAVE_GAS_HIDDEN 423124048Salc return default_external_stack_protect_fail (); 4241541Srgrimes#else 42512767Sdyson tree t = stack_chk_fail_decl; 42642957Sdillon 42742957Sdillon if (!flag_pic) 42842957Sdillon return default_external_stack_protect_fail (); 429175067Salc 430175067Salc if (t == NULL_TREE) 431108351Salc { 4321541Srgrimes t = build_function_type_list (void_type_node, NULL_TREE); 433124048Salc t = build_decl (FUNCTION_DECL, 4341541Srgrimes get_identifier ("__stack_chk_fail_local"), t); 4351541Srgrimes TREE_STATIC (t) = 1; 4365455Sdg TREE_PUBLIC (t) = 1; 4371541Srgrimes DECL_EXTERNAL (t) = 1; 4381541Srgrimes TREE_USED (t) = 1; 4391541Srgrimes TREE_THIS_VOLATILE (t) = 1; 44042957Sdillon TREE_NOTHROW (t) = 1; 4411541Srgrimes DECL_ARTIFICIAL (t) = 1; 4421541Srgrimes DECL_IGNORED_P (t) = 1; 4431541Srgrimes DECL_VISIBILITY_SPECIFIED (t) = 1; 4441541Srgrimes DECL_VISIBILITY (t) = VISIBILITY_HIDDEN; 44542957Sdillon 4461541Srgrimes stack_chk_fail_decl = t; 4478876Srgrimes } 4485455Sdg 4495455Sdg return build_function_call_expr (t, NULL_TREE); 4505455Sdg#endif 4511541Srgrimes} 4525455Sdg 4531541Srgrimesbool 4541541Srgrimeshook_bool_rtx_commutative_p (rtx x, int outer_code ATTRIBUTE_UNUSED) 455194766Skib{ 456194766Skib return COMMUTATIVE_P (x); 4571541Srgrimes} 4581541Srgrimes 4591541Srgrimesrtx 4605455Sdgdefault_function_value (tree ret_type ATTRIBUTE_UNUSED, 4615455Sdg tree fn_decl_or_type, 4621541Srgrimes bool outgoing ATTRIBUTE_UNUSED) 4631541Srgrimes{ 46433758Sdyson /* The old interface doesn't handle receiving the function type. */ 4651541Srgrimes if (fn_decl_or_type 4661541Srgrimes && !DECL_P (fn_decl_or_type)) 4671541Srgrimes fn_decl_or_type = NULL; 4681541Srgrimes 469194766Skib#ifdef FUNCTION_OUTGOING_VALUE 4701541Srgrimes if (outgoing) 4711541Srgrimes return FUNCTION_OUTGOING_VALUE (ret_type, fn_decl_or_type); 47299754Salc#endif 473173429Spjd 4741541Srgrimes#ifdef FUNCTION_VALUE 475194766Skib return FUNCTION_VALUE (ret_type, fn_decl_or_type); 476194766Skib#else 4771541Srgrimes return NULL_RTX; 4781541Srgrimes#endif 4791541Srgrimes} 4801541Srgrimes 4811541Srgrimesrtx 48242957Sdillondefault_internal_arg_pointer (void) 4831541Srgrimes{ 4849507Sdg /* If the reg that the virtual arg pointer will be translated into is 4851541Srgrimes not a fixed reg or is the stack pointer, make a copy of the virtual 4861541Srgrimes arg pointer, and address parms via the copy. The frame pointer is 4878876Srgrimes considered fixed even though it is not marked as such. */ 4885455Sdg if ((ARG_POINTER_REGNUM == STACK_POINTER_REGNUM 4895455Sdg || ! (fixed_regs[ARG_POINTER_REGNUM] 4905455Sdg || ARG_POINTER_REGNUM == FRAME_POINTER_REGNUM))) 4915455Sdg return copy_to_reg (virtual_incoming_args_rtx); 4921541Srgrimes else 49376827Salfred return virtual_incoming_args_rtx; 4941541Srgrimes} 495189015Skib 49699754Salcenum reg_class 49799754Salcdefault_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, 49899754Salc enum reg_class reload_class ATTRIBUTE_UNUSED, 49999754Salc enum machine_mode reload_mode ATTRIBUTE_UNUSED, 5001541Srgrimes secondary_reload_info *sri) 5011541Srgrimes{ 5021541Srgrimes enum reg_class class = NO_REGS; 5031541Srgrimes 50442957Sdillon if (sri->prev_sri && sri->prev_sri->t_icode != CODE_FOR_nothing) 50542957Sdillon { 50642957Sdillon sri->icode = sri->prev_sri->t_icode; 50742957Sdillon return NO_REGS; 50842957Sdillon } 50942957Sdillon#ifdef SECONDARY_INPUT_RELOAD_CLASS 5101541Srgrimes if (in_p) 5118876Srgrimes class = SECONDARY_INPUT_RELOAD_CLASS (reload_class, reload_mode, x); 5125455Sdg#endif 5131541Srgrimes#ifdef SECONDARY_OUTPUT_RELOAD_CLASS 5141541Srgrimes if (! in_p) 51570480Salfred class = SECONDARY_OUTPUT_RELOAD_CLASS (reload_class, reload_mode, x); 5161541Srgrimes#endif 51732702Sdyson if (class != NO_REGS) 518108426Salc { 5191541Srgrimes enum insn_code icode = (in_p ? reload_in_optab[(int) reload_mode] 5201541Srgrimes : reload_out_optab[(int) reload_mode]); 5211541Srgrimes 522108426Salc if (icode != CODE_FOR_nothing 523179923Salc && insn_data[(int) icode].operand[in_p].predicate 524179923Salc && ! insn_data[(int) icode].operand[in_p].predicate (x, reload_mode)) 525179923Salc icode = CODE_FOR_nothing; 526179923Salc else if (icode != CODE_FOR_nothing) 527179923Salc { 528179923Salc const char *insn_constraint, *scratch_constraint; 5291541Srgrimes char insn_letter, scratch_letter; 5301541Srgrimes enum reg_class insn_class, scratch_class; 5311541Srgrimes 532188964Srwatson gcc_assert (insn_data[(int) icode].n_operands == 3); 533188967Srwatson insn_constraint = insn_data[(int) icode].operand[!in_p].constraint; 534188964Srwatson if (!*insn_constraint) 535188964Srwatson insn_class = ALL_REGS; 536188964Srwatson else 537188964Srwatson { 538188964Srwatson if (in_p) 539188964Srwatson { 540188964Srwatson gcc_assert (*insn_constraint == '='); 541188964Srwatson insn_constraint++; 542188964Srwatson } 543188964Srwatson insn_letter = *insn_constraint; 544188964Srwatson insn_class 545188964Srwatson = (insn_letter == 'r' ? GENERAL_REGS 546188964Srwatson : REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter, 547188964Srwatson insn_constraint)); 548188964Srwatson gcc_assert (insn_class != NO_REGS); 549188964Srwatson } 550188964Srwatson 551188964Srwatson scratch_constraint = insn_data[(int) icode].operand[2].constraint; 552188964Srwatson /* The scratch register's constraint must start with "=&", 553188964Srwatson except for an input reload, where only "=" is necessary, 554188967Srwatson and where it might be beneficial to re-use registers from 555 the input. */ 556 gcc_assert (scratch_constraint[0] == '=' 557 && (in_p || scratch_constraint[1] == '&')); 558 scratch_constraint++; 559 if (*scratch_constraint == '&') 560 scratch_constraint++; 561 scratch_letter = *scratch_constraint; 562 scratch_class 563 = (scratch_letter == 'r' ? GENERAL_REGS 564 : REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter, 565 scratch_constraint)); 566 567 if (reg_class_subset_p (reload_class, insn_class)) 568 { 569 gcc_assert (scratch_class == class); 570 class = NO_REGS; 571 } 572 else 573 class = insn_class; 574 575 } 576 if (class == NO_REGS) 577 sri->icode = icode; 578 else 579 sri->t_icode = icode; 580 } 581 return class; 582} 583 584 585/* If STRICT_ALIGNMENT is true we use the container type for accessing 586 volatile bitfields. This is generally the preferred behavior for memory 587 mapped peripherals on RISC architectures. 588 If STRICT_ALIGNMENT is false we use the narrowest type possible. This 589 is typically used to avoid spurious page faults and extra memory accesses 590 due to unaligned accesses on CISC architectures. */ 591 592bool 593default_narrow_bitfield (void) 594{ 595 return !STRICT_ALIGNMENT; 596} 597 598/* By default, if flag_pic is true, then neither local nor global relocs 599 should be placed in readonly memory. */ 600 601int 602default_reloc_rw_mask (void) 603{ 604 return flag_pic ? 3 : 0; 605} 606 607bool 608default_builtin_vector_alignment_reachable (tree type, bool is_packed) 609{ 610 if (is_packed) 611 return false; 612 613 /* Assuming that types whose size is > pointer-size are not guaranteed to be 614 naturally aligned. */ 615 if (tree_int_cst_compare (TYPE_SIZE (type), bitsize_int (POINTER_SIZE)) > 0) 616 return false; 617 618 /* Assuming that types whose size is <= pointer-size 619 are naturally aligned. */ 620 return true; 621} 622 623#include "gt-targhooks.h" 624