ia64.md (movdi): Split out load address code.
authorRichard Henderson <rth@gcc.gnu.org>
Mon, 17 Jul 2000 22:19:58 +0000 (15:19 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 17 Jul 2000 22:19:58 +0000 (15:19 -0700)
        * config/ia64/ia64.md (movdi): Split out load address code.
        New post-reload splitter for symbolic operands.
        (movdi_internal): Abort if we didn't split symbolic operands
        when we should have.
        * config/ia64/ia64.c (ia64_expand_load_address): New, from movdi bits.
        (ia64_reorg): Split insns when not optimizing.
        * config/ia64/ia64-protos.h (ia64_expand_load_address): Declare.

From-SVN: r35106

gcc/ChangeLog
gcc/config/ia64/ia64-protos.h
gcc/config/ia64/ia64.c
gcc/config/ia64/ia64.md

index 9ba275175388bb404c1200c795051dcc8ce3fa96..1cca26365fb7db23af0da887152b081d7add30aa 100644 (file)
@@ -1,3 +1,13 @@
+2000-07-17  Richard Henderson  <rth@cygnus.com>
+
+       * config/ia64/ia64.md (movdi): Split out load address code.
+       New post-reload splitter for symbolic operands.
+       (movdi_internal): Abort if we didn't split symbolic operands
+       when we should have.
+       * config/ia64/ia64.c (ia64_expand_load_address): New, from movdi bits.
+       (ia64_reorg): Split insns when not optimizing.
+       * config/ia64/ia64-protos.h (ia64_expand_load_address): Declare.
+
 Mon Jul 17 23:43:26 MET DST 2000  Jan Hubicka  <jh@suse.cz>
 
        * real.h (REAL_VALUE_TO_TARGET_LONG_DOUBLE): Use LONG_DOUBLE_TYPE_SIZE
@@ -39,7 +49,7 @@ Mon Jul 17 08:26:35 2000  Clinton Popetz  <cpopetz@cygnus.com>
 
 2000-07-17  Mark Klein <mklein@dis.com>
 
-         * pa.c (emit_hpdiv_const): Update to match new pattern for udivsi3.
+        * pa.c (emit_hpdiv_const): Update to match new pattern for udivsi3.
 
 2000-07-17  J. David Anglin  <dave@hiauly1.hia.nrc.ca>
 
index e918420aa3fcbdd86ad3df979f4b03bfe99a2666..8949c1dfac9f7eb69a64ed8e6f1c23d312f235d5 100644 (file)
@@ -52,6 +52,7 @@ extern int call_multiple_values_operation PARAMS((rtx, enum machine_mode));
 extern int predicate_operator PARAMS((rtx, enum machine_mode));
 extern int ia64_move_ok PARAMS((rtx, rtx));
 
+extern void ia64_expand_load_address PARAMS((rtx, rtx));
 extern void ia64_expand_fetch_and_op PARAMS ((enum fetchop_code,
                                              enum machine_mode, rtx []));
 extern void ia64_expand_op_and_fetch PARAMS ((enum fetchop_code,
index c88f1a94753466be6bcf9d90f48fc6fa524ee293..a87d25661c623b9b2d7c9e3b6be3455b55d7f76b 100644 (file)
@@ -542,7 +542,7 @@ predicate_operator (op, mode)
   return ((GET_MODE (op) == mode || mode == VOIDmode)
          && (code == EQ || code == NE));
 }
-
+\f
 /* Return 1 if the operands of a move are ok.  */
 
 int
@@ -566,6 +566,53 @@ ia64_move_ok (dst, src)
   else
     return GET_CODE (src) == CONST_DOUBLE && CONST_DOUBLE_OK_FOR_G (src);
 }
+
+/* Expand a symbolic constant load.  */
+/* ??? Should generalize this, so that we can also support 32 bit pointers.  */
+
+void
+ia64_expand_load_address (dest, src)
+      rtx dest, src;
+{
+  rtx temp;
+
+  /* The destination could be a MEM during initial rtl generation,
+     which isn't a valid destination for the PIC load address patterns.  */
+  if (! register_operand (dest, DImode))
+    temp = gen_reg_rtx (DImode);
+  else
+    temp = dest;
+
+  if (TARGET_AUTO_PIC)
+    emit_insn (gen_load_gprel64 (temp, src));
+  else if (GET_CODE (src) == SYMBOL_REF && SYMBOL_REF_FLAG (src))
+    emit_insn (gen_load_fptr (temp, src));
+  else if (sdata_symbolic_operand (src, DImode))
+    emit_insn (gen_load_gprel (temp, src));
+  else if (GET_CODE (src) == CONST
+          && GET_CODE (XEXP (src, 0)) == PLUS
+          && GET_CODE (XEXP (XEXP (src, 0), 1)) == CONST_INT
+          && (INTVAL (XEXP (XEXP (src, 0), 1)) & 0x1fff) != 0)
+    {
+      rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
+      rtx sym = XEXP (XEXP (src, 0), 0);
+      HOST_WIDE_INT ofs, hi, lo;
+
+      /* Split the offset into a sign extended 14-bit low part
+        and a complementary high part.  */
+      ofs = INTVAL (XEXP (XEXP (src, 0), 1));
+      lo = ((ofs & 0x3fff) ^ 0x2000) - 0x2000;
+      hi = ofs - lo;
+
+      emit_insn (gen_load_symptr (subtarget, plus_constant (sym, hi)));
+      emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
+    }
+  else
+    emit_insn (gen_load_symptr (temp, src));
+
+  if (temp != dest)
+    emit_move_insn (dest, temp);
+}
 \f
 /* Begin the assembly file.  */
 
@@ -3016,6 +3063,10 @@ void
 ia64_reorg (insns)
      rtx insns;
 {
+  /* If optimizing, we'll have split before scheduling.  */
+  if (optimize == 0)
+    split_all_insns (0);
+
   emit_predicate_relation_info (insns);
   emit_insn_group_barriers (insns);
 }
index 9c90de16e8b2aae039a380e4650e6afe578c01a2..1e5253b201921e3d0ec8851aa5df6b102b79c2aa 100644 (file)
   ""
   "
 {
-  /* ??? Should generalize this, so that we can also support 32 bit
-     pointers.  */
   if (! TARGET_NO_PIC && symbolic_operand (operands[1], DImode))
     {
-      rtx temp;
-
-      /* Operand[0] could be a MEM, which isn't a valid destination for the
-        PIC load address patterns.  */
-      if (! register_operand (operands[0], DImode))
-       temp = gen_reg_rtx (DImode);
-      else
-       temp = operands[0];
-
-      if (TARGET_AUTO_PIC)
-       emit_insn (gen_load_gprel64 (temp, operands[1]));
-      else if (GET_CODE (operands[1]) == SYMBOL_REF
-              && SYMBOL_REF_FLAG (operands[1]))
-       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)
-       {
-         rtx subtarget = no_new_pseudos ? temp : gen_reg_rtx (DImode);
-         rtx sym = XEXP (XEXP (operands[1], 0), 0);
-         HOST_WIDE_INT ofs, hi, lo;
-
-         /* Split the offset into a sign extended 14-bit low part
-            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, plus_constant (sym, hi)));
-         emit_insn (gen_adddi3 (temp, subtarget, GEN_INT (lo)));
-       }
-      else
-       emit_insn (gen_load_symptr (temp, operands[1]));
-
-      if (temp == operands[0])
-       DONE;
-
-      operands[1] = temp;
+      ia64_expand_load_address (operands[0], operands[1]);
+      DONE;
     }
-
   if (! reload_in_progress && ! reload_completed
       && ! ia64_move_ok (operands[0], operands[1]))
     operands[1] = force_reg (DImode, operands[1]);
   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r, m,r,*f,*f,*f,Q, r,*b")
        (match_operand:DI 1 "move_operand"         "rO,J,i,m,rO,*f,rO,*f,Q,*f,*b,rO"))]
   "ia64_move_ok (operands[0], operands[1])"
-  "@
-  mov %0 = %r1
-  addl %0 = %1, r0
-  movl %0 = %1
-  ld8%O1 %0 = %1%P1
-  st8%Q0 %0 = %r1%P0
-  getf.sig %0 = %1
-  setf.sig %0 = %r1
-  mov %0 = %1
-  ldf8 %0 = %1%P1
-  stf8 %0 = %1%P0
-  mov %0 = %1
-  mov %0 = %r1"
+  "*
+{
+  static const char * const alt[] = {
+    \"mov %0 = %r1\",
+    \"addl %0 = %1, r0\",
+    \"movl %0 = %1\",
+    \"ld8%O1 %0 = %1%P1\",
+    \"st8%Q0 %0 = %r1%P0\",
+    \"getf.sig %0 = %1\",
+    \"setf.sig %0 = %r1\",
+    \"mov %0 = %1\",
+    \"ldf8 %0 = %1%P1\",
+    \"stf8 %0 = %1%P0\",
+    \"mov %0 = %1\",
+    \"mov %0 = %r1\"
+  };
+
+  /* We use 'i' for alternative 2 despite possible PIC problems.
+
+     If we define LEGITIMATE_CONSTANT_P such that symbols are not
+     allowed, then the compiler dumps the data into constant memory
+     instead of letting us read the values from the GOT.  Similarly
+     if we use 'n' instead of 'i'.
+
+     Instead, we allow such insns through reload and then split them
+     afterward (even without optimization).  Therefore, we should
+     never get so far with a symbolic operand.  */
+
+  if (which_alternative == 2 && ! TARGET_NO_PIC
+      && symbolic_operand (operands[1], VOIDmode))
+    abort ();
+
+  return alt[which_alternative];
+}"
   [(set_attr "type" "A,A,L,M,M,M,M,F,M,M,I,I")])
 
+(define_split
+  [(set (match_operand:DI 0 "register_operand" "")
+       (match_operand:DI 1 "symbolic_operand" ""))]
+  "reload_completed && ! TARGET_NO_PIC"
+  [(const_int 0)]
+  "
+{
+  ia64_expand_load_address (operands[0], operands[1]);
+  DONE;
+}")
+
 (define_expand "load_fptr"
   [(set (match_dup 2)
        (plus:DI (reg:DI 1) (match_operand:DI 1 "function_operand" "")))