34
8-bit PIC マイコン用ネイティブコンパイラの作成(後編) 2015.4.27 Masayuki Takagi Lisp Meet Up presented by Shibuya.lisp #27

Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

Embed Size (px)

Citation preview

Page 1: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

2015.4.27 Masayuki Takagi

Lisp Meet Up presented by Shibuya.lisp #27

Page 2: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-2-

自己紹介

高木 雅之

cl-cuda : a library to use NVIDIA CUDA in Common LispCommon Lisp から CUDA を使うライブラリ。昨年ここで紹介しました。

仕事は?1月に会社を設立。お見積もりお受けします。

Common Lisp

@kamonama

Page 3: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-3-

前回のおさらい - 動機

これまで、まともにアセンブラを書いたことがなかったのです。

1月下旬:はじめての PIC マイコン

2月上旬:はじめてのアセンブラ

PIC マイコンをはじめて触りました。

PIC で何作ろう?PIC用のコンパイラ作ろう。

2月中旬:PIC 用のコンパイラ

Page 4: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-4-

前回のおさらい - 前回のサマリ

ピン配置

メモリアーキテクチャ

プログラムメモリ

データメモリ

スペシャル・ファンクション・レジスタ

W レジスタ

命令セット

前回は、主に PIC マイコンのアーキテクチャを説明しました。

Page 5: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-5-

前回のおさらい - 話の流れ

そのあと、今回作った、PIC マイコン用のコンパイラについて説明します。

PIC マイコンについて

PIC マイコン用コンパイラについて

最初に、PIC マイコン自体について説明します。

基本的な内容なので、知っている人はニヤニヤしながら聞いていてください

Page 6: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-6-

コンパイラについて - コンパイラの概要

ホスト言語は、ML 系言語の本当に小さなサブセット。ただし S 式表現

ターゲット言語は、 8 ビット PIC マイコンのアセンブリ

コンパイラ言語は、Common Lisp

コンパイラの設計は、MinCaml をベースにした(MinCaml ですみません…)

8 ビット PIC

アセンブリ

ML 系言語

サブセット

(S 式表現)

Common Lisp

ホスト言語ホスト言語 ターゲット言語ターゲット言語コンパイラ言語コンパイラ言語

Page 7: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-7-

コンパイラについて - 構文

リテラル 42

変数参照 x

減算 -

条件分岐 if

変数束縛 let

局所関数定義 let

関数適用 (f x y)

繰り返し loop

I/O setreg

リテラルは、8ビット符号無し整数のみ提供。

関数の引数や let 式で定義された変数を参照する。

いったん、8ビット符号無し整数の減算のみ提供。

いったん、整数の等値比較による条件分岐のみ提供。

let 式によって、変数を定義できる。

let 式によって、局所関数を定義できる。束縛の要素数によって、変数束縛構文と区別する。クロージャは採用しない。

大域関数や局所関数に対する関数呼び出し。

PIC アセンブリの DECFSZ 命令にコンパイルされる効率的な繰り返しを提供。

スペシャル・ファンクション・レジスタに対する I/O を提供。例外的に、副作用を持つ構文。

今回のコンパイラは、いったん以下の構文を提供しています。

Page 8: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-8-

コンパイラについて - loop 構文

繰り返しを、構文として提供

当初は、関数の再帰呼び出しに展開される PIC マクロを定義していた

→ループ変数の管理が必要

PIC の DECFSZ 命令にコンパイルされるよう、改めて構文として定義

loop 構文

movlw 02Ah

movwf L0

_LOOP7

call _DO_SOMETHING

decfsz L0,f

goto _LOOP7

retlw 000h

この loop 構文は、以下の PIC アセンブリにコンパイルされる。

(loop 42

(do-something))

以下のように loop 構文を使用する。

Common Lisp マクロ

PIC マクロ

以下の中での設計選択

構文

コンパイラでの最適化

インライン・アセンブラ

Page 9: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-9-

コンパイラについて - progn PICマクロ

逐次処理は、入れ子の let 式で表現する(専用の構文を設けない)

簡単のため、progn PICマクロを提供

無駄な mov 命令は、アセンブリ出力時に排除し最適化

progn PICマクロ

