0

I'm trying cross-compile MongoDB to a custom Linux. It compiles fine with Linux, but when using the cross compiler toolchain, it complains about this code.

static T compareAndSwap(volatile T* dest, T expected, T newValue) {
       T result = expected;
       asm volatile ("push %%eax\n\t"
                      "push %%ebx\n\t"
                      "push %%ecx\n\t"
                      "push %%edx\n\t"
                      "mov (%%edx), %%ebx\n\t"
                      "mov 4(%%edx), %%ecx\n\t"
                      "mov (%%edi), %%eax\n\t"
                      "mov 4(%%edi), %%edx\n\t"
                      "lock cmpxchg8b (%%esi)\n\t"
                      "mov %%eax, (%%edi)\n\t"
                      "mov %%edx, 4(%%edi)\n\t"
                      "pop %%edx\n\t"
                      "pop %%ecx\n\t"
                      "pop %%ebx\n\t"
                      "pop %%eax\n"
                       :
                       : "S" (dest),
                         "D" (&result),
                         "d" (&newValue)
                       : "memory", "cc");
       return result;
}

The compiler error is as below.

_party/js-1.7 -Isrc/third_party/js-1.7 src/mongo/bson/oid.cpp
src/mongo/platform/atomic_intrinsics_gcc.h: In member function 'void mongo::OID::initSequential()':
src/mongo/platform/atomic_intrinsics_gcc.h:123:44: error: impossible constraint in 'asm'
src/mongo/platform/atomic_intrinsics_gcc.h:123:44: error: impossible constraint in 'asm'
scons: *** [build/linux2/cc_gcc/cxx_toolchain-c++/mongo/bson/oid.o] Error 1
scons: building terminated because of errors.

The complained line 123:44 is end of the the line before : "memory", "cc");

Was also looked at the other parts of the code, which compiled asm code, was also looks similar. do not know what happened with this one.

Please advice what's wrong with this.

codester_09
  • 5,622
  • 2
  • 5
  • 27
NoAIUser
  • 3,966
  • 6
  • 34
  • 52
  • BTW, this is super nasty inline asm. Normally you'd tell the compiler (using clobbers) about what registers you modify, instead of putting push/pop instructions inside the asm template. The asm template string should be just once instruction, `"lock cmpxchg8b %[dest]\n\t"` with a `"+m"(*dest)` memory operand, and in/out constraints to describe the rest of it. – Peter Cordes May 25 '22 at 05:20

1 Answers1

1

Try using the __sync_val_compare_and_swap GCC intrinsic here.

Due to the F00F bug the lock cmpxchg8b is invalid. I guess you're using something like i586-linux-gcc toolchain and thus you're getting right into this Pentium's problem.

More workarounds may follow if you tell us the exact hardware for you custom linux kernel.

Viktor Latypov
  • 14,289
  • 3
  • 40
  • 55
  • 'Intel(R) Core(TM)2 Quad CPU Q9300 @ 2.50GHz' 64 bit processor. Linux version 3.5.3-1.fc17.i686.PAE (mockbuild@) (gcc version 4.7.0 20120507 (Red Hat 4.7.0-5) (GCC). This is the only information I can get. Doesn't know how to use __sync_val_compare_and_swap as I am a novice here. – NoAIUser Sep 24 '12 at 20:05
  • Tried compiling using __sync_val_compare_and_swap. It has compiled that piece of code. But at the end it complains "undefined reference to __sync_val_compare_and_swap_8". Doesn't understand why it is adding _8 at the end. Is there any way to solve this? Thanks in advance – NoAIUser Sep 25 '12 at 22:21
  • There's an answer on SO: http://stackoverflow.com/questions/9329020/undefined-reference-to-sync-val-compare-and-swap-4-error-at-compilation-usi – Viktor Latypov Sep 25 '12 at 23:24