Mercurial > hg > CbC > old > device
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); +}