# HG changeset patch # User kono # Date 1046962062 -32400 # Node ID 917947ffeb7cafc9169d5a421e80e3fa0bd676b7 # Parent 5c8553d7f984059561c9dd197e6816fb7e200757 power pc version diff -r 5c8553d7f984 -r 917947ffeb7c Changes --- a/Changes Wed Mar 05 23:07:00 2003 +0900 +++ b/Changes Thu Mar 06 23:47:42 2003 +0900 @@ -1920,3 +1920,91 @@ FCONST とか。3日で出来たね。 (gcc の方をやった方がいいかなぁ...) + goto.c が通らなくなってるな。 + +Thu Mar 6 14:00:13 JST 2003 + +PowerPCのnon-lazy pointerって、テーブルに入っていてそれを読 +み込む形式なのね。いったん、レジスタに読み込んだら、それを再 +利用する形が良いらしい。ということは、code_gvar にキャッシュ +を作らないといけない。しかも RLU ですか? (めんどくさ〜) +でも、そうしないと、 + i = i+1; +なんてのでも、ひどい目にあってしまう。 + +local variable も最初に move mutilple register で大半は +レジスタに読み込んじゃうみたいね。pointer で参照されると +困るんでしょうけど。まぁ、31個もあれば、そういうことを +してもあまり問題ないのかも知れないけど。 + +creg を破壊しない実装にすれば、少しはましになるんじゃない? +(IA32では、それは難しいけど) + +Thu Mar 6 20:50:24 JST 2003 + +やっぱり、使った分だけregisterを保存するようなコードに +なるみたい。one path で、それをするためには、 + .align 2 +_main0__: + lwz r5,2136(r1) + addi r1,r1,2128 + lmw r23,-36(r1) + mtlr r5 + blr + .align 2 + .globl _main0 +_main0: + mflr r2 + stmw r30,-8(r1) + stw r2,8(r1) + li r11,0 + stwu r1,-480(r1) + li r2,100 + mtctr r2 + mr r30,r3 + addi r0,r1,64 + mr r9,r0 + b _main0__; +とかいう感じにするしかないね。 + +あと引数は、レジスタに積むようになっているみたいだけど... r3 から? + + mflr r31 + li r0,7 + stw r0,56(r1) + +だから8個まではレジスタに積むみたいね。 +r3-r10 だね。 + +構造体もregisterにコピーされるのか。そして、向う側で受取の +コピーを行うわけだね。先頭にreturn structへのポインタがあるのも +同じ。 + +(うう、memcpyしまくりだ...) + +浮動小数点もレジスタ渡し見たい。f1から。(なるほど) + +saveFPってのを呼び出して、 f24-f31をsaveするらしい。 +(31-24)*8 数合わないな? + +pointer のことを考えると、レジスタだとまずいものもある +わけだけど。アドレスを取られてからで間に合うんじゃない? +配列などは、もともとだめだし。場所と値(?)は確保するとして。 + +そうか、逆に、r3-r10 は引数でなければ壊しても良いわけか。 +(それでr9とか良く使われているわけか...) +ということは足りなくなったら、引数をセーブすれば良いわけね。 +(ってことは、LVAR かつ REGISTER っていう状況があるんじゃん... +まぁ、そうだけどさ...) +これは get_register がめんどくさそ。 + +どうも、r11-r12 あたりは自由に使っているらしい。 + +引数を作っている途中で関数呼出しするときは、どうするの? +r30などに移動するのか? + +なんか知らんけど、in file call name と out file call name が +違うみたいね。(sigh...) こんなのなんとかなるのかなぁ。 +全部、stub にしておいて、.set で書き換えるという手もあるけど。 + +(さすがに一日ではできないか...) diff -r 5c8553d7f984 -r 917947ffeb7c mc-code-ia32.c --- a/mc-code-ia32.c Wed Mar 05 23:07:00 2003 +0900 +++ b/mc-code-ia32.c Thu Mar 06 23:47:42 2003 +0900 @@ -100,8 +100,7 @@ void code_leave(char *name); int lvar(int l); void global_table(void); - -char * fstore(int d); +int virtual(int real); char * fload(int d); int code_d1(double d); int code_d2(double d); @@ -163,6 +162,170 @@ return virtual(r+REG_ESI); } + + +int +get_register(void) +{ /* 使われていないレジスタを調べる */ + int i; + for(i=0;isc==REGISTER) { + if ((n->dsp = get_register_var()) <0) { + error(-1); return; + } + use_register_var(n->dsp); /* it has now value in it */ + } + code_arg_register(cadr(args)); + } +} + + +void +register_usage(char *s) +{ + int i; + if (chk) return; + printf("# %d: %s:",lineno,s); + printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0)); + for(i=0;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;isc==REGISTER) { + if ((n->dsp = get_register_var()) <0) { + error(-1); return; + } + use_register_var(n->dsp); /* it has now value in it */ + } + code_arg_register(cadr(args)); + } +} + + +void +register_usage(char *s) +{ + int i; + if (chk) return; + printf("# %d: %s:",lineno,s); + printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0)); + for(i=0;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_MAX) error(-1); + reg_stack[reg_sp++] = -1; + printf("\tstwu %s,-%d(%s)\n",register_name(creg), + size_of_int,register_name(reg_sp)); + /* creg is used soon, don't regv[creg]=0 */ + } else { + reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ + creg = new_reg; + regv[creg]=1; + } +} + +int +emit_pop() +{ + int xreg; + if ((xreg=pop_register())==-1) { + xreg=get_register(); + if(!xreg) error(-1); + printf("\tlwz %s,(%s)\n",register_name(xreg),register_name(reg_sp); + printf("\taddis %s,%s,%d\n", + register_name(reg_sp),register_name(reg_sp),size_of_int; + regv[xreg]=1; + } + return xreg; +} + +static char *code_base; + +#define MAX_PTR_CACHE 10 + +int ptr_cache=0; + +int +clear_ptr_cache() +{ + int ptcptr=ptr_cache; + while(ptcptr) { + if(car(ptcptr)) + free_register(caddr(ptcptr)); + car(ptcptr)=0; + caddr(ptcptr)=0; + ptcptr=cadr(ptcptr); + } +} + +int +init_ptr_cache() +{ + int i; + for(i=0;i < ... */ + xrn = register_name(creg); + printf("\tli %s,0\n",xrn); + jmp(e3=fwdlabel()); + fwddef(e2); + printf("\tli %s,1\n",xrn); + fwddef(e3); +} + +char * +code_gt(int cond) { + return (cond?"gt":"le"); +} + +char * +code_ugt(int cond) { + return (cond?"gt":"le"); +} + +char * +code_ge(int cond) { + return (cond?"ge":"lt"); +} + +char * +code_uge(int cond) { + return (cond?"ge":"lt"); +} + +char * +code_eq(int cond) { + return (cond?"eq":"ne"); +} + +void +code_cmp_crgvar(int e1) { + int r; + char *crn = register_name(creg); + r = get_ptr_cache((char *)caddr(e1)); + printf("\tlbz %s,(%s)\n",crn,register_name(r)); + printf("\tcmpwi cr0,%s,0\n",crn); +} + + +void +code_cmp_crlvar(int e1) { + char *crn = register_name(creg); + printf("\tlbz %s,%d(r1)\n",crn,e1); + printf("\tcmpwi cr0,%s,0\n",crn); +} + + +void +code_cmp_rgvar(int e1) { + int r; + char *crn = register_name(creg); + r = get_ptr_cache((char *)caddr(e1)); + printf("\tlwz %s,(%s)\n",crn,register_name(r)); + code_cmp_register(creg); +} + + +void +code_cmp_rlvar(int e1) { + char *crn = register_name(creg); + printf("\tlwz %s,%d(r1)\n",crn,e1); + code_cmp_register(creg); +} + + +void +code_cmp_register(int e2) { + printf("\tcmpwi cr0,%s,0\n",register_name(e2)); +} + + +void +ascii(char *s) +{ + printf("\t.ascii \""); + 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("\\0%c\n",34); +} + +void +string(int e1) +{ + char *s; + int i,lb; + + s=(char *)cadr(e1); + printf(".data\t.cstring\n\t.align 2\n"); + lb=fwdlabel(); + printf("_%d:\n",lb); + ascii(s); + if (output_mode==TEXT_EMIT_MODE) { + printf(".text\n"); + } else { + text_mode(); + } + printf("\taddis %s,r31,ha16(_%d-%s)\n",crn,lb,code_base); + printf("\tla %s,lo16(_%d-%s)(%s)\n",crn,lb,code_base,crn); +} + +#define MAX_COPY_LEN 20 + +void +emit_copy(int from,int to,int length,int offset,int value,int det) +{ + char *frn = register_name(from); + char *trn = register_name(to); + char *drn; + int fix = 0; + char *bcopy = "bcopy"; + int dreg = get_regiter(); if (!dreg) error(-1); + drn = register_name(dreg); + + /* length <0 means upward direction copy */ + switch (length) { + case 0: break; + case 1: case -1: + printf("\tlbz %s,%d(%s)\n",drn,offset,frn); + printf("\tstb %s,%d(%s)\n",drn,offset,trn); + break; + case 2: case -2: + printf("\tlhz %s,%d(%s)\n",drn,offset,frn); + printf("\tsth %s,%d(%s)\n",drn,offset,trn); + break; + case 4: case -4: + printf("\tlwz %s,%d(%s)\n",drn,offset,frn); + printf("\tstw %s,%d(%s)\n",drn,offset,trn); + break; + default: + if (-MAX_COPY_LEN0) + 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) { + printf("\tli r5,%d\n",length); + printf("\tmr r4,%s\n",trn); + printf("\tmr r3,%s\n",frn); + printf("\tbl L_%s$stub\n",bcopy); + regist_extern_function(bcopy); + break; + } + } + 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("\taddi %s,%s,%d\n",trn,trn,fix); + if(creg!=to) { + free_register(creg); creg=to; + } + } + free_register(dreg); + regv[from]=regv[to]=regv[dreg]=0; + regv[creg]=1; +} + +int +struct_push(int e4,int t) +{ + int length,save,count; + int dreg; char *drn,*crn,*srn; + g_expr(e4); + length=size(t); + if(length%size_of_int) { + length += size_of_int - (length%size_of_int); + } + dreg = get_regiter(); if (!dreg) error(-1); + drn = register_name(dreg); + crn = register_name(dreg); + srn = register_name(reg_sp); + for(count=0;lengthnm); + } else { + jmp=get_tmp_register(); + jrn = register_name(jmp); + printf("\tmr %s,%s\n",jrn,crn); + printf("\tmtctr %s\n",jrn); + printf("\tbctrl\n"); + free_register(jmp); + } + regv[creg]=1; +} + +void +code_frame_pointer(int e3) { + printf("\tmovl %s,r1\n",register_name(e3,0)); +} + + +void +code_fix_frame_pointer(int disp_offset) { + printf("\tla r1,%d(r1)\n",disp_offset); +} + + +void +code_jmp(char *s) { + printf("\tb L_%s$stub\n",s); +} + + +void +code_indirect_jmp(int e2) { + printf("\tmtctr %s\n",register_name(e2)); + printf("\tbctr\n"); +} + +void +rindirect(int e1) /* *(p +5 ) */ +{ + char *op; + int e2,e3,byte; + e3 = cadr(e2 = cadr(e1)); + g_expr(e2); + switch (car(e1)) { + case FRINDIRECT: case DRINDIRECT: + printf("\t%s (%s)\n",fload(car(e1)==DRINDIRECT),register_name(creg)); + break; + case CRINDIRECT: case RINDIRECT: + op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl"); + printf("\t%s (%s),%s\n",op,register_name(creg),register_name(creg)); + } +} + + +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),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)); +} + + +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),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); + 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)); +} + +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() */ + if(chk) return; + use_register(creg,csreg,0); + printf("\tcmpl $%d,%s\n",e,register_name(creg)); +} + +void +code_opening(char *filename) +{ + printf("\t.file \"%s\"\n",filename); + printf("\t.version\t\"01.01\"\n"); + /* printf("gcc2_compiled.:\n"); */ + printf(".text\n"); +} + +void +code_closing() +{ + 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) +{ + if (chk) return; + printf("\tj%s\t_%d\n",cond?"ne":"e",l); +} + +void +jmp(int l) +{ + control=0; + if (chk) return; + 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) +{ + if (chk) return; + 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) +{ + disp&= -size_of_int; + 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)); + /* printf("\tleave\n"); */ + } + fwddef(retlabel); + /* use_register(creg,REG_EAX,0); too late */ + /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */ + disp &= -size_of_int; + + 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; + double d; + float f; + char *name; + name = n->nm; + if(mode!=GDECL) { + error(-1); return; + } + if (chk) 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 if (t==SHORT) { + printf("\t.word %d\n",cadr(e)); + if (data_alignment>0) data_alignment++; + gpc += 2; + } else { + printf("\t.long %d\n",cadr(e)); + gpc += size_of_int; + } + } else if(t==DOUBLE) { + d = dcadr(e); + printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d)); + } else if(t==FLOAT) { + f = dcadr(e); + printf("\t.long\t0x%x\n",*(int *)&f); + } 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 (chk) return; + 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; + } +} + +/* floating point */ + + +char * +fstore(int d) +{ + return use? + (d?"fstl":"fsts"): + (d?"fstpl":"fstps") + ; +} + +char * +fstore_u(int d) +{ + return d?"fstpl":"fstps"; +} + +char * +fload(int d) +{ + return d?"fldl":"flds"; +} + + +void code_dassign_gvar(int e2,int d) +{ + printf("\t%s %s\n",fstore(d),(char *)caddr(e2)) ; +} + +void code_dassign_lvar(int e2,int d) +{ + printf("\t%s %d(%%ebp)\n",fstore(d),e2); +} + +void code_dassign(int e2,int d) +{ + printf("\t%s (%s)\n",fstore(d),register_name(e2,0)); +} + +static double d0 = 1.0; + +int +code_d1(double d) +{ + int *i = (int *)&d0; int *j = (int *)&d; + return (i[1] == 0x3ff00000)?j[0]:j[1]; +} + +int +code_d2(double d) +{ + int *i = (int *)&d0; int *j = (int *)&d; + return (i[1] == 0x3ff00000)?j[1]:j[0]; +} + +void code_dconst(int e2) +{ + int lb; + double d = dcadr(e2); + + if (d==0.0) { + printf("\tfldz\n"); return; + } + if (d==1.0) { + printf("\tfld1\n"); return; + } + printf(" \t.section\t.rodata\n\t.align 8\n"); + lb=fwdlabel(); + printf("_%d:\n",lb); + printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d)); + if (output_mode==TEXT_EMIT_MODE) { + printf(".text\n"); + } else { + text_mode(); + } + printf("\tfldl _%d\n",lb); +} + +void code_dneg() +{ + printf("\tfchs\n"); +} + +void code_d2i() +{ + /* fuck you! */ + printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2); + printf("\tfnstcw (%%esp)\n"); + printf("\tmovl (%%esp), %s\n",register_name(creg)); + printf("\tmovb $12, 1(%%esp)\n"); + printf("\tfldcw (%%esp)\n"); + printf("\tmovl %s, (%%ebp)\n",register_name(creg)); + printf("\tfistpl %d(%%esp)\n",size_of_int); + printf("\tfldcw (%%esp)\n"); + printf("\tpopl %s\n",register_name(creg)); + printf("\tpopl %s\n",register_name(creg)); +} + +void code_i2d() +{ + printf("\tpushl %s\n",register_name(creg)); + printf("\tfildl (%%esp)\n"); + printf("\tlea %d(%%esp),%%esp\n",size_of_int); +} + +void code_d2u() +{ + /* fuck you! */ + printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3); + printf("\tfnstcw (%%esp)\n"); + printf("\tmovl (%%esp), %s\n",register_name(creg)); + printf("\tmovb $12, 1(%%esp)\n"); + printf("\tfldcw (%%esp)\n"); + printf("\tmovl %s, (%%ebp)\n",register_name(creg)); + printf("\tfistpll %d(%%esp)\n",size_of_int); + printf("\tfldcw (%%esp)\n"); + printf("\tmovl %d(%%esp),%s\n",size_of_int,register_name(creg)); + printf("\tlea %d(%%esp),%%esp\n",size_of_int*3); +} + +void code_u2d() +{ + printf("\tpushl %s\n",register_name(creg)); + printf("\tpushl %s\n",register_name(creg)); + printf("\tmovl $0, %d(%%esp)\n",size_of_int); + printf("\tfildll (%%esp)\n"); + printf("\tlea %d(%%esp),%%esp\n",size_of_int*2); +} + +void code_drgvar(int e2,int d) +{ + printf("\t%s %s\n",fload(d),(char *)caddr(e2)) ; +} + + +void code_drlvar(int e2,int d) +{ + printf("\t%s %d(%%ebp)\n",fload(d),e2); +} + +void code_cmp_drgvar(int e2) +{ + printf("\tfcomp %s\n",(char *)caddr(e2)) ; +} + +void code_cmp_drlvar(int e2) +{ + printf("\tfcomp %d(%%ebp)\n",e2); +} + +void dtosop(int op,int e1) +{ + switch(op) { + case DADD: printf("\tfaddp %%st,%%st(1)\n"); break; + case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break; + case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break; + case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break; + case DCOMP: + /* printf("\tfxch\t%%st(1)\n"); */ + printf("\tfucompp\n"); + printf("\tfnstsw\t%%ax\n"); + break; + } +} + +void +code_dassop(int op,int d) { + /* we have lvalue in creg, applied floating value is in %st(0) */ + printf("\t%s (%s)\n",fload(d),register_name(creg)); + dtosop(op,0); + printf("\t%s (%s)\n",fstore(d),register_name(creg)); +} + +void +code_dpreinc(int e1,int e2,int d) { + g_expr(e2); + printf("\t%s (%s)\n",fload(d),register_name(creg)); + printf("\tfld1\n"); + if (caddr(e1)>0) + printf("\tfaddp %%st,%%st(1)\n"); + else + printf("\tfsubrp %%st,%%st(1)\n"); + printf("\t%s (%s)\n",fstore(d),register_name(creg)); +} + +void +code_dpostinc(int e1,int e2,int d) { + g_expr(e2); + printf("\t%s (%s)\n",fload(d),register_name(creg)); + if (use) + printf("\t%s (%s)\n",fload(d),register_name(creg)); + printf("\tfld1\n"); + if (caddr(e1)>0) + printf("\tfaddp %%st,%%st(1)\n"); + else + printf("\tfsubrp %%st,%%st(1)\n"); + printf("\t%s (%s)\n",(use?fstore_u(d):fstore(d)),register_name(creg)); +} + +void +drexpr(int e1, int e2,int l1, int op) +{ + g_expr(list3(DCOMP,e1,e2)); + switch(op) { + case DOP+GE: + printf("\ttestb\t$5,%%ah\n"); + printf("\tjne\t_%d\n",l1); + break; + case DOP+GT: + printf("\ttestb\t$69,%%ah\n"); + printf("\tjne\t_%d\n",l1); + break; + case DOP+EQ: + printf("\tandb\t$69,%%ah\n"); + printf("\txorb\t$64,%%ah\n"); + printf("\tjne\t_%d\n",l1); + break; + case DOP+NEQ: + printf("\tandb\t$69,%%ah\n"); + printf("\txorb\t$64,%%ah\n"); + printf("\tje\t_%d\n",l1); + break; + } +} + +int dpop_register() +{ + return 1; +} + +int emit_dpop(int e1) +{ + return 1; +} + +void emit_dpop_free(int e1) +{ +} + +void emit_dpush() +{ +} + +/* end */ + diff -r 5c8553d7f984 -r 917947ffeb7c mc-code.h --- a/mc-code.h Wed Mar 05 23:07:00 2003 +0900 +++ b/mc-code.h Thu Mar 06 23:47:42 2003 +0900 @@ -68,7 +68,7 @@ extern void tosop(int op,int oreg); extern void code_opening(char *filename); extern void code_closing(); -extern void rexpr(int e1, int l1, char *s); +extern void rexpr(int e1, int l1, char *s,int t); extern void drexpr(int e1, int e2,int l1, int op); extern void jcond(int l, char cond); extern void jmp(int l); @@ -101,3 +101,13 @@ extern void code_dpreinc(int e1,int e2,int d); extern void code_dpostinc(int e1,int e2,int d); extern void code_dassop(int op,int d); + +extern void code_arg_register(int); + +extern int get_register(void); +extern void free_register(int i) ; +extern int virtual(int real); +extern int pop_register(void); +extern void emit_pop_free(int xreg); + +/* */ diff -r 5c8553d7f984 -r 917947ffeb7c mc-codegen.c --- a/mc-codegen.c Wed Mar 05 23:07:00 2003 +0900 +++ b/mc-codegen.c Thu Mar 06 23:47:42 2003 +0900 @@ -54,172 +54,6 @@ void assop(int e1); void g_expr0(int e1); -int -get_register(void) -{ /* 使われていないレジスタを調べる */ - int i; - for(i=0;isc==REGISTER) { - if ((n->dsp = get_register_var()) <0) { - error(-1); return; - } - use_register_var(n->dsp); /* it has now value in it */ - } - arg_register0(cadr(args)); - } -} - -void -arg_register(NMTBL *fnptr) -{ - arg_register0(fnptr->dsp); -} - -void -register_usage(char *s) -{ - int i; - if (chk) return; - printf("# %d: %s:",lineno,s); - printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0)); - for(i=0;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;idsp); +} + /* goto arguments list */ /* target list4(list2(tag,disp),cdr,ty,source_expr) */ /* source expr=listn(tag,...) */ diff -r 5c8553d7f984 -r 917947ffeb7c mc-codegen.h --- a/mc-codegen.h Wed Mar 05 23:07:00 2003 +0900 +++ b/mc-codegen.h Thu Mar 06 23:47:42 2003 +0900 @@ -31,17 +31,9 @@ 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(); @@ -69,10 +61,8 @@ extern void opening(char *filename); extern void closing(); extern void ret(void); -extern void use_register_var(int); -extern void arg_register(NMTBL *); extern void creg_destroy(); -extern void regvar_creg(int); +extern void arg_register(NMTBL *fnptr); /* floating point */ diff -r 5c8553d7f984 -r 917947ffeb7c mc.h --- a/mc.h Wed Mar 05 23:07:00 2003 +0900 +++ b/mc.h Thu Mar 06 23:47:42 2003 +0900 @@ -108,57 +108,58 @@ #define UMOD 29 #define ADD 30 #define SUB 31 -#define RSHIFT 32 -#define URSHIFT 33 -#define LSHIFT 34 -#define ULSHIFT 35 -#define GT 36 -#define UGT 37 -#define GE 38 -#define UGE 39 -#define LT 40 -#define ULT 41 -#define LE 42 -#define ULE 43 -#define EQ 44 -#define NEQ 45 -#define BAND 46 -#define EOR 47 -#define BOR 48 -#define LAND 49 -#define LOR 50 -#define COND 51 -#define ASS 52 -#define CASS 53 -#define ASSOP 54 -#define CASSOP 55 -#define COMMA 56 -#define LPAR 57 -#define RPAR 58 -#define LBRA 59 -#define RBRA 60 -#define LC 61 -#define RC 62 -#define COLON 63 -#define SM 64 -#define PERIOD 65 -#define ARROW 66 -#define CNAME 67 -#define SASS 68 -#define RSTRUCT 69 +#define CMP 32 +#define RSHIFT 33 +#define URSHIFT 34 +#define LSHIFT 35 +#define ULSHIFT 36 +#define GT 37 +#define UGT 38 +#define GE 39 +#define UGE 40 +#define LT 41 +#define ULT 42 +#define LE 43 +#define ULE 44 +#define EQ 45 +#define NEQ 46 +#define BAND 47 +#define EOR 48 +#define BOR 49 +#define LAND 50 +#define LOR 51 +#define COND 52 +#define ASS 53 +#define CASS 54 +#define ASSOP 55 +#define CASSOP 56 +#define COMMA 57 +#define LPAR 58 +#define RPAR 59 +#define LBRA 60 +#define RBRA 61 +#define LC 62 +#define RC 63 +#define COLON 64 +#define SM 65 +#define PERIOD 66 +#define ARROW 67 +#define CNAME 68 +#define SASS 69 +#define RSTRUCT 70 -#define FASSOP 70 -#define DASSOP 71 -#define DCOMP 72 -#define DMINUS 73 +#define FASSOP 71 +#define DASSOP (DOP+ASSOP) +#define DCMP (DOP+CMP) +#define DMINUS (DOP+MINUS) #define DMUL (DOP+MUL) #define DDIV (DOP+DIV) #define DADD (DOP+ADD) #define DSUB (DOP+SUB) -#define LMUL 78 -#define LDIV 79 -#define LADD 80 -#define LSUB 81 +#define LMUL 72 +#define LDIV 73 +#define LADD 74 +#define LSUB 75 #define FRGVAR 82 #define FRLVAR 83 diff -r 5c8553d7f984 -r 917947ffeb7c test/basic.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/basic.c Thu Mar 06 23:47:42 2003 +0900 @@ -0,0 +1,47 @@ + +int i; +print(double d) +{ + float f; + int *dd; + + f = d; + + dd = (int*) &d; + printf("d %g\n",d); + printf("dx %08x %08x\n",*(dd),*(dd+1)); + + dd = (int*) &f; + printf("f %g\n",f); + printf("dx %08x \n",*(dd)); +} + +void +tmp () { + char c; + int i; + c=-1; + i=c; + printf("%d %d %d\n",!i,~i,-i); + printf("%d\n",i); +} + +void +tmp1 () { + + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d \n", +0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49 +); + printf("%g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g \n", +0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0,19.0,20.0,21.0,22.0,23.0,24.0,25.0,26.0,27.0,28.0,29.0,30.0,31.0,32.0,33.0,34.0,35.0,36.0,37.0,38.0,39.0,40.0,41.0,42.0,43.0,44.0,45.0,46.0,47.0,48.0,49.0 +); + +} + + +main() { + print(1.0); + print(0.1234); + print(1.234e10); + print(1.234e-10); +}