diff mc-codegen.c @ 445:5ec2a88b9f4d const-attribute

const
author kono
date Sun, 21 Nov 2004 19:20:18 +0900
parents 8bec605d1701
children 6654aa80851b
line wrap: on
line diff
--- a/mc-codegen.c	Sun Nov 21 11:20:56 2004 +0900
+++ b/mc-codegen.c	Sun Nov 21 19:20:18 2004 +0900
@@ -786,8 +786,8 @@
 	error(-1);
     }
     n->sc  = LVAR;
-    lvar = list2(LVAR,n->dsp);
-    g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),t,t));
+    lvar = list3(LVAR,n->dsp,(int)n);
+    g_expr_u(assign_expr0(list3(LVAR,n->dsp,(int)n),list3(tag,reg,(int)n),t,t));
     if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) {
 	free_register(reg);
     return g_expr0(lvar);
@@ -928,7 +928,7 @@
 	*target = append4(*target,t,ty,e1);
 #endif
     } else {
-	g_expr_u(assign_expr0((e1=list2(LVAR,new_lvar(sz))),s,ty,ty));
+	g_expr_u(assign_expr0((e1=list3(LVAR,new_lvar(sz),0)),s,ty,ty));
 	*target = append4(*target,t,ty,e1);
 	*use=list3(t,*use,e1);
     }
@@ -1132,7 +1132,7 @@
 	    target=list4(r, target,ty,e2); regs+=2;
 	} else {
 	    while(car(e2)==RSTRUCT) e2=cadr(e2);
-	    target=list4(list2(LVAR,0), target,ty,e2);
+	    target=list4(list3(LVAR,0,0), target,ty,e2);
 	}
         /* keep arg space for register variables */
         arg_size += sz;
@@ -1161,7 +1161,7 @@
 	}
         arg_size-=sz;
 	if (!is_simple(car(s0))) {
-	    g_expr_u(assign_expr0((e4=list2(LVAR,new_lvar(sz))),s0,ty,ty));
+	    g_expr_u(assign_expr0((e4=list3(LVAR,new_lvar(sz),0)),s0,ty,ty));
 	    use=list3(ty,use,e1);
 	    cadddr(e2)=e4;
 	    s0=e4;
@@ -1201,8 +1201,8 @@
 		    default: caddr(e2) = UNSIGNED; r = 4;
 		    }
 		    if (e4==4) e3=cadr(e2);
-		    car(e2) =  list2(LVAR,cadr(t0)+e4);
-		    cadddr(e2) = list2(LVAR,cadr(s0)+e4);
+		    car(e2) =  list3(LVAR,cadr(t0)+e4,0);
+		    cadddr(e2) = list3(LVAR,cadr(s0)+e4,0);
 		    source=list3( cadddr(e2), source,r);
 		    e4 += r;
 #if DEBUG_PARALLEL_ASSIGN
@@ -2071,7 +2071,7 @@
 	}
 	/*  new = &e2 */
 	/*  *new = *new op e3 */
-	n = list2(LVAR,new_lvar(size_of_int));
+	n = list3(LVAR,new_lvar(size_of_int),0);
 	g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT));
 	g_expr(assign_expr0(list2(INDIRECT,n),list3(op,n,e3),t,t));
 	free_lvar(cadr(n));
@@ -2161,7 +2161,7 @@
 	}
 	/*  new = &e2 */
 	/*  *new = *new op e3 */
-	n = list2(LVAR,new_lvar(size_of_int));
+	n = list3(LVAR,new_lvar(size_of_int),0);
 	g_expr_u(assign_expr0(n,list2(ADDRESS,e2),INT,INT));
 	g_expr(assign_expr0(list2(INDIRECT,n),
 			list3(op,list2(LRINDIRECT,n),e3),t,t));
@@ -2442,7 +2442,7 @@
  */
 
 extern NMTBL *
