changeset 637:140b65f8ff03

ARRAY argument in fuction
author kono
date Tue, 31 Oct 2006 20:42:42 +0900
parents 72c4a8137fff
children 35014112c01d
files Changes README README.jp mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-parse.c test/ps2.c
diffstat 10 files changed, 135 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/Changes	Wed Oct 11 18:38:15 2006 +0900
+++ b/Changes	Tue Oct 31 20:42:42 2006 +0900
@@ -8933,3 +8933,88 @@
 use_data_reg() で初期化してない変数を使ってました。
 
 "hoge" "hage" を #ifdef で挟むと動かない... (ふーん...)
+
+escape() 内部で処理したのが間違いだったみたいだね。
+このコードは呼ばれないはずなので取り去るべき。
+
+Thu Oct 12 00:05:15 JST 2006
+
+switch 文で、行き先がおなじ分を「まとめる」ってのを
+してない。range にまとめられるなら、それが有利か。
+
+Thu Oct 12 12:08:36 JST 2006
+
+    code hoge(i,j,cont,...);
+
+    code hoga(int a,int b,int k, int l, int m);
+    {
+        int i,j,k,l,m;
+	code (*cont)(int,int,...);
+	goto hoge(i,j,hoga,k,l,m);
+    }
+
+    code hoge(int i,int j,code (*cont)(int,int,...), ...) {
+	goto cont(i,j,...);
+    }
+
+の実装なんだけど.... fix typed stack あるいは、bounded stack かな?
+
+                 * gotoを呼び出した関数のr1 ! r1(goto前のr1)
+   #             *                           r30 <---r1_offset---------> r1
+r+ +----------+--+----------+----------------+-----------+----------+----+
+    cousin arg xx  reg save !callee arg      !code local  caller arg  xx
+                   r20-r29     lvar>0         lvar<0      lvar>0x1000 000
+                   f20-f31  <-my_func_args--><--disp-----><-max_func_arg->
+                              *SIZE_OF_INT                  *SIZE_OF_INT
+
+長さが知り得ないので、code local variable をどこに取っていいか
+わからないという問題がある。ふん。 
+
+呼び出されたときのstack (っていうのかな?) top を見れば良いのかな?
+local variable 分も入っているようですが.. まぁ、r30 使っても
+いいんだけど。
+
+ということは、「隠れて、code segment argument の長さを持ち歩く」
+ってことだね。その方が良い。
+
+あぁ、でも、PowerPC とかだと、local variable は、r30 からの
+固定オフセットで取っているのか。いや、そんなことないな。
+r1 からアクセスしているようですね。
+
+いや、関数呼び出しの時の引数をr1から積んでいるらしい。
+これは変更しないとだめだね。
+
+i386 でも、%ebp からアクセスしているな。
+
+      | frame pointer                     | stack pointer
+      v----> argument      local <--------v
+
+という形にしないとだめか。stdarg を使うためには、順序を関数呼び出しに
+合わせないとだめだが...
+
+つまり、local variable を CALLER ARG 上にとってやれば
+良いらしい。問題は、stack をずらしたとき(alloca)に、
+pointer がずれるってことだが... (それはcopyするか...)
+
+逆に言えば、これをやれば、動きます。ということだね。メモリの
+アクセス範囲は | frame pointer --> <--- stack pointer |
+に閉じるわけか。
+
+意味的には、全体を展開してしまえば、全部固定長になるので、
+問題はない。
+
+ちょっと、修正が多いかな...
+
+Wed Oct 18 21:35:36 JST 2006
+
+GVAR の dsp は(initialization のフラグ以外) 空いているので、
+ここに、asm("alias") の属性を入れるのは構わない。まぁ、毎回、
+attribute チェックしてもいいんだけど。そんなけちる意味もな
+いので、alias field をNMTBL に足してもいいんだけどね。
+
+function の場合は、属性に入れるんでしょ?
+
+Tue Oct 31 20:16:16 JST 2006
+
+関数の引数に固定長の配列を渡すと破綻するらしい。
+gcc には可変長配列ってのもあるにはあるんだよな。
--- a/README	Wed Oct 11 18:38:15 2006 +0900
+++ b/README	Tue Oct 31 20:42:42 2006 +0900
@@ -124,6 +124,7 @@
 //    Long is equal to an int and a pointer (32bit).
 
 Only Mac OS X and Red hat Linux is supported.
+Intel Mac is supported.
 
 Inline directive is ignored and gives normal function definition.
 
--- a/README.jp	Wed Oct 11 18:38:15 2006 +0900
+++ b/README.jp	Tue Oct 31 20:42:42 2006 +0900
@@ -132,6 +132,7 @@
 //    long は32bit. int もpointerも同じ。
 
 Mac OS X と Red hat Linux だけでテストしてあります。
