public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* complex support on alpha
@ 1997-10-01 21:03 Weiwen Liu
  1997-10-01 22:34 ` Richard Henderson
  1997-10-02 20:35 ` Jim Wilson
  0 siblings, 2 replies; 9+ messages in thread
From: Weiwen Liu @ 1997-10-01 21:03 UTC (permalink / raw)
  To: egcs

Hi,

egcs on alpha-dec-osf4.0 fails to generate correct code for
gcc.c-torture/execute/complex-5.c 
in the testsuite, because gcc does not calculate correctly the number of
registers needed for 'float __complex__'.  Instead of 2 registers, gcc
says only one register is needed. 

egcs generates rtl's for complex-5.c:
(insn 4 2 6 (set (mem:SF (reg:DI 65))
        (reg:SF 48 $f16)) -1 (nil)
    (nil))

(insn 6 4 8 (set (mem:SF (plus:DI (reg:DI 65)
                (const_int 4)))
        (reg:SF 48 $f16)) -1 (nil)
    (nil))
===> register $f16 is used to pass both real and imagine part, and the
===> real part is lost in function f in complex-5.c 
(insn 8 6 10 (set (mem:SF (plus:DI (reg:DI 65)
                (const_int 8)))
        (reg:SF 49 $f17)) -1 (nil)
    (nil))

(insn 10 8 11 (set (mem:SF (plus:DI (reg:DI 65)
                (const_int 12)))
        (reg:SF 49 $f17)) -1 (nil)
    (nil))


The following patch  will calculate number of registers for
complex arguments correctly and compile complex-5.c correctly.

With this patch, egcs generates correct code for the following
program:

/*
long int __complex__ t5 (long int __complex__ a, long int __complex__ b)
{
    return a + b;
}
*/

float __complex__ t1 (float __complex__ a, float __complex__ b)
{
    return a + b;
}

double __complex__ t2 (double __complex__ a, double __complex__ b)
{
    return a + b;
}

short __complex__ t3 (short __complex__ a, short __complex__ b)
{
    return a + b;
}

int __complex__ t4 (int __complex__ a, int __complex__ b)
{
    return a + b;
}

float __complex__ a1 = 1. + 2.i;
float __complex__ b1 = 3. + 4.i;
float __complex__ c1 = 4. + 6.i;

double __complex__ a2 = 1.L + 2.Li;
double __complex__ b2 = 3.L + 4.Li;
double __complex__ c2 = 4.L + 6.Li;

short __complex__ a3 = 1 + 2i;
short __complex__ b3 = 3 + 4i;
short __complex__ c3 = 4 + 6i;

int __complex__ a4 = 1 + 2i;
int __complex__ b4 = 3 + 4i;
int __complex__ c4 = 4 + 6i;

/*
long int __complex__ a5 = 1L + 2Li;
long int __complex__ b5 = 3L + 4Li;
long int __complex__ c5 = 4L + 6Li;
*/

int main()
{
    if (t1(a1, b1) != c1)
        abort ();
    if (t2(a2, b2) != c2)
        abort ();
    if (t3(a3, b3) != c3)
        abort ();
    if (t4(a4, b4) != c4)
        abort ();
/*
    if (t5(a5, b5) != c5)
        abort ();
*/
    return 0;
}

Note that "long int __complex__" parts are commented out because gcc
does not accept it even though gcc.info says it supports.  I have a
patch to enable "long int __complex__" support.  If you need this
patch, let me know.

Weiwen

Wed Oct  2  23:30:00  Weiwen Liu <liu@hepunix.physics.yale.edu>

	 * regs.h: Correctly calculates number of registers needed.
	 * emit-rtl.c (gen_lowpart_common, gen_highpart): Ditto.
	 * config/alpha/alpha.h: Ditto.

	 * config/alpha/alpha.h: Use $f0 and $f1 for complex float.

*** gcc/regs.h.orig	Tue Sep 30 01:07:59 1997
--- gcc/regs.h	Wed Oct  1 00:20:26 1997
*************** Boston, MA 02111-1307, USA.  */
*** 27,33 ****
     valid way to get this value.  You cannot get it from the regno.  */
  
  #define REG_SIZE(R) \
