changeset 750:f28900807fd9

i64 continue... first printf worked.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 14 Nov 2010 01:49:40 +0900
parents 593f15532e76
children c921670e2ce8
files mc-code-i64.c mc-codegen.c mc-parse.c
diffstat 3 files changed, 127 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/mc-code-i64.c	Sun Nov 14 00:22:33 2010 +0900
+++ b/mc-code-i64.c	Sun Nov 14 01:49:40 2010 +0900
@@ -789,7 +789,7 @@
 
     init_src = init_src0;
     size_of_int = SIZE_OF_INT;
-    size_of_pointer = SIZE_OF_INT;
+    size_of_pointer = SIZE_OF_LONGLONG;
     size_of_short = SIZE_OF_SHORT;
     size_of_float = SIZE_OF_FLOAT;
     size_of_double = SIZE_OF_DOUBLE;
@@ -1589,7 +1589,7 @@
     xrn = register_name((e2=emit_pop(0)),0);
     use_int(reg);
     if (use)
-	printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,SIZE_OF_INT));
+	printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,0));
     printf("\t%s $%d,(%s)\n",(sz==1)?"addb":(sz==SIZE_OF_SHORT)?"addw":"addl",dir,xrn);
     emit_pop_free(e2);
 }
@@ -1933,6 +1933,29 @@
 #define caller_arg_offset_v(arg) (ARG_LVAR_OFFSET+(arg)*SIZE_OF_INT)
 
 /*
+     use input register as current register
+ */
+
+static void
+use_input_reg(int reg,int mode)
+{
+    if (is_int_reg(reg)) {
+        if (ireg&&reg == ireg) {
+            if (creg==ireg) creg = 0;
+            ireg = 0;
+        }
+    } else if (is_float_reg(reg)) {
+        if (freg&&reg == freg) {
+            if (creg==freg) creg = ireg;
+            freg = 0;
+        }
+    }
+    if (mode) 
+        regs[reg]=USING_REG;
+}
+
+
+/*
     Eary implementation uses pushl arg for function call. gcc
     use the same arguement evaluation order. Of course, the
     order is unspecified in C language, but it is better to
@@ -2068,13 +2091,12 @@
     int e2,e3,e4,e5,nargs,t;
     int arg,reg_arg,freg_arg,arg_assign;
     int dots;
-    int reg_arg_list=0,ret_type,special_lvar;
+    int reg_arg_list=0,ret_type;
     NMTBL *fn = 0;
     int jmp = 0;
     int complex_;
     int pnargs,preg_arg,pfreg_arg;
     int stargs;
-    int half_register = 0;
 #if (ARG_ORDER==1)
     int save_delayed_arg = delayed_arg;
     int as_save = AS_ARG;  // 1st pushed argment will evaluate at the last
@@ -2083,7 +2105,6 @@
     const int as_save = AS_SAVE;
 #endif
 
-    special_lvar = -1;
     ret_type = function_type(cadddr(e1),&dots);
     if (caddr(cadddr(e1))==0) dots=1;
 
@@ -2111,9 +2132,6 @@
     pnargs = preg_arg = pfreg_arg = 0;
     for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {    
         t=caddr(e3);
-        if (reg_arg==3 && (t==DOUBLE||t==LONGLONG||t==ULONGLONG)) {
-            half_register=1;
-        }
         if ((e5= !simple_arg(car(e3)))) {
             if (complex_) {
                 arg = get_input_arg(caddr(complex_),as_save,
@@ -2227,6 +2245,28 @@
         g_expr_u(assign_expr0(arg,e4,t,t));
         car(e3)=0;  // done
     }
+    nargs = reg_arg = freg_arg = 0;
+    for (e3 = e1; e3;
+                increment_function_arg(e3,&nargs,&reg_arg,&freg_arg),
+                e3 = cadr(e3)) {
+        if (!(e4=car(e3))) continue;
+        t=type_value(caddr(e3));
+        arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg);
+        if(scalar(t)||t==LONGLONG||t==ULONGLONG) {
+            reg_arg_list = list2(arg,reg_arg_list);
+            /* protect from input register free */
+            if (car(arg)==REGISTER||car(arg)==LREGISTER)
+                use_input_reg(cadr(arg),1);
+            g_expr_u(assign_expr0(arg,e4,t,t));
+        } else if (t==DOUBLE||t==FLOAT) {
+            reg_arg_list = list2(arg,reg_arg_list);
+            if (car(arg)==DREGISTER)
+                use_input_reg(cadr(arg),1); /* protect from input register free */
+            g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */
+        }
+        // structs are finished
+    }
+
     if (max_func_args<nargs) max_func_args=nargs;
     for(;arg_assign;arg_assign=cadr(arg_assign)) {
         g_expr_u(car(arg_assign));
--- a/mc-codegen.c	Sun Nov 14 00:22:33 2010 +0900
+++ b/mc-codegen.c	Sun Nov 14 01:49:40 2010 +0900
@@ -4559,6 +4559,12 @@
 #if LONGLONG_CODE
 
 static int
+lintegral(int t)
+{
+    return (t==LONGLONG||t==ULONGLONG);
+}
+
+static int
 lbinop(int op, int e1, int e2, int t1, int t2)
 {
     int e=0;
@@ -4571,9 +4577,8 @@
 	type=t2; e2=ulonglong_value(e2);
 	t1=t2=ULONGLONG;
     } else {
-	type=t1; e1=longlong_value(e1);
-	type=t2; e2=longlong_value(e2);
-	t1=t2=LONGLONG;
+	if(!(t1>0&&car(t1)==POINTER)) { type=t1; e1=longlong_value(e1); t1 = LONGLONG;}
+	if(!(t2>0&&car(t2)==POINTER)) { type=t2; e2=longlong_value(e2); t2 = LONGLONG;}
     }
     if(car(e1)==LCONST&&car(e2)==LCONST) {
 	le1=lcadr(e1);
@@ -4586,9 +4591,34 @@
 	case BAND:
 	    le=le1&le2;break;
 	case ADD:
-	    le=le1+le2;break;
+	    if(lintegral(t1)) {
+		if(lintegral(t2)) {
+			le=le1+le2;
+		} else {
+			if(car(t2)!=POINTER) error(TYERR);
+			le=size(cadr(t2))*le1+le2;
+			type=t2;
+		}
+	    } else {
+		if(car(t1)!=POINTER) error(TYERR);
+		le=le1+size(cadr(t1))*le2;
+		type=t1;
+	    }
+	    break;
 	case SUB:
-	    le=le1-le2; type=LONGLONG; break;
+	    if(lintegral(t1)) {
+		le=le1-le2; type=LONGLONG;
+	    } else {
+		if(car(t1)!=POINTER) error(TYERR);
+		if(lintegral(t2)) {
+		    le=le1-size(cadr(t1))*le2;
+		    type=t1;
+		} else {
+		    le=(le1-le2)/size(cadr(t1));
+		    type=LONGLONG;
+		}
+	    }
+	    break;
 	case MUL:
 	    le=le1*le2;break;
 	case DIV:
@@ -4640,6 +4670,47 @@
 		)) {
 	e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e;
     }
