本文介绍了GCC内联大会SPARC架构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在互联网上找到:

#define LOCK_PREFIX "lock ; "

struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((struct __xchg_dummy *)(x))

static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
                  unsigned long new, int size)
{
   unsigned long prev;
   switch (size) {
   case 1:
      __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
                 : "=a"(prev)
                 : "q"(new), "m"(*__xg(ptr)), "0"(old)
                 : "memory");
      return prev;
   case 2:
      __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
                 : "=a"(prev)
                 : "q"(new), "m"(*__xg(ptr)), "0"(old)
                 : "memory");
      return prev;
   case 4:
      __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
                 : "=a"(prev)
                 : "q"(new), "m"(*__xg(ptr)), "0"(old)
                 : "memory");
      return prev;
   }
   return old;
}

#define cmpxchg(ptr,o,n)\
   ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
               (unsigned long)(n),sizeof(*(ptr))))

当我编译并使用此功能(CMPXCHG)为i386架构 - 所有的好!但是,当我在SPARC架构编译,我以下错误:

When I compile and use this function (cmpxchg) for i386 architecture - all good! But, when i compile under Sparc architecture, i've the following error:

error: impossible constraint in `asm'

这是什么问题?

推荐答案

在Solaris上,最好不要写自己的code本(既不在SPARC也不在x86);相反,使用为目的的功能:

On Solaris, better don't write your own code for this (neither on SPARC nor on x86); rather, use the atomic_cas(3C) functions for the purpose:

static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
              unsigned long new, int size)
{
    switch (size) {
    case 1: return atomic_cas_8(ptr, (unsigned char)old, (unsigned char)new);
    case 2: return atomic_cas_16(ptr, (unsigned short)old, (unsigned short)new);
    case 4: return atomic_cas_32(ptr, (unsigned int)old, (unsigned int)new);
#ifdef _LP64
    case 8: return atomic_cas_64(ptr, old, new);
#endif
    default: break;
    }
    return old;
}

这将用于Solaris做的。

That'll do for Solaris.

编辑:如果你绝对要内联这种事情,在SPARC(V8 +,又名的UltraSPARC)指令使用的是比较和交换,又名 CAS 。它总是原子(SPARC不知道锁prefixes)。它仅配备在32bit和64bit( CASX )的变种,从而使8 / 16bit的库函数执行32位的 CAS 掩蔽出非目标字/字节。我不会重复实现,帮助 - 这是不是一个好主意,使用库接口

if you absolutely have to inline this kind of thing, the SPARC (v8+, aka UltraSPARC) instruction to use is "compare and swap", aka CAS. It's always atomic (sparc doesn't know lock prefixes). It only comes in 32bit and 64bit (CASX) variants, so that the 8/16bit library functions perform 32bit CAS masking out the non-targeted word/bytes. I won't help with reimplementing that - it's not a good idea, use the library interfaces.

EDIT2:一些帮助,重新实现您的(如果你不能使用Solaris的libc链接)。

Some help with reimplementing you get by reading the sourcecode (if you cannot link with Solaris libc).

这篇关于GCC内联大会SPARC架构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 21:08