changeset 655:cddab906095e

struct init in function arg (or other expression).
author kono
date Sun, 14 Jan 2007 20:30:31 +0900
parents fd2dfa1fa627
children 8320ae3ac186
files .gdbinit Changes Idea Makefile Makefile.powerpc mc-code-arm.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-parse.c mc-parse.h mc.h test/code-gen.c test/strinit.c test/tmp8.c
diffstat 15 files changed, 236 insertions(+), 38 deletions(-) [+]
line wrap: on
line diff
--- a/.gdbinit	Sun Nov 26 21:54:03 2006 +0900
+++ b/.gdbinit	Sun Jan 14 20:30:31 2007 +0900
@@ -45,7 +45,7 @@
 # run -s test/code-gen-inline.c
 # run -s -DINLINE=inline test/basic.c
 # run -s test/too-long-argument.c
-# run -s test/strinit.c
+run -s test/strinit.c
 # run -DINLINE=inline test/scope.c
 # run -DINLINE=inline test/code-gen-all.c
 # run -DINLINE=inline test/bitfield1.c
@@ -58,4 +58,4 @@
 # run -DINLINE=inline test/code-gen-all.c
 # run -s throw.c
 # run -s test/simp.c
-run -s test/ps2.c
+# run -s test/ps2.c
--- a/Changes	Sun Nov 26 21:54:03 2006 +0900
+++ b/Changes	Sun Jan 14 20:30:31 2007 +0900
@@ -9161,3 +9161,45 @@
 offset は、結構複雑になるので、直す方が良いらしい。
 
 時間かける価値あるの? 少しかかりそうだな...
+
+Fri Dec  1 22:45:28 JST 2006
+
+long double の実装ねぇ。
+
+Mon Dec 25 22:02:12 JST 2006
+
+     f((struct arg){.fuga = 3});
+
+が、うまくうごかない。init_vars は、いつどこで評価されるべきなの?
+    decl_str_init
+あたりなみたい。
+
+うーん、結構、壊して来ちゃった。
+
+     f((struct arg){.fuga = g()});
+
+みたいな場合もあるよね?
+    flush_local_static_struct()
+あたりをちゃんと直さないと。
+
+Sat Jan 13 18:52:37 JST 2007
+
+emit_init_vars() は ad-hoc にしちゃだめ。どこで出て来るかわからない
+んだから。
+
+あと、式のcarに0を入れるのは反則なはず。
+
+tmp7.c が通らないぞ。
+
+Sun Jan 14 20:01:03 JST 2007
+
+やっぱり、ちょっと変更が大きいけど、タグに木の大きさを入れるべきだな。
+
+あぁ、そうか。
+
+##      f((struct arg){.fuga = 3,.aho=5});
+
+とかだと、構造体はstackに積めば良い。だが、exprの中で、emit_init_vars
+してしまうと、それは出来ない。deleyed みたいな扱いをすればいい?
+実際に使われるところでemit_init_vars() するみたいな?
+
--- a/Idea	Sun Nov 26 21:54:03 2006 +0900
+++ b/Idea	Sun Jan 14 20:30:31 2007 +0900
@@ -1962,6 +1962,7 @@
 どうせ、だめではあるんだが。引数の型は一段階までしか、
 チェックしないので、だめだね。
 
+
 このあたり、理論的な問題があるみたいだな。
 
     stack を含めた有限な型付け
@@ -1972,3 +1973,102 @@
 そうか、parallel assignment では、同じ部分を前もって探した
 方が効率がよいわけか。(どうせ、やっていることだが)
 