(let ((tmp (setreg :gpio #x20)))

(let ((tmp (mdelay 50)))

(let ((tmp (setreg :gpio #x00)))

(mdelay 950))))

progn PICマクロは、以下のように入れ子の let 式に展開される。

(progn

(setreg :gpio #x20) ; LED を点灯

(mdelay 50) ; 50ms の遅延

(setreg :gpio #x00) ; LED を消灯

(mdelay 950)) ; 950ms の遅延

逐次処理は、progn PICマクロを使って以下のように記述できる。

Page 10: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-10-

コンパイラについて – 呼び出し規約(1/2)

ハードウェアには、「関数呼び出し」の概念はない

あるのは、サブルーチン・コールのみ

「関数呼び出し」を実現するために、引数と戻り値の受け渡しのルールが必要

ソフトウェア・スタックに引数を積んで引き渡し

X86 系 CPU の push/pop 命令に相当

間接アドレシングが煩雑なため、方針変更

なぜ呼び出し規約が必要か?なぜ呼び出し規約が必要か?

当初の設計当初の設計

Page 11: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-11-

コンパイラについて – 呼び出し規約(2/2)

入力用疑似レジスタ(I0-I7)、ローカル用疑似レジスタ(L0-L7)

MIPS や Sparc の呼び出し規約を参考

引数は、入力用疑似レジスタに格納して、呼び出される関数に渡す

戻り値は、W レジスタに格納して返す

関数呼び出し時に、「生きているレジスタ」をスタックに退避する

変更後の設計変更後の設計

Page 12: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-12-

コンパイラについて - コンパイルステージ

マクロ展開

インライン化

K 正規化

α変換

β簡約

let の平坦化

アセンブリ生成

レジスタ割り当て

即値最適化

仮想マシンコード生成

クロージャ変換

不要定義削除

以下のように、ホスト言語で記述されたプログラムを少しずつ変換して、ターゲット言語のプログラムを得ます。

Page 13: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-13-

コンパイルステージ(1/12) - マクロ展開

コンパイルされる式に含まれるマクロを展開

マクロは、DEFPICMACRO マクロで定義

式を走査し、マクロがあれば再帰的に走査

マクロ展開

;; delay for 500ms

(mdelay 500)

(progn

(loop 1

(loop 0 (mdelay1)))

(loop 244 (mdelay1)))

マクロ展開前のコードを以下とすると、

以下のように、MDELAY PICマクロが展開される。

(defpicmacro mdelay (n)

(check-type n (unsigned-byte 16))

(multiple-value-bind (q r) (truncate n 256)

(cond

((and (> q 0) (> r 0))

`(progn

(loop ,q (loop 0 (mdelay1)))

(loop ,r (mdelay1))))

((> q 0) `(loop ,q (loop 0 (mdelay1))))

((> r 0) `(loop ,r (mdelay1)))

(t '(nop)))))

以下のように、MDELAY PICマクロが定義されているとする。

マクロ展開 インライン化 K 正規化 α変換 β簡約 letの平坦化 不要定義削除 クロージャ変換 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力

Page 14: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-14-

コンパイルステージ(2/12) - インライン化

大域関数や局所関数を、呼び出し元に展開

関数呼び出しに伴う処理(レジスタの退避、引数の受け渡し、ジャンプ)を削減

パフォーマンス上、非常に有効

ただし、デメリットもある(コードの肥大化、コンパイル時間の増大) → どこまで実施?

インライン化

(loop 255

(mdelay1))

(loop 255

(loop #xf8

(nop)))

インライン化される前のコードを以下とすると、

このコードは、以下のように MDELAY1 PIC関数がインライン化される。

(defpic mdelay1 ()

(loop #xf8 ; 0xF8 is a magic number to delay

(nop))) ; for 1 msec

以下のように、MDELAY1 PIC関数が定義されているとする。

マクロ展開 K 正規化 α変換 β簡約 letの平坦化 不要定義削除 クロージャ変換 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力インライン化

Page 15: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-15-

コンパイルステージ(3/12) – K 正規化

式の評価の途中結果を、一時変数に格納する

アセンブリは、複雑な式を一度に計算できない

複雑な式を、よりアセンブリに近い簡単な式に分解する

K 正規化

(let ((tmp1 (+ x y))

(+ tmp1 z))

この式を K 正規化し、途中の評価結果を一時変数に格納することで、以下の式が得られる。

(+ (+ x y) z)

以下のように、ある式の評価結果を別の式の引数に使う式があるとする。

マクロ展開 インライン化 α変換 β簡約 letの平坦化 不要定義削除 クロージャ変換 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力K 正規化

Page 16: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-16-

コンパイルステージ(4/12) – α変換

異なる変数に、異なる名前を付ける

後のコンパイルの過程が簡単になる

今回は、変数名だけでなく、関数名についても同様の変換を行う

α変換

(let ((x1 (+ 1 2)))

(let ((x2 (+ x1 3)))

x2))

この式をα変換し、変数 x に別々の名前を付ける。

(let ((x (+ 1 2)))

(let ((x (+ x 3)))

x))

以下のように、(たまたま)同じ名前の変数 x に値を束縛する式があるとする。

マクロ展開 インライン化 K 正規化 β簡約 letの平坦化 不要定義削除 クロージャ変換 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力α変換

Page 17: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-17-

コンパイルステージ(5/12) – β簡約

ある変数が別の変数に束縛されているとき、被束縛変数を束縛変数で置き換える

λ計算におけるβ簡約(≒関数適用)の特殊な形

β簡約

(+ y y)

この式をβ簡約し、変数 x を変数 y で置き換える。伴い、let 束縛は取り除かれる。

(let ((x y))

(+ x y))

以下のように、変数 x に変数 y が束縛されているとする。

マクロ展開 インライン化 K 正規化 α変換 letの平坦化 不要定義削除 クロージャ変換 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力β簡約

Page 18: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-18-

コンパイルステージ(6/12) – let の平坦化

let 式の束縛式の中に、ネストして let 式が現れるとき、それを平坦化する

let の平坦化

(let ((y 1))

(let ((x (+ y 2)))

(+ x 3)))

これを、束縛式の中の let 式を外側に移しその本体式を変数に束縛することで、平坦化する。

(let ((x (let ((y 1))

(+ y 2))))

(+ x 3))

以下のように、let 式の束縛式の中にネストして let 式が現れる式があるとする。

マクロ展開 インライン化 K 正規化 α変換 β簡約 不要定義削除 クロージャ変換 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力letの平坦化

Page 19: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-19-

コンパイルステージ(7/12) – 不要定義削除

使われていない変数束縛や局所関数定義を取り除く

このような変数束縛や局所関数定義は、インライン化や定数畳み込みで生じる

ただし、副作用を伴う束縛は取り除かないものとする

不要定義削除

(let ((f (x y)

(+ x y)))

(+ 1 2))

(+ 1 2)

関数 f は、その呼び出し元でインライン化される。

他に関数 f を呼び出す箇所がない場合、関数 f の定義を取り除くことができる。

(let ((f (x y)

(+ x y)))

(f 1 2))

以下のように、局所関数定義 f とその関数呼び出しがあるとする。

(let ((tmp (setreg :gpio #x00)))

(mdelay 950))

ただし、逐次処理に伴う副作用を持つ束縛は、取り除かない。

マクロ展開 インライン化 K 正規化 α変換 β簡約 letの平坦化 クロージャ変換 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力不要定義削除

Page 20: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-20-

コンパイルステージ(8/12) – クロージャ変換

今回は、クロージャを採用しない(第一級の関数や自由変数は扱わない)

簡単のため、局所関数定義を式の外側に移動するにとどめる

局所定義関数は、大域関数定義に続けてアセンブリにコンパイルされる

クロージャ変換

(let ((f (x y)

(+ x y)))

(let ((a 1))

(f a 2)))

簡単のため、局所関数定義を外側へ移動する。

(let ((a 1))

(let ((f (x y)

(+ x y)))

(f a 2)))

以下のように、局所関数 f が定義されているとする。

マクロ展開 インライン化 K 正規化 α変換 β簡約 letの平坦化 不要定義削除 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力クロージャ変換

Page 21: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-21-

コンパイルステージ(9/12) – 仮想マシンコード生成

最適化された式を、仮想マシンコードに変換する

基本的には、Sparc の命令に対応

ただし、非線形な仮想マシンコード

let 命令の束縛式か本体式かが、リンケージに対応

仮想マシンコード生成

(let ((x (set 1)))

(let ((y (add 1 2)))

(add x y)))

この式は、以下の仮想マシンコードに変換される。

(let ((x 1))

(let ((y (+ 1 2)))

(+ x y)))

以下のような式があるとする。

let 命令 letrec 命令

set 命令 mov 命令

sub 命令 ifeq 命令

loop 命令 call 命令

setreg 命令 with-save 命令

仮想マシンコードの一覧

:tail

(:non-tail REG)

リンケージ

関数末尾

関数非末尾(REGへの格納)

restore 命令

マクロ展開 インライン化 K 正規化 α変換 β簡約 letの平坦化 不要定義削除 クロージャ変換 即値最適化 レジスタ割り当て アセンブリ出力仮想マシンコード

Page 22: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-22-

コンパイルステージ(10/12) – 即値最適化

可能な場合、即値をオペランドにとる命令を使うことで最適化

clrf 命令、movlw 命令、retlw 命令など

即値最適化

(let ((x (set 1)))

(add x 2))

movlw 001h

movwf L0

movlw 002h

movwf L1

movf L1,w

addwf L0,w

return

即値最適化により、以下の仮想マシンコードに変換できる。

即値最適化により、最終的なアセンブリが以下のようになる。

(let ((x (set 1)))

(let ((y (set 2)))

(add x y)))

以下の仮想マシンコードがあるとする。

movlw 001h

movwf L0

movlw 002h

addwf L0,w

return

即値最適化前(7命令) 即値最適化後(5命令)

マクロ展開 インライン化 K 正規化 α変換 β簡約 letの平坦化 不要定義削除 クロージャ変換 仮想マシンコード レジスタ割り当て アセンブリ出力即値最適化

Page 23: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-23-

コンパイルステージ(11/12) – レジスタ割当て

変数(≒無限に存在する仮想レジスタ)に、レジスタを割り当てる

ソフトウェア的な疑似レジスタ :L0 - :L7 を、順に割り当てる

レジスタの数が足りない場合は:

「死んでいる」レジスタを再利用

それでも足りない場合、ソフトウェア・スタックに退避

レジスタ割当て

(let ((:L0 (set 1)))

(let ((:L1 (set 2)))

(add :L0 :L1)))

変数に、レジスタを割り当てる。

(let ((x (set 1)))

(let ((y (set 2)))

(add x y)))

以下の仮想マシンコードがあるとする。

マクロ展開 インライン化 K 正規化 α変換 β簡約 letの平坦化 不要定義削除 クロージャ変換 仮想マシンコード 即値最適化 アセンブリ出力レジスタ割り当て

Page 24: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-24-

コンパイルステージ(12/12) – アセンブリ出力

仮想マシンコードを PIC のアセンブリに変換する

非線形のマシンコードを走査し、線形の PIC アセンブリに変換する

リンケージに応じ、レジスタに MOV するか、関数から RETURN する

アセンブリ出力

((movlw 1) ; (set 1) to :L0

(movwf :L0)

(movlw 2) ; (set 2) to :L1

(movwf :L1)

(movf :L1 :w) ; (add :L0 :L1) and set W reg

(addwf :L0 :w)

(return)) ; return to the caller

movlw 001h

movwf L0

movlw 002h

movwf L1

movf L1,w

addwf L0,w

return

この仮想マシンコードは、いったん PIC アセンブリの S 式表現に変換される。

S 式で表現された PIC アセンブリは、以下の PIC アセンブリに変換され出力される。

(let ((:L0 (set1)))

(let ((:L1 (set 2)))

(add :L0 :L1)))

以下のような、レジスタ割り当て済みの仮想マシンコードがあるとする。

マクロ展開 インライン化 K 正規化 α変換 β簡約 letの平坦化 不要定義削除 クロージャ変換 仮想マシンコード 即値最適化 レジスタ割り当て アセンブリ出力

Page 25: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

実行例

Page 26: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-26-

実行例 – LED 点滅サンプル

(defpic mdelay1 ()

(loop #xf8 ; 0xF8 is a magic number to delay

(nop))) ; for 1 msec

(defpicmacro mdelay (n)

(check-type n (unsigned-byte 16))

(multiple-value-bind (q r) (truncate n 256)

(cond

((and (> q 0) (> r 0)) `(progn

(loop ,q (loop 0 (mdelay1)))

(loop ,r (mdelay1))))

((> q 0) `(loop ,q (loop 0 (mdelay1))))

((> r 0) `(loop ,r (mdelay1)))

(t '(nop)))))

(defpic init ()

(progn

(setreg :gpio #x0) ; clera GP0-5

(setreg :cmcon0 #x07) ; disable comparator

(setbank1) ; switch to bank 1

(setreg :trisio #x08) ; only GP3 is input mode

(setreg :ansel #x00) ; disable analog IO

(setreg :ioc #x00) ; disable interruption

(setbank0) ; switch to bank 0

(setreg :intcon #x00))) ; disable interruption

(defpic main ()

(progn

(setreg :gpio #x20) ; set GP5 to high

(mdelay 50) ; delay for 50 msec

(setreg :gpio #x00) ; set GP5 to low

(mdelay 950) ; delay for 950 msec

(main))) ; repeat

LED 点滅サンプル - led.lisp

mdelay1 PIC関数 処理を 1ms 遅延させる

mdelay PICマクロ 指定したマイクロ秒だけ、処理を遅延させる

8ビット整数のため、一重のループでは 255ms まで。1秒を表現できず不便

マクロにすることで、65535ms まで表現可能。

init PIC関数 ブート時に1度だけ実行される特殊関数

ここで、必要な初期設定を行う

main PIC関数 init PIC関数の後に実行される特殊関数

ここで、メイン処理を行う

しばしば、自己再帰ループを構成する

Page 27: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-27-

実行例 – LED 点滅サンプル – mdelay1 PIC関数

_MDELAY1

MOVLW 0F8h

MOVWF L0

_LOOP3

CLRF NULL

DECFSZ L0,F

GOTO _LOOP3

RETLW 000h

;;; 0xF8 is a magic number to delay

;;; for 1 msec.

(defpic mdelay1 ()

(loop #xf8

(nop)))

コンパイル前コンパイル前 アセンブリアセンブリ

Page 28: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-28-

実行例 – LED 点滅サンプル – mdelay PICマクロ

(defpicmacro mdelay (n)

(check-type n (unsigned-byte 16))

(multiple-value-bind (q r) (truncate n 256)

(cond

((and (> q 0) (> r 0))

`(progn

(loop ,q (loop 0 (mdelay1)))

(loop ,r (mdelay1))))

((> q 0) `(loop ,q (loop 0 (mdelay1))))

((> r 0) `(loop ,r (mdelay1)))

(t '(nop)))))

(defpic mdelay950 ()

(mdelay 950))

コンパイル前コンパイル前

_MDELAY950

MOVLW 003h

MOVWF L0

_LOOP11

CLRF L1

_LOOP12

MOVLW 0F8h

MOVWF L2

_LOOP13

CLRF NULL

DECFSZ L2,F

GOTO _LOOP13

DECFSZ L1,F

GOTO _LOOP12

DECFSZ L0,F

GOTO _LOOP11

MOVLW 0B6h

MOVWF L4

_LOOP14

MOVLW 0F8h

MOVWF L5

_LOOP15

CLRF NULL

アセンブリアセンブリ

DECFSZ L5,F

GOTO _LOOP15

DECFSZ L4,F

GOTO _LOOP14

RETLW 000h

Page 29: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-29-

実行例 – LED 点滅サンプル – init PIC関数

_INIT

CLRF GPIO

MOVLW 007h

MOVWF CMCON0

MOVLW 020h

MOVWF STATUS

MOVLW 008h

MOVWF TRISIO

CLRF ANSEL

CLRF IOC

CLRF STATUS

CLRF INTCON

RETURN

(defpic init ()

(progn

(setreg :gpio #x0) ; clear GP0-5

(setreg :cmcon0 #x07) ; disable comparator

(setbank1) ; switch to bank 1

(setreg :trisio #x08) ; only GP3 is input mode

(setreg :ansel #x00) ; disable analog IO

(setreg :ioc #x00) ; disable interruption

(setbank0) ; switch to bank 0

(setreg :intcon #x00))) ; disable interruption

コンパイル前コンパイル前 アセンブリアセンブリ

Page 30: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-30-

実行例 – LED 点滅サンプル – main PIC関数

_MAIN

MOVLW 020h

MOVWF GPIO

MOVLW 032h

MOVWF L1

_LOOP4

MOVLW 0F8h

MOVWF L2

_LOOP5

CLRF NULL

DECFSZ L2,F

GOTO _LOOP5

DECFSZ L1,F

GOTO _LOOP4

CLRF GPIO

MOVLW 003h

MOVWF L5

_LOOP6

CLRF L6

_LOOP7

MOVLW 0F8h

MOVWF L7

_LOOP8

(defpic main ()

(progn

(setreg :gpio #x20) ; set GP5 to high

(mdelay 50) ; delay for 50 msec

(setreg :gpio #x00) ; set GP5 to low

(mdelay 950) ; delay for 950 msec

(main))) ; repeat

コンパイル前コンパイル前 アセンブリアセンブリ

CLRF NULL

DECFSZ L7,F

GOTO _LOOP8

DECFSZ L6,F

GOTO _LOOP7

DECFSZ L5,F

GOTO _LOOP6

MOVLW 0B6h

MOVWF L0

_LOOP9

MOVLW 0F8h

MOVWF L1

_LOOP10

CLRF NULL

DECFSZ L1,F

GOTO _LOOP10

DECFSZ L0,F

GOTO _LOOP9

GOTO _MAIN

Page 31: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-31-

実行例 – LED 点滅サンプル – 生成されるアセンブリ

INCLUDE"p12f683.inc"

list p=12f683

__CONFIG _CP_OFF & _CPD_OFF & _WDT_OFF & _BOD_ON & _IESO_OFF& _PWRTE_ON & _INTOSCIO & _MCLRE_OFF

CBLOCK 020h

L0,L1,L2,L3,L4,L5,L6,L7

I0,I1,I2,I3,I4,I5,I6,I7

NULL

SP,STMP,STK

ENDC

ORG 0

GOTO MAIN

ORG 4

GOTO INTR

_INTR

RETURN

_INIT

CLRF GPIO

MOVLW 007h

MOVWF CMCON0

MOVLW 020h

MOVWF STATUS

MOVLW 008h

MOVWF TRISIO

CLRF ANSEL

CLRF IOC

CLRF STATUS

CLRF INTCON

RETURN

_MAIN

MOVLW 020h

MOVWF GPIO

MOVLW 032h

MOVWF L1

_LOOP1

MOVLW 0F8h

MOVWF L2

_LOOP2

CLRF NULL

DECFSZ L2,F

GOTO _LOOP2

DECFSZ L1,F

GOTO _LOOP1

CLRF GPIO

MOVLW 003h

MOVWF L5

_LOOP3

CLRF L6

_LOOP4

MOVLW 0F8h

MOVWF L7

_LOOP5

CLRF NULL

DECFSZ L7,F

GOTO _LOOP5

DECFSZ L6,F

GOTO _LOOP4

DECFSZ L5,F

GOTO _LOOP3

MOVLW 0B6h

MOVWF L0

_LOOP6

MOVLW 0F8h

MOVWF L1

_LOOP7

CLRF NULL

DECFSZ L1,F

GOTO _LOOP7

DECFSZ L0,F

GOTO _LOOP6

GOTO _MAIN

_PUSH_STACK

MOVWF STMP

MOVF SP,W

MOVWF FSR

MOVF STMP,W

MOVWF INDF

INCF SP,F

RETURN

_POP_STACK

DECF SP,F

MOVF SP,W

MOVWF FSR

MOVF INDF,W

RETURN

INTR

CALL _INTR

RETFIE

MAIN

MOVLW STK

MOVWF SP

CALL _INIT

CALL _MAIN

END

Page 32: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

おまけ

Page 33: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-33-

Lisp マシン

CONS マシン、CADR マシン、Symbolics、SCHEME-79 チップ、ELIS、SILENT

LispmFPGA、Spica

Reduceron(ハードウェアによるλ計算)

タグ付きデータ

多重分岐

メモリ管理

非線形命令セット(どこまで可能?)

Lisp マシンいろいろLisp マシンいろいろ

Lisp マシンの要件(仮)Lisp マシンの要件(仮)

Page 34: Lisp Meet Up #27, 8-bit PIC マイコン用ネイティブコンパイラの作成(後編)

© 2015 Masayuki Takagi-34-

Lisp マシン

ハードウェアによるリアルタイム・ガベージ・コレクションの実装

S. Shukla et al., IBM Research, 2012, “And Then There Were None: A Stall-Free Real-Time Garbage Collector for Reconfigurable Hardware”

CPU ストールがゼロ

ゴール設定は?

いまやっていることいまやっていること

課題課題