Mercurial > hg > CbC > old > device
changeset 13:a8a812dace23
struct local initialization
author | kono |
---|---|
date | Mon, 17 Jan 2000 00:43:06 +0900 |
parents | f928bd330351 |
children | 77c0710a8729 |
files | mc-nop-386.c mc-parse.c test/tmp7.c |
diffstat | 3 files changed, 171 insertions(+), 90 deletions(-) [+] |
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); } }
--- a/mc-parse.c Sat Jan 15 00:01:14 2000 +0900 +++ b/mc-parse.c Mon Jan 17 00:43:06 2000 +0900 @@ -6,7 +6,7 @@ void ntable_consistency(); static void adecl(NMTBL *n); -static void decl_data(int t, NMTBL *n); +static int decl_data(int t, NMTBL *n,int offset); static int alpha(char c); static int binop(int op, int e1, int e2, int t1, int t2); int caddr(int e); @@ -656,7 +656,7 @@ *cheapp++ = 0; } if(sym==ASS) { - decl_data(type,n); + decl_data(type,n,0); emit_data_closing(n); /* gpc is incremented by emit_data */ } else @@ -723,9 +723,11 @@ ndsp = (disp -= sz); } if(sym==ASS) { - decl_data(type,n); + n->sc = nsc; + n->dsp = ndsp; + decl_data(type,n,0); } - break; + return; case LSDECL: nsc = FIELD; ndsp = disp; @@ -752,52 +754,54 @@ void emit_init_vars(void) { + if (!init_vars) return; + init_vars = reverse0(init_vars); while(init_vars) { g_expr(car(init_vars)); init_vars = cadr(init_vars); } } -void -assign_data(int e, int t, int n) +int +assign_data(int e, int t, NMTBL *n,int offset) { int ass; if(mode==GDECL) { - emit_data(e,t,(NMTBL *)n); + emit_data(e,t,n); + return offset+size(t); } else if(mode==LDECL) { - if (t==STRUCT || t==UNION) { - ass = list3(SASS,list2(LVAR,nptr->dsp),e); + if(t==CHAR) { + ass =list3(CASS,list2(LVAR,n->dsp+offset),e); + } else if (scalar(t)) { + ass = list3(ASS,list2(LVAR,n->dsp+offset),e); + } else if (car(t)==STRUCT || car(t)==UNION || car(t)==STRING) { + ass = list3(SASS,list2(LVAR,n->dsp+offset),e); } else { - if(t==CHAR) { - ass =list3(CASS,list2(LVAR,nptr->dsp),e); - } else { - ass = list3(ASS,list2(LVAR,nptr->dsp),e); - } + error(DCERR); } init_vars = list2(ass,init_vars); + return offset+size(t); } else { error(DCERR); } } -void -decl_data(int t, NMTBL *n) +int +decl_data(int t, NMTBL *n,int offset) /* type */ { - int t1,slfree,e,i; + int t1,e,i; getsym(); if (scalar(t)) { - slfree=lfree; e=expr1(); if(car(e)!=CONST && t==CHAR) error(TYERR); - emit_data(e,t,n); - lfree=slfree; + offset = assign_data(e,t,n,offset); type=t; - return; + return offset; } t1 = car(t); if (t1==ARRAY) { @@ -805,35 +809,37 @@ t1 = cadr(t); for(i=0;;i++) { if (sym!=RC) - decl_data(t1,n); + offset=decl_data(t1,n,offset); if (sym==COMMA) { continue; } else if (sym==RC) { - if (caddr(t)==0) { - heap[t+2]=i; - } else if (caddr(t)!=i+1) { + if (caddr(t)==0) { /* size not defined */ + heap[t+2]=i+1; /* define array size */ + } else if (caddr(t)!=i+1) { /* size match? */ error(TYERR); } getsym(); - return; + return offset; } else { error(TYERR); } } } else if (cadr(t)==CHAR) { - slfree=lfree; e=expr1(); if(car(e)!=STRING) error(TYERR); - emit_data(e,STRING,n); - heap[t+2]= size(type); - lfree=slfree; + offset=assign_data(e,list3(ARRAY,CHAR,size(type)),n,offset); + if (caddr(t)==0) { /* size not defined */ + heap[t+2]=size(type); /* define array size */ + } else if (caddr(t)!=size(type)) { /* size match? */ + error(TYERR); + } } else error(DCERR); } else if (t1==STRUCT) { if(cadr(t)==-1) error(DCERR); t1 = caddr(t); /* list of fields */ while(t1) { - decl_data(car(t1),n); /* alignment? */ + offset = decl_data(car(t1),n,offset); /* alignment? */ t1 = cadr(t1); if ( t1 && sym==COMMA) continue; if (!t1 && sym!=RC) error(DCERR); @@ -876,11 +882,14 @@ heap[nptr0->ty+2]=tags; rplacad(type0 = nptr0->ty,disp); } else { + /* struct tag name */ if(nptr0->sc == EMPTY) nptr0=gnptr0; if(nptr0->sc == EMPTY) error(UDERR); if(nptr0->sc != TAG) error(TYERR); - type0 = nptr0->ty; + tags = caddr(nptr0->ty); + disp = cadr(nptr0->ty); } + type0 = list3(s,disp,tags); } else if(sym==LC) { tags = 0; while(getsym() != RC) {
--- a/test/tmp7.c Sat Jan 15 00:01:14 2000 +0900 +++ b/test/tmp7.c Mon Jan 17 00:43:06 2000 +0900 @@ -1,19 +1,19 @@ +int k=3; + +struct aa { int a[100]; } aaa,bbb; + void tmp(void); int main0(int,char *[]); -main0(ac,av) +main0(int ac,char *av[]) { return ac; } -int k=3; - -struct aa { int a[100]; } aaa,bbb; - void main2(struct aa a1) { @@ -30,6 +30,7 @@ return a1; } + main(ac,av) int ac; char *av[]; @@ -51,6 +52,7 @@ printf("%d %s\n",i,p-i); } +void tmp() { }