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 */