!   ((mode_size[(int) GET_MODE (R)] + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
  
  /* Maximum register number used in this function, plus one.  */
  
--- 27,36 ----
     valid way to get this value.  You cannot get it from the regno.  */
  
  #define REG_SIZE(R) \
!   (GET_MODE_SIZE (GET_MODE (R)) == 0?					\
!    0:(((GET_MODE_UNIT_SIZE (GET_MODE (R)) + (UNITS_PER_WORD - 1))	\
!       / UNITS_PER_WORD) * (GET_MODE_SIZE (GET_MODE (R))			\
!       / GET_MODE_UNIT_SIZE (GET_MODE (R)))))
  
  /* Maximum register number used in this function, plus one.  */
  
*** gcc/emit-rtl.c.orig	Mon Sep 22 13:41:24 1997
--- gcc/emit-rtl.c	Tue Sep 30 23:09:20 1997
*************** gen_lowpart_common (mode, x)
*** 635,644 ****
  	     / UNITS_PER_WORD)))
      return 0;
  
!   if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
!     word = ((GET_MODE_SIZE (GET_MODE (x))
! 	     - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
! 	    / UNITS_PER_WORD);
  
    if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
        && (GET_MODE_CLASS (mode) == MODE_INT
--- 635,647 ----
  	     / UNITS_PER_WORD)))
      return 0;
  
