*** empty log message ***

From-SVN: r742
This commit is contained in:
Jim Wilson 1992-04-14 10:46:57 -07:00
parent f24ec84c7b
commit a3ee589982
5 changed files with 165 additions and 101 deletions

View File

@ -1613,7 +1613,8 @@ yylex ()
else if (TREE_UNSIGNED (traditional_type)
!= TREE_UNSIGNED (ansi_type))
warning ("integer constant is unsigned in ANSI C, signed with -traditional");
else abort ();
else
warning ("width of integer constant may change on other systems with -traditional");
}
#endif

View File

@ -1048,63 +1048,53 @@ output_move_double (operands)
|| (optype0 != REGOP && optype0 != CNSTOP && optype1 == REGOP
&& (REGNO (operands[1]) & 1) == 0))
{
rtx op1, op2;
rtx base = 0, offset = const0_rtx;
rtx addr;
rtx base, offset;
/* OP1 gets the register pair, and OP2 gets the memory address. */
if (optype0 == REGOP)
op1 = operands[0], op2 = operands[1];
addr = operands[1];
else
op1 = operands[1], op2 = operands[0];
addr = operands[0];
/* Now see if we can trust the address to be 8-byte aligned. */
/* Trust double-precision floats in global variables. */
/* Now see if we can trust the address to be 8-byte aligned.
Trust double-precision floats in global variables. */
if (GET_CODE (XEXP (op2, 0)) == LO_SUM && GET_MODE (op2) == DFmode)
if (GET_CODE (XEXP (addr, 0)) == LO_SUM && GET_MODE (addr) == DFmode)
return (addr == operands[1] ? "ldd %1,%0" : "std %1,%0");
base = 0;
if (GET_CODE (XEXP (addr, 0)) == PLUS)
{
if (final_sequence)
abort ();
return (op1 == operands[0] ? "ldd %1,%0" : "std %1,%0");
}
if (GET_CODE (XEXP (op2, 0)) == PLUS)
{
rtx temp = XEXP (op2, 0);
if (GET_CODE (XEXP (temp, 0)) == REG)
rtx temp = XEXP (addr, 0);
if (GET_CODE (XEXP (temp, 0)) == REG
&& GET_CODE (XEXP (temp, 1)) == CONST_INT)
base = XEXP (temp, 0), offset = XEXP (temp, 1);
else if (GET_CODE (XEXP (temp, 1)) == REG)
base = XEXP (temp, 1), offset = XEXP (temp, 0);
}
else if (GET_CODE (XEXP (addr, 0)) == REG)
base = XEXP (addr, 0), offset = const0_rtx;
/* Trust round enough offsets from the stack or frame pointer. */
/* Trust round enough offsets from the stack or frame pointer.
If TARGET_HOPE_ALIGN, trust round enough offset from any register
for DFmode loads. If it is obviously unaligned, don't ever
generate ldd or std. */
if (base
&& (REGNO (base) == FRAME_POINTER_REGNUM
|| REGNO (base) == STACK_POINTER_REGNUM))
|| REGNO (base) == STACK_POINTER_REGNUM
|| (TARGET_HOPE_ALIGN && GET_MODE (addr) == DFmode)))
{
if (GET_CODE (offset) == CONST_INT
&& (INTVAL (offset) & 0x7) == 0)
{
if (op1 == operands[0])
return "ldd %1,%0";
else
return "std %1,%0";
}
if ((INTVAL (offset) & 0x7) == 0)
return (addr == operands[1] ? "ldd %1,%0" : "std %1,%0");
}
/* We know structs not on the stack are properly aligned. Since a
double asks for 8-byte alignment, we know it must have got that
if it is in a struct. But a DImode need not be 8-byte aligned,
because it could be a struct containing two ints or pointers. */
else if (GET_CODE (operands[1]) == MEM
&& GET_MODE (operands[1]) == DFmode
&& (CONSTANT_P (XEXP (operands[1], 0))
/* Let user ask for it anyway. */
|| TARGET_HOPE_ALIGN))
return "ldd %1,%0";
else if (GET_CODE (operands[0]) == MEM
&& GET_MODE (operands[0]) == DFmode
&& (CONSTANT_P (XEXP (operands[0], 0))
|| TARGET_HOPE_ALIGN))
return "std %1,%0";
because it could be a struct containing two ints or pointers.
Hence, a constant DFmode address will always be 8-byte aligned.
If TARGET_HOPE_ALIGN, then assume all doubles are aligned even if this
is not a constant address. */
else if (GET_CODE (addr) == MEM && GET_MODE (addr) == DFmode
&& (CONSTANT_P (addr) || TARGET_HOPE_ALIGN))
return (addr == operands[1] ? "ldd %1,%0" : "std %1,%0");
}
if (optype0 == REGOP && optype1 == REGOP
@ -1159,6 +1149,9 @@ output_move_double (operands)
return "";
}
/* Output assembler code to perform a doubleword move insn with perands
OPERANDS, one of which must be a floating point register. */
char *
output_fp_move_double (operands)
rtx *operands;
@ -1169,35 +1162,15 @@ output_fp_move_double (operands)
{
if (FP_REG_P (operands[1]))
return "fmovs %1,%0\n\tfmovs %R1,%R0";
if (GET_CODE (operands[1]) == REG)
else if (GET_CODE (operands[1]) == REG)
{
if ((REGNO (operands[1]) & 1) == 0)
return "std %1,[%@-8]\n\tldd [%@-8],%0";
else
return "st %R1,[%@-4]\n\tst %1,[%@-8]\n\tldd [%@-8],%0";
}
addr = XEXP (operands[1], 0);
/* Use ldd if known to be aligned. */
if (TARGET_HOPE_ALIGN
|| (GET_CODE (addr) == PLUS
&& (((XEXP (addr, 0) == frame_pointer_rtx
|| XEXP (addr, 0) == stack_pointer_rtx)
&& GET_CODE (XEXP (addr, 1)) == CONST_INT
&& (INTVAL (XEXP (addr, 1)) & 0x7) == 0)
/* Arrays are known to be aligned,
and reg+reg addresses are used (on this machine)
only for array accesses. */
|| (REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))))
|| (GET_MODE (operands[0]) == DFmode
&& (GET_CODE (addr) == LO_SUM || CONSTANT_P (addr))))
return "ldd %1,%0";
/* Otherwise use two ld insns. */
operands[2]
= gen_rtx (MEM, GET_MODE (operands[1]),
plus_constant_for_output (addr, 4));
return "ld %1,%0\n\tld %2,%R0";
else
return output_move_double (operands);
}
else if (FP_REG_P (operands[1]))
{
@ -1208,28 +1181,8 @@ output_fp_move_double (operands)
else
return "std %1,[%@-8]\n\tld [%@-4],%R0\n\tld [%@-8],%0";
}
addr = XEXP (operands[0], 0);
/* Use std if we can be sure it is well-aligned. */
if (TARGET_HOPE_ALIGN
|| (GET_CODE (addr) == PLUS
&& (((XEXP (addr, 0) == frame_pointer_rtx
|| XEXP (addr, 0) == stack_pointer_rtx)
&& GET_CODE (XEXP (addr, 1)) == CONST_INT
&& (INTVAL (XEXP (addr, 1)) & 0x7) == 0)
/* Arrays are known to be aligned,
and reg+reg addresses are used (on this machine)
only for array accesses. */
|| (REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))))
|| (GET_MODE (operands[1]) == DFmode
&& (GET_CODE (addr) == LO_SUM || CONSTANT_P (addr))))
return "std %1,%0";
/* Otherwise use two st insns. */
operands[2]
= gen_rtx (MEM, GET_MODE (operands[0]),
plus_constant_for_output (addr, 4));
return "st %r1,%0\n\tst %R1,%2";
else
return output_move_double (operands);
}
else abort ();
}