+    if(op==ADD) {
+	if(lintegral(t1)) {
+	    if(lintegral(t2)) {
+		// if(t1==INT) type=t2;else type=t1;
+		if (us) type=ULONGLONG; else type=LONGLONG;
+		return(list3(LADD,e1,e2));
+	    }
+	    if(car(t2)!=POINTER) error(TYERR);
+	    e=lbinop(MUL,e1,llist2(LCONST,size(cadr(t2))),t1,LONGLONG);
+	    type=t2;
+	    return(list3(LADD,e,e2));
+	}
+	if(car(t1)!=POINTER||!lintegral(t2)) error(TYERR);
+	e=lbinop(MUL,e2,llist2(LCONST,size(cadr(t1))),t2,LONGLONG);
+	type=t1;
+	if (car(e)==LCONST && lcadr(e)==0)
+	    return(e1);
+	return(lvalue_opt(list3(LADD,e1,e)));
+    }
+    if(op==SUB) {
+	if(lintegral(t1)) {
+	    if(!lintegral(t2)) error(TYERR);
+	    if(t1==LONGLONG) type=t2;else type=t1;
+	    if (type==ULONGLONG) type=LONGLONG;
+	    return(list3(LSUB,e1,e2));
+	}
+	if(car(t1)!=POINTER) error(TYERR);
+	if(lintegral(t2)) {
+	    e=binop(MUL,e2,llist2(LCONST,size(cadr(t1))),t2,LONGLONG);
+	    type=t1;
+	    if (car(e)==LCONST) error(-1);
+	    return(list3(LSUB,e1,e));
+	}
+	if(car(t2)!=POINTER)
+	    error(TYERR);
+	compatible(t1,t2);
+	e=list3(LSUB,e1,e2);
+	e=lbinop(DIV,e,llist2(LCONST,size(cadr(t1))),LONGLONG,LONGLONG);
+	type= LONGLONG;
+	return e;
+    }
     if((op==MUL||op==DIV)&&car(e2)==LCONST&&lcadr(e2)==1) return e1;
     if(op==BOR||op==EOR||op==BAND||op==ADD||op==SUB) {
 	return(list3(op+LOP,e1,e2));
@@ -4684,10 +4755,12 @@
     // for inmode, destructive modification e1,e2,t1,t2 is not allowed
 
     if(t1>0&&car(t1)==POINTER) { 
+	if (lp64) return lbinop(op,e1,e2,t1,t2);
 	if(!(op==SUB && t2>0&&car(t2)==POINTER))  {
 	    type = t2; e2= int_value(e2); t2=INT; 
 	}
     } else if(t2>0&&car(t2)==POINTER) { 
+	if (lp64) return lbinop(op,e1,e2,t1,t2);
 	type = t1; e1= int_value(e1); t1=INT; 
     }
 #if FLOAT_CODE
--- a/mc-parse.c	Sun Nov 14 00:22:33 2010 +0900
+++ b/mc-parse.c	Sun Nov 14 01:49:40 2010 +0900
@@ -1438,6 +1438,7 @@
 	case LONGLONG: return size_of_longlong;
 	case ULONGLONG: return size_of_longlong;
 	case ENUM: return size_of_int;
+	case POINTER: return size_of_pointer;
 	default:
 	    if(scalar(t)) return size_of_int;
 	    error(DCERR);