+2000-07-01 Richard Henderson <rth@cygnus.com>
+
+ * config/ia64/ia64.c (symbolic_operand): Reject CONST expressions
+ with the low 13 bits set.
+ (move_operand): Check for CONST|SYMBOL_REF|LABEL_REF directly.
+ * config/ia64/ia64.md (movdi): Likewise. Expand a CONST with one
+ of the low 13 bits into a CONST plus an adddi3.
+ (load_symptr): Set RTX_UNCHANGING_P.
+
2000-06-30 Mark Mitchell <mark@codesourcery.com>
* Makefile.in (c-common.o): Don't depend on c-tree.h or c-lex.h.
switch (GET_CODE (op))
{
case CONST:
+ op = XEXP (op, 0);
+ if (GET_CODE (op) != PLUS)
+ return 0;
+ if (GET_CODE (XEXP (op, 0)) != SYMBOL_REF)
+ return 0;
+ op = XEXP (op, 1);
+ if (GET_CODE (op) != CONST_INT)
+ return 0;
+ /* Force the low 13 bits of the constant to zero so that we do not
+ use up so many GOT entries. */
+ if (! TARGET_NO_PIC && ! TARGET_AUTO_PIC && (INTVAL (op) & 0x1fff) != 0)
+ return 0;
+ return 1;
+
case SYMBOL_REF:
case LABEL_REF:
return 1;
rtx op;
enum machine_mode mode;
{
- if (! TARGET_NO_PIC && symbolic_operand (op, mode))
+ if (! TARGET_NO_PIC
+ && (GET_CODE (op) == CONST
+ || GET_CODE (op) == SYMBOL_REF
+ || GET_CODE (op) == LABEL_REF))
return 0;
return general_operand (op, mode);
{
/* ??? Should generalize this, so that we can also support 32 bit
pointers. */
- if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
+ if (! TARGET_NO_PIC
+ && (GET_CODE (operands[1]) == CONST
+ || GET_CODE (operands[1]) == SYMBOL_REF
+ || GET_CODE (operands[1]) == LABEL_REF))
{
rtx temp;
emit_insn (gen_load_fptr (temp, operands[1]));
else if (sdata_symbolic_operand (operands[1], DImode))
emit_insn (gen_load_gprel (temp, operands[1]));
+ else if (GET_CODE (operands[1]) == CONST
+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT
+ && (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);
+
+ sym = plus_constant (sym, ofs & ~(HOST_WIDE_INT)0x1fff);
+ ofs &= 0x1fff;
+
+ emit_insn (gen_load_symptr (subtarget, sym));
+ emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (ofs)));
+ }
else
emit_insn (gen_load_symptr (temp, operands[1]));
(define_expand "load_symptr"
[(set (match_dup 2)
(plus:DI (reg:DI 1) (match_operand:DI 1 "symbolic_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] = operands[0];
- else
- operands[2] = gen_reg_rtx (DImode);
+ operands[2] = reload_in_progress ? operands[0] : gen_reg_rtx (DImode);
+ operands[3] = gen_rtx_MEM (DImode, operands[2]);
+ RTX_UNCHANGING_P (operands[3]) = 1;
}")
(define_insn "*load_symptr_internal1"