Mercurial > hg > CbC > old > device
changeset 536:a349f9c2aef5 inline-test-passed
MIPS set_ireg/lreg interferance
author | kono |
---|---|
date | Sat, 31 Dec 2005 14:26:40 +0900 |
parents | c17f1ef0d2be |
children | a6c9ffbf3f08 |
files | Changes mc-code-arm.c mc-code-ia32.c mc-code-mips.c mc-code-powerpc.c mc-codegen.c mc-parse.c |
diffstat | 7 files changed, 86 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Sat Dec 31 03:14:03 2005 +0900 +++ b/Changes Sat Dec 31 14:26:40 2005 +0900 @@ -7700,3 +7700,31 @@ ia32 は inline のregister_varをfreeしたことがなかったみたいだね。 +Sat Dec 31 10:34:44 JST 2005 + +code_return_struct で、一時構造体がinlineの場合にうまく +とられない。 + +.data +.globl foo + .comm foo,4 + .comm ebp,4 +.text + .set ebx_offset,16 +.globl check +check: + pushl %eax + pushl %ebx + movl ebp,%ebx + movl ebx_offset(%ebx),%eax + cmpl %eax,foo + jne bad + popl %ebx + popl %eax + ret +bad: + popl %ebx + popl %eax + ret + +とかで stack のぶっこわしを検出できます。
--- a/mc-code-arm.c Sat Dec 31 03:14:03 2005 +0900 +++ b/mc-code-arm.c Sat Dec 31 14:26:40 2005 +0900 @@ -2059,6 +2059,7 @@ } } free_register(creg); + if (creg==lreg) lreg=0; regs[reg]=USING_REG; } creg = ireg = reg;
--- a/mc-code-ia32.c Sat Dec 31 03:14:03 2005 +0900 +++ b/mc-code-ia32.c Sat Dec 31 14:26:40 2005 +0900 @@ -28,7 +28,7 @@ #define ENDIAN_L 0 #define ENDIAN_D 0 -#define SAVE_STACKS 1 + #define TEXT_EMIT_MODE 0 #define DATA_EMIT_MODE 1 @@ -611,14 +611,15 @@ int get_register_var(NMTBL *nptr) { - int i; + int i,j; if (reg_var<2) { for(i=REG_ESI;i<REG_EBP;i++) { - if (! regs[i]) { /* 使われていないなら */ - regs[i]=REG_VAR; /* そのレジスタを使うことを宣言し */ - regv[i]=0; + j = virtual(i); + if (! regs[j]) { /* 使われていないなら */ + regs[j]=REG_VAR; /* そのレジスタを使うことを宣言し */ + regv[j]=0; regvar[reg_var++]=i; - return list3(REGISTER,i,(int)nptr); /* その場所を表す番号を返す */ + return list3(REGISTER,j,(int)nptr); /* その場所を表す番号を返す */ } } } @@ -1246,12 +1247,12 @@ ret_type = cadr(cadddr(e1)); if (ret_type==CHAR) ret_type=INT; -#ifdef SAVE_STACKS + code_save_stacks(); #if FLOAT_CODE code_save_fstacks(); #endif -#endif + if (free_register_count(0)<1) { for(save = 0;save==dreg||save==creg;save++); printf("\tpushl %s\n",register_name(save,0));
--- a/mc-code-mips.c Sat Dec 31 03:14:03 2005 +0900 +++ b/mc-code-mips.c Sat Dec 31 14:26:40 2005 +0900 @@ -1662,6 +1662,7 @@ } } free_register(creg); + if (creg==lreg) lreg = 0; regs[reg]=USING_REG; } creg = ireg = reg;
--- a/mc-code-powerpc.c Sat Dec 31 03:14:03 2005 +0900 +++ b/mc-code-powerpc.c Sat Dec 31 14:26:40 2005 +0900 @@ -675,6 +675,8 @@ cleanup_lregister0() { int i; + // we should not have this, but powerpc's function + // lost some input register variables. #if 1 for(i=LREG_OFFSET+1;i<REAL_MAX_LREGISTER+LREG_OFFSET;i++) { if (regs[i]) { @@ -1664,6 +1666,7 @@ } } free_register(creg); + if (creg==lreg) lreg = 0; regs[reg]=USING_REG; } creg = ireg = reg;
--- a/mc-codegen.c Sat Dec 31 03:14:03 2005 +0900 +++ b/mc-codegen.c Sat Dec 31 14:26:40 2005 +0900 @@ -3135,7 +3135,7 @@ str_ret.dsp = 0; str_ret.ty = 0; type=list2(POINTER,t); /* fix all argument's offset */ - sz = size(type); + sz = inmode?1:size(type); for(t=fnptr->dsp;t;t=cadr(t)) { n=(NMTBL *)caddr(t); n->dsp += sz; @@ -3145,7 +3145,9 @@ else { args = 0; def(&str_ret,0); - struct_return = list3(list3(LVAR,str_ret.dsp,0),sz,type); + struct_return = inmode + ?list3(list3(IVAR,str_ret.dsp,0),sz,type) + :list3(list3(LVAR,str_ret.dsp,0),sz,type); caddr(fnptr->ty) = glist2(POINTER,caddr(fnptr->ty)); } type = type_save;
--- a/mc-parse.c Sat Dec 31 03:14:03 2005 +0900 +++ b/mc-parse.c Sat Dec 31 14:26:40 2005 +0900 @@ -1833,6 +1833,7 @@ nargs=list4(car(args),nargs,(int)n1,cadddr(args)); } + // fdecl_struct(fnptr->ty); already done by fdecl before fnptr->dsp=reverse0(nargs); retcont = 0; @@ -3446,10 +3447,42 @@ /* function call */ +static NMTBL * +make_tmp_struct() +{ + int sz; + /* checks type */ + /* make temporary struct for return value */ + /* but it is better to see we can reuse old one */ + if (tmp_struct && !inmode) { + sz = size(tmp_struct->ty); + if (sz>=size(type)) { + /* reuse it */ + } else if (tmp_struct->dsp-sz==disp) { + /* extendable */ + disp -= tmp_struct->dsp-sz; + tmp_struct->dsp = disp; + } else { + tmp_struct = def(0,0); + } + } else if (tmp_struct && inmode) { + if (size(type)>size(tmp_struct->ty)) { + tmp_struct->ty = type; + } + } else { + tmp_struct = def(0,0); + if (inmode) { + set_attr(tmp_struct,HAS_ADDRESS,1); + parse = list4(ST_DECL,parse,(int)tmp_struct,0); + } + } + return tmp_struct; +} + static int expr15(int e1) { - int t,arglist,e,sz,argtypes,at,ftype; + int t,arglist,e,argtypes,at,ftype; int type0 = type_value(type); int dots; @@ -3514,23 +3547,12 @@ if(type0==CHAR||type0==SHORT) type=set_type_with_attr(INT,type); else if(type0==UCHAR||type0==USHORT) type=set_type_with_attr(UNSIGNED,type); else if(type0>0 && (car(type0)==STRUCT||car(type0)==UNION)) { - /* make temporary struct for return value */ - /* but it is better to see we can reuse old one */ - if (tmp_struct) { - sz = size(tmp_struct->ty); - if (sz>=size(type)) { - /* reuse it */ - } else if (tmp_struct->dsp-sz==disp) { - /* extendable */ - disp -= tmp_struct->dsp-sz; - tmp_struct->dsp = disp; - } else { - tmp_struct = def(0,0); - } - } else { - tmp_struct = def(0,0); - } - e = list3(LVAR,tmp_struct->dsp,0); + + /* temporal struct is required */ + + NMTBL *tmp = make_tmp_struct(); + + e = list3(inmode?IVAR:LVAR,tmp->dsp,(int)tmp); /* pass the pointer as an argument */ /* this is recognized by called function declaration */