aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSandra Loosemore <sandra@codesourcery.com>2017-12-07 23:23:00 -0500
committerSandra Loosemore <sandra@gcc.gnu.org>2017-12-07 23:23:00 -0500
commitdf8ceba6a23ea326444348b922ef0550f9239107 (patch)
tree91b675f96614fe5d29161e867aff8b5ea29f635d /gcc
parent6cb0725cdbef47a7486629b7933f51a29a591781 (diff)
downloadgcc-df8ceba6a23ea326444348b922ef0550f9239107.zip
gcc-df8ceba6a23ea326444348b922ef0550f9239107.tar.gz
gcc-df8ceba6a23ea326444348b922ef0550f9239107.tar.bz2
nios2.c (nios2_symbolic_constant_allowed): Rename to...
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/nios2/nios2-protos.h4
-rw-r--r--gcc/config/nios2/nios2.c109
-rw-r--r--gcc/config/nios2/nios2.md52
4 files changed, 128 insertions, 57 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b9d7ed7..39a6f94 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/nios2/nios2-protos.h b/gcc/config/nios2/nios2-protos.h
index 84d450b..578750c 100644
--- a/gcc/config/nios2/nios2-protos.h
+++ b/gcc/config/nios2/nios2-protos.h
@@ -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);
diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c
index 5c70de7..e0df9c5 100644
--- a/gcc/config/nios2/nios2.c
+++ b/gcc/config/nios2/nios2.c
@@ -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:
diff --git a/gcc/config/nios2/nios2.md b/gcc/config/nios2/nios2.md
index ef2883f..1d16be4 100644
--- a/gcc/config/nios2/nios2.md
+++ b/gcc/config/nios2/nios2.md
@@ -224,14 +224,14 @@
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")])
@@ -253,14 +253,14 @@
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")])
@@ -296,15 +296,17 @@
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]);
}
@@ -364,10 +366,10 @@
"@
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")])
@@ -378,10 +380,10 @@
"@
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")])
@@ -394,10 +396,10 @@
"@
#
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")])
@@ -408,10 +410,10 @@
"@
#
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")])