ia64.c (symbolic_operand): Reject CONST expressions with the low 13 bits set.
authorRichard Henderson <rth@cygnus.com>
Sat, 1 Jul 2000 21:20:32 +0000 (14:20 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 1 Jul 2000 21:20:32 +0000 (14:20 -0700)
        * 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.

From-SVN: r34821

gcc/ChangeLog
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.md

index 35be3b2..48eef23 100644 (file)
@@ -1,3 +1,12 @@
+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.
index ca6ee29..e6dbd10 100644 (file)
@@ -186,6 +186,20 @@ symbolic_operand (op, mode)
   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;
@@ -270,7 +284,10 @@ move_operand (op, mode)
      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);
index bb9c3f3..c6bfb9f 100644 (file)
 {
   /* ??? 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"