+Sun Nov 26 23:22:12 JST 2006
+
+fp のsave は必要。何故かと言うと、
+    goto f(a,b,...)
+で、後ろの部分がどれだけあるかは、間接的な引数での
+宣言ではわからないから。
+
+stack 上に全部 interface があるなら、良いが、
+部分は register に乗っている。
+
+    goto f(a,b,c,...)
+
+としたときに、... の一部はregisterに乗っている。どれだけ
+乗っているのかを知る必要があるが、それをfpから推察する
+ことはできない。浮動小数点とかの異なる型が散在している
+から。
+
+... で引き渡す引数は、メモリに乗っている必要がある。
+型が明解なら、レジスタ上でもだいじょぶなはずだが。
+
+明示的な引数に大域的には変換できるはずだけど、open 
+な環境では、それはできない。
+
+だとすれば、
+    __code f(int a, int b : int h, ...) {
+       ...
+	goto g(a,b,c : d,e,f,...)
+    }
+みたいな形で、stack 上に乗せる引数を明示する必要がある。
+
+これは、なんなの?
+
+    : の前の引数は可変に出来ない
+    : の後までは可変に出来る
+
+っていうことか。
+
+構造体は、メモリ上に取るとしても..
+
+まぁ、...   のところまでレジスタで、それ以降は、メモリでも
+十分だけどね。いずれにせよ、複雑すぎることは確か。
+
+      __code g(int c,__code (*n)(int a,int b,int d,...),...) {
+	goto n(int d,int e,int c,...);
+      }
+
+で、この... は、すべて、同じものに置き換わるはず。 ... が
+入る場合もあるが。
+
+受け側が
+	__code c(int d,int e,int c,int k,int j) {}
+で定義されているときに、k,j がレジスタに乗っているかも知れず、
+乗っていたらダメダメ。なので、可変になる部分を明示する必要がある。
+
+Mon Nov 27 11:17:39 JST 2006
+
+結局、このn の定義と、実際のn の定義がずれることが問題なんだよね。
+	__code c(int d,int e,int c,...) {}
+で、受けることもあれば、
+	__code c(int d,int e,int c,int k,int j) {}
+で受けることもある。あるいは、
+	__code c(int d,int e,int c,int k,int j,...) {}
+とかも。
+
+implements というか、accetps というか、そんな形の別な
+宣言がいいのかな。
+    __code f(int a, int b : int h, ...) {
+でもいいんだが...
+
+Mon Nov 27 11:34:33 JST 2006
+
+      __code f(int a,int b,...) {
+	goto g(int c,__code *f,int a,int b,...);
+      }
+
+      __code g(int c,__code (*n)(...),...) {
+	goto n(...);
+      }
+
+
+g に入るときに、fp は、n の頭になければならない。これを
+移動するのは、f の役割。出て行くときには、b の頭に
+合わせる必要がある。これは、g の役割。g は、元の頭(fp)
+を知らないから、これは取っておく必要がある。差では
+判断できない。g 側で取っておくことは可能だが、その
+時にも、f 側からずらす大きさを渡す必要がある。
+
+明示しても良いんだけどね...
+	goto g(int c,__code *f,__environment,interface &rest),
+		__envronment+sizeof(interface);
+      __code g(int c,__code (*n)(...),(void*)parent,...) {
+	goto n(...),parent;
+      }
+みたいな形でさ... その方がいいのかな。繁雑だけど。: よりかまし?
+
+: を使う方法だと、: が fp みたいな感じになる。
+
+難しいね。きれいなsyntaxにならない。
+
--- a/Makefile	Sun Nov 26 21:54:03 2006 +0900
+++ b/Makefile	Sun Jan 14 20:30:31 2007 +0900
@@ -92,7 +92,6 @@
 	make check TARGET=test/tmp12
 	make check TARGET=test/tmp5
 	make check TARGET=test/tmp7
-	make check TARGET=test/tmp7
 	make check-inline TARGET=test/tmp8
 	make check TARGET=test/tmp9
 	make check TARGET=test/enum
--- a/Makefile.powerpc	Sun Nov 26 21:54:03 2006 +0900
+++ b/Makefile.powerpc	Sun Jan 14 20:30:31 2007 +0900
@@ -90,7 +90,6 @@
 	make check TARGET=test/tmp12
 	make check TARGET=test/tmp5
 	make check TARGET=test/tmp7
-	make check TARGET=test/tmp7
 	make check-inline TARGET=test/tmp8
 	make check TARGET=test/tmp9
 	make check TARGET=test/enum
--- a/mc-code-arm.c	Sun Nov 26 21:54:03 2006 +0900
+++ b/mc-code-arm.c	Sun Jan 14 20:30:31 2007 +0900
@@ -2198,7 +2198,7 @@
 
 #endif
 
-void
+static void
 use_reg(int arg)
 {
 // printf("## use reg %d\n",arg);
@@ -2219,7 +2219,7 @@
     }
 }
 
