Встроенные ограничения asm GCC, конфликтующее распределение регистров - PullRequest
1 голос
/ 11 апреля 2011

Я сделал некоторый встроенный в ARM код ассемблера.
Глядя в Semaphore.s, я вижу, что gcc использует регистр r3 для обеих переменных: «success» и «change».Интересно, есть ли проблема с моими ограничениями?
Первые наиболее важные строки кода:

asm inline:

"1: MVN %[success], #0 @ success=TRUE=~FALSE\n\t"
"LDREX   %[value], %[signal] @ try to get exclusive access\n\t"
"ADDS    %[newValue], %[value], %[change]   @ new value = value + change\n\t"

ограничений:

: [signal] "+m" (signal), [success] "=r" (success), [locked] "=r" (locked), [newValue] "=r" (newValue), [value] "=r" (value)
: [borderValue] "r" (borderValue),  [change] "r" (change)
: "cc"

символfile:

1: MVN  r3, #0 @ success=TRUE=~FALSE
LDREX   r0, [r7, #12] @ try to get exclusive access
ADDS    r1, r0, r3  @ new value = value + change

Больше источника и сгенерированного символа ниже.

BOOLEAN Semaphore_exclusiveChange (INT32U * signal, INT32S change, INT32U borderValue)
{
BOOLEAN success;
INT32U locked;// exclusive status
INT32U newValue;
INT32U value;

asm (
"1: MVN %[success], #0 @ success=TRUE=~FALSE\n\t"
"LDREX   %[value], %[signal] @ new to get exclusive access\n\t"
"ADDS    %[newValue], %[value], %[change]   @ new value = value + change\n\t"
"ITE MI @ if (new value<0) \n\t"
" SUBSMI %[newValue], %[newValue] @ (new value<0): new value=0, set zero flag \n\t"
"@ else\n\t"
" CMPPL %[newValue], %[borderValue]  @ (new value>=0): if new value > border value \n\t"
"\n\t@ zero flag is either: new value=0 or =bordervalue\n\t"
"ITE HI @ if new signal level > border value \n\t"  //
" MOVHI     %[success], #0 @ fail to raise signal, success=FALSE \n\t"
"\t@ else\n\t"
" MOVLS     %[value], %[newValue] @ use new value \n\t" // ok
"STREX  %[locked], %[value], %[signal] @ new exclusive store of value\n\t"
"TST %[locked],%[locked] @ is locked? \n\t"
"IT NE @ if locked \n\t"
"BNE 1b @ try again\n\t"
"DMB    @ memory barrier\n\t"   //

: [signal] "+m" (signal), [success] "=r" (success), [locked] "=r" (locked), [newValue] "=r" (newValue), [value] "=r" (value)
: [borderValue] "r" (borderValue),  [change] "r" (change)
: "cc"  );
return success;
}

Соответствующий текст из файла символов:

Semaphore_exclusiveChange:
.LFB2:
    .loc 1 10 0
    @ args = 0, pretend = 0, frame = 32
    @ frame_needed = 1, uses_anonymous_args = 0
    @ link register save eliminated.
    push    {r7}
.LCFI0:
    sub sp, sp, #36
.LCFI1:
    add r7, sp, #0
.LCFI2:
    str r0, [r7, #12]
    str r1, [r7, #8]
    str r2, [r7, #4]
    .loc 1 16 0
    ldr r2, [r7, #4]
    ldr r3, [r7, #8]
@ 16 "../drivers/Semaphore.c" 1
    1: MVN  r3, #0 @ success=TRUE=~FALSE
    LDREX   r0, [r7, #12] @ new to get exclusive access
    ADDS    r1, r0, r3  @ new value = value + change
    ITE MI @ if (new value<0) 
     SUBSMI r1, r1 @ (new value<0): new value=0, set zero flag 
    @ else
     CMPPL  r1, r2  @ (new value>=0): if new value > border value 

    @ zero flag is either: new value=0 or =bordervalue
    ITE HI @ if new signal level > border value 
     MOVHI      r3, #0 @ fail to raise signal, success=FALSE 
        @ else
     MOVLS     r0, r1 @ use new value 
    STREX   r2, r0, [r7, #12] @ new exclusive store of value
    TST r2,r2 @ is locked? 
    IT NE @ if locked 
    BNE 1b  @ try again
    DMB @ memory barrier

@ 0 "" 2
    .thumb
    strb    r3, [r7, #19]
    str r2, [r7, #20]
    str r1, [r7, #24]
    str r0, [r7, #28]
    .loc 1 38 0
    ldrb    r3, [r7, #19]   @ zero_extendqisi2
    .loc 1 39 0
    mov r0, r3
    add r7, r7, #36
    mov sp, r7
    pop {r7}
    bx  lr

1 Ответ

0 голосов
/ 11 апреля 2011

Вы должны ограничить "успех" далее с помощью '&':

: [signal] "+m" (signal), [success] "=&r" (success), [locked] "=r" (locked), [newValue] "=r" (newValue), [value] "=r" (value)

, который помечает его как «ранний клоббер». В противном случае компилятор будет считать, что все выходы генерируются после того, как все входы использованы, и может использовать один и тот же регистр для разных выходов и входов. Если у вас есть значение «вход / выход», вам нужно использовать ограничение «повторяющееся значение».

...