独自言語 picle のコンパイラ化(その4) [PIC]
picle言語 のPIC24FJ用セルフコンパイラの製作を進めています。問題点や状況などを少し書いておきます。
[TOP] [ 前へ ] 連載記事 [ 次へ ]
- 環境等の問題
- アプリからのフラッシュ書込未反映
MPLABX + Pickit3 環境ではテーブルアクセス(TBLWR)を使ってアプリケーションでフラッシュメモリに書き込んだ結果がMPLABX の「Program Memory」に反映されません orz
念のため MPLABX を最新版(Ver3.26)にして見ましたが状況は同じでした。
初めは書込み方法が悪いのかと思い、アプリ側を何度も確認しましたがアプリ側の処理は問題無いようにしか見えません^^;
MPLABX の「Program Memory」で見えないだけで実際にはフラッシュへの書込みができていることに気づきました orz
従ってディバッグモードを継続したままで生成したマシン語部分をステップ動作させることができません orz
一旦、ディバッグモードから抜けた後、PIC からフラッシュメモリを吸上げて、開始アドレス指定してステップ動作させることは可能です(めんどいですが・・)
- CP命令の byte サイズ指定ビット
「16-bit MCU and DSC Programmer’s Reference Manual((C) 2005-2011 Microchip Technology Inc.)」では下記のように書かれていますが、 MPLABX の「Program Memory」でのニーモニック表示では マシン語コード:0xE1801D のニーモニックが CPB W0,[W13] と表示されます。
確認のためにCP命令をアセンブラにかけてみると
000000 1D 80 E1 cpb W0,[W13]
000002 1D 00 E1 cp W0,[W13]
となり、MPLABX の方が正解でしたw。今後、リファレンスマニュアルの完成度も考慮して作業を進めていく必要がありそうです。
(マイクロチップ社のエラータに記載済みか否かは未確認です)
CP part of the Reference Manual
- 配列要素のアドレス
除算の余りがうまく設定されなかったので調査した結果、Cコンパイラの挙動に不思議な点がありました。
使用しているCコンパイラは XC16 1.26 (A) です。
#define MODULO_IDX 1
#define Modulo_ VarVal[MODULO_IDX]
こんな感じで define し、
MOV_Ws_f16( W(1), (WORD)(&Modulo_) );
でW1が保存される先が、0x08d4 でした。 VarVal のアドレスは 0x882 なので変なアドレスに保存されています。
MOV_Ws_f16( W(1), (WORD)&Modulo_ );
のように括弧を取ってみたら 期待通りに 0x0884 にW1が保存されました。
C言語の演算子の優先順位は高い順に
添字演算子[] > アドレス演算子& > キャスト演算子()
なので括弧の有無は影響しないはずなのですが・・
因みに 上記ニーモニックのマクロ定義は
#define MOV_Ws_f16(Ws,freg) COND {DISP2("MOV W%d,[%xh]",Ws,freg); COND2 \
FWRITE(0x880000|(((long)freg<<3)&0x7fff0)|Ws);} Flash+=2;
です。
★2016/03/28 追記 {
下記の「2.コンパイル時の最適化」の改善前後で比較すると改善後の変数のアドレスが 0x50 だけ小さくなっていて上記のズレと一致します。上記のズレはCコンパイラ自身ではなく、makeかリンク機能に起因している可能性があります。そう仮定すると上記の括弧削除は関係なかったことになります・・・(たまに「Cleaning and Build Project」を実行した方が良さそうです)
}
- レジスタのアドレスモード(一般的な呼称は「アドレッシングモード」)
MOV命令等、多くのマシン語コード内に「レジスタのアドレスモード」を指定する3ビットのビットフィールドがありますが、この値とアドレッシングモードとの具体的な対応が「16-bit MCU and DSC Programmer’s Reference Manual」には見当たりませんでした。
アセンブラで確認してみれば直ぐわかることなのですが確認結果を記載しておきます。
(「7」の場合の動作に興味が沸いてきますねw)
// addressing mode value #define ADRS_MODE_DIR 0 // W direct #define ADRS_MODE_INDIR 1 // [W] indirect #define ADRS_MODE_POST_DEC 2 // [W--] post dec #define ADRS_MODE_POST_INC 3 // [W++] post inc #define ADRS_MODE_PRE_DEC 4 // [--W] pre dec #define ADRS_MODE_PRE_INC 5 // [++W] pre inc #define ADRS_MODE_BASE 6 // [W+Wb] indirect with base register
- アプリからのフラッシュ書込未反映
- コンパイル時の最適化
今回はPIC でのセルフコンパイルなのでメモリ使用量も極力最小限にしており、また JITコンパイルでは短時間でコンパイルする必要があるので大域的な最適化はしません。
ステップレベルの最適化としてあまりにも冗長な部分を少し改善してみました。
前回の その3 で記載したサンプル例との比較が下記です。改善が見られ、まあまあ許せる範囲になってきた感じです ^^
尚、改善側(右側)の最後の「RETURN」の後に '7' が付いていますが、フラッシュに書込み後、実行しているための出力ですw
IF文のコンパイル例 前回(その3) 改善後 :l 1:# if-else sentence test 2: 3:proc test( x ) { 4: if ( x <> 1 ) { 5: PrnDec_( x ); 6: } else { 7: PrnDec_( 5 ); 8: } 9:} 10: 11: 12:proc main() { 13: test(7); 14:} :run 8000 : MOV W15,[ba0h] 8002 : MOV #b16h,W13 8004 : BRA 803ch 8006 : MOV [ba0h],W15 8008 : RETURN 800a : LNK #2 800c : MOV W0,[W14+0h] 800e : MOV [W14+0h],W0 8010 : MOV W0,[++W13] 8012 : MOV #1h,W0 8014 : MOV W0,[++W13] 8016 : MOV [W13--],W1 8018 : CP W1,[W13] 801a : CLR [W13] 801c : BRA Z,8020h 801e : INC [W13],[W13] 8020 : MOV [W13--],W0 8022 : CP0 W0 8024 : BRA Z,8030h 8026 : MOV [W14+0h],W0 8028 : MOV W0,[++W13] 802a : MOV [W13--],W0 802c : RCALL 178eh 802e : BRA 8038h 8030 : MOV #5h,W0 8032 : MOV W0,[++W13] 8034 : MOV [W13--],W0 8036 : RCALL 178eh 8038 : ULNK 803a : RETURN 803c : LNK #0 803e : MOV #7h,W0 8040 : MOV W0,[++W13] 8042 : MOV [W13--],W0 8044 : RCALL 800ah 8046 : ULNK 8048 : RETURN :
:l 1:# if-else sentence test 2: 3:proc test( x ) { 4: if ( x <> 1 ) { 5: PrnDec_( x ); 6: } else { 7: PrnDec_( 5 ); 8: } 9:} 10: 11: 12:proc main() { 13: test(7); 14:} :run 8000 : MOV W15,[b50h] 8002 : MOV #ac6h,W13 8004 : BRA 802eh 8006 : MOV [b50h],W15 8008 : RETURN 800a : LNK #2 800c : MOV W0,[W14+0h] 800e : MOV [W14+0h],W0 8010 : MOV W0,[++W13] 8012 : MOV #1h,W0 8014 : CP W0,[W13--] 8016 : CLR W0 8018 : BTSS [42h],#1 801a : INC W0,W0 801c : CP0 W0 801e : BRA Z,8026h 8020 : MOV [W14+0h],W0 8022 : RCALL 17b0h 8024 : BRA 802ah 8026 : MOV #5h,W0 8028 : RCALL 17b0h 802a : ULNK 802c : RETURN 802e : LNK #0 8030 : MOV #7h,W0 8032 : RCALL 800ah 8034 : ULNK 8036 : RETURN7 :
★2016/03/28 追記 改善側を更に1ワード削減
[TOP] [ 前へ ] 連載記事 [ 次へ ]
コメント 0