-void
+static void
 code_save_input_registers(int dots)
 {
     int args;
@@ -2283,7 +2283,7 @@
     return 0;
 }
 
-int
+static int
 simple_arg(int e3)
 {
     return !contains_p(e3,not_simple_p);
--- a/mc-code-mips.c	Sun Nov 26 21:54:03 2006 +0900
+++ b/mc-code-mips.c	Sun Jan 14 20:30:31 2007 +0900
@@ -1796,7 +1796,7 @@
 
 #endif
 
-void
+static void
 use_reg(int arg)
 {
 // printf("## use reg %d\n",arg);
@@ -1817,7 +1817,7 @@
     }
 }
 
-void
+static void
 code_save_input_registers(int dots)
 {
     int args;
@@ -1904,19 +1904,19 @@
     return 0;
 }
 
-int
+static int
 simple_arg(int e3)
 {
     return !contains_p(e3,not_simple_p);
 }
 
-int
+static int
 caller_arg_offset_v(int arg)
 {
     return ARG_LVAR_OFFSET+arg*SIZE_OF_INT;
 }
 
-void
+static void
 use_input_reg(int reg,int mode)
 {
     if (is_int_reg(reg)) {
--- a/mc-code-powerpc.c	Sun Nov 26 21:54:03 2006 +0900
+++ b/mc-code-powerpc.c	Sun Jan 14 20:30:31 2007 +0900
@@ -1691,7 +1691,7 @@
 	code_lvar(cadr(arg),dreg);
 	for(count=0;count<length;count+=SIZE_OF_INT) {
 	    printf("\tlwz %s,%d(%s)\n",srn,count,crn);
-	    printf("\tstwu %s,%d(%s)\n",srn,count,drn);
+	    printf("\tstw %s,%d(%s)\n",srn,count,drn);
 	}
 	free_register(sreg);
 	free_register(dreg);
@@ -1705,7 +1705,7 @@
     return length/SIZE_OF_INT;
 }
 
-void
+static void
 set_ireg(int reg,int mode)
 {
     if (!is_int_reg(reg)) error(-1);
@@ -1724,7 +1724,7 @@
     creg = ireg = reg;
 }
 
-void
+static void
 set_freg(int reg,int mode)
 {
     if (!is_float_reg(reg)) error(-1);
@@ -1741,7 +1741,7 @@
     creg = freg = reg;
 }
 
-void
+static void
 set_lreg(int reg,int mode)
 {
     if (reg==RET_LREGISTER) {
@@ -1772,7 +1772,7 @@
     }
 }
 
-void
+static void
 set_lreg_operand(int reg,int mode)
 {
     // save_stack,clear_ptr_cache is assumed    
@@ -1785,7 +1785,7 @@
     }
 }
 
-void
+static void
 set_lreg_operand1(int reg,int mode)
 {
     // save_stack,clear_ptr_cache is assumed    
@@ -1798,7 +1798,7 @@
     }
 }
 
-void
+static void
 use_reg(int arg)
 {
 // printf("## use reg %d\n",arg);
@@ -1814,7 +1814,7 @@
     }
 }
 
