Mercurial > hg > CbC > old > device
changeset 750:f28900807fd9
i64 continue... first printf worked.
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 14 Nov 2010 01:49:40 +0900 |
parents | 593f15532e76 |
children | c921670e2ce8 |
files | mc-code-i64.c mc-codegen.c mc-parse.c |
diffstat | 3 files changed, 127 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/mc-code-i64.c Sun Nov 14 00:22:33 2010 +0900 +++ b/mc-code-i64.c Sun Nov 14 01:49:40 2010 +0900 @@ -789,7 +789,7 @@ init_src = init_src0; size_of_int = SIZE_OF_INT; - size_of_pointer = SIZE_OF_INT; + size_of_pointer = SIZE_OF_LONGLONG; size_of_short = SIZE_OF_SHORT; size_of_float = SIZE_OF_FLOAT; size_of_double = SIZE_OF_DOUBLE; @@ -1589,7 +1589,7 @@ xrn = register_name((e2=emit_pop(0)),0); use_int(reg); if (use) - printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,SIZE_OF_INT)); + printf("\t%s (%s),%s\n",cload(sign,sz),xrn,register_name(reg,0)); printf("\t%s $%d,(%s)\n",(sz==1)?"addb":(sz==SIZE_OF_SHORT)?"addw":"addl",dir,xrn); emit_pop_free(e2); } @@ -1933,6 +1933,29 @@ #define caller_arg_offset_v(arg) (ARG_LVAR_OFFSET+(arg)*SIZE_OF_INT) /* + use input register as current register + */ + +static void +use_input_reg(int reg,int mode) +{ + if (is_int_reg(reg)) { + if (ireg&® == ireg) { + if (creg==ireg) creg = 0; + ireg = 0; + } + } else if (is_float_reg(reg)) { + if (freg&® == freg) { + if (creg==freg) creg = ireg; + freg = 0; + } + } + if (mode) + regs[reg]=USING_REG; +} + + +/* Eary implementation uses pushl arg for function call. gcc use the same arguement evaluation order. Of course, the order is unspecified in C language, but it is better to @@ -2068,13 +2091,12 @@ int e2,e3,e4,e5,nargs,t; int arg,reg_arg,freg_arg,arg_assign; int dots; - int reg_arg_list=0,ret_type,special_lvar; + int reg_arg_list=0,ret_type; NMTBL *fn = 0; int jmp = 0; int complex_; int pnargs,preg_arg,pfreg_arg; int stargs; - int half_register = 0; #if (ARG_ORDER==1) int save_delayed_arg = delayed_arg; int as_save = AS_ARG; // 1st pushed argment will evaluate at the last @@ -2083,7 +2105,6 @@ const int as_save = AS_SAVE; #endif - special_lvar = -1; ret_type = function_type(cadddr(e1),&dots); if (caddr(cadddr(e1))==0) dots=1; @@ -2111,9 +2132,6 @@ pnargs = preg_arg = pfreg_arg = 0; for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { t=caddr(e3); - if (reg_arg==3 && (t==DOUBLE||t==LONGLONG||t==ULONGLONG)) { - half_register=1; - } if ((e5= !simple_arg(car(e3)))) { if (complex_) { arg = get_input_arg(caddr(complex_),as_save, @@ -2227,6 +2245,28 @@ g_expr_u(assign_expr0(arg,e4,t,t)); car(e3)=0; // done } + nargs = reg_arg = freg_arg = 0; + for (e3 = e1; e3; + increment_function_arg(e3,&nargs,®_arg,&freg_arg), + e3 = cadr(e3)) { + if (!(e4=car(e3))) continue; + t=type_value(caddr(e3)); + arg = get_input_arg(t,AS_ARG,nargs,reg_arg,freg_arg); + if(scalar(t)||t==LONGLONG||t==ULONGLONG) { + reg_arg_list = list2(arg,reg_arg_list); + /* protect from input register free */ + if (car(arg)==REGISTER||car(arg)==LREGISTER) + use_input_reg(cadr(arg),1); + g_expr_u(assign_expr0(arg,e4,t,t)); + } else if (t==DOUBLE||t==FLOAT) { + reg_arg_list = list2(arg,reg_arg_list); + if (car(arg)==DREGISTER) + use_input_reg(cadr(arg),1); /* protect from input register free */ + g_expr_u(assign_expr0(arg,e4,t,t)); /* XXX */ + } + // structs are finished + } + if (max_func_args<nargs) max_func_args=nargs; for(;arg_assign;arg_assign=cadr(arg_assign)) { g_expr_u(car(arg_assign));
--- a/mc-codegen.c Sun Nov 14 00:22:33 2010 +0900 +++ b/mc-codegen.c Sun Nov 14 01:49:40 2010 +0900 @@ -4559,6 +4559,12 @@ #if LONGLONG_CODE static int +lintegral(int t) +{ + return (t==LONGLONG||t==ULONGLONG); +} + +static int lbinop(int op, int e1, int e2, int t1, int t2) { int e=0; @@ -4571,9 +4577,8 @@ type=t2; e2=ulonglong_value(e2); t1=t2=ULONGLONG; } else { - type=t1; e1=longlong_value(e1); - type=t2; e2=longlong_value(e2); - t1=t2=LONGLONG; + if(!(t1>0&&car(t1)==POINTER)) { type=t1; e1=longlong_value(e1); t1 = LONGLONG;} + if(!(t2>0&&car(t2)==POINTER)) { type=t2; e2=longlong_value(e2); t2 = LONGLONG;} } if(car(e1)==LCONST&&car(e2)==LCONST) { le1=lcadr(e1); @@ -4586,9 +4591,34 @@ case BAND: le=le1&le2;break; case ADD: - le=le1+le2;break; + if(lintegral(t1)) { + if(lintegral(t2)) { + le=le1+le2; + } else { + if(car(t2)!=POINTER) error(TYERR); + le=size(cadr(t2))*le1+le2; + type=t2; + } + } else { + if(car(t1)!=POINTER) error(TYERR); + le=le1+size(cadr(t1))*le2; + type=t1; + } + break; case SUB: - le=le1-le2; type=LONGLONG; break; + if(lintegral(t1)) { + le=le1-le2; type=LONGLONG; + } else { + if(car(t1)!=POINTER) error(TYERR); + if(lintegral(t2)) { + le=le1-size(cadr(t1))*le2; + type=t1; + } else { + le=(le1-le2)/size(cadr(t1)); + type=LONGLONG; + } + } + break; case MUL: le=le1*le2;break; case DIV: @@ -4640,6 +4670,47 @@ )) { e=e1;e1=e2;e2=e;e=t1;t1=t2;t2=e; } + if(op==ADD) { + if(lintegral(t1)) { + if(lintegral(t2)) { + // if(t1==INT) type=t2;else type=t1; + if (us) type=ULONGLONG; else type=LONGLONG; + return(list3(LADD,e1,e2)); + } + if(car(t2)!=POINTER) error(TYERR); + e=lbinop(MUL,e1,llist2(LCONST,size(cadr(t2))),t1,LONGLONG); + type=t2; + return(list3(LADD,e,e2)); + } + if(car(t1)!=POINTER||!lintegral(t2)) error(TYERR); + e=lbinop(MUL,e2,llist2(LCONST,size(cadr(t1))),t2,LONGLONG); + type=t1; + if (car(e)==LCONST && lcadr(e)==0) + return(e1); + return(lvalue_opt(list3(LADD,e1,e))); + } + if(op==SUB) { + if(lintegral(t1)) { + if(!lintegral(t2)) error(TYERR); + if(t1==LONGLONG) type=t2;else type=t1; + if (type==ULONGLONG) type=LONGLONG; + return(list3(LSUB,e1,e2)); + } + if(car(t1)!=POINTER) error(TYERR); + if(lintegral(t2)) { + e=binop(MUL,e2,llist2(LCONST,size(cadr(t1))),t2,LONGLONG); + type=t1; + if (car(e)==LCONST) error(-1); + return(list3(LSUB,e1,e)); + } + if(car(t2)!=POINTER) + error(TYERR); + compatible(t1,t2); + e=list3(LSUB,e1,e2); + e=lbinop(DIV,e,llist2(LCONST,size(cadr(t1))),LONGLONG,LONGLONG); + type= LONGLONG; + return e; + } if((op==MUL||op==DIV)&&car(e2)==LCONST&&lcadr(e2)==1) return e1; if(op==BOR||op==EOR||op==BAND||op==ADD||op==SUB) { return(list3(op+LOP,e1,e2)); @@ -4684,10 +4755,12 @@ // for inmode, destructive modification e1,e2,t1,t2 is not allowed if(t1>0&&car(t1)==POINTER) { + if (lp64) return lbinop(op,e1,e2,t1,t2); if(!(op==SUB && t2>0&&car(t2)==POINTER)) { type = t2; e2= int_value(e2); t2=INT; } } else if(t2>0&&car(t2)==POINTER) { + if (lp64) return lbinop(op,e1,e2,t1,t2); type = t1; e1= int_value(e1); t1=INT; } #if FLOAT_CODE
--- a/mc-parse.c Sun Nov 14 00:22:33 2010 +0900 +++ b/mc-parse.c Sun Nov 14 01:49:40 2010 +0900 @@ -1438,6 +1438,7 @@ case LONGLONG: return size_of_longlong; case ULONGLONG: return size_of_longlong; case ENUM: return size_of_int; + case POINTER: return size_of_pointer; default: if(scalar(t)) return size_of_int; error(DCERR);