changeset 449:c55363eff5e5

parallel assignment (modify not completed)
author kono
date Thu, 25 Nov 2004 16:56:26 +0900
parents 422415e15eb8
children eaf9e2746c83
files Changes Makefile mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-code.h mc-codegen.c mc-codegen.h mc-parse.c mc.h test/test1.c test/tmp1.c test/tmp6.c
diffstat 14 files changed, 317 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Mon Nov 22 22:52:12 2004 +0900
+++ b/Changes	Thu Nov 25 16:56:26 2004 +0900
@@ -6765,3 +6765,66 @@
 // #define hash_value(hash,ch) (hash = (37*hash)^((unsigned char)(ch)))
 
 なのかぁ。open hash だからか。
+
+Wed Nov 24 13:21:03 JST 2004
+
+レジスタの
+        mov creg, regv
+        add creg,$3
+        mov regv, creg
+はなんとかしたいよね。
+
+goto 文で、parallel assignment が、
+        i+1
+みたいな場合に、
+        mov creg,regv
+        add creg,$1
+        store creg,lvar
+        load creg,lvar
+みたいなのを出してしまう。それは、i+1 がis_memory でないから。
+単純に、これを残すと、source list にi が入らないので、iをoverwrite
+されてしまう。
+
+で、is_contains_p1 で、source を列挙すると、parallel_assign が
+止まらなくなる。(何故?)
+
+remove0(soruce) で含まれているsourceを全部落し切れないからだね。
+save したあと、source を書き換えるわけだけど、その部分が考慮されてない。
+うーん、ちょっと諦めた方が良いみたいだなぁ。
+
+やっぱ、まじめに parallel assign かかないとだめなんじゃないの?
+
+えーと、
+     i = i+1
+ってのがあると、i=i でないから消えないで残る。これを処理する方法が
+ないわけね。でも、circular dependency にならないのは何故?
+
+Thu Nov 25 09:05:24 JST 2004
+
+progress で捕まえられているんだから、そこでなんとかする?
+
+dependency singleton を見つければ良いわけだよね。複数見つかっていれば
+save しているはずなわけだから。
+
+circlular dependency に渡されているのはsourceの「一つのメモリ」であって、
+式でない。だから、circular dependency ではoverlap を見つけられないわけ
+だね。
+
+うーん、やっぱり、adhoc なわりに複雑になってしまう。これだったら、CSE
+を真面目にやった方がいいんじゃないかなぁ。
+
+tmp1 は、違うエラーだな。code4 の中のprintf が j を壊しているね。
+なんで、r30 から負のoffset をcaller が爆撃するんだ?
+
+r1 を延ばして片付けたけど... そういえば、register の分を code
+segement ではメモリに割り振らないって話はどうしたの? 
+
+    list5(target,next, ty, source, source-dependency)
+
+だよね。そうすると、source list から単純にremoveできない。他の
+dependencyを削除しちゃうかも知れないから。なので、source は、
+やめて、list5 を直接使った方が良い? そうすれば、target を
+remove すれば自動的にremoveされるので...
+
+progress でなんとかすると、やっぱり、全部 save されちゃうね。
+toplogical sort しないとだめか。
--- a/Makefile	Mon Nov 22 22:52:12 2004 +0900
+++ b/Makefile	Thu Nov 25 16:56:26 2004 +0900
@@ -103,11 +103,11 @@
 	make check-code$(MK) TARGET=test/fact-a
 	make check-code$(MK) TARGET=test/fact
 	make check-code$(MK) TARGET=test/goto
-#	make check-code$(MK) TARGET=test/test1
-#	make check-code$(MK) TARGET=test/tmp1
+	make check-code$(MK) TARGET=test/test1
+	make check-code$(MK) TARGET=test/tmp1
 	make check-code$(MK) TARGET=test/tmp2
 	make check-code$(MK) TARGET=test/tmp4
-#	make check-code$(MK) TARGET=test/tmp6
+	make check-code$(MK) TARGET=test/tmp6
 	make check-code$(MK) TARGET=test/scope
 
 check-nkf:
--- a/mc-code-arm.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc-code-arm.c	Thu Nov 25 16:56:26 2004 +0900
@@ -2231,7 +2231,7 @@
     my_func_args = offset;
 }
 
