xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/rtlhooks.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Generic hooks for the RTL middle-end.
2*8feb0f0bSmrg    Copyright (C) 2004-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 under
71debfc3dSmrg the terms of the GNU General Public License as published by the Free
81debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
91debfc3dSmrg version.
101debfc3dSmrg 
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
141debfc3dSmrg 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 #include "config.h"
211debfc3dSmrg #include "system.h"
221debfc3dSmrg #include "coretypes.h"
231debfc3dSmrg #include "tm.h"
241debfc3dSmrg #include "function.h"
251debfc3dSmrg #include "rtl.h"
261debfc3dSmrg #include "tree.h"
271debfc3dSmrg #include "insn-config.h"
281debfc3dSmrg #include "memmodel.h"
291debfc3dSmrg #include "emit-rtl.h"
301debfc3dSmrg #include "recog.h"
311debfc3dSmrg #include "rtlhooks-def.h"
321debfc3dSmrg #include "explow.h"
33a2dc1f3fSmrg #include "target.h"
341debfc3dSmrg 
351debfc3dSmrg 
361debfc3dSmrg /* For speed, we will copy the RTX hooks struct member-by-member
371debfc3dSmrg    instead of doing indirect calls.  For these reason, we initialize
381debfc3dSmrg    *two* struct rtl_hooks globals: rtl_hooks is the one that is used
391debfc3dSmrg    to actually call the hooks, while general_rtl_hooks is used
401debfc3dSmrg    to restore the hooks by passes that modify them.  */
411debfc3dSmrg 
421debfc3dSmrg const struct rtl_hooks general_rtl_hooks = RTL_HOOKS_INITIALIZER;
431debfc3dSmrg struct rtl_hooks rtl_hooks = RTL_HOOKS_INITIALIZER;
441debfc3dSmrg 
451debfc3dSmrg rtx
gen_lowpart_general(machine_mode mode,rtx x)461debfc3dSmrg gen_lowpart_general (machine_mode mode, rtx x)
471debfc3dSmrg {
481debfc3dSmrg   rtx result = gen_lowpart_common (mode, x);
491debfc3dSmrg 
501debfc3dSmrg   if (result)
511debfc3dSmrg     return result;
521debfc3dSmrg   /* Handle SUBREGs and hard REGs that were rejected by
531debfc3dSmrg      simplify_gen_subreg.  */
541debfc3dSmrg   else if (REG_P (x) || GET_CODE (x) == SUBREG)
551debfc3dSmrg     {
561debfc3dSmrg       result = gen_lowpart_common (mode, copy_to_reg (x));
571debfc3dSmrg       gcc_assert (result != 0);
581debfc3dSmrg       return result;
591debfc3dSmrg     }
601debfc3dSmrg   else
611debfc3dSmrg     {
621debfc3dSmrg       /* The only additional case we can do is MEM.  */
631debfc3dSmrg       gcc_assert (MEM_P (x));
641debfc3dSmrg 
651debfc3dSmrg       /* The following exposes the use of "x" to CSE.  */
66a2dc1f3fSmrg       scalar_int_mode xmode;
67a2dc1f3fSmrg       if (is_a <scalar_int_mode> (GET_MODE (x), &xmode)
68a2dc1f3fSmrg 	  && GET_MODE_SIZE (xmode) <= UNITS_PER_WORD
69a2dc1f3fSmrg 	  && TRULY_NOOP_TRUNCATION_MODES_P (mode, xmode)
701debfc3dSmrg 	  && !reload_completed)
71a2dc1f3fSmrg 	return gen_lowpart_general (mode, force_reg (xmode, x));
721debfc3dSmrg 
73a2dc1f3fSmrg       poly_int64 offset = byte_lowpart_offset (mode, GET_MODE (x));
741debfc3dSmrg       return adjust_address (x, mode, offset);
751debfc3dSmrg     }
761debfc3dSmrg }
771debfc3dSmrg 
781debfc3dSmrg rtx
reg_num_sign_bit_copies_general(const_rtx,scalar_int_mode,scalar_int_mode,unsigned int *)79a2dc1f3fSmrg reg_num_sign_bit_copies_general (const_rtx, scalar_int_mode, scalar_int_mode,
80a2dc1f3fSmrg 				 unsigned int *)
811debfc3dSmrg {
821debfc3dSmrg   return NULL;
831debfc3dSmrg }
841debfc3dSmrg 
851debfc3dSmrg rtx
reg_nonzero_bits_general(const_rtx,scalar_int_mode,scalar_int_mode,unsigned HOST_WIDE_INT *)86a2dc1f3fSmrg reg_nonzero_bits_general (const_rtx, scalar_int_mode, scalar_int_mode,
87a2dc1f3fSmrg 			  unsigned HOST_WIDE_INT *)
881debfc3dSmrg {
891debfc3dSmrg   return NULL;
901debfc3dSmrg }
911debfc3dSmrg 
921debfc3dSmrg bool
reg_truncated_to_mode_general(machine_mode mode ATTRIBUTE_UNUSED,const_rtx x ATTRIBUTE_UNUSED)931debfc3dSmrg reg_truncated_to_mode_general (machine_mode mode ATTRIBUTE_UNUSED,
941debfc3dSmrg 			       const_rtx x ATTRIBUTE_UNUSED)
951debfc3dSmrg {
961debfc3dSmrg   return false;
971debfc3dSmrg }
981debfc3dSmrg 
991debfc3dSmrg /* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point
1001debfc3dSmrg    number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
1011debfc3dSmrg    least-significant part of X.
1021debfc3dSmrg    MODE specifies how big a part of X to return.
1031debfc3dSmrg 
1041debfc3dSmrg    If the requested operation cannot be done, 0 is returned.
1051debfc3dSmrg 
1061debfc3dSmrg    This is similar to gen_lowpart_general.  */
1071debfc3dSmrg 
1081debfc3dSmrg rtx
gen_lowpart_if_possible(machine_mode mode,rtx x)1091debfc3dSmrg gen_lowpart_if_possible (machine_mode mode, rtx x)
1101debfc3dSmrg {
1111debfc3dSmrg   rtx result = gen_lowpart_common (mode, x);
1121debfc3dSmrg 
1131debfc3dSmrg   if (result)
1141debfc3dSmrg     return result;
1151debfc3dSmrg   else if (MEM_P (x))
1161debfc3dSmrg     {
1171debfc3dSmrg       /* This is the only other case we handle.  */
118a2dc1f3fSmrg       poly_int64 offset = byte_lowpart_offset (mode, GET_MODE (x));
119a2dc1f3fSmrg       rtx new_rtx = adjust_address_nv (x, mode, offset);
1201debfc3dSmrg       if (! memory_address_addr_space_p (mode, XEXP (new_rtx, 0),
1211debfc3dSmrg 					 MEM_ADDR_SPACE (x)))
1221debfc3dSmrg 	return 0;
1231debfc3dSmrg 
1241debfc3dSmrg       return new_rtx;
1251debfc3dSmrg     }
126a2dc1f3fSmrg   else if (mode != GET_MODE (x) && GET_MODE (x) != VOIDmode && !SUBREG_P (x)
1271debfc3dSmrg 	   && validate_subreg (mode, GET_MODE (x), x,
1281debfc3dSmrg 			       subreg_lowpart_offset (mode, GET_MODE (x))))
1291debfc3dSmrg     return gen_lowpart_SUBREG (mode, x);
1301debfc3dSmrg   else
1311debfc3dSmrg     return 0;
1321debfc3dSmrg }
1331debfc3dSmrg 
134