简体   繁体   中英

compiling error “impossible constraint in 'asm'”

I tried to compile Csmith on my "SunOS sun4v 5.10" system, but I got errors like these:

platform.cpp: In function 'long unsigned int platform_gen_seed()':
platform.cpp:78: error: impossible constraint in 'asm'

Could anyone tell where is the mistake?

#if (TARGET_CPU_powerpc == 1 || TARGET_CPU_powerpc64 == 1)
/*For PPC, got from:
http://lists.ozlabs.org/pipermail/linuxppc-dev/1999-October/003889.html
*/
static unsigned long long read_time(void) {
    unsigned long long retval;
    unsigned long junk;
    __asm__ __volatile__ ("\n\
1:  mftbu %1\n\
    mftb %L0\n\
    mftbu %0\n\
    cmpw %0,%1\n\
    bne 1b"
    : "=r" (retval), "=r" (junk));
    return retval;
}
#else
#ifdef WIN32
static unsigned __int64 read_time(void) {
        unsigned l, h;
        _asm {rdtsc    
        mov l, eax  
        mov h, edx 
        }
        return (h << 32) + l ;
}
#else
static long long read_time(void) {
        long long l;
        asm volatile(   "rdtsc\n\t"
                : "=A" (l)
        );
        return l;
}
#endif
#endif

unsigned long platform_gen_seed()
{
    return (long) read_time();
}

The problem is that the code you're trying to compile assumes that any target CPU that's not a PowerPC must be an x86 processor. The code simply doesn't doesn't support your SPARC CPU.

Fortunately the code doesn't seem to be critical, it's apparently only used to seed a random number generator, which is then used to create random C programs. The goal being to prevent multiple instances of the program that are started at the same time from generating the same random programs. I'd replace the code with something more portable that's not dependent on the CPU. Something like this:

#ifdef WIN32

unsigned long platform_gen_seed()
{
    LARGE_INTEGER now;
    QueryPerformanceCounter(&now);
    return now.LowPart;
}

#else /* assume something Unix-like */

static unsigned long generic_gen_seed() {
    pid_t pid = getpid();
    time_t now;
    time(&now);
    return (unsigned long)(now ^ (pid << 16 | ((pid >> 16) & 0xFFFF)));
}

#ifdef CLOCK_REALTIME

unsigned long platform_gen_seed()
{
    struct timespec now, resolution;
    if (clock_gettime(CLOCK_REALTIME, &now) == -1
        || clock_getres(CLOCK_REALTIME, &resolution) == -1
            || resolution.tv_sec > 0 || resolution.tv_nsec > 1000000) {
        return generic_gen_seed();
    }
    return (now.tv_nsec / resolution.tv_nsec
        + now.tv_sec * resolution.tv_nsec);
}

#else 

unsigned long platform_gen_seed()
{
    return generic_gen_seed();
}

#endif /* CLOCK_REALTIME */

#endif /* WIN32 */

The code has been test in isolation on Linux and Windows. It should also work in isolation on Solaris SPARC, but I don't know how well it work in context of the actual program.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM