summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorwehle <wehle@138bc75d-0d04-0410-961f-82ee72b054a4>1999-04-25 11:43:49 +0000
committerwehle <wehle@138bc75d-0d04-0410-961f-82ee72b054a4>1999-04-25 11:43:49 +0000
commitaae163e1020becf456dafd42e6995a3ec1203cec (patch)
tree7ca441f8bb80a8971078183607b030c4dd82e538 /gcc/config
parenta6af95fb35a4f613476d2ae14f070f0a4c5613bd (diff)
downloadgcc-aae163e1020becf456dafd42e6995a3ec1203cec.tar.gz
* stupid.c (stupid_mark_refs): Generate a REG_UNUSED note
for a register which is clobbered even if the register was used by an earlier instruction. * i386.md (fix_truncsfdi2, fix_truncdfdi2, fix_truncxfdi2): Don't bother with the gen_reg_RTX. (fix_truncsfsi2, fix_truncsfdi2, fix_truncdfsi2, fix_truncdfdi2, fix_truncxfsi2, fix_truncxfdi2): Update operand constraints and modes. * i386.c (output_fix_trunc): Use HImode register to avoid memory stalls. Call output_move_double instead of output_to_reg. (output_to_reg): Remove. * i386.h: Likewise. * i386.md (negsf2, negdf2, negxf2): Set the type attribute to fpop. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26621 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.c148
-rw-r--r--gcc/config/i386/i386.h1
-rw-r--r--gcc/config/i386/i386.md233
3 files changed, 148 insertions, 234 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a63718e97b9..e3c2f02d3f2 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -871,102 +871,6 @@ function_arg_partial_nregs (cum, mode, type, named)
return 0;
}
-/* Output an insn to pop an value from the 387 top-of-stack to 386
- register DEST. The 387 register stack is popped if DIES is true. If
- the mode of DEST is an integer mode, a `fist' integer store is done,
- otherwise a `fst' float store is done. */
-
-void
-output_to_reg (dest, dies, scratch_mem)
- rtx dest;
- int dies;
- rtx scratch_mem;
-{
- rtx xops[4];
- int size = GET_MODE_SIZE (GET_MODE (dest));
-
- if (! scratch_mem)
- xops[0] = AT_SP (Pmode);
- else
- xops[0] = scratch_mem;
-
- xops[1] = stack_pointer_rtx;
- xops[2] = GEN_INT (size);
- xops[3] = dest;
-
- if (! scratch_mem)
- output_asm_insn (AS2 (sub%L1,%2,%1), xops);
-
- if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT)
- {
- if (dies)
- output_asm_insn (AS1 (fistp%z3,%y0), xops);
- else if (GET_MODE (xops[3]) == DImode && ! dies)
- {
- /* There is no DImode version of this without a stack pop, so
- we must emulate it. It doesn't matter much what the second
- instruction is, because the value being pushed on the FP stack
- is not used except for the following stack popping store.
- This case can only happen without optimization, so it doesn't
- matter that it is inefficient. */
- output_asm_insn (AS1 (fistp%z3,%0), xops);
- output_asm_insn (AS1 (fild%z3,%0), xops);
- }
- else
- output_asm_insn (AS1 (fist%z3,%y0), xops);
- }
-
- else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT)
- {
- if (dies)
- output_asm_insn (AS1 (fstp%z3,%y0), xops);
- else
- {
- if (GET_MODE (dest) == XFmode)
- {
- output_asm_insn (AS1 (fstp%z3,%y0), xops);
- output_asm_insn (AS1 (fld%z3,%y0), xops);
- }
- else
- output_asm_insn (AS1 (fst%z3,%y0), xops);
- }
- }
-
- else
- abort ();
-
- if (! scratch_mem)
- output_asm_insn (AS1 (pop%L0,%0), &dest);
- else
- output_asm_insn (AS2 (mov%L0,%0,%3), xops);
-
-
- if (size > UNITS_PER_WORD)
- {
- dest = gen_rtx_REG (SImode, REGNO (dest) + 1);
- if (! scratch_mem)
- output_asm_insn (AS1 (pop%L0,%0), &dest);
- else
- {
- xops[0] = adj_offsettable_operand (xops[0], 4);
- xops[3] = dest;
- output_asm_insn (AS2 (mov%L0,%0,%3), xops);
- }
-
- if (size > 2 * UNITS_PER_WORD)
- {
- dest = gen_rtx_REG (SImode, REGNO (dest) + 1);
- if (! scratch_mem)
- output_asm_insn (AS1 (pop%L0,%0), &dest);
- else
- {
- xops[0] = adj_offsettable_operand (xops[0], 4);
- output_asm_insn (AS2 (mov%L0,%0,%3), xops);
- }
- }
- }
-}
-
char *
singlemove_string (operands)
rtx *operands;
@@ -4087,10 +3991,10 @@ output_387_binary_op (insn, operands)
}
/* Output code for INSN to convert a float to a signed int. OPERANDS
- are the insn operands. The output may be SFmode or DFmode and the
- input operand may be SImode or DImode. As a special case, make sure
- that the 387 stack top dies if the output mode is DImode, because the
- hardware requires this. */
+ are the insn operands. The input may be SFmode, DFmode, or XFmode
+ and the output operand may be SImode or DImode. As a special case,
+ make sure that the 387 stack top dies if the output mode is DImode,
+ because the hardware requires this. */
char *
output_fix_trunc (insn, operands)
@@ -4103,38 +4007,36 @@ output_fix_trunc (insn, operands)
if (! STACK_TOP_P (operands[1]))
abort ();
- xops[0] = GEN_INT (12);
- xops[1] = operands[4];
+ if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
+ abort ();
+
+ xops[0] = GEN_INT (0x0c00);
+ xops[1] = operands[5];
output_asm_insn (AS1 (fnstc%W2,%2), operands);
- output_asm_insn (AS2 (mov%L2,%2,%4), operands);
- output_asm_insn (AS2 (mov%B1,%0,%h1), xops);
- output_asm_insn (AS2 (mov%L4,%4,%3), operands);
+ output_asm_insn (AS2 (mov%W5,%2,%w5), operands);
+ output_asm_insn (AS2 (or%W1,%0,%w1), xops);
+ output_asm_insn (AS2 (mov%W3,%w5,%3), operands);
output_asm_insn (AS1 (fldc%W3,%3), operands);
- if (NON_STACK_REG_P (operands[0]))
- output_to_reg (operands[0], stack_top_dies, operands[3]);
+ xops[0] = NON_STACK_REG_P (operands[0]) ? operands[4] : operands[0];
- else if (GET_CODE (operands[0]) == MEM)
+ if (stack_top_dies)
+ output_asm_insn (AS1 (fistp%z0,%y0), xops);
+ else
+ output_asm_insn (AS1 (fist%z0,%y0), xops);
+
+ if (NON_STACK_REG_P (operands[0]))
{
- if (stack_top_dies)
- output_asm_insn (AS1 (fistp%z0,%0), operands);
- else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies)
+ if (GET_MODE (operands[0]) == SImode)
+ output_asm_insn (AS2 (mov%L0,%4,%0), operands);
+ else
{
- /* There is no DImode version of this without a stack pop, so
- we must emulate it. It doesn't matter much what the second
- instruction is, because the value being pushed on the FP stack
- is not used except for the following stack popping store.
- This case can only happen without optimization, so it doesn't
- matter that it is inefficient. */
- output_asm_insn (AS1 (fistp%z0,%0), operands);
- output_asm_insn (AS1 (fild%z0,%0), operands);
+ xops[0] = operands[0];
+ xops[1] = operands[4];
+ output_asm_insn (output_move_double (xops), xops);
}
- else
- output_asm_insn (AS1 (fist%z0,%0), operands);
}
- else
- abort ();
return AS1 (fldc%W2,%2);
}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 6b0045922ef..5e27fd80034 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2713,7 +2713,6 @@ extern void function_arg_advance ();
extern struct rtx_def *function_arg ();
extern int function_arg_partial_nregs ();
extern char *output_strlen_unroll ();
-extern void output_to_reg ();
extern char *singlemove_string ();
extern char *output_move_double ();
extern char *output_move_pushmem ();
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 2d02ef69ef2..fb3e1b2ad0b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2693,164 +2693,172 @@
}"
[(set_attr "type" "fpop")])
-;; Signed conversion to DImode.
+;; Conversions between floating point and fix point.
-(define_expand "fix_truncxfdi2"
- [(set (match_dup 2)
- (match_operand:XF 1 "register_operand" ""))
- (parallel [(set (match_operand:DI 0 "general_operand" "")
- (fix:DI (fix:XF (match_dup 2))))
+(define_expand "fix_truncsfsi2"
+ [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_dup 4))
- (clobber (match_scratch:SI 5 ""))])]
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
- operands[1] = copy_to_mode_reg (XFmode, operands[1]);
- operands[2] = gen_reg_rtx (XFmode);
- operands[3] = (rtx) assign_386_stack_local (SImode, 0);
- operands[4] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (SImode, 0);
}")
-(define_expand "fix_truncdfdi2"
- [(set (match_dup 2)
- (match_operand:DF 1 "register_operand" ""))
- (parallel [(set (match_operand:DI 0 "general_operand" "")
- (fix:DI (fix:DF (match_dup 2))))
- (clobber (match_dup 2))
- (clobber (match_dup 3))
- (clobber (match_dup 4))
- (clobber (match_scratch:SI 5 ""))])]
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
+ (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:SI 4 "memory_operand" "m,m"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
"TARGET_80387"
- "
-{
- operands[1] = copy_to_mode_reg (DFmode, operands[1]);
- operands[2] = gen_reg_rtx (DFmode);
- operands[3] = (rtx) assign_386_stack_local (SImode, 0);
- operands[4] = (rtx) assign_386_stack_local (DImode, 1);
-}")
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
(define_expand "fix_truncsfdi2"
- [(set (match_dup 2)
- (match_operand:SF 1 "register_operand" ""))
- (parallel [(set (match_operand:DI 0 "general_operand" "")
- (fix:DI (fix:SF (match_dup 2))))
+ [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (fix:DI (fix:SF (match_operand:SF 1 "register_operand" ""))))
+ (clobber (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_dup 4))
- (clobber (match_scratch:SI 5 ""))])]
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
operands[1] = copy_to_mode_reg (SFmode, operands[1]);
- operands[2] = gen_reg_rtx (SFmode);
- operands[3] = (rtx) assign_386_stack_local (SImode, 0);
- operands[4] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (DImode, 0);
}")
-;; These match a signed conversion of either DFmode or SFmode to DImode.
-
(define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
- (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f"))))
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
+ (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f"))))
(clobber (match_dup 1))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:DI 4 "memory_operand" "m,o"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
-
-(define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
- (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f"))))
- (clobber (match_dup 1))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
- "TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
-
-(define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
- (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f"))))
- (clobber (match_dup 1))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
- "TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
-
-;; Signed MODE_FLOAT conversion to SImode.
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
-(define_expand "fix_truncxfsi2"
- [(parallel [(set (match_operand:SI 0 "general_operand" "")
- (fix:SI
- (fix:XF (match_operand:XF 1 "register_operand" ""))))
+(define_expand "fix_truncdfsi2"
+ [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (fix:SI (fix:DF (match_operand:DF 1 "register_operand" ""))))
(clobber (match_dup 2))
(clobber (match_dup 3))
- (clobber (match_scratch:SI 4 ""))])]
+ (clobber (match_dup 4))
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
- operands[2] = (rtx) assign_386_stack_local (SImode, 0);
- operands[3] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (SImode, 0);
}")
-(define_expand "fix_truncdfsi2"
- [(parallel [(set (match_operand:SI 0 "general_operand" "")
- (fix:SI
- (fix:DF (match_operand:DF 1 "register_operand" ""))))
+(define_insn ""
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
+ (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:SI 4 "memory_operand" "m,m"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
+ "TARGET_80387"
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "fix_truncdfdi2"
+ [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (fix:DI (fix:DF (match_operand:DF 1 "register_operand" ""))))
+ (clobber (match_dup 1))
(clobber (match_dup 2))
(clobber (match_dup 3))
- (clobber (match_scratch:SI 4 ""))])]
+ (clobber (match_dup 4))
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
- operands[2] = (rtx) assign_386_stack_local (SImode, 0);
- operands[3] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[1] = copy_to_mode_reg (DFmode, operands[1]);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (DImode, 0);
}")
-(define_expand "fix_truncsfsi2"
- [(parallel [(set (match_operand:SI 0 "general_operand" "")
- (fix:SI
- (fix:SF (match_operand:SF 1 "register_operand" ""))))
+(define_insn ""
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
+ (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f"))))
+ (clobber (match_dup 1))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:DI 4 "memory_operand" "m,o"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
+ "TARGET_80387"
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
+
+(define_expand "fix_truncxfsi2"
+ [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (fix:SI (fix:XF (match_operand:XF 1 "register_operand" ""))))
(clobber (match_dup 2))
(clobber (match_dup 3))
- (clobber (match_scratch:SI 4 ""))])]
+ (clobber (match_dup 4))
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
"
{
- operands[2] = (rtx) assign_386_stack_local (SImode, 0);
- operands[3] = (rtx) assign_386_stack_local (DImode, 1);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (SImode, 0);
}")
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
- (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f"))))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r")
+ (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:SI 4 "memory_operand" "m,m"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
-(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
- (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+(define_expand "fix_truncxfdi2"
+ [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (fix:DI (fix:XF (match_operand:XF 1 "register_operand" ""))))
+ (clobber (match_dup 1))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_dup 4))
+ (clobber (match_scratch:HI 5 ""))])]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
+ "
+{
+ operands[1] = copy_to_mode_reg (XFmode, operands[1]);
+ operands[2] = (rtx) assign_386_stack_local (HImode, 0);
+ operands[3] = (rtx) assign_386_stack_local (HImode, 1);
+ operands[4] = (rtx) assign_386_stack_local (DImode, 0);
+}")
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
- (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))
- (clobber (match_operand:SI 2 "memory_operand" "m"))
- (clobber (match_operand:DI 3 "memory_operand" "m"))
- (clobber (match_scratch:SI 4 "=&q"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r")
+ (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f"))))
+ (clobber (match_dup 1))
+ (clobber (match_operand:HI 2 "memory_operand" "m,m"))
+ (clobber (match_operand:HI 3 "memory_operand" "m,m"))
+ (clobber (match_operand:DI 4 "memory_operand" "m,o"))
+ (clobber (match_scratch:HI 5 "=&r,&r"))]
"TARGET_80387"
- "* return output_fix_trunc (insn, operands);")
+ "* return output_fix_trunc (insn, operands);"
+ [(set_attr "type" "fpop")])
;; Conversion between fixed point and floating point.
@@ -4880,31 +4888,36 @@ byte_xor_operation:
[(set (match_operand:SF 0 "register_operand" "=f")
(neg:SF (match_operand:SF 1 "register_operand" "0")))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
(define_insn "negdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(neg:DF (match_operand:DF 1 "register_operand" "0")))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
(define_insn ""
[(set (match_operand:DF 0 "register_operand" "=f")
(neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
(define_insn "negxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(neg:XF (match_operand:XF 1 "register_operand" "0")))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
(define_insn ""
[(set (match_operand:XF 0 "register_operand" "=f")
(neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))]
"TARGET_80387"
- "fchs")
+ "fchs"
+ [(set_attr "type" "fpop")])
;; Absolute value instructions