Mercurial > hg > CbC > old > device
diff mc-nop-386.c @ 13:a8a812dace23
struct local initialization
author | kono |
---|---|
date | Mon, 17 Jan 2000 00:43:06 +0900 |
parents | f928bd330351 |
children | 77c0710a8729 |
line wrap: on
line diff
--- a/mc-nop-386.c Sat Jan 15 00:01:14 2000 +0900 +++ b/mc-nop-386.c Mon Jan 17 00:43:06 2000 +0900 @@ -122,6 +122,7 @@ #define POINTER_REG 3 static char *reg_name[8]; static char *reg_name_l[4]; +static char *reg_name_w[4]; /* creg currrent virtual register @@ -178,6 +179,10 @@ reg_name_l[REG_EBX] = "%bl"; reg_name_l[REG_ECX] = "%cl"; reg_name_l[REG_EDX] = "%dl"; + reg_name_w[REG_EAX] = "%ax"; + reg_name_w[REG_EBX] = "%bx"; + reg_name_w[REG_ECX] = "%cx"; + reg_name_w[REG_EDX] = "%dx"; } @@ -730,15 +735,85 @@ } } +#define MAX_COPY_LEN 20 + +void +emit_copy(char *from,char *to,int length,int offset) +{ + if (length<0) return; + switch (length) { + case 0: break; + case 1: + printf("\tmovb %d(%s),%s\n",offset,from, reg_name_l[rname[dreg]] ); + printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset,to); + break; + case 2: + printf("\tmovw %d(%s),%s\n",offset,from, reg_name_w[rname[dreg]] ); + printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset,to); + break; + case 4: + printf("\tmovl %d(%s),%s\n",offset,from, drn); + printf("\tmovl %s,%d(%s)\n",drn, offset,to); + break; + default: + if (length <=MAX_COPY_LEN) { + for(;length>4;length-=4,offset+=4); + emit_copy(from,to,4,offset); + for(;length>2;length-=2,offset+=2); + emit_copy(from,to,2,offset); + if(length>0) + emit_copy(from,to,length,offset); + return; + } + printf("\texch %%edi,%s\n",from); + printf("\texch %%esi,%s\n",to); + printf("\texch %%ecx,%s\n",drn); + printf("\tmovl $%d,%%ecx\n",length); + printf("\tcld\n\trep\n\tmovsl\n"); + printf("\texch %%ecx,%s\n",drn); + printf("\texch %%esi,%s\n",to); + printf("\texch %%edi,%s\n",from); + } +} + +int +struct_push(int e4,int t) +{ + int e5; + g_expr(e4); + e5=size(t); + if(e5%size_of_int) { + e5 += size_of_int - (e5%size_of_int); + } + printf("\tsubl $%d,%%esp\n",e5); + if (e5<=MAX_COPY_LEN) + emit_copy(crn,"%esp",e5,0); + else { + printf("\tpushl %%edi\n"); + printf("\tpushl %%esi\n"); + printf("\tpushl %%ecx\n"); + printf("\tleal 12(%%esp),%%di\n"); + if (rname[creg]!=REG_ESI) + printf("\tmovl %s,%%esi\n",crn); + printf("\tmovl $%d,%%ecx\n",e5); + printf("\tcld\n\trep\n\tmovsl\n"); + printf("\tpopl %%ecx\n"); + printf("\tpopl %%esi\n"); + printf("\tpopl %%edi\n"); + } + return e5/size_of_int; +} + void function(int e1) { - int e2,e3,e4,e5,nargs; + int e2,e3,e4,e5,nargs,t; NMTBL *n; e2 = cadr(e1); nargs = 0; for (e3 = caddr(e1); e3; e3 = cadr(e3)) { + t=caddr(e3); n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); switch(car(e4)) { case FNAME: @@ -749,8 +824,16 @@ g_expr(e5); printf("\tpushl %s\n",crn); break; - default:g_expr(e4); - printf("\tpushl %s\n",crn); + default: + if(scalar(t)) { + g_expr(e4); + printf("\tpushl %s\n",crn); + } else if (car(t)==STRUCT||car(t)==UNION) { + nargs += struct_push(e4,t); + continue; + } else { + error(TYERR); + } } ++nargs; } @@ -954,6 +1037,7 @@ emit_push(); g_expr(e2); xrn = emit_pop(0); + emit_copy(crn,xrn,sz,0); return; } @@ -1406,58 +1490,44 @@ int l; char *name; name = n->nm; - if(mode==GDECL) { /* global */ - if (n->dsp != -1) { - n->dsp = -1; /* initiallized flag */ - printf(".globl\t%s\n",name); - data_mode(name); - align(t); - printf("%s:\n",name); + if(mode!=GDECL) { + error(-1); return; + } + if (n->dsp != -1) { + n->dsp = -1; /* initiallized flag */ + printf(".globl\t%s\n",name); + data_mode(name); + align(t); + printf("%s:\n",name); + } else { + data_mode(0); + } + if(car(e)==CONST) { + if (t==CHAR) { + printf("\t.byte %d\n",cadr(e)); + if (data_alignment>0) + data_alignment++; + gpc += 1; } else { - data_mode(0); - } - if(car(e)==CONST) { - if (t==CHAR) { - printf("\t.byte %d\n",cadr(e)); - if (data_alignment>0) - data_alignment++; - gpc += 1; - } else { - printf("\t.long %d\n",cadr(e)); - gpc += size_of_int; - } - } else if(t!=CHAR) { + printf("\t.long %d\n",cadr(e)); gpc += size_of_int; - if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { - printf("\t.long %s\n",caddr(cadr(e))); - } else if(car(e)==FNAME) { - printf("\t.long %s\n",((NMTBL *)cadr(e))->nm); - } else if(car(e)==STRING) { - if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { - l = fwdlabel(); - printf("\t.long _%d\n",l); - printf(".section\t.rodata\n"); - printf("_%d:\n",l); - output_mode = RODATA_EMIT_MODE; - } - ascii((char *)cadr(e)); - } else error(TYERR); - } - } else { - /* if (n->sc!=LVAR) { error(TYERR); return; } */ - if(car(e)==CONST) { - printf("\tmovl $%d,%s\n",cadr(e),crn); - printf("\t%s %s,%d(%%ebp)\n",t==CHAR?"movsbl":"movl",crn,n->dsp); - } else if(t!=CHAR) { - if(car(e)==ADDRESS&&car(cadr(e))==GVAR) - printf("\tlea %s,%s\n",caddr(e),crn); - else if(car(e)==FNAME) - printf("\tlea %s,%s\n",((NMTBL *)cadr(e))->nm,crn); - else if(car(e)==STRING) { - string(e); - } else error(TYERR); - printf("\tmovl %s,%d(%%ebp)\n",crn,n->dsp); - } + } + } else if(t!=CHAR) { + gpc += size_of_int; + if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { + printf("\t.long %s\n",caddr(cadr(e))); + } else if(car(e)==FNAME) { + printf("\t.long %s\n",((NMTBL *)cadr(e))->nm); + } else if(car(e)==STRING) { + if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { + l = fwdlabel(); + printf("\t.long _%d\n",l); + printf(".section\t.rodata\n"); + printf("_%d:\n",l); + output_mode = RODATA_EMIT_MODE; + } + ascii((char *)cadr(e)); + } else error(TYERR); } }