優れた 68k アセンブリ プログラマーはいますか?? Motorola 68040 用に商用の Green Hills コンパイラを使用していますが、コードから非常に奇妙な動作が見られます。場合によっては、コードが if/else 比較を行い、間違った分岐を取ることがあります。例えば:
float a = 1, b = 2;
if (a < b)
do c;
else
do d;
コードは時々 d!? になります。このエラーが発生するたびに、比較を中断する特定の ISR が常に 1 つあります。ISR 用に生成されたアセンブリを調べたところ、意味をなさないものがいくつかありました。まず、浮動小数点ステータス レジスタ、FPSR、FPCR、および FPIAR が ISR に保存されていないようです。これは、if/else が間違った分岐を取っている理由を説明します。FPSR レジスタは比較の結果を決定するために使用され、そのレジスタが ISR で上書きされた場合、分岐は間違ったパスを取る可能性があります。以下は、コンパイラーによって生成された入り口と出口のアセンブリーです。
isr_function:
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
; isr code ...
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FRESTORE (%SP)+
RTE
Programmer's Reference Manual を調べましたが、FSAVE または FMOVEM が FP ステータス レジスタを保存することを示唆するものは見つかりません。実際、「FSAVE はプログラマの浮動小数点ユニットのモデル レジスタを保存しません。マシンのユーザーの目に見えない部分だけを保存します。」というコメントを見ました。そのため、ISR の開始時にレジスタを保存し、最後に復元するために独自のアセンブリを追加しました。これにより、パフォーマンスが劇的に改善されましたが、まだいくつかの問題が見られます。以下は私が行った追加です。C コードでは、バックアップ変数は unsigned long として入力されます。
isr_function:
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
FMOVE %FPIAR,fpiar_backup
FMOVE %FPSR,fpsr_backup
FMOVE %FPCR,fpcr_backup
; isr code ...
FMOVE fpiar_backup,%FPIAR
FMOVE fpsr_backup,%FPSR
FMOVE fpcr_backup,%FPCR
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FRESTORE (%SP)+
RTE
レジスターを保存しないことで、コンパイラーに実際にバグがあるとは信じられませんでした。そこで、FPx と Dx の値を調べて、それらが適切な値に復元されていることを確認しましたが、そうではないようです。ただし、アセンブリ コードに変更を加えていないということは 100% ではありません。以下は、レジスタを保存するために追加したコードです。デバッグ変数は unsigned long として入力されます。
isr_function:
FMOVE %FP0,debug3
FMOVE %FP1,debug5
FMOVE %FP2,debug7
FMOVE %FP3,debug9
FMOVE %FP4,debug11
FMOVE %FP5,debug13
FMOVE %FP6,debug15
FMOVE %FP7,debug17
FMOVE %FPCR,debug19
FMOVE %FPIAR,debug23
FMOVE %FPSR,debug25
FSAVE -(%SP)
LINK %A6,#-192
MOVEM.L %D0/%D1/%D2/%A0/%A1,-(%SP)
FMOVEM %FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7,-(%SP)
; isr code ...
FMOVEM -308(%A6),%FP0/%FP1/%FP2/%FP3/%FP4/%FP5/%FP6/%FP7
MOVEM.L -212(%A6),%D0/%D1/%D2/%A0/%A1
UNLK %A6
FMOVE %FP0,debug4
FMOVE %FP1,debug6
FMOVE %FP2,debug8
FMOVE %FP3,debug10
FMOVE %FP4,debug12
FMOVE %FP5,debug14
FMOVE %FP6,debug16
FMOVE %FP7,debug18
FMOVE %FPCR,debug20
FMOVE %FPIAR,debug24
FMOVE %FPSR,debug26
FRESTORE (%SP)+
RTE
要するに、私の質問は、
1) FPSR、FPCR、および FPIAR レジスターを保存しないという点で、生成されたアセンブリーに問題がありますか?
2) ISR に出入りするときに、レジスタの値を適切に保存していますか?
比較する別のコンパイラがあれば、それは素晴らしいことです。残念ながら、デバッガーをコードにアタッチできません。私は C/C++/C#/Java/Python/PHP などの経験が豊富ですが、アセンブリの専門家にはほど遠いです。
どんなアイデアでも大歓迎です!