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
This commit is contained in:
Richard Henderson 2000-07-17 15:19:58 -07:00
parent 5dc6aef5d4
commit 9b7bf67dad
4 changed files with 111 additions and 59 deletions

View 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>

View 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,

View File

@ -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);
}

View File

@ -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" "")))