-static int
+int
 not_simple_p(int e3)
 {
     switch(e3) {
--- a/mc-code-ia32.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc-code-ia32.c	Thu Nov 25 16:56:26 2004 +0900
@@ -3743,4 +3743,22 @@
 
 #endif
 
+int
+not_simple_p(int e3)
+{
+    switch(e3) {
+        case FUNCTION: case CONV: case STASS: case ALLOCA:
+        case LDIV: case LUDIV: case LMOD: case LUMOD:
+        case LMUL: case LUMUL:
+        case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT:
+        case DDIV: case DADD: case DSUB: case DMUL: case DMINUS:
+        case DPOSTINC : case DPREINC : case DASSOP :
+        case DOP+LT : case DOP+LE : case DOP+GT : case DOP+GE :
+        case DOP+EQ : case DOP+NEQ:
+        case RBIT_FIELD: case BASS: case BASSOP:
+        return 1;
+    }
+    return 0;
+}
+
 /* end */
--- a/mc-code-mips.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc-code-mips.c	Thu Nov 25 16:56:26 2004 +0900
@@ -1831,7 +1831,7 @@
     my_func_args = offset;
 }
 
-static int
+int
 not_simple_p(int e3)
 {
     return (e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS||e3==ALLOCA||
--- a/mc-code-powerpc.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc-code-powerpc.c	Thu Nov 25 16:56:26 2004 +0900
@@ -274,7 +274,7 @@
  function call stack frame
                       <-------r1_offset------------------------------>
                                       <------------lvar_offset0------>
-                      <--lvar_offset-->
+                      <--lvar_offset-->          r30(?)              r1
  r+  +------------+---+---------------+----------+--------------+----+    -
       callee arg   xx   register save   local      caller arg     xx
                           reg_save      disp       max_func_args*SIZE_OF_INT
@@ -291,11 +291,15 @@
                               *SIZE_OF_INT                  *SIZE_OF_INT
 
  */
-int arg_offset = 24; int arg_offset1 = 24; int disp_offset = -12;
+static int arg_offset = 24; 
+static int arg_offset1 = 24; 
+int disp_offset = -12;
 // #define func_disp_offset 60
 #define func_disp_offset 68
 #define r1_offset func_disp_offset+12 
-int code_disp_offset = 0; int jump_offset = 0;
+static int code_disp_offset = 0; 
+// static int jump_offset = 0;
+
 #define CODE_LVAR l+code_disp_offset
 #define CODE_CALLER_ARG (l-ARG_LVAR_OFFSET)+arg_offset1
 #define FUNC_LVAR l+disp_offset
@@ -1770,7 +1774,7 @@
     my_func_args = offset;
 }
 
-static int
+int
 not_simple_p(int e3)
 {
     return e3==FUNCTION||e3==CONV/*||e3==RSTRUCT*/||e3==STASS|| 
@@ -2750,7 +2754,7 @@
 {
     int r1_offsetv;
     disp&= -SIZE_OF_INT;
-    r1_offsetv = -disp+max_func_args*SIZE_OF_INT+code_disp_offset+8;
+    r1_offsetv = -disp+max_func_args*SIZE_OF_INT +code_disp_offset +8+32;
 
     printf(".set L_%d,%d\n",code_disp_label,-r1_offsetv);
     if (max_func_arg_label) {
--- a/mc-code.h	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc-code.h	Thu Nov 25 16:56:26 2004 +0900
@@ -45,6 +45,7 @@
 extern void enter1();
 extern void leave(int control, char *name);
 extern void jmp(int l);
+extern int not_simple_p(int l);
 
 extern int get_register_var(NMTBL *n);
 extern int get_dregister_var(NMTBL *n,int d);
--- a/mc-codegen.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc-codegen.c	Thu Nov 25 16:56:26 2004 +0900
@@ -849,7 +849,9 @@
 /*     source (after) list2(tag,disp)                       */
 /* source list    list3(e,cdr,sz)                           */
 
-#define DEBUG_PARALLEL_ASSIGN 0
+#define DEBUG_PARALLEL_ASSIGN 7
+
+static int is_memory(int e1);
 
 static int
 overlap(int t,int sz,int source)
@@ -962,12 +964,15 @@
     return 0;
 }
 
+static void remove_a(int source,int s);  // remove all child
+
 static void
 parallel_assign(int *target,int *source,int *processing,int *use)
 {
-    int t,s,sz,ty,target0,s1;
+    int t,s,sz,ty,target0,s1,progress;
     while(*target) {
 	target0=*target;
+	progress = 0;
 	while(target0) {
 	    t=car(target0); s=cadddr(target0);
 	    sz=size(ty=caddr(target0)); 
@@ -976,26 +981,40 @@
 #if DEBUG_PARALLEL_ASSIGN
 printf("# remove same %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz);
 #endif
-		remove_target(target,t,use);
-		/* 破壊されては困るので、source listからは除かない */
+		remove_target(target,t,use); remove_a((int)source,s);
+		progress = 1;
 	    } else if (!(s1=overlap(t,sz,*source))) {
 		/* 重なってないので安心して書き込める */
 #if DEBUG_PARALLEL_ASSIGN
 printf("# normal assign %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz);
 #endif
 		g_expr_u(assign_expr0(t,s,ty,ty));
-		remove_target(target,t,use); remove0(source,s);
+		remove_target(target,t,use); remove_a((int)source,s);
+		progress = 1;
 	    } else {
 		if(circular_dependency(t,s1,target,source)) {
 #if DEBUG_PARALLEL_ASSIGN
     printf("# saving %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz);
 #endif
-		    remove_target(target,t,use); remove0(source,s);
+		    remove_target(target,t,use); remove_a((int)source,s);
 		    save_target(t,s,target,use,sz,ty);
+		    progress = 1;
 		}
 	    }
 	    target0=cadr(target0);
 	}
+	if (!progress) {
+	    // can't performe parallel assign
+	    // error(-1);
+	    target0 = *target;
+	    t=car(target0); s=cadddr(target0);
+	    sz=size(ty=caddr(target0)); 
+#if DEBUG_PARALLEL_ASSIGN
+printf("# can't progress save any %d ty %d+%d sz %d\n",car(s),ty,cadr(t),sz);
+#endif
+	    remove_target(target,t,use); remove_a((int)source,s);
+	    save_target(t,s,target,use,sz,ty);
+	}
     }
 }
 
@@ -1012,21 +1031,23 @@
     }
 }
 
-/*
-static void 
-remove0_all(int *parent,int e) 
+static int
+remove_1(int source,int e)
 {
-    int list;
-    while ((list=*parent)) {
-	if (car(list)==e) {
-	    *parent= cadr(list);
-	} else {
-	     parent=&cadr(list);
-	}
+    int sz;
+    if ((sz=is_memory(e))) {
+	remove0((int*)source,e);
     }
+    return source;
 }
- */
-
+
+static void
+remove_a(int source,int s)
+{
+    contains_p1(source,s,remove_1);
+}
+
+#ifdef SAVE_ALL_NON_MEMORY
 static int
 is_simple(int e1) 
 {
@@ -1040,7 +1061,7 @@
     }
     return 0;
 }
-
+#endif
 
 static int
 is_same_type(int e1,int e2)
@@ -1085,17 +1106,45 @@
 is_memory(int e1)
 {
     switch(car(e1)) {
-	case LVAR : case RLVAR: case CRLVAR  : case DRLVAR  : case LRLVAR :
-	case GVAR : case RGVAR: case CRGVAR  : case DRGVAR  : case LRGVAR :
-	case FRLVAR  : case FRGVAR :
-	case CURGVAR : case SURGVAR: case SRGVAR :
-	case REGISTER : case DREGISTER  : case FREGISTER :
-	case LREGISTER:
+    case CRLVAR  :
+    case CRGVAR  :
+    case CURGVAR :
 	return 1;
+    case SURGVAR:
+    case SRGVAR :
+	return size_of_short;
+    case LVAR :
+    case RLVAR:
+    case GVAR :
+    case REGISTER :
+    case RGVAR:
+	return size_of_int;
+    case FRLVAR  :
+    case FRGVAR :
+    case FREGISTER :
+	return size_of_float;
+    case DRLVAR  :
+    case DRGVAR  :
+    case DREGISTER  :
+	return size_of_double;
+    case LRGVAR :
+    case LRLVAR :
+    case LREGISTER:
+	return size_of_longlong;
     }
     return 0;
 }
 
+static int
+check_source(int source,int e)
+{
+    int sz;
+    if ((sz=is_memory(e))) {
+	source = list3(e,source,sz);
+    }
+    return source;
+}
+
 #define ASSIGN_STRUCT_DIVIDE 40
 
 static void
@@ -1155,7 +1204,12 @@
 	    cadr(t0)=-arg_size;
 	}
         arg_size-=sz;
+#ifdef SAVE_ALL_NON_MEMORY
 	if (!is_simple(car(s0))) {
+#else
+	if (contains_p(s0,not_simple_p)) {
+#endif
+	    /* complex case */
 	    g_expr_u(assign_expr0((e4=list3(LVAR,new_lvar(sz),0)),s0,ty,ty));
 	    use=list3(ty,use,e1);
 	    cadddr(e2)=e4;
@@ -1211,6 +1265,9 @@
 #if DEBUG_PARALLEL_ASSIGN
 printf("# source %d ty %d+%d sz %d\n",car(car(source)),ty,cadr(car(source)),sz);
 #endif
+	} else {
+	    /* check used sources in rather complex source */
+	    source = contains_p1(source,s0,check_source);
 	}
     }
     /* compute jump address */
@@ -2364,6 +2421,52 @@
     return 0;
 }
 
+static int
+contains_in_list_p1(int arg,int e,int (*p)(int,int))
+{
+    while(e) {
+	arg=contains_p1(arg,car(e),p);
+	e = cadr(e);
+    }
+    return arg;
+}
+
+extern int
+contains_p1(int arg,int e,int (*p)(int,int))
+{
+    while(e) {
+	if (!car(e)) return arg;
+	if (LIST_ARGS(car(e))){
+        /* list arguments */
+	    return contains_in_list_p1(arg,caddr(e),p);
+	} else if (UNARY_ARGS(car(e))) {
+        /* unary operators */
+	    e = cadr(e);
+	    continue;
+	} else if (BINARY_ARGS(car(e))) {
+        /* biary operators */
+	    arg=contains_p1(arg,cadr(e),p);
+	    e = caddr(e);
+	    continue;
+	} else if (TARNARY_ARGS(car(e))) {
+        /* tarary operators */
+	    arg=contains_p1(arg,cadr(e), p);
+	    arg=contains_p1(arg,caddr(e),p);
+	    e = cadddr(e);
+	    continue;
+	} else if (NULLARY_ARGS(car(e))) {
+        /* nullary operators */
+	    arg=p(arg,e);
+	    return arg;
+	} else {
+	    // fprintf(stderr,"Unknown Tree ID %d\n",car(e));
+	    // error(-1);
+	    return arg;
+	}
+    }
+    return arg;
+}
+
 #if ASM_CODE
 
 
--- a/mc-codegen.h	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc-codegen.h	Thu Nov 25 16:56:26 2004 +0900
@@ -77,6 +77,7 @@
 extern int assign_expr0(int e1,int e2,int t,int type0) ;
 extern int b_expr(int e1, char cond, int l1,int err);
 extern int contains_p(int e,int (*p)(int));
+extern int contains_p1(int arg,int e,int (*p)(int,int));
 extern void fwddef(int l);
 extern int fwdlabel(void);
 extern int g_expr(int e1);
--- a/mc-parse.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc-parse.c	Thu Nov 25 16:56:26 2004 +0900
@@ -4029,6 +4029,20 @@
     return e;
 }
 
