2016-08-31 8 views
0

При составлении обработчика прерываний для 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.

Это особенность или ошибка?

Можно ли заставить компилятор использовать СУБС каждый раз?

+0

Какой конкретный релиз Линаро? (FWIW У меня нет проблем с жесткими старыми 13.11 arm-linux-gnueabihf бинарниками) Во-вторых, какие параметры компилятора/ассемблера вы проходите? Вопрос as-выглядит как простое неправильное чтение (правильной) сборки, созданной компилятором, но ваши комментарии к ответу подразумевают что-то другое - добавьте немного подробней к вопросу, чтобы выяснить, что именно происходит здесь. – Notlikethat

+0

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} ^' –

+0

Проблема известна и исправлена ​​в ветке 6 https://gcc.gnu.org/ bugzilla/show_bug.cgi? id = 70830 –

ответ

1

Я не могу найти ссылку, но IIRC, pop {} эквивалентно LDM sp ...

Для LDM, то ARM ARM (A4.1.22 LDM (3)) говорится, что:

^Для инструкции LDM, которая загружает компьютер, это указывает на то, что СПСР текущего режима копируется к CPSR.

Именно поэтому сгенерированная команда pop восстанавливает CPSR из SPSR, поэтому возвращается в предыдущий режим CPU.

+0

Да, проблема не решена. 'pop {r0, r1, r2, r3, r4, fp, ip, pc}' инструкция 'e8bd981f'. 'pop {r0, r1, r2, r3, r4, fp, ip, pc} ^' инструкция также 'e8bd981f', но должна быть' e8fd981f'. –

+0

Итак, генерируется генерируемый LDM вместо LDM (возврат исключения). Является ли ошибка генерации кода GAS или должны быть указаны некоторые дополнительные параметры компиляции? –

 Смежные вопросы

  • Нет связанных вопросов^_^