[3.4-BIB] updated patch for x86_64 PIC
Jan Hubicka
jh@suse.cz
Mon Nov 11 14:37:00 GMT 2002
Hi,
this is updated patch I sent some time ago with some changes suggested
by Jakub. It's purpose is to make the whole code more consistent so it
will be easier to understand I hope and it produces better code in some
side cases.
Honza
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/egcs/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 11 Nov 2002 22:31:09 -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/egcs/gcc/config/i386/i386.c,v
retrieving revision 1.447.2.23
diff -c -3 -p -r1.447.2.23 i386.c
*** i386.c 8 Nov 2002 23:14:28 -0000 1.447.2.23
--- i386.c 11 Nov 2002 22:31:17 -0000
*************** x86_64_general_operand (op, mode)
*** 2968,2974 ****
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
--- 2968,2974 ----
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)
*** 2983,2989 ****
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. */
--- 2983,2989 ----
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)
*** 2997,3003 ****
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. */
--- 2997,3003 ----
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)
*** 3009,3015 ****
{
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;
--- 3009,3015 ----
{
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
*** 3027,3033 ****
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. */
--- 3027,3033 ----
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)
*** 3039,3045 ****
{
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. */
--- 3039,3045 ----
{
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)
*** 3159,3168 ****
{
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)
--- 3159,3165 ----
{
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 ()
*** 3964,3972 ****
/* 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))
{
--- 3961,3968 ----
/* 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
*** 3988,4004 ****
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. */
--- 3984,3995 ----
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_SMALL || ix86_cmodel == CM_MEDIUM
! || ix86_cmodel == CM_KERNEL);
/* We also may accept the offsetted memory references in certain special
cases. */
*************** x86_64_sign_extended_value (value, allow
*** 4044,4069 ****
&& 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;
--- 4035,4045 ----
&& 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)
*** 5273,5280 ****
/* 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);
--- 5249,5278 ----
/* 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
*** 5481,5503 ****
{
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))
--- 5479,5484 ----
*************** legitimate_address_p (mode, addr, strict
*** 5575,5580 ****
--- 5556,5571 ----
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)
*** 5636,5663 ****
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)
{
--- 5627,5650 ----
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_int_movcc (operands)
*** 9343,9349 ****
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
--- 9330,9336 ----
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/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.280.4.16
diff -c -3 -p -r1.280.4.16 i386.h
*** i386.h 7 Nov 2002 01:18:00 -0000 1.280.4.16
--- i386.h 11 Nov 2002 22:31:20 -0000
*************** enum reg_class
*** 1442,1448 ****
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)
--- 1442,1448 ----
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 { \
*** 2565,2571 ****
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; \
--- 2565,2571 ----
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; \
More information about the Gcc-patches
mailing list