nios2.c (nios2_symbolic_constant_allowed): Rename to...
authorSandra Loosemore <sandra@codesourcery.com>
Fri, 8 Dec 2017 04:23:00 +0000 (23:23 -0500)
committerSandra Loosemore <sandra@gcc.gnu.org>
Fri, 8 Dec 2017 04:23:00 +0000 (23:23 -0500)
2017-12-07  Sandra Loosemore  <sandra@codesourcery.com>

gcc/
* config/nios2/nios2.c (nios2_symbolic_constant_allowed):
Rename to...
(nios2_large_constant_allowed): ...this.  Adjust uses.
(nios2_plus_symbolic_constant_p): Rename to...
(nios2_plus_large_constant_p): ...this.  Adjust uses.
(nios2_legitimate_address_p): Correct CONST_INT handling.
(nios2_symbolic_memory_operand_p): Rename to...
(nios2_large_constant_memory_operand_p): ...this.  Adjust uses.
(nios2_large_constant_p): Check for large constant integers too.
(nios2_split_large_constant): Handle constant integers.
(nios2_split_symbolic_memory_operand): Rename to...
(nios2_split_large_constant_memory_operand): ...this.  Adjust uses.
(nios2_legitimize_constant_address): Handle constant integers.
(r0rel_constant_p): Handle small constant integers.
(nios2_print_operand_address): Handle r0-relative integer addresses.
* config/nios2/nios2-protos.h: Adjust for renamed functions.
* config/nios2/nios2.md: Adjust for renamed functions.

From-SVN: r255492

gcc/ChangeLog
gcc/config/nios2/nios2-protos.h
gcc/config/nios2/nios2.c
gcc/config/nios2/nios2.md

index b9d7ed742cb70f55d27c01757073d82ecdbb772b..39a6f94c4adbad4e7cb01feba7b1a1284389e860 100644 (file)
@@ -1,3 +1,23 @@
+2017-12-07  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * config/nios2/nios2.c (nios2_symbolic_constant_allowed):
+       Rename to...
+       (nios2_large_constant_allowed): ...this.  Adjust uses.
+       (nios2_plus_symbolic_constant_p): Rename to...
+       (nios2_plus_large_constant_p): ...this.  Adjust uses.
+       (nios2_legitimate_address_p): Correct CONST_INT handling.
+       (nios2_symbolic_memory_operand_p): Rename to...
+       (nios2_large_constant_memory_operand_p): ...this.  Adjust uses.
+       (nios2_large_constant_p): Check for large constant integers too.
+       (nios2_split_large_constant): Handle constant integers.
+       (nios2_split_symbolic_memory_operand): Rename to...
+       (nios2_split_large_constant_memory_operand): ...this.  Adjust uses.
+       (nios2_legitimize_constant_address): Handle constant integers.
+       (r0rel_constant_p): Handle small constant integers.
+       (nios2_print_operand_address): Handle r0-relative integer addresses.
+       * config/nios2/nios2-protos.h: Adjust for renamed functions.
+       * config/nios2/nios2.md: Adjust for renamed functions.
+
 2017-12-07  Andrew Waterman  <andrew@sifive.com>
 
        * config/riscv/riscv.c (TARGET_ASM_SELECT_SECTION): New define.
index 84d450bfe94683ea97210551d26c2f65697c69b8..578750c53d5dac28292feb84f677a95cefac127d 100644 (file)
@@ -31,10 +31,10 @@ extern void nios2_function_profiler (FILE *, int);
 
 #ifdef RTX_CODE
 extern bool nios2_large_constant_p (rtx);
-extern bool nios2_symbolic_memory_operand_p (rtx);
+extern bool nios2_large_constant_memory_operand_p (rtx);
 
 extern rtx nios2_split_large_constant (rtx, rtx);
-extern rtx nios2_split_symbolic_memory_operand (rtx);
+extern rtx nios2_split_large_constant_memory_operand (rtx);
 extern bool nios2_emit_move_sequence (rtx *, machine_mode);
 extern void nios2_emit_expensive_div (rtx *, machine_mode);
 extern void nios2_adjust_call_address (rtx *, rtx);
index 5c70de7baf5a00f84e8a0cbc68e696a1914cf152..e0df9c5b8b442a7cd38b3ba12d914f124c863779 100644 (file)
@@ -2009,12 +2009,13 @@ nios2_validate_compare (machine_mode mode, rtx *cmp, rtx *op1, rtx *op2)
 
 /* Addressing modes and constants.  */
 
