SSブログ
English Version

独自言語 picle のコンパイラ化(その2) [PIC]

 セルフコンパイラ化するための方法として 独自言語の検討(その2)では一足飛びに PIC24 のマシン語を出力するのはディバッグが大変なので、一旦簡易バイトコード出力し、VM上で動作させた上でバイトコード出力部を PIC24 のマシン生成処理に変えるというように二段階の方がいいのかもしれないというようなことを書きました。
 ディバッグが大変と考えた大きな理由の1つは、現状の私の環境では実機上でステップ動作ができない(pickit2ではMPLABXのPIC24環境でブレークやステップ動作ができないorz)からです。
 ステップ動作ができないのでディバッグ効率がかなり悪い(特にマシン語)のです。 OneBitLoader(ブートローダー)もほぼ机上ディバッグで作りましたがプログラムステップが短かったのでなんとかなりました。

 今回は、pickit3 を購入する(まぁあまり高いものでもないし)ことでディバッグ環境を改善し、一足飛びに PIC24 のマシン語を出力することにします。(ステップ動作ができれば問題ありません^^)。

 昔はZ80でハンドアセンブルしていたので GAME80 コンパイラのソースを見ていると生成しているマシン語の処理が判りますが、PIC24FJ では流石にそういうわけには行かないのでセルフコンパイラ化するためにはアセンブラのサブセット機能が必要になります。
 インラインアセンブラを使えるかもしれませんが、引数の渡し方が使いづらかったこととコンパイラで使用する命令は数が限られていること及びそもそもコンパイラでは動的にマシンコードを生成する必要があり何かしらの仕掛けが必要となるのでインラインアセンブラは使用しないことにしました。

 そこで次のような方法でコード生成処理を作る予定です。
 また、当初は1パスのコンパイラにする予定でしたが、Flashメモリへの書込み回数を減らすためエラーチェックでパスしたらFlashメモリへ書込む2パス方式にします。

  1. マクロで簡易アセンブラを実現する。
     プリプロセッサのマクロでアセンブリ命令を定義します。ニーモニックは名前が重ならないように適当に変えます。

     例 MOV_lit16_Wd(lit16,reg)のみ実装した状態
       使用例:MOV_lit16_Wd(0x1234,W(2))
    
      #define ASSEM
    
      #define W(n) (n)    // n=0..15
    
      #ifdef ASSEM
       #define DISP(fmt,p0,p1,p2) printf("\n%04x : ",Flash);printf(fmt,p0,p1,p2);
      #else
       #define DISP(fmt,p0,p1,p2)
      #endif
    
      #define FWRITE( code ) FlashWrite( Flash, code )
      #define COND if( Pass == 0 )
    
      // アセンブリ命令
      #define MOV_lit16_Wd(lit16,reg) COND {DISP("MOV #%d,W%d",lit16,reg,0);} else \
              {FWRITE(0x200000|(lit16<<4)|reg);} Flash+=2;
    
    

  2. picleソースのインタープリット部をマシン語生成処理に変える。
    まずは1パス目で出力されるニーモニックを確認し、picleソースの内容を実現できているか机上確認する。
    ★2016/03/24 追記
    上記1項のDISP()でフォーマット内に含まれる参照変数の数と実際の引数の数をCコンパイラがチェックしてくれる(一致しない場合warning)ので引数の数毎に4通りのDISPマクロを作成するようにした。また、その3 で書いたように前方参照アドレス解決のためにニーモニックは2パス目で表示するように変更した。

  3. 生成されたコードが1パス目で表示されたニーモニックとあっているかを確認する。
    意味的には簡易アセンブラ機能の動作確認ということになります。

  4. フラッシュ上での動作確認
    フラッシュメモリ上に生成されたマシン語をステップ動作でpicleソース通りの動作をしているか確認する。

  5. 最後に1の「#define ASSEM」行をコメントアウトしリコンパイルする。
    コメントアウトすることでニーモニック出力部分が削除され、かつ printf() もリンクされなくなるのでコンパイラのサイズが小さくなる。

[TOP] [ 前へ ] 連載記事 [ 次へ ]

nice!(0)  コメント(0)  トラックバック(2) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 2