《Arm Cortex-A7シミュレータ》

　Cortex-A7シミュレータは，最初，「おまけ」の位置づけでした．本誌でRISC-V，Cortex-M0のシミュレータを作った後，暇ができたので，Cortex-A7のシミュレータにもチャレンジしてみました．
　しかし，ArmのCortex-A（32ビット）に手を出すのは無謀でした．例によって，命令デコーダから作り始めたのですが，Armの命令の多さ，命令エンコーディングの複雑さを前にして，「やるんじゃなかった」と思ったことが何回もあります．何とか形になりました（多少のバグあり？）ので公開します．
　今回，改めて認識したArmの命令セット（Armv7-A）の特徴は以下になります．
（1）殆ど全ての命令が，条件フラグに従って実行を行う．
（2）殆ど全ての命令で，ソース・オペランドの片方をシフトできる．
（3）ロード/ストア命令のアドレッシングは，[bease + offset」だけでなく
　　[base + (register shift)]というインデックス機能がある．
（4）ロード/ストア命令で，ベース・レジスタを次のデータ用に更新できる．
　さて，このような仕様を実現するに当たり，他のシミュレータと大きく方針を変えたのは，ソース・オペランドのシフト機能を命令デコード時に行うことです．命令の実行時に，シフトを行ってから演算，シフトを行ってからアドレス計算というのは「美しくない」という判断です．このため，「decode.c」というファイルから「execute.c」の中にある「ISHIFT32()」という関数を呼び出しています．しかし，この手法には懸念点があります．Armの仕様ではシフト量が0以外のシフトにおいてはCフラグが変わってしまいます．また，シフト実行時にはCフラグを変更しないといけません．そこで、命令デコード時のシフト操作においてもCフラグを変更しています．しかし，Armではデコードした命令が必ずしも実行されません．そうです，条件実行という，命令で指定してある条件に条件フラグの状態が一致した時のみ命令を実行するという機能があります．この条件実行で「実行されない時」は，命令デコード時に変更したCフラグの値は元に戻さなければなりません（多分）．流石にその機能は実装していません．
　とにかく，このシミュレータはデコード部を作成してから1ヵ月放置してありました．あまりの複雑さに嫌気が差したのですが，本業が少し暇になったので，続きを作ることにしました．命令デコーダの次は逆アセンブラの作成ですが，これも命令デコーダと同じ位コーディングに時間がかかりました．
　今回のシミュレータの開発方針として「コンパイラが出力しない命令はサポートしない」ことを大前提としています．そういう制限の下でも，命令デコーダや逆アセンブラの作成にはかなりの時間を要しました．命令実行部は1日程度で完成しました．その後が，Dhrystoneベンチマーク，Stanfordベンチマーク，Coremarkを使ってデバッグです．
　ここであらかじめ誤っておきます．このシミュレータは完全にはデバッグが終わっていません．DhrystoneベンチマークはPASSするのですが、Stanfordベンチマークは最適化レベル1の時にPASSしません．最適化レベルで0（最適化なし）と2ではPASSしたのですが，結局，PASSしない理由がわかりませんでした．Coremarkに至っては最適化なしの場合しかPASSしていません．まあ，そんな程度の品質であることをご承知おきください．内心は，コンパイラがバグっているなんて思ってもいるですが…
　今回のコンパイラはArm Embeddedのコンパイラを使用しました．Cortex-M0のシミュレータ作成の時も紹介しましたが，以下のURLからダウンロードできます．
https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads
コンパイルオプションは「-mcpu=cortex-a7」です．最初は「-march=armv7-a」も同時につけていたのですが，この場合，割り算命令がサブルーチンで処理されます．それでも，割り算ルーチンがArmのネイティブ・コードなら問題ないのですが，なんと，割り算ルーチンはThumb命令で記述されています．「-march=armv7-a」オプションを削除するとちゃんと「SDIV命令」をコンパイラが出力するようになりました．
　RISC-V，SH-2，R3000，V850，Cortex-M0，Cortex-A7とシミュレータを作ってきましたが，ここで少しひらめきました．ここまで来たらArmv8-Aのシミュレータも作ってしまおうと思いました．Armアーキテクチャ・マニュアルをみると，Armv8-AはArmv7-Aより単純に思えました．そこで，本誌の連載を，最初はRISC-Vに重きを置いていたのですが，RISC-VとArmのシミュレータで，それぞれのアーキテクチャの違いを学ぶというように方針転換しました．プラットフォームは基本的にWindowsでやりたいので，Windowsで動作するArmv8-A（AArch64）のGCCを探したところ，Linaroのページからダウンロードできることが判明しました．これで，新方針で原稿が書けます．Armv8-Aのシミュレータに関しては，Cortex-A53シミュレータの解説を参照してください．