-/* Symbolic constants are split into high/lo_sum pairs during the 
-   split1 pass.  After that, they are not considered legitimate addresses.
+/* Symbol references and other 32-bit constants are split into
+   high/lo_sum pairs during the split1 pass.  After that, they are not
+   considered legitimate addresses.
    This function returns true if in a pre-split context where these
    constants are allowed.  */
 static bool
-nios2_symbolic_constant_allowed (void)
+nios2_large_constant_allowed (void)
 {
   /* The reload_completed check is for the benefit of
      nios2_asm_output_mi_thunk and perhaps other places that try to
@@ -2046,13 +2047,13 @@ nios2_symbolic_constant_p (rtx x)
 }
 
 /* Return true if X is an expression of the form 
-   (PLUS reg symbolic_constant).  */
+   (PLUS reg large_constant).  */
 static bool
-nios2_plus_symbolic_constant_p (rtx x)
+nios2_plus_large_constant_p (rtx x)
 {
   return (GET_CODE (x) == PLUS
          && REG_P (XEXP (x, 0))
-         && nios2_symbolic_constant_p (XEXP (x, 1)));
+         && nios2_large_constant_p (XEXP (x, 1)));
 }
 
 /* Implement TARGET_LEGITIMATE_CONSTANT_P.  */
@@ -2122,7 +2123,7 @@ nios2_valid_addr_expr_p (rtx base, rtx offset, bool strict_p)
          && nios2_regno_ok_for_base_p (REGNO (base), strict_p)
          && (offset == NULL_RTX
              || nios2_valid_addr_offset_p (offset)
-             || (nios2_symbolic_constant_allowed () 
+             || (nios2_large_constant_allowed () 
                  && nios2_symbolic_constant_p (offset))
              || nios2_unspec_reloc_p (offset)));
 }
@@ -2146,12 +2147,16 @@ nios2_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
 
       /* Else, fall through.  */
     case LABEL_REF:
-      if (nios2_symbolic_constant_allowed () 
+      if (nios2_large_constant_allowed () 
          && nios2_symbolic_constant_p (operand))
        return true;
+      return false;
 
-      /* Else, fall through.  */
     case CONST_INT:
+      if (r0rel_constant_p (operand))
+       return true;
+      return nios2_large_constant_allowed ();
+
     case CONST_DOUBLE:
       return false;
 
@@ -2213,9 +2218,9 @@ nios2_address_cost (rtx address,
                    addr_space_t as ATTRIBUTE_UNUSED, 
                    bool speed ATTRIBUTE_UNUSED)
 {
-  if (nios2_plus_symbolic_constant_p (address))
+  if (nios2_plus_large_constant_p (address))
     return COSTS_N_INSNS (1);
-  if (nios2_symbolic_constant_p (address))
+  if (nios2_large_constant_p (address))
     {
       if (GET_CODE (address) == CONST)
        return COSTS_N_INSNS (1);
@@ -2225,10 +2230,10 @@ nios2_address_cost (rtx address,
   return COSTS_N_INSNS (0);
 }
 
-/* Return true if X is a MEM whose address expression involves a symbolic
+/* Return true if X is a MEM whose address expression involves a large (32-bit)
    constant.  */
 bool
-nios2_symbolic_memory_operand_p (rtx x)
+nios2_large_constant_memory_operand_p (rtx x)
 {
   rtx addr;
 
@@ -2236,8 +2241,8 @@ nios2_symbolic_memory_operand_p (rtx x)
     return false;
   addr = XEXP (x, 0);
 
-  return (nios2_symbolic_constant_p (addr)
-         || nios2_plus_symbolic_constant_p (addr));
+  return (nios2_large_constant_p (addr)
+         || nios2_plus_large_constant_p (addr));
 }
 
 
@@ -2247,15 +2252,36 @@ bool
 nios2_large_constant_p (rtx x)
 {
   return (nios2_symbolic_constant_p (x)
-         || nios2_large_unspec_reloc_p (x));
+         || nios2_large_unspec_reloc_p (x)
+         || (CONST_INT_P (x) && !SMALL_INT (INTVAL (x))));
 }
 
 /* Given an RTX X that satisfies nios2_large_constant_p, split it into
    high and lo_sum parts using TEMP as a scratch register.  Emit the high 
-   instruction and return the lo_sum expression.  */
+   instruction and return the lo_sum expression.  
+   Also handle special cases involving constant integers.  */
 rtx
 nios2_split_large_constant (rtx x, rtx temp)
 {
+  if (CONST_INT_P (x))
+    {
+      HOST_WIDE_INT val = INTVAL (x);
+      if (SMALL_INT (val))
+       return x;
+      else if (SMALL_INT_UNSIGNED (val) || UPPER16_INT (val))
+       {
+         emit_move_insn (temp, x);
+         return temp;
+       }
+      else
+       {
+         HOST_WIDE_INT high = (val + 0x8000) & ~0xffff;
+         HOST_WIDE_INT low = val - high;
+         emit_move_insn (temp, gen_int_mode (high, Pmode));
+         return gen_rtx_PLUS (Pmode, temp, gen_int_mode (low, Pmode));
+       }
+    }
+  
   emit_insn (gen_rtx_SET (temp, gen_rtx_HIGH (Pmode, copy_rtx (x))));
   return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (x));
 }
@@ -2278,16 +2304,17 @@ nios2_split_plus_large_constant (rtx op0, rtx op1)
   return gen_rtx_LO_SUM (Pmode, temp, copy_rtx (op1));
 }
 
