При составлении обработчика прерываний для ARM GIC при использовании Linaro gcc возникает странный результат.ARM GIC Обработчик прерываний от Linaro GCC
Код:
void foo1(void) __attribute__((interrupt("IRQ")));
void foo2(void) __attribute__((interrupt("IRQ")));
void foo1() {
dummy();
return;
}
void foo2() {
return;
}
Код результата ассемблер:
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
Итак, ПЕРЕВОДНИКИ используется для возврата из прерывания, если нет Подпрограммы внутри кода обработчика и PUSH {Lr}/POP { pc} используется, если есть какая-либо подпрограмма.
Проблема заключается в том, что SUBS автоматически переключается из режима IRQ процессора в режим SVC, но POP {pc} - нет. Таким образом, SUBS следует использовать, и для foo1 необходимо добавить внешнюю инструкцию SUBS для переключения из режима IRQ в SVC.
Это особенность или ошибка?
Можно ли заставить компилятор использовать СУБС каждый раз?
Какой конкретный релиз Линаро? (FWIW У меня нет проблем с жесткими старыми 13.11 arm-linux-gnueabihf бинарниками) Во-вторых, какие параметры компилятора/ассемблера вы проходите? Вопрос as-выглядит как простое неправильное чтение (правильной) сборки, созданной компилятором, но ваши комментарии к ответу подразумевают что-то другое - добавьте немного подробней к вопросу, чтобы выяснить, что именно происходит здесь. – Notlikethat
arm-eabi-gcc -mfloat-abi = softfp -march = armv7-a -mcpu = cortex-a9 -S -function-sections -fdata-sections arm-eabi-gcc (Linaro GCC 5.3-2016.02) 5.3.1 20160113 Генерируется 'pop {r0, r1, r2, r3, r4, fp, ip, pc} ^', но это неверно. Кажется, что это должно быть 'ldm \t sp !, {r0, r1, r2, r3, r4, fp, ip, pc} ^' –
Проблема известна и исправлена в ветке 6 https://gcc.gnu.org/ bugzilla/show_bug.cgi? id = 70830 –