diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-11-21 22:54:20 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-11-21 22:54:20 +0000 |
commit | a73600cc276da2976565f9a67ac52a8fa13174b7 (patch) | |
tree | c6e181d870a0f2ad32f56e87c4132dcad5a9e601 /gcc/config/i386 | |
parent | 790088f319969f84937d5904c4cdd461d45ce77d (diff) | |
download | gcc-a73600cc276da2976565f9a67ac52a8fa13174b7.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@59362 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i386')
-rw-r--r-- | gcc/config/i386/i386-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 137 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 4 |
3 files changed, 65 insertions, 78 deletions
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index a5940140937..4afdf668bd8 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -153,7 +153,7 @@ extern int ix86_attr_length_address_default PARAMS ((rtx)); 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_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)); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 0ccb62c3213..e379c4aa85f 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2894,7 +2894,7 @@ x86_64_general_operand (op, mode) return general_operand (op, mode); if (nonimmediate_operand (op, mode)) return 1; - return x86_64_sign_extended_value (op, 1); + return x86_64_sign_extended_value (op); } /* Return nonzero if OP is general operand representable on x86_64 @@ -2909,7 +2909,7 @@ x86_64_szext_general_operand (op, mode) 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 x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op); } /* Return nonzero if OP is nonmemory operand representable on x86_64. */ @@ -2923,7 +2923,7 @@ x86_64_nonmemory_operand (op, mode) return nonmemory_operand (op, mode); if (register_operand (op, mode)) return 1; - return x86_64_sign_extended_value (op, 1); + return x86_64_sign_extended_value (op); } /* Return nonzero if OP is nonmemory operand acceptable by movabs patterns. */ @@ -2935,7 +2935,7 @@ x86_64_movabs_operand (op, mode) { if (!TARGET_64BIT || !flag_pic) return nonmemory_operand (op, mode); - if (register_operand (op, mode) || x86_64_sign_extended_value (op, 0)) + if (register_operand (op, mode) || x86_64_sign_extended_value (op)) return 1; if (CONSTANT_P (op) && !symbolic_reference_mentioned_p (op)) return 1; @@ -2953,7 +2953,7 @@ x86_64_szext_nonmemory_operand (op, mode) 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 x86_64_sign_extended_value (op) || x86_64_zero_extended_value (op); } /* Return nonzero if OP is immediate operand representable on x86_64. */ @@ -2965,7 +2965,7 @@ x86_64_immediate_operand (op, mode) { if (!TARGET_64BIT) return immediate_operand (op, mode); - return x86_64_sign_extended_value (op, 0); + return x86_64_sign_extended_value (op); } /* Return nonzero if OP is immediate operand representable on x86_64. */ @@ -3085,10 +3085,7 @@ local_symbolic_operand (op, mode) { 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))) + && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT) op = XEXP (XEXP (op, 0), 0); if (GET_CODE (op) == LABEL_REF) @@ -3839,9 +3836,8 @@ ix86_can_use_return_insn_p () /* Return 1 if VALUE can be stored in the sign extended immediate field. */ int -x86_64_sign_extended_value (value, allow_rip) +x86_64_sign_extended_value (value) rtx value; - int allow_rip; { switch (GET_CODE (value)) { @@ -3863,17 +3859,12 @@ x86_64_sign_extended_value (value, allow_rip) 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)))); + 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 - && (allow_rip || ix86_cmodel != CM_SMALL_PIC); + 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. */ @@ -3919,26 +3910,11 @@ x86_64_sign_extended_value (value, allow_rip) && 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)) + if ((ix86_cmodel == CM_SMALL || ix86_cmodel == CM_MEDIUM) && offset < 16*1024*1024 && trunc_int_for_mode (offset, SImode) == offset) return 1; @@ -5148,8 +5124,30 @@ legitimate_pic_address_disp_p (disp) /* 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 (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); @@ -5356,23 +5354,6 @@ legitimate_address_p (mode, addr, strict) { 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)) @@ -5450,6 +5431,16 @@ legitimate_address_p (mode, addr, strict) 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. */ @@ -5511,28 +5502,24 @@ legitimize_pic_address (orig, reg) return machopic_legitimize_pic_address (orig, GET_MODE (orig), reg); #endif - if (local_symbolic_operand (addr, Pmode)) + if (TARGET_64BIT && legitimate_pic_address_disp_p (addr)) + new = addr; + else if (!TARGET_64BIT && 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). */ + /* 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 (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; - } - } + if (reg != 0) + { + emit_move_insn (reg, new); + new = reg; + } } else if (GET_CODE (addr) == SYMBOL_REF) { @@ -9218,7 +9205,7 @@ ix86_expand_int_movcc (operands) 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))) + && (mode != DImode || x86_64_sign_extended_value (GEN_INT (cf)))) { /* * xorl dest,dest diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index ceba0b627ec..373e3373b64 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -1430,7 +1430,7 @@ enum reg_class 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) == 'e' ? x86_64_sign_extended_value (VALUE) \ : (D) == 'Z' ? x86_64_zero_extended_value (VALUE) \ : (D) == 'C' ? standard_sse_constant_p (VALUE) \ : 0) @@ -2566,7 +2566,7 @@ do { \ case CONST: \ case LABEL_REF: \ case SYMBOL_REF: \ - if (TARGET_64BIT && !x86_64_sign_extended_value (RTX, 0)) \ + if (TARGET_64BIT && !x86_64_sign_extended_value (RTX)) \ return 3; \ if (TARGET_64BIT && !x86_64_zero_extended_value (RTX)) \ return 2; \ |