This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PowerPC ASM_OUTPUT_{FLOAT,DOUBLE} and ASM_OUTPUT_REG_{PUSH,POP}


	I am planning to install the following patch, but I want to make
sure that no one knows of any reason these changes should not be made.

	The PowerPC port currently emits float and double constants (other
than unrepresentable numbers) as floating-point values as opposed to IEEE
754 bit-patterns.  I think this is a hold-over from a time when the port
did not use GCC's REAL_ARITHMETIC support.  This format triggers a bug in
the GNU assembler for the smallest denormalized number.  This change makes
the port consistent with most other ports.

	The second change moves the location on the stack to which
registers are "pushed" and "popped".  GCC rarely utilizes this
functionality, but it had been shifting the stack pointer and then storing
values just past the backchain instead of skipping the fixed and
parameters areas to use the hole really created in the alloca area.  It
looks like STACK_DYNAMIC_OFFSET macro defines this location, but I am not
completely sure.

David


	* rs6000.h (ASM_OUTPUT_{DOUBLE,FLOAT}): Always emit
	IEEE 754 real value bit-patterns.
	(ASM_OUTPUT_REG_{PUSH,POP}): Store register in alloca area.

Index: rs6000.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.42
diff -c -p -r1.42 rs6000.h
*** rs6000.h	1999/03/05 21:19:46	1.42
--- rs6000.h	1999/03/07 05:10:56
*************** extern char rs6000_reg_names[][8];	/* re
*** 3000,3042 ****
  
  /* This is how to output an assembler line defining a `double' constant.  */
  
! #define ASM_OUTPUT_DOUBLE(FILE, VALUE)					\
!   {									\
!     if (REAL_VALUE_ISINF (VALUE)					\
!         || REAL_VALUE_ISNAN (VALUE)					\
! 	|| REAL_VALUE_MINUS_ZERO (VALUE))				\
!       {									\
! 	long t[2];							\
! 	REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);			\
! 	fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n",		\
! 		t[0] & 0xffffffff, t[1] & 0xffffffff);			\
!       }									\
!     else								\
!       {									\
! 	char str[30];							\
! 	REAL_VALUE_TO_DECIMAL (VALUE, "%.20e", str);			\
! 	fprintf (FILE, "\t.double 0d%s\n", str);			\
!       }									\
    }
  
  /* This is how to output an assembler line defining a `float' constant.  */
  
! #define ASM_OUTPUT_FLOAT(FILE, VALUE)					\
!   {									\
!     if (REAL_VALUE_ISINF (VALUE)					\
!         || REAL_VALUE_ISNAN (VALUE)					\
! 	|| REAL_VALUE_MINUS_ZERO (VALUE))				\
!       {									\
! 	long t;								\
! 	REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);			\
! 	fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff);		\
!       }									\
!     else								\
!       {									\
! 	char str[30];							\
! 	REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", str);			\
! 	fprintf (FILE, "\t.float 0d%s\n", str);				\
!       }									\
    }
  
  /* This is how to output an assembler line defining an `int' constant.  */
--- 3000,3020 ----
  
  /* This is how to output an assembler line defining a `double' constant.  */
  
! #define ASM_OUTPUT_DOUBLE(FILE, VALUE)			\
!   {							\
!     long t[2];						\
!     REAL_VALUE_TO_TARGET_DOUBLE ((VALUE), t);		\
!     fprintf (FILE, "\t.long 0x%lx\n\t.long 0x%lx\n",	\
! 	     t[0] & 0xffffffff, t[1] & 0xffffffff);	\
    }
  
  /* This is how to output an assembler line defining a `float' constant.  */
  
! #define ASM_OUTPUT_FLOAT(FILE, VALUE)			\
!   {							\
!     long t;						\
!     REAL_VALUE_TO_TARGET_SINGLE ((VALUE), t);		\
!     fprintf (FILE, "\t.long 0x%lx\n", t & 0xffffffff);	\
    }
  
  /* This is how to output an assembler line defining an `int' constant.  */
*************** do {									\
*** 3097,3106 ****
    extern char *reg_names[];						\
    asm_fprintf (FILE,							\
  	       (TARGET_32BIT)						\
! 	       ? "\t{stu|stwu} %s,-16(%s)\n\t{st|stw} %s,12(%s)\n"	\
! 	       : "\tstdu %s,-32(%s)\n\tstd %s,24(%s)\n",		\
  	       reg_names[1], reg_names[1], reg_names[REGNO],		\
! 	       reg_names[1]);						\
  } while (0)
  
  /* This is how to output an insn to pop a register from the stack.
--- 3075,3084 ----
    extern char *reg_names[];						\
    asm_fprintf (FILE,							\
  	       (TARGET_32BIT)						\
! 	       ? "\t{stu|stwu} %s,-16(%s)\n\t{st|stw} %s,%d(%s)\n"	\
! 	       : "\tstdu %s,-32(%s)\n\tstd %s,%d(%s)\n",		\
  	       reg_names[1], reg_names[1], reg_names[REGNO],		\
! 	       STACK_DYNAMIC_OFFSET(0), reg_names[1]);			\
  } while (0)
  
  /* This is how to output an insn to pop a register from the stack.
*************** do {									\
*** 3111,3120 ****
    extern char *reg_names[];						\
    asm_fprintf (FILE,							\
  	       (TARGET_32BIT)						\
! 	       ? "\t{l|lwz} %s,12(%s)\n\t{ai|addic} %s,%s,16\n"		\
! 	       : "\tld %s,24(%s)\n\t{ai|addic} %s,%s,32\n",		\
! 	       reg_names[REGNO], reg_names[1], reg_names[1],		\
! 	       reg_names[1]);						\
  } while (0)
  
  /* This is how to output an element of a case-vector that is absolute.
--- 3089,3098 ----
    extern char *reg_names[];						\
    asm_fprintf (FILE,							\
  	       (TARGET_32BIT)						\
! 	       ? "\t{l|lwz} %s,%d(%s)\n\t{ai|addic} %s,%s,16\n"		\
! 	       : "\tld %s,%d(%s)\n\t{ai|addic} %s,%s,32\n",		\
! 	       reg_names[REGNO], STACK_DYNAMIC_OFFSET(0),		\
! 	       reg_names[1], reg_names[1], reg_names[1]);		\
  } while (0)
  
  /* This is how to output an element of a case-vector that is absolute.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]