mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-21 19:09:56 +08:00
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:
parent
5dc6aef5d4
commit
9b7bf67dad
@ -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>
|
||||
|
||||
|
@ -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" "")))
|
||||
|
Loading…
Reference in New Issue
Block a user