Tree Generation Part
式と型を表す2種類の中間木
list2, list3, list4 などで作られる
型
INT CHAR UNSIGNED POINTER ARRAY STRUCT UNION
FUNCTION EMPTY
式
変数を表すノード (変数のoffset付き)
GVAR RGVAR CRGVAR LVAR RLVAR CRLVAR
定数を表す (値付き)
CONST
関数名 (名前付き)
FNAME
式の間接参照(indirect = *)
INDIRECT RINDIRECT CRINDIRECT
式のアドレス( = &)
ADDRESS
Unary operator (単項演算子)
MINUS LNOT BNOT INC POSTINC PREINC CPOSTINC CPREINC DEC
CPOSTDEC CPREDEC
Binary operator (2項演算子)
MUL UMUL DIV UDIV MOD UMOD ADD SUB
RSHIFT URSHIFT LSHIFT ULSHIFT
BAND EOR BOR LAND LOR
Relational operator (比較演算子)
GT UGT GE UGE LT ULT LE ULE EQ NEQ
3項演算子 (?:)
COND COLON
Assignment (代入)
ASS CASS ASSOP CASSOP
Comma (逐次演算)
COMMA
条件文のコード生成
do_if() など
bexpr()
リターン文のコード生成
doreturn()
return2()
ret()
unlink()
goto文
dogoto()
jmp()
左辺値への木の変更
rvalue()
左辺値かどうかのチェック
lcheck()
indrect の木の変更
expr13()
indop(e)
構造体の木の生成
expr16()
strop()
rvalue()
2項演算子の木の生成 (定数の計算などを含む)
binop()
アドレスの足し算等もここで木を生成する
bexpr() 条件分岐のコード生成
rexpr()
jcond()
rexpr() 引き算して条件分岐するのコード生成
jcond() EQ/NE での条件分岐
jmp() 分岐
fwdlabel() 新しい forward label の参照
fwddef(l) forward labelの定義
backdef() 直前に定義したラベルの定義
gexpr() 式のコード生成
GVAR: leaxy(e2);
RGVAR: lddy(e2);
CRGVAR: ldby(e2); sex();
LVAR: leaxu(e2);
RLVAR: lddu(e2);
CRLVAR: ldbu(e2); sex();
FNAME: leaxpcr() tfrxd();
CONST: lddim() (0 だったら clrd())
STRING: string(e1);
FUNCTION: function(e1);
INDIRECT: indirect(e1);
RINDIRECT: CRINDIRECT: rindirect(e1);
ADDRESS: gexpr(e2); tfrxd();
MINUS: NEGA NEGB SBCA
BNOT: COMA COMB
PREINC:
GVAR: LVAR:
ldd(e2); adddim(caddr(e1)); std(e2);
default:
gexpr(e2); lddx(); adddim()); stdx();
POSTINC:
GVAR: LVAR:
ldd(e2); adddim() std(e2); subdim(e3);
default:
gexpr(e2); lddx(); adddim() stdx(); subdim(e3);
CPOSTINC:
gexpr(e2); ldbx(); incx(); sex();
CPREINC:
gexpr(e2); incx(); ldbx(); sex();
CPOSTDEC:
gexpr(e2); ldbx(); decx(); sex();
CPREDEC:
gexpr(e2); decx(); ldbx(); sex();
MUL: UMUL:
定数の場合はいろいろ工夫する (asld() など)
DIV: UDIV: MOD: UMOD:
LSHIFT: ULSHIFT: RSHIFT: URSHIFT:
binexpr(e1);
ADD: SUB: BAND: EOR: BOR:
machinop(e1);
COND:
?: のコード生成 bexpr()
ASS: case CASS:
assign(e1);
ASSOP: CASSOP:
assop(e1);
COMMA:
default:
式の値によって 1,0 を返す
string()
文字定数 "abc" などのコード生成
function(e1)
関数呼び出しのコード生成
最初に引き数を積む
FNAME:
leaxpcr(n); pushx();
ADDRESS:
gexpr(e5); pushx();
default:
gexpr(e4); pushd();
FNAME ならば LBSR する
そうでなければ JSR ,X する
最後にスタックをたたむ
printf("\tLEAS\t%d,S\n",2*nargs);
indirect(e1)
間接参照のコード生成
RGVAR: RLVAR:
ldx(e2);
ADD:
ADDRESS
opdx("LEAX");
RGVAR: RLVAR:
gexpr(e3); ldx(e4); opdx("LEAX");
default:
gexpr(e2); tfrdx();
machinop(e1)
RGVAR: RLVAR: CONST:
gexpr(e2); oprt(car(e1),e3);
default:
gexpr(e3); pushd(); gexpr(e2); tosop(car(e1));
rindirect(e1)
間接参照の右辺値 最後にLDB or LDD を生成する
RGVAR: RLVAR:
indir(op,e2); sextend(byte);
ADD:
ADDRESS
opdx(op); sextend(byte);
RGVAR: RLVAR:
gexpr(e3); ldx(e4); opdx(op); sextend(byte);
CONST:
RGVAR: RLVAR:
ldx(e3); indexx(op,cadr(e4)); sextend(byte);
default:
gexpr(e3); pushd(); gexpr(e4); pulx();
opdx(op); sextend(byte);
PREINC:
1,2の場合は特別扱い
GVAR: LVAR:
ldx(e3); predecx(op,l);
stx(e3); sextend(byte);
POSTINC:
1,2の場合は特別扱い
{GVAR: LVAR:
ldx(e3); postincx(op,l);
stx(e3); sextend(byte);
default:
gexpr(e2); tfrdx(); indexx(op,0); sextend(byte);
assign(e1)
代入文 STB STD を生成する
{GVAR: LVAR:
gexpr(e4); index(op,e2);
INDIRECT:
RGVAR: RLVAR:
gexpr(e4); indir(op,e3);
ADD:
定数の場合は
gexpr(e4); ldx(e5);
indexx(op,cadr(caddr(e3)));
PREINC:
1,2の場合は特別扱い
GVAR: LVAR:
gexpr(e4); ldx(e5);
predecx(op,l); stx(e5);
POSTINC:
1,2の場合は特別扱い
GVAR: LVAR:
gexpr(e4); ldx(e5);
postincx(op,l); stx(e5);
RGVAR: CRGVAR: RLVAR: CRLVAR: CONST:
この場合はスタックを使わずに左辺値を計算出来る
gexpr(e2); gexpr(e4);
default:
普通はできないのでDをスタックに積んでから左辺値を計算する
gexpr(e4); pushd(); gexpr(e2); pulld();
最後に STD, STB を生成する
indexx(op,0);
assop(e1)
演算代入文 += など LDB,LDD して計算そしてSTB,STD
GVAR: LVAR:
右辺が変数
RGVAR: RLVAR: CONST:
左辺も右辺も変数か定数で簡単な演算
index(ldop,e2); sextend(byte);
oprt(op,e3); index(stop,e2);
default:
gexpr(e3); pushd(); index(ldop,e2);
sextend(byte); tosop(op); index(stop,e2);
default:
右辺はもっと複雑
RGVAR: RLVAR: CONST:
右辺は変数か定数で簡単な演算
gexpr(e2); indexx(ldop,0); sextend(byte);
oprt(op,e3); indexx(stop,0);
default:
gexpr(e3); pushd(); gexpr(e2);
indexx(ldop,0); sextend(byte);
tosop(op); indexx(stop,0);
simpop(op)
6809で一命令で計算出来る ADD SUB BAND EOR BOR
oprt(op,e1)
oprt1()
oprtc()
oprt1(op,index,n)
index mode での計算
dualop(op,index,n)
byte 毎に計算する index mode での計算
oprtc(op,n)
定数演算
dualc(op,n)
byte 毎に計算する 定数演算
tosop(op)
stackとの演算 (一つスタックを片づける)
ADD: addds();
SUB: subds();
BAND: EOR: BOR: dualtosop(op);
default:
pulx(); library(op);
dualtosop(op)
byte 毎に計算する stackとの演算 (一つスタックを片づける)
ldd(e)
D register へのload
GVAR:
lddy(cadr(e));
LVAR:
lddu(cadr(e));
std(e)
D register のstore
GVAR:
stdy(cadr(e));
LVAR:
stdu(cadr(e));
ldx(e)
X register への load
GVAR: RGVAR:
ldxy(cadr(e));
LVAR: RLVAR:
ldxu(cadr(e));
stx(e)
X register の store
GVAR:
stxy(cadr(e));
LVAR:
stxu(cadr(e));
index(op,e)
Index register へのload/store
GVAR:
indexy(op,cadr(e));
LVAR:
indexu(op,cadr(e));
indir(op,e)
間接
RGVAR:
indiry(op,cadr(e));
RLVAR:
indiru(op,cadr(e));
sextend(byte)
符号拡張(byteのみ)
binexpr(e1)
ライブラリを使う演算
gexpr(caddr(e1));
pushd();
gexpr(cadr(e1));
pulx();
library(car(e1));
library(op)
ライブラリの呼び出し
MUL UMUL DIV UDIV MOD UMOD
LSHIFT ULSHIFT RSHIFT URSHIFT