Mercurial > hg > CbC > old > device
diff mc-code-ia32.c @ 313:f73b93de216a alloca
alloca done for ia32, powerpc, mips
author | kono |
---|---|
date | Tue, 15 Jun 2004 00:11:26 +0900 |
parents | a86612cf1a19 |
children | 84df3dd8cc3d |
line wrap: on
line diff
--- 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]<MAX_DATA_REG); switch(op) { case LSHIFT: @@ -1496,13 +1536,23 @@ printf("\tsubl $%d,%s\n",orn,crn); break; case BAND: - printf("\tandl $%d,%s\n",orn,crn); + if (datareg&&(orn & ~255)==~255) + printf("\tandb $%d,%s\n",orn,register_name(reg,1)); + else if (datareg&&(orn & ~65535)==~65535) + printf("\tandw $%d,%s\n",orn,register_name(reg,2)); + else + printf("\tandl $%d,%s\n",orn,crn); break; case EOR: printf("\txorl $%d,%s\n",orn,crn); break; case BOR: - printf("\torl $%d,%s\n",orn,crn); + if (datareg&&(orn & ~255)==0) + printf("\tor $%d,%s\n",orn,register_name(reg,1)); + else if (datareg&&(orn & ~65535)==0) + printf("\tor $%d,%s\n",orn,register_name(reg,2)); + else + printf("\torl $%d,%s\n",orn,crn); break; case MUL: case UMUL: @@ -2587,6 +2637,7 @@ // e2 (operand) is on the top of the stack use_longlong(reg); opl = 0; call=0; + stack_depth -= SIZE_OF_INT * 2; switch(op) { case LLSHIFT: @@ -2736,9 +2787,9 @@ switch(op) { case LADD: opl="addl";oph="adcl"; break; case LSUB: opl="subl";oph="sbbl"; break; - case LBAND: opl=oph="andl"; break; case LEOR: opl=oph="xorl"; break; case LBOR: opl=oph="orl"; break; + case LBAND: opl=oph="andl"; break; default: error(-1); } printf("\t%s $%d,%s\n\t%s $%d,%s\n",opl,vl,l_eax(reg),oph,vh,l_edx(reg)); @@ -2751,6 +2802,7 @@ void emit_lpush() { + stack_depth += SIZE_OF_INT * 2; printf("\tpushl %%edx\n\tpushl %%eax\n"); }