Mercurial > hg > CbC > old > device
changeset 125:e537da31dce3 struct-push
struct push
author | kono |
---|---|
date | Mon, 24 Mar 2003 12:15:53 +0900 |
parents | f52805504ffa |
children | 1d1612fe705a |
files | Changes mc-code-powerpc.c mc-parse.c |
diffstat | 3 files changed, 70 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/Changes Mon Mar 24 03:11:14 2003 +0900 +++ b/Changes Mon Mar 24 12:15:53 2003 +0900 @@ -2462,3 +2462,37 @@ Intel 側にもだいぶ embug してしまったようだ。 basicとかfloatの難易度を上げすぎたか? + +mc-code-power.c のlvar は、 + input arg > 0 + local var < 0 + output arg > ARG_OFF +とするべきだね。 + +Mon Mar 24 12:08:43 JST 2003 + + addi r27,r1,56 + addi r29,r28,28 + mr r3,r27 + mr r4,r29 + li r5,372 + bl L_memcpy$stub + lwz r4,0(r28) + lwz r5,4(r28) + lwz r6,8(r28) + lwz r7,12(r28) + lwz r8,16(r28) + lwz r9,20(r28) + lwz r10,24(r28) + mr r3,r28 + bl _main3 + + +うーむ、最低な奴。最初の28byteだけレジスタ渡しなのか。アドレス +は変わらないんでしょうけど。まぁ、合わせなくても害は無いけどさ。 +そのうちね。(そんなに難しくは無いが... また、function が複雑 +怪奇になるな) しかし浮動小数点レジスタも使うとかそんなんじゃなくて +良かったかも。 + + +
--- a/mc-code-powerpc.c Mon Mar 24 03:11:14 2003 +0900 +++ b/mc-code-powerpc.c Mon Mar 24 12:15:53 2003 +0900 @@ -193,7 +193,7 @@ printf("lo16(%d+L_%d)(r30)\n",CODE_LVAR,lvar_offset_label); } else if (l<0) { /* local variable */ printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); - } else if (l>ARG_LVAR_OFFSET) { /* caller's arguments */ + } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ printf("lo16(%d)(r30)\n",CALLER_ARG); } else { /* callee's arguments */ printf("lo16(%d+L_%d)(r30)\n",CALLEE_ARG,r1_offset_label); @@ -216,7 +216,7 @@ printf("la r0,ha16(%d+L_%d)(r30)\n",CODE_LVAR,lvar_offset_label); } else if (l<0) { /* local variable */ printf("la r0,ha16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); - } else if (l>ARG_LVAR_OFFSET) { /* caller's arguments */ + } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ if (CALLER_ARG>32765) printf("la r0,ha16(%d)(r30)\n",CALLER_ARG); } else { /* callee's arguments */ @@ -231,7 +231,7 @@ printf("lo16(%d+L_%d)(r0)\n",CODE_LVAR,lvar_offset_label); } else if (l<0) { /* local variable */ printf("lo16(%d+L_%d)(r0)\n",FUNC_LVAR,lvar_offset_label); - } else if (l>ARG_LVAR_OFFSET) { /* caller's arguments */ + } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ if (CALLER_ARG>32765) printf("lo16(%d)(r0)\n",CALLER_ARG); else @@ -1050,7 +1050,7 @@ char *trn = register_name(to); char *drn; int fix = 0; - char *bcopy = "bcopy"; + char *memmove = "memmove"; int dreg = get_register(); if (!dreg) error(-1); drn = register_name(dreg); @@ -1087,14 +1087,20 @@ 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); - extern_define(bcopy,0,FUNCTION,1); - break; + clear_ptr_cache(); + code_save_stacks(); + printf("\tli r5,%d\n",length); + printf("\tmr r4,%s\n",frn); + printf("\tmr r3,%s\n",trn); + /* overrap must be allowed */ + printf("\tbl L_%s$stub\n",memmove); + extern_define(memmove,0,FUNCTION,1); + fix=0; + set_creg(RET_REGISTER,0); + if (creg!=to) { + free_register(to); to = creg; } + break; } if (value) { /* creg must point top of the destination data */ @@ -1121,27 +1127,27 @@ length += size_of_int - (length%size_of_int); } dreg = get_register(); if (!dreg) error(-1); - sreg = get_register(); if (!sreg) error(-1); drn = register_name(dreg); crn = register_name(creg); - srn = register_name(sreg); - code_lvar(arg,sreg); - for(count=0;length<MAX_COPY_LEN;count++,length-=size_of_int) { - if (length==0) { - free_register(dreg); - return count; - } else { - printf("\tlwz %s,%d(%s)\n",drn,length-size_of_int,crn); - printf("\tstwu %s,%d(%s)\n",drn,-size_of_int,srn); + if (length<MAX_COPY_LEN) { + sreg = get_register(); if (!sreg) error(-1); + srn = register_name(sreg); + code_lvar(cadr(arg),sreg); + for(count=0;length<MAX_COPY_LEN;count++,length-=size_of_int) { + if (length==0) { + free_register(sreg); + free_register(dreg); + return count; + } else { + printf("\tlwz %s,%d(%s)\n",drn,length-size_of_int,crn); + printf("\tstwu %s,%d(%s)\n",drn,-size_of_int,srn); + } } } - printf("\taddis %s,%s,ha16(%d)\n",srn,srn,length); - printf("\taddi %s,%s,lo16(%d)\n",srn,srn,length); + code_lvar(cadr(arg),dreg); /* downward direction copy */ - printf("\tmr %s,%s\n",drn,srn); emit_copy(creg,dreg,length,0,0,1); if (dreg) free_register(dreg); - if (sreg) free_register(sreg); return length/size_of_int; } @@ -1271,6 +1277,7 @@ return !contains_in_list(e3,FUNCTION) && !contains_in_list(e3,CONV) && + !contains_in_list(e3,RSTRUCT) && !contains_in_list(e3,SASS) ; }
--- a/mc-parse.c Mon Mar 24 03:11:14 2003 +0900 +++ b/mc-parse.c Mon Mar 24 12:15:53 2003 +0900 @@ -1217,7 +1217,7 @@ int type_save,mode_save,t,sz; NMTBL *n; - t = fntype; + t = cadr(fntype); if (!scalar(t) && (car(t)==STRUCT||car(t)==UNION)) { mode_save = mode; mode=ADECL; @@ -1234,11 +1234,11 @@ n->dsp += sz; } fnptr->dsp = reverse0(fnptr->dsp); - if ((t=size(fntype))==-1) error(TYERR); + if ((sz=size(cadr(fntype)))==-1) error(TYERR); else { args = 0; def(&str_ret); - struct_return = list3(list2(LVAR,str_ret.dsp),t,type); + struct_return = list3(list2(LVAR,str_ret.dsp),sz,type); } type = type_save; mode = mode_save; @@ -1626,7 +1626,6 @@ rvalue_t(car(struct_return),caddr(struct_return))); gexpr(cadr(e),0); } else { - e = rvalue(e); type = caddr(struct_return); e1 = rvalue_t(cadr(struct_return),INT); /* size */ gexpr(list4(SASS,rvalue(car(struct_return)),e,e1),0); @@ -2428,6 +2427,7 @@ if(car(e)==INDIRECT) return cadr(e); return list2(ADDRESS,e); } else if(t==STRUCT || t==UNION) { + if(car(e)==RSTRUCT) return e; /* ??? */ t = cadr(type); /* size */ return list3(RSTRUCT,e,t); } else if(t==FUNCTION) {