-def(NMTBL *n)
+def(NMTBL *n,int ctmode)
 {
     int sz,nsc,ndsp;
     int sbit_f = bit_field_disp;
@@ -2458,14 +2458,16 @@
     if(type>0&&(car(type)==FUNCTION || car(type)==CODE)) {
 	if ((mode==GDECL)) {
 	    fcheck(n);
+	    n->attr = ctmode;
 	    return n;
 	    /* function and code segment are defined using fdecl/code_decl */
             /* in decl() */
 	}
     }
     if (mode==GSDECL||mode==LSDECL) {
-          /* Struct fields name lists are in the struct type or tag. */
-          /* Only name in the table is used. Do not set n->ty! */
+        /* Struct fields name lists are in the struct type or tag. */
+        /* Only name in the table is used. Do not set n->ty! */
+	/* Struct field may volatile... where do I put? list2(VOLATILE,type)? */
 	if (car(type)==BIT_FIELD) {
 	    bit_field_disp=sbit_f;   // default is 0, recover only here.
             //        type = list4(BIT_FIELD,value type,
@@ -2526,6 +2528,7 @@
 	    }
 	}
 	gpc +=sz;
+	n->attr = list2(ctmode,0);
 	return n;
     case GSDECL: case LSDECL:
 	disp += sz;
@@ -2578,6 +2581,7 @@
 	} else {
 	    n->ty = type;
 	}
+	n->attr = ctmode;
 	return n;
     case STAT: /* return (struct hoge)f() case? */
     case LDECL:
@@ -2603,12 +2607,14 @@
 	}
 	n->sc = nsc;
 	n->dsp = ndsp;
+	n->attr = list2(ctmode,0);
 	return n;
     default:
 	error(DCERR);
     }
     n->sc = nsc;
     n->dsp = ndsp;
+    n->attr = list2(ctmode,0);
     if (stmode==EXTRN)
 	n->sc = EXTRN;
     return n;
@@ -2723,10 +2729,13 @@
 	    /* empty space in partial initialization */
 	    return offset+cadr(e);
 	}
+	/* If this is a local declared constant, we don't have to assign.
+           But some one may take it's address. We have to generate assign.
+         */
 	ass = assign_expr0(
     (n->sc==REGISTER||n->sc==DREGISTER||n->sc==FREGISTER||n->sc==LREGISTER)?
 	    list3(n->sc,n->dsp,(int)n):
-	    list2(LVAR,n->dsp+offset),
+	    list3(LVAR,n->dsp+offset,0),
 	e,t,type);
 	init_vars = list2(ass,init_vars);
     } else if(mode==SFDINIT) {
@@ -2744,6 +2753,10 @@
 #endif
 	return offset+sz;
     }
+    /* constant value field */
+    if (offset==0 && n && car(n->attr)==KONST) {
+	cadr(n->attr) = e;
+    }
     return offset+((t==EMPTY)?cadr(e):size(t));
 }
 
@@ -2799,6 +2812,7 @@
 	    n1->dsp = n->dsp;
 	    n->ty =  n1->ty;
 	    n->sc =  n1->sc;
+	    n->attr =  n1->attr;
 	    cadddr(j)=sz= cadddr(i);
 	    if (sz==1||sz==size_of_short) sz = size_of_int;
 	    dsp += sz;
@@ -2847,8 +2861,8 @@
 	if ((sz=size(cadr(fntype)))==-1) error(TYERR);
 	else {
 	    args = 0;
-	    def(&str_ret);
-	    struct_return = list3(list2(LVAR,str_ret.dsp),sz,type);
+	    def(&str_ret,0);
+	    struct_return = list3(list3(LVAR,str_ret.dsp,0),sz,type);
 	    caddr(fnptr->ty) = glist2(POINTER,caddr(fnptr->ty));
 	}
 	type = type_save;