+extern int
+list5(int e1, int e2, int e3, int e4,int e5)
+{
+    int e;
+
+    e=getfree(5);
+    heap[e]=e1;
+    heap[e+1]=e2;
+    heap[e+2]=e3;
+    heap[e+3]=e4;
+    heap[e+4]=e5;
+    return e;
+}
+
 static int
 getfree(int n)
 {
@@ -4219,9 +4233,11 @@
 extern int c1(int d)  { fprintf(stderr,"heap[%d]=",d);return cadr(d); }
 extern int c2(int d)  { fprintf(stderr,"heap[%d]=",d);return caddr(d); }
 extern int c3(int d)  { fprintf(stderr,"heap[%d]=",d);return cadddr(d); }
+extern int c4(int d)  { fprintf(stderr,"heap[%d]=",d);return caddddr(d); }
 extern char *cc0(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)car(d); }
 extern char *cc1(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)cadr(d); }
 extern char *cc2(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)caddr(d); }
 extern char *cc3(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)cadddr(d); }
+extern char *cc4(int d) { fprintf(stderr,"heap[%d]=",d);return (char *)caddddr(d); }
 
 /* end */
--- a/mc.h	Mon Nov 22 22:52:12 2004 +0900
+++ b/mc.h	Thu Nov 25 16:56:26 2004 +0900
@@ -140,7 +140,7 @@
 #define FNAME  	9
 #define LABEL  	10
 
