This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to correct x86 FP extend splits
- To: rth at cygnus dot com
- Subject: Patch to correct x86 FP extend splits
- From: John Wehle <john at feith dot com>
- Date: Wed, 14 Apr 1999 13:52:52 -0400 (EDT)
- Cc: egcs-patches at egcs dot cygnus dot com, zack at rabi dot columbia dot edu
This should address the issues raised by you and Zack.
It passes bootstrap and make check on x86 FreeBSD 3.1
configured for aout.
ChangeLog:
Tue Apr 13 02:52:35 EDT 1999 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.
Enjoy!
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/config/i386/i386.md.ORIGINAL Tue Apr 13 22:40:39 1999
--- gcc/config/i386/i386.md Wed Apr 14 02:17:15 1999
***************
*** 2256,2262 ****
(clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))]
"TARGET_80387 && (GET_CODE (operands[0]) != MEM
|| GET_CODE (operands[1]) != MEM)"
! "#")
(define_split
[(set (match_operand:DF 0 "register_operand" "")
--- 2256,2267 ----
(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" "")
***************
*** 2299,2319 ****
|| 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]))
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")])
--- 2304,2311 ----
|| GET_CODE (operands[1]) != MEM)"
"*
{
! output_float_extend (insn, operands);
return \"\";
}"
[(set_attr "type" "fld,fpop")])
***************
*** 2341,2347 ****
(clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
"TARGET_80387 && (GET_CODE (operands[0]) != MEM
|| GET_CODE (operands[1]) != MEM)"
! "#")
(define_split
[(set (match_operand:XF 0 "register_operand" "")
--- 2333,2344 ----
(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" "")
***************
*** 2384,2409 ****
|| 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]))
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")])
--- 2381,2388 ----
|| GET_CODE (operands[1]) != MEM)"
"*
{
! output_float_extend (insn, operands);
return \"\";
}"
[(set_attr "type" "fld,fpop")])
***************
*** 2431,2437 ****
(clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))]
"TARGET_80387 && (GET_CODE (operands[0]) != MEM
|| GET_CODE (operands[1]) != MEM)"
! "#")
(define_split
[(set (match_operand:XF 0 "register_operand" "")
--- 2410,2421 ----
(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" "")
***************
*** 2475,2500 ****
|| 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]))
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")])
--- 2459,2466 ----
|| GET_CODE (operands[1]) != MEM)"
"*
{
! output_float_extend (insn, operands);
return \"\";
}"
[(set_attr "type" "fld,fpop")])
*** gcc/config/i386/i386.c.ORIGINAL Tue Apr 13 22:40:03 1999
--- gcc/config/i386/i386.c Wed Apr 14 03:03:41 1999
*************** output_fix_trunc (insn, operands)
*** 4179,4184 ****
--- 4179,4244 ----
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
*** gcc/config/i386/i386.h.ORIGINAL Tue Apr 13 22:40:09 1999
--- gcc/config/i386/i386.h Wed Apr 14 01:59:35 1999
*************** extern int shift_op ();
*** 2743,2748 ****
--- 2743,2749 ----
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 ();
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------