#include #include "bind.h" #include "tree.h" #include "qc.h" /* stringf.c で定義 */ char *Stringf(char *fmt, ...); /* 文字列を生成して返す (malloc 使用) */ /* asm.c で定義 */ char *newLabel(char prefix); /* ラベルの生成 */ void L(char *label); /* ラベルをを追加する */ void I(char *op, char *arg1, char *arg2); /* 命令を追加する */ void LI(char *label, char *op, char *arg1, char *arg2); /* code_exp.c で定義 */ void codeExp(Node exp); /********************************/ /* コード生成関係 */ /********************************/ /* 初期コードの生成 */ void initCode() { I(".intel_syntax", NUL, NUL); /* インテル形式を指定する */ LI(".macro", "mdiv", "eax", "SRC"); /* 除算を他の演算と同じ形式で */ I("cdq", NUL, NUL); /* 書けるように,マクロ命令 */ I("idiv", "\\SRC", NUL); /* mdiv を定義する */ L(".endm"); } /* 文のコード生成 */ void codeStmt(Node t, Obj func) { char *l1, *l2; if (t==NUL) return; switch (t->type) { case Lvar: return; case RETURN: if (t->left != NUL) codeExp(t->left); I("jmp", Stringf("_%s_r", func->name), NUL); return; case',': /* {…} (ブロック) */ for (; t!=NUL; t=t->right) codeStmt(t->left, func); return; case IF: codeExp(t->left); I("or", "%eax", "%eax"); I("jz", l1 = newLabel('I'), NUL); codeStmt(t->right->left, func); /* true パート */ if (t->right->right != NUL) I("jmp", l2 = newLabel('I'), NUL); L(l1); if (t->right->right != NUL) { codeStmt(t->right->right, func); /* false パート */ L(l2); } return; case WHILE: L(l2 = newLabel('W')); codeExp(t->left); I("or", "%eax", "%eax"); I("jz", l1 = newLabel('W'), NUL); codeStmt(t->right, func); /* 反復パート */ I("jmp", l2, NUL); L(l1); return; default: /* 式; */ codeExp(t); } } /* 大域定義のコード生成 */ void genCode(Node t) { Node u; Obj o; char *entry; switch (t->type) { case Gvar: /* 大域変数の宣言 */ for (u=t->left; u!=NUL; u=u->right) { o = (Obj)u->left->left->right; I(".comm", o->name, Stringf("%d", o->size * 4)); } return; case Fdef: /* 関数定義 */ if (t->right==NUL) break; /* 本体が空ならコードを生成しない */ o = (Obj)t->left->left->right; entry = o->name; I(".globl", entry, NUL); L(entry); I("push", "%ebp", NUL); I("mov", "%ebp", "%esp"); I("sub", "%esp", Stringf("%d", o->size * 4)); codeStmt(t->right, o); L(Stringf("_%s_r", entry)); I("mov", "%esp", "%ebp"); I("pop", "%ebp", NUL); I("ret", NUL, NUL); } }