+Intel Mac でも動作します。
 
 // Inline は無視され、普通のstatic関数にコンパイルされます。 
 
--- a/mc-code-arm.c	Wed Oct 11 18:38:15 2006 +0900
+++ b/mc-code-arm.c	Tue Oct 31 20:42:42 2006 +0900
@@ -2440,7 +2440,7 @@
     } else if (t==FLOAT) {
 	reg_arg ++ ; freg_arg++;
 	nargs += size(t)/SIZE_OF_INT;
-    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	nargs += round4(size(t))/SIZE_OF_INT;
     } else {
 	error(TYERR);
@@ -2485,7 +2485,7 @@
 	    return list3(LVAR,caller_arg_offset_v(nargs),0);
 	} else
 	    return get_input_dregister_var(reg_arg,0,0,1);
-    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	if (mode==AS_SAVE) {
 	    return get_register_var(0);
 	} else
@@ -2565,12 +2565,12 @@
 	    pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg;
 	    complex_ = e3;
 	}
-	if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+	if (t>=0&&(car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	    // The struct should be pushed after complex arguments.
 	    if (e5) { // compute address only, complex_ is me now. Clear it.
 		complex_ = 0;
 		e4 = car(e3);
-		if (car(e4)!=RSTRUCT) error(-1);
+		if (car(e4)!=RSTRUCT && car(e4)!=ARRAY) error(-1);
 		if (!simple_arg(cadr(e4))) {
 		    // Calculate complex struct address here.
 		    // If simple, leave it.
@@ -3481,7 +3481,8 @@
 #endif
 	} else if (cadr(fnptr->ty)>0&&(
 	    car(cadr(fnptr->ty))==STRUCT ||
-	    car(cadr(fnptr->ty))==UNION)) {
+	    car(cadr(fnptr->ty))==UNION ||
+	    car(cadr(fnptr->ty))==ARRAY)) {
 	    sz = size(cadr(fnptr->ty));
 	    inc_inst(3);
 	    code_const(sz,REGISTER_OPERAND);
--- a/mc-code-ia32.c	Wed Oct 11 18:38:15 2006 +0900
+++ b/mc-code-ia32.c	Tue Oct 31 20:42:42 2006 +0900
@@ -1539,7 +1539,7 @@
 	} else if (t==FLOAT) {
 	    nargs += SIZE_OF_FLOAT/SIZE_OF_INT;
 	    continue;
-	} else if (car(t)==STRUCT||car(t)==UNION) {
+	} else if (car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY) {
 	    // struct must align 16 (but how?)
 	    length = size(t);
 	    if (length%SIZE_OF_INT)
@@ -1598,7 +1598,7 @@
 	    nargs += SIZE_OF_FLOAT/SIZE_OF_INT;
 	    stack_depth += SIZE_OF_FLOAT;
 	    continue;
-	} else if (car(t)==STRUCT||car(t)==UNION) {
+	} else if (car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY) {
 	    nargs += push_struct(e4,t);
 	    continue;
 	} else {
@@ -2243,7 +2243,8 @@
 	    printf("\tfldl %d(%%ebp)\n",-SIZE_OF_DOUBLE);
         } else if (cadr(fnptr->ty)>0&&(
             car(cadr(fnptr->ty))==STRUCT ||
-            car(cadr(fnptr->ty))==UNION)) {
+            car(cadr(fnptr->ty))==UNION ||
+            car(cadr(fnptr->ty))==ARRAY)) {
             sz = size(cadr(fnptr->ty));
 	    set_ireg(RET_REGISTER,0);
             printf("\tmovl %d(%%ebp),%s\n",disp-SIZE_OF_INT,
--- a/mc-code-mips.c	Wed Oct 11 18:38:15 2006 +0900
+++ b/mc-code-mips.c	Tue Oct 31 20:42:42 2006 +0900
@@ -2026,7 +2026,7 @@
     } else if (t==FLOAT) {
 	reg_arg ++ ; freg_arg++;
 	nargs += size(t)/SIZE_OF_INT;
-    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	nargs += round4(size(t))/SIZE_OF_INT;
     } else {
 	error(TYERR);
@@ -2075,7 +2075,7 @@
 	    return list3(LVAR,caller_arg_offset_v(nargs),0);
 	} else
 	    return get_input_dregister_var(reg_arg,0,0,1);
-    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	if (mode==AS_SAVE) {
 	    return get_register_var(0);
 	} else
@@ -2157,7 +2157,7 @@
 	    pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg;
 	    complex_ = e3;
 	}
-	if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+	if (t>=0&&(car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	    // The struct should be pushed after complex arguments.
 	    if (e5) { // compute address only, complex_ is me now. Clear it.
 		complex_ = 0;
--- a/mc-code-powerpc.c	Wed Oct 11 18:38:15 2006 +0900
+++ b/mc-code-powerpc.c	Tue Oct 31 20:42:42 2006 +0900
@@ -1970,7 +1970,7 @@
 	}
 	freg_arg++;
 	nargs += size(t)/SIZE_OF_INT;
-    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+    } else if (t>=0&&(car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	nargs += round4(size(t))/SIZE_OF_INT;
     } else {
 	error(TYERR);
@@ -2024,6 +2024,11 @@
 	    return get_register_var(0);
 	} else
 	    return list3(LVAR,caller_arg_offset_v(nargs),0);
+    } else if (t>=0&&(car(t)==ARRAY)) {
+	if (mode==AS_SAVE) {
+	    return get_register_var(0);
+	} else
+	    return list3(LVAR,caller_arg_offset_v(nargs),0);
     } else {
 	error(-1);
 	return get_register_var(0);
@@ -2078,12 +2083,12 @@
 	    pnargs=nargs;preg_arg=reg_arg;pfreg_arg=freg_arg;
 	    complex_ = e3;
 	}
-	if (t>=0&&(car(t)==STRUCT||car(t)==UNION)) {
+	if (t>=0&&(car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	    // The struct should be pushed after complex arguments.
 	    if (e5) { // compute address only, complex_ is me now. Clear it.
 		complex_ = 0;
 		e4 = car(e3);
-		if (car(e4)!=RSTRUCT) error(-1);
+		if (car(e4)!=RSTRUCT && car(e4)!=ARRAY) error(-1);
 		if (!simple_arg(cadr(e4))) {
 		    // Calculate complex struct address here.
 		    // If simple, leave it.
--- a/mc-codegen.c	Wed Oct 11 18:38:15 2006 +0900
+++ b/mc-codegen.c	Tue Oct 31 20:42:42 2006 +0900
@@ -2266,7 +2266,7 @@
             //            list3(type /*store type*/,0 /*bit offset*/,bitsize));
 	    e2 = correct_type(e2,cadr(t)); /* value type */
 	    return(list4(BASS,e1,e2,list2(BASS,t)));
-	case STRUCT:case UNION:
+	case STRUCT:case UNION: case ARRAY:
 	    if (size(t)!=size(type)) error(TYERR);
 	    type=t;    // dispose attr
 	    if(car(e2)==RSTRUCT && car(cadr(e2))==FUNCTION) {
@@ -3437,7 +3437,7 @@
 }
 
 //
-// local variable initialization
+// local/global variable initialization
 //
 
 extern int
--- a/mc-parse.c	Wed Oct 11 18:38:15 2006 +0900
+++ b/mc-parse.c	Tue Oct 31 20:42:42 2006 +0900
@@ -4024,7 +4024,7 @@
 
     argtypes = caddr(type0);
     if (!argtypes) dots=1;
-    if ((t=type_value(cadr(type0)))>=0 && (car(t)==STRUCT||car(t)==UNION)) {
+    if ((t=type_value(cadr(type0)))>=0 && (car(t)==STRUCT||car(t)==UNION||car(t)==ARRAY)) {
 	/* skip return struct pointer */
 	if (argtypes==0) error(-1);
 	argtypes = cadr(argtypes);
@@ -4067,7 +4067,7 @@
     type0 = type_value(type);
     if(type0==CHAR||type0==SHORT) type=set_type_with_attr(INT,type);
     else if(type0==UCHAR||type0==USHORT) type=set_type_with_attr(UNSIGNED,type);
-    else if(type0>0 && (car(type0)==STRUCT||car(type0)==UNION)) {
+    else if(type0>0 && (car(type0)==STRUCT||car(type0)==UNION||car(type0)==ARRAY)) {
 
 	/* temporal struct is required */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/ps2.c	Tue Oct 31 20:42:42 2006 +0900
@@ -0,0 +1,23 @@
+
+int printf(const char *,...);
+
+typedef float        ps2_vu0_fmatrix[4][4] __attribute__((aligned (16)));
+typedef ps2_vu0_fmatrix FMATRIX;
+
+
+void  ps2_vu0_unit_matrix(ps2_vu0_fmatrix m);
+
+
+void  ps2_vu0_unit_matrix(ps2_vu0_fmatrix m)
+{
+    printf("%g\n",m[1][1]);
+}
+
+int
+main(int ac, char *av[])
+{
+    FMATRIX m;
+
+    m[1][1] = 0.5;
+    ps2_vu0_unit_matrix(m);
+}