Commit 7a525da6 authored by rth's avatar rth
Browse files

* 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.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35106 138bc75d-0d04-0410-961f-82ee72b054a4
parent eda58c9c
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>
 
......
......@@ -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,
......
......@@ -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);
}
......
......@@ -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" "")))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment