# HG changeset patch # User kono # Date 1087225886 -32400 # Node ID f73b93de216aa4aacacf1619740e137c4dd6a6dd # Parent a93e619cf7723cc6637c041242735c0ca90e943c alloca done for ia32, powerpc, mips diff -r a93e619cf772 -r f73b93de216a Changes --- a/Changes Sat Jun 12 15:58:56 2004 +0900 +++ b/Changes Tue Jun 15 00:11:26 2004 +0900 @@ -4899,3 +4899,47 @@ sizeof(typeof(hoge)); ((typeof (hoge)) fuga) みたいな感じ。 + +なんか g() で、register_save が出ちゃってるね。 + +Sun Jun 13 12:20:39 JST 2004 + +ia32 の alloca は、関数の引数に呼び出されるのはまずい。あと、 +stack の途中も、まずい。じゃぁ、どうするの? + a = alloca(3)+3; + f(i,alloca(3),j); +みたいなのでも破綻しちゃうのね。 + +powerpc でも結構奥が深いな。関数呼び出し時の引数は、 +r1 相対でつまないとだめ。そうだよね。というか、 +最初から r1 相対で積めよ。 + + lwz r2,0(r1) + neg r0,r0 + stwux r2,r1,r0 + addi r2,r1,208 + addi r0,r2,15 + srwi r0,r0,4 + slwi r0,r0,4 + stw r0,208(r30) <=== 最初のlocal 変数のアドレス。 + b L26 +L25: + li r0,0 + stw r0,208(r30) +L26: + +ってわけか。 + +うーん、 + int i; + goto f(alloca(100),&i); +なのってあるよね。だとすれば、local 変数はつぶさない方が +いいのか。その方が簡単か。そうすると絶対に local 変数と +goto の引数は重ならないから parallel assignment の必要 +ないし。なんで、最初からそうしなかったんだろう? + +しかし、そうするにはどこ直せば良いんだろう? max-func-arg? + +Mon Jun 14 20:48:13 JST 2004 + +PowerPC の alloca は動いたけど... diff -r a93e619cf772 -r f73b93de216a mc-code-ia32.c --- a/mc-code-ia32.c Sat Jun 12 15:58:56 2004 +0900 +++ b/mc-code-ia32.c Tue Jun 15 00:11:26 2004 +0900 @@ -63,6 +63,7 @@ static int reg_sp; /* REGister Stack-Pointer */ static int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +int stack_depth = 0; /* floating point registers */ @@ -227,6 +228,7 @@ #define __externsion__\n\ #define __flexarr\n\ #define wchar_t int\n\ +#define __GNUC__ 2\n\ "; void @@ -471,6 +473,7 @@ if (freg_sp>0) error(-1); reg_sp = 0; freg_sp = 0; + stack_depth = 0; text_mode(); gexpr_code_init(); register_usage("gexpr_init"); @@ -599,6 +602,7 @@ if (reg_sp>=MAX_MAX) error(-1); reg_stack[reg_sp++] = -1; printf("\tpushl %s\n",register_name(creg,0)); + stack_depth += SIZE_OF_INT; /* creg is used soon, don't regv[creg]=0 */ } else { reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ @@ -622,6 +626,7 @@ } printf("\tpopl %s\n",register_name(dreg,0)); regv[dreg]=1; + stack_depth -= SIZE_OF_INT; return dreg; } else if (xreg<= -REG_LVAR_OFFSET) { code_rlvar(xreg+REG_LVAR_OFFSET,dreg); @@ -1096,6 +1101,7 @@ regv[xreg]=1; } else free_register(xreg); + stack_depth += length*SIZE_OF_INT; return length/SIZE_OF_INT; } @@ -1105,6 +1111,8 @@ int e2,e3,e4,nargs,t,ret_type; NMTBL *n=0; int save,saved; + int stack_depth_save = stack_depth; + ret_type = cadr(cadddr(e1)); if (ret_type==CHAR) ret_type=INT; @@ -1135,6 +1143,7 @@ g_expr(e4); printf("\tpushl %s\n",register_name(creg,0)); } + stack_depth += SIZE_OF_INT; } else if (t==LONGLONG||t==ULONGLONG) { if (car(e4)==LREGISTER) { printf("\tpushl %s\n\tpushl %s\n",l_edx(cadr(e4)),l_eax(cadr(e4))); @@ -1143,17 +1152,20 @@ printf("\tpushl %%edx\n\tpushl %%eax\n"); } ++nargs; + stack_depth += SIZE_OF_INT*2; } else if (t==DOUBLE) { g_expr(e4); printf("\tleal\t-8(%%esp),%%esp\n\tfstpl\t(%%esp)\n"); nargs += SIZE_OF_DOUBLE/SIZE_OF_INT; fregv[freg]=0; + stack_depth += SIZE_OF_DOUBLE; continue; } else if (t==FLOAT) { g_expr(e4); printf("\tleal\t-4(%%esp),%%esp\n\tfstps\t(%%esp)\n"); nargs += SIZE_OF_FLOAT/SIZE_OF_INT; fregv[freg]=0; + stack_depth += SIZE_OF_FLOAT; continue; } else if (car(t)==STRUCT||car(t)==UNION) { nargs += struct_push(e4,t); @@ -1202,10 +1214,36 @@ use_register(creg,REG_EAX,0); fregv[freg]=0; regv[creg]=1; } + stack_depth = stack_depth_save; return ret_type; } void +code_alloca(int e1,int reg) +{ + char *crn,*drn; + int edx; + + g_expr(list3(BAND,list3(ADD,e1,list2(CONST,15)),list2(CONST,~15))); + use_int(reg); + if (stack_depth>0) { + edx = edx_setup(-1); + crn = register_name(reg,0); + drn = register_name(edx,0); + printf("\tmovl %%esp,%s\n",drn); + printf("\tsubl %s,%%esp\n",crn); + printf("\tmovl %%esp,%s\n",crn); + emit_copy(edx,creg,stack_depth,0,1,1); + printf("\taddl $%d,%s\n",stack_depth,register_name(creg,0)); + edx_cleanup(); + } else { + crn = register_name(reg,0); + printf("\tsubl %s,%%esp\n",crn); + printf("\tmovl %%esp,%s\n",crn); + } +} + +void code_frame_pointer(int e3) { use_int(e3); printf("\tmovl %s,%%ebp\n",register_name(e3,0)); @@ -1474,9 +1512,11 @@ oprtc(int op,int reg,int orn) { char *crn; + int datareg; use_int(reg); crn = register_name(reg,0); orn = cadr(orn); + datareg=(rname[reg]nm); l = ARG_LVAR_OFFSET; @@ -326,7 +342,7 @@ } else if (l<0) { /* local variable */ printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ - printf("lo16(%d)(r30)\n",CALLER_ARG); + printf("lo16(%d)(r1)\n",CALLER_ARG); } else { /* callee's arguments */ printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label); } @@ -353,7 +369,7 @@ printf("la r0,ha16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ if (CALLER_ARG>32765) - printf("la r0,ha16(%d)(r30)\n",CALLER_ARG); + printf("la r0,ha16(%d)(r1)\n",CALLER_ARG); } else { /* callee's arguments */ printf("la r0,ha16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label); } @@ -373,7 +389,7 @@ if (CALLER_ARG>32765) printf("lo16(%d)(r0)\n",CALLER_ARG); else - printf("lo16(%d)(r30)\n",CALLER_ARG); + printf("lo16(%d)(r1)\n",CALLER_ARG); } else { /* callee's arguments */ printf("lo16(%d+L_%d)(r0)\n",CALLEE_ARG,r1_offset_label); } @@ -391,15 +407,6 @@ lvar(e2); } -char *init_src = "\ -#define __ppc__ 1\n\ -#define __BIG_ENDIAN__ 1\n\ -#define __STDC__ 1\n\ -#define __builtin_va_list int\n\ -#define __builtin_va_start(ap,arg) ap=(((int)(&arg))+sizeof(arg))\n\ -#define __builtin_va_arg(ap,type) (*((type *)ap)++)\n\ -"; - void code_init(void) { @@ -1784,7 +1791,7 @@ { return e3==FUNCTION||e3==CONV||e3==RSTRUCT||e3==STASS|| e3==LLSHIFT||e3==LULSHIFT||e3==LRSHIFT||e3==LURSHIFT|| - e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD||e3==LASSOP; + e3==LDIV||e3==LUDIV||e3==LMOD||e3==LUMOD||e3==LASSOP||e3==ALLOCA; } static int @@ -1950,6 +1957,7 @@ } #else ret_type = function_type(cadddr(e1),&dots); + if (caddr(cadddr(e1))==0) dots=1; #endif arg_assign = 0; @@ -2180,6 +2188,28 @@ } void +code_alloca(int e1,int reg) +{ + char *crn,*grn; + int g; + + g_expr(list3(BAND,list3(ADD,e1,list2(CONST,30)),list2(CONST,~15))); + use_int(reg); + g = get_register(); + crn = register_name(reg); + grn = register_name(g); +// printf("\trlwinm r0,%s,0,0,27\n",crn); + printf("\tlwz %s,0(r1)\n",grn); + printf("\tneg %s,%s\n",crn,crn); + printf("\tstwux %s,r1,%s\n",grn,crn); +// printf("\tstw %s,0(r1)\n",grn); + if (!max_func_arg_label) max_func_arg_label = fwdlabel(); + printf("\taddis r1,r1,ha16(L_%d)\n",max_func_arg_label); + printf("\taddi %s,r1,lo16(L_%d)\n",crn,max_func_arg_label); + free_register(g); +} + +void code_frame_pointer(int e3) { use_int(e3); #if R1SAVE diff -r a93e619cf772 -r f73b93de216a mc-code.h --- a/mc-code.h Sat Jun 12 15:58:56 2004 +0900 +++ b/mc-code.h Tue Jun 15 00:11:26 2004 +0900 @@ -198,6 +198,7 @@ #endif +extern void code_alloca(int e,int reg); extern void code_arg_register(NMTBL *fnptr); extern int get_register(void); diff -r a93e619cf772 -r f73b93de216a mc-codegen.c --- a/mc-codegen.c Sat Jun 12 15:58:56 2004 +0900 +++ b/mc-codegen.c Tue Jun 15 00:11:26 2004 +0900 @@ -409,6 +409,9 @@ case RSTRUCT: g_expr0(e2); return RSTRUCT; + case ALLOCA: + code_alloca(e2,USE_CREG); + return list2(POINTER,CHAR); case COMMA: g_expr_u(e2); return g_expr0(caddr(e1)); @@ -659,7 +662,7 @@ /* check argments type is DOTS? */ t = caddr(e1); - if (t==0 || t==DOTS) *dots = 1; + if (/* t==0 || */ t==DOTS) *dots = 1; else { *dots = 0; for(;t;t = cadr(t)) { diff -r a93e619cf772 -r f73b93de216a mc-parse.c --- a/mc-parse.c Sat Jun 12 15:58:56 2004 +0900 +++ b/mc-parse.c Tue Jun 15 00:11:26 2004 +0900 @@ -319,6 +319,7 @@ reserve("enum",ENUM); reserve("volatile",VOLATILE); reserve("typeof",TYPEOF); + reserve("__builtin_alloca",ALLOCA); gpc=glineno=0; gfree=ilabel=1; @@ -689,7 +690,7 @@ getsym(0); n=decl0(); checksym(RPAR); - } else if (sym == IDENT) { + } else if (sym == IDENT||sym==ALLOCA) { n=nptr; getsym(0); } else { @@ -2855,6 +2856,14 @@ if(!scalar(type)) error(TYERR); return list2(LNOT,e); + case ALLOCA: + conv->prefix_(sym); + type=POINTER; + getsym(0); + checksym(LPAR); + e=expr0(); + checksym(RPAR); + return list2(ALLOCA,rvalue(e)); case SIZEOF: conv->prefix_(sym); if(getsym(0)==LPAR) { diff -r a93e619cf772 -r f73b93de216a mc.h --- a/mc.h Sat Jun 12 15:58:56 2004 +0900 +++ b/mc.h Tue Jun 15 00:11:26 2004 +0900 @@ -199,52 +199,53 @@ #define LRINDIRECT (LOP+RINDIRECT) #define LURINDIRECT (LOP+URINDIRECT) #define RSTRUCT 27 -#define CONV 28 +#define ALLOCA 28 +#define CONV 29 #define UNARY_ARGS(i) (ADDRESS<=(i%SOP)&&(i%SOP)<=CONV) /* binary argments */ -#define MUL 29 -#define UMUL 30 -#define DIV 31 -#define UDIV 32 -#define MOD 33 -#define UMOD 34 -#define ADD 35 -#define SUB 36 -#define CMP 37 -#define RSHIFT 38 -#define URSHIFT 39 -#define LSHIFT 40 -#define ULSHIFT 41 -#define GT 42 -#define UGT 43 -#define GE 44 -#define UGE 45 -#define LT 46 -#define ULT 47 -#define LE 48 -#define ULE 49 -#define EQ 50 -#define NEQ 51 -#define BAND 52 -#define EOR 53 -#define BOR 54 -#define LAND 55 -#define LOR 56 -#define ASS 57 -#define UCMP 58 -#define UCMPGE 59 -#define CMPGE 60 -#define CMPEQ 61 -#define CMPNEQ 62 -#define ASSOP 63 -#define COMMA 64 +#define MUL 30 +#define UMUL 31 +#define DIV 32 +#define UDIV 33 +#define MOD 34 +#define UMOD 35 +#define ADD 36 +#define SUB 37 +#define CMP 38 +#define RSHIFT 39 +#define URSHIFT 40 +#define LSHIFT 41 +#define ULSHIFT 42 +#define GT 43 +#define UGT 44 +#define GE 45 +#define UGE 46 +#define LT 47 +#define ULT 48 +#define LE 49 +#define ULE 50 +#define EQ 51 +#define NEQ 52 +#define BAND 53 +#define EOR 54 +#define BOR 55 +#define LAND 56 +#define LOR 57 +#define ASS 58 +#define UCMP 59 +#define UCMPGE 60 +#define CMPGE 61 +#define CMPEQ 62 +#define CMPNEQ 63 +#define ASSOP 64 +#define COMMA 65 -#define CASS 65 -#define CASSOP 66 -#define CUASSOP 67 +#define CASS 66 +#define CASSOP 67 +#define CUASSOP 68 #define SASS (SOP+CASS) #define SASSOP (SOP+CASSOP) @@ -301,13 +302,13 @@ #define LBOR (LOP+BOR) -#define STASS 68 +#define STASS 69 #define BINARY_ARGS(i) (MUL<=(i%SOP)&&(i%SOP)<=STASS) /* tarnary argments */ -#define COND 69 +#define COND 70 #define SCOND (SOP+COND) #define DCOND (DOP+COND) #define FCOND (FOP+COND) @@ -317,19 +318,19 @@ /* not appeared as tags */ -#define I2I 70 -#define I2U 71 -#define I2D 72 -#define I2F 73 -#define I2LL 74 -#define I2ULL 75 +#define I2I 71 +#define I2U 72 +#define I2D 73 +#define I2F 74 +#define I2LL 75 +#define I2ULL 76 -#define U2I 76 -#define U2U 77 -#define U2D 78 -#define U2F 79 -#define U2LL 80 -#define U2ULL 81 +#define U2I 77 +#define U2U 78 +#define U2D 79 +#define U2F 80 +#define U2LL 81 +#define U2ULL 82 #define D2I (DOP+I2I) #define D2U (DOP+I2U) @@ -359,17 +360,17 @@ #define ULL2LL (LOP+U2LL) #define ULL2ULL (LOP+U2ULL) -#define LPAR 82 -#define RPAR 83 -#define LBRA 84 -#define RBRA 85 -#define LC 86 -#define RC 87 -#define COLON 88 -#define SM 89 -#define PERIOD 90 -#define ARROW 91 -#define CNAME 92 +#define LPAR 83 +#define RPAR 84 +#define LBRA 85 +#define RBRA 86 +#define LC 87 +#define RC 88 +#define COLON 89 +#define SM 90 +#define PERIOD 91 +#define ARROW 92 +#define CNAME 93 /* tree node tags end */ diff -r a93e619cf772 -r f73b93de216a stdio.h --- a/stdio.h Sat Jun 12 15:58:56 2004 +0900 +++ b/stdio.h Tue Jun 15 00:11:26 2004 +0900 @@ -1,4 +1,4 @@ -#ifndef __micro_c__ +#ifndef __micro_c__aaa #include "/usr/include/stdio.h" long long strtoll(const char *, char **, int); #else diff -r a93e619cf772 -r f73b93de216a test/tmp8.c --- a/test/tmp8.c Sat Jun 12 15:58:56 2004 +0900 +++ b/test/tmp8.c Tue Jun 15 00:11:26 2004 +0900 @@ -4,12 +4,18 @@ int f(int i,int j,int k,int *l); int g(); +int f1(int i,int j,int *l,int k); +int g1(int k); +void f2(); int main() { int a[0] ; + f2(1); + f2(0); printf("%d %d\n",g(),f(0,1,2,a)); + printf("%d %d\n",g1(100),f1(0,1,a,2)); return 0; } @@ -31,3 +37,42 @@ if (i++ >20) return *l; return f(i,j,k,(int*)alloca(asize)); } + +int +g1(int k) +{ + int i; + + char *p = ((char *)alloca(asize))+k; + p -= k; + for(i=0;i<100;i++) p[i]=i; + for(i=0;i<100;i++) k += p[i]; + return k; +} + +int +f1(int i,int j,int *l,int k) +{ + // printf("f1 &i=%x &k=%x\n",&i,&k); + // printf("f1 i=%d j=%d *l=%0x k=%d\n",i,j,l,k); + *l = 3; + printf("f1 i=%d j=%d *l=%0x k=%d\n",i,j,*l,k); + if (i++ >20) return *l; + return f1(i,j,(int*)alloca(asize),k); +} + +void +f2(int k) +{ + int *l; + if (k==1) + l = alloca(asize); + else + l = 0; + printf("f2: %0x %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", + // l, + 0, +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40 + ); +} +