-#define NULLARY_ARGS(i) (i==REGISTER||i==DREGISTER||i==FREGISTER||i==LREGISTER||(GVAR<=(i%SOP)&&(i%SOP)<=LABEL))
+#define NULLARY_ARGS(i) (i==RETURN||i==ENVIRONMENT||i==REGISTER||i==DREGISTER||i==FREGISTER||i==LREGISTER||(GVAR<=(i%SOP)&&(i%SOP)<=LABEL))
 
 /* unary  argments */
 
@@ -461,6 +461,8 @@
 
 #define cadddr(e) (heap[((int)(e))+3])
 
+#define caddddr(e) (heap[((int)(e))+4])
+
 #if FLOAT_CODE
 #define dcadr(e) (*(double*)&heap[((int)(e))+1])
 #define dcaddr(e) (*(double*)&heap[((int)(e))+2])
--- a/test/test1.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/test/test1.c	Thu Nov 25 16:56:26 2004 +0900
@@ -1,7 +1,13 @@
+/*
+    test for CbC converted code from C
+ */
+
 #include "stdio.h"
 
 typedef void *stack;
 
+void *stack0;      /* size of void* == 1 */
+
 struct cont_save { /* General Return Continuation */
     code (*ret)();
 };
@@ -34,13 +40,13 @@
 code f(int i,void *sp) {
     int k,j;
     struct f_g0_save *c;
-printf("#0036:f 0 sp: %x\n",sp);
+printf("#0036:f 0 sp: %x\n",sp-stack0);
 
     k = 3+i;
 
-printf("#0040:f 1 sp: %x\n",sp);
+printf("#0040:f 1 sp: %x\n",sp-stack0);
     sp -= sizeof(struct f_g0_save);
-printf("#0042:f 2 sp: %x\n",sp);
+printf("#0042:f 2 sp: %x\n",sp-stack0);
     c = sp;
     c->kk = k;
     c->ii = i;
@@ -50,8 +56,6 @@
 }
 
 
