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