Es gibt ein seltsames Ergebnis beim Kompilieren von Interrupt Handler für ARM GIC mit Linaro GCC.ARM GIC Interrupt-Handler von Linaro GCC
Der Code ist:
void foo1(void) __attribute__((interrupt("IRQ")));
void foo2(void) __attribute__((interrupt("IRQ")));
void foo1() {
dummy();
return;
}
void foo2() {
return;
}
Das Ergebnis Assemblercode:
foo1:
sub lr, lr, #4
push {r0, r1, r2, r3, r4, fp, ip, lr}
add fp, sp, #28
bl dummy
nop
sub sp, fp, #28
pop {r0, r1, r2, r3, r4, fp, ip, pc}^
foo2:
str fp, [sp, #-4]!
add fp, sp, #0
nop
sub sp, fp, #0
ldr fp, [sp], #4
subs pc, lr, #4
So wird SUBS verwendet, um Rückkehr von der Unterbrechung, wenn keine Subroutinen innerhalb Handler-Code und PUSH {lr}/POP { pc} wird verwendet, wenn ein Unterprogramm vorhanden ist.
Das Problem ist, dass SUBS automatisch von Prozessor IRQ-Modus in SVC-Modus wechseln, aber POP {pc} nicht. Also sollte SUBS verwendet werden und für foo1 ist es notwendig, einen externen SUBS-Befehl hinzuzufügen, um vom IRQ- zum SVC-Modus zu wechseln.
Ist es Feature oder Bug?
Gibt es eine Möglichkeit, Compiler zu zwingen, SUBS jedes Mal zu verwenden?
Welche spezifische Linaro-Version? (FWIW Ich sehe kein Problem mit den knorrigen alten 13.11 arm-linux-gnueabihf Binaries zur Hand) Zweitens, welche Compiler/Assembler-Optionen gibst du weiter? Die Frage, wie sie aussieht, sieht wie ein einfaches Fehllesen der (korrekten) vom Compiler generierten Assembly aus, aber Ihre Kommentare zu der Antwort implizieren etwas anderes - bitte fügen Sie der Frage etwas mehr Detail hinzu, um zu klären, was genau hier vor sich geht. – Notlikethat
arm-eabi-gcc-mfloat-abi = softfp -march = armv7-a-mcpu = Kortex-a9 -S-Funktionsabschnitte -fdata-Abschnitte arm-eabi-gcc (Linaro GCC 5.3-2016.02) 5.3.1 20160113 Der 'pop {r0, r1, r2, r3, r4, fp, ip, pc} ^' wird erzeugt, ist aber nicht korrekt. Es scheint, dass es sein sollte "ldm \t sp !, {r0, r1, r2, r3, r4, fp, ip, pc} ^' –
Das Problem ist bekannt und in Zweig 6 https://gcc.gnu.org/ bugzilla/show_bug.cgi? id = 70830 –