-void *stack0;
-
 
 struct f0_save {  /* Specialized Return Continuation */
 	code (*ret)();
@@ -63,15 +67,15 @@
 code f0(int i,int j,code(*exit2)(), void *exit2env,void *sp)
 {
 	struct f0_save *c;
-    printf("#0065:f0 1 sp: %x\n",sp);
+    printf("#0065:f0 1 sp: %x\n",sp-stack0);
 	sp -= sizeof(struct f0_save);
-    printf("#0067:f0 2 sp: %x\n",sp);
+    printf("#0067:f0 2 sp: %x\n",sp-stack0);
 	c = sp;
 	c->jj = j;
         c->exit1 = exit2;
         c->exit1env = exit2env;
 	c->ret = f1;
-    printf("#0073:f0 3 sp: %x\n",sp);
+    printf("#0073:f0 3 sp: %x\n",sp-stack0);
 	goto f(i,sp);
 }
 
@@ -101,7 +105,7 @@
     sp = stack0;
     j = i;
     
-    printf("#0103:sp: %x\n",sp);
+    printf("#0103:sp: %x %x\n",sp-(int*)stack0,sizeof(*stack0));
     goto f0(i,j,return,environment,sp);
 }
 
--- a/test/tmp1.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/test/tmp1.c	Thu Nov 25 16:56:26 2004 +0900
@@ -1,56 +1,86 @@
+/* easy test */
 
-main(ac,av)
+code (*ret)();
+void *env;
+
+main0(ac,av)
 int ac;
 char *av[];
 {
-    if (ac>1)
-	goto code1(av,return);
+    ret = return;
+    env = environment;
+    printf("main0 %d start.\n",ac);
+    if (ac>=1)
+	goto code0(ac,av,return);
     goto code1(ac,av,exit1);
+    // not reached. (warning?)
+    printf("main0 %d end.\n",ac);
 }
 
-code exit1(int ac,int av)
+code exit1(int ac)
 {
-    exit(0);
+    // exit(0);
+    goto code3(0,1,2,3,4,5);
 }
 
 code code3(a,b,c,d,e,f)
 char a,b;
 int c,d,e,f;
 {
-    if(a)
-	goto code3(a,b,c,d,e,f);
+    printf("code3: %d %d %d %d %d %d\n",a,b,c,d,e,f);
+    if(a<10)
+	goto code3(a+1,b,c,d,e,f);
     else
-	goto code3(a+3,b+3,c+3,d+3,e+3,f+3);
+	goto code4(a+3,b+3,c+3,d+3,e+3,f+3);
 }
 
 code code4(a,b,c,d,e,f)
 char a,b;
 int c,d,e,f;
 {
-    int i,j;
-    if(a)
+    int i=1,j=2;
+    printf("code4: %d %d %d %d %d %d\n",a,b,c,d,e,f);
+    if(a<20)   // cyclic binary dependency
+	goto code3(a+b,b+c,c+d,d+e,e+f,f+a);
+    else if(a<30)
 	goto code3(a,b,c,d,e,f);
-    else
-	goto code3(a+i,b+j,c+i,d+3,e+3,f+3);
+    else if(a<40) // cyclic dependency
+	goto code3(b,c,a,e,f,d);
+    else if(a<50)
+	goto code4(a+i,b+j,c+i,d+3,e+3,f+3);
+    else goto ret(0),env;
 }
 
-code code0(ac,av)
+code code0(ac,av,ret)
 int ac;
 char *av[];
+code ret();
 {
-    goto code0(ac,av);
+    goto code1(ac,av,ret);
 }
 
 code code1(ac,av,exit)
 int ac,exit;
 char *av[];
 {
-    code (*f)();
+    code (*f)(int);
+    printf("code1: %d\n",ac);
     f = exit;
     if (ac>3)
-	goto code1(ac,av);
+	goto code1(ac,av,f);
     else if (ac>2)
-	goto code1(av,ac);
+	goto code1(av,ac,f);
     else
-	goto (*f)(ac,av);
+	goto (*f)(ac),env;
 }
+
+int
+main(int ac,char *av[])
+{
+   main0(1,av);
+   printf("main continue.\n");
+   main0(0,av);
+   printf("main end.\n");
+}
+
+/* end */
--- a/test/tmp6.c	Mon Nov 22 22:52:12 2004 +0900
+++ b/test/tmp6.c	Thu Nov 25 16:56:26 2004 +0900
@@ -1,5 +1,7 @@
 #include "stdio.h"
 
+char *a[] = {"test1","2"};
+
 int
 main(ac,av)
 int ac;
@@ -8,11 +10,13 @@
     int i;
 
     if(ac!=2)	{
-	fprintf(stderr,"must have one neumeric argument.\n");
-	return(0);
+	fprintf(stdout,"a used.\n");
+	// return(0);
+	i=main0(2,a,return,environment);
+        return 0;
     }
     i=main0(ac,av,return,environment);
-    fprintf(stderr,"1: %s %d\n",av[0],i);
+    fprintf(stdout,"1: %s %d\n",av[0],i);
     return 0;
 }
 
@@ -27,7 +31,7 @@
     i=123;
     j=456;
     k = atoi(av[1]);
-    fprintf(stderr,"2: av=%x av[0]=%x %s\n",av,av[0],av[0]);
+    fprintf(stdout,"2: av=%x av[0]=%x %s\n",av==a,av[0]==a[0],av[0]);
     goto code0(i,j,k,av,ret,retenv,return,environment);
 }
 
@@ -41,7 +45,7 @@
 {
     char *p;
     p = av[0];
-    fprintf(stderr,"3: i=%d j=%d k=%d av=%x p=%s\n",i,j,k,av,p);
+    fprintf(stdout,"code0\n",av[0]);
     goto code1(i,j,k,av,ret,retenv,ret1,ret1env);
 }
 
@@ -53,7 +57,7 @@
 code (*ret1)();
 void *ret1env;
 {
-    fprintf(stderr,"4: %s\n",av[0]);
+    fprintf(stdout,"4: %s\n",av[0]);
     goto code2(i,j,k,av,ret,retenv,ret1,ret1env);
 }
 
@@ -65,8 +69,8 @@
 code (*ret1)();
 void *ret1env;
 {
-    fprintf(stderr,"5: %s\n",av[0]);
-    fprintf(stderr,"5: i=%d j=%d k=%d av=%x\n",i,j,k,av);
+    fprintf(stdout,"5: %s\n",av[0]);
+    fprintf(stdout,"5: i=%d j=%d k=%d av=%x\n",i,j,k,av==a);
     if (k>3)
 	goto (*ret1)(1234),ret1env;
     goto (*ret)(1234),retenv;