aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2000-07-17 15:19:58 -0700
committerRichard Henderson <rth@gcc.gnu.org>2000-07-17 15:19:58 -0700
commit9b7bf67dadd9a23364c784de2c64be87d1819b67 (patch)
tree84a0d95bd1cb6c54a3aefe6a2cc6016d9bc3b4ce /gcc
parent5dc6aef5d443eae0800271a357d9a03c3b75bc15 (diff)
downloadgcc-9b7bf67dadd9a23364c784de2c64be87d1819b67.zip
gcc-9b7bf67dadd9a23364c784de2c64be87d1819b67.tar.gz
gcc-9b7bf67dadd9a23364c784de2c64be87d1819b67.tar.bz2
ia64.md (movdi): Split out load address code.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/ia64/ia64-protos.h1
-rw-r--r--gcc/config/ia64/ia64.c53
-rw-r--r--gcc/config/ia64/ia64.md104
4 files changed, 111 insertions, 59 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9ba2751..1cca263 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h
index e918420..8949c1d 100644
--- a/gcc/config/ia64/ia64-protos.h
+++ b/gcc/config/ia64/ia64-protos.h
@@ -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,
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index c88f1a9..a87d256 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -542,7 +542,7 @@ predicate_operator (op, mode)
return ((GET_MODE (op) == mode || mode == VOIDmode)
&& (code == EQ || code == NE));
}
-
+
/* 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);
+}
/* 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);
}
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md
index 9c90de1..1e5253b 100644
--- a/gcc/config/ia64/ia64.md
+++ b/gcc/config/ia64/ia64.md
@@ -247,53 +247,11 @@
""
"
{
- /* ??? 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]);
@@ -303,21 +261,53 @@
[(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" "")))