Yusuf Khan
Yusuf Khan

Reputation: 409

Atomic compare and exchange in arm assembly

I am trying to compile the arm inline assembly code for ARMV7 to compare and swap atomically, basically i have copied the code from ARM linux kernel but somehow it doesnt compile. it gives the below error

Erro: thumb conditional instruction should be in IT block -- strexeq r5,r1,[r3]. below is the code

static inline int
dfp_atomic32_cmpset(volatile uint32_t *dst, uint32_t exp, uint32_t src)
{

        unsigned long oldval, res;

        smp_mb();

        do {
                __asm__ __volatile__("@ dfp_atomic32_cmpset\n"
                "ldrex  %1, [%3]\n"
                "mov    %0, #0\n"
                "teq    %1, %4\n"
                "strexeq %0, %5, [%3]\n"
                    : "=&r" (res), "=&r" (oldval), "+Qo" (*dst)
                    : "r" (dst), "Ir" (exp), "r" (src)
                    : "cc");
        } while (res);

        smp_mb();

        return oldval;
}

Any idea what that error means?

Upvotes: 2

Views: 3453

Answers (1)

artless-noise-bye-due2AI
artless-noise-bye-due2AI

Reputation: 22420

You need to add an IT EQ instruction; see Thumb2 porting at the Ubuntu wiki. You are copying ARM code and trying to use it in thumb2 mode. All ARM instructions are conditional and the IT EQ is a phantom in ARM mode (not needed). In Thumb2 mode, you have to notify the process which condition should be tested for the following instructions.

It is possible that gcc inlines do not apply to -mimplicit-it; especially as the compiler needs to guess the number of op-codes to make it's own code. Ie, to calculate branch sizes, etc.

Upvotes: 3

Related Questions