[gnu.gcc.bug] Problems with gcc and '-mfpa' option

valdis@SUN.MCS.CLARKSON.EDU (10/25/88)

Scenario:  Sun 3/260 running SunOS 4.0 and gcc 1.30
gcc was built with tm-sun3.h, m68k.md, and config-sun4.h.

Symptom:  Specifying -mfpa causes an error msg.  Compiling without
this produces a clean compile.

I used gcc-cpp on the original C file to produce zztop.c

Attached is a 'script' of the two compiles, and a 'cat' of the source file.
(I know - the C code is ugly, but (a) I didn't write it and (b) I don't think
that -mfpa should cause this sort of error).
(I edited the typescript file, but only to remove trailing ctl-M chars).

				Valdis Kletnieks
				Sr. Systems Programmer
				Clarkson University
---- start included file
Script started on Mon Oct 24 20:44:51 1988
[alchemy:~/src/ray/tracer,1] gcc -O -v -mfpa -DFAST_MATH_PRIMS  -sun3 -c  zztop.c
gcc version 1.30
 /usr/local/lib/gcc-cpp -v -DFAST_MATH_PRIMS -undef -D__GNU__ -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__OPTIMIZE__ -D__HAVE_FPA__ -D__HAVE_68881__ -Dmc68020 zztop.c /tmp/cca14615.cpp
GNU CPP version 1.30
 /usr/local/lib/gcc-cc1 /tmp/cca14615.cpp -quiet -dumpbase zztop.c -mfpa -O -version -o /tmp/cca14615.s
GNU C version 1.30 (68k, MIT syntax) compiled by GNU C version 1.30.
sphere.c: In function SphereIntersect:
sphere.c:70: inconsistent operand constraints in an `asm' in this function
[alchemy:~/src/ray/tracer,2] gcc -O -v  -DFAST_MATH_PRIMS  -sun3 -c  zztop.c
gcc version 1.30
 /usr/local/lib/gcc-cpp -v -DFAST_MATH_PRIMS -undef -D__GNU__ -D__GNUC__ -Dmc68000 -Dsun -Dunix -D__OPTIMIZE__ -D__HAVE_68881__ -Dmc68020 zztop.c /tmp/cca14618.cpp
GNU CPP version 1.30
 /usr/local/lib/gcc-cc1 /tmp/cca14618.cpp -quiet -dumpbase zztop.c -O -version -o /tmp/cca14618.s
GNU C version 1.30 (68k, MIT syntax) compiled by GNU C version 1.30.
 as -mc68020 /tmp/cca14618.s -o zztop.o
[alchemy:~/src/ray/tracer,3] cat zztop.c
# 1 "sphere.c"
# 1 "/usr/include/stdio.h"
 




extern	struct	_iobuf {
	int	_cnt;
	unsigned char *_ptr;
	unsigned char *_base;
	int	_bufsiz;
	short	_flag;
	char	_file;		 
} _iob[];







































extern struct _iobuf 	*fopen();
extern struct _iobuf 	*fdopen();
extern struct _iobuf 	*freopen();
extern struct _iobuf 	*popen();
extern struct _iobuf 	*tmpfile();
extern long	ftell();
extern char	*fgets();
extern char	*gets();



extern char	*ctermid();
extern char	*cuserid();
extern char	*tempnam();
extern char	*tmpnam();






# 1 "sphere.c"

# 1 "/usr/include/math.h"
 

 



 







# 1 "/usr/include/floatingpoint.h"
 

 



 













# 1 "/usr/include/sys/ieeefp.h"
 

 



 








 

# 26 "/usr/include/sys/ieeefp.h"

# 35 "/usr/include/sys/ieeefp.h"


enum fp_direction_type 		 
	{
	fp_nearest	= 0,
	fp_tozero	= 1,
	fp_negative	= 2,
	fp_positive	= 3
	} ;


# 54 "/usr/include/sys/ieeefp.h"

enum fp_precision_type		 
	{
	fp_extended	= 0,
	fp_single	= 1,
	fp_double	= 2,
	fp_precision_3	= 3
	} ;


# 74 "/usr/include/sys/ieeefp.h"

enum fp_exception_type		 
	{
	fp_inexact	= 0,
	fp_division	= 1,
	fp_underflow	= 2,
	fp_overflow	= 3,
	fp_invalid	= 4
	} ;


enum fp_class_type		 
	{
	fp_zero		= 0,
	fp_subnormal	= 1,
	fp_normal	= 2,
	fp_infinity   	= 3,
	fp_quiet	= 4,
	fp_signaling	= 5
	} ;
# 21 "/usr/include/floatingpoint.h"


 

typedef float single ;			
typedef unsigned extended[3] ;



typedef unsigned fp_exception_field_type ; 
				 




typedef int sigfpe_code_type ;   

typedef void (* sigfpe_handler_type)() ; 
				 





 

extern enum fp_direction_type fp_direction ;
				 


	

extern enum fp_precision_type fp_precision ;
				 


	

extern sigfpe_handler_type ieee_handlers [5	] ;
				 









extern fp_exception_field_type fp_accrued_exceptions ;	
				 








extern sigfpe_handler_type sigfpe( ) ;

 


				 

typedef char decimal_string[512	] ;	
				 

typedef struct
	{
	enum fp_class_type fpclass ;
	int	sign ;
	int	exponent ;
	decimal_string ds ;	 


	int	more ;		 


	int 	ndigits ;	 


	}
	decimal_record ;

enum decimal_form
	{
	fixed_form,		 


	floating_form		 

	} ;

typedef struct
	{
	enum fp_direction_type rd ;	
				 
	enum decimal_form df ;	 

	int ndigits ;		 
	}
	decimal_mode ;

enum decimal_string_form
	{			 
	invalid_form,		 
	whitespace_form,	 
	fixed_int_form,		 
	fixed_intdot_form,	 
	fixed_dotfrac_form,	 
	fixed_intdotfrac_form,	 
	floating_int_form,	 	
	floating_intdot_form,	 
	floating_dotfrac_form,	 
	floating_intdotfrac_form, 
	inf_form,		 
	infinity_form,		 
	nan_form,		 
	nanstring_form		 
	} ;

extern void single_to_decimal ( ) ; 
extern void double_to_decimal ( ) ;
extern void extended_to_decimal ( ) ;

extern void decimal_to_single ( ) ;
extern void decimal_to_double ( ) ;
extern void decimal_to_extended ( ) ;

extern char *econvert( ) ;
extern char *fconvert( ) ;
extern char *gconvert( ) ;
extern char *seconvert( ) ;
extern char *sfconvert( ) ;
extern char *sgconvert( ) ;

extern void string_to_decimal( ) ; 
extern void   file_to_decimal( ) ; 
extern void   func_to_decimal( ) ; 

 

extern double atof();

 

extern int errno;

extern double strtod ();
# 16 "/usr/include/math.h"


 

extern int    finite();
extern double fabs(), floor(), ceil(), rint();
extern double hypot();
extern double copysign();
extern double sqrt();
extern double modf(), frexp();
extern double asinh(), acosh(), atanh();
extern double erf(), erfc();
extern double exp(), expm1(), log(), log10(), log1p(), pow();
extern double lgamma();
extern double j0(), j1(), jn(), y0(), y1(), yn();
extern double sin(), cos(), tan(), asin(), acos(), atan(), atan2();
extern double sinh(), cosh(), tanh();
extern double cbrt();

 
 
enum fp_pi_type { 		 

	fp_pi_infinite	= 0,	 
	fp_pi_66	= 1,	 
	fp_pi_53	= 2	 
	} ;

extern enum fp_pi_type fp_pi ;   


 

extern enum fp_class_type fp_class() ;
extern int ilogb(), irint(), signbit() ;
extern int isinf(), isnan(), isnormal(), issubnormal(), iszero() ;
extern double nextafter(), remainder() ;
extern double logb(), significand(), scalb(), scalbn();
extern double min_subnormal(), max_subnormal();
extern double min_normal(), max_normal();
extern double infinity(), quiet_nan(), signaling_nan();

 

extern double log2(), exp10(), exp2(), aint(), anint() ;
extern int nint() ;
extern void   sincos();

 

extern int ieee_flags ();
extern int ieee_handler ();

 












 







 







 







 




extern int    ir_finite_();
extern int  r_fabs_(), r_floor_(), r_ceil_(), r_rint_();
extern int  r_hypot_();
extern int  r_copysign_();
extern int  r_sqrt_();
extern int  r_asinh_(), r_acosh_(), r_atanh_();
extern int  r_erf_(), r_erfc_();
extern int  r_exp_(), r_expm1_(), r_log_(), r_log10_(), r_log1p_();
extern int  r_pow_();
extern int  r_lgamma_();
extern int  r_j0_(), r_j1_(), r_jn_(), r_y0_(), r_y1_(), r_yn_();
extern int  r_sin_(), r_cos_(), r_tan_(), r_asin_(), r_acos_();
extern int  r_atan_(), r_atan2_();
extern int  r_sinh_(), r_cosh_(), r_tanh_();
extern int  r_cbrt_();
extern int ir_ilogb_(), ir_irint_(), ir_signbit_() ;
extern int ir_isinf_(), ir_isnan_(), 
	   ir_issubnormal_(), ir_isnormal_(), ir_iszero_() ;
extern enum fp_class_type ir_fp_class_();
extern int  r_nextafter_(), r_remainder_() ;
extern int  r_log2_(), r_exp10_(), r_exp2_(), r_aint_(), r_anint_() ;
extern int ir_nint_() ;
extern int  r_fmod_();
extern int  r_logb_(), r_significand_(), r_scalb_(), r_scalbn_();
extern int  r_min_subnormal_(), r_max_subnormal_();
extern int  r_min_normal_(), r_max_normal_();
extern int  r_infinity_(), r_quiet_nan_(), r_signaling_nan_();
extern void r_sincos_();

 













struct exception {
        int type;
        char *name;
        double arg1;
        double arg2;
        double retval;
};

extern int signgam;

extern double fmod();
extern int matherr();

 

























 




extern double cabs();	 


extern double drem();	 

extern double gamma();	 



extern double ldexp();	 



# 2 "sphere.c"

# 1 "defs.h"
 








typedef double Flt ;
typedef Flt Vec[3] ;
typedef Vec Point ;
typedef Vec Color ;
typedef Flt Matrix[4][4] ;
























typedef struct Ray {
	Point P ;
	Point D ;
} Ray ;






 

typedef struct t_surface {
	Color	surf_color ;
	Flt	surf_kd ;
	Flt	surf_ks ;
	Flt	surf_shine ;
	Flt 	surf_kt ;
	Flt	surf_ior ;
} Surface ;

typedef struct t_light {
	Vec	light_pos ;
	Flt	light_brightness ;
} Light ;

typedef struct t_viewpoint {
	Vec	view_from ;
	Vec	view_at ;
	Vec	view_up ;
	Flt	view_angle ;
	Flt	view_dist ;
} Viewpoint ;

typedef struct t_object {
	unsigned short 	o_type ;
	Flt	o_dmin[	(3) ] ;
	Flt	o_dmax[	(3) ] ;
	struct t_objectprocs {
		int 	(*print) () ;
		int 	(*intersect) () ;
		int 	(*normal) () ;
	} * o_procs ;
	struct t_surface 	* o_surf ;
	void	* o_data ;
} Object ;

typedef struct t_compositedata {
	unsigned short 	c_size ;
	Object *	c_object[(10) ] ;
} CompositeData ;

typedef struct t_objectprocs ObjectProcs ;

typedef struct t_isect {
	Flt 		isect_t ;
	int 		isect_enter ;
	Object 		* isect_prim ;
	Surface 	* isect_surf ;
} Isect ;

typedef struct t_pixel {
	unsigned char r, g, b, q ;
} Pixel ;































# 3 "sphere.c"

# 1 "extern.h"



extern  int 		yylinecount ;
extern	Viewpoint 	Eye ;
extern	int 		Xresolution ;
extern	int 		Yresolution ;
extern	Light		Lights[] ;
extern	int		nLights ;
extern	Vec		BackgroundColor ;
extern	Surface		* CurrentSurface ;
extern	Object		* Prims[] ;
extern	int		nPrims ;
extern 	Flt		rayeps ;
extern	char *		Progname ;
extern 	int		maxQueueSize ;
extern 	int		totalQueues ;
extern	int		totalQueueResets ;
extern 	int		tickflag ;
extern  int		nChecked ;
extern 	int		nEnqueued ;

extern 	Flt		minweight ;
extern 	int		maxlevel ;
extern 	int		nRays ;
extern	int		nShadows ;
extern	int		nReflected ;
extern 	int		nRefracted ;

char *		malloc() ;
char *		calloc() ;
char *		rindex() ;

extern	Object *	MakeCone() ;
extern	Object *	MakeSphere() ;
extern	Object *	MakePatch() ;
extern	Object *	MakePoly() ;

extern 	Flt		VecNormalize() ;
extern	Vec		Slab[] ;
extern	ObjectProcs	NullProcs ;
extern 	Object *	Root ;
# 4 "sphere.c"


typedef struct t_spheredata {
	Vec 		sph_center ;
	Flt 		sph_radius ;
	Flt 		sph_radius2 ;
} SphereData ;

int SpherePrint ();
int SphereIntersect ();
int SphereNormal ();

ObjectProcs SphereProcs = {
	SpherePrint,
	SphereIntersect,
	SphereNormal,
} ;

int 
SpherePrint(obj)
 Object *obj ;
{
	SphereData * sp ;

	sp = (SphereData *) obj -> o_data ;

	printf("s %g %g %g %g\n", sp -> sph_center[0], 
				   sp -> sph_center[1],
				   sp -> sph_center[2],
				   sp -> sph_radius) ;
}

SphereIntersect(obj, ray, hit)
 Object * obj ;
 Ray * ray ;
 Isect * hit ;
{

	Flt b, disc, t;
	Point V ;
	SphereData * sp ;

	sp = (SphereData *) obj -> o_data ;

	 ( V)[0]=((sp->sph_center))[0]-( ray -> P)[0];	( V)[1]=((sp->sph_center))[1]-( ray -> P)[1];	( V)[2]=((sp->sph_center))[2]-( ray -> P)[2] ;

	b = ((V)[0]*( ray -> D)[0]+(V)[1]*( ray -> D)[1]+(V)[2]*( ray -> D)[2]) ;

	disc = b * b - ((V)[0]*( V)[0]+(V)[1]*( V)[1]+(V)[2]*( V)[2])  + (sp -> sph_radius2) ;

	if (disc < 0.0)
		return(0);

	disc = ({ double __value, __arg = (disc) ;	asm("fsqrtx %1,%0": "=f" (__value): "f" (__arg)) ;	__value ;}) ;

	t = (b - disc < rayeps) ? b + disc : b - disc ;

	if (t < rayeps) {
		return(0);
	}

	hit -> isect_t = t ;
	hit -> isect_enter = ((V)[0]*( V)[0]+(V)[1]*( V)[1]+(V)[2]*( V)[2])  > sp -> sph_radius2 + rayeps ? 1 : 0 ;
	hit -> isect_prim = obj ;
	hit -> isect_surf = obj -> o_surf ;
	return (1);
}

int
SphereNormal(obj, hit, P, N)
 Object * obj ;
 Isect * hit ;
 Point P, N ;
{
	SphereData * sp ;
	sp = (SphereData *) obj -> o_data ;

	 ( N)[0]=(P)[0]-( sp -> sph_center)[0];	( N)[1]=(P)[1]-( sp -> sph_center)[1];	( N)[2]=(P)[2]-( sp -> sph_center)[2] ;
	(void) VecNormalize(N);
}

Object *
MakeSphere(pos, radius)
 Vec pos ;
 Flt radius ;
{
	Object * tmp ;
	int i ;
	SphereData *sp ;

	tmp = (Object *) malloc (sizeof(Object)) ;
	tmp -> o_type = (1)  ;
	tmp -> o_procs = & SphereProcs ;
	tmp -> o_surf = CurrentSurface ;
	sp = (SphereData *) malloc (sizeof(SphereData)) ;
	 ( sp -> sph_center)[0]=(pos)[0];( sp -> sph_center)[1]=(pos)[1];( sp -> sph_center)[2]=(pos)[2];  ;
	sp -> sph_radius = radius ;
	sp -> sph_radius2 = radius * radius ;
	tmp -> o_data = (void *) sp ;

	 



	
	for (i = 0 ; i < 	(3) ; i ++) {
		tmp -> o_dmin[i] = ((sp -> sph_center)[0]*( Slab[i])[0]+(sp -> sph_center)[1]*( Slab[i])[1]+(sp -> sph_center)[2]*( Slab[i])[2])  
			- sp -> sph_radius ;
		tmp -> o_dmax[i] = ((sp -> sph_center)[0]*( Slab[i])[0]+(sp -> sph_center)[1]*( Slab[i])[1]+(sp -> sph_center)[2]*( Slab[i])[2])  
			+ sp -> sph_radius ;
	}
	return tmp ;
}
[alchemy:~/src/ray/tracer,4] exit
[alchemy:~/src/ray/tracer,5] 
script done on Mon Oct 24 20:45:45 1988
---- end included file

randy@WHEATIES.AI.MIT.EDU (10/25/88)

    Your problem is the asm on line 70.  It uses the m68881
  coprocessor, and you cannot use both the fpa and the 68881 together
  under gcc.  (This decision was made when I was doing the port.  It
  is *somewhat* arbitrary, and fully explained in the m68k.md file.
  The asm you use is the first good reason I've seen not to do it my
  way).  If someone wants to make the necessary changes to m68k.md to
  allow use of the fpa and the 68881 together, that would be
  wonderful.  However, I'm probably not going to be that person.  See
  m68k.md for more details.

						-- Randy

						randy@wheaties.ai.mit.edu