Mercurial > hg > CbC > old > device
changeset 61:8ffb8ca3fe34
separation of architecture dependent part.
author | kono |
---|---|
date | Thu, 20 Feb 2003 03:29:15 +0900 |
parents | aa779bcffef7 |
children | 129f4802b027 |
files | Makefile mc-code-ia32.c mc-code.h mc-codegen.c mc-codegen.h mc-nop-386.c mc-parse.c mc.h stdio.h |
diffstat | 9 files changed, 2531 insertions(+), 222 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Wed Feb 19 21:22:49 2003 +0900 +++ b/Makefile Thu Feb 20 03:29:15 2003 +0900 @@ -9,8 +9,10 @@ all: mc -mc : mc-parse.o mc-nop-386.o mc-tree.o $(CONVERTER) - $(CC) -g mc-parse.o mc-nop-386.o mc-tree.o $(CONVERTER) -o $@ +mc : mc-parse.o mc-codegen.o mc-code-ia32.o mc-tree.o $(CONVERTER) + $(CC) -g mc-parse.o mc-codegen.o mc-code-ia32.o \ + mc-tree.o $(CONVERTER) -o $@ + tar : make clean tar cBf - . | gzip > ../comp.tgz @@ -19,7 +21,7 @@ makedepend mc-parse.c mc-nop-386.c mc-tree.c clean : - -rm -f *.s *.o mc mc1 a.out *~ core* + -rm -f *.s *.o mc mc1 a.out *~ core* */*.o mc1 : b00.s b01.s mc-tree.o $(CC) -g -o $@ $(PRINTF) mc-tree.o b00.s b01.s
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc-code-ia32.c Thu Feb 20 03:29:15 2003 +0900 @@ -0,0 +1,1304 @@ +/* Micro-C Code Generatation Part for intel386 */ +/* $Id$ */ + +#define EXTERN extern +#include "mc.h" +#include "mc-codegen.h" + +#define TEXT_EMIT_MODE 0 +#define DATA_EMIT_MODE 1 +#define RODATA_EMIT_MODE 2 + +static int output_mode = TEXT_EMIT_MODE; +static int data_alignment = 0; + +static int code_disp_label; +static int func_disp_label; + +/* + -16 -8 local2 + -12 -4 local1 + -8 8 arg3 + -4 4 arg2 + 0 0 arg1 + local2 -20 4 0 (%edi) + local1 <-- -16 0 local variable 0 (%esi) + %edi -12 <- disp_offset %ebp + %esi -8 + %ebx -4 + %ebp = %esp 0 + %eip 4 <- arg_offset + arg1 8 0 + arg2 12 4 + see enter/enter1/leave see code_enter + */ +int arg_offset = 8; +int disp_offset = -12; +int func_disp_offset = -12; +int code_disp_offset = 0; +int jump_offset = 0; + +int size_of_int = 4; +int endian = 0; +int MAX_REGISTER=6; /* intel386のレジスタを4つまで使う*/ +int REAL_MAX_REGISTER=8; /* intel386のレジスタが8つということ*/ +int MAX_DATA_REG=4; +int MAX_POINTER=3; +int MAX_REGISTGER_VAR=2; + +EXTERN int creg; /* current register */ +EXTERN int dreg; /* temporary register */ +EXTERN int reg_sp; /* REGister Stack-Pointer */ + + +#define REG_EAX 0 +#define REG_EBX 1 +#define REG_ECX 2 +#define REG_EDX 3 +#define REG_ESI 4 +#define REG_EDI 5 +#define REG_EBP 6 +#define REG_ESP 7 + + +#define DATA_REG 0 +#define POINTER_REG 3 +static char *reg_name[8]; +static char *reg_name_l[4]; +static char *reg_name_w[4]; + +extern int creg; /* current register */ +extern int dreg; /* temporary register */ +extern int reg_sp; /* REGister Stack-Pointer */ + +#define MAX_MAX 10 +int rname[MAX_MAX]; +int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ +int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +int regv[MAX_MAX]; /* 値が入っているかどうか */ + + +void use_register(int virt, int real, int move); +void code_preinc(int e1,int e2) ; +void code_cmp_register(int e2) ; +void code_assign_gvar(int e2,int byte) ; +void tosop(int op,int oreg); +void edx_cleanup(); +void shift(char *op, int reg); +void ld_indexx(int byte, int n, int xreg); +void jmp(int l); +void global_table(void); +void local_table(void); +void text_mode(void); +void data_mode(char *name); + +char *register_name(int i,int byte); +int register_var(int r); +int get_register_var(void); +void emit_push(void); +void emit_push_x(int xreg); +int emit_pop(int type); +void code_crlvar(int e2); +void code_preinc(int e1,int e2); +void code_postinc(int e1,int e2); +void code_bool(int e1); +void string(int e1); +void emit_copy(int from,int to,int length,int offset,int value,int det); +int struct_push(int e4,int t); +void function(int e1); +void code_assop(int op,int byte); +int edx_setup(); +void opening(char *filename); +void code_leave(char *name); +int lvar(int l); + +void +code_init(void) +{ + arg_offset = 8; + func_disp_offset = -12; + disp_offset = -12; + size_of_int = 4; + endian = 0; + MAX_REGISTER=6; + MAX_DATA_REG=4; + MAX_POINTER=3; + MAX_REGISTER_VAR=2; + + reg_name[REG_EAX] = "%eax"; + reg_name[REG_EBX] = "%ebx"; + reg_name[REG_ECX] = "%ecx"; + reg_name[REG_EDX] = "%edx"; + reg_name[REG_ESI] = "%esi"; + reg_name[REG_EDI] = "%edi"; + reg_name[REG_EBP] = "%ebp"; + reg_name[REG_ESP] = "%esp"; + reg_name_l[REG_EAX] = "%al"; + 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"; + +} + +char * +register_name(int i,int byte) +{ + if (i<0) { + error(REG_ERR); + return "%eax"; + } + if (byte && rname[i] <= REG_EDX) { + return reg_name_l[rname[i]]; + } else { + return reg_name[rname[i]]; /* should be error */ + } +} + +extern int rname[MAX_MAX]; +extern int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ +extern int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ +extern int regv[MAX_MAX]; /* 値が入っているかどうか */ + +extern int creg_regvar; + +void +gexpr_code_init(void){ + use_register(creg,REG_EAX,0); + regv[dreg]=0; + creg_regvar = -1; +} + +int +register_var(int r) { + return virtual(r+REG_ESI); +} + +int +get_register_var(void) +{ + int i; + for(i=REG_ESI;i<REG_ESP;i++) { + if (! regs[i]) { /* 使われていないなら */ + regs[i]=1; /* そのレジスタを使うことを宣言し */ + regv[i]=0; + return i; /* その場所を表す番号を返す */ + } + } + return -1; +} + +void +use_register(int virt, int real, int move) +{ + int real_v; + char *move_op; + if (rname[virt]==real) + return; + real_v = virtual(real); + move_op = regs[real_v]?"\txchg %s,%s\n":"\tmovl %s,%s\n"; + if (move || (regv[real_v])) { + printf(move_op,reg_name[rname[virt]],reg_name[real]); + } + rname[real_v] = rname[virt]; + rname[virt] = real; +} + +void +use_pointer(int virt, int move) +{ + int i; + if (rname[virt]>=POINTER_REG) + return; + for(i=POINTER_REG;i<MAX_REGISTER;i++) { + if (!regs[virtual(i)]) { + use_register(virt,i,move); + return; + } + } + /* we prefer EBX */ + use_register(virt,REG_EBX,move); +} + +void +use_data_reg(int virt, int move) +{ + int i; + if (rname[virt]<MAX_DATA_REG) + return; + for(i=0;i<MAX_DATA_REG;i++) { + if (!regs[virtual(i)]) { + use_register(virt,i,move); + return; + } + } + /* we prefer EBX */ + use_register(virt,REG_EBX,move); +} + + +void +emit_push(void) +{ + int new_reg; + new_reg = get_register(); + if(new_reg<0) { /* もうレジスタがない */ + reg_stack[reg_sp++] = -1; + printf("\tpushl %s\n",register_name(creg,0)); + /* creg is used soon, don't regv[creg]=0 */ + } else { + reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ + creg = new_reg; + regv[creg]=1; + } +} + +void +emit_push_x(int xreg) +{ + int new_reg; + new_reg = get_register(); + if(new_reg<0) { /* もうレジスタがない */ + reg_stack[reg_sp++] = -1; + printf("\tpushl %s\n",register_name(xreg,0)); + /* creg is used soon, don't regv[xreg]=0 */ + } else { + reg_stack[reg_sp++] = xreg; /* push するかわりにレジスタを使う */ + xreg = new_reg; + regv[xreg]=1; + } +} + +int +emit_pop(int type) +{ + int xreg; + if ((xreg=pop_register())==-1) { + if (type==POINTER_REG) + use_pointer(dreg,0); + else if (type==DATA_REG) + use_data_reg(dreg,0); +if (regv[dreg]) { + printf("# emit_pop dreg conflict\n"); +} + printf("\tpopl %s\n",register_name(dreg,0)); + xreg = dreg; + regv[xreg]=1; + } + return xreg; +} + + +void +code_gvar(int e1) { + printf("\tmovl $%s,%s\n",(char *)caddr(e1),register_name(creg,0)); +} + + +void +code_rgvar(int e1) { + printf("\tmovl %s,%s\n",(char *)caddr(e1),register_name(creg,0)); +} + +void +code_crgvar(e1){ + printf("\tmovsbl %s,%s\n",(char *)caddr(e1),register_name(creg,0)); +} + + +void +code_lvar(int e2) { + printf("\tlea %d(%%ebp),%s\n",e2,register_name(creg,0)); +} + + +void +code_register(int e2) { + printf("\tmovl %s,%s\n",register_name(e2,0),register_name(creg,0)); +} + + +void +code_rlvar(int e2) { + printf("\tmovl %d(%%ebp),%s\n",e2,register_name(creg,0)); +} + + +void +code_crlvar(int e2) { + printf("\tmovsbl %d(%%ebp),%s\n",lvar(e2),register_name(creg,0)); +} + + +void +code_fname(char *e2) { + printf("\tmovl $%s,%s\n",e2,register_name(creg,0)); +} + + +void +code_const(int e2) { + printf("\tmovl $%d,%s\n",e2,register_name(creg,0)); +} + + +void +code_neg() { + printf("\tnegl %s\n", register_name(creg,0)); +} + + +void +code_not() { + printf("\tnotl %s\n", register_name(creg,0)); +} + + +void +code_lnot() { + char *xrn; + use_data_reg(creg,1); + xrn = register_name(creg,1); + printf("\tcmpl $0,%s\n", register_name(creg,0)); + printf("\tsete %s\n", xrn); + printf("\tmovzbl %s,%s\n", xrn,register_name(creg,0)); +} + +void +code_preinc(int e1,int e2) { + char *xrn; + if (car(e2)==REGISTER) { + printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0)); + printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + return; + } + g_expr(e2); + xrn = register_name(creg,0); + printf("\taddl $%d,(%s)\n",caddr(e1),xrn); + printf("\tmovl (%s),%s\n",xrn,xrn); +} + + +void +code_postinc(int e1,int e2) { + char *xrn; + if (car(e2)==REGISTER) { + printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0)); + return; + } + g_expr(e2); + emit_push(); + xrn = register_name((e2=emit_pop(0)),0); + printf("\tmovl (%s),%s\n",xrn,register_name(creg,0)); + printf("\taddl $%d,(%s)\n",caddr(e1),xrn); + emit_pop_free(e2); +} + + +void +code_cpostinc(int e1,int e2) { + char *xrn; + if (car(e2)==REGISTER) { + printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0)); + return; + } + g_expr(e2); + emit_push(); + xrn = register_name((e2=emit_pop(0)),1); + printf("\tmovsbl (%s),%s\n",xrn,register_name(creg,0)); + printf("\tincl (%s)\n",xrn); + emit_pop_free(e2); +} + + +void +code_cpreinc(int e1,int e2) { + if (car(e2)==REGISTER) { + printf("\taddl $%d,%s\n",caddr(e1),register_name(cadr(e2),0)); + printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + return; + } + g_expr(e2); + printf("\tincl (%s)\n",register_name(creg,0)); + printf("\tmovsbl (%s),%s\n",register_name(creg,0),register_name(creg,0)); +} + + +void +code_cpostdec(int e1,int e2) { + if (car(e2)==REGISTER) { + printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + printf("\tdecl %s\n",register_name(cadr(e2),0)); + return; + } + g_expr(e2); + printf("\tmovsbl (%s),%s\n",register_name(creg,0),register_name(creg,0)); + printf("\tdecl (%s)\n",register_name(creg,0)); +} + + +void +code_cpredec(int e1,int e2) { + if (car(e2)==REGISTER) { + printf("\tdecl %s\n",register_name(cadr(e2),0)); + printf("\tmovl %s,%s\n",register_name(cadr(e2),0),register_name(creg,0)); + return; + } + g_expr(e2); + emit_push(); + e2 = emit_pop(0); + printf("\tdecl (%s)\n",register_name(e2,0)); + printf("\tmovsbl (%s),%s\n",register_name(e2,0),register_name(creg,0)); + emit_pop_free(e2); +} + + +void +code_return() { + printf("\tleal _%d,%s\n",retcont,register_name(creg,0)); +} + + +void +code_environment() { + printf("\tmovl %%ebp,%s\n",register_name(creg,0)); +} + + +void +code_bool(int e1) { + char *xrn; + int e2,e3; + b_expr(e1,1,e2=fwdlabel(),1); /* including > < ... */ + xrn = register_name(creg,0); + printf("\txorl %s,%s\n",xrn,xrn); + jmp(e3=fwdlabel()); + fwddef(e2); + printf("\tmovl $1,%s\n",xrn); + fwddef(e3); +} + +char * +code_gt(int cond) { + return (cond?"g":"le"); +} + +char * +code_ugt(int cond) { + return (cond?"a":"be"); +} + +char * +code_ge(int cond) { + return (cond?"ge":"l"); +} + +char * +code_uge(int cond) { + return (cond?"ae":"b"); +} + +char * +code_eq(int cond) { + return (cond?"e":"ne"); +} + +void +code_cmp_crgvar(int e1) { + printf("\tcmpb $0,%s\n",(char *)caddr(e1)); +} + + +void +code_cmp_crlvar(int e1) { + printf("\tcmpb $0,%d(%%ebp)\n",e1); +} + + +void +code_cmp_rgvar(int e1) { + printf("\tcmpl $0,%s\n",(char *)caddr(e1)); +} + + +void +code_cmp_rlvar(int e1) { + printf("\tcmpl $0,%d(%%ebp)\n",e1); +} + + +void +code_cmp_register(int e2) { + printf("\tcmpl $0,%s\n",register_name(e2,0)); +} + + +void +ascii(char *s) +{ + printf("\t.string \""); + while(*s) { + if (*s=='\n') + printf("%cn",92); + else if (*s<' ') + printf("%c%03o",92,*s); + else if (*s==34) + printf("%c%c",92,34); + else + printf("%c",*s); + s++; + } + printf("%c\n",34); +} + +void +string(int e1) +{ + char *s; + int i,lb; + + if (0) { + s=(char *)cadr(e1); + lb=fwdlabel(); + printf("\tjmp _%d\n",lb); + i=backdef(); + ascii(s); + printf("\t.align 2\n"); + fwddef(lb); + printf("\tlea _%d,%s\n",i,register_name(creg,0)); + } else { + s=(char *)cadr(e1); + printf(".section\t.rodata\n"); + lb=fwdlabel(); + printf("_%d:\n",lb); + ascii(s); + if (output_mode==TEXT_EMIT_MODE) { + printf(".text\n"); + } else { + text_mode(); + } + printf("\tlea _%d,%s\n",lb,register_name(creg,0)); + } +} + +#define MAX_COPY_LEN 20 + +void +emit_copy(int from,int to,int length,int offset,int value,int det) +{ + int fix = 0; + /* length <0 means upward direction copy */ + switch (length) { + case 0: break; + case 1: case -1: + printf("\tmovb %d(%s),%s\n",offset, + register_name(from,0), reg_name_l[rname[dreg]] ); + printf("\tmovb %s,%d(%s)\n",reg_name_l[rname[dreg]] ,offset, + register_name(to,0)); + break; + case 2: case -2: + printf("\tmovw %d(%s),%s\n",offset, + register_name(from,0), reg_name_w[rname[dreg]] ); + printf("\tmovw %s,%d(%s)\n",reg_name_w[rname[dreg]] ,offset, + register_name(to,0)); + break; + case 4: case -4: + printf("\tmovl %d(%s),%s\n",offset, + register_name(from,0), register_name(dreg,0)); + printf("\tmovl %s,%d(%s)\n",register_name(dreg,0), offset, + register_name(to,0)); + break; + default: + if (-MAX_COPY_LEN<length && length <0) { + for(;length<=4;length+=4,offset-=4) + emit_copy(from,to,4,offset,0,det); + for(;length<=2;length+=2,offset-=2) + emit_copy(from,to,2,offset,0,det); + if(length>0) + emit_copy(from,to,length,offset,0,det); + break; + } else if (length <=MAX_COPY_LEN) { + for(;length>=4;length-=4,offset+=4) + emit_copy(from,to,4,offset,0,det); + for(;length>=2;length-=2,offset+=2) + emit_copy(from,to,2,offset,0,det); + if(length>0) + emit_copy(from,to,length,offset,0,det); + break; + } + if (det) { +/* + call bcopy + g_expr(list3(FUNCTION,,); + break; + */ + } + use_register(from,REG_ESI,1); + use_register(to, REG_EDI,1); + use_register(dreg,REG_ECX,0); + if (length<0) { + printf("\tmovl $%d,%%ecx\n",-length/4); + printf("\taddl $%d,%%esi\n",-length); + printf("\taddl $%d,%%edi\n",-length); + printf("\tstd\n\trep\n\tmovsl\n"); + if(length%4) { + emit_copy(from,to,length,offset+length/4,0,det); + } + } else { + printf("\tmovl $%d,%%ecx\n",length/4); + fix = (length/4)*4; + printf("\tcld\n\trep\n\tmovsl\n"); + if(length%4) { + emit_copy(from,to,length,offset+length/4,0,det); + } + } + } + if (value) { + /* creg must point top of the destination data */ + /* this code is necessary for the value of assignment or function call */ + /* otherwise we don't need this */ + if (fix) printf("\tsubl $%d,%s\n",fix,register_name(to,0)); + if(creg!=to) { + if (to==dreg) + printf("\tmovl %s,%s\n",register_name(to,0),register_name(creg,0)); + else { + free_register(creg); creg=to; + } + } + } + regv[from]=regv[to]=regv[dreg]=0; + regv[creg]=1; +} + +int +struct_push(int e4,int t) +{ + int length,xreg,save,lreg; + g_expr(e4); + length=size(t); + if(length%size_of_int) { + length += size_of_int - (length%size_of_int); + } + if (length==4) { + printf("\tpushl (%s)\n",register_name(creg,0)); return 1; + } + if (length==8) { + printf("\tpushl 4(%s)\n",register_name(creg,0)); + printf("\tpushl (%s)\n",register_name(creg,0)); return 2; + } + printf("\tsubl $%d,%%esp\n",length); + if (register_full()) { + save = 1; + for(lreg=0;lreg==creg||lreg==dreg;lreg++); + printf("\tpushl %s\n",register_name(lreg,0)); + xreg = lreg; regv[xreg]=0; + } else { + save=0; + xreg = get_register(); + } + if (save) + printf("\tlea %d(%%esp),%s\n",size_of_int,register_name(xreg,0)); + else + printf("\tmovl %%esp,%s\n",register_name(xreg,0)); + regv[xreg]=1; + /* downward direction copy */ + emit_copy(creg,xreg,length,0,0,1); + /* we have value in creg, it may be changed */ + if (save) { + if(creg==xreg) { + creg = get_register(); /* creg is freed in emit_copy */ + } + printf("\tpopl %s\n",register_name(xreg,0)); + regv[xreg]=1; + } else + free_register(xreg); + return length/size_of_int; +} + +void +function(int e1) +{ + int e2,e3,e4,e5,nargs,t; + NMTBL *n; + int save,saved; + if (free_register_count()<1) { + for(save = 0;save==dreg||save==creg;save++); + printf("\tpushl %s\n",register_name(save,0)); + saved = 1; + } else { + save = get_register(); + saved = 0; + } + regv[save]=0; + e2 = cadr(e1); + nargs = 0; + for (e3 = caddr(e1); e3; e3 = cadr(e3)) { + t=caddr(e3); + n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); + if(scalar(t)) { + g_expr(e4); + printf("\tpushl %s\n",register_name(creg,0)); + } else if (car(t)==STRUCT||car(t)==UNION) { + nargs += struct_push(e4,t); + continue; + } else { + error(TYERR); + } + ++nargs; + } + if (car(e2) == FNAME) { + n=(NMTBL *)cadr(e2); + } else { + use_register(creg,REG_EAX,0); + g_expr(e2); + } + + /* we don't have to save creg nor dreg */ + regs[creg]=0; regs[dreg]=0; + regv[creg]= regv[dreg]= regv[save]= 0; + use_register(creg,REG_EAX,0); + use_register(dreg,REG_EDX,0); /* will be destroyed */ + use_register(save,REG_ECX,0); /* will be destroyed */ + regs[creg]=1; regs[dreg]=1; + + if (car(e2) == FNAME) { + printf("\tcall\t%s\n",n->nm); + } else { + printf("\tcall\t*%s\n",register_name(creg,0)); + } + if (nargs) printf("\taddl $%d,%%esp\n",size_of_int*nargs); + if (saved) { + printf("\tpopl %s\n",register_name(save,0)); + } else { + free_register(save); + } + regv[save]=0; + regv[creg]=1; +} + +void +code_frame_pointer(int e3) { + printf("\tmovl %s,%%ebp\n",register_name(e3,0)); +} + + +void +code_fix_frame_pointer(disp_offset) { + printf("\tlea %d(%%ebp),%%ebp\n",disp_offset); +} + + +void +code_jmp(char *s) { + printf("\tjmp %s\n",s); +} + + +void +code_indirect_jmp(int e2) { + printf("\tjmp *%s\n",register_name(e2,0)); +} + +void +rindirect(int e1) /* *(p +5 ) */ +{ + char *op; + int e2,e3,byte; + + op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl"); + e3 = cadr(e2 = cadr(e1)); + g_expr(e2); + printf("\t%s (%s),%s\n",op,register_name(creg,0),register_name(creg,0)); +} + +char * +move(int byte) +{ + return byte?"movb":"movl"; +} + +void +code_assign_gvar(int e2,int byte) { + if (byte) use_data_reg(creg,1); + printf("\t%s %s,%s\n",move(byte),register_name(creg,byte),(char *)caddr(e2)); +} + +void +code_assign_lvar(int e2,int byte) { + if (byte) use_data_reg(creg,1); + printf("\t%s %s,%d(%%ebp)\n",move(byte),register_name(creg,byte),e2); +} + +void +code_assign_register(int e2,int byte) { + printf("\tmovl %s,%s\n",register_name(creg,0),register_name(e2,0)); +} + +void +code_assign(int e2,int byte) { + printf("\t%s %s,(%s)\n",move(byte),register_name(creg,byte),register_name(e2,0)); +} + + +void +code_register_assop(int e2,int op,int byte) { + int reg; + int xreg = creg; + creg = reg = e2; + tosop(op,xreg); + creg = xreg; + printf("\tmovl %s,%s\n",register_name(reg,0),register_name(creg,0)); +} + + +void +code_assop(int op,int byte) { + char *xrn; + int xreg; + int edx = edx_setup(); + xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */ + regv[xreg]=regs[xreg]=1; + printf("\tmovl %s,%s # assop \n",register_name(creg,0),register_name(edx,0)); + regv[edx]=1; + ld_indexx(byte,0,edx); + tosop(op,xreg); + printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",register_name(creg,byte),register_name(edx,0)); + edx_cleanup(); + emit_pop_free(xreg); +} + + +void +tosop(int op,int oreg) +{ + int dx; + char *orn,*crn; + + switch(op) { + case LSHIFT: + case ULSHIFT: + shift("sall",oreg); + return; + case RSHIFT: + shift("sarl",oreg); + return; + case URSHIFT: + shift("shrl",oreg); + return; + } + if(oreg==-1) { + printf("\tpopl %s\n",register_name(dreg,0)); + oreg = dreg; + regv[dreg]=1; + } + regv[oreg]=1; regs[oreg]=1; + orn = register_name(oreg,0); + crn = register_name(creg,0); + switch(op) { + case ADD: + printf("\taddl %s,%s\n",orn,crn); + break; + case SUB: + printf("\tsubl %s,%s\n",orn,crn); + break; + case BAND: + printf("\tandl %s,%s\n",orn,crn); + break; + case EOR: + printf("\txorl %s,%s\n",orn,crn); + break; + case BOR: + printf("\torl %s,%s\n",orn,crn); + break; + case MUL: + case UMUL: + printf("\t%s %s,%s\n","imull",orn,crn); + break; + case DIV: + case UDIV: + use_register(creg,REG_EAX,1); + edx_setup(); + orn = register_name(oreg,0); + if (op==DIV) + printf("\tcltd\n\tdivl %s\n",orn); + else + printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); + edx_cleanup(); + break; + case MOD: + case UMOD: + use_register(creg,REG_EAX,1); + edx_setup(); + orn = register_name(oreg,0); + if (op==DIV) + printf("\tcltd\n\tdivl %s\n",orn); + else + printf("\txor %%edx,%%edx\n\tidivl %s\n",orn); + dx = virtual(REG_EDX); + if (dx!=creg) { + rname[dx]=rname[creg]; + rname[creg]=REG_EDX; + } + edx_cleanup(); + break; + } + if (oreg!=dreg&&oreg>=0) + free_register(oreg); +} + +static int edx_stack=0; + +int +edx_setup() +{ + int edx_save; + /* make real EDX register empty */ + if (free_register_count()<1) { + for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++); + printf("\tpushl %s\n",register_name(edx_save,0)); + edx_stack = list3(edx_save,edx_stack,0); + } else { + edx_save = get_register(); + edx_stack = list3(edx_save,edx_stack,1); + } + regv[edx_save]=0; + use_register(edx_save,REG_EDX,0); + return edx_save; +} + + +void +edx_cleanup() +{ + if (caddr(edx_stack)==0) { + printf("\tpopl %s\n",register_name(car(edx_stack),0)); + } else + free_register(car(edx_stack)); + edx_stack = cadr(edx_stack); +} + +void +shift(char *op, int reg) +{ + if (reg>=0) { + use_register(reg,REG_ECX,1); + } else { + use_register(dreg,REG_ECX,0); + printf("\tpopl %%ecx\n"); + } + printf("\t%s %%cl,%s\n",op,register_name(creg,0)); +} + +void +ld_indexx(int byte, int n, int xreg) +{ + char *op; + + op = byte ? "movsbl" : "movl"; + if (n) + printf("\t%s %d(%s),%s\n",op,n,register_name(xreg,0),register_name(creg,byte)); + else + printf("\t%s (%s),%s\n",op,register_name(xreg,0),register_name(creg,byte)); +} + +void +cmpdimm(int e, int csreg) +{ + /* used in dosiwtch() */ + use_register(creg,csreg,0); + printf("\tcmpl $%d,%s\n",e,register_name(creg,0)); +} + +void +opening(char *filename) +{ + printf("\t.file \"%s\"\n",filename); + printf("\t.version\t\"01.01\"\n"); + printf("gcc2_compiled.:\n"); + printf(".text\n"); + emit_init(); +} + +void +closing(void) +{ + global_table(); + printf("\t.ident \"Micro-C compiled\"\n"); +} + +void +rexpr(int e1, int l1, char *s) +{ + g_expr(list3(SUB,cadr(e1),caddr(e1))); + printf("\tj%s\t_%d\n",s,l1); +} + +void +jcond(int l, char cond) +{ + printf("\tj%s\t_%d\n",cond?"ne":"e",l); +} + +void +jmp(int l) +{ + control=0; + printf("\tjmp\t_%d\n",l); + /* align? */ + /* + this is not allowed because of ? operator + regv[creg]=regv[dreg]=0; + use_register(creg,REG_EAX,0); + use_register(dreg,REG_EBX,0); + */ +} + +void +gen_comment(char *s) +{ + printf("## %s",s); +} + + +void +code_enter(char *name) +{ + printf("\t.align 4\n"); + if (stmode!=STATIC) + printf(".globl %s\n",name); + printf("\t.type\t%s,@function\n",name); + printf("%s:\n",name); +} + +void +code_enter1(int args) +{ + code_disp_label=fwdlabel(); + printf("\tlea _%d(%%ebp),%%esp\n",code_disp_label); + + printf("## args %d disp %d code_arg_offset=%d code_disp_offset=%d\n",args,disp,code_arg_offset,code_disp_offset); +} + +void +code_leave(char *name) +{ + printf("\t.set _%d,%d\n",code_disp_label,disp+code_disp_offset); + printf("_%d:\n",labelno); + printf("\t.size\t%s,_%d-%s\n",name,labelno,name); + local_table(); + labelno++; + free_all_register(); +} + +void +enter(char *name) +{ + printf("\t.align 2\n"); + if (stmode!=STATIC) + printf(".globl %s\n",name); + printf("%s:\n",name); + printf("\t.type\t%s,@function\n",name); + printf("\tpushl %%ebp\n"); + printf("\tmovl %%esp,%%ebp\n"); + printf("\tpushl %%ebx\n"); + printf("\tpushl %%esi\n"); + printf("\tpushl %%edi\n"); +} + +void +enter1() +{ + func_disp_label=fwdlabel(); + printf("\tlea _%d(%%ebp),%%esp\n",func_disp_label); + /* if(disp) printf("\tsubl $%d,%%esp\n",-disp); */ +} + +void +leave(int control, char *name) +{ + if (control) + use_register(creg,REG_EAX,1); + if (retcont) { + if (control) + jmp(retlabel); + fwddef(retcont); + use_register(creg,REG_EAX,0); + printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg,0)); + /* printf("\tleave\n"); */ + } + fwddef(retlabel); + /* use_register(creg,REG_EAX,0); too late */ + /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */ + printf("\tlea %d(%%ebp),%%esp\n",disp_offset); + printf("\tpopl %%edi\n"); + printf("\tpopl %%esi\n"); + printf("\tpopl %%ebx\n"); + printf("\tleave\n"); + printf("\tret\n"); + printf("\t.set _%d,%d\n",func_disp_label,disp+disp_offset); + printf("_%d:\n",labelno); + printf("\t.size\t%s,_%d-%s\n",name,labelno,name); + local_table(); + labelno++; + free_all_register(); +} + + +void +code_set_fixed_creg(int mode) { + use_register(creg,REG_EAX,mode); +} + +void +gen_gdecl(char *n, int gpc) +{ + /* + if (stmode!=STATIC) + printf(".globl %s\n",n); + */ +} + +void +align(int t) +{ + if (t!=CHAR) { + if (data_alignment & 1) + printf("\t.align 2\n"); + data_alignment = 0; + } +} + +void +emit_data(int e, int t, NMTBL *n) +{ + int l; + char *name; + name = n->nm; + 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 { + printf("\t.long %d\n",cadr(e)); + gpc += size_of_int; + } + } else if(t!=CHAR) { + gpc += size_of_int; + if(car(e)==ADDRESS&&car(cadr(e))==GVAR) { + printf("\t.long %s\n",(char *)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); + } +} + +void +emit_data_closing(NMTBL *n) +{ + int lb; + if (mode==GDECL) { + data_mode(0); + lb=fwdlabel(); + printf("_%d:\n",lb); + printf("\t.size\t%s,_%d-%s\n",n->nm,lb,n->nm); + } +} + +void +global_table(void) +{ + NMTBL *n; + int init; + init=0; + for(n=ntable;n < &ntable[GSYMS];n++) { + if (n->sc == GVAR && n->dsp != -1) { + /* n->dsp = -1 means initialized global */ + if (init==0) { + data_mode(0); + init=1; + } + printf(".comm %s,%d\n",n->nm,size(n->ty)); + } + } +} + +void +local_table(void) +{ + NMTBL *n; + int init; + init=0; + /* static local variables */ + for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) { + if (n->sc == GVAR) { + if (init==0) { + data_mode(0); + init=1; + } + printf(".lcomm %s,%d\n",n->nm,size(n->ty)); + } + } +} + +void +text_mode(void) +{ + if (output_mode!=TEXT_EMIT_MODE) { + printf(".text\n"); + printf("\t.align 2\n"); + output_mode = TEXT_EMIT_MODE; + } +} + +void +data_mode(char *name) +{ + if (output_mode!=DATA_EMIT_MODE) { + printf(".data\n"); + output_mode = DATA_EMIT_MODE; + } + if (name) + printf("\t.type\t%s,@object\n",name); +} + +int +lvar(int l) +{ + if (fnptr->sc==CODE) { + return l+code_disp_offset; + } else if (l<0) { + return l+disp_offset; + } else { + return l+arg_offset; + } +} + +/* end */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc-code.h Thu Feb 20 03:29:15 2003 +0900 @@ -0,0 +1,67 @@ +/* function required by mc-codegen.c + mc-code-*.c have to provied these + */ + +extern char *register_name(int i,int byte); +extern void gexpr_code_init(void); +extern int register_var(int r); +extern int get_register_var(void); +extern void use_data_reg(int virt, int move); +extern void emit_push(void); +extern void emit_push_x(int xreg); +extern int emit_pop(int type); +extern void gexpr_code_init(); +extern void code_gvar(int e1); +extern void code_rgvar(int e1); +extern void code_crgvar(int e1); +extern void code_lvar(int e2); +extern void code_register(int e2); +extern void code_rlvar(int e2); +extern void code_crlvar(int e2); +extern void code_fname(char *e2); +extern void code_const(int e2); +extern void code_neg(); +extern void code_not(); +extern void code_lnot(); +extern void code_preinc(int e1,int e2); +extern void code_postinc(int e1,int e2); +extern void code_cpostinc(int e1,int e2); +extern void code_cpreinc(int e1,int e2); +extern void code_cpostdec(int e1,int e2); +extern void code_cpredec(int e1,int e2); +extern void code_return(); +extern void code_environment(); +extern void code_bool(int e1); +extern char *code_gt(int cond); +extern char *code_ugt(int cond); +extern char *code_ge(int cond); +extern char *code_uge(int cond); +extern char *code_eq(int cond); +extern void code_cmp_crgvar(int e1); +extern void code_cmp_crlvar(int e1); +extern void code_cmp_rgvar(int e1); +extern void code_cmp_rlvar(int e1); +extern void code_cmp_register(int e2); +extern void string(int e1); +extern void emit_copy(int from,int to,int length,int offset,int value,int det); +extern void function(int e1); +extern void code_frame_pointer(int e3); +extern void code_fix_frame_pointer(int disp_offset); +extern void code_jmp(char *s); +extern void code_indirect_jmp(int e2); +extern void rindirect(int e1); +extern void code_assign_gvar(int e2,int byte); +extern void code_assign_lvar(int e2,int byte); +extern void code_assign_register(int e2,int byte); +extern void code_assign(int e2,int byte); +extern void code_register_assop(int e2,int op,int byte); +extern void code_assop(int op,int byte); +extern void tosop(int op,int oreg); +extern void opening(char *filename); +extern void rexpr(int e1, int l1, char *s); +extern void jcond(int l, char cond); +extern void jmp(int l); +extern void code_set_fixed_creg(int mode); +extern void text_mode(void); +extern int lvar(int l); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc-codegen.c Thu Feb 20 03:29:15 2003 +0900 @@ -0,0 +1,909 @@ +/* Micro-C Generic Code Generatation Part */ +/* $Id$ */ + +#define EXTERN extern +#include "mc.h" +#include "mc-codegen.h" +#include "mc-code.h" + +int creg; /* current register */ +int dreg; /* temporary register */ +int reg_sp; /* REGister Stack-Pointer */ + +/* + creg currrent virtual register + dreg spare virtual register + + rname[creg] currrent real register + rname[dreg] spare real register + + regs[] virtual register usage + regv[] value in virtual register flag + + reg_name[rname[creg]] + */ + +void remove0(int *parent,int e) ; +void remove0_all(int *parent,int e) ; +int is_same_type(int e1,int e2); +void jump(int e1, int env); +void machinop(int e1); +void sassign(int e1); +void assign(int e1); +void assop(int e1); + +int +get_register(void) +{ /* 使われていないレジスタを調べる */ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { /* 使われていないなら */ + regs[i]=1; /* そのレジスタを使うことを宣言し */ + return i; /* その場所を表す番号を返す */ + } + } + return -1; /* 空いている場所がないなら、それを表す -1 を返す */ +} + +void +free_register(int i) { /* いらなくなったレジスタを開放 */ + regv[i]=regs[i]=0; +} + +int +register_full(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { + return 0; + } + } + return 1; +} + +int +free_register_count(void) +{ + int i,count; + count = 0; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i] && ! regv[i]) count++; + } + return count; +} + +void +free_all_register(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + regs[i]=regv[i]=0; + } + creg = get_register(); + dreg = get_register(); + return; +} + +void +use_register_var(int i) { + regv[i]=1; +} + +int creg_regvar = -1; +static int creg_regvar_back; +static int creg_back; + +void +creg_destroy() { + creg_back = creg; creg_regvar_back = creg_regvar; + if (creg_regvar>=0) + creg = creg_regvar; + creg_regvar=-1; +} + +void +creg_un_destroy() { + creg = creg_back; creg_regvar = creg_regvar_back; +} + +void +register_usage(char *s) +{ + int i; + printf("# %d: %s:",lineno,s); + printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0)); + for(i=0;i<MAX_REGISTER;i++) { + printf("%d",regs[i]); + } + printf(":"); + for(i=0;i<MAX_REGISTER;i++) { + printf("%d",regv[i]); + } +#if 0 + printf(" regs_stack",register_name(creg,0),register_name(dreg,0)); + for(i=reg_sp;i>=0;i--) { + if(reg_stack[i]>=0) + printf(" %s",register_name(reg_stack[i],0)); + } +#endif + printf("\n"); +} + +void +gexpr_init(void) +{ + while(reg_sp > 0) { + free_register(reg_stack[--reg_sp]); + } + text_mode(); + gexpr_code_init(); + register_usage("gexpr_init"); +} + + +void +emit_init(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;} + free_all_register(); + reg_sp = 0; + text_mode(); +} + +int +virtual(int real) +{ + int real_v,i; + real_v = -1; + for(i=0;i<MAX_REGISTER;i++) { + if (rname[i]==real) { + real_v=i; + break; + } + } + return real_v; +} + +int +pop_register(void) +{ /* レジスタから値を取り出す */ + return reg_stack[--reg_sp]; +} + +int +stack_used(void) { + return reg_stack[--reg_sp]<0; +} + +void +emit_pop_free(int xreg) +{ + if (xreg==dreg) { + regv[dreg]=0; + } else if (xreg!=-1) { + free_register(xreg); + } +} + +void +gexpr(int e1) +{ + gexpr_init(); +#if 0 + if(lineno==2862) { + g_expr(e1); /*break here*/ + return; + } +#endif + g_expr(e1); +} + +int +csvalue() +{ + return rname[creg]; /* for switch value */ +} + +void +g_expr(int e1) +{ + int e2,e3/*,e4*/; + NMTBL *n; + + if (chk) return; + e2 = cadr(e1); + switch (car(e1)){ + case GVAR: + code_gvar(e1); + regv[creg]=1; + return; + case RGVAR: + code_rgvar(e1); + regv[creg]=1; + return; + case CRGVAR: + code_crgvar(e1); + regv[creg]=1; + return; + case LVAR: + code_lvar(lvar(e2)); + regv[creg]=1; + return; + case REGISTER: + /* this is of course redundant... */ + /* we can use rname for this? */ + /* or why not creg=e2? */ + code_register(e2); + regv[creg]=1; + return; + case RLVAR: + code_rlvar(lvar(e2)); + regv[creg]=1; + return; + case CRLVAR: + code_crlvar(lvar(e2)); + regv[creg]=1; + return; + case FNAME: + code_fname(((NMTBL *)(e2))->nm); + regv[creg]=1; + return; + case CONST: /* 代入する値が0でも特別な処理はしない */ + code_const(e2); + regv[creg]=1; + return; + case STRING: + string(e1); + regv[creg]=1; + return; + case FUNCTION: + function(e1); + regv[creg]=1; + return; + case CODE: + jump(e2,caddr(e1)); + return; + case INDIRECT: + g_expr(e2); + return; + case RINDIRECT: case CRINDIRECT: + rindirect(e1); + return; + case ADDRESS: + g_expr(e2); + return; + case MINUS: /* レジスタに対し、neglを実行すれば実現可能 */ + g_expr(e2); + code_neg(); + return; + case BNOT: /* ~ */ + g_expr(e2); + code_not(); + return; + case LNOT: /* ! */ + g_expr(e2); + code_lnot(); + return; + case PREINC: + code_preinc(e1,e2); + return; + case POSTINC: + code_postinc(e1,e2); + return; + case CPOSTINC: + /* char *p; *p++ */ + code_cpostinc(e1,e2); + return; + case CPREINC: + code_cpreinc(e1,e2); + return; + case CPOSTDEC: + code_cpostdec(e1,e2); + return; + case CPREDEC: + code_cpredec(e1,e2); + return; + case MUL: case UMUL: + case DIV: case UDIV: + case MOD: case UMOD: + case LSHIFT: case ULSHIFT: case RSHIFT: case URSHIFT: + case ADD: case SUB: case BAND: case EOR: case BOR: + machinop(e1); + return; + case COND: + e2=fwdlabel(); + b_expr(cadr(e1),0,e2,0); + code_set_fixed_creg(0); + g_expr(caddr(e1)); + /* e4 = rname[creg]; this is a bad idea */ + code_set_fixed_creg(1); + jmp(e3=fwdlabel()); + fwddef(e2); + code_set_fixed_creg(0); + g_expr(cadddr(e1)); + code_set_fixed_creg(1); + fwddef(e3); + return; + case SASS: + sassign(e1); + return; + case ASS: case CASS: + assign(e1); + return; + case ASSOP: case CASSOP: + assop(e1); + return; + case RSTRUCT: + g_expr(e2); + return; + case COMMA: + g_expr(e2); + g_expr(caddr(e1)); + return; + case RETURN: + n = (NMTBL *)e2; + if (retcont==0) + retcont=fwdlabel(); + code_return(creg); + regv[creg]=1; + return; + case ENVIRONMENT: + code_environment(creg); + regv[creg]=1; + return; + default: + code_bool(e1); + regv[creg]=1; + } +} + +void +bexpr(int e1, char cond, int l1) +{ + gexpr_init(); + b_expr(e1,cond,l1,0); +} + +void +b_expr(int e1, char cond, int l1,int err) +{ + int e2,l2; + if (chk) return; + e2=cadr(e1); + switch(car(e1)) { + case LNOT: + b_expr(e2,!cond,l1,0); + return; + case GT: + rexpr(e1,l1,code_gt(cond)); + return; + case UGT: + rexpr(e1,l1,code_ugt(cond)); + return; + case GE: + rexpr(e1,l1,code_ge(cond)); + return; + case UGE: + rexpr(e1,l1,code_uge(cond)); + return; + case LT: + rexpr(e1,l1,code_ge(!cond)); + return; + case ULT: + rexpr(e1,l1,code_uge(!cond)); + return; + case LE: + rexpr(e1,l1,code_gt(!cond)); + return; + case ULE: + rexpr(e1,l1,code_ugt(!cond)); + return; + case EQ: + rexpr(e1,l1,code_eq(cond)); + return; + case NEQ: + rexpr(e1,l1,code_eq(!cond)); + return; + case LAND: + b_expr(e2,0,cond?(l2=fwdlabel()):l1,0); + b_expr(caddr(e1),cond,l1,0); + if(cond) fwddef(l2); + return; + case LOR: + b_expr(e2,1,cond?l1:(l2=fwdlabel()),0); + b_expr(caddr(e1),cond,l1,0); + if(!cond) fwddef(l2); + return; + case CRGVAR: + code_cmp_crgvar(e1); + jcond(l1,cond); + return; + case CRLVAR: + code_cmp_crlvar(lvar(e2)); + jcond(l1,cond); + return; + case RGVAR: + code_cmp_rgvar(e1); + jcond(l1,cond); + return; + case RLVAR: + code_cmp_rlvar(lvar(e2)); + jcond(l1,cond); + return; + case REGISTER: + code_cmp_register(e2); + jcond(l1,cond); + return; + case CONST: + if((cond&&e2)||(!cond&&!e2)) jmp(l1); + return; + default: + if(err) { + error(-1); return; /* recursice g_expr/b_expr */ + } + g_expr(e1); + code_cmp_register(creg); + jcond(l1,cond); + return; + } +} + + +/* goto arguments list */ +/* target list4(list2(tag,disp),cdr,ty,source_expr) */ +/* source expr=listn(tag,...) */ +/* source (after) list2(tag,disp) */ +/* source list list3(e,cdr,sz) */ + +#define DEBUG_PARALLEL_ASSIGN 1 + +int +overrap(int t,int sz,int source) +{ + int s,s0,s1; + int t0=cadr(t); + int t1=t0+sz; + for(;source;source=cadr(source)) { + s=car(source); s0=cadr(s); + if(car(s)==REGISTER && car(t)==REGISTER) { + if(s0==t0) return s; + } else if (is_same_type(s,t)) { + s1=s0+caddr(source); +#if DEBUG_PARALLEL_ASSIGN>1 +printf("# ovedrrap source %d t0 %d t1 %d\n",car(car(t)),t0,t1); +printf("# ovedrrap target %d s0 %d s1 %d\n",car(car(source)),s0,s1); +printf("# ovedrrap equal = %d\n",((t0<=s0&&s0<t1)||(t0<s1&&s1<=t1))); +#endif + if((t0<=s0&&s0<t1)||(t0<s1&&s1<=t1)) return s; + } + } + return 0; +} + +void +remove_target(int *target,int t,int *use) +{ + int use0=*use; + while(use0) { + if (car(use0)==t) { + free_register(caddr(use0)); + break; + } + use0 = cadr(use0); + } + remove0(target,t); +} + +void +save_target(int t,int s,int *target,int *use,int sz,int ty) +{ + int e1; + /*新しいレジスタ(or スタック)を取得する*/ + if (sz==size_of_int && (e1=get_register())!=-1) { + *use=list3(t,*use,e1); + e1=list2(REGISTER,e1); + g_expr(assign_expr0(e1,s,ty,ty)); + *target = append4(*target,t,ty,e1); + } else { + disp-=sz; + g_expr(assign_expr0((e1=list2(LVAR,disp)),s,ty,ty)); + *target = append4(*target,t,ty,e1); + } +} + +int +circular_dependency(int t,int s,int *target,int *source) +{ + int target0=*target; + int t1,sz,ty,s1; + while(target0) { + if (cadddr(target0)==s) { + t1=car(target0); + s=cadddr(target0); + sz=size(ty=caddr(target0)); + if(t==t1) { +#if DEBUG_PARALLEL_ASSIGN +printf("# circular dependency %d ty %d+%d sz %d\n",car(t1),ty,cadr(t1),sz); +#endif + return 1; + } + if ((s1=overrap(t1,sz,*source))) { + /* another overrap start over */ + return circular_dependency(t,s1,target,source); + } + } + target0=cadr(target0); + } + return 0; +} + +void +parallel_assign(int *target,int *source,int *processing,int *use) +{ + int t,s,sz,ty,target0,s1; + while(*target) { + target0=*target; + while(target0) { + t=car(target0); s=cadddr(target0); + sz=size(ty=caddr(target0)); + if(car(t)==car(s) && cadr(t)==cadr(s)) { + /*書き込み先が自分自身*/ +#if DEBUG_PARALLEL_ASSIGN +printf("# remove same %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); +#endif + remove_target(target,t,use); + /* 破壊されては困るので、source listからは除かない */ + } else if (!(s1=overrap(t,sz,*source))) { + /* 重なってないので安心して書き込める */ +#if DEBUG_PARALLEL_ASSIGN +printf("# normal assign %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); +#endif + g_expr(assign_expr0(t,s,ty,ty)); + remove_target(target,t,use); remove0(source,s); + } else { + if(circular_dependency(t,s1,target,source)) { +#if DEBUG_PARALLEL_ASSIGN + printf("# saving %d ty %d+%d sz %d\n",car(t),ty,cadr(t),sz); +#endif + remove_target(target,t,use); remove0(source,s); + save_target(t,s,target,use,sz,ty); + } + } + target0=cadr(target0); + } + } +} + +void +remove0(int *parent,int e) +{ + int list; + while ((list=*parent)) { + if (car(list)==e) { + *parent= cadr(list); return; + } else { + parent=&cadr(list); + } + } +} + +void +remove0_all(int *parent,int e) +{ + int list; + while ((list=*parent)) { + if (car(list)==e) { + *parent= cadr(list); + } else { + parent=&cadr(list); + } + } +} + +int +is_simple(int e1) +{ + return ( + e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER || + e1==GVAR || e1==RGVAR || e1==RLVAR || e1==CRLVAR || e1==CRGVAR + ); +} + +int +is_same_type(int e1,int e2) +{ + int ce1=car(e1); + int ce2=car(e2); + return ( + (ce1==LVAR && (ce2==RLVAR||ce2==CRLVAR)) + || (ce2==LVAR && (ce1==RLVAR||ce1==CRLVAR)) + || (ce1==GVAR && (ce2==RGVAR||ce2==CRGVAR)) + || (ce2==GVAR && (ce1==RGVAR||ce1==CRGVAR)) + ); +} + +int +is_memory(int e1) +{ + int ce1=car(e1); + return ( + ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || + ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || + ce1==REGISTER + ); +} + +void +jump(int e1, int env) +{ + int e2,e3,e4,sz,arg_size,ty,max_regs,regs; + int t0,s0; + NMTBL *code0; + int target = 0; + int source = 0; + int processing = 0; + int use = 0; + + /* まず、サイズを計算しながら、決まった形に落す。 */ + + arg_size = 0; regs = 0; max_regs = MAX_REGISTER_VAR-1; + for (e3 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { + e2 = car(e3); sz = size(ty=caddr(e3)); + if (regs <= max_regs&&scalar(ty)) { + target=list4(list2(REGISTER,register_var(regs++)), target,ty,e2); + } else { + target=list4(list2(LVAR,0), target,ty,e2); + arg_size += sz; + } +#if DEBUG_PARALLEL_ASSIGN +printf("# target %d ty %d+%d sz %d\n",car(car(target)),ty,cadr(car(target)),sz); +#endif + } + + /* disp を飛び先似合わせて修正 */ + if (fnptr->sc==CODE) { + if (-arg_size<disp) disp = -arg_size; + } else { + if (disp_offset-arg_size<disp) disp = disp_offset-arg_size; + } + + /* 複雑な式を前もって計算しておく */ + /* 必要なら局所変数を用いる。 */ + /* 局所変数へのオフセットを覚えておく */ + + for (e2 = target; e2; e2 = cadr(e2)) { + t0=car(e2); s0=cadddr(e2); + sz=size(ty=caddr(e2)); + if(car(t0)==LVAR) { + /* ここで、書込先アドレスを決める */ + cadr(t0)=-arg_size; + arg_size-=sz; + } + if (!is_simple(car(s0))) { + disp-=sz; + g_expr(assign_expr0((e4=list2(LVAR,disp)),s0,ty,ty)); + cadddr(e2)=e4; + s0=e4; + } else if (is_same_type(t0,s0)) { + if(cadr(t0)==cadr(s0)) { +#if DEBUG_PARALLEL_ASSIGN +printf("# remove same memory %d ty %d+%d sz %d\n",car(t0),ty,cadr(t0),sz); +#endif + /* we should check size also (but currently useless */ + remove0(&target,t0); + /* still we have source to avoid overwrite */ + } + } + if(is_memory(s0)) { + source=list3(s0,source,sz); +#if DEBUG_PARALLEL_ASSIGN +printf("# source %d ty %d+%d sz %d\n",car(car(source)),ty,cadr(car(source)),sz); +#endif + } + } + + /* compute jump address */ + e2 = cadr(e1); + if (car(e2) == FNAME) { + code0=(NMTBL *)cadr(e2); + if (code0->sc!=CODE) { + error(TYERR); return; + } + } else { /* indirect */ + g_expr(e2); + emit_push(); + } + if (env) { + g_expr(env); + emit_push(); + } + + /* 並列代入を実行 */ + + parallel_assign(&target,&source,&processing,&use); + while (use) { + free_register(caddr(use)); use=cadr(use); + } + if(target) error(-1); + + if (env) { + /* change the frame pointer */ + e3 = emit_pop(0); + code_frame_pointer(e3); + emit_pop_free(e3); + } else if (fnptr->sc==FUNCTION) { + code_fix_frame_pointer(disp_offset); + } + + if (car(e2) == FNAME) { + code_jmp(code0->nm); + } else { + e2 = emit_pop(0); + code_indirect_jmp(e2); + emit_pop_free(e2); + } +} + +void +machinop(int e1) +{ + int e2,e3,op; + + e2 = cadr(e1); + op = car(e1); + e3 = caddr(e1); + g_expr(e3); + emit_push(); + g_expr(e2); + tosop(car(e1),(e2=pop_register())); + emit_pop_free(e2); + regv[creg]=1; + return; +} + + +void +sassign(int e1) +{ + int e2,e3,e4,sz,xreg,det; + + /* structure assignment */ + e2 = cadr(e1); /* pointer variable to the struct */ + e3 = cadr(e2); /* offset of the variable (distination) */ + e4 = caddr(e1); /* right value (source) */ + sz = cadddr(e1); /* size of struct or union */ + g_expr(e4); + emit_push(); + g_expr(e2); + xreg = emit_pop(0); + /* 一般的にはコピーのオーバラップの状況は実行時にしかわからない */ + /* しかし、わかる場合もある */ + if (car(e4)==RSTRUCT) e4=cadr(e4); + if (is_same_type(e2,e4)) { + if(cadr(e2)<cadr(e4)) sz=-sz; + det=1; + } else { + det = 0; + } + emit_copy(xreg,creg,sz,0,1,det); + emit_pop_free(xreg); + return; +} + +void +assign(int e1) +{ + int e2,e3,e4,byte; + + byte=(car(e1) == CASS); + /* e2=e4 */ + e2 = cadr(e1); + e3 = cadr(e2); + e4 = caddr(e1); + switch(car(e2)) { + case GVAR: /* i=3 */ + g_expr(e4); + code_assign_gvar(e2,byte); + return; + case LVAR: + g_expr(e4); + code_assign_lvar(lvar(cadr(e2)),byte); + return; + case REGISTER: + g_expr(e4); + if (creg!=cadr(e2)) + code_assign_register(cadr(e2),byte); + return; + } + g_expr(e2); + emit_push(); + use_data_reg(creg,0); + g_expr(e4); + if (byte) use_data_reg(creg,1); + e2 = emit_pop(0); + code_assign(e2,byte); + emit_pop_free(e2); + regv[creg]=1; + return; +} + +void +assop(int e1) +{ + int e2,e3,byte,op; + + /* e2 op= e3 */ + byte = (car(e1) == CASSOP); + e2 = cadr(e1); + if (car(e2)==INDIRECT) e2=cadr(e2); + e3 = caddr(e1); + op = cadddr(e1); + + g_expr(e3); + if (car(e2)==REGISTER) { + code_register_assop(cadr(e2),op,byte); + regv[creg]=1; + return; + } + emit_push(); + g_expr(e2); + code_assop(op,byte); + regv[creg]=1; + return; +} + + +int +fwdlabel(void) +{ + return labelno++; +} + +void +fwddef(int l) +{ + control=1; + printf("_%d:\n",l); +} + +int +backdef(void) +{ + control=1; + printf("_%d:\n",labelno); + return labelno++; +} + +void +def_label(int cslabel, int dlabel) +{ + int fl; + + fl = 0; + if (control) { + jmp(fl=fwdlabel()); + } + fwddef(cslabel); + if (dlabel) + jmp(dlabel); + if (fl) { + fwddef(fl); + } +} + +void +gen_source(char *s) +{ + printf("%s",s); +} + +void +ret(void) +{ + code_set_fixed_creg(1); + jmp(retlabel); +} + +/* end */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc-codegen.h Thu Feb 20 03:29:15 2003 +0900 @@ -0,0 +1,63 @@ + +extern int creg; /* current register */ +extern int dreg; /* temporary register */ +extern int reg_sp; /* REGister Stack-Pointer */ + +extern int rname[]; +extern int regs[]; /* 使われているレジスタを示すフラグ */ +extern int reg_stack[]; /* 実際のレジスタの領域 */ +extern int regv[]; /* 値が入っているかどうか */ +extern int MAX_REGISTER; + +extern int creg_regvar; + +/* function provided by mc-codegen.c */ + + +extern void def_label(int cslabel, int dlabel); +extern int backdef(void); +extern int csvalue(); +extern int free_register_count(void); +extern int fwdlabel(void); +extern int get_register(void); +extern int pop_register(void); +extern int register_full(void); +extern int virtual(int real); +extern void use_register_var(int i) ; +extern void b_expr(int e1, char cond, int l1,int err); +extern void bexpr(int e1, char cond, int l1); +extern void emit_init(void); +extern void emit_pop_free(int xreg); +extern void free_all_register(void); +extern void free_register(int i); +extern void fwddef(int l); + +extern int csvalue(); +extern void closing(void); +extern void cmpdimm(int e, int csreg); +extern void code_enter(char *name) ; +extern void code_enter1(int args); +extern void code_init(void); +extern void code_leave(char *name) ; +extern void emit_data(int e, int t, NMTBL *n); +extern void emit_data_closing(NMTBL *n); +extern void emit_init(void); +extern void enter(char *name); +extern void enter1(); +extern void g_expr(int e1); +extern void gen_comment(char *s); +extern void gen_gdecl(char *n, int gpc); +extern void gen_source(char *s); +extern void gexpr(int e1); +extern void gexpr_init(void); +extern void jcond(int l, char cond); +extern void jmp(int l); +extern void jmp_eq_label(int l); +extern void jmp_label(int l); +extern void leave(int control, char *name); +extern void opening(char *filename); +extern void ret(void); +extern void use_register_var(int); + + +/* end */
--- a/mc-nop-386.c Wed Feb 19 21:22:49 2003 +0900 +++ b/mc-nop-386.c Thu Feb 20 03:29:15 2003 +0900 @@ -62,7 +62,7 @@ static void emit_copy(int from,int to,int length,int offset,int value,int det); static int is_same_type(int s,int t); -extern int error(int n); +extern void error(int n); extern int fwdlabel(void); extern void fwddef(int l); extern int backdef(void); @@ -491,7 +491,7 @@ int csvalue() { - return rname[creg]; /* for siwtch value */ + return rname[creg]; /* for switch value */ } void @@ -954,10 +954,8 @@ printf("\tpushl 4(%s)\n",register_name(creg,0)); printf("\tpushl (%s)\n",register_name(creg,0)); return 2; } - /* I think, after g_expr, at least two registers are free */ printf("\tsubl $%d,%%esp\n",length); if (register_full()) { - /* this is wrong assumption */ save = 1; for(lreg=0;lreg==creg||lreg==dreg;lreg++); printf("\tpushl %s\n",register_name(lreg,0)); @@ -1336,13 +1334,6 @@ printf("\tlea %d(%%ebp),%%ebp\n",disp_offset); } - /* shrink stack if necessary */ - /* - if (!env && -arg_size<disp) { - printf("\tleal %d(%%ebp),%%esp\n",-arg_size); - } Why we need this? - */ - if (car(e2) == FNAME) { printf("\tjmp %s\n",code0->nm); } else { @@ -1625,26 +1616,6 @@ printf("\t%s (%s),%s\n",op,register_name(xreg,0),register_name(creg,byte)); } -/* -void -st_indexx(int byte, int n, int xreg) -{ - char *op; - - op = byte ? "movb" : "movl"; - if (n) - printf("\t%s %s,%d(%s)\n",op,register_name(creg,byte),n,register_name(xreg,0)); - else - printf("\t%s %s,(%s)\n",op,register_name(creg,byte),register_name(xreg,0)); -} - -void -indexy(char *op, char *gvar) -{ - printf("\t%s %s,%s\n",op,register_name(creg,0),gvar); -} - */ - void cmpdimm(int e, int csreg) {
--- a/mc-parse.c Wed Feb 19 21:22:49 2003 +0900 +++ b/mc-parse.c Thu Feb 20 03:29:15 2003 +0900 @@ -3,36 +3,30 @@ #define EXTERN /**/ #include "mc.h" +#include "mc-codegen.h" -void ntable_consistency(); -static void adecl(NMTBL *n); -static int decl_data(int t, NMTBL *n,int offset); +static NMTBL *decl0(void),*decl1(void),*lsearch(char *name),*gsearch(void); +static NMTBL *def(NMTBL *n); +static NMTBL *free_nptr(); +static NMTBL *msearch(char *name); +static NMTBL *msearch0(char *name); +static char * mappend(int lists); static int alpha(char c); +static int append3(int p,int a1,int a2); static int binop(int op, int e1, int e2, int t1, int t2); -static void compatible(int t1, int t2); -static void decl(void); -static NMTBL *def(NMTBL *n); +static int cexpr(int e); +static int decl_data(int t, NMTBL *n,int offset); static int digit(char c); -static void docase(void); -static void docomp(void); -static void dodefault(void); -static void dodo(void); -static void dofor(void); -static void dogoto(void); -static void doif(void); -static void dolabel(void); -static void doswitch(void); -static void doreturn(void); -static void dowhile(void); -static void errmsg(void); -static void macro_processing(); -static void macro_define(); -static void macro_define0(); -static void copy(NMTBL *nptr, char *s); -void error(int n); static int expr(void); static int expr0(void); static int expr1(void); +static int expr10(void); +static int expr11(void); +static int expr12(void); +static int expr13(void); +static int expr14(void); +static int expr15(int e1); +static int expr16(int e1); static int expr2(void); static int expr3(void); static int expr4(void); @@ -41,101 +35,61 @@ static int expr7(void); static int expr8(void); static int expr9(void); -static int expr10(void); -static int expr11(void); -static int expr12(void); -static int expr13(void); -static int expr14(void); -static int expr15(int e1); -static int expr16(int e1); -static void fcheck(NMTBL *n); -static void fdecl(NMTBL *n); static int getch(void); static int getfree(int n); -static void getline(void); -static void getstring(void); static int getsym(void); static int indop(int e); -static void init(void); -extern int integral(int t); -static void lcheck(int e); -extern int glist2(int e1,int e2); -extern int list2(int e1, int e2); -extern int list3(int e1, int e2, int e3); -extern int list4(int e1, int e2, int e3, int e4); -extern int rplacad(int e, int n); -extern int rplacadd(int e, int n); -static void reserve(char *s, int d); +static int macro_args(char **pcheapp,char* max,char **pchptr); +static int macro_eval(int macrop,char *body,int history); +static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history); static int macroeq(char *s); static int ndecl0(void); static int ndecl1(void); static int neqname(char *p,char *name); -static void newfile(void); static int postequ(int s1, int s2); -static void reverse(int t1); -int reverse0(int t1); static int rvalue(int e); -extern int rvalue_t(int e,int type); -int scalar(int t); static int sdecl(int s); static int skipspc(void); -static void statement(void); static int strop(int e); static int typeid(int s); static int typename(void); static int typespec(void); -static int cexpr(int e); +static void adecl(NMTBL *n); static void code_decl(NMTBL *n); -static int macro_args(char **pcheapp,char* max,char **pchptr); -static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history); +static void compatible(int t1, int t2); +static void copy(NMTBL *nptr, char *s); +static void decl(void); +static void docase(void); +static void docomp(void); +static void dodefault(void); +static void dodo(void); +static void dofor(void); +static void dogoto(void); +static void doif(void); +static void dolabel(void); +static void doreturn(void); +static void doswitch(void); +static void dowhile(void); +static void errmsg(void); +static void fcheck(NMTBL *n); +static void fdecl(NMTBL *n); +static void fdecl_struct(int type); +static void getline(void); +static void getstring(void); +static void init(void); +static void lcheck(int e); static void local_define(); static void local_undef(); -static int macro_eval(int macrop,char *body,int history); -static char * mappend(int lists); -static NMTBL *free_nptr(); +static void macro_define(); +static void macro_define0(); +static void macro_processing(); +static void newfile(void); static void replace_return_struct(int func,int left); -static void fdecl_struct(int type); -static int append3(int p,int a1,int a2); -extern int append4(int p,int a1,int a2,int a3); +static void reserve(char *s, int d); +static void reverse(int t1); static void set_converter(char *s); +static void statement(void); -extern void display_ntable(NMTBL *n, char *s); -extern void closing(void); -extern void opening(char *filename); -extern void gen_gdecl(char *n, int gpc); -extern void emit_init(void); -extern void enter(char *name); -extern void enter1(); -extern void leave(int control, char *name); -extern void ret(void); -extern void jmp(int l); -extern void gexpr(int e1); -extern void g_expr(int e1); -extern int get_register_var(void); -extern void use_register_var(int); -extern void bexpr(int e1, char cond, int l1); -extern int fwdlabel(void); -extern void fwddef(int l); -extern int backdef(void); -extern int def_label(int cslabel, int dlabel); -extern void jmp_label(int l); -extern void cmpdimm(int e, int csreg); -extern void jcond(int l, char cond); -extern void jmp_eq_label(int l); -extern void gen_comment(char *s); -extern void gen_source(char *s); -extern void code_init(void); -extern void code_enter(char *name) ; -extern void code_leave(char *name) ; -extern void code_enter1(int args); -extern int csvalue(); -extern int assign_expr(int e1,int e2,int t,int type); -extern int assign_expr0(int e1,int e2,int t,int type); - -extern void emit_data_closing(NMTBL *n); -extern void emit_data(int e, int t, NMTBL *n); - -extern void exit(int l); static int struct_return = 0; static int arglist = 0; @@ -246,7 +200,7 @@ exit(1); } -void +static void errmsg(void) { char *p,*lim; @@ -262,7 +216,7 @@ fprintf (stderr,"^\n"); } -void +static void checksym(int s) { char *p; @@ -277,7 +231,7 @@ getsym(); } -void +static void init(void) { NMTBL *nptr; @@ -330,7 +284,7 @@ getch(); } -void +static void newfile(void) { char *s; @@ -343,7 +297,7 @@ while((*cheapp++ = *s++)); } -void +static void set_converter(char *s) { chptr = s; @@ -353,7 +307,7 @@ else conv=&null_converter; } -void +static void reserve(char *s, int d) { NMTBL *nptr; @@ -377,7 +331,7 @@ static NMTBL null_nptr; -void +static void decl(void) { NMTBL *n; @@ -444,7 +398,7 @@ mode=LDECL; } -int +static int typespec(void) { int t; @@ -500,7 +454,7 @@ return t; } -struct nametable * +static struct nametable * decl0(void) { NMTBL *n; @@ -514,7 +468,7 @@ } -NMTBL * +static NMTBL * decl1(void) { NMTBL *n; @@ -581,7 +535,7 @@ } -void +static void adecl(NMTBL *n) { NMTBL *arg,*sfnptr; @@ -637,7 +591,7 @@ return; } -void +static void reverse(int t1) { int t2,t3; @@ -684,7 +638,7 @@ return 0; } -NMTBL * +static NMTBL * def(NMTBL *n) { int sz,nsc,ndsp,t; @@ -832,7 +786,7 @@ return n; } -void +static void emit_init_vars(void) { if (!init_vars) return; @@ -869,7 +823,7 @@ return 0; /* not reached */ } -int +static int decl_data(int t, NMTBL *n,int offset) { int t1,e,i,mode_save; @@ -939,7 +893,7 @@ return offset; /* not reached */ } -int +static int sdecl(int s) { int smode,sdisp,type0; @@ -994,7 +948,7 @@ return type0; } -void +static void code_decl(NMTBL *n) { int t; @@ -1039,7 +993,7 @@ static NMTBL *tmp_struct; -void +static void fdecl(NMTBL *n) { enter(n->nm); @@ -1080,7 +1034,7 @@ static NMTBL str_ret; -void +static void fdecl_struct(int fntype) { int type_save,mode_save,t,sz; @@ -1131,7 +1085,7 @@ } } -void +static void compatible(int t1, int t2) { if(integral(t1)) { @@ -1157,7 +1111,7 @@ return(t==INT||t==CHAR||t==UNSIGNED); } -void +static void checkret(void) { if (retpending) { @@ -1167,7 +1121,7 @@ } } -void +static void statement(void) { int slfree; @@ -1232,7 +1186,7 @@ } } -void +static void doif(void) { int l1,l2,slfree; @@ -1256,7 +1210,7 @@ else fwddef(l1); } -void +static void dowhile(void) { int sbreak,scontinue,slfree,e; @@ -1287,7 +1241,7 @@ blabel=sbreak; } -void +static void dodo(void) { int sbreak,scontinue,l,slfree; @@ -1313,7 +1267,7 @@ blabel=sbreak; } -void +static void dofor(void) { int sbreak,scontinue,l,e,slfree; @@ -1358,7 +1312,7 @@ blabel=sbreak; } -void +static void doswitch(void) { int sbreak,scase,sdefault,slfree,svalue; @@ -1389,7 +1343,7 @@ blabel=sbreak; } -void +static void docomp(void) { getsym(); @@ -1397,7 +1351,7 @@ getsym(); } -void +static void docase(void) { int c,l,slfree; @@ -1426,7 +1380,7 @@ fwddef(l); } -void +static void dodefault(void) { getsym(); @@ -1436,7 +1390,7 @@ dlabel = backdef(); } -void +static void doreturn(void) { int slfree,e,e1; @@ -1481,7 +1435,7 @@ rplacad(e,left); } -void +static void dogoto(void) { NMTBL *nptr0; @@ -1525,7 +1479,7 @@ return; } -void +static void dolabel(void) { if(nptr->sc == FLABEL) @@ -1574,7 +1528,7 @@ return(rvalue(expr0())); } -int +static int expr0(void) { int e; @@ -1586,7 +1540,7 @@ return e; } -int +static int expr1(void) { int e1,e2,t,op; @@ -1624,7 +1578,7 @@ } } -int +static int expr2(void) { int e1,e2,e3,t; @@ -1650,7 +1604,7 @@ return(e1); } -int +static int expr3(void) { int e; @@ -1665,7 +1619,7 @@ return(e); } -int +static int expr4(void) { int e; @@ -1680,7 +1634,7 @@ return(e); } -int +static int expr5(void) { int e1,e2,t; @@ -1696,7 +1650,7 @@ return(e1); } -int +static int expr6(void) { int e1,e2,t; @@ -1712,7 +1666,7 @@ return(e1); } -int +static int expr7(void) { int e1,e2,t; @@ -1728,7 +1682,7 @@ return(e1); } -int +static int expr8(void) { int e,op; @@ -1743,7 +1697,7 @@ return e; } -int +static int expr9(void) { int e1,e2,t,op; @@ -1763,7 +1717,7 @@ return e1; } -int +static int expr10(void) { int e1,e2,t,op; @@ -1779,7 +1733,7 @@ return e1; } -int +static int expr11(void) { int e1,e2,t,op; @@ -1795,7 +1749,7 @@ return e1; } -int +static int expr12(void) { int e1,e2,t,op; @@ -1811,7 +1765,7 @@ return e1; } -int +static int expr13(void) { int e,op; @@ -1910,7 +1864,7 @@ return e; } -int +static int expr14(void) { int e1,t; @@ -2003,7 +1957,7 @@ return expr16(e1); } -int +static int expr16(int e1) { int e2,t; @@ -2026,7 +1980,7 @@ return e1; } -int +static int rvalue(int e) { int t; @@ -2076,7 +2030,7 @@ return e; } -void +static void lcheck(int e) { int t; @@ -2086,7 +2040,7 @@ error(LVERR); } -int +static int indop(int e) { if(type!=INT&&type!=UNSIGNED) { @@ -2100,7 +2054,7 @@ return(list2(INDIRECT,e)); } -int +static int strop(int e) { getsym(); @@ -2134,7 +2088,7 @@ return e; } -int +static int binop(int op, int e1, int e2, int t1, int t2) { int e; @@ -2240,7 +2194,7 @@ return(list3(type==UNSIGNED?op+US:op,e1,e2)); } -int +static int expr15(int e1) { int t,arglist,e,sz; @@ -2294,7 +2248,7 @@ return list3(FUNCTION,e1,arglist); } -int +static int typeid(int s) { return (integral(s) || s==CODE || s==SHORT || @@ -2302,7 +2256,7 @@ (s==IDENT && nptr->sc==TYPE)); } -int +static int typename(void) { int t; @@ -2313,7 +2267,7 @@ return type; } -int +static int ndecl0(void) { if(sym==MUL) { @@ -2323,7 +2277,7 @@ return ndecl1(); } -int +static int ndecl1(void) { int i,t,arglist; @@ -2360,16 +2314,16 @@ } } -int +static int cexpr(int e) { if (car(e) != CONST) error(CNERR); return (cadr(e)); } -int in_comment = 0; +static int in_comment = 0; -int +static int getsym(void) { NMTBL *nptr0,*nptr1,*nptrm; @@ -2560,20 +2514,20 @@ } } -int +static int postequ(int s1, int s2) { if(ch=='=') {getch();return sym=s2;} return sym=s1; } -int +static int alpha(char c) { return(('a'<=c&&c<='z')||('A'<=c&&c<='Z')||c=='_'); } -int +static int digit(char c) { return('0'<=c&&c<='9'); @@ -2581,7 +2535,7 @@ int dummy_count = 0; -NMTBL * +static NMTBL * free_nptr() { NMTBL *nptr,*iptr; @@ -2602,7 +2556,7 @@ return nptr; } -NMTBL * +static NMTBL * gsearch(void) { NMTBL *nptr,*iptr; @@ -2620,7 +2574,7 @@ return nptr; } -NMTBL * +static NMTBL * lsearch(char *name) { NMTBL *nptr,*iptr; @@ -2639,7 +2593,7 @@ return nptr; } -NMTBL * +static NMTBL * msearch(char *name) { NMTBL *nptr,*iptr; @@ -2659,7 +2613,7 @@ return nptr; } -NMTBL * +static NMTBL * msearch0(char *name) { NMTBL *nptr,*iptr; @@ -2685,14 +2639,14 @@ } -void +static void copy(NMTBL *nptr, char *s) { nptr->nm = cheapp; while((*cheapp++ = *s++)); } -int +static int neqname(char *p,char *q) { if (!p) @@ -2702,7 +2656,7 @@ return (*q!=0); } -void +static void getstring(void) { getch(); @@ -2718,7 +2672,7 @@ symval++; } -int +static int skipspc(void) { while(ch=='\t'||ch=='\n'||ch==' '||ch=='\r') @@ -2726,7 +2680,7 @@ return ch; } -int +static int getch(void) { if(*chptr) return ch = *chptr++; @@ -2778,7 +2732,7 @@ return c; } -FILE * +static FILE * getfname(void) { int i; @@ -2803,7 +2757,7 @@ static int macro_if_current ; static int macro_if_skip ; -void +static void getline(void) { int i; @@ -2829,7 +2783,7 @@ } while(macro_if_skip || linebuf[0] == '#'); } -void +static void macro_processing() { int i; @@ -2922,7 +2876,7 @@ else error(MCERR); } -int +static int macroeq(char *s) { char *p; @@ -2932,7 +2886,7 @@ return 1; } -void +static void macro_define(char *macro) { char *chptr_save; @@ -2946,7 +2900,7 @@ ch = chsave; } -void +static void macro_define0() { int i,args,c; @@ -2980,7 +2934,7 @@ mode=i; } -int +static int macro_args(char **pcheapp,char *maxcheap,char **pchptr) { int c; @@ -3063,7 +3017,7 @@ /* output macro expansion result into macrobuf (macropp) */ -int +static int macro_function(int macrop,char **pchptr,NMTBL *nptr,int history) { int args,sargs,values,evalues; @@ -3094,7 +3048,7 @@ return macrop; } -void +static void local_define(char *macro,char *value) { NMTBL *nptr0; @@ -3104,7 +3058,7 @@ nptr0->dsp=list2((int)value,0); } -void +static void local_undef(char *macro) { NMTBL *nptr0; @@ -3116,7 +3070,7 @@ nptr0->ty=cadr(save); } -int +static int macro_eval(int macrop,char *body,int history) { int c; @@ -3207,7 +3161,7 @@ return e; } -int +static int getfree(int n) { int e; @@ -3273,7 +3227,7 @@ return p1; } -char * +static char * mappend(int lists) { char *p;
--- a/mc.h Wed Feb 19 21:22:49 2003 +0900 +++ b/mc.h Thu Feb 20 03:29:15 2003 +0900 @@ -206,15 +206,26 @@ EXTERN NMTBL mtable[MSYMS]; EXTERN NMTBL ntable[GSYMS+LSYMS]; EXTERN NMTBL *nptr,*gnptr; -EXTERN NMTBL *decl0(void),*decl1(void),*lsearch(char *name),*gsearch(void); EXTERN NMTBL *fnptr; -EXTERN NMTBL *msearch(char *name); -EXTERN NMTBL *msearch0(char *name); EXTERN struct {int fd,ln;char *name0;FILE *fcb;} *filep,filestack[FILES]; EXTERN char cheap[CHEAPSIZE]; EXTERN char *macropp,macro_buf[MACROSIZE]; +extern void error(int n); +extern int size(int t); +extern int scalar(int t); +extern int list2(int e1, int e2); +extern int list3(int e1, int e2, int e3); +extern int list4(int e1, int e2, int e3,int e4); +extern int reverse0(int t1); +extern int assign_data(int e, int t, NMTBL *n,int offset); +extern int assign_expr0(int e1,int e2,int t,int type) ; +extern int assign_expr(int e1,int e2,int t,int type) ; +extern int append4(int p,int a1,int a2,int a3); + + + #define car(e) (heap[(int)(e)]) #define cadr(e) (heap[((int)(e))+1]) @@ -234,4 +245,28 @@ EXTERN Converter *conv; + +EXTERN void error(int n); +EXTERN int append4(int p,int a1,int a2,int a3); +EXTERN int assign_expr(int e1,int e2,int t,int type); +EXTERN int assign_expr0(int e1,int e2,int t,int type); +EXTERN int backdef(void); +EXTERN int fwdlabel(void); +EXTERN int get_register_var(void); +EXTERN int glist2(int e1,int e2); +EXTERN int integral(int t); +EXTERN int list2(int e1, int e2); +EXTERN int list3(int e1, int e2, int e3); +EXTERN int list4(int e1, int e2, int e3, int e4); +EXTERN int reverse0(int t1); +EXTERN int rplacad(int e, int n); +EXTERN int rplacadd(int e, int n); +EXTERN int rvalue_t(int e,int type); +EXTERN int scalar(int t); +EXTERN void bexpr(int e1, char cond, int l1); +EXTERN void def_label(int cslabel, int dlabel); +EXTERN void display_ntable(NMTBL *n, char *s); +EXTERN void exit(int l); +EXTERN void fwddef(int l); + /* end */
--- a/stdio.h Wed Feb 19 21:22:49 2003 +0900 +++ b/stdio.h Thu Feb 20 03:29:15 2003 +0900 @@ -1,9 +1,12 @@ +#ifndef __micro_c__ +#include "/usr/include/stdio.h" +#else + typedef struct { /* this is all wrong, but so what? */ /* char pad[96]; */ char pad[148]; } FILE; - #ifdef __APPLE__ extern FILE __sF[]; @@ -110,3 +113,4 @@ char *tempnam(const char *, const char *); FILE *tmpfile(void); char *tmpnam(char *); +#endif