diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-04-14 14:27:38 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-04-14 14:27:38 +0000 |
commit | 37a8f6b4d7f9bedc3438b64eb509c168e3b8087e (patch) | |
tree | a97c00a571ca8d697b4ca76134c15ecb94562240 /gcc/config | |
parent | 8fc541287d1c021d547e69b63f0f01f598dff133 (diff) | |
download | gcc-37a8f6b4d7f9bedc3438b64eb509c168e3b8087e.tar.gz |
John Wehle (john@feith.com)
* i386.md (extendsfdf, extendsfxf, extenddfxf): Use
output_float_extend instead specifying '#' as the template.
* i386.c (output_float_extend): Define.
* i386.h (output_float_extend): Declare.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26455 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/i386/i386.c | 60 | ||||
-rw-r--r-- | gcc/config/i386/i386.h | 1 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 76 |
3 files changed, 82 insertions, 55 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 3da661affe2..8432443a06a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -4179,6 +4179,66 @@ output_fix_trunc (insn, operands) return AS1 (fldc%W2,%2); } +/* Output code for INSN to extend a float. OPERANDS are the insn + operands. The output may be DFmode or XFmode and the input operand + may be SFmode or DFmode. Operands 2 and 3 are scratch memory and + are only necessary if operands 0 or 1 are non-stack registers. */ + +void +output_float_extend (insn, operands) + rtx insn; + rtx *operands; +{ + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + rtx xops[2]; + + if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1])) + abort (); + + if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]) && stack_top_dies) + return; + + if (STACK_TOP_P (operands[0]) ) + { + if (NON_STACK_REG_P (operands[1])) + { + if (GET_MODE (operands[1]) == SFmode) + output_asm_insn (AS2 (mov%L0,%1,%2), operands); + else + { + xops[0] = operands[2]; + xops[1] = operands[1]; + output_asm_insn (output_move_double (xops), xops); + } + } + + xops[0] = NON_STACK_REG_P (operands[1]) ? operands[2] : operands[1]; + + output_asm_insn (AS1 (fld%z0,%y0), xops); + } + else + { + xops[0] = NON_STACK_REG_P (operands[0]) ? operands[3] : operands[0]; + + if (stack_top_dies + || (GET_CODE (xops[0]) == MEM && GET_MODE (xops[0]) == XFmode)) + { + output_asm_insn (AS1 (fstp%z0,%y0), xops); + if (! stack_top_dies) + output_asm_insn (AS1 (fld%z0,%y0), xops); + } + else + output_asm_insn (AS1 (fst%z0,%y0), xops); + + if (NON_STACK_REG_P (operands[0])) + { + xops[0] = operands[0]; + xops[1] = operands[3]; + output_asm_insn (output_move_double (xops), xops); + } + } +} + /* Output code for INSN to compare OPERANDS. The two operands might not have the same mode: one might be within a FLOAT or FLOAT_EXTEND expression. If the compare is in mode CCFPEQmode, use an opcode that diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index de4da2cb6fe..56967a69165 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -2743,6 +2743,7 @@ extern int shift_op (); extern int VOIDmode_compare_op (); extern char *output_387_binary_op (); extern char *output_fix_trunc (); +extern void output_float_extend (); extern char *output_float_compare (); extern char *output_fp_cc0_set (); extern void save_386_machine_status (); diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index ef062b95727..211b0ba1214 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -2259,7 +2259,12 @@ (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))] "TARGET_80387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "#") + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) (define_split [(set (match_operand:DF 0 "register_operand" "") @@ -2302,21 +2307,8 @@ || GET_CODE (operands[1]) != MEM)" "* { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1])) - abort (); - - if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) + output_float_extend (insn, operands); return \"\"; - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - if (stack_top_dies) - return AS1 (fstp%z0,%y0); - else - return AS1 (fst%z0,%y0); }" [(set_attr "type" "fld,fpop")]) @@ -2344,7 +2336,12 @@ (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] "TARGET_80387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "#") + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) (define_split [(set (match_operand:XF 0 "register_operand" "") @@ -2387,26 +2384,8 @@ || GET_CODE (operands[1]) != MEM)" "* { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1])) - abort (); - - if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) + output_float_extend (insn, operands); return \"\"; - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - if (stack_top_dies || GET_CODE (operands[0]) == MEM) - output_asm_insn (AS1 (fstp%z0,%y0), operands); - else - return AS1 (fst%z0,%y0); - - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - - return \"\"; }" [(set_attr "type" "fld,fpop")]) @@ -2434,7 +2413,12 @@ (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] "TARGET_80387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "#") + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) (define_split [(set (match_operand:XF 0 "register_operand" "") @@ -2478,26 +2462,8 @@ || GET_CODE (operands[1]) != MEM)" "* { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1])) - abort (); - - if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1])) + output_float_extend (insn, operands); return \"\"; - - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); - - if (stack_top_dies || GET_CODE (operands[0]) == MEM) - output_asm_insn (AS1 (fstp%z0,%y0), operands); - else - return AS1 (fst%z0,%y0); - - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - - return \"\"; }" [(set_attr "type" "fld,fpop")]) |