Mercurial > hg > CbC > old > device
diff mc-codegen.c @ 195:c193120ee2a6
*** empty log message ***
author | kono |
---|---|
date | Sun, 04 Apr 2004 21:17:10 +0900 |
parents | 114e9d64b5cc |
children | 5f70abd9453d |
line wrap: on
line diff
--- a/mc-codegen.c Sat Jan 10 17:13:49 2004 +0900 +++ b/mc-codegen.c Sun Apr 04 21:17:10 2004 +0900 @@ -25,6 +25,22 @@ static int g_expr0(int e1); static int register_to_lvar(int e); +#if FLOAT_CODE + +/* floating point */ + +static void dassop(int e1); +static void dmachinop(int e1,int d); +static void dassign(int e1); + +#endif +#if LONGLONG_CODE +static void lassop(int e1); +static void lmachinop(int e1); +static void lassign(int e1); +#endif + + void codegen_init() { @@ -117,6 +133,7 @@ creg=use_int(creg); code_register(e2,creg); return INT; +#if FLOAT_CODE case DREGISTER: creg=use_double(creg); code_dregister(e2,creg,1); @@ -125,6 +142,7 @@ creg=use_float(creg); code_dregister(e2,creg,0); return FLOAT; +#endif case RLVAR: creg=use_int(creg); code_rlvar(e2,creg); @@ -145,6 +163,7 @@ creg=use_int(creg); code_crlvar(e2,creg,0,size_of_short); return UCHAR; +#if FLOAT_CODE case FRLVAR: creg=use_float(creg); code_drlvar(e2,0,creg); @@ -161,6 +180,7 @@ creg=use_double(creg); code_drgvar(e1,1,creg); return DOUBLE; +#endif case FNAME: creg=use_int(creg); code_fname((NMTBL *)(e2),creg); @@ -169,6 +189,7 @@ creg=use_int(creg); code_const(e2,creg); return INT; +#if FLOAT_CODE case DCONST: creg=use_double(creg); code_dconst(e1,creg,1); @@ -177,6 +198,7 @@ creg=use_float(creg); code_dconst(e1,creg,0); return FLOAT; +#endif case STRING: creg=use_int(creg); code_string(e1,creg); @@ -191,7 +213,9 @@ return g_expr0(e2); case RINDIRECT: case CRINDIRECT: case CURINDIRECT: case SRINDIRECT: case SURINDIRECT: +#if FLOAT_CODE case DRINDIRECT: case FRINDIRECT: +#endif return rindirect(e1); case ADDRESS: if (car(e2)==REGISTER||car(e2)==DREGISTER||car(e2)==FREGISTER) @@ -201,15 +225,18 @@ case MINUS: /* レジスタに対し、neglを実行すれば実現可能 */ g_expr0(e2); code_neg(creg); return INT; +#if FLOAT_CODE case DMINUS: g_expr0(e2); code_dneg(creg,1); return DOUBLE; case FMINUS: g_expr0(e2); code_dneg(creg,0); return FLOAT; +#endif case CONV: g_expr0(e2); switch(caddr(e1)) { +#if FLOAT_CODE case I2D: code_i2d(creg); return DOUBLE; case D2I: code_d2i(creg); return INT; case U2D: code_u2d(creg); return DOUBLE; @@ -220,6 +247,30 @@ case D2U: code_d2u(creg); return UNSIGNED; case D2F: code_d2f(creg); return FLOAT; case F2D: code_f2d(creg); return DOUBLE; +#endif +#if LONGLONG_CODE + case I2LL: code_i2ll(creg); return LONGLONG; + case I2ULL: code_i2ull(creg); return ULONGLONG; + case U2LL: code_u2ll(creg); return LONGLONG; + case U2ULL: code_u2ull(creg); return ULONGLONG; + case LL2I: code_ll2i(creg); return INT; + case LL2U: code_ll2u(creg); return UNSIGNED; + case ULL2I: code_ull2i(creg); return INT; + case ULL2U: code_ull2u(creg); return UNSIGNED; +#if FLOAT_CODE + case D2LL: code_d2ll(creg); return LONGLONG; + case D2ULL: code_d2ull(creg); return ULONGLONG; + case F2LL: code_f2ll(creg); return LONGLONG; + case F2ULL: code_f2ull(creg); return ULONGLONG; + case LL2D: code_ll2d(creg); return DOUBLE; + case LL2F: code_ll2f(creg); return FLOAT; + case ULL2D: code_ull2d(creg); return DOUBLE; + case ULL2F: code_ull2f(creg); return FLOAT; + case ULL2LL: code_ull2ll(creg); return LONGLONG; + case ULL2ULL: code_ull2ull(creg); return ULONGLONG; +#endif +#endif + default: error(-1); return INT; } @@ -245,6 +296,7 @@ creg=use_int(creg); code_postinc(e1,e2,caddr(e1),0,cadddr(e1),creg); return INT; +#if FLOAT_CODE case DPREINC: /* ++d */ creg=use_double(creg); code_dpreinc(e1,e2,1,creg); @@ -261,6 +313,17 @@ creg=use_float(creg); code_dpostinc(e1,e2,0,creg); return FLOAT; +#endif +#if LONGLONG_CODE + case LPREINC: /* ++d */ + creg=use_longlong(creg); + code_lpreinc(e1,e2,creg); + return DOUBLE; + case LPOSTINC: /* d++ */ + creg=use_longlong(creg); + code_lpostinc(e1,e2,creg); + return DOUBLE; +#endif case MUL: case UMUL: case DIV: case UDIV: case MOD: case UMOD: @@ -269,6 +332,7 @@ creg=use_int(creg); machinop(e1); return INT; +#if FLOAT_CODE case DMUL: case DDIV: case DADD: case DSUB: case DCMP: case DCMPGE: @@ -281,10 +345,22 @@ creg=use_float(creg); dmachinop(e1,0); return FLOAT; - case COND: /* a?0:1 should consider non-brach instruction */ case DCOND: case FCOND: - d = (car(e1)==COND?INT:car(e1)==DCOND?DOUBLE:FLOAT); +#endif +#if LONGLONG_CODE + case LMUL: case LUMUL: + case LDIV: case LUDIV: + case LMOD: case LUMOD: + case LLSHIFT: case LULSHIFT: case LRSHIFT: case LURSHIFT: + case LADD: case LSUB: case LBAND: case LEOR: case LBOR: case LCMP: + creg=use_longlong(creg); + lmachinop(e1); + return INT; +#endif + case COND: /* a?0:1 should consider non-brach instruction */ + d = (car(e1)==LCOND?LONGLONG: + car(e1)==COND?INT:car(e1)==DCOND?DOUBLE:FLOAT); e2=fwdlabel(); b_expr(cadr(e1),0,e2,0); g_expr0(caddr(e1)); @@ -301,15 +377,25 @@ case ASS: case CASS: case SASS: assign(e1); return INT; - case FASS: case DASS: case LASS: - dassign(e1); - return DOUBLE; case ASSOP: case CASSOP: case CUASSOP: assop(e1); return INT; +#if FLOAT_CODE + case FASS: case DASS: + dassign(e1); + return DOUBLE; case DASSOP: case FASSOP: dassop(e1); return DOUBLE; +#endif +#if LONGLONG_CODE + case LASS: + lassign(e1); + return LONGLONG; + case LASSOP: case LUASSOP: + lassop(e1); + return LONGLONG ; +#endif case RSTRUCT: g_expr0(e2); return RSTRUCT; @@ -344,22 +430,33 @@ int rop_dual(op) { - if (op==GT) return LT; - if (op==UGT) return ULT; - if (op==GE) return LE; - if (op==UGE) return ULE; - if (op==LT) return GT; - if (op==ULT) return UGT; - if (op==LE) return GE; - if (op==ULE) return UGE; - if (op==DOP+GT) return DOP+LT; - if (op==DOP+GE) return DOP+LE; - if (op==DOP+LT) return DOP+GT; - if (op==DOP+LE) return DOP+GE; - if (op==FOP+GT) return FOP+LT; - if (op==FOP+GE) return FOP+LE; - if (op==FOP+LT) return FOP+GT; - if (op==FOP+LE) return FOP+GE; + switch(op) { + case GT: return LT; + case UGT: return ULT; + case GE: return LE; + case UGE: return ULE; + case LT: return GT; + case ULT: return UGT; + case LE: return GE; + case ULE: return UGE; + case DOP+GT: return DOP+LT; + case DOP+GE: return DOP+LE; + case DOP+LT: return DOP+GT; + case DOP+LE: return DOP+GE; + case FOP+GT: return FOP+LT; + case FOP+GE: return FOP+LE; + case FOP+LT: return FOP+GT; + case FOP+LE: return FOP+GE; + + case LOP+GT: return LOP+LT; + case LOP+GE: return LOP+LE; + case LOP+LT: return LOP+GT; + case LOP+LE: return LOP+GE; + case LOP+UGT: return FOP+ULT; + case LOP+UGE: return FOP+ULE; + case LOP+ULT: return FOP+UGT; + case LOP+ULE: return FOP+UGE; + } return op; } @@ -416,7 +513,7 @@ case NEQ: rexpr(e1,l1,code_eq(!cond),INT); return; - +#if FLOAT_CODE case DOP+GT: case DOP+GE: case DOP+EQ: @@ -439,7 +536,21 @@ case DOP+LE: drexpr(caddr(e1),cadr(e1),l1,DOP+GE); return; - +#endif +#if LONGLONG_CODE + case LOP+GT: + case LOP+GE: + case LOP+EQ: + case LOP+NEQ: + lrexpr(cadr(e1),caddr(e1),l1,car(e1)); + return; + case LOP+LT: + lrexpr(caddr(e1),cadr(e1),l1,LOP+GT); + return; + case LOP+LE: + lrexpr(caddr(e1),cadr(e1),l1,LOP+GE); + return; +#endif case LAND: b_expr(e2,0,cond?(l2=fwdlabel()):l1,0); b_expr(caddr(e1),cond,l1,0); @@ -480,6 +591,7 @@ code_cmp_rlvar(e2); jcond(l1,cond); return; +#if FLOATC_DOE case DRLVAR: creg=use_double(creg); code_cmp_drlvar(e2,1); @@ -500,11 +612,6 @@ code_cmp_drgvar(e2,0); jcond(l1,cond); return; - case REGISTER: - creg=use_int(creg); - code_cmp_register(e2); - jcond(l1,cond); - return; case FREGISTER: creg=use_float(creg); code_cmp_dregister(e2,0); @@ -515,22 +622,55 @@ code_cmp_dregister(e2,1); jcond(l1,cond); return; - case CONST: - if(control&&((cond&&e2)||(!cond&&!e2))) jmp(l1); - return; case DCONST: case FCONST: if(control&&((dcadr(e2)!=0.0)^cond)) jmp(l1); return; +#endif +#if LONGLONG_DOE + case LRLVAR: + creg=use_longlong(creg); + code_cmp_lrlvar(e2,1); + jcond(l1,cond); + return; + case LRGVAR: + creg=use_longlong(creg); + code_cmp_lrgvar(e2,1); + jcond(l1,cond); + return; + case LREGISTER: + creg=use_longlong(creg); + code_cmp_lregister(e2,1); + jcond(l1,cond); + return; + case LCONST: + if(control&&((lcadr(e2)!=0)^cond)) jmp(l1); + return; +#endif + case REGISTER: + creg=use_int(creg); + code_cmp_register(e2); + jcond(l1,cond); + return; + case CONST: + if(control&&((cond&&e2)||(!cond&&!e2))) jmp(l1); + return; default: if(err) { error(-1); return; /* recursive g_expr/b_expr */ } t=g_expr(e1); - if(t==FLOAT) + if (0) ; +#if FLOAT_CODE + else if(t==FLOAT) code_cmp_dregister(creg,0); else if(t==DOUBLE) code_cmp_dregister(creg,1); +#endif +#if LONGLONG_CODE + else if(t==LONGLONG||t==ULONGLONG) + code_cmp_lregister(creg); +#endif else code_cmp_register(creg); jcond(l1,cond); @@ -576,11 +716,14 @@ } else if (tag==FREGISTER) { n->dsp = new_lvar(size_of_float); t = DOUBLE; + } else if (tag==LREGISTER) { + n->dsp = new_lvar(size_of_longlong); + t = LONGLONG; } else error(-1); n->sc = LVAR; lvar = list2(LVAR,n->dsp); g_expr_u(assign_expr0(list2(LVAR,n->dsp),list3(tag,reg,(int)n),t,t)); - if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER) { + if (tag==REGISTER||tag==DREGISTER||tag==FREGISTER||tag==LREGISTER) { free_register(reg); return g_expr0(lvar); #endif @@ -644,6 +787,7 @@ *use=list3(t,*use,e1); g_expr_u(assign_expr0(e1,s,ty,ty)); *target = append4(*target,t,ty,e1); +#if FLOAT_CODE } else if (sz==size_of_double && (e1=get_dregister(1))!=-1) { e1=list3(DREGISTER,e1,0); *use=list3(t,*use,e1); @@ -654,6 +798,7 @@ *use=list3(t,*use,e1); g_expr_u(assign_expr0(e1,s,ty,ty)); *target = append4(*target,t,ty,e1); +#endif } else { g_expr_u(assign_expr0((e1=list2(LVAR,new_lvar(sz))),s,ty,ty)); *target = append4(*target,t,ty,e1); @@ -757,9 +902,9 @@ { return ( e1==CONST || e1==FNAME || e1==LVAR || e1==REGISTER ||e1==DREGISTER || - e1==FREGISTER || + e1==FREGISTER || e1==LREGISTER || e1==GVAR || e1==RGVAR || e1==RLVAR || e1==CRLVAR || e1==CRGVAR || - e1==DRLVAR || e1==FRLVAR || + e1==DRLVAR || e1==FRLVAR || e1==LRLVAR || e1==CURLVAR || e1==SURLVAR || e1==CURGVAR || e1==SURGVAR ); } @@ -774,10 +919,12 @@ || (ce1==LVAR && (ce2==SRLVAR||ce2==SURLVAR||ce2==CURLVAR)) || (ce2==LVAR && (ce1==RLVAR||ce1==CRLVAR||ce1==FRLVAR||ce1==DRLVAR)) || (ce2==LVAR && (ce1==SRLVAR||ce1==SURLVAR||ce1==CURLVAR)) + || (ce2==LVAR && (ce1==LRLVAR)) || (ce1==GVAR && (ce2==RGVAR||ce2==CRGVAR||ce2==FRGVAR||ce2==DRGVAR)) || (ce1==GVAR && (ce2==SRGVAR||ce2==SURGVAR||ce2==CURGVAR)) || (ce2==GVAR && (ce1==RGVAR||ce1==CRGVAR||ce1==FRGVAR||ce1==DRGVAR)) || (ce2==GVAR && (ce1==SRGVAR||ce1==SURGVAR||ce1==CURGVAR)) + || (ce2==GVAR && (ce1==LRGVAR)) ); } @@ -786,8 +933,9 @@ { int ce1=car(e1); return ( - ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || ce1==DRLVAR || - ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || ce1==DRGVAR || + ce1==LVAR ||ce1==RLVAR||ce1==CRLVAR || ce1==DRLVAR || ce1==LRLVAR || + ce1==GVAR ||ce1==RGVAR||ce1==CRGVAR || ce1==DRGVAR || ce1==LRGVAR || + ce1==FRLVAR || ce1==FRGVAR || ce1==CURGVAR ||ce1==SURGVAR||ce1==SRGVAR || ce1==REGISTER|| ce1==DREGISTER || ce1==FREGISTER ); @@ -889,7 +1037,7 @@ parallel_assign(&target,&source,&processing,&use); while (use) { reg = car(caddr(use)); - if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER) + if (reg==REGISTER||reg==FREGISTER||reg==DREGISTER||reg==LREGISTER) free_register(cadr(caddr(use))); else if (car(caddr(use))==LVAR) free_lvar(cadr(caddr(use))); @@ -943,6 +1091,7 @@ return; } +#if FLOAT_CODE void dmachinop(int e1,int d) { @@ -958,6 +1107,25 @@ emit_dpop_free(e2,d); return; } +#endif + +#if LONGLONG_CODE +void +lmachinop(int e1) +{ + int e2,e3,op; + + e2 = cadr(e1); + op = car(e1); + e3 = caddr(e1); + g_expr(e3); + emit_lpush(); + g_expr(e2); + ltosop(car(e1),(e2=emit_lpop())); + emit_lpop_free(e2); + return; +} +#endif void sassign(int e1) @@ -1077,6 +1245,8 @@ return; } +#if FLOAT_CODE + void dassign_opt(int e5,int e2,int e4,int d) { @@ -1163,6 +1333,91 @@ return; } +#endif + +#if LONGLONG_CODE + +void +lassign_opt(int e5,int e2,int e4) +{ + int reg; + /* e2=e4 */ + if (e5==LREGISTER) { + reg = cadr(e4); + switch(car(e2)) { + case GVAR: /* i=3 */ + code_lassign_gvar(e2,reg); + return; + case LVAR: + code_lassign_lvar(cadr(e2),reg); + return; + case LREGISTER: + if (reg!=cadr(e2)) + code_lassign_lregister(cadr(e2),reg); + return; + default: + error(-1); + } + } + /* e2 is register now */ + if (car(e2)!=LREGISTER) error(-1); + reg = cadr(e2); + switch(e5) { + case LRGVAR: code_lrgvar(e4,reg); return; + case LRLVAR: code_lrlvar(cadr(e4),reg); return; + case LCONST: code_lconst(e4,reg); return; + default: + error(-1); + } +} + +void +lassign(int e1) +{ + int e2,e3,e4,e5; + + /* e2=e4 */ + e2 = cadr(e1); + e3 = cadr(e2); + e4 = caddr(e1); e5=car(e4); + if (!use && ( + (e5==LREGISTER) || + (car(e2)==LREGISTER&&(e5==LRGVAR||e5==LRLVAR||e5==LCONST)) + )) { + creg = use_longlong(creg); + lassign_opt(e5,e2,e4); + return; + } + switch(car(e2)) { + case GVAR: + g_expr(e4); + creg = use_longlong(creg); + code_lassign_gvar(e2,creg); + return; + case LVAR: + g_expr(e4); + creg = use_longlong(creg); + code_lassign_lvar(cadr(e2),creg); + return; + case LREGISTER: + g_expr(e4); + if (creg!=cadr(e2)) { + creg = use_longlong(creg); + code_lassign_lregister(cadr(e2),creg); + } + return; + } + g_expr(e2); + emit_lpush(); + g_expr(e4); + e2 = emit_lpop(); + code_lassign(e2,creg); + emit_lpop_free(e2); + return; +} + +#endif + void assop(int e1) { @@ -1197,6 +1452,8 @@ return; } +#if FLOAT_CODE + void dassop(int e1) { @@ -1222,6 +1479,36 @@ return; } +#endif + +#if LONGLONG_CODE + +void +lassop(int e1) +{ + int e2,e3,op; + + /* e2 op= e3 */ + e2 = cadr(e1); + if (car(e2)==INDIRECT) e2=cadr(e2); + e3 = caddr(e1); + op = cadddr(e1); + + creg = use_longlong(creg); + g_expr(e3); + emit_lpush(); + g_expr(e2); + if (car(e2)==LREGISTER) { + /* code_register_lassop(cadr(e2),op); */ + error(-1); /* unsupported now */ + return; + } + code_lassop(op); + return; +} + +#endif + void cmpdimm(int e, int csreg) {