2016-08-31 31 views
0

Linaro gccを使用してARM GIC用の割り込みハンドラをコンパイルする際に、奇妙な結果が生じます。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 

したがって、SUBS割り込みから復帰するために使用される場合、ハンドラコードとPUSH {LR}/POPの内部には、サブルーチンありません{ pc}は、サブルーチンがある場合に使用されます。

問題は、SUBSは自動的にプロセッサIRQモードからSVCモードに切り替わりますが、POP {pc}は無効になります。したがって、SUBSを使用する必要があり、foo1に対しては、外部SUBS命令を追加してIRQからSVCモードに切り替える必要があります。

機能やバグはありますか?

コンパイラに毎回SUBSを強制的に使用させる方法はありますか?

+0

リナロの特定のリリースは? (FWIW古い13.11 arm-linux-gnueabihfバイナリを手にしても問題はありません)第2に、コンパイラ/アセンブラのオプションはどれですか?問題は、正しい(正確な)コンパイラ生成アセンブリの誤解のように見えますが、答えに対するあなたのコメントは他に何かを暗示しています。正確にここで何が起こっているのかを明確にするために質問に少し詳しく説明してください。 – Notlikethat

+0

arm-eabi-gcc -mfloat-abi = softfp -march = armv7-a -mcpu =皮質-a9-S機能セクション-fデータセクション arm-eabi-gcc(Linaro GCC53-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

私は参考文献を見つけることができませんが、pop {}LDM sp ..に相当します。これは現在のモードの SPSRがコピーされていることを示し

^PCをロードするLDM命令に対して:LDMについては、ARMのARM(A4.1.22 LDM(3))こと

を述べCPSRに提出する。

これは、生成されたpop命令がSPSRからCPSRを復元し、以前の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のコード生成のバグか、追加のコンパイルオプションを指定する必要がありますか? –

関連する問題