!   if (WORDS_BIG_ENDIAN && GET_MODE_SIZE (GET_MODE (x)) >0)
!     word = ((GET_MODE_UNIT_SIZE (GET_MODE (x)) + (UNITS_PER_WORD - 1))
!             / UNITS_PER_WORD)
!         * (GET_MODE_SIZE (GET_MODE (x))
!            / GET_MODE_UNIT_SIZE (GET_MODE (x)))
!         - ((GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1))
!            / UNITS_PER_WORD);
  
    if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
        && (GET_MODE_CLASS (mode) == MODE_INT
*************** gen_highpart (mode, x)
*** 1013,1022 ****
        int word = 0;
  
        if (! WORDS_BIG_ENDIAN
! 	  && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
! 	word = ((GET_MODE_SIZE (GET_MODE (x))
! 		 - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD))
! 		/ UNITS_PER_WORD);
  
        /*
         * ??? This fails miserably for complex values being passed in registers
--- 1016,1028 ----
        int word = 0;
  
        if (! WORDS_BIG_ENDIAN
! 	  && GET_MODE_SIZE (GET_MODE (x)) > 0)
!         word = ((GET_MODE_UNIT_SIZE (GET_MODE (x)) + (UNITS_PER_WORD - 1))
!                 / UNITS_PER_WORD)
!             * (GET_MODE_SIZE (GET_MODE (x))
!                / GET_MODE_UNIT_SIZE (GET_MODE (x)))
!             - ((GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1))
!                / UNITS_PER_WORD);
  
        /*
         * ??? This fails miserably for complex values being passed in registers
*** gcc/config/alpha/alpha.h.orig	Thu Sep 25 10:21:11 1997
--- gcc/config/alpha/alpha.h	Wed Oct  1 12:33:43 1997
*************** extern void override_options ();
*** 515,521 ****
     but can be less for certain modes in special long registers.  */
  
  #define HARD_REGNO_NREGS(REGNO, MODE)   \
!   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
  
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     On Alpha, the integer registers can hold any mode.  The floating-point
--- 515,525 ----
     but can be less for certain modes in special long registers.  */
  
  #define HARD_REGNO_NREGS(REGNO, MODE)   \
!   (GET_MODE_SIZE (MODE) == 0?					\
!    0:(((GET_MODE_UNIT_SIZE (MODE) + (UNITS_PER_WORD - 1))	\
!       / UNITS_PER_WORD) * (GET_MODE_SIZE (MODE)			\
!       / GET_MODE_UNIT_SIZE (MODE))))
! /*  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)*/
  
  /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
     On Alpha, the integer registers can hold any mode.  The floating-point
*************** enum reg_class { NO_REGS, GENERAL_REGS, 
*** 891,901 ****
  #define FUNCTION_VALUE(VALTYPE, FUNC)	\
    gen_rtx (REG,							\
  	   (INTEGRAL_MODE_P (TYPE_MODE (VALTYPE))		\
  	    && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) 	\
  	   ? word_mode : TYPE_MODE (VALTYPE),			\
  	   ((TARGET_FPREGS					\
  	     && (TREE_CODE (VALTYPE) == REAL_TYPE		\
! 		 || TREE_CODE (VALTYPE) == COMPLEX_TYPE))	\
  	    ? 32 : 0))
  
  /* Define how to find the value returned by a library function
--- 895,909 ----
  #define FUNCTION_VALUE(VALTYPE, FUNC)	\
    gen_rtx (REG,							\
  	   (INTEGRAL_MODE_P (TYPE_MODE (VALTYPE))		\
+             && (GET_MODE_CLASS(TYPE_MODE (VALTYPE))		\
+                 != MODE_COMPLEX_INT)				\
  	    && TYPE_PRECISION (VALTYPE) < BITS_PER_WORD) 	\
  	   ? word_mode : TYPE_MODE (VALTYPE),			\
  	   ((TARGET_FPREGS					\
  	     && (TREE_CODE (VALTYPE) == REAL_TYPE		\
! 		 || TREE_CODE (VALTYPE) == COMPLEX_TYPE)	\
!              && (GET_MODE_CLASS(TYPE_MODE (VALTYPE))		\
!                  != MODE_COMPLEX_INT))				\
  	    ? 32 : 0))
  
  /* Define how to find the value returned by a library function
*************** enum reg_class { NO_REGS, GENERAL_REGS, 
*** 953,959 ****
  
  #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED)				\
  ((MODE) != BLKmode							\
!  ? (GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD 	\
   : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
  
  /* Update the data in CUM to advance over an argument
--- 961,970 ----
  
  #define ALPHA_ARG_SIZE(MODE, TYPE, NAMED)				\
  ((MODE) != BLKmode							\
!  ? (GET_MODE_SIZE (MODE) > 0?						\
!     (GET_MODE_UNIT_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD	\
!     * GET_MODE_SIZE (MODE) / GET_MODE_UNIT_SIZE (MODE)			\
!     : 0)								\
   : (int_size_in_bytes (TYPE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
  
  /* Update the data in CUM to advance over an argument


The result from "make check-gcc" with this patch is

		=== gcc Summary ===

# of expected passes		4879
# of unexpected failures	8
# of expected failures		4
# of unsupported tests		7

FAIL: gcc.c-torture/compile/961203-1.c,  -O0  
FAIL: gcc.c-torture/compile/961203-1.c,  -O1  
FAIL: gcc.c-torture/compile/961203-1.c,  -O2  
FAIL: gcc.c-torture/compile/961203-1.c,  -O2 -fomit-frame-pointer -finline-functions  
FAIL: gcc.c-torture/execute/ieee/fp-cmp-1.c execution,  -O0 
FAIL: gcc.c-torture/execute/ieee/fp-cmp-1.c execution,  -O1 
FAIL: gcc.c-torture/execute/ieee/fp-cmp-1.c execution,  -O2 
FAIL: gcc.c-torture/execute/ieee/fp-cmp-1.c execution,  -O2 -fomit-frame-pointer -finline-functions 



^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~1997-10-05 18:28 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-10-01 21:03 complex support on alpha Weiwen Liu
1997-10-01 22:34 ` Richard Henderson
1997-10-02  9:22   ` Weiwen Liu
1997-10-02 10:46     ` Richard Henderson
1997-10-05 16:16   ` Weiwen Liu
1997-10-05 18:28     ` Richard Henderson
1997-10-02 20:35 ` Jim Wilson
1997-10-04 14:33   ` Kamil Iskra
1997-10-04 18:29     ` Richard Henderson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).