View File

@ -1402,6 +1402,92 @@
}"
[(set_attr "type" "fp")
(set_attr "length" "3")])
;; Allow combiner to combine a fix_truncdfsi2 with a floatsidf2
;; This eliminates 2 useless instructions.
;; The first one matches if the fixed result is needed. The second one
;; matches if the fixed result is not needed.
(define_insn ""
[(set (match_operand:DF 0 "general_operand" "=f")
(float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))
(set (match_operand:SI 2 "general_operand" "=rm")
(fix:SI (fix:DF (match_dup 1))))]
""
"*
{
if (FP_REG_P (operands[1]))
output_asm_insn (\"fdtoi %1,%0\", operands);
else
{
output_asm_insn (output_fp_move_double (operands), operands);
output_asm_insn (\"fdtoi %0,%0\", operands);
}
if (GET_CODE (operands[2]) == MEM)
return \"st %0,%2\;fitod %0,%0\";
else
return \"st %0,[%%fp-4]\;fitod %0,%0\;ld [%%fp-4],%2\";
}"
[(set_attr "type" "fp")
(set_attr "length" "5")])
(define_insn ""
[(set (match_operand:DF 0 "general_operand" "=f")
(float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))]
""
"*
{
if (FP_REG_P (operands[1]))
output_asm_insn (\"fdtoi %1,%0\", operands);
else
{
output_asm_insn (output_fp_move_double (operands), operands);
output_asm_insn (\"fdtoi %0,%0\", operands);
}
return \"fitod %0,%0\";
}"
[(set_attr "type" "fp")
(set_attr "length" "3")])
;; Allow combiner to combine a fix_truncsfsi2 with a floatsisf2
;; This eliminates 2 useless instructions.
;; The first one matches if the fixed result is needed. The second one
;; matches if the fixed result is not needed.
(define_insn ""
[(set (match_operand:SF 0 "general_operand" "=f")
(float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))
(set (match_operand:SI 2 "general_operand" "=rm")
(fix:SI (fix:SF (match_dup 1))))]
""
"*
{
if (FP_REG_P (operands[1]))
output_asm_insn (\"fstoi %1,%0\", operands);
else
output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
if (GET_CODE (operands[2]) == MEM)
return \"st %0,%2\;fitos %0,%0\";
else
return \"st %0,[%%fp-4]\;fitos %0,%0\;ld [%%fp-4],%2\";
}"
[(set_attr "type" "fp")
(set_attr "length" "5")])
(define_insn ""
[(set (match_operand:SF 0 "general_operand" "=f")
(float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))]
""
"*
{
if (FP_REG_P (operands[1]))
output_asm_insn (\"fstoi %1,%0\", operands);
else
output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
return \"fitos %0,%0\";
}"
[(set_attr "type" "fp")
(set_attr "length" "3")])
;;- arithmetic instructions

View File

@ -383,21 +383,39 @@ add_dependence (insn, elem, dep_type)
rtx elem;
enum reg_note dep_type;
{
rtx link;
rtx link, next;
/* Don't depend an insn on itself. */
if (insn == elem)
return;
/* If elem is part of a sequence that must be scheduled together, then
make the dependence point to the last insn of the sequence. */
if (NEXT_INSN (elem) && SCHED_GROUP_P (NEXT_INSN (elem)))
make the dependence point to the last insn of the sequence.
When HAVE_cc0, it is possible for NOTEs to exist between users and
setters of the condition codes, so we must skip past notes here.
Otherwise, NOTEs are impossible here. */
next = NEXT_INSN (elem);
#ifdef HAVE_cc0
while (next && GET_CODE (next) == NOTE)
next = NEXT_INSN (next);
#endif
if (next && SCHED_GROUP_P (next))
{
while (NEXT_INSN (elem) && SCHED_GROUP_P (NEXT_INSN (elem)))
elem = NEXT_INSN (elem);
/* Again, don't depend an insn of itself. */
if (insn == elem)
/* Notes will never intervene here though, so don't bother checking
for them. */
while (next && SCHED_GROUP_P (next))
next = NEXT_INSN (next);
/* Again, don't depend an insn on itself. */
if (insn == next)
return;
/* Make the dependence to NEXT, the last insn of the group, instead
of the original ELEM. */
elem = next;
}
/* Check that we don't already have this dependence. */

View File

@ -1214,18 +1214,24 @@ sched_analyze_2 (x, insn)
#ifdef HAVE_cc0
case CC0:
{
rtx link;
rtx link, prev;
/* There may be a note before this insn now, but all notes will
be removed before we actually try to schedule the insns, so
it won't cause a problem later. We must avoid it here though. */
/* User of CC0 depends on immediately preceding insn.
There may be a note before this insn now, but all notes will
be removed before we actually try to schedule the insns, so
it doesn't matter. */
SCHED_GROUP_P (insn) = 1;
/* Make a copy of all dependencies on PREV_INSN, and add to this insn.
This is so that all the dependencies will apply to the group. */
/* Make a copy of all dependencies on the immediately previous insn,
and add to this insn. This is so that all the dependencies will
apply to the group. */
for (link = LOG_LINKS (PREV_INSN (insn)); link; link = XEXP (link, 1))
prev = PREV_INSN (insn);
while (GET_CODE (prev) == NOTE)
prev = PREV_INSN (prev);
for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
add_dependence (insn, XEXP (link, 0), GET_MODE (link));
return;