+++ /dev/null
-From e5398fbcaa1dc35422958acfdb13074bf4a797a3 Mon Sep 17 00:00:00 2001
-From: claziss <claziss@138bc75d-0d04-0410-961f-82ee72b054a4>
-Date: Tue, 25 Jun 2019 11:02:21 +0000
-Subject: [PATCH 1/2] [ARC] Backport fix PR89838
-
-Fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89838
-Similar to https://git.buildroot.org/buildroot/commit/?h=dbf7fffb37e25c40fd5c03d0a64e50a1bba86424
-but rebased on upstream stable "gcc-9-branch".
-
-gcc/
-xxxx-xx-xx Claudiu Zissulescu <claziss@synopsys.com>
-
- * config/arc/arc.c (arc_symbol_binds_local_p): New function.
- (arc_legitimize_pic_address): Simplify and cleanup the function.
- (SYMBOLIC_CONST): Remove.
- (prepare_pic_move): Likewise.
- (prepare_move_operands): Handle complex mov cases here.
- (arc_legitimize_address_0): Remove call to
- arc_legitimize_pic_address.
- (arc_legitimize_address): Remove call to
- arc_legitimize_tls_address.
- * config/arc/arc.md (movqi_insn): Allow Cm3 match.
- (movhi_insn): Likewise.
-
-/gcc/testsuite
-xxxx-xx-xx Claudiu Zissulescu <claziss@synopsys.com
-
-git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-9-branch@272645 138bc75d-0d04-0410-961f-82ee72b054a4
-
-Fix in upstream gcc-9-branch:
-https://github.com/gcc-mirror/gcc/commit/472bac30e63ffacecfa5eda813054555f2cc7de
-
-Signed-off-by: Claudiu Zissulescu <claziss@synopsys.com>
-Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
----
- gcc/config/arc/arc.c | 238 ++++++++++++--------------------------------------
- gcc/config/arc/arc.md | 8 +-
- 2 files changed, 60 insertions(+), 186 deletions(-)
-
-diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
-index 2f5753b02fa..daacc79d0cb 100644
---- a/gcc/config/arc/arc.c
-+++ b/gcc/config/arc/arc.c
-@@ -5971,130 +5971,47 @@ arc_legitimize_tls_address (rtx addr, enum tls_model model)
- }
- }
-
--/* Legitimize a pic address reference in ORIG.
-- The return value is the legitimated address.
-- If OLDX is non-zero, it is the target to assign the address to first. */
-+/* Return true if SYMBOL_REF X binds locally. */
-
--static rtx
--arc_legitimize_pic_address (rtx orig, rtx oldx)
-+static bool
-+arc_symbol_binds_local_p (const_rtx x)
- {
-- rtx addr = orig;
-- rtx pat = orig;
-- rtx base;
-+ return (SYMBOL_REF_DECL (x)
-+ ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
-+ : SYMBOL_REF_LOCAL_P (x));
-+}
-
-- if (oldx == orig)
-- oldx = NULL;
-+/* Legitimize a pic address reference in ADDR. The return value is
-+ the legitimated address. */
-
-- if (GET_CODE (addr) == LABEL_REF)
-- ; /* Do nothing. */
-- else if (GET_CODE (addr) == SYMBOL_REF)
-+static rtx
-+arc_legitimize_pic_address (rtx addr)
-+{
-+ if (!flag_pic)
-+ return addr;
-+
-+ switch (GET_CODE (addr))
- {
-- enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
-- if (model != 0)
-- return arc_legitimize_tls_address (addr, model);
-- else if (!flag_pic)
-- return orig;
-- else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr))
-- return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
-+ case SYMBOL_REF:
-+ /* TLS symbols are handled in different place. */
-+ if (SYMBOL_REF_TLS_MODEL (addr))
-+ return addr;
-
- /* This symbol must be referenced via a load from the Global
- Offset Table (@GOTPC). */
-- pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT);
-- pat = gen_const_mem (Pmode, pat);
--
-- if (oldx == NULL)
-- oldx = gen_reg_rtx (Pmode);
--
-- emit_move_insn (oldx, pat);
-- pat = oldx;
-- }
-- else
-- {
-- if (GET_CODE (addr) == CONST)
-- {
-- addr = XEXP (addr, 0);
-- if (GET_CODE (addr) == UNSPEC)
-- {
-- /* Check that the unspec is one of the ones we generate? */
-- return orig;
-- }
-- /* fwprop is placing in the REG_EQUIV notes constant pic
-- unspecs expressions. Then, loop may use these notes for
-- optimizations resulting in complex patterns that are not
-- supported by the current implementation. The following
-- two if-cases are simplifying the complex patters to
-- simpler ones. */
-- else if (GET_CODE (addr) == MINUS)
-- {
-- rtx op0 = XEXP (addr, 0);
-- rtx op1 = XEXP (addr, 1);
-- gcc_assert (oldx);
-- gcc_assert (GET_CODE (op1) == UNSPEC);
--
-- emit_move_insn (oldx,
-- gen_rtx_CONST (SImode,
-- arc_legitimize_pic_address (op1,
-- NULL_RTX)));
-- emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx)));
-- return oldx;
--
-- }
-- else if (GET_CODE (addr) != PLUS)
-- {
-- rtx tmp = XEXP (addr, 0);
-- enum rtx_code code = GET_CODE (addr);
--
-- /* It only works for UNARY operations. */
-- gcc_assert (UNARY_P (addr));
-- gcc_assert (GET_CODE (tmp) == UNSPEC);
-- gcc_assert (oldx);
--
-- emit_move_insn
-- (oldx,
-- gen_rtx_CONST (SImode,
-- arc_legitimize_pic_address (tmp,
-- NULL_RTX)));
--
-- emit_insn (gen_rtx_SET (oldx,
-- gen_rtx_fmt_ee (code, SImode,
-- oldx, const0_rtx)));
--
-- return oldx;
-- }
-- else
-- {
-- gcc_assert (GET_CODE (addr) == PLUS);
-- if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
-- return orig;
-- }
-- }
--
-- if (GET_CODE (addr) == PLUS)
-- {
-- rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
-+ if (!arc_symbol_binds_local_p (addr))
-+ return gen_const_mem (Pmode, arc_unspec_offset (addr, ARC_UNSPEC_GOT));
-
-- base = arc_legitimize_pic_address (op0, oldx);
-- pat = arc_legitimize_pic_address (op1,
-- base == oldx ? NULL_RTX : oldx);
--
-- if (base == op0 && pat == op1)
-- return orig;
-+ /* Local symb: use @pcl to access it. */
-+ /* Fall through. */
-+ case LABEL_REF:
-+ return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
-
-- if (GET_CODE (pat) == CONST_INT)
-- pat = plus_constant (Pmode, base, INTVAL (pat));
-- else
-- {
-- if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1)))
-- {
-- base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0));
-- pat = XEXP (pat, 1);
-- }
-- pat = gen_rtx_PLUS (Pmode, base, pat);
-- }
-- }
-+ default:
-+ break;
- }
-
-- return pat;
-+ return addr;
- }
-
- /* Output address constant X to FILE, taking PIC into account. */
-@@ -6256,28 +6173,6 @@ arc_output_pic_addr_const (FILE * file, rtx x, int code)
- }
- }
-
--#define SYMBOLIC_CONST(X) \
--(GET_CODE (X) == SYMBOL_REF \
-- || GET_CODE (X) == LABEL_REF \
-- || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
--
--/* Emit insns to move operands[1] into operands[0]. */
--
--static void
--prepare_pic_move (rtx *operands, machine_mode)
--{
-- if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])
-- && flag_pic)
-- operands[1] = force_reg (Pmode, operands[1]);
-- else
-- {
-- rtx temp = (reload_in_progress ? operands[0]
-- : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX);
-- operands[1] = arc_legitimize_pic_address (operands[1], temp);
-- }
--}
--
--
- /* The function returning the number of words, at the beginning of an
- argument, must be put in registers. The returned value must be
- zero for arguments that are passed entirely in registers or that
-@@ -9053,54 +8948,37 @@ prepare_move_operands (rtx *operands, machine_mode mode)
- }
- }
-
-- if (mode == SImode && SYMBOLIC_CONST (operands[1]))
-+ if (GET_CODE (operands[1]) == SYMBOL_REF)
- {
-- prepare_pic_move (operands, SImode);
--
-- /* Disable any REG_EQUALs associated with the symref
-- otherwise the optimization pass undoes the work done
-- here and references the variable directly. */
-+ enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
-+ if (MEM_P (operands[0]) && flag_pic)
-+ operands[1] = force_reg (mode, operands[1]);
-+ else if (model)
-+ operands[1] = arc_legitimize_tls_address (operands[1], model);
- }
-
-+ operands[1] = arc_legitimize_pic_address (operands[1]);
-+
-+ /* Store instructions are limited, they only accept as address an
-+ immediate, a register or a register plus a small immediate. */
- if (MEM_P (operands[0])
-- && !(reload_in_progress || reload_completed))
-+ && !move_dest_operand (operands[0], mode))
- {
-- operands[1] = force_reg (mode, operands[1]);
-- if (!move_dest_operand (operands[0], mode))
-- {
-- rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
-- /* This is like change_address_1 (operands[0], mode, 0, 1) ,
-- except that we can't use that function because it is static. */
-- rtx pat = change_address (operands[0], mode, addr);
-- MEM_COPY_ATTRIBUTES (pat, operands[0]);
-- operands[0] = pat;
-- }
-- if (!cse_not_expected)
-- {
-- rtx pat = XEXP (operands[0], 0);
--
-- pat = arc_legitimize_address_0 (pat, pat, mode);
-- if (pat)
-- {
-- pat = change_address (operands[0], mode, pat);
-- MEM_COPY_ATTRIBUTES (pat, operands[0]);
-- operands[0] = pat;
-- }
-- }
-+ rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
-+ rtx tmp1 = change_address (operands[0], mode, tmp0);
-+ MEM_COPY_ATTRIBUTES (tmp1, operands[0]);
-+ operands[0] = tmp1;
- }
-
-- if (MEM_P (operands[1]) && !cse_not_expected)
-- {
-- rtx pat = XEXP (operands[1], 0);
--
-- pat = arc_legitimize_address_0 (pat, pat, mode);
-- if (pat)
-- {
-- pat = change_address (operands[1], mode, pat);
-- MEM_COPY_ATTRIBUTES (pat, operands[1]);
-- operands[1] = pat;
-- }
-- }
-+ /* Check if it is constant but it is not legitimized. */
-+ if (CONSTANT_P (operands[1])
-+ && !arc_legitimate_constant_p (mode, operands[1]))
-+ operands[1] = force_reg (mode, XEXP (operands[1], 0));
-+ else if (MEM_P (operands[0])
-+ && ((CONSTANT_P (operands[1])
-+ && !satisfies_constraint_Cm3 (operands[1]))
-+ || MEM_P (operands[1])))
-+ operands[1] = force_reg (mode, operands[1]);
-
- return false;
- }
-@@ -9572,11 +9450,10 @@ arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
- {
- rtx addr, inner;
-
-- if (flag_pic && SYMBOLIC_CONST (x))
-- (x) = arc_legitimize_pic_address (x, 0);
- addr = x;
- if (GET_CODE (addr) == CONST)
- addr = XEXP (addr, 0);
-+
- if (GET_CODE (addr) == PLUS
- && CONST_INT_P (XEXP (addr, 1))
- && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
-@@ -9607,13 +9484,6 @@ arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
- static rtx
- arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
- {
-- if (GET_CODE (orig_x) == SYMBOL_REF)
-- {
-- enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x);
-- if (model != 0)
-- return arc_legitimize_tls_address (orig_x, model);
-- }
--
- rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
-
- if (new_x)
-diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
-index ce1004c1b56..78e304d4c71 100644
---- a/gcc/config/arc/arc.md
-+++ b/gcc/config/arc/arc.md
-@@ -671,7 +671,9 @@ core_3, archs4x, archs4xd, archs4xd_slow"
- [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w, w,???w,h, w,Rcq, S,!*x, r,r, Ucm,m,???m, m,Usc")
- (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL, I,?Rac,i,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3,i"))]
- "register_operand (operands[0], QImode)
-- || register_operand (operands[1], QImode)"
-+ || register_operand (operands[1], QImode)
-+ || (satisfies_constraint_Cm3 (operands[1])
-+ && memory_operand (operands[0], QImode))"
- "@
- mov%? %0,%1%&
- mov%? %0,%1%&
-@@ -713,7 +715,9 @@ core_3, archs4x, archs4xd, archs4xd_slow"
- /* Don't use a LIMM that we could load with a single insn - we loose
- delay-slot filling opportunities. */
- && !satisfies_constraint_I (operands[1])
-- && satisfies_constraint_Usc (operands[0]))"
-+ && satisfies_constraint_Usc (operands[0]))
-+ || (satisfies_constraint_Cm3 (operands[1])
-+ && memory_operand (operands[0], HImode))"
- "@
- mov%? %0,%1%&
- mov%? %0,%1%&
---
-2.16.2
-