diff options
author | wehle <wehle@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-04-25 11:43:49 +0000 |
---|---|---|
committer | wehle <wehle@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-04-25 11:43:49 +0000 |
commit | aae163e1020becf456dafd42e6995a3ec1203cec (patch) | |
tree | 7ca441f8bb80a8971078183607b030c4dd82e538 /gcc/config | |
parent | a6af95fb35a4f613476d2ae14f070f0a4c5613bd (diff) | |
download | gcc-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.c | 148 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 233 |
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 |