2
votes

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?

1
yes, i figured that out but instead of IT EQ, i am using a cheat at the gcc assembler level. i.e. Wa,-mimplicit-it=always, do you see any problem with this other than compatibility ?Yusuf Khan
Actually i figured out the answer after i posted the question, i was in bit hurry to find out the answer ;-). Error is due to "In Thumb-2, most instructions to not have a built in condition code (except for conditional branches). Instead, short sequences of instructions which are to be executed conditionally can be preceded by a special "IT instruction"" This site explains it well wiki.ubuntu.com/ARM/Thumb2PortingHowto#Types . BTW i still would like to accept your answer, let me figure out how to accept ;-)Yusuf Khan
I know I sound like a broken record with this, but...ARM quite clearly states that chip vendors do not have to support the exclusive access (strex/ldrex). Linux quite often gets ARM details wrong in particular uses the wrong atomic (strex/ldrex vs swp) as a general rule. Just beware of this, esp if you are changing chips.old_timer
@dwelch: i am looking for fast atomic operation to build highly optimized multithread safe library, definitely its a trade off between performance and portability.Yusuf Khan
Sure, that is fine, strex/ldrex are for exclusive access to shared memory ranges in a multi-core arm chip.old_timer

1 Answers

3
votes

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.