-void
+static void
 code_save_input_registers(int dots)
 {
     int args;
@@ -1899,7 +1899,7 @@
 
 #define caller_arg_offset_v(arg) (ARG_LVAR_OFFSET+(arg)*SIZE_OF_INT)
 
-void
+static void
 use_input_reg(int reg,int mode)
 {
     if (is_int_reg(reg)) {
--- a/mc-codegen.c	Sun Nov 26 21:54:03 2006 +0900
+++ b/mc-codegen.c	Sun Jan 14 20:30:31 2007 +0900
@@ -621,7 +621,9 @@
         e1=binop(e2,car(e1),cadr(e3),caddr(e3),cadddr(e3));
 	return g_expr0(e1);
     case IVAR:      	  error(-1);	break;
-    case 0:               break; // empty case
+    case 0:               
+	error(-1);
+	break; // empty case
     default:
 	code_bool(e1,USE_CREG); /* type? */
 	return INT;
@@ -2981,7 +2983,7 @@
 	    return glist4(car(e),copy_expr(cadr(e)),caddr(e),cadddr(e));
 	case LVAR: case RLVAR:
 	case GVAR: case RGVAR:
-	    return (e>=lfree)?glist3(car(e),cadr(e),caddr(e)):e;
+	    return (e<gfree)?glist3(car(e),cadr(e),caddr(e)):e;
 	case INDIRECT: case RINDIRECT:
 	    return glist2(car(e),copy_expr(cadr(e)));
 	}
@@ -3004,7 +3006,7 @@
 	    return e;
 	} else if (NULLARY_ARGS(car(e))) {
         /* nullary operators */
-	    if (e>=lfree) { // local
+	    if (e<gfree) { // local
 		int smode = mode;
 		switch(car(e)%SOP) {
 		case GVAR: case RGVAR: case URGVAR:
@@ -3088,7 +3090,7 @@
         p = ((NMTBL*)cadr(car(i)))->nm;
         e1 = car(e); e = cadr(e);
         repl = code_asm_operand(p,e1,ASM_OUTPUT,repl,0,0);
-        if (!chk && car(car(repl))==REGISTER) {
+        if (!chk && repl && car(car(repl))==REGISTER) {
             assign = list2(assign_expr0(e1,car(repl),INT,INT),assign);
         }
     }
@@ -3098,7 +3100,7 @@
         p = ((NMTBL*)cadr(car(i)))->nm;
         e1 = car(e); e = cadr(e);
         repl = code_asm_operand(p,e1,ASM_INPUT,repl,n,repl0);
-        if (!chk && car(car(repl))==REGISTER) {
+        if (!chk && repl && car(car(repl))==REGISTER) {
             g_expr_u(assign_expr0(car(repl),e1,INT,INT));
         }
     }
--- a/mc-parse.c	Sun Nov 26 21:54:03 2006 +0900
+++ b/mc-parse.c	Sun Jan 14 20:30:31 2007 +0900
@@ -88,7 +88,7 @@
  */
 int *heap;                        // heap pointer
 int lfree;                        // local heap top
-static int gfree;                 // global heap top
+int gfree;                        // global heap top
 int heapsize = HEAPSIZE;
 int asmf;                         // in asm (no longer used)
 int bit_field_disp;
@@ -394,6 +394,7 @@
     case UCERR:  // "already used as code segement" :
     case UFERR:  // "already used as function" :
     case ENERR:  // function has return value but reached to the end
+    case RETERR: // return in code segement is not allowed
     return 0;
     }
     return 1;
@@ -462,6 +463,7 @@
 	(n==UFERR) ? "already used as function" :
 	(n==ENERR) ? "function has return value but reached to the end" :
 	(n==CSERR) ? "no excutable code in switch" :
+	(n==RETERR) ? "return in code segement is not allowed" :
 	"Bug of compiler");
     errmsg();
     if (serious(n))
@@ -2451,7 +2453,7 @@
 	decl();
 	mode=STAT;
 	checkret();
-	if (chk) {
+	if (chk) {   // why? kono
 	    p0 = list3(ST_COMP,reverse0(init_vars),0);
 	} else {
 	    emit_init_vars();
@@ -2852,6 +2854,9 @@
 {
     int slfree,e,e1;
 
+    if (is_code(fnptr)) {
+	error(RETERR);
+    }
     if (!inmode && !cslabel) gen_jmp(cslabel = fwdlabel());
     if(getsym(0)==SM) {
 	// should check fnptr have no return value
@@ -3897,17 +3902,39 @@
 		//    initializer
 		//             q->lock = (spinlock_t) { };
 		conv->lc_();
-		smode = mode;
-		type = t;
-		nptr0=new_static_name("__lstruct",'_');
-		mode=STADECL;
-		def(nptr0,0);
-		e1 = size(type);
-		mode = smode;
-		decl_data_field(type,nptr0,0);
+		if (mode==GDECL) {
+		    smode = mode;
+		    type = t;
+		    nptr0=new_static_name("__lstruct",'_');
+		    mode=STADECL;
+		    def(nptr0,0);
+		    e1 = size(type);
+		    mode = smode;
+		    decl_data_field(type,nptr0,0);
+		    e1 = list3(RSTRUCT,list3(GVAR,0,(int)nptr0),e1);
+		} else {
+		    NMTBL n;
+		    nptr0 = &n;
+		    type = t;
+		    nptr0->dsp=new_lvar(e1=size(type));
+		    nptr0->nm = "";
+		    nptr0->ty = t;
+		    nptr0->attr = 0;
+		    nptr0->sc = LVAR;
+#if LOCAL_STRUCT_INIT_STATIC 
+		    local_struct_static(nptr0); 
+#else
+		    decl_data_field(type,nptr0,0);
+#endif
+		    e1 = list3(RSTRUCT,list3(
+			inmode?IVAR:LVAR,nptr0->dsp,(int)nptr0),e1);
+		}
+		if (init_vars && mode!=LDECL) {
+		    emit_init_vars();
+		}
 		conv->rc_();
 		checksym(RC);
-		e1 = list3(RSTRUCT,list3(GVAR,0,(int)nptr0),e1);
+		type = t;
 		return e1;
 	    }
 	    e1=expr13();
@@ -4109,12 +4136,14 @@
 	if (stmode!=GOTO) error(FNERR);
 	// code segment has no return type
 	type = ftype;
+
 	return list4(CODE,e1,arglist,ftype); // should be CODE?
     } else if (stmode==GOTO) {
 	// symbol is undefined at this time
 	// error(GTERR);
     }
 
+
     /* return type */
 
     type = cadr(ftype); 
--- a/mc-parse.h	Sun Nov 26 21:54:03 2006 +0900
+++ b/mc-parse.h	Sun Jan 14 20:30:31 2007 +0900
@@ -149,6 +149,7 @@
 extern int type_value(int type);
 extern int set_type_with_attr(int type,int type_with_attr);
 extern int gset_type_with_attr(int type,int type_with_attr);
+extern int gfree;            /* local free heap top */
 
 
 #if LONGLONG_CODE
--- a/mc.h	Sun Nov 26 21:54:03 2006 +0900
+++ b/mc.h	Sun Jan 14 20:30:31 2007 +0900
@@ -512,7 +512,8 @@
 #define UCERR   34
 #define UFERR   35
 #define ENERR   36
-#define SIERR   37
+#define RETERR   37
+#define SIERR   38
 
 /* error number end */
 
--- a/test/code-gen.c	Sun Nov 26 21:54:03 2006 +0900
+++ b/test/code-gen.c	Sun Jan 14 20:30:31 2007 +0900
@@ -21,6 +21,13 @@
 	unsigned int i;
 	unsigned long long l;
     } u;
+    printf("sizeof(int)=%d\n",sizeof(char));
+    printf("sizeof(short)=%d\n",sizeof(short));
+    printf("sizeof(int)=%d\n",sizeof(int));
+    printf("sizeof(long long)=%d\n",sizeof(long long));
+    printf("sizeof(float)=%d\n",sizeof(float));
+    printf("sizeof(double)=%d\n",sizeof(double));
+    printf("sizeof(long double)=%d\n",sizeof(long double));
     u.s = 0x0123;
     printf("#0025:endian s : %02x %02x\n",u.a[0],u.a[1]);
     u.i = 0x01234567;
--- a/test/strinit.c	Sun Nov 26 21:54:03 2006 +0900
+++ b/test/strinit.c	Sun Jan 14 20:30:31 2007 +0900
@@ -1,6 +1,7 @@
 #include <stdio.h>
 
 void main7();
+int main8();
 
 int b[3] = {1,2,3};
 
@@ -88,6 +89,7 @@
     printf("#0085:2: %d\n",temp8.e);
     printf("#0086:2: %d\n",temp6.e);
     main7();
+    main8();
     linux_kernel();
     return 0;
 }
@@ -228,4 +230,18 @@
 
 }
 
+
+
+struct arg { int hage, fuga; int aho; };
+
+void f(struct arg h) {
+    printf("%d %d %d\n",h.hage,h.fuga,h.aho);
+}
+
+int main8() {
+     f((struct arg){.fuga = 3,.aho=5});
+}
+
+
+
 // end
--- a/test/tmp8.c	Sun Nov 26 21:54:03 2006 +0900
+++ b/test/tmp8.c	Sun Jan 14 20:30:31 2007 +0900
@@ -28,9 +28,11 @@
 {
    int k = 0,i;
 
+   char *q = alloca(100);
    char *p = alloca(asize<100?100:asize);
    for(i=0;i<100;i++) p[i]=i;
    for(i=0;i<100;i++) k += p[i];
+   for(i=0;i<100;i++) q[i]=i;
    return k;
 }