Subject: port-m68k/35561: gcc-3.3.3 generates invalid assembly code on m68k platform
To: None <port-m68k-maintainer@netbsd.org, gnats-admin@netbsd.org,>
From: None <arthur@ilvsun3.com>
List: netbsd-bugs
Date: 02/07/2007 18:20:00
>Number:         35561
>Category:       port-m68k
>Synopsis:       gcc-3.3.3 generates invalid assembly code on m68k platform
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-m68k-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Feb 07 18:20:00 +0000 2007
>Originator:     arthur townsend
>Release:        3.0
>Organization:
>Environment:
3.0 for sun3
>Description:
Using the default gcc-3.3.3 under NetBSD 3.0 for Sun3, the following command:
gcc -save-temps -c -O2 art9.c

generates the error:
art9.s: Assembler messages:
art9.s:68: Error: operands mismatch -- statement 'move.b %a0,%d1' ignored.

The c source statement that causes the error is the "add192" line.  It is easy to see that the assembly line in question is indeed invalid (possibly the %a0 should be in parenthesis or move.b should be move.l).

The same problem occurs with gcc-3.2.3 running under SunOS 4.1.1.

typedef unsigned char tme_uint8_t;
typedef tme_uint8_t flag;
typedef signed char tme_int8_t;
typedef tme_int8_t int8;

typedef int __int32_t;
typedef __int32_t int32_t;
typedef signed int tme_int32_t;
typedef tme_int32_t int32;

typedef unsigned long long int tme_uint64_t;
typedef tme_uint64_t bits64;
typedef signed long long int tme_int64_t;
typedef tme_int64_t sbits64;

typedef struct {
  tme_uint64_t low;
  tme_uint64_t high;
} float128;

extern float128 roundAndPackFloat128( flag, int32, bits64, bits64, bits64 );

static inline void
 add192(
     bits64 a0,
     bits64 a1,
     bits64 a2,
     bits64 b0,
     bits64 b1,
     bits64 b2,
     bits64 *z0Ptr,
     bits64 *z1Ptr,
     bits64 *z2Ptr
 )
{ 
    bits64 z0, z1, z2;
    int8 carry0, carry1;
    z2 = a2 + b2;
    carry1 = ( z2 < a2 );
    z1 = a1 + b1;
    carry0 = ( z1 < a1 );
    z0 = a0 + b0;
    z1 += carry1;
    z0 += ( z1 < (bits64) carry1 );
    z0 += carry0;
    *z2Ptr = z2;
    *z1Ptr = z1;
    *z0Ptr = z0;
 
}

float128 float128_div( float128 a, float128 b )
{
    flag aSign, bSign, zSign;
    int32 aExp, bExp, zExp;
    bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
    bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
    float128 z;

    while ( (sbits64) rem0 < 0 ) {
        --zSig0;
        add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
    }

    return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 );

}

>How-To-Repeat:
Attempt to make TME from pkgsrc, or compile the above test case with -O2.

>Fix: