changeset 15:8741552a4e4b

register base intel64
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 26 Oct 2012 16:16:00 +0900
parents efaf426d6150
children 5b631c16f89b
files Makefile s-calc-r.c s-code-intel64-mac-r.c
diffstat 3 files changed, 380 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Fri Oct 28 01:54:41 2011 +0000
+++ b/Makefile	Fri Oct 26 16:16:00 2012 +0900
@@ -1,4 +1,4 @@
-TEST = s-imac64
+TEST = s-intel
 
 CC = gcc
 CFLAGS = -g -O  -Wall
--- a/s-calc-r.c	Fri Oct 28 01:54:41 2011 +0000
+++ b/s-calc-r.c	Fri Oct 26 16:16:00 2012 +0900
@@ -39,7 +39,7 @@
     }
     if('0'<=c && c<='9') {     /* Decimal */
 	d = c-'0';
-	while(c= *ptr++) {
+	while((c= *ptr++)) {
 	    if('0'<=c && c<='9') {
 		d = d*10 + (c - '0');
 	    } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/s-code-intel64-mac-r.c	Fri Oct 26 16:16:00 2012 +0900
@@ -0,0 +1,378 @@
+/*
+    Very Simple Code Generator for Intel x86
+    $Id$
+ */
+
+ #include "s-compile.h"
+
+int  label = 0;
+char *comments = "#####";
+static
+char *intro[] = {
+  "      .cstring\n",
+  "LC0:\n",
+  "  .ascii \"%d\\n\\0\"\n"
+  "    .text\n",
+  ".globl _print\n",
+  "_print:\n",
+  "LFB2:\n",
+  "    pushq   %rbp\n",
+  "LCFI0:\n",
+  "    movq    %rsp, %rbp\n",
+  "LCFI1:\n",
+  "    subq    $16, %rsp\n",
+  "LCFI2:\n",
+  "    movl    %edi, -4(%rbp)\n",
+  "    movl    -4(%rbp), %esi\n",
+  "    leaq    LC0(%rip), %rdi\n",
+  "    movl    $0, %eax\n",
+  "    call    _printf\n",
+  "    leave\n",
+  "    ret\n",
+  "LFE2:\n",
+  ".globl _main\n",
+  "_main:\n",
+  "LFB3:\n",
+  "    pushq   %rbp\n",
+  "LCFI3:\n",
+  "    movq    %rsp, %rbp\n",
+  "LCFI4:\n",
+  "    subq    $16, %rsp\n",
+  "LCFI5:\n",
+  "\n",
+  "\n",
+  NULL
+};
+
+static
+char *ending[] = {
+  "    movq    %rax, %rdi\n",
+  "    call    _print\n",
+  "    leave\n",
+  "    ret\n",
+  "LFE3:\n",
+  ".comm _v,96,5\n",
+  "    .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n",
+  "EH_frame1:\n",
+  "    .set L$set$0,LECIE1-LSCIE1\n",
+  "    .long L$set$0\n",
+  "LSCIE1:\n",
+  "    .long   0x0\n",
+  "    .byte   0x1\n",
+  "    .ascii \"zR\\0\"\n",
+  "    .byte   0x1\n",
+  "    .byte   0x78\n",
+  "    .byte   0x10\n",
+  "    .byte   0x1\n",
+  "    .byte   0x10\n",
+  "    .byte   0xc\n",
+  "    .byte   0x7\n",
+  "    .byte   0x8\n",
+  "    .byte   0x90\n",
+  "    .byte   0x1\n",
+  "    .align 3\n",
+  "LECIE1:\n",
+  "    .globl _print.eh\n",
+  "_print.eh:\n",
+  "LSFDE1:\n",
+  "    .set L$set$1,LEFDE1-LASFDE1\n",
+  "    .long L$set$1\n",
+  "LASFDE1:\n",
+  "    .long   LASFDE1-EH_frame1\n",
+  "    .quad   LFB2-.\n",
+  "    .set L$set$2,LFE2-LFB2\n",
+  "    .quad L$set$2\n",
+  "    .byte   0x0\n",
+  "    .byte   0x4\n",
+  "    .set L$set$3,LCFI0-LFB2\n",
+  "    .long L$set$3\n",
+  "    .byte   0xe\n",
+  "    .byte   0x10\n",
+  "    .byte   0x86\n",
+  "    .byte   0x2\n",
+  "    .byte   0x4\n",
+  "    .set L$set$4,LCFI1-LCFI0\n",
+  "    .long L$set$4\n",
+  "    .byte   0xd\n",
+  "    .byte   0x6\n",
+  "    .align 3\n",
+  "LEFDE1:\n",
+  "    .globl _main.eh\n",
+  "_main.eh:\n",
+  "LSFDE3:\n",
+  "    .set L$set$5,LEFDE3-LASFDE3\n",
+  "    .long L$set$5\n",
+  "LASFDE3:\n",
+  "    .long   LASFDE3-EH_frame1\n",
+  "    .quad   LFB3-.\n",
+  "    .set L$set$6,LFE3-LFB3\n",
+  "    .quad L$set$6\n",
+  "    .byte   0x0\n",
+  "    .byte   0x4\n",
+  "    .set L$set$7,LCFI3-LFB3\n",
+  "    .long L$set$7\n",
+  "    .byte   0xe\n",
+  "    .byte   0x10\n",
+  "    .byte   0x86\n",
+  "    .byte   0x2\n",
+  "    .byte   0x4\n",
+  "    .set L$set$8,LCFI4-LCFI3\n",
+  "    .long L$set$8\n",
+  "    .byte   0xd\n",
+  "    .byte   0x6\n",
+  "    .align 3\n",
+  "LEFDE3:\n",
+  "    .subsections_via_symbols\n",
+ NULL
+};
+
+static int  creg;     /* current register */
+static char *crn;     /* current register name */
+static int  lreg;     /* operand register */
+static char *lrn;     /* operand register name */
+static int  dreg;     /* temporary register */
+static char *drn;     /* temporary register name */
+static int  xreg;     /* operand register  */
+static char *xrn;     /* operand register name */
+static int  reg_sp;   /* REGister Stack-Pointer */
+
+const int REG_RAX    = 0;
+const int REG_RBX    = 1;
+const int REG_RCX    = 2;
+const int REG_RDX    = 3;
+const int REG_RSI    = 4;
+const int REG_RDI    = 5;
+const int REG_RBP    = 6;
+const int REG_R07    = 7;
+const int REG_R08    = 8;
+const int REG_R09    = 9;
+const int REG_R10    = 10;
+const int REG_R11    = 11;
+const int REG_R12    = 12;
+const int REG_R13    = 13;
+const int REG_R14    = 14;
+const int REG_R15    = 15;
+
+const int REG_RSP    = 16;
+
+#define MAX_MAX  20
+static int regs[MAX_MAX];       /* 使われているレジスタを示すフラグ */
+static int reg_stack[MAX_MAX];  /* 実際のレジスタの領域 */
+
+const int	MAX_REGISTER=10;
+
+static char    *reg_name[] = {"%rax","%rbx","%rcx","%rdx","%rsi", "%rdi", "%rbp",
+                      "%r07", "%r08", "%r09", "%r10", "%r12", "%r13", "%r14", "%r15",
+                      "%rsp"};
+
+static char *
+regster(i)
+int i;
+{
+    return reg_name[i];
+}
+
+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();
+    crn = reg_name[creg];
+    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;
+	lrn = reg_name[lreg];
+	regs[i]=0;
+	return lreg;
+    }
+}
+
+void 
+emit_push()
+{
+    int new_reg;
+    new_reg = get_register();
+    if(new_reg<0) {                     /* もうレジスタがない */
+	if (reg_sp==MAX_MAX-1) {
+	    printf("Compilation error: too complex expression\n");
+	} else {
+	    reg_stack[reg_sp++] =  -1;
+	    printf("\tpushq %s\n",crn);
+	}
+    } else {
+	reg_stack[reg_sp++] = creg;     /* push するかわりにレジスタを使う */
+	creg = new_reg;
+	crn = reg_name[creg];
+    }
+}
+
+char *
+emit_pop()
+{
+    if (pop_register()==-1) {
+	printf("\tpopq %s\n",drn);
+	xrn = drn;
+	xreg = dreg;
+    } else {
+	xrn = lrn;
+	xreg = lreg;
+    }
+    return xrn;
+}
+
+
+void
+emit_compare() 
+{
+    char *orn;
+    orn = emit_pop();
+    printf("\tcmpq %s,%s\n",crn,orn);
+    printf("\t%s %%dl\n","setg");
+    printf("\tmovzbq %%dl,%s\n",crn);
+}
+
+void
+emit_store(assign)
+int assign;
+{
+    int tmp = get_register();
+    printf("\tmovq _v@GOTPCREL(%%rip), %s\n",reg_name[tmp] );
+    printf("\tmovq %s, %d(%s)\n" ,crn, d*8, reg_name[tmp]);
+    free_register(tmp);
+}
+
+void
+emit_load(int d)
+{
+    int tmp = get_register();
+    printf("\tmovq _v@GOTPCREL(%%rip), %s\n",reg_name[tmp]);
+    printf("\tmovq %d(%s),%s\n" ,reg_name[tmp],d*8,crn);
+    free_register(tmp);
+}
+
+
+static
+char *opcode[] = {
+    "",
+    "subq",
+    "addq",
+    "imulq",
+    "idivq",
+    "",
+    "",
+    "",
+    "",
+    "subq",
+    "idivq",
+};
+
+void
+emit_calc(enum opcode op)
+{
+    char *orn;
+    orn = emit_pop();
+    if(op==O_DIV) {
+        //   crn -> rax
+        //   rdx !!!
+        printf("\tcltd\n");
+        printf("\tidivq %s\n",orn);
+    } else if(op==O_SUB) {
+        printf("\t%s %s,%s\n",orn,opcode[op],crn);
+        printf("\tnegq %s\n",crn);
+    } else {
+        printf("\t%s %s,%s\n",orn,opcode[op],crn);
+    }
+}
+
+void
+emit_value(d)
+int d;
+{
+    printf("\tmovq $%d,%s\n",d,crn);
+}
+
+void
+emit_comment()
+{
+    if (before < ptr) {
+    putchar('#'); putchar('#'); putchar(' ');
+    while (before < ptr) {
+        if(*before && *before!='\n') {
+        putchar(*before);
+        }
+        before++;
+    }
+    putchar('\n');
+    }
+}
+
+void
+emit_print()
+{
+    printf("\tmovq %s, %%rdi\n",crn);
+    printf("\tcall _print\n");
+}
+
+
+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 */