Commit 02ae0e08 by Claudiu Zissulescu

arc: Update legitimate small data address.

All ARC's small data adressing is using address scaling feature of the
load/store instructions (i.e., the address is made of a general
pointer plus a shifted offset. The shift amount depends on the
addressing mode).  This patch is checking the offset of an address if
it fits the scalled constraint.  If so, a small data access is
generated.  This patch fixes execute' pr93249 failure.

gcc/
xxxx-xx-xx  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc.c (leigitimate_small_data_address_p): Check if an
	address has an offset which fits the scalling constraint for a
	load/store operation.
	(legitimate_scaled_address_p): Update use
	leigitimate_small_data_address_p.
	(arc_print_operand): Likewise.
	(arc_legitimate_address_p): Likewise.
	(legitimate_small_data_address_p): Likewise.

Signed-off-by: Claudiu Zissulescu <claziss@gmail.com>
parent 9c3044a2
2020-03-03 Claudiu Zissulescu <claziss@synopsys.com> 2020-03-03 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc.c (leigitimate_small_data_address_p): Check if an
address has an offset which fits the scalling constraint for a
load/store operation.
(legitimate_scaled_address_p): Update use
leigitimate_small_data_address_p.
(arc_print_operand): Likewise.
(arc_legitimate_address_p): Likewise.
(legitimate_small_data_address_p): Likewise.
2020-03-03 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc.md (fmasf4_fpu): Use accl_operand predicate. * config/arc/arc.md (fmasf4_fpu): Use accl_operand predicate.
(fnmasf4_fpu): Likewise. (fnmasf4_fpu): Likewise.
......
...@@ -463,21 +463,37 @@ get_symbol_alignment (rtx x) ...@@ -463,21 +463,37 @@ get_symbol_alignment (rtx x)
/* Return true if x is ok to be used as a small data address. */ /* Return true if x is ok to be used as a small data address. */
static bool static bool
legitimate_small_data_address_p (rtx x) legitimate_small_data_address_p (rtx x, machine_mode mode)
{ {
switch (GET_CODE (x)) switch (GET_CODE (x))
{ {
case CONST: case CONST:
return legitimate_small_data_address_p (XEXP (x, 0)); return legitimate_small_data_address_p (XEXP (x, 0), mode);
case SYMBOL_REF: case SYMBOL_REF:
return SYMBOL_REF_SMALL_P (x); return SYMBOL_REF_SMALL_P (x);
case PLUS: case PLUS:
{ {
bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF) bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
&& SYMBOL_REF_SMALL_P (XEXP (x, 0)); && SYMBOL_REF_SMALL_P (XEXP (x, 0));
bool p1 = CONST_INT_P (XEXP (x, 1))
&& (INTVAL (XEXP (x, 1)) <= g_switch_value); /* If no constant then we cannot do small data. */
return p0 && p1; if (!CONST_INT_P (XEXP (x, 1)))
return false;
/* Small data relocs works with scalled addresses, check if
the immediate fits the requirements. */
switch (GET_MODE_SIZE (mode))
{
case 1:
return p0;
case 2:
return p0 && ((INTVAL (XEXP (x, 1)) & 0x1) == 0);
case 4:
case 8:
return p0 && ((INTVAL (XEXP (x, 1)) & 0x3) == 0);
default:
return false;
}
} }
default: default:
return false; return false;
...@@ -531,7 +547,7 @@ legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict) ...@@ -531,7 +547,7 @@ legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
} }
/* Scalled addresses for sdata is done other places. */ /* Scalled addresses for sdata is done other places. */
if (legitimate_small_data_address_p (op)) if (legitimate_small_data_address_p (op, mode))
return false; return false;
if (CONSTANT_P (XEXP (op, 1))) if (CONSTANT_P (XEXP (op, 1)))
...@@ -4810,7 +4826,7 @@ arc_print_operand (FILE *file, rtx x, int code) ...@@ -4810,7 +4826,7 @@ arc_print_operand (FILE *file, rtx x, int code)
break; break;
case SYMBOL_REF: case SYMBOL_REF:
case CONST: case CONST:
if (legitimate_small_data_address_p (addr) if (legitimate_small_data_address_p (addr, GET_MODE (x))
&& GET_MODE_SIZE (GET_MODE (x)) > 1) && GET_MODE_SIZE (GET_MODE (x)) > 1)
{ {
int align = get_symbol_alignment (addr); int align = get_symbol_alignment (addr);
...@@ -4943,7 +4959,7 @@ arc_print_operand (FILE *file, rtx x, int code) ...@@ -4943,7 +4959,7 @@ arc_print_operand (FILE *file, rtx x, int code)
rtx addr = XEXP (x, 0); rtx addr = XEXP (x, 0);
int size = GET_MODE_SIZE (GET_MODE (x)); int size = GET_MODE_SIZE (GET_MODE (x));
if (legitimate_small_data_address_p (addr)) if (legitimate_small_data_address_p (addr, GET_MODE (x)))
output_sdata = 1; output_sdata = 1;
fputc ('[', file); fputc ('[', file);
...@@ -6701,7 +6717,7 @@ arc_legitimate_address_p (machine_mode mode, rtx x, bool strict) ...@@ -6701,7 +6717,7 @@ arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
return true; return true;
if (legitimate_scaled_address_p (mode, x, strict)) if (legitimate_scaled_address_p (mode, x, strict))
return true; return true;
if (legitimate_small_data_address_p (x)) if (legitimate_small_data_address_p (x, mode))
return true; return true;
if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x))) if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
return true; return true;
...@@ -8748,7 +8764,7 @@ compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p) ...@@ -8748,7 +8764,7 @@ compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
/* Decode the address now. */ /* Decode the address now. */
addr = XEXP (op, 0); addr = XEXP (op, 0);
if (!legitimate_small_data_address_p (addr)) if (!legitimate_small_data_address_p (addr, mode))
return false; return false;
if (!short_p || size == 1) if (!short_p || size == 1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment