Mercurial > hg > CbC > old > device
changeset 51:c2ef3a2fbe88
*** empty log message ***
author | kono |
---|---|
date | Sun, 16 Feb 2003 22:21:23 +0900 |
parents | 1ec39b34ed98 |
children | ddaa1aa5b49b |
files | .gdbinit Idea mc-mips.c mc-nop-386.c |
diffstat | 4 files changed, 1697 insertions(+), 42 deletions(-) [+] |
line wrap: on
line diff
--- a/.gdbinit Sun Feb 16 06:34:12 2003 +0900 +++ b/.gdbinit Sun Feb 16 22:21:23 2003 +0900 @@ -9,6 +9,7 @@ end define ni nexti +regs x/1i $eip end b error
--- a/Idea Sun Feb 16 06:34:12 2003 +0900 +++ b/Idea Sun Feb 16 22:21:23 2003 +0900 @@ -1156,6 +1156,44 @@ 関数呼び出しの最初にやってやればいいか。それでできるかな? +Sun Feb 20 23:59:16 JST 2000 + +MIPS のcall frame + + $sp = $fp + local variables + saved register (including $31 = return address) + +mask は使用したレジスタのbit pattern + -4 は何? + + 18 .mask 0xc0000000,-4 + 19 .fmask 0x00000000,0 + 20 0000 D0FFBD27 subu $sp,$sp,48 + 21 0004 2C00BFAF sw $31,44($sp) + 22 0008 2800BEAF sw $fp,40($sp) + 23 000c 0000000C move $fp,$sp + 24 0010 21F0A003 jal __main + 25 0014 03000224 li $2,0x00000003 # 3 + 26 0018 000082AF sw $2,a + 27 001c 04000224 li $2,0x00000004 # 4 + 28 0020 00C082AF sw $2,b + 29 0024 05000224 li $2,0x00000005 # 5 + 30 0028 000082A3 sb $2,c + 31 002c 06000224 li $2,0x00000006 # 6 + 32 0030 08C082A3 sb $2,d + 33 $L1: + 34 0034 21E8C003 move $sp,$fp # sp not trusted + here + 35 0038 2C00BF8F lw $31,44($sp) + 36 003c 2800BE8F lw $fp,40($sp) + 37 0040 0800E003 addu $sp,$sp,48 + 38 0044 3000BD27 j $31 + 39 .end main + +これと同じようにするならば、regiterの使用数を最初に調べる必要が +あるのだけど、one path compiler である micro-C では、それは +できない。したがって、enter は後ろでする方が良い。 Mon Jan 20 18:25:27 JST 2003 3年間さわってないのかよ。何やってんだ? @@ -1528,3 +1566,8 @@ struct_push のregisterの扱いが複雑すぎ。なんか、もっと 簡単にならないの? + +Sun Feb 16 07:58:23 JST 2003 + +代入しなくて良いからと言って、ソース +のリストから除いては、上書きを防げない。
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mc-mips.c Sun Feb 16 22:21:23 2003 +0900 @@ -0,0 +1,1553 @@ +/* Micro-C Code Generatation Part for Mips */ + +#define EXTERN extern +#include "mc.h" + +#define REGISTERS6 0 + +void code_init(void); +void free_register(int i); +void emit_init(void); +void emit_push(void); +void gexpr(int e1); +void g_expr(int e1); +void bexpr(int e1, char cond, int l1); +void b_expr(int e1, char cond, int l1); +void string(int e1); +void function(int e1); +void machinop(int e1); +void rindirect(int e1); +void assign(int e1); +void sassign(int e1); +void assop(int e1); +void tosop(int op); +void shift(char *op, int reg) ; +void ld_indexx(int byte, int n, char *xrn); +void st_indexx(int byte, int n, char *xrn); +void indexy(char *op, char *gvar); +void cmpdimm(int e, int csreg); +void global_table(void) ; +void local_table(void) ; +void opening(char *filename); +void closing(void); +void gen_gdecl(char *n, int gpc) ; +void jmp_label(int l); +void jmp_eq_label(int l); +void rexpr(int e1, int l1, char *s); +void jcond(int l, char cond); +void jmp(int l); +void def_label(int cslabel, int dlabel) ; +void gen_comment(char *s); +void gen_source(char *s); +void code_enter(char *name) ; +void code_leave(char *name) ; +void enter(char *name, int disp) ; +void enter_no(char *name,int disp); +void enter1(int disp) ; +void ret(void); +void emit_data(int e, int t, NMTBL *n); +void text_mode(void); +void data_mode(char *name); +int get_register_var(void); +void jump(int e1, int env); +int lvar(int l); + +int cadr(int e); +int car(int e); +int caddr(int e); +int fwdlabel(void); +void fwddef(int l); +int cadddr(int e); +int backdef(void); +int error(int n); +int size(int t); +int list3(int e1, int e2, int e3); +extern int scalar(int); +extern int reverse0(int); + +#define TEXT_EMIT_MODE 0 +#define DATA_EMIT_MODE 1 +#define RODATA_EMIT_MODE 2 + +static output_mode = TEXT_EMIT_MODE; +static data_alignment = 0; + +/* + local1 <----24 local variable + -20 <- disp_offset + saved register + .mask 0...0,-8 + .fmask 0 + $fp = $sp 0 + $ip 4 <- arg_offset + arg1 8 + */ +int arg_offset = 8; +int code_arg_offset = -4; +int disp_offset = -12; +int func_disp_offset = -12; +int code_disp_offset = -4; +int size_of_int = 4; +int endian = 0; +int MAX_REGISTER=32; /* Mipsのレジスタを32つまで使う*/ +int REAL_MAX_REGISTER=32; /* Mipsのレジスタが32つということ*/ +int MAX_REGISTGER_VAR=20; + +int save_reg = 0; /*saveされたレジスタの回数*/ +int save_reg1 = 0; + +static int creg; /* current register */ +static char *crn; /* current register name */ +static int lreg; /* operand register */ +static char *lrn; /* operand register name */ +static int dreg; /* temporary register */ +static char *drn; /* temporary register name */ +static int xreg; /* pointer register */ +static int reg_sp; /* REGister Stack-Pointer */ + + +#define REG_00 0 +#define REG_01 1 +#define REG_02 2 +#define REG_03 3 +#define REG_04 4 +#define REG_05 5 +#define REG_06 6 +#define REG_07 7 +#define REG_08 8 +#define REG_09 9 +#define REG_10 10 +#define REG_11 11 +#define REG_12 12 +#define REG_13 13 +#define REG_14 14 +#define REG_15 15 +#define REG_16 16 +#define REG_17 17 +#define REG_18 18 +#define REG_19 19 +#define REG_20 20 +#define REG_21 21 +#define REG_22 22 +#define REG_23 23 +#define REG_24 24 +#define REG_25 25 +#define REG_26 26 +#define REG_27 27 +#define REG_28 28 +#define REG_29 29 +#define REG_30 30 +#define REG_31 31 + +static char *reg_name[32]; + +/* + creg currrent virtual register + lreg operand virtual register + dreg spare virtual register + + rname[creg] currrent real register + rname[lreg] operand real register + rname[dreg] spare real register + + regs[] virtual register usage + + reg_name[rname[creg]] + */ + +#define MAX_MAX 40 +static int rname[MAX_MAX]; +static int regs[MAX_MAX]; /* 使われているレジスタを示すフラグ */ +static int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */ + +void +code_init(void) +{ + int i; + + if (REGISTERS6) { + arg_offset = 8; + func_disp_offset = -20; + disp_offset = -20; + size_of_int = 4; + endian = 0; + MAX_REGISTER=32; + } else { + arg_offset = 8; + func_disp_offset = -12; + disp_offset = -12; + size_of_int = 4; + endian = 0; + MAX_REGISTER=32; + } + MAX_REGISTER_VAR=2; + + reg_name[REG_00] = "$0"; + reg_name[REG_01] = "$1"; + reg_name[REG_02] = "$2"; + reg_name[REG_03] = "$3"; + reg_name[REG_04] = "$4"; + reg_name[REG_05] = "$5"; + reg_name[REG_06] = "$6"; + reg_name[REG_07] = "$7"; + reg_name[REG_08] = "$8"; + reg_name[REG_09] = "$9"; + reg_name[REG_10] = "$10"; + reg_name[REG_11] = "$11"; + reg_name[REG_12] = "$12"; + reg_name[REG_13] = "$13"; + reg_name[REG_14] = "$14"; + reg_name[REG_15] = "$15"; + reg_name[REG_16] = "$16"; + reg_name[REG_17] = "$17"; + reg_name[REG_18] = "$18"; + reg_name[REG_19] = "$19"; + reg_name[REG_20] = "$20"; + reg_name[REG_21] = "$21"; + reg_name[REG_22] = "$22"; + reg_name[REG_23] = "$23"; + reg_name[REG_24] = "$24"; + reg_name[REG_25] = "$25"; + reg_name[REG_26] = "$26"; + reg_name[REG_27] = "$27"; + reg_name[REG_28] = "$28"; + reg_name[REG_29] = "$29"; + reg_name[REG_30] = "$30"; + reg_name[REG_31] = "$31"; + +} + +char * +register_name(int i) +{ + return reg_name[rname[i]]; +} + +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) { /* いらなくなったレジスタを開放 */ + regs[i]=0; +} + +int +register_full(void) +{ + int i; + for(i=0;i<MAX_REGISTER;i++) { + if (! regs[i]) { + return 0; + } + } + return 1; +} + +void +gexpr_init(void) +{ + int i; + while(reg_sp > 0) { + free_register(reg_stack[--reg_sp]); + } + text_mode(); +} + +void +emit_init(void) +{ + int i; + for(i=0;i<REAL_MAX_REGISTER;i++) regs[i]=0; + for(i=0;i<REAL_MAX_REGISTER;i++) rname[i]=i; + regs[REG_00] = 1; /* reserved */ + regs[REG_01] = 1; /* reserved */ + regs[REG_02] = 1; /* $v0 */ + regs[REG_03] = 1; /* $v1 */ + regs[REG_28] = 1; /* reserved */ + regs[REG_29] = 1; /* reserved */ + regs[REG_30] = 1; /* reserved */ + regs[REG_31] = 1; /* reserved */ + creg = get_register(); + crn = reg_name[rname[creg]]; + dreg = get_register(); + drn = reg_name[rname[dreg]]; + reg_sp = 0; + text_mode(); +} + +void +set_crn(int i) +{ + creg = i; + crn = reg_name[rname[creg]]; +} + +void +set_drn(int i) +{ + dreg = i; + drn = reg_name[rname[dreg]]; +} + +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; + } + } + if (real_v == -1) + error(-1); + return real_v; +} + +void +use_register(int virt, int real, int move) +{ + int real_v; + char *move_op,*a,*b; + if (rname[virt]==real) + return; + real_v = virtual(real); + if (move || regs[real_v]) { + if(regs[real_v]) { + a=reg_name[real]; + b=reg_name[rname[virt]]; + printf("\txor \t%s,%s,%s\n",a,a,b); + printf("\txor \t%s,%s,%s\n",b,a,b); + printf("\txor \t%s,%s,%s\n",a,a,b); + } else { + printf("\tmove \t%s,%s\n",reg_name[real],reg_name[rname[virt]]); + } + } + rname[real_v] = rname[virt]; + rname[virt] = real; + crn = reg_name[rname[creg]]; + drn = reg_name[rname[dreg]]; + lrn = reg_name[rname[lreg]]; + + save_reg++; +} + +int +pop_register(void) +{ /* レジスタから値を取り出す */ + int i,j; + + j = creg; + i = reg_stack[--reg_sp]; + + if(i<0) { + return i; + } else { + free_register(i); + lreg = i; + lrn = reg_name[rname[lreg]]; + regs[i]=0; + return lreg; + } +} + +int +stack_used(void) { + return reg_stack[--reg_sp]<0; +} + +void +emit_push(void) +{ + int new_reg; + new_reg = get_register(); + if(new_reg<0) { /* もうレジスタがない */ + reg_stack[reg_sp++] = -1; + printf("\tsubu $sp,$sp,%d\n",size_of_int); + printf("\tsw \t%s,0($sp)\n",crn); + } else { + reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */ + set_crn(new_reg); + } +} + +char * +emit_pop(int type) +{ + char *xrn; + if (pop_register()==-1) { + printf("\tlw %s,0($sp)\n",drn); + printf("\taddu $sp,$sp,%d\n",size_of_int); + xrn = drn; + xreg = dreg; + } else { + xrn = lrn; + xreg = lreg; + } + return xrn; +} + +int +get_register_var(void) +{ + int i; + for(i=REG_05;i<REG_31;i++) { + if (! regs[i]) { /* 使われていないなら */ + regs[i]=1; /* そのレジスタを使うことを宣言し */ + return i; /* その場所を表す番号を返す */ + } + } + return -1; +} + +void +gexpr(int e1) +{ + gexpr_init(); + g_expr(e1); + csvalue = rname[creg]; /* for siwtch value */ +} + +void +g_expr(int e1) +{ + int e2,e3,e4; + char *xrn; + NMTBL *n; + + if (chk) return; + e2 = cadr(e1); + switch (car(e1)){ + case GVAR: + printf("\tla\t%s,%s\n",crn,caddr(e1)); + return; + case RGVAR: + printf("\tlw\t%s,%s\n",crn,caddr(e1)); + return; + case CRGVAR: + printf("\tlb\t%s,%s\n",crn,caddr(e1)); + return; + case LVAR: + printf("\taddu\t%s,$fp,%d\n",crn,lvar(e2)); + return; + case REGISTER: + /* this is of course redundant... */ + printf("\tmove\t%s,%s\n",crn,register_name(e2)); + return; + case RLVAR: + printf("\tlw\t%s,%d($fp)\n",crn,lvar(e2)); + return; + case CRLVAR: + printf("\tlb\t%s,%d($fp)\n",crn,lvar(e2)); + return; + case FNAME: + printf("\tla\t%s,%s\n",crn,((NMTBL *)e2)->nm); + return; + case CONST: /* 代入する値が0でも特別な処理はしない */ + printf("\tli\t%s,%d\n",crn,e2); + return; + case STRING: + string(e1); + return; + case FUNCTION: + function(e1); + 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: /* レジスタに対し、引き算を実行すれば実現可能 */ + g_expr(e2); + printf("\tsubu\t%s,$0,%s\n",crn,crn); + return; + case BNOT: /* ~ */ + g_expr(e2); + /* use_data_reg(creg,1); */ + printf("\tnor\t%s,$0,%s\n",crn,crn); + return; + case LNOT: /* ! */ + g_expr(e2); + /*use_data_reg(creg,1);*/ + printf("\txori\t%s,%s,0x0000\n",drn,crn); + printf("\tsltu\t%s,%s,1\n",crn,drn); + return; + case PREINC:/* ++q */ + if (car(e2)==REGISTER) { + printf("\taddu \t%s,%s,%d\n",register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); + return; + } + g_expr(e2); + printf("\taddu \t%s,%s,%d\n",crn,crn,caddr(e1)); + return; + case POSTINC:/* p++ */ + if (car(e2)==REGISTER) { + printf("\taddu \t%s,%s,%d\n",register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); + return; + } + g_expr(e2); + emit_push(); + /* in case of register full we should copy crn to drn */ + xrn = emit_pop(0); + printf("\taddu \t%s,%s,%d\n",crn,xrn,caddr(e1)); + return; + case CPOSTINC: + /* char *p; *p++ */ + if (car(e2)==REGISTER) { + printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2))); + printf("\taddu\t%s,%s,%d\n",register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); + return; + } + g_expr(e2); + emit_push(); /* in case of register full we should copy crn to drn */ + xrn = emit_pop(0); + printf("\tmovsbl (%s),%s\n",xrn,crn); + printf("\tincl (%s)\n",xrn); + return; + case CPREINC: /* char *p; *++p */ + if (car(e2)==REGISTER) { + printf("\taddu\t%s,%s,%d\n",register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1)); + printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2))); + return; + } + g_expr(e2); + printf("\tincl (%s)\n",crn); + printf("\tmovsbl (%s),%s\n",crn,crn); + return; + case CPOSTDEC:/* char *p; *p-- */ + if (car(e2)==REGISTER) { + printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2))); + printf("\tsubu\t%s,%s,1\n",register_name(cadr(e2)),register_name(cadr(e2))); + return; + } + g_expr(e2); + printf("\tmovsbl (%s),%s\n",crn,crn); + printf("\tdecl (%s)\n",crn); + return; + case CPREDEC:/* char *p; *--p */ + if (car(e2)==REGISTER) { + printf("\tdecl %s\n",register_name(cadr(e2))); + printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2))); + return; + } + g_expr(e2); + emit_push(); + xrn = emit_pop(0); + printf("\tdecl (%s)\n",xrn); + printf("\tmovsbl (%s),%s\n",xrn,crn); + 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); + g_expr(caddr(e1)); + e4 = rname[creg]; + jmp(e3=fwdlabel()); + fwddef(e2); + g_expr(cadddr(e1)); + use_register(creg,e4,1); + fwddef(e3); + return; + case SASS: + sassign(e1); + return; + case ASS: case CASS: + assign(e1); + return; + case ASSOP: case CASSOP: + assop(e1); + return; + case COMMA: + g_expr(e2); + g_expr(caddr(e1)); + return; + case RETURN: + n = (NMTBL *)e2; + if (retcont==0) + retcont=fwdlabel(); + printf("\tla\t%s,$L%d\n",crn,retcont); + return; + case ENVIRONMENT: + printf("\tmove\t%s,$fp\n",crn); + return; + default: + b_expr(e1,1,e2=fwdlabel()); /* including > < ... */ + /*printf("\txor \t%s,%s\n",crn,crn);*/ + jmp(e3=fwdlabel()); + fwddef(e2); + printf("\tli \t%s,%d\n",crn,lvar(e2)); + fwddef(e3); + } +} + +void +bexpr(int e1, char cond, int l1) +{ + gexpr_init(); + b_expr(e1,cond,l1); +} + +void +b_expr(int e1, char cond, int l1) +{ + int e2,l2; + if (chk) return; + e2=cadr(e1); + switch(car(e1)) { + case LNOT: + b_expr(e2,!cond,l1); + return; + case GT: + /*rexpr(e1,l1,cond?"bg":"ble");*/ + return; + case UGT: + /*rexpr(e1,l1,cond?"ba":"bbe");*/ + return; + case GE: + /*rexpr(e1,l1,cond?"bge":"bl");*/ + return; + case UGE: + /*rexpr(e1,l1,cond?"bae":"bb");*/ + return; + case LT: + /*rexpr(e1,l1,cond?"bl":"bge");*/ + return; + case ULT: + /*rexpr(e1,l1,cond?"bb":"bae");*/ + return; + case LE: + /*rexpr(e1,l1,cond?"ble":"bg");*/ + return; + case ULE: + /*rexpr(e1,l1,cond?"bbe":"ba");*/ + return; + case EQ: + rexpr(e1,l1,cond?"beq":"bne"); + return; + case NEQ: + rexpr(e1,l1,cond?"bne":"beq"); + return; + case LAND: + b_expr(e2,0,cond?(l2=fwdlabel()):l1); + b_expr(caddr(e1),cond,l1); + if(cond) fwddef(l2); + return; + case LOR: + b_expr(e2,1,cond?l1:(l2=fwdlabel())); + b_expr(caddr(e1),cond,l1); + if(!cond) fwddef(l2); + return; + case CRGVAR: + /*printf("\tcmpb $0,%s\n",caddr(e1));*/ + jcond(l1,cond); + return; + case CRLVAR: + /*printf("\tcmpb $0,%d($fp)\n",lvar(e2));*/ + jcond(l1,cond); + return; + case RGVAR: + /*printf("\tcmpl $0,%s\n",caddr(e1));*/ + jcond(l1,cond); + return; + case RLVAR: + /*printf("\tlw \t%s,%d($fp)\n",crn,lvar(e2));*/ + jcond(l1,cond); + return; + case REGISTER: + /*printf("\tcmpl $0,%s\n",register_name(e2));*/ + jcond(l1,cond); + return; + case CONST: + if((cond&&e2)||(!cond&&!e2)) jmp(l1); + return; + default: + g_expr(e1); + /*printf("\tcmpl $0,%s\n",crn);*/ + jcond(l1,cond); + return; + } +} + +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("%c\n",34); +} + +void +string(int e1) +{ + char *s; + int i,lb; + + if (0) { + s=(char *)cadr(e1); + printf("\t.rdata\n"); + printf("\t.align\t2\n"); + lb=fwdlabel(); + printf("\tj\t$L%d\n",lb); + i=backdef(); + ascii(s); + printf("\t.align 2\n"); + fwddef(lb); + printf("\tla\t%s,$L%d\n",crn,i); + } else { + s=(char *)cadr(e1); + printf("\t.rdata\n"); + printf("\t.align\t2\n"); + lb=fwdlabel(); + printf("$L%d:\n",lb); + ascii(s); + if (output_mode==TEXT_EMIT_MODE) { + printf("\t.text\n"); + } else { + text_mode(); + } + printf("\tla\t%s,$L%d\n",crn,lb); + } +} + +void +function(int e1) +{ + int e2,e3,e4,e5,nargs; + NMTBL *n; + + e2 = cadr(e1); + nargs = 0; + for (e3 = caddr(e1); e3; e3 = cadr(e3)) { + n=(NMTBL *)(e5=(cadr(e4 = car(e3)))); + switch(car(e4)){ + case FNAME: + printf("\tlw\t%s,0(%s)\n",crn,n->nm); + break; + case ADDRESS: + g_expr(e5); + break; + default:g_expr(e4); + } + ++nargs; + } + if (car(e2) == FNAME) { + n=(NMTBL *)cadr(e2); + use_register(creg,REG_04,0); + printf("\tjal\t%s\n",n->nm); + } else { + g_expr(e2); + use_register(creg,REG_04,0); + printf("\tjal\t*%s\n",crn); + } + /*if (nargs) printf("\taddl $%d,%%esp\n",size_of_int*nargs);*/ +} + +int +arg_size(int e3,int *nargs0) +{ + int i,nargs,offset_list,e,t; + + offset_list = 0; + /* we should use prototypes's type */ + for (i = nargs = 0; e3;e3 =cadr(e3)) { + e = car(e3); t = caddr(e3); + if (i < MAX_REGISTER_VAR && scalar(t)) { + offset_list = list3(-(REG_05+i++),offset_list,e); + } else { + offset_list = + list3(nargs,offset_list,e); + nargs += (car(e3)==CHAR?size_of_int:size(t)); + } + } + *nargs0 = -nargs; + return offset_list; +} + +void +jump(int e1, int env) +{ + int i,args,e2,e3,e4,e5,nargs,nargs0,regs; + NMTBL *n,*code0; + int new_disp,scode,disp1; + char *xrn; + + /* We need three passes. Compute Stack size, Compute Arg, Copy it. */ + /* count number of args */ + args = caddr(e1); + args = reverse0(args); + nargs = arg_size(args,&new_disp); /* compute in normal order */ + disp1 = (fnptr->sc==CODE)?0:-size_of_int; + if (new_disp+disp1 < disp) { /* have to extend stack */ + if (fnptr->sc==CODE) + printf("\tlw\t$sp,%d($fp)\n",new_disp-size_of_int); + else + printf("\tlw\t$sp,%d($fp)\n",new_disp+disp_offset); + } + /* compute jump address */ + e2 = cadr(e1); + if (car(e2) == FNAME) { + code0=(NMTBL *)cadr(e2); + if (code0->sc!=CODE) { + error(STERR); return; + } + } else { /* indirect */ + g_expr(e2); + emit_push(); + } + /* compute arguments in reverse order */ + regs = 0; + i=MAX_REGISTER_VAR; + for (e3=nargs; e3;e3 =cadr(e3)) { + n=(NMTBL *)(e5=(cadr(e4 = caddr(e3)))); + switch(car(e4)) { + case FNAME: + printf("\tlw\t%s,0(%s)\n",crn,n->nm); + emit_push(); + break; + case ADDRESS: + g_expr(e5); + emit_push(); + break; + case RLVAR: + case CRLVAR: + if (env==0 && fnptr->sc==CODE) { + if (e5>=0 && e5==car(e3)) { + /* The same positioned local variable. No need to copy */ + reg_stack[reg_sp++] = -2; + } + break; + } + g_expr(e4); + emit_push(); + break; + case REGISTER: + if (i>0 && rname[e5]==REG_05+ --i) { + /* The same register variable. No need to copy */ + reg_stack[reg_sp++] = e5; + break; + } + default: + g_expr(e4); + emit_push(); + } + regs++; + } + if (env) { + /* change the frame pointer */ + g_expr(env); + printf("\tmove\t%s,$fp\n",crn); + } else if (fnptr->sc==FUNCTION) { + printf("\tlw\t$fp,%d($fp)\n",disp_offset); + } + /* force lvar offset mode to CODE */ + scode = fnptr->sc; fnptr->sc = CODE; + /* copy arguments to destination environment if necessary */ + nargs = reverse0(nargs); /* pop in normal order */ + i=0; + for (e3=nargs; e3;e3 =cadr(e3)) { + if ((e4=car(e3))<0) { + /* register case */ + if (reg_stack[--reg_sp]>=REG_05) { + /* the same registger */ + } else { + if(reg_stack[reg_sp]<0) { + /*printf("\tpopl %s\n",reg_name[rname[REG_05+i]]);*/ /* e4? */ + } else { + printf("\tmove\t%s,%s\n", + reg_name[rname[REG_05+i]], + reg_name[rname[reg_stack[reg_sp]]]); /* e4? */ + free_register(reg_stack[reg_sp]); + } + i++; + } + } else { + /* local variable case */ + if (reg_stack[reg_sp-1]== -2) { + /* same positioned variable */ + reg_sp--; + } else { + xrn=emit_pop(0); + printf("\tlw\t%s,%d($fp)\n",xrn, lvar(e4)); + } + } + } + if (car(e2) != FNAME) { + xrn=emit_pop(0); + } + if (!env && new_disp+disp1>disp) { + /* shrink stack if necessary */ + printf("\tlw\t$sp,%d($fp)\n",new_disp-size_of_int); + } + if (car(e2) == FNAME) { + printf("\tj\t%s\n",code0->nm); + } else { + printf("\tj\t*%s\n",xrn); + } + fnptr->sc = scode; +} + + +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)); + return; +} + + +void +rindirect(int e1) /* *(p +5 ) */ + +{ + char *op; + int e2,e3,byte; + + op = ((byte = (car(e1) == CRINDIRECT)) ? "lb" : "lw"); + e3 = cadr(e2 = cadr(e1)); + g_expr(e2); + printf("\t%s \t%s,%d(%s)\n",op,crn,lvar(e3),crn); +} + +void +sassign(int e1) +{ + int e2,e3,e4,sz; + char *xrn; + + e2 = cadr(e1); + e3 = cadr(e2); + e4 = caddr(e1); + sz = size(cadr(e2)); /* cld rep movsb */ + g_expr(e4); + emit_push(); + g_expr(e2); + xrn = emit_pop(0); + return; +} + +void +assign(int e1) +{ + char *op; + int e2,e3,e4,byte; + char *xrn; + + op = ((byte=(car(e1) == CASS))? "sb" : "sw"); + /* e2=e4 */ + e2 = cadr(e1); + e3 = cadr(e2); + e4 = caddr(e1); + switch(car(e2)) { + case GVAR: /* i=3 */ + g_expr(e4); + /*if (byte) use_data_reg(creg,1);*/ + printf("\t%s \t%s,%s\n",op,crn,caddr(e2)); + return; + case LVAR: + g_expr(e4); + /*if (byte) use_data_reg(creg,1);*/ + printf("\t%s \t%s,%d($fp)\n",op,crn,lvar(cadr(e2))*-1); + return; + case REGISTER: + g_expr(e4); + if (creg!=cadr(e2)) + printf("\t%s \t%s,%s\n",op,crn,register_name(cadr(e2))); + return; + } + g_expr(e4); + emit_push(); + g_expr(e2); + xrn = emit_pop(0); + /*if (byte) use_data_reg(creg,1);*/ + printf("\t%s %s,(%s)\n",op,xrn,crn); + printf("\tmove\t%s,%s\n",crn,xrn); + return; +} + +void +assop(int e1) +{ + int e2,e3,byte,op,new_reg; + char *xrn; + + /* 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); + emit_push(); + if (car(e2)==REGISTER) { + new_reg=creg; + set_crn(cadr(e2)); + tosop(op); + set_crn(new_reg); + printf("\tmove\t%s,%s\n",crn,register_name(cadr(e2))); + return; + } + g_expr(e2); + xrn = emit_pop(0); /* pop e3 value */ + /*printf("\tpushl %s # assop \n",crn);*/ /* push e2 address */ + ld_indexx(byte,0,crn); + new_reg = get_register(); + /* push e3 value */ + if(new_reg<0) { /* もうレジスタがない */ + reg_stack[reg_sp++] = -1; + /*printf("\tpushl %s\n",xrn);*/ + } else { + reg_stack[reg_sp++] = xreg; /* push するかわりにレジスタを使う */ + } + tosop(op); + if(new_reg>=0) free_register(new_reg); + /*printf("\tpopl %s # assop \n",drn);*/ + printf("\t%s\t%s,0(%s)\n",byte ? "lb" : "lw",crn,drn); + return; + +} + + +void +tosop(int op) +{ + int oreg; + char *orn; + + oreg = pop_register(); + 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) { + oreg = dreg; + } + orn = reg_name[rname[oreg]]; + switch(op) { + case ADD: + printf("\taddu \t%s,%s,%s\n",crn,crn,orn); + return; + case SUB: + printf("\tsubu \t%s,%s,%s\n",crn,crn,orn); + return; + case BAND: + printf("\tand \t%s,%s,%s\n",crn,crn,orn); + return; + case EOR: + printf("\txor \t%s,%s,%s\n",crn,crn,orn); + return; + case BOR: + printf("\tor \t%s,%s,%s\n",crn,crn,orn); + return; + case MUL: + case UMUL: + printf("\t%s\t%s,%s\n","mult",crn,orn); + printf("\tmflo\t%s\n",crn); + return; + case DIV: + case UDIV: + if (op==DIV) + printf("\tdiv\t%s,%s,%s\n",crn,crn,orn); + else + printf("\txor\t%s,%s,%s\n\tdiv\t%s,%s,%s\n",crn,crn,orn,crn,crn,orn); + return; + case MOD: + case UMOD: + if (op==MOD) + printf("\trem\t%s,%s,%s\n",crn,crn,orn); + else + printf("\txor\t%s,%s,%s\n\tdiv\t%s,%s,%s\n",crn,crn,orn,crn,crn,orn); + return; + } +} + +void +shift(char *op, int reg) +{ + if (reg>=0) { + use_register(lreg,REG_03,1); + } else { + use_register(dreg,REG_03,0); + } + /*printf("\t%s %%cl,%s\n",op,crn);*/ +} + +void +ld_indexx(int byte, int n, char *xrn) +{ + char *op; + + op = byte ? "lb" : "lw"; + if (n) + printf("\t%s\t%s,%d(%s)\n",op,crn,n,xrn); + else + printf("\t%s\t%s,0(%s)\n",op,crn,xrn); +} + +void +st_indexx(int byte, int n, char *xrn) +{ + char *op; + + op = byte ? "sb" : "sw"; + if (n) + printf("\t%s\t%s,%d(%s)\n",op,crn,n,xrn); + else + printf("\t%s\t%s,0(%s)\n",op,crn,xrn); +} + +void +indexy(char *op, char *gvar) +{ + printf("\t%s %s,%s\n",op,crn,gvar); +} + +void +cmpdimm(int e, int csreg) +{ + /* used in dosiwtch() */ + use_register(creg,csreg,0); + /*printf("\tcmpl $%d,%s\n",e,crn);*/ +} + +void +opening(char *filename) +{ + printf("\t.file \t1 \"%s\"\n",filename); + printf(" # GNU C 2.7.2.2 [AL 1.1, MM 40] Sony PlayStation compiled by GNU C\n\n"); + printf(" # Cc1 defaults:\n\n"); + printf(" # Cc1 arguments (-G value = 8, Cpu = 3000, ISA = 1):\n"); + printf(" # -msoft-float -quiet -dumpbase -o\n\n"); + printf(" # gcc2_compiled.:\n"); + printf(" # __gnu_compiled_c:\n"); + + printf("\t.text\n"); + emit_init(); +} + +void +closing(void) +{ + global_table(); +} + +void +jmp_label(int l) +{ + printf("\tjmp\t_%d\n",l); +} + +void +jmp_eq_label(int l) +{ + printf("\tj\t_%d\n",l); +} + +void +rexpr(int e1, int l1, char *s) +{ + g_expr(list3(SUB,cadr(e1),caddr(e1))); + printf("\t%s\t%s,%s,$L%d\n",s,crn,crn,l1); +} + +void +jcond(int l, char cond) +{ + printf("\t%s\t%s,%s,$L%d\n",cond?"bne":"beq",crn,crn,l); +} + +void +jmp(int l) +{ + control=0; + printf("\tj\t$L%d\n",l); + /* align? */ +} + +int +fwdlabel(void) +{ + return labelno++; +} + +void +fwddef(int l) +{ + control=1; + printf("$L%d:\n",l); +} + +int +backdef(void) +{ + control=1; + printf("$L%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_comment(char *s) +{ + printf("# %s",s); +} + +void +gen_source(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 disp0,int args) +{ + if(disp0) { + printf("\tsubl $%d,%%esp\n",-disp0); + } +} + +void +code_leave(char *name) +{ + local_table(); + printf("$L%d:\n",labelno); + printf("\t.size\t%s,_%d-%s\n",name,labelno,name); + labelno++; +} + +void +enter(char *name, int disp) +{ + int a,b,i; + a = b = 0; + + /*printf("\t.text\n"); + printf("\t.align \t2\n"); + if (stmode!=STATIC) + printf("\t.globl \t%s\n",name);*/ + printf("%s:\n",name); + + printf("\t.frame \t$fp,%d,$31\n",-disp+save_reg*size_of_int); + + + if(disp) a = 8; + + printf("\t.mask \t0x%d0000000,-8\n",a); + printf("\t.fmask \t0x00000000,0\n"); + + if(disp){ + printf("\tsubu \t$sp,$sp,%d\n",-disp+save_reg*size_of_int); + printf("\tsw\t$31,%d($sp)\n",-disp+4*save_reg1); + save_reg1--; + } + for(i=save_reg1;i==0;i--) { + printf("\tsw\t$%d,%d($sp)\n",16+i,-disp+4*i); + } + + /*if(strcmp("main",name)) + printf("\tjal \t%s_0\n",name); + else + printf("\tjal \t__%s_0\n",name);*/ + + printf("\tjal \t%s_0\n",name); + + printf("\t.end \t%s\n",name); + printf("\t.sdata\n"); + printf("\t.align 2\n"); + + save_reg = 0; + save_reg1 = 0; +} + +/* void +enter_no(char *name, int disp) +{ + + printf("\t.align \t2\n"); + if (stmode!=STATIC) + printf("\t.globl \t%s\n",name); + + printf("\t.ent \t%s\n",name); + printf("%s_0:\n",name); +} + +*/ +void +enter1(int disp) +{ + if(disp) printf("\tsubu \t$sp,$sp,%d\n",-disp+save_reg*size_of_int); + +} + +void +leave(int control, char *name) +{ + int i; + + if (control) + use_register(creg,REG_04,1); + if (retcont) { + if (control) + jmp(retlabel); + fwddef(retcont); + use_register(creg,REG_04,0); + printf("\tmove\t%s,%s\n",crn,reg_name[REG_05]); + } + fwddef(retlabel); + use_register(creg,REG_04,0); + save_reg1 = save_reg; + printf("\tmove\t$sp,$fp\n"); + + printf("\tlw\t$31,%d($sp)\n",-disp+4*save_reg); + save_reg--; + for(i=save_reg;i==0;i--) { + printf("\tlw\t$%d,%d($sp)\n",16+i,-disp+4*i); + } + + + if(disp) printf("\taddu \t$sp,$sp,%d\n",-disp+save_reg*size_of_int); + printf("\tj\t$31\n"); + + local_table(); + printf("$L%d:\n",labelno); + labelno++; +} + + +void +ret(void) +{ + use_register(creg,REG_04,1); + jmp(retlabel); +} + +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) { /* global */ + if (n->dsp != -1) { + n->dsp = -1; /* initiallized flag */ + printf(".globl\t%s\n",name); + data_mode(name); + align(t); + printf("%s:\n",name); + } 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.word %s\n",caddr(cadr(e))); + } else if(car(e)==FNAME) { + printf("\t.word %s\n",((NMTBL *)cadr(e))->nm); + } else if(car(e)==STRING) { + if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) { + l = fwdlabel(); + printf("\t.word _%d\n",l); + printf("$L%d:\n",l); + output_mode = RODATA_EMIT_MODE; + } + ascii((char *)cadr(e)); + } else error(TYERR); + } + } else { + /* if (n->sc!=LVAR) { error(TYERR); return; } */ + if(car(e)==CONST) { + printf("\tmove\t%s,%d\n",crn,cadr(e)); + printf("\t%s\t%s,%d($fp)\n",t==CHAR?"lb":"lw",crn,n->dsp); + } else if(t!=CHAR) { + if(car(e)==ADDRESS&&car(cadr(e))==GVAR) + printf("\tlw\t%s,0(%s)\n",crn,caddr(e)); + else if(car(e)==FNAME) + printf("\tlw\t%s,0(%s)\n",crn,((NMTBL *)cadr(e))->nm); + else if(car(e)==STRING) { + string(e); + } else error(TYERR); + printf("\tlw\t%s,%d($fp)\n",crn,n->dsp); + } + } +} + +void +emit_data_closing(NMTBL *n) +{ + int lb; + if (mode=GDECL) { + data_mode(0); + lb=fwdlabel(); + printf("$L%d:\n",lb); + printf("\t.size\t%s,_%d-%s\n",n->nm,lb,n->nm); + } +} + +void +global_table(void) +{ + NMTBL *n; + for(n=ntable;n < &ntable[GSYMS];n++) { + if (n->sc == GVAR && n->dsp != -1) { + /* n->dsp = -1 means initialized global */ + printf("\n\t.comm \t%s,%d\n",n->nm,size(n->ty)); + } + } +} + +void +local_table(void) +{ + NMTBL *n; + /* static local variables */ + for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) { + if (n->sc == GVAR) { + 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 (l<0) { + if (fnptr->sc==CODE) + return l+code_disp_offset; + else + return l+disp_offset; + } else { + if (fnptr->sc==CODE) + return -l+code_arg_offset; + else + return l+arg_offset; + } +} + +/* end */
--- a/mc-nop-386.c Sun Feb 16 06:34:12 2003 +0900 +++ b/mc-nop-386.c Sun Feb 16 22:21:23 2003 +0900 @@ -61,6 +61,7 @@ static void edx_cleanup(); static void use_register(int virt, int real, int move); static void emit_copy(int from,int to,int length,int offset,int value); +static int is_same_type(int s,int t); extern int error(int n); extern int fwdlabel(void); @@ -1027,10 +1028,11 @@ regv[creg]=1; } -/* goto arguments list */ -/* target list3(list2(tag,disp),cdr,ty) */ -/* source list3(expr,cdr,ty) expr=listn(tag,...) */ -/* source (after) list3(list2(tag,disp),cdr,ty) */ +/* goto arguments list */ +/* target list4(list2(tag,disp),cdr,source_expr,ty) */ +/* source expr=listn(tag,...) */ +/* source (after) list2(tag,disp) */ +/* source list list2(e,cdr) */ int overrap(int t,int source) @@ -1040,27 +1042,49 @@ int t1=size(caddr(t)); for(;source;source=cadr(source)) { s0=cadr(caddr(source)); - if(car(source)==REGISTER && car(car(t))==REGISTER) { + if(car(car(source))==REGISTER && car(car(t))==REGISTER) { if(s0==t0) return 1; - } else if(car(source)==car(car(t))) { - s1=s0+size(cadddr(source)); + } else if (is_same_type(car(source),car(t))) { + s1=s0+size(caddr(source)); +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))); if((t0<=s0&&s0<=t1)||(t0<=s1&&s1<=t1)) return 1; } } return 0; } +void +parallel_assign_post(int e1) { + int ce1; + while(e1) { + ce1=car(e1); + if (ce1) { + if(car(ce1)) + g_expr(car(ce1)); + if(cadr(ce1)>=0) { + free_register(cadr(ce1)); + } + } + e1=cadr(e1); + } +} + int -parallel_assign(int *source,int *target,int *processing) +parallel_assign(int *target,int *source,int *processing) { int t,s,e1,p,sz,ty; while(*target) { - t=car(*target); - s=car(*source); + t=car(*target); s=cadddr(*target); sz=size(ty=caddr(*target)); +printf("#0p type %d car(type) %d size %d\n",ty,car(ty),sz); for(p=*processing;p;p=cadr(p)) { if(car(p)==t) { /*ターゲットが処理リスト中にある*/ + + /* どけてしまえば、もう関係ない。二度と処理する必要もない。*/ remove0(target,t); remove0(source,s); remove0(processing,p); + /*新しいレジスタ(or スタック)を取得する*/ if (sz==size_of_int && (e1=get_register())!=-1) { e1=list2(REGISTER,e1); @@ -1075,23 +1099,22 @@ } if(car(t)==car(s) && cadr(t)==cadr(s)) { /*書き込み先が自分自身*/ - remove0(target,t); remove0(source,s); + remove0(target,t); } else if (overrap(*target,*source)) { - /*書き込み先がソースと重なっている*/ + remove0(target,t); *processing=list2(t,*processing); - remove0(target,t); remove0(source,s); - /*他のを先にする*/ - e1=parallel_assign(source,target,processing); + e1=0; + while (overrap(*target,*source)) { + /*書き込み先がソースと重なっているあいだ*/ + /*他のを先にする*/ + e1=list2(parallel_assign(target,source,processing),e1); + } /* これで空いたはず*/ + remove0(source,s); + remove0(processing,t); g_expr(assign_expr0(t,car(s),ty,ty)); /* 横によけたものがあれば、後始末をする*/ - if(e1) { - if(car(e1)) - g_expr(e1); - if(cadr(e1)>0) { - free_register(cadr(e1)); - } - } + parallel_assign_post(e1); } else { g_expr(assign_expr0(t,s,ty,ty)); remove0(target,t); remove0(source,s); @@ -1106,6 +1129,19 @@ 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); @@ -1123,18 +1159,23 @@ } int -is_same(int e1,int e2) +is_same_type(int e1,int e2) { - if( (car(e1)==LVAR && (car(e2)==RLVAR||car(e2)==CRLVAR)) - || (car(e1)==GVAR && (car(e2)==RGVAR||car(e2)==CRGVAR))) - return cadr(e1)==cadr(e2); - return 0; + 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)) + ); } void jump(int e1, int env) { - int e2,e3,e4,ce2,ce3,sz,arg_size,ty,max_regs,regs; + int e2,e3,e4,sz,arg_size,ty,max_regs,regs; + int t0,s0; NMTBL *code0; int target = 0; int source = 0; @@ -1142,16 +1183,20 @@ int sdisp = disp; /* まず、サイズを計算しながら、決まった形に落す。 */ + /* ここで、書込先アドレスを決める */ + 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)); +printf("#00 type %d car(type) %d size %d\n",ty,car(ty),sz); if (regs <= max_regs&&integral(ty)) { - target=list3(list2(REGISTER,virtual((regs++)+REG_ESI)),target,ty); + target=list4(list2(REGISTER,virtual((regs++)+REG_ESI)), + target,ty,e2); } else { - target=list3(list2(LVAR,cvar(arg_size)),target,ty); + target=list4(list2(LVAR,cvar(arg_size)), + target,ty,e2); arg_size += sz; } - source = list3(e2,source,ty); } /* disp を飛び先似合わせて修正 */ @@ -1164,17 +1209,27 @@ /* 複雑な式を前もって計算しておく */ /* 必要なら局所変数を用いる。 */ /* 局所変数へのオフセットを覚えておく */ - /* ついでに、同じものがあれば、除く */ - for (e3 = source,e2 = target; e3; e3 = cadr(e3),e2 = cadr(e2)) { - ce3=car(e3);ce2=car(e2); - if (!is_simple(car(ce3))) { - disp-=size(ty=caddr(e3)); - g_expr(assign_expr0((e4=list2(LVAR,cvar(disp))),ce3,ty,ty)); - car(e3)=e4; - } else if (is_same(ce2,ce3)) { - remove0(&source,ce3);remove0(&target,ce2); + for (e2 = target; e2; e2 = cadr(e2)) { + t0=car(e2); s0=cadddr(e2); + if (!is_simple(car(s0))) { + disp-=size(ty=caddr(e2)); + g_expr(assign_expr0((e4=list2(LVAR,cvar(disp))),s0,ty,ty)); + cadddr(e2)=e4; + s0=e4; +#if 0 + } else if (is_same_type(t0,s0)) { + if(cadr(t0)==cadr(s0)) { + /* we should check size also (but currently useless */ + remove0(&target,t0); + /* still we have to avoid overwrite */ + } + } else { +printf("#01 diffrent type t0: car(t0)=%d s0: car(s0)=%d\n",car(t0),car(s0)); +#endif } + source=list2(e4,source); +printf("#01 type %d car(type) %d\n",ty,car(ty)); } /* compute jump address */ @@ -1195,7 +1250,10 @@ /* 並列代入を実行 */ - parallel_assign(&source,&target,&processing); + e1=parallel_assign(&target,&source,&processing); + + /* 後始末が残っていた */ + parallel_assign_post(e1); if (env) { /* change the frame pointer */ @@ -1845,7 +1903,7 @@ printf("\tpopl %%ebx\n"); printf("\tleave\n"); printf("\tret\n"); - printf("\t.set _%d,%d\n",func_disp_label,lvar(vdisp)); + printf("\t.set _%d,%d\n",func_disp_label,vdisp+disp_offset); printf("_%d:\n",labelno); printf("\t.size\t%s,_%d-%s\n",name,labelno,name); local_table();