The attached change fixes a problem found in the libcap-ng package.
TLS call arguments
were not being pre expanded. As a result, the register arguments were
being clobbered.
After fixing pa_legitimate_constant_p() to return false for all TLS
references, I found that the
code in pa_emit_move_sequence to simplify TLS references in the form
CONST (PLUS SYMBOL_REF
CONST_INT) was not being executed. I fixed that and adjusted
CONSTANT_ADDRESS_P
to reject this form.
Tested on hppa-unknown-linux-gnu, hppa2.0w-hp-hpux11.11 and hppa64-hp-
hpux11.11.
Committed to trunk and 4.8.
Dave
--
John David Anglin dave.ang...@bell.net
2014-02-04 John David Anglin <dang...@gcc.gnu.org>
PR target/59777
* config/pa/pa.c (legitimize_tls_address): Return original address
if not passed a SYMBOL_REF rtx.
(hppa_legitimize_address): Call legitimize_tls_address for all TLS
addresses.
(pa_emit_move_sequence): Simplify TLS source operands.
(pa_legitimate_constant_p): Reject all TLS constants.
* config/pa/pa.h (PA_SYMBOL_REF_TLS_P): Correct comment.
(CONSTANT_ADDRESS_P): Reject TLS CONST addresses.
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c (revision 207393)
+++ config/pa/pa.c (working copy)
@@ -916,9 +910,12 @@
legitimize_tls_address (rtx addr)
{
rtx ret, insn, tmp, t1, t2, tp;
- enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
- switch (model)
+ /* Currently, we can't handle anything but a SYMBOL_REF. */
+ if (GET_CODE (addr) != SYMBOL_REF)
+ return addr;
+
+ switch (SYMBOL_REF_TLS_MODEL (addr))
{
case TLS_MODEL_GLOBAL_DYNAMIC:
tmp = gen_reg_rtx (Pmode);
@@ -1039,7 +1036,7 @@
&& !REG_POINTER (XEXP (x, 1)))
return gen_rtx_PLUS (Pmode, XEXP (x, 1), XEXP (x, 0));
- if (PA_SYMBOL_REF_TLS_P (x))
+ if (pa_tls_referenced_p (x))
return legitimize_tls_address (x);
else if (flag_pic)
return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
@@ -1920,9 +1917,10 @@
not consider them legitimate constants. Loop optimizations can
call the emit_move_xxx with one as a source. */
if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
+ || (GET_CODE (operand1) == HIGH
+ && symbolic_operand (XEXP (operand1, 0), mode))
|| function_label_operand (operand1, VOIDmode)
- || (GET_CODE (operand1) == HIGH
- && symbolic_operand (XEXP (operand1, 0), mode)))
+ || pa_tls_referenced_p (operand1))
{
int ishighonly = 0;
@@ -10300,7 +10298,7 @@
/* TLS_MODEL_GLOBAL_DYNAMIC and TLS_MODEL_LOCAL_DYNAMIC are not
legitimate constants. The other variants can't be handled by
the move patterns after reload starts. */
- if (PA_SYMBOL_REF_TLS_P (x))
+ if (pa_tls_referenced_p (x))
return false;
if (TARGET_64BIT && GET_CODE (x) == CONST_DOUBLE)
Index: config/pa/pa.h
===================================================================
--- config/pa/pa.h (revision 207393)
+++ config/pa/pa.h (working copy)
@@ -784,9 +784,9 @@
#define MAX_REGS_PER_ADDRESS 2
-/* Non-TLS symbolic references. */
-#define PA_SYMBOL_REF_TLS_P(RTX) \
- (GET_CODE (RTX) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (RTX) != 0)
+/* TLS symbolic reference. */
+#define PA_SYMBOL_REF_TLS_P(X) \
+ (GET_CODE (X) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (X) != 0)
/* Recognize any constant value that is a valid address except
for symbolic addresses. We get better CSE by rejecting them
@@ -796,7 +796,8 @@
#define CONSTANT_ADDRESS_P(X) \
((GET_CODE (X) == LABEL_REF \
|| (GET_CODE (X) == SYMBOL_REF && !SYMBOL_REF_TLS_MODEL (X))
\
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
+ || GET_CODE (X) == CONST_INT
\
+ || (GET_CODE (X) == CONST && !pa_tls_referenced_p (X)) \
|| GET_CODE (X) == HIGH) \
&& (reload_in_progress || reload_completed \
|| ! pa_symbolic_expression_p (X)))