diff gcc/config/alpha/predicates.md @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
line wrap: on
line diff
--- a/gcc/config/alpha/predicates.md	Sun Aug 21 07:07:55 2011 +0900
+++ b/gcc/config/alpha/predicates.md	Fri Oct 27 22:46:09 2017 +0900
@@ -1,6 +1,5 @@
 ;; Predicate definitions for DEC Alpha.
-;; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010
-;; Free Software Foundation, Inc.
+;; Copyright (C) 2004-2017 Free Software Foundation, Inc.
 ;;
 ;; This file is part of GCC.
 ;;
@@ -20,7 +19,7 @@
 
 ;; Return 1 if OP is the zero constant for MODE.
 (define_predicate "const0_operand"
-  (and (match_code "const_int,const_double,const_vector")
+  (and (match_code "const_int,const_wide_int,const_double,const_vector")
        (match_test "op == CONST0_RTX (mode)")))
 
 ;; Returns true if OP is either the constant zero or a register.
@@ -67,13 +66,13 @@
 ;; Return 1 if the operand is a non-symbolic constant operand that
 ;; does not satisfy add_operand.
 (define_predicate "non_add_const_operand"
-  (and (match_code "const_int,const_double,const_vector")
+  (and (match_code "const_int,const_wide_int,const_double,const_vector")
        (not (match_operand 0 "add_operand"))))
 
 ;; Return 1 if the operand is a non-symbolic, nonzero constant operand.
 (define_predicate "non_zero_const_operand"
-  (and (match_code "const_int,const_double,const_vector")
-       (match_test "op != CONST0_RTX (mode)")))
+  (and (match_code "const_int,const_wide_int,const_double,const_vector")
+       (not (match_test "op == CONST0_RTX (mode)"))))
 
 ;; Return 1 if OP is the constant 4 or 8.
 (define_predicate "const48_operand"
@@ -86,11 +85,7 @@
     (match_test "(unsigned HOST_WIDE_INT) INTVAL (op) < 0x100
 		 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100
 		 || zap_mask (INTVAL (op))")
-    (if_then_else (match_code "const_double")
-      (match_test "GET_MODE (op) == VOIDmode
-		   && zap_mask (CONST_DOUBLE_LOW (op))
-		   && zap_mask (CONST_DOUBLE_HIGH (op))")
-      (match_operand 0 "register_operand"))))
+    (match_operand 0 "register_operand")))
 
 ;; Return 1 if OP is a valid first operand to an IOR or XOR insn.
 (define_predicate "or_operand"
@@ -111,26 +106,19 @@
 ;; Return 1 if OP is a constant that is a mask of ones of width of an
 ;; integral machine mode not larger than DImode.
 (define_predicate "mode_mask_operand"
-  (match_code "const_int,const_double")
+  (match_code "const_int")
 {
-  if (CONST_INT_P (op))
-    {
-      HOST_WIDE_INT value = INTVAL (op);
+  HOST_WIDE_INT value = INTVAL (op);
 
-      if (value == 0xff)
-	return 1;
-      if (value == 0xffff)
-	return 1;
-      if (value == 0xffffffff)
-	return 1;
-      if (value == -1)
-	return 1;
-    }
-  else if (HOST_BITS_PER_WIDE_INT == 32 && GET_CODE (op) == CONST_DOUBLE)
-    {
-      if (CONST_DOUBLE_LOW (op) == 0xffffffff && CONST_DOUBLE_HIGH (op) == 0)
-	return 1;
-    }
+  if (value == 0xff)
+    return 1;
+  if (value == 0xffff)
+    return 1;
+  if (value == 0xffffffff)
+    return 1;
+  if (value == -1)
+    return 1;
+
   return 0;
 })
 
@@ -146,7 +134,7 @@
 (define_predicate "hard_fp_register_operand"
   (match_operand 0 "register_operand")
 {
-  if (GET_CODE (op) == SUBREG)
+  if (SUBREG_P (op))
     op = SUBREG_REG (op);
   return REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS;
 })
@@ -155,29 +143,14 @@
 (define_predicate "hard_int_register_operand"
   (match_operand 0 "register_operand")
 {
-  if (GET_CODE (op) == SUBREG)
+  if (SUBREG_P (op))
     op = SUBREG_REG (op);
   return REGNO_REG_CLASS (REGNO (op)) == GENERAL_REGS;
 })
 
-;; Return 1 if OP is something that can be reloaded into a register;
-;; if it is a MEM, it need not be valid.
-(define_predicate "some_operand"
-  (ior (match_code "reg,mem,const_int,const_double,const_vector,
-		    label_ref,symbol_ref,const,high")
-       (and (match_code "subreg")
-	    (match_test "some_operand (SUBREG_REG (op), VOIDmode)"))))
-
-;; Likewise, but don't accept constants.
-(define_predicate "some_ni_operand"
-  (ior (match_code "reg,mem")
-       (and (match_code "subreg")
-	    (match_test "some_ni_operand (SUBREG_REG (op), VOIDmode)"))))
-
 ;; Return 1 if OP is a valid operand for the source of a move insn.
 (define_predicate "input_operand"
-  (match_code "label_ref,symbol_ref,const,high,reg,subreg,mem,
-	       const_double,const_vector,const_int")
+  (match_operand 0 "general_operand")
 {
   switch (GET_CODE (op))
     {
@@ -195,9 +168,8 @@
 		  || gotdtp_symbolic_operand (op, mode)
 		  || gottp_symbolic_operand (op, mode));
 	}
-
-      /* This handles both the Windows/NT and OSF cases.  */
-      return mode == ptr_mode || mode == DImode;
+      /* VMS still has a 32-bit mode.  */
+      return mode == ptr_mode || mode == Pmode;
 
     case HIGH:
       return (TARGET_EXPLICIT_RELOCS
@@ -209,24 +181,25 @@
     case SUBREG:
       if (register_operand (op, mode))
 	return 1;
-      /* ... fall through ...  */
+      /* fall through */
     case MEM:
       return ((TARGET_BWX || (mode != HImode && mode != QImode))
 	      && general_operand (op, mode));
 
+    case CONST_WIDE_INT:
     case CONST_DOUBLE:
       return op == CONST0_RTX (mode);
 
     case CONST_VECTOR:
       if (reload_in_progress || reload_completed)
-	return alpha_legitimate_constant_p (op);
+	return alpha_legitimate_constant_p (mode, op);
       return op == CONST0_RTX (mode);
 
     case CONST_INT:
       if (mode == QImode || mode == HImode)
 	return true;
       if (reload_in_progress || reload_completed)
-	return alpha_legitimate_constant_p (op);
+	return alpha_legitimate_constant_p (mode, op);
       return add_operand (op, mode);
 
     default:
@@ -295,14 +268,13 @@
 ;; Return 1 if OP is a valid operand for the MEM of a CALL insn.
 ;;
 ;; For TARGET_ABI_OSF, we want to restrict to R27 or a pseudo.
-;; For TARGET_ABI_UNICOSMK, we want to restrict to registers.
 
 (define_predicate "call_operand"
-  (if_then_else (match_code "reg")
-    (match_test "!TARGET_ABI_OSF
-		 || REGNO (op) == 27 || REGNO (op) > LAST_VIRTUAL_REGISTER")
-    (and (match_test "!TARGET_ABI_UNICOSMK")
-	 (match_code "symbol_ref"))))
+  (ior (match_code "symbol_ref")
+       (and (match_code "reg")
+	    (ior (not (match_test "TARGET_ABI_OSF"))
+		 (not (match_test "HARD_REGISTER_P (op)"))
+		 (match_test "REGNO (op) == R27_REG")))))
 
 ;; Return true if OP is a LABEL_REF, or SYMBOL_REF or CONST referencing
 ;; a (non-tls) variable known to be defined in this file.
@@ -330,26 +302,50 @@
 (define_predicate "small_symbolic_operand"
   (match_code "const,symbol_ref")
 {
+  HOST_WIDE_INT ofs = 0, max_ofs = 0;
+
   if (! TARGET_SMALL_DATA)
-    return 0;
+    return false;
 
   if (GET_CODE (op) == CONST
       && GET_CODE (XEXP (op, 0)) == PLUS
       && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
-    op = XEXP (XEXP (op, 0), 0);
+    {
+      ofs = INTVAL (XEXP (XEXP (op, 0), 1));
+      op = XEXP (XEXP (op, 0), 0);
+    }
 
   if (GET_CODE (op) != SYMBOL_REF)
-    return 0;
+    return false;
 
   /* ??? There's no encode_section_info equivalent for the rtl
      constant pool, so SYMBOL_FLAG_SMALL never gets set.  */
   if (CONSTANT_POOL_ADDRESS_P (op))
-    return GET_MODE_SIZE (get_pool_mode (op)) <= g_switch_value;
+    {
+      max_ofs = GET_MODE_SIZE (get_pool_mode (op));
+      if (max_ofs > g_switch_value)
+	return false;
+    }
+  else if (SYMBOL_REF_LOCAL_P (op)
+	    && SYMBOL_REF_SMALL_P (op)
+	    && !SYMBOL_REF_WEAK (op)
+	    && !SYMBOL_REF_TLS_MODEL (op))
+    {
+      if (SYMBOL_REF_DECL (op))
+        max_ofs = tree_to_uhwi (DECL_SIZE_UNIT (SYMBOL_REF_DECL (op)));
+    }
+  else
+    return false;
 
-  return (SYMBOL_REF_LOCAL_P (op)
-	  && SYMBOL_REF_SMALL_P (op)
-	  && !SYMBOL_REF_WEAK (op)
-	  && !SYMBOL_REF_TLS_MODEL (op));
+  /* Given that we know that the GP is always 8 byte aligned, we can
+     always adjust by 7 without overflowing.  */
+  if (max_ofs < 8)
+    max_ofs = 8;
+
+  /* Since we know this is an object in a small data section, we know the
+     entire section is addressable via GP.  We don't know where the section
+     boundaries are, but we know the entire object is within.  */
+  return IN_RANGE (ofs, 0, max_ofs - 1);
 })
 
 ;; Return true if OP is a SYMBOL_REF or CONST referencing a variable
@@ -374,10 +370,9 @@
 (define_predicate "symbolic_operand"
   (ior (match_code "symbol_ref,label_ref")
        (and (match_code "const")
-	    (match_test "GET_CODE (XEXP (op,0)) == PLUS
-			 && (GET_CODE (XEXP (XEXP (op,0), 0)) == SYMBOL_REF
-			     || GET_CODE (XEXP (XEXP (op,0), 0)) == LABEL_REF)
-			 && CONST_INT_P (XEXP (XEXP (op,0), 1))"))))
+	    (match_code "plus" "0")
+	    (match_code "symbol_ref,label_ref" "00")
+	    (match_code "const_int" "01"))))
 
 ;; Return true if OP is valid for 16-bit DTP relative relocations.
 (define_predicate "dtp16_symbolic_operand"
@@ -511,7 +506,7 @@
 (define_special_predicate "any_memory_operand"
   (match_code "mem,reg,subreg")
 {
-  if (GET_CODE (op) == SUBREG)
+  if (SUBREG_P (op))
     op = SUBREG_REG (op);
 
   if (MEM_P (op))
@@ -528,14 +523,6 @@
   return false;
 })
 
-;; Return 1 is OP is a memory location that is not a reference
-;; (using an AND) to an unaligned location.  Take into account
-;; what reload will do.
-(define_special_predicate "normal_memory_operand"
-  (ior (match_test "op = resolve_reload_operand (op), 0")
-       (and (match_code "mem")
-	    (match_test "GET_CODE (XEXP (op, 0)) != AND"))))
-
 ;; Returns 1 if OP is not an eliminable register.
 ;;
 ;; This exists to cure a pathological failure in the s8addq (et al) patterns,
@@ -550,7 +537,7 @@
 (define_predicate "reg_not_elim_operand"
   (match_operand 0 "register_operand")
 {
-  if (GET_CODE (op) == SUBREG)
+  if (SUBREG_P (op))
     op = SUBREG_REG (op);
   return op != frame_pointer_rtx && op != arg_pointer_rtx;
 })
@@ -617,5 +604,16 @@
   /* Avoid search unless necessary.  */
   if (!TARGET_EXPLICIT_RELOCS || !reload_completed)
     return false;
-  return for_each_rtx (&op, some_small_symbolic_operand_int, NULL);
+  return some_small_symbolic_operand_int (op);
 })
+
+;; Accept a register, or a memory if BWX is enabled.
+(define_predicate "reg_or_bwx_memory_operand"
+  (ior (match_operand 0 "register_operand")
+       (and (match_test "TARGET_BWX")
+	    (match_operand 0 "memory_operand"))))
+
+;; Accept a memory whose address is only a register.
+(define_predicate "mem_noofs_operand"
+  (and (match_code "mem")
+       (match_code "reg" "0")))