Mercurial > hg > Members > kono > compiler-examples
changeset 16:5b631c16f89b
llvm output
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 02 Nov 2012 14:04:35 +0900 |
parents | 8741552a4e4b |
children | e5c8532ab38d |
files | s-code-llvm.c |
diffstat | 1 files changed, 226 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/s-code-llvm.c Fri Nov 02 14:04:35 2012 +0900 @@ -0,0 +1,226 @@ +/* + Very Simple Code Generator for Intel x86 + $Id$ + */ + + #include "s-compile.h" + +int label = 0; +char *comments = "; "; +static +char *intro[] = { + "target datalayout = \"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128\"\n", + "target triple = \"x86_64-apple-macosx10.8.0\"\n", + "@.str = private unnamed_addr constant [5 x i8] c\"\0A = \00\", align 1\n", + "define i32 @main() nounwind uwtable ssp {\n", + "entry:\n", + NULL +}; + +static +char *ending[] = { + " ret i32 0\n", + "}\n", + "declare i32 @printf(i8*, ...)\n", + NULL +}; + +static int creg; /* current register */ +static int lreg; /* operand register */ +static int dreg; /* temporary register */ +static int xreg; /* operand register */ +static int reg_sp; /* REGister Stack-Pointer */ + +#define MAX_MAX 20 +static int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ +static int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ + +const int MAX_REGISTER=20; + +static int +get_register() +{ /* 使われていないレジスタを調べる */ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { /* 使われていないなら */ + regs[i]=1; /* そのレジスタを使うことを宣言し */ + return i; /* その場所を表す番号を返す */ + } + } + return -1; /* 空いている場所がないなら、それを表す -1 を返す */ +} + +static void +free_register(i) { /* いらなくなったレジスタを開放 */ + regs[i]=0; +} + +static int +register_full() +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { + return 0; + } + } + return 1; +} + +void +emit_init() +{ + int i; + for(i=0;i<MAX_REGISTER;i++) regs[i]=0; + creg = get_register(); + reg_sp = 0; +} + +static int +pop_register() +{ /* レジスタから値を取り出す */ + int i,j; + + j = creg; + i = reg_stack[--reg_sp]; + + if(i<0) { + return i; + } else { + lreg = i; + regs[i]=0; + return lreg; + } +} + +void +emit_push() +{ + int new_reg; + new_reg = get_register(); + if(new_reg<0) { /* もうレジスタがない */ + printf("Compilation error: too complex expression\n"); + } else { + reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ + creg = new_reg; + } +} + +int +emit_pop() +{ + pop_register(); + xreg = lreg; + return xreg; +} + + +void +emit_compare() +{ + int oreg; + oreg = emit_pop(); + printf("\t%%%d = icmp sgt i32 %%%d %%%d\n",creg,oreg,oreg); + printf("\t%%%d = zext i1 %%%d to i32\n",creg,creg); +} + +void +emit_store(assign) +int assign; +{ + int tmp = get_register(); + + printf("\t%%d = getelementptr inbounds [48 x i32]* @variable, i32 0, i64 %d\n",tmp,assign); + printf("\tstore i32 %%%d i32* %%%d, align 4\n",creg); + + free_register(tmp); +} + +void +emit_load(int d) +{ + int tmp = get_register(); + printf("\t%%%d = getelementptr inbounds [48 x i32]* @variable, i32 0, i64 %d\n", tmp, d); + printf("\t%%d = load i32* %%%d, align 4\n", creg, tmp); + + free_register(tmp); +} + + +static +char *opcode[] = { + "", + "sub nsw i32", + "add nsw i32", + "mul nsw i32", + "sdiv i32", + "", + "", + "", + "", + "sub ndw i32", + "sdiv i32", +}; + +void +emit_calc(enum opcode op) +{ + int oreg; + oreg = emit_pop(); + if(op==O_DIV) { + printf("\t%%%d = %s %%%d, %%%d\n",creg,opcode[op],oreg); + } else if(op==O_SUB) { + printf("\t%%%d = %s %%%d, %%%d\n",creg,opcode[op],oreg); + } else { + printf("\t%%%d = %s %%%d, %%%d\n",creg,opcode[op],oreg); + } +} + +void +emit_value(d) +int d; +{ + printf("\t%%%d = i32 %d\n",creg,d); +} + +void +emit_comment() +{ + if (before < ptr) { + putchar(';'); putchar(' '); + while (before < ptr) { + if(*before && *before!='\n') { + putchar(*before); + } + before++; + } + putchar('\n'); + } +} + +void +emit_print() +{ + printf("\t%%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.str, i32 %%%d, i32 0))\n", creg); +} + + +void +emit_intro() +{ + char **iptr; + for(iptr=intro;*iptr;iptr++) { + printf("%s",*iptr); + } +} + +void +emit_ending() +{ + char **iptr; + for(iptr=ending;*iptr;iptr++) { + printf("%s",*iptr); + } +} + +/* end */