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