【问题标题】:compiling error "impossible constraint in 'asm'"编译错误“'asm' 中的不可能约束”
【发布时间】:2015-04-26 17:05:54
【问题描述】:

我尝试在我的“SunOS sun4v 5.10”系统上编译 Csmith,但出现如下错误:

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

谁能告诉错误在哪里?

#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();
}

【问题讨论】:

  • 有助于了解第 78 行,或者至少知道您使用的是什么架构,这样我们就可以决定正在编译哪个 asm 块。
  • 几乎可以肯定是最后一个asm 块;第一个用于 PowerPC,这似乎不太可能,第二个用于 MSVC,不会生成该错误消息。
  • @Jester line 78 is asm volatile( "rdtsc\n\t" : "=A" (l) ); 我尝试在我的系统中编译一个名为 csmith 的测试工具。谢谢。
  • 什么架构?我想原作者应该更小心使用#else ...
  • @Jester SunOS sun4v 5.10

标签: gcc assembly solaris inline-assembly


【解决方案1】:

问题在于,您尝试编译的代码假定任何不是 PowerPC 的目标 CPU 都必须是 x86 处理器。该代码根本不支持您的 SPARC CPU。

幸运的是,该代码似乎并不重要,它显然仅用于播种随机数生成器,然后用于创建随机 C 程序。目标是防止同时启动的程序的多个实例生成相同的随机程序。我会用不依赖于 CPU 的更便携的东西替换代码。像这样的:

#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 */

代码已在 Linux 和 Windows 上单独测试。它也应该在 Solaris SPARC 上单独工作,但我不知道它在实际程序的上下文中工作得如何。

【讨论】:

    猜你喜欢
    • 2010-12-01
    • 2012-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    相关资源
    最近更新 更多