From: hando@prd.CS.fujitsu.co.JP (Hisashige Ando)
Subject: gcc-2.1 for i386 bug report
Organization: GNUs Not Usenet
Distribution: gnu
Date: Tue, 14 Apr 1992 00:37:42 GMT

  This bug report is made of 3 parts.

  gcc-2.1 made with configure --host=sparc i386 generates code below.

			hando@prd.cs.fujitsu.co.jp (Hisashige Ando)

****** 1st part of bug report *****************************

It generates, 80387 FPU code even with  -msoft-float.

-----------------dialogue---------------------------------
gcc version 2.1
 /home/hando/gcc2/gcc-2.1/cpp -lang-c -v -undef -D__GNUC__=2 -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix ftest.c /usr/tmp/cca00965.i
GNU CPP version 2.1 (80386, ATT syntax)
 /home/hando/gcc2/gcc-2.1/cc1 /usr/tmp/cca00965.i -quiet -dumpbase ftest.c -msoft-float -version -o ftest.s
GNU C version 2.1 (80386, ATT syntax) compiled by CC.
------------------source-----------------------------------
double	gdx;
float	gfx;

double	dfl(double x)
{
	gdx = x;
	return gdx;
}

float	fl(float x)
{
	gfx = x;
	return gfx;
}
-----------------assembler output--------------------------
	.file	"ftest.c"
gcc2_compiled.:
.text
	.align 4
.globl dfl
dfl:
	pushl %ebp
	movl %esp,%ebp
	fldl 8(%ebp)
	fstpl gdx
	fldl gdx
	jmp .L1
	.align 4
.L1:
	leave
	ret
	.align 4
.globl fl
fl:
	pushl %ebp
	movl %esp,%ebp
	flds 8(%ebp)
	fstps gfx
	flds gfx
	jmp .L2
	.align 4
.L2:
	leave
	ret
.comm gdx,8
.comm gfx,4
-------------------------------------------------------------
 I believe, 

  1. the portion below in i386sco.h (which is tm.h) has to 
     be enabled.
  2. register constraint of movsf and movdf shoud have 'r' like below.
          [(set (match_operand:SF 0 "general_operand" "=fr,frm,!*rf,!*rm")
	        (match_operand:SF 1 "general_operand" "frmG,fr,*rfm,*rfF"))]
  3. i386.h REG_CLASS_FROM_LETTER(C) should be like this.
       (C) == 'f' ? (TARGET_80387 ? FLOAT_REGS : NO_REGS) :		\
  4. unrelated to the above problem, but, 
   4.1 swapdf seems to need TARTGET_80387 as a condition.

-------------------i386sco.h(tm.h)---------------------------
#if 0 /* Not yet certain whether this is needed.  */
/* If no 387, use the general regs to return floating values,
   since this system does not emulate the 80387.  */

#undef VALUE_REGNO(MODE)
#define VALUE_REGNO(MODE) \
  ((TARGET_80387 && ((MODE) == SFmode || (MODE) == DFmode)) \
   ? FIRST_FLOAT_REG : 0)

#undef HARD_REGNO_MODE_OK(REGNO, MODE)
#define HARD_REGNO_MODE_OK(REGNO, MODE) \
  ((REGNO) < 2 ? 1							\
   : (REGNO) < 4 ? 1							\
   : (REGNO) >= 8 ? ((GET_MODE_CLASS (MODE) == MODE_FLOAT		\
		      || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT)	\
		     && TARGET_80387					\
		     && GET_MODE_UNIT_SIZE (MODE) <= 8)			\
   : (MODE) != QImode)
#endif
-------------------i386.md(md)---------------------------------
(define_insn "movsf"
  [(set (match_operand:SF 0 "general_operand" "=f,fm,!*rf,!*rm")
	(match_operand:SF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  ""
  "*
{
  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;

  /* First handle a `pop' insn or a `fld %st(0)' */
.
.
.
(define_insn "movdf"
  [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm")
	(match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))]
  ""
  "*
{
  int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0;
----------------------i386.h---------------------------------------
/* Get reg_class from a letter such as appears in the machine description.  */

#define REG_CLASS_FROM_LETTER(C)	\
  ((C) == 'r' ? GENERAL_REGS :		\
   (C) == 'q' ? Q_REGS :		\
   (C) == 'f' ? FLOAT_REGS :		\
   (C) == 't' ? FP_TOP_REG :		\
   (C) == 'u' ? FP_SECOND_REG :		\
   (C) == 'a' ? AREG :			\
   (C) == 'b' ? BREG :			\
   (C) == 'c' ? CREG :			\
   (C) == 'd' ? DREG :			\
   (C) == 'D' ? DIREG :			\
   (C) == 'S' ? SIREG : NO_REGS)
----------------------i386.md-----------------------------------
(define_insn "swapdf"
  [(set (match_operand:DF 0 "register_operand" "f")
	(match_operand:DF 1 "register_operand" "f"))
   (set (match_dup 1)
	(match_dup 0))]
  ""
  "*
{
  if (STACK_TOP_P (operands[0]))
    return AS1 (fxch,%1);
  else
    return AS1 (fxch,%0);
}")

******* 2nd part of bug report *********************************

  gcc-2.1 configured with " --host=sparc i386 " dies with following code
compiled with -O . This is the trimmed down version which reproduces 
this problem and the action of this program is useless.

----------------source------------------------------------------
union llval {	double		d;
		long long	ll;
	};

long long 
mincase(double x, int n)
{
	union llval val;

	val.d = x;
	if(n >= 0) {
		val.ll <<= 63;
	} else {
		val.ll += 1 << -n;
		val.ll >>= -n;
	}
	return val.ll;
}
---------------------------------------------------------------
gcc version 2.1
 /home/hando/gcc2/gcc-2.1/cpp -lang-c -v -undef -D__GNUC__=2 -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__sparc -D__sun -D__unix -D__OPTIMIZE__ mincase.c /usr/tmp/cca00280.i
GNU CPP version 2.1 (80386, ATT syntax)
 /home/hando/gcc2/gcc-2.1/cc1 /usr/tmp/cca00280.i -quiet -dumpbase mincase.c -O -version -o mincase.s
GNU C version 2.1 (80386, ATT syntax) compiled by CC.
mincase.c: In function `midcase':
mincase.c:18: internal error--unrecognizable insn:
(insn 38 37 39 (parallel[ 
           (set (reg:DI 31)
               (ashiftrt:DI (reg/v:DI 23)
                   (subreg:QI (reg:SI 25) 0)))
           (clobber (subreg:QI (reg:SI 30) 0))
       ] ) -1 (insn_list 34 (nil))
   (expr_list:REG_DEAD (reg/v:DI 23)
       (expr_list:REG_DEAD (reg:SI 25)
           (expr_list:REG_UNUSED (reg:SI 30)
               (nil)))))
gcc: Internal compiler error: program cc1 got fatal signal 6

***** 3rd part of bug report *******************************

  This program compiles OK without -O, but assmbler output has 
other problems.

------------------assembler output without -O ----------------
	.file	"mincase.c"
gcc2_compiled.:
.text
	.align 4
.globl mincase
mincase:
	pushl %ebp
	movl %esp,%ebp
	subl $8,%esp
	pushl %edi
	pushl %esi
	pushl %ebx
	fldl 8(%ebp)
	fstpl -8(%ebp)
	cmpl $0,16(%ebp)
	jl .L2
	movl -8(%ebp),%esi
	movl -4(%ebp),%edi
	movl %esi,%edi
	xorl %esi,%esi
	sal%edi $31,%edi    <-----strange code
	movl %esi,-8(%ebp)
	movl %edi,-4(%ebp)
	jmp .L3
	.align 4
.L2:
	movl 16(%ebp),%ecx
	negl %ecx
	movl $1,%ebx
	sall %cl,%ebx
	movl %ebx,%ecx
	sarl $31,%ecx
	movl %ebx,%eax
	movl %ecx,%edx
	movl %eax,%eax
	movl %edx,%edx
	addl %eax,-8(%ebp)
	adcl %edx,-4(%ebp)
	movl 16(%ebp),%ecx
	negl %ecx
	movl -8(%ebp),%esi
	movl -4(%ebp),%edi
	rorb $1,%cl
	shrdl %edi,%esi   <----- 386 gas does not like this format
	sarl %cl,%edi            it likes to have
	shrdl %edi,%esi          shrdl %cl, %edi, %esi
	sarl %cl,%edi            although %cl is redundant information
	shrb $7,%cl
	shrdl %edi,%esi
	sarl %cl,%edi
	movl %esi,-8(%ebp)
	movl %edi,-4(%ebp)
.L3:
	movl -8(%ebp),%eax
	movl -4(%ebp),%edx
	jmp .L1
	.align 4
.L1:
	leal -20(%ebp),%esp
	popl %ebx
	popl %esi
	popl %edi
	leave
	ret
*********** end of bug report ********************************

Newsgroups: gnu.gcc.bug