Mercurial > hg > CbC > old > device
diff mc-code-powerpc.c @ 313:f73b93de216a alloca
alloca done for ia32, powerpc, mips
author | kono |
---|---|
date | Tue, 15 Jun 2004 00:11:26 +0900 |
parents | e1d17d6adfcc |
children | 22d92986c7f7 |
line wrap: on
line diff
--- a/mc-code-powerpc.c Sat Jun 12 15:58:56 2004 +0900 +++ b/mc-code-powerpc.c Tue Jun 15 00:11:26 2004 +0900 @@ -11,6 +11,16 @@ 0 }; +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\ +#define alloca __builtin_alloca\n\ +"; + #define TEXT_EMIT_MODE 0 #define DATA_EMIT_MODE 1 #define RODATA_EMIT_MODE 2 @@ -32,6 +42,7 @@ static int code_setup; static int r1_offset_label; static int lvar_offset_label; +static int max_func_arg_label; static int reg_save; static int freg_save; @@ -294,6 +305,11 @@ int r1_offsetv = -disp+max_func_args*SIZE_OF_INT-reg_save+r1_offset; printf(".set L_%d,%d\n",lvar_offset_label,lvar_offsetv); printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv); + if (max_func_arg_label) { + printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24); + max_func_arg_label = 0; + } + #if 0 printf("# function %s\n",fnptr->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