* Re: Fix x86-64 PIC
2002-10-29 12:55 ` Jakub Jelinek
2002-10-29 13:04 ` Jan Hubicka
@ 2002-10-29 14:46 ` Jan Hubicka
1 sibling, 0 replies; 10+ messages in thread
From: Jan Hubicka @ 2002-10-29 14:46 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Jan Hubicka, gcc-patches, rth
Hi,
Here is updated patch that fix somewhat inconsistent situation.
It makes sign_extended_operand, local_symbolic_operand and
legitimate_pic_address_disp_p do what they are supposed to do (and have
in comments) and fixes the rest to deal with these.
Jakub, can you please check wehtehr it does good job for your testcases?
Tue Oct 29 23:41:46 CET 2002 Jan Hubicka <jh@suse.cz>
* i386-protos.h (x86_64_sign_extended_value): Fix prototype.
* i386.c (x86_64_general_operand, x86_64_szext_general_operand,
x86_64_nonmemory_operand, x86_64_movabs_operand,
x86_64_szext_nonmemory_operand, x86_64_immediate_operand,
ix86_expand_int_movcc): Update call of x86_64_sign_extended_value.
(local_symbolic_operand): Do not care the 64bit limits.
(x86_64_sign_extended_value): Remove allow_rip support.
(legitimate_pic_address_disp_p): Handle all cases allowed
with RIP addressing.
(legitimate_address_p): Use legitimate_pic_address_disp_p for PIC.
(legitimize_pic_address): Reorganize.
* i386.h (EXTRA_CONSTRAINT): Update call of x86_64_sign_extended_value.
Index: i386-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v
retrieving revision 1.77.4.5
diff -c -3 -p -r1.77.4.5 i386-protos.h
*** i386-protos.h 29 Oct 2002 19:49:58 -0000 1.77.4.5
--- i386-protos.h 29 Oct 2002 22:40:54 -0000
*************** extern int ix86_attr_length_address_defa
*** 154,160 ****
extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
! extern int x86_64_sign_extended_value PARAMS ((rtx, int));
extern int x86_64_zero_extended_value PARAMS ((rtx));
extern rtx ix86_libcall_value PARAMS ((enum machine_mode));
extern bool ix86_function_value_regno_p PARAMS ((int));
--- 154,160 ----
extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
! extern int x86_64_sign_extended_value PARAMS ((rtx));
extern int x86_64_zero_extended_value PARAMS ((rtx));
extern rtx ix86_libcall_value PARAMS ((enum machine_mode));
extern bool ix86_function_value_regno_p PARAMS ((int));
Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.447.2.18
diff -c -3 -p -r1.447.2.18 i386.c
*** i386.c 29 Oct 2002 19:49:58 -0000 1.447.2.18
--- i386.c 29 Oct 2002 22:40:57 -0000
*************** x86_64_general_operand (op, mode)
*** 2946,2952 ****
return general_operand (op, mode);
if (nonimmediate_operand (op, mode))
return 1;
! return x86_64_sign_extended_value (op, 1);
}
/* Return nonzero if OP is general operand representable on x86_64
--- 2946,2952 ----
return general_operand (op, mode);
if (nonimmediate_operand (op, mode))
return 1;
! return x86_64_sign_extended_value (op);
}
/* Return nonzero if OP is general operand representable on x86_64
*************** x86_64_szext_general_operand (op, mode)
*** 2961,2967 ****
return general_operand (op, mode);
if (nonimmediate_operand (op, mode))
return 1;
! return x86_64_sign_extended_value (op, 1) || x86_64_zero_extended_value (op);
}
/* Return nonzero if OP is nonmemory operand representable on x86_64. */
--- 2961,2967 ----
return general_operand (op, mode);
if (nonimmediate_operand (op, mode))
return 1;
! return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
}
/* Return nonzero if OP is nonmemory operand representable on x86_64. */
*************** x86_64_nonmemory_operand (op, mode)
*** 2975,2981 ****
return nonmemory_operand (op, mode);
if (register_operand (op, mode))
return 1;
! return x86_64_sign_extended_value (op, 1);
}
/* Return nonzero if OP is nonmemory operand acceptable by movabs patterns. */
--- 2975,2981 ----
return nonmemory_operand (op, mode);
if (register_operand (op, mode))
return 1;
! return x86_64_sign_extended_value (op);
}
/* Return nonzero if OP is nonmemory operand acceptable by movabs patterns. */
*************** x86_64_movabs_operand (op, mode)
*** 2987,2993 ****
{
if (!TARGET_64BIT || !flag_pic)
return nonmemory_operand (op, mode);
! if (register_operand (op, mode) || x86_64_sign_extended_value (op, 0))
return 1;
if (CONSTANT_P (op) && !symbolic_reference_mentioned_p (op))
return 1;
--- 2987,2993 ----
{
if (!TARGET_64BIT || !flag_pic)
return nonmemory_operand (op, mode);
! if (register_operand (op, mode) || x86_64_sign_extended_value (op))
return 1;
if (CONSTANT_P (op) && !symbolic_reference_mentioned_p (op))
return 1;
*************** x86_64_szext_nonmemory_operand (op, mode
*** 3005,3011 ****
return nonmemory_operand (op, mode);
if (register_operand (op, mode))
return 1;
! return x86_64_sign_extended_value (op, 0) || x86_64_zero_extended_value (op);
}
/* Return nonzero if OP is immediate operand representable on x86_64. */
--- 3005,3011 ----
return nonmemory_operand (op, mode);
if (register_operand (op, mode))
return 1;
! return x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op);
}
/* Return nonzero if OP is immediate operand representable on x86_64. */
*************** x86_64_immediate_operand (op, mode)
*** 3017,3023 ****
{
if (!TARGET_64BIT)
return immediate_operand (op, mode);
! return x86_64_sign_extended_value (op, 0);
}
/* Return nonzero if OP is immediate operand representable on x86_64. */
--- 3017,3023 ----
{
if (!TARGET_64BIT)
return immediate_operand (op, mode);
! return x86_64_sign_extended_value (op);
}
/* Return nonzero if OP is immediate operand representable on x86_64. */
*************** local_symbolic_operand (op, mode)
*** 3137,3146 ****
{
if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
! && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
! && (ix86_cmodel != CM_SMALL_PIC
! || (INTVAL (XEXP (XEXP (op, 0), 1)) >= -16*1024*1024
! && INTVAL (XEXP (XEXP (op, 0), 1)) < 16*1024*1024)))
op = XEXP (XEXP (op, 0), 0);
if (GET_CODE (op) == LABEL_REF)
--- 3137,3143 ----
{
if (GET_CODE (op) == CONST
&& GET_CODE (XEXP (op, 0)) == PLUS
! && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
op = XEXP (XEXP (op, 0), 0);
if (GET_CODE (op) == LABEL_REF)
*************** ix86_can_use_return_insn_p ()
*** 3942,3950 ****
\f
/* Return 1 if VALUE can be stored in the sign extended immediate field. */
int
! x86_64_sign_extended_value (value, allow_rip)
rtx value;
- int allow_rip;
{
switch (GET_CODE (value))
{
--- 3939,3946 ----
\f
/* Return 1 if VALUE can be stored in the sign extended immediate field. */
int
! x86_64_sign_extended_value (value)
rtx value;
{
switch (GET_CODE (value))
{
*************** x86_64_sign_extended_value (value, allow
*** 3966,3982 ****
library. Don't count TLS SYMBOL_REFs here, since they should fit
only if inside of UNSPEC handled below. */
case SYMBOL_REF:
! return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL
! || (allow_rip
! && ix86_cmodel == CM_SMALL_PIC
! && (CONSTANT_POOL_ADDRESS_P (value)
! || SYMBOL_REF_FLAG (value))
! && ! tls_symbolic_operand (value, GET_MODE (value))));
/* For certain code models, the code is near as well. */
case LABEL_REF:
! return ix86_cmodel != CM_LARGE
! && (allow_rip || ix86_cmodel != CM_SMALL_PIC);
/* We also may accept the offsetted memory references in certain special
cases. */
--- 3962,3972 ----
library. Don't count TLS SYMBOL_REFs here, since they should fit
only if inside of UNSPEC handled below. */
case SYMBOL_REF:
! return (ix86_cmodel == CM_SMALL || ix86_cmodel == CM_KERNEL);
/* For certain code models, the code is near as well. */
case LABEL_REF:
! return ix86_cmodel != CM_LARGE;
/* We also may accept the offsetted memory references in certain special
cases. */
*************** x86_64_sign_extended_value (value, allow
*** 4022,4047 ****
&& offset > 0
&& trunc_int_for_mode (offset, SImode) == offset)
return 1;
- /* For CM_SMALL_PIC, we can make similar assumptions
- as for CM_SMALL model, if we know the symbol is local
- to the shared library. Disallow any TLS symbols,
- since they should always be enclosed in an UNSPEC. */
- if (ix86_cmodel == CM_SMALL_PIC
- && allow_rip
- && (CONSTANT_POOL_ADDRESS_P (op1)
- || SYMBOL_REF_FLAG (op1))
- && ! tls_symbolic_operand (op1, GET_MODE (op1))
- && offset < 16*1024*1024
- && offset >= -16*1024*1024
- && trunc_int_for_mode (offset, SImode) == offset)
- return 1;
break;
case LABEL_REF:
/* These conditions are similar to SYMBOL_REF ones, just the
constraints for code models differ. */
! if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM
! || (ix86_cmodel == CM_SMALL_PIC && allow_rip
! && offset >= -16*1024*1024))
&& offset < 16*1024*1024
&& trunc_int_for_mode (offset, SImode) == offset)
return 1;
--- 4012,4022 ----
&& offset > 0
&& trunc_int_for_mode (offset, SImode) == offset)
return 1;
break;
case LABEL_REF:
/* These conditions are similar to SYMBOL_REF ones, just the
constraints for code models differ. */
! if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM)
&& offset < 16*1024*1024
&& trunc_int_for_mode (offset, SImode) == offset)
return 1;
*************** legitimate_pic_address_disp_p (disp)
*** 5248,5255 ****
/* In 64bit mode we can allow direct addresses of symbols and labels
when they are not dynamic symbols. */
! if (TARGET_64BIT && local_symbolic_operand (disp, Pmode))
! return 1;
if (GET_CODE (disp) != CONST)
return 0;
disp = XEXP (disp, 0);
--- 5223,5252 ----
/* In 64bit mode we can allow direct addresses of symbols and labels
when they are not dynamic symbols. */
! if (TARGET_64BIT)
! {
! /* TLS references should always be enclosed in UNSPEC. */
! if (tls_symbolic_operand (disp, GET_MODE (disp)))
! return 0;
! if (GET_CODE (disp) == SYMBOL_REF
! && ix86_cmodel == CM_SMALL_PIC
! && (CONSTANT_POOL_ADDRESS_P (disp)
! || SYMBOL_REF_FLAG (disp)))
! return 1;
! if (GET_CODE (disp) == LABEL_REF)
! return 1;
! if (GET_CODE (disp) == CONST
! && GET_CODE (XEXP (disp, 0)) == PLUS
! && ((GET_CODE (XEXP (XEXP (disp, 0), 0)) == SYMBOL_REF
! && ix86_cmodel == CM_SMALL_PIC
! && (CONSTANT_POOL_ADDRESS_P (XEXP (XEXP (disp, 0), 0))
! || SYMBOL_REF_FLAG (XEXP (XEXP (disp, 0), 0))))
! || GET_CODE (XEXP (XEXP (disp, 0), 0)) == LABEL_REF)
! && GET_CODE (XEXP (XEXP (disp, 0), 1)) == CONST_INT
! && INTVAL (XEXP (XEXP (disp, 0), 1)) < 16*1024*1024
! && INTVAL (XEXP (XEXP (disp, 0), 1)) >= -16*1024*1024)
! return 1;
! }
if (GET_CODE (disp) != CONST)
return 0;
disp = XEXP (disp, 0);
*************** legitimate_address_p (mode, addr, strict
*** 5456,5478 ****
{
reason_rtx = disp;
- if (TARGET_64BIT)
- {
- if (!x86_64_sign_extended_value (disp, !(index || base)))
- {
- reason = "displacement is out of range";
- goto report_error;
- }
- }
- else
- {
- if (GET_CODE (disp) == CONST_DOUBLE)
- {
- reason = "displacement is a const_double";
- goto report_error;
- }
- }
-
if (GET_CODE (disp) == CONST
&& GET_CODE (XEXP (disp, 0)) == UNSPEC)
switch (XINT (XEXP (disp, 0), 1))
--- 5453,5458 ----
*************** legitimate_address_p (mode, addr, strict
*** 5550,5555 ****
--- 5530,5545 ----
reason = "displacement is not constant";
goto report_error;
}
+ else if (TARGET_64BIT && !x86_64_sign_extended_value (disp))
+ {
+ reason = "displacement is out of range";
+ goto report_error;
+ }
+ else if (!TARGET_64BIT && GET_CODE (disp) == CONST_DOUBLE)
+ {
+ reason = "displacement is a const_double";
+ goto report_error;
+ }
}
/* Everything looks valid. */
*************** legitimize_pic_address (orig, reg)
*** 5611,5638 ****
return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
#endif
! if (local_symbolic_operand (addr, Pmode))
! {
! /* In 64bit mode we can address such objects directly. */
! if (TARGET_64BIT)
! new = addr;
! else
! {
! /* This symbol may be referenced via a displacement from the PIC
! base address (@GOTOFF). */
!
! if (reload_in_progress)
! regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
! new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
! new = gen_rtx_CONST (Pmode, new);
! new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
! if (reg != 0)
! {
! emit_move_insn (reg, new);
! new = reg;
! }
! }
}
else if (GET_CODE (addr) == SYMBOL_REF)
{
--- 5601,5624 ----
return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg);
#endif
! if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
! new = addr;
! else if (!TARGET_64BIT && local_symbolic_operand (addr, Pmode))
! {
! /* This symbol may be referenced via a displacement from the PIC
! base address (@GOTOFF). */
!
! if (reload_in_progress)
! regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
! new = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
! new = gen_rtx_CONST (Pmode, new);
! new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new);
! if (reg != 0)
! {
! emit_move_insn (reg, new);
! new = reg;
! }
}
else if (GET_CODE (addr) == SYMBOL_REF)
{
*************** ix86_expand_vector_move (mode, operands)
*** 7922,7935 ****
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands[0], mode)
&& CONSTANT_P (operands[1]))
! {
! rtx addr = gen_reg_rtx (Pmode);
! emit_move_insn (addr, XEXP (force_const_mem (mode, operands[1]), 0));
! operands[1] = gen_rtx_MEM (mode, addr);
! }
/* Make operand1 a register if it isn't already. */
! if ((reload_in_progress | reload_completed) == 0
&& !register_operand (operands[0], mode)
&& !register_operand (operands[1], mode))
{
--- 7908,7917 ----
if ((reload_in_progress | reload_completed) == 0
&& register_operand (operands[0], mode)
&& CONSTANT_P (operands[1]))
! operands[1] = force_const_mem (mode, operands[1]);
/* Make operand1 a register if it isn't already. */
! if (!no_new_pseudos
&& !register_operand (operands[0], mode)
&& !register_operand (operands[1], mode))
{
*************** ix86_expand_int_movcc (operands)
*** 9322,9328 ****
if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
|| diff == 3 || diff == 5 || diff == 9)
! && (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf), 0)))
{
/*
* xorl dest,dest
--- 9304,9310 ----
if ((diff == 1 || diff == 2 || diff == 4 || diff == 8
|| diff == 3 || diff == 5 || diff == 9)
! && (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf))))
{
/*
* xorl dest,dest
Index: i386.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v
retrieving revision 1.280.4.14
diff -c -3 -p -r1.280.4.14 i386.h
*** i386.h 29 Oct 2002 19:49:59 -0000 1.280.4.14
--- i386.h 29 Oct 2002 22:40:59 -0000
*************** enum reg_class
*** 1435,1441 ****
constraint, the value returned should be 0 regardless of VALUE. */
#define EXTRA_CONSTRAINT(VALUE, D) \
! ((D) == 'e' ? x86_64_sign_extended_value (VALUE, 0) \
: (D) == 'Z' ? x86_64_zero_extended_value (VALUE) \
: (D) == 'C' ? standard_sse_constant_p (VALUE) \
: 0)
--- 1435,1441 ----
constraint, the value returned should be 0 regardless of VALUE. */
#define EXTRA_CONSTRAINT(VALUE, D) \
! ((D) == 'e' ? x86_64_sign_extended_value (VALUE) \
: (D) == 'Z' ? x86_64_zero_extended_value (VALUE) \
: (D) == 'C' ? standard_sse_constant_p (VALUE) \
: 0)
*************** do { \
*** 2558,2564 ****
case CONST: \
case LABEL_REF: \
case SYMBOL_REF: \
! if (TARGET_64BIT && !x86_64_sign_extended_value (RTX, 0)) \
return 3; \
if (TARGET_64BIT && !x86_64_zero_extended_value (RTX)) \
return 2; \
--- 2558,2564 ----
case CONST: \
case LABEL_REF: \
case SYMBOL_REF: \
! if (TARGET_64BIT && !x86_64_sign_extended_value (RTX)) \
return 3; \
if (TARGET_64BIT && !x86_64_zero_extended_value (RTX)) \
return 2; \
^ permalink raw reply [flat|nested] 10+ messages in thread