-/* Given a MEM OP with an address that includes a splittable symbol,
-   emit some instructions to do the split and return a new MEM.  */
+/* Given a MEM OP with an address that includes a splittable symbol or
+   other large constant, emit some instructions to do the split and 
+   return a new MEM.  */
 rtx
-nios2_split_symbolic_memory_operand (rtx op)
+nios2_split_large_constant_memory_operand (rtx op)
 {
   rtx addr = XEXP (op, 0);
 
-  if (nios2_symbolic_constant_p (addr))
+  if (nios2_large_constant_p (addr))
     addr = nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
-  else if (nios2_plus_symbolic_constant_p (addr))
+  else if (nios2_plus_large_constant_p (addr))
     addr = nios2_split_plus_large_constant (XEXP (addr, 0), XEXP (addr, 1));
   else
     gcc_unreachable ();
@@ -2533,9 +2560,19 @@ nios2_legitimize_constant_address (rtx addr)
     base = nios2_legitimize_tls_address (base);
   else if (flag_pic)
     base = nios2_load_pic_address (base, UNSPEC_PIC_SYM, NULL_RTX);
-  else if (!nios2_symbolic_constant_allowed () 
+  else if (!nios2_large_constant_allowed () 
           && nios2_symbolic_constant_p (addr))
     return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
+  else if (CONST_INT_P (addr))
+    {
+      HOST_WIDE_INT val = INTVAL (addr);
+      if (SMALL_INT (val))
+       /* Use r0-relative addressing.  */
+       return addr;
+      else if (!nios2_large_constant_allowed ())
+       /* Split into high/lo pair.  */
+       return nios2_split_large_constant (addr, gen_reg_rtx (Pmode));
+    }
   else
     return addr;
 
@@ -2579,7 +2616,7 @@ nios2_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
   /* We may need to split symbolic constants now.  */
   else if (nios2_symbolic_constant_p (op1))
     {
-      if (nios2_symbolic_constant_allowed ())
+      if (nios2_large_constant_allowed ())
        return gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), copy_rtx (op1));
       else
        return nios2_split_plus_large_constant (op0, op1);
@@ -2689,7 +2726,7 @@ nios2_emit_move_sequence (rtx *operands, machine_mode mode)
           representing a 32-bit offset.  We split the former 
           only conditionally and the latter always.  */
        {
-         if (!nios2_symbolic_constant_allowed () 
+         if (!nios2_large_constant_allowed () 
              || nios2_large_unspec_reloc_p (from))
            {
              rtx lo = nios2_split_large_constant (from, to);
@@ -3042,6 +3079,9 @@ r0rel_constant_p (rtx op)
   else if (GET_CODE (op) == CONST
            && GET_CODE (XEXP (op, 0)) == PLUS)
     return r0rel_constant_p (XEXP (XEXP (op, 0), 0));
+  else if (GET_CODE (op) == CONST_INT
+          && SMALL_INT (INTVAL (op)))
+    return true;
 
   return false;
 }
@@ -3112,11 +3152,20 @@ nios2_print_operand_address (FILE *file, machine_mode mode, rtx op)
         }
       else if (r0rel_constant_p (op))
         {
-          fprintf (file, "%%lo(");
-          output_addr_const (file, op);
-          fprintf (file, ")(r0)");
-          return;
-        }
+         if (CONST_INT_P (op))
+           {
+             output_addr_const (file, op);
+             fprintf (file, "(r0)");
+             return;
+           }
+         else
+           {
+             fprintf (file, "%%lo(");
+             output_addr_const (file, op);
+             fprintf (file, ")(r0)");
+             return;
+           }
+       }
       break;
 
     case PLUS:
index ef2883f25169c27b376942a14cde5afa52c5df32..1d16be489928df735d0d5aa0c88530e260f7a410 100644 (file)
        gcc_unreachable ();
       }
   }
