Mercurial > hg > Members > kono > compiler-examples
view s-code-llvm.c @ 18:230d5ca49f9f
fix
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 28 Oct 2016 15:16:55 +0900 |
parents | 5b631c16f89b |
children |
line wrap: on
line source
/* 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.10.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", "; Function Attrs: nounwind ssp uwtable", "define i32 @main() #0 {", " %1 = load i32* @a, align 4", " %2 = load i32* @b, align 4", " %3 = add nsw i32 %1, %2", " call void @print(i32 %3)", " ret i32 0", "}", "", "attributes #0 = { nounwind ssp uwtable \"less-precise-fpmad\"=\"false\" \"no-frame-pointer-elim\"=\"true\" \"no-frame-pointer-elim-non-leaf\" \"no-infs-fp-math\"=\"false\" \"no-nans-fp-math\"=\"false\" \"stack-protector-buffer-size\"=\"8\" \"unsafe-fp-math\"=\"false\" \"use-soft-float\"=\"false\" }", "attributes #1 = { \"less-precise-fpmad\"=\"false\" \"no-frame-pointer-elim\"=\"true\" \"no-frame-pointer-elim-non-leaf\" \"no-infs-fp-math\"=\"false\" \"no-nans-fp-math\"=\"false\" \"stack-protector-buffer-size\"=\"8\" \"unsafe-fp-math\"=\"false\" \"use-soft-float\"=\"false\" }", "", "!llvm.ident = !{!0}", "", "!0 = metadata !{metadata !\"Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)\"}", NULL }; static int creg; /* current register */ static int lreg; /* operand 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,tmp); 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,oreg); } else if(op==O_SUB) { printf("\t%%%d = %s %%%d, %%%d\n",creg,opcode[op],oreg,oreg); } else { printf("\t%%%d = %s %%%d, %%%d\n",creg,opcode[op],oreg,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 */