104 lines
3.6 KiB
Diff
104 lines
3.6 KiB
Diff
|
From b55922d45fd16f5e8fc7c3885da42b2b9b37754d Mon Sep 17 00:00:00 2001
|
||
|
From: Claudiu Zissulescu <claziss@synopsys.com>
|
||
|
Date: Mon, 18 Jan 2016 16:43:18 +0100
|
||
|
Subject: [PATCH] UPDATE: Fix handling complex PIC moves.
|
||
|
|
||
|
fwprop is putting in the REG_EQUIV notes which are involving the
|
||
|
constant pic unspecs. Then, loop may use those notes for
|
||
|
optimizations rezulting in complex patterns that are not supported by
|
||
|
the current implementation. The following piece of code tries to
|
||
|
convert the complex instruction in simpler ones.
|
||
|
|
||
|
The fix is done in development tree: [arc-4.8-dev b55922d]
|
||
|
and will be a part of the next release of ARC GNU tools.
|
||
|
Once that new release happens this patch must be removed.
|
||
|
|
||
|
|
||
|
gcc/
|
||
|
2016-01-18 Claudiu Zissulescu <claziss@synopsys.com>
|
||
|
|
||
|
* config/arc/arc.c (arc_legitimize_pic_address): Handle MINUS
|
||
|
operations when doing PIC moves. Make this function static.
|
||
|
(arc_legitimate_pc_offset_p): Use
|
||
|
arc_raw_symbolic_reference_mentioned_p.
|
||
|
* config/arc/arc-protos.h (arc_legitimize_pic_address): Remove.
|
||
|
|
||
|
gcc/config/arc/arc-protos.h | 1 -
|
||
|
gcc/config/arc/arc.c | 33 +++++++++++++++++++--------------
|
||
|
2 files changed, 19 insertions(+), 15 deletions(-)
|
||
|
|
||
|
* config/arc/arc.c (arc_legitimize_pic_address): Handle complex
|
||
|
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
|
||
|
index 464e0ab..5986e06 100644
|
||
|
--- a/gcc/config/arc/arc-protos.h
|
||
|
+++ b/gcc/config/arc/arc-protos.h
|
||
|
@@ -53,7 +53,6 @@ extern unsigned int arc_compute_frame_size ();
|
||
|
extern bool arc_ccfsm_branch_deleted_p (void);
|
||
|
extern void arc_ccfsm_record_branch_deleted (void);
|
||
|
|
||
|
-extern rtx arc_legitimize_pic_address (rtx, rtx);
|
||
|
void arc_asm_output_aligned_decl_local (FILE *, tree, const char *,
|
||
|
unsigned HOST_WIDE_INT,
|
||
|
unsigned HOST_WIDE_INT,
|
||
|
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
|
||
|
index a89c8ee..f7cae9f 100644
|
||
|
--- a/gcc/config/arc/arc.c
|
||
|
+++ b/gcc/config/arc/arc.c
|
||
|
@@ -5243,19 +5243,7 @@ arc_legitimate_pc_offset_p (rtx addr)
|
||
|
if (GET_CODE (addr) != CONST)
|
||
|
return false;
|
||
|
addr = XEXP (addr, 0);
|
||
|
- if (GET_CODE (addr) == PLUS)
|
||
|
- {
|
||
|
- if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
|
||
|
- return false;
|
||
|
- addr = XEXP (addr, 0);
|
||
|
- }
|
||
|
- return (GET_CODE (addr) == UNSPEC
|
||
|
- && XVECLEN (addr, 0) == 1
|
||
|
- && (XINT (addr, 1) == ARC_UNSPEC_GOT
|
||
|
- || XINT (addr, 1) == ARC_UNSPEC_GOTOFFPC
|
||
|
- || XINT (addr, 1) == UNSPEC_TLS_GD
|
||
|
- || XINT (addr, 1) == UNSPEC_TLS_IE)
|
||
|
- && GET_CODE (XVECEXP (addr, 0, 0)) == SYMBOL_REF);
|
||
|
+ return flag_pic && !arc_raw_symbolic_reference_mentioned_p (addr, false);
|
||
|
}
|
||
|
|
||
|
/* Return true if ADDR is a valid pic address.
|
||
|
@@ -5522,7 +5510,7 @@ arc_legitimize_tls_address (rtx addr, enum tls_model model)
|
||
|
The return value is the legitimated address.
|
||
|
If OLDX is non-zero, it is the target to assign the address to first. */
|
||
|
|
||
|
-rtx
|
||
|
+static rtx
|
||
|
arc_legitimize_pic_address (rtx orig, rtx oldx)
|
||
|
{
|
||
|
rtx addr = orig;
|
||
|
@@ -5569,6 +5557,23 @@ arc_legitimize_pic_address (rtx orig, rtx oldx)
|
||
|
/* Check that the unspec is one of the ones we generate? */
|
||
|
return orig;
|
||
|
}
|
||
|
+ else if (GET_CODE (addr) == MINUS)
|
||
|
+ {
|
||
|
+ /* The same story with fwprop. */
|
||
|
+ 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 (VOIDmode, oldx,
|
||
|
+ gen_rtx_MINUS (SImode, op0, oldx)));
|
||
|
+ return oldx;
|
||
|
+
|
||
|
+ }
|
||
|
else if (GET_CODE (addr) != PLUS)
|
||
|
{
|
||
|
/* fwprop is putting in the REG_EQUIV notes which are
|
||
|
--
|
||
|
2.5.0
|
||
|
|