-  "(nios2_symbolic_memory_operand_p (operands[0]) 
-   || nios2_symbolic_memory_operand_p (operands[1]))"
+  "(nios2_large_constant_memory_operand_p (operands[0]) 
+   || nios2_large_constant_memory_operand_p (operands[1]))"
   [(set (match_dup 0) (match_dup 1))]
   {
-    if (nios2_symbolic_memory_operand_p (operands[0]))
-      operands[0] = nios2_split_symbolic_memory_operand (operands[0]);
+    if (nios2_large_constant_memory_operand_p (operands[0]))
+      operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
     else
-      operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
+      operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
   }
   [(set_attr "type" "st,ld,mov")])
 
        gcc_unreachable ();
       }
   }
-  "(nios2_symbolic_memory_operand_p (operands[0]) 
-   || nios2_symbolic_memory_operand_p (operands[1]))"
+  "(nios2_large_constant_memory_operand_p (operands[0]) 
+   || nios2_large_constant_memory_operand_p (operands[1]))"
   [(set (match_dup 0) (match_dup 1))]
   {
-    if (nios2_symbolic_memory_operand_p (operands[0]))
-      operands[0] = nios2_split_symbolic_memory_operand (operands[0]);
+    if (nios2_large_constant_memory_operand_p (operands[0]))
+      operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
     else
-      operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
+      operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
   }
   [(set_attr "type" "st,ld,mov")])
 
        gcc_unreachable ();
       }
   }
-  "(nios2_symbolic_memory_operand_p (operands[0]) 
-    || nios2_symbolic_memory_operand_p (operands[1])
-    || nios2_large_constant_p (operands[1]))"
+  "(nios2_large_constant_memory_operand_p (operands[0]) 
+    || nios2_large_constant_memory_operand_p (operands[1])
+    || (nios2_large_constant_p (operands[1]) 
+        && !SMALL_INT_UNSIGNED (INTVAL (operands[1]))
+       && !UPPER16_INT (INTVAL (operands[1]))))"
   [(set (match_dup 0) (match_dup 1))]
   {
-    if (nios2_symbolic_memory_operand_p (operands[0]))
-      operands[0] = nios2_split_symbolic_memory_operand (operands[0]);
-    else if (nios2_symbolic_memory_operand_p (operands[1]))
-      operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
+    if (nios2_large_constant_memory_operand_p (operands[0]))
+      operands[0] = nios2_split_large_constant_memory_operand (operands[0]);
+    else if (nios2_large_constant_memory_operand_p (operands[1]))
+      operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
     else
       operands[1] = nios2_split_large_constant (operands[1], operands[0]);
   }
   "@
     andi%.\\t%0, %1, 0xffff
     ldhu%o1%.\\t%0, %1"
-  "nios2_symbolic_memory_operand_p (operands[1])"
+  "nios2_large_constant_memory_operand_p (operands[1])"
   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))]
   {
-    operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
   }
   [(set_attr "type"     "and,ld")])
 
   "@
     andi%.\\t%0, %1, 0xff
     ldbu%o1%.\\t%0, %1"
-  "nios2_symbolic_memory_operand_p (operands[1])"
+  "nios2_large_constant_memory_operand_p (operands[1])"
   [(set (match_dup 0) (zero_extend:QX (match_dup 1)))]
   {
-    operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
   }
   [(set_attr "type"     "and,ld")])
 
   "@
    #
    ldh%o1%.\\t%0, %1"
-  "nios2_symbolic_memory_operand_p (operands[1])"
+  "nios2_large_constant_memory_operand_p (operands[1])"
   [(set (match_dup 0) (sign_extend:SI (match_dup 1)))]
   {
-    operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
   }
   [(set_attr "type" "alu,ld")])
 
   "@
    #
    ldb%o1%.\\t%0, %1"
-  "nios2_symbolic_memory_operand_p (operands[1])"
+  "nios2_large_constant_memory_operand_p (operands[1])"
   [(set (match_dup 0) (sign_extend:QX (match_dup 1)))]
   {
-    operands[1] = nios2_split_symbolic_memory_operand (operands[1]);
+    operands[1] = nios2_split_large_constant_memory_operand (operands[1]);
   }
   [(set_attr "type" "alu,ld")])