@@ -2954,6 +2968,7 @@
 rvalue(int e)
 {
     int op;
+    NMTBL *n;    
 
     if (e==0) error(-1);
     op = 0;
@@ -3000,9 +3015,17 @@
     }
     switch(car(e)) {
     case GVAR:
+	n = (NMTBL*)caddr(e);
+	if (cadr(e)==0 && n->attr && car(n->attr)==KONST) {
+	    if (cadr(n->attr)) return cadr(n->attr);
+	}
 	return(list3(RGVAR+op,cadr(e),caddr(e)));
     case LVAR:
-	return(list2(RLVAR+op,cadr(e)));
+	n = (NMTBL*)caddr(e);
+	if (n && car(n->attr)==KONST) {
+	    if (cadr(n->attr)) return cadr(n->attr);
+	}
+	return(list3(RLVAR+op,cadr(e),caddr(e)));
     case INDIRECT:
 	return(indirect(RINDIRECT+op,cadr(e)));
     default:return(e); /* idempotent case? */
@@ -3096,7 +3119,7 @@
 	    e=list3(GVAR,cadr(e)+dsp,caddr(e));
 	    break;
 	case LVAR:
-	    e=list2(LVAR,cadr(e) + dsp);
+	    e=list3(LVAR,cadr(e) + dsp,0);  /* may have attribute */
 	    break;
 	case INDIRECT:
 	    e=list2(INDIRECT,list3(ADD,cadr(e),list2(CONST,dsp)));
@@ -3337,8 +3360,13 @@
     int e=0;
     int us = 0;
 
-    if(t1>0&&car(t1)==POINTER) { type = t2; e2= int_value(e2); t2=INT; }
-    else if(t2>0&&car(t2)==POINTER) { type = t1; e1= int_value(e1); t1=INT; }
+    if(t1>0&&car(t1)==POINTER) { 
+	if(!(op==SUB && t2>0&&car(t2)==POINTER))  {
+	    type = t2; e2= int_value(e2); t2=INT; 
+	}
+    } else if(t2>0&&car(t2)==POINTER) { 
+	type = t1; e1= int_value(e1); t1=INT; 
+    }
 #if FLOAT_CODE
     else if(t1==DOUBLE||t2==DOUBLE)
 	return dbinop(op,e1,e2,t1,t2);
@@ -3387,8 +3415,13 @@
 		e=e1-e2; type=INT;
 	    } else {
 		if(car(t1)!=POINTER) error(TYERR);
-		e=e1-size(cadr(t1))*e2;
-		type=t1;
+		if(integral(t2)) {
+		    e=e1-size(cadr(t1))*e2;
+		    type=t1;
+		} else {
+		    e=(e1-e2)/size(cadr(t1));
+		    type=INT;
+		}
 	    }
 	    break;
 	case MUL:
@@ -3462,8 +3495,11 @@
 	if (car(e)==CONST) {
 	    if(car(e1)==ADDRESS) {
 		if (car(cadr(e1))!=GVAR) {
+		    // must be lvar
+		    if (car(cadr(e1))!=LVAR) error(-1);
 		    return(list2(ADDRESS,
-			list2(car(cadr(e1)),cadr(cadr(e1))+cadr(e))));
+			list3(car(cadr(e1)),cadr(cadr(e1))+cadr(e),
+				caddr(cadr(e1)))));
 		} else {
 		    return(list2(ADDRESS,
 			list3(GVAR,cadr(cadr(e1))+cadr(e),caddr(cadr(e1)))));
@@ -3471,7 +3507,7 @@
 	    } else if(car(e1)==GVAR) {
 		return(list3(GVAR,cadr(e1)+cadr(e),caddr(e1)));
 	    } else if(car(e1)==LVAR) {
-		return(list2(LVAR,cadr(e1)+cadr(e)));
+		return(list3(LVAR,cadr(e1)+cadr(e),0));
 	    }
 	}
 	return(list3(ADD,e1,e));
@@ -3632,11 +3668,11 @@
     if (lo) {
 #if LONGLONG_CODE
 	if (post) {
-	    n1 = list2(LVAR,new_lvar(size_of_longlong));
+	    n1 = list3(LVAR,new_lvar(size_of_longlong),0);
 	    code_lassign_lvar(cadr(n1),USE_CREG);
 	}
 	if (!code_lassop_p) {
-	    n2 = list2(LVAR,new_lvar(size_of_longlong));
+	    n2 = list3(LVAR,new_lvar(size_of_longlong),0);
 	    code_lassign_lvar(cadr(n2),USE_CREG);
 	    lassign(list4(LASSOP,n2,e3,op+LOP));
 	} else {
@@ -3649,7 +3685,7 @@
 #endif
     } else {
 	if (post) {
-	    n1 = list2(LVAR,new_lvar(size_of_int));
+	    n1 = list3(LVAR,new_lvar(size_of_int),0);
 	    code_assign_lvar(cadr(n1),USE_CREG,0);
 	}
 	emit_push();