Commit ec039e3c by Richard Henderson

ia64.c (got_symbolic_operand): New.

        * config/ia64/ia64.c (got_symbolic_operand): New.
        (symbolic_operand, move_operand): Revert 0701 change.
        * config/ia64/ia64.h (PREDICATE_CODES): Update.
        * config/ia64/ia64-protos.h (got_symbolic_operand): Declare.
        * config/ia64/ia64.md (movdi): Revert 0701 wrt symbolic_operand;
        split the offset into a 14-bit low part instead of a 13-bit low part.
        (load_fptr): Mark the mem as unchanging.
        (load_symptr): Use got_symbolic_operand.

From-SVN: r34948
parent 14e7eabd
2000-07-10 Richard Henderson <rth@cygnus.com>
* config/ia64/ia64.c (got_symbolic_operand): New.
(symbolic_operand, move_operand): Revert 0701 change.
* config/ia64/ia64.h (PREDICATE_CODES): Update.
* config/ia64/ia64-protos.h (got_symbolic_operand): Declare.
* config/ia64/ia64.md (movdi): Revert 0701 wrt symbolic_operand;
split the offset into a 14-bit low part instead of a 13-bit low part.
(load_fptr): Mark the mem as unchanging.
(load_symptr): Use got_symbolic_operand.
2000-07-10 Nick Clifton <nickc@cygnus.com> 2000-07-10 Nick Clifton <nickc@cygnus.com>
* libgcc2.c (next_stack_level): Cast result of computation to * libgcc2.c (next_stack_level): Cast result of computation to
......
...@@ -29,6 +29,7 @@ extern rtx ia64_compare_op0, ia64_compare_op1; ...@@ -29,6 +29,7 @@ extern rtx ia64_compare_op0, ia64_compare_op1;
#ifdef RTX_CODE #ifdef RTX_CODE
extern int call_operand PARAMS((rtx, enum machine_mode)); extern int call_operand PARAMS((rtx, enum machine_mode));
extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode)); extern int sdata_symbolic_operand PARAMS((rtx, enum machine_mode));
extern int got_symbolic_operand PARAMS((rtx, enum machine_mode));
extern int symbolic_operand PARAMS((rtx, enum machine_mode)); extern int symbolic_operand PARAMS((rtx, enum machine_mode));
extern int function_operand PARAMS((rtx, enum machine_mode)); extern int function_operand PARAMS((rtx, enum machine_mode));
extern int setjmp_operand PARAMS((rtx, enum machine_mode)); extern int setjmp_operand PARAMS((rtx, enum machine_mode));
......
...@@ -176,10 +176,10 @@ sdata_symbolic_operand (op, mode) ...@@ -176,10 +176,10 @@ sdata_symbolic_operand (op, mode)
return 0; return 0;
} }
/* Return 1 if OP refers to a symbol. */ /* Return 1 if OP refers to a symbol, and is appropriate for a GOT load. */
int int
symbolic_operand (op, mode) got_symbolic_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED; enum machine_mode mode ATTRIBUTE_UNUSED;
{ {
...@@ -194,12 +194,43 @@ symbolic_operand (op, mode) ...@@ -194,12 +194,43 @@ symbolic_operand (op, mode)
op = XEXP (op, 1); op = XEXP (op, 1);
if (GET_CODE (op) != CONST_INT) if (GET_CODE (op) != CONST_INT)
return 0; return 0;
/* Force the low 13 bits of the constant to zero so that we do not
return 1;
/* Ok if we're not using GOT entries at all. */
if (TARGET_NO_PIC || TARGET_AUTO_PIC)
return 1;
/* "Ok" while emitting rtl, since otherwise we won't be provided
with the entire offset during emission, which makes it very
hard to split the offset into high and low parts. */
if (rtx_equal_function_value_matters)
return 1;
/* Force the low 14 bits of the constant to zero so that we do not
use up so many GOT entries. */ use up so many GOT entries. */
if (! TARGET_NO_PIC && ! TARGET_AUTO_PIC && (INTVAL (op) & 0x1fff) != 0) return (INTVAL (op) & 0x3fff) == 0;
return 0;
case SYMBOL_REF:
case LABEL_REF:
return 1; return 1;
default:
break;
}
return 0;
}
/* Return 1 if OP refers to a symbol. */
int
symbolic_operand (op, mode)
rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
switch (GET_CODE (op))
{
case CONST:
case SYMBOL_REF: case SYMBOL_REF:
case LABEL_REF: case LABEL_REF:
return 1; return 1;
...@@ -284,10 +315,7 @@ move_operand (op, mode) ...@@ -284,10 +315,7 @@ move_operand (op, mode)
rtx op; rtx op;
enum machine_mode mode; enum machine_mode mode;
{ {
if (! TARGET_NO_PIC if (! TARGET_NO_PIC && symbolic_operand (op, mode))
&& (GET_CODE (op) == CONST
|| GET_CODE (op) == SYMBOL_REF
|| GET_CODE (op) == LABEL_REF))
return 0; return 0;
return general_operand (op, mode); return general_operand (op, mode);
......
...@@ -2705,6 +2705,7 @@ do { \ ...@@ -2705,6 +2705,7 @@ do { \
#define PREDICATE_CODES \ #define PREDICATE_CODES \
{ "call_operand", {SUBREG, REG, SYMBOL_REF}}, \ { "call_operand", {SUBREG, REG, SYMBOL_REF}}, \
{ "got_symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "sdata_symbolic_operand", {SYMBOL_REF, CONST}}, \ { "sdata_symbolic_operand", {SYMBOL_REF, CONST}}, \
{ "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \ { "symbolic_operand", {SYMBOL_REF, CONST, LABEL_REF}}, \
{ "function_operand", {SYMBOL_REF}}, \ { "function_operand", {SYMBOL_REF}}, \
......
...@@ -255,10 +255,7 @@ ...@@ -255,10 +255,7 @@
{ {
/* ??? Should generalize this, so that we can also support 32 bit /* ??? Should generalize this, so that we can also support 32 bit
pointers. */ pointers. */
if (! TARGET_NO_PIC if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
&& (GET_CODE (operands[1]) == CONST
|| GET_CODE (operands[1]) == SYMBOL_REF
|| GET_CODE (operands[1]) == LABEL_REF))
{ {
rtx temp; rtx temp;
...@@ -281,15 +278,18 @@ ...@@ -281,15 +278,18 @@
&& GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT
&& (INTVAL (XEXP (XEXP (operands[1], 0), 1)) & 0x1fff) != 0) && (INTVAL (XEXP (XEXP (operands[1], 0), 1)) & 0x1fff) != 0)
{ {
HOST_WIDE_INT ofs = INTVAL (XEXP (XEXP (operands[1], 0), 1));
rtx sym = XEXP (XEXP (operands[1], 0), 0);
rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode); rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
rtx sym = XEXP (XEXP (operands[1], 0), 0);
HOST_WIDE_INT ofs, hi, lo;
sym = plus_constant (sym, ofs & ~(HOST_WIDE_INT)0x1fff); /* Split the offset into a sign extended 14-bit low part
ofs &= 0x1fff; and a complementary high part. */
ofs = INTVAL (XEXP (XEXP (operands[1], 0), 1));
lo = ((ofs & 0x3fff) ^ 0x2000) - 0x2000;
hi = ofs - lo;
emit_insn (gen_load_symptr (subtarget, sym)); emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi)));
emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (ofs))); emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
} }
else else
emit_insn (gen_load_symptr (temp, operands[1])); emit_insn (gen_load_symptr (temp, operands[1]));
...@@ -329,14 +329,13 @@ ...@@ -329,14 +329,13 @@
(define_expand "load_fptr" (define_expand "load_fptr"
[(set (match_dup 2) [(set (match_dup 2)
(plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" ""))) (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))
(set (match_operand:DI 0 "register_operand" "") (mem:DI (match_dup 2)))] (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
"" ""
" "
{ {
if (reload_in_progress) operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
operands[2] = operands[0]; operands[3] = gen_rtx_MEM (DImode, operands[2]);
else RTX_UNCHANGING_P (operands[3]) = 1;
operands[2] = gen_reg_rtx (DImode);
}") }")
(define_insn "*load_fptr_internal1" (define_insn "*load_fptr_internal1"
...@@ -366,28 +365,26 @@ ...@@ -366,28 +365,26 @@
(set (match_operand:DI 0 "register_operand" "") (set (match_operand:DI 0 "register_operand" "")
(plus:DI (reg:DI 1) (match_dup 2)))] (plus:DI (reg:DI 1) (match_dup 2)))]
"" ""
"{ "
if (reload_in_progress) {
operands[2] = operands[0]; operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
else
operands[2] = gen_reg_rtx (DImode);
}") }")
(define_expand "load_symptr" (define_expand "load_symptr"
[(set (match_dup 2) [(set (match_dup 2)
(plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" ""))) (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "")))
(set (match_operand:DI 0 "register_operand" "") (match_dup 3))] (set (match_operand:DI 0 "register_operand" "") (match_dup 3))]
"" ""
" "
{ {
operands[2] = reload_in_progress ? operands[0] : gen_reg_rtx (DImode); operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (DImode);
operands[3] = gen_rtx_MEM (DImode, operands[2]); operands[3] = gen_rtx_MEM (DImode, operands[2]);
RTX_UNCHANGING_P (operands[3]) = 1; RTX_UNCHANGING_P (operands[3]) = 1;
}") }")
(define_insn "*load_symptr_internal1" (define_insn "*load_symptr_internal1"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
(plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_operand" "s")))] (plus:DI (reg:DI 1) (match_operand:DI 1 "got_symbolic_operand" "s")))]
"" ""
"addl %0 = @ltoff(%1), gp" "addl %0 = @ltoff(%1), gp"
[(set_attr "type" "A")]) [(set_attr "type" "A")])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment