void subinvdadd(short m,short n, signed char *in,signed char *topout, signed char *botout) {long i,height; signed char *x2d,*x2dp1,*toprow,*botrow; int charac; // printf("startinversedadd\n"); // printarray(pwrof2(m),16,in); if(m == 0) return; height = pwrof2(m-1); initdaddarr(m-1,n,topout); //initialize arrays initdaddarr(m-1,n,botout); for(i=0;i<height;i++) {x2d = in +2*i*n; x2dp1 = in +(2*i+1)*n; botrow = botout + n*i; toprow = topout + n*i; // printrows(n,i,botrow,toprow,x2d,x2dp1); splitpath(n,i,botrow,toprow,x2d,x2dp1); // printrows(n,i,botrow,toprow,x2d,x2dp1); // charac = getchar(); // printarray(pwrof2(m-1),16,botout); // printarray(pwrof2(m-1),16,topout); } subinvdadd(m-1,n,botout,in+(height*n)/2,in); subinvdadd(m-1,n,topout,in+ (3*height*n)/2,in+height*n); }
/* void mov8(signed char *dest,signed char *src) {dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest[3] = src[3]; dest[4] = src[4]; dest[5] = src[5]; dest[6] = src[6]; dest[7] = src[7]; } // simulate a packed 4 wide add void addeight(signed char *in1,signed char *in2,signed char *out) {short i; out[0] = in1[0] + in2[0]; out[1] = in1[1] + in2[1]; out[2] = in1[2] + in2[2]; out[3] = in1[3] + in2[3]; out[4] = in1[4] + in2[4]; out[5] = in1[5] + in2[5]; out[6] = in1[6] + in2[6]; out[7] = in1[7] + in2[7]; } void topdowndaddpair(short length,short drift,signed char *inrowlower,signed char *inrowupper) {short i,lminusd,lmdm1,lmdm1ov8,lmdm1mod8; signed char temp1; double junk; //alignment for temp signed char temp[8]; lminusd = length - drift; lmdm1 = lminusd -1; lmdm1ov8 = lmdm1/8; lmdm1mod8 = lmdm1 % 8; for(i=0;i<8*lmdm1ov8;i=i+8) {mov8(temp,&inrowlower[i]); addeight(temp,&inrowupper[i+drift],&inrowlower[i]); addeight(temp,&inrowupper[i+drift+1],&inrowupper[i]); } if(lmdm1mod8 > 0) for(i=8*lmdm1ov8;i<lmdm1;i++) {temp1 = inrowlower[i]; inrowlower[i] = temp1 + inrowupper[i+drift]; inrowupper[i] = temp1 + inrowupper[i+drift+1]; } temp1 = inrowlower[lminusd-1]; if(lminusd>0) inrowlower[lminusd-1] = temp1 + inrowupper[lminusd-1+drift]; for(i=lminusd; i<length;i++) inrowupper[i] = inrowlower[i]; inrowupper[lminusd-1] = temp1; } */ void topdowndadd(short m,short length,signed char *data) { long lowbase,highbase; short half,i,ibitrev; half = 1; if(m > 1) {half = pwrof2(m-1); topdowndadd(m-1,length,data); topdowndadd(m-1,length,&data[half*length]); } for(i=0;i<half;i++) {ibitrev = bitreverser(m-1,i); lowbase = ibitrev*length; highbase = (ibitrev + half)*length; topdowndaddpair(length,i,&data[lowbase],&data[highbase]); } }
/* * opt0 - delete useless expressions and combine constants. * * opt0 will delete expressions such as x + 0, x - 0, x * 0, * x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to * by node and combine obvious constant operations. It cannot * combine name and label constants but will combine icon type * nodes. */ static void opt0(ENODE **node) { ENODE *ep; int sc; int64_t val; ep = *node; if( ep == (ENODE *)NULL ) return; switch( (*node)->nodetype ) { case en_vector_ref: case en_ref32: case en_ref32u: case en_b_ref: case en_c_ref: case en_h_ref: case en_w_ref: /* optimize unary node */ case en_ub_ref: case en_uc_ref: case en_uh_ref: case en_uw_ref: /* optimize unary node */ case en_flt_ref: case en_dbl_ref: case en_quad_ref: case en_wp_ref: case en_hp_ref: case en_ccwp: case en_cucwp: opt0(&((*node)->p[0])); return; case en_cubw: case en_cucw: case en_cuhw: case en_cubu: case en_cucu: case en_cuhu: case en_cbu: case en_ccu: case en_chu: case en_cbc: case en_cbh: case en_cbw: case en_cch: case en_ccw: case en_chw: opt0( &(ep->p[0])); if (ep->p[0]->nodetype == en_icon) { ep->nodetype = en_icon; ep->i = ep->p[0]->i; } return; case en_sxb: case en_sxc: case en_sxh: case en_zxb: case en_zxc: case en_zxh: case en_abs: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) dooper(*node); return; case en_compl: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = ~ep->p[0]->i; } return; case en_not: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = !ep->p[0]->i; } return; case en_uminus: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = -ep->p[0]->i; } return; case en_tempref: opt0( &(ep->p[0])); if( ep->p[0] && ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = ep->p[0]->i; } else if (ep->constflag) { ep->nodetype = en_icon; } return; case en_tempfpref: opt0( &(ep->p[0])); if( ep->p[0] && ep->p[0]->nodetype == en_fcon ) { ep->nodetype = en_fcon; ep->f = ep->p[0]->f; Float128::Assign(&ep->f128,&ep->p[0]->f128); } return; case en_vadd: case en_vsub: case en_add: case en_sub: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if(ep->p[0]->nodetype == en_icon) { if(ep->p[1]->nodetype == en_icon) { dooper(*node); return; } if( ep->p[0]->i == 0 ) { if( ep->nodetype == en_sub ) { ep->p[0] = ep->p[1]; ep->nodetype = en_uminus; } else *node = ep->p[1]; return; } // Place the constant node second in the add to allow // use of immediate mode instructions. if (ep->nodetype==en_add) swap_nodes(ep); } // Add or subtract of zero gets eliminated. else if( ep->p[1]->nodetype == en_icon ) { if( ep->p[1]->i == 0 ) { *node = ep->p[0]; return; } } return; case en_ptrdif: opt0(&(ep->p[0])); opt0(&(ep->p[1])); opt0(&(ep->p[4])); if (ep->p[0]->nodetype == en_icon) { if (ep->p[1]->nodetype == en_icon && ep->p[4]->nodetype == en_icon) { dooper(*node); return; } } break; case en_i2d: opt0(&(ep->p[0])); if (ep->p[0]->nodetype == en_icon) { dooper(*node); return; } break; case en_d2i: opt0(&(ep->p[0])); if (ep->p[0]->nodetype == en_fcon) { ep->i = (long)ep->p[0]->f; ep->nodetype = en_icon; return; } break; case en_fadd: case en_fsub: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_fcon) { if (ep->p[1]->nodetype == en_fcon) { dooper(*node); return; } } break; case en_fmul: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_fcon) { if (ep->p[1]->nodetype == en_fcon) { dooper(*node); return; } //else if (ep->p[1]->nodetype == en_icon) { // ep->nodetype = en_fcon; // ep->f = ep->p[0]->f * ep->p[1]->i; // return; //} } //else if (ep->p[0]->nodetype == en_icon) { // if (ep->p[1]->nodetype == en_fcon) { // ep->nodetype = en_fcon; // ep->f = ep->p[0]->i * ep->p[1]->f; // return; // } //} break; case en_fdiv: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_fcon) { if (ep->p[1]->nodetype == en_fcon) { dooper(*node); return; } //else if (ep->p[1]->nodetype == en_icon) { // ep->nodetype = en_fcon; // ep->f = ep->p[0]->f / ep->p[1]->i; // return; //} } break; case en_isnullptr: opt0(&(ep->p[0])); if (ep->p[0]->nodetype == en_icon) dooper(*node); return; case en_mulf: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon) dooper(*node); return; case en_vmul: case en_vmuls: case en_mul: case en_mulu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(*node); return; } if (ep->p[1]->nodetype == en_fcon) { ep->nodetype = en_icon; ep->i = ep->p[0]->i * ep->p[1]->f; return; } val = ep->p[0]->i; if( val == 0 ) { *node = ep->p[0]; return; } if( val == 1 ) { *node = ep->p[1]; return; } sc = pwrof2(val); if( sc != -1 ) { swap_nodes(ep); ep->p[1]->i = sc; ep->nodetype = en_shl; return; } // Place constant as oper2 swap_nodes(ep); } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 0 ) { *node = ep->p[1]; return; } if( val == 1 ) { *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; ep->nodetype = en_shl; return; } } break; case en_div: case en_udiv: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(*node); return; } if( ep->p[0]->i == 0 ) { /* 0/x */ *node = ep->p[0]; return; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 1 ) { /* x/1 */ *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; if ((*node)->nodetype == en_udiv) ep->nodetype = en_shru; else ep->nodetype = ep->p[0]->isUnsigned ? en_shru : en_shr; } } break; case en_mod: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[1]->nodetype == en_icon ) { if( ep->p[0]->nodetype == en_icon ) { dooper(*node); return; } sc = pwrof2(ep->p[1]->i); if( sc != -1 ) { ep->p[1]->i = mod_mask(sc); ep->nodetype = en_and; } } break; case en_and: case en_or: case en_xor: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon) dooper(*node); else if (ep->p[0]->nodetype == en_icon) swap_nodes(ep); break; case en_shr: case en_shru: case en_asr: case en_asl: case en_shl: case en_shlu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon ) dooper(*node); // Shift by zero.... else if( ep->p[1]->nodetype == en_icon ) { if( ep->p[1]->i == 0 ) { *node = ep->p[0]; return; } } break; case en_land_safe: case en_land: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) dooper(*node); break; case en_lor_safe: case en_lor: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) dooper(*node); break; case en_ult: case en_ule: case en_ugt: case en_uge: case en_lt: case en_le: case en_gt: case en_ge: case en_eq: case en_ne: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) dooper(*node); break; case en_feq: case en_fne: case en_flt: case en_fle: case en_fgt: case en_fge: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_fcon && ep->p[1]->nodetype == en_fcon) dooper(*node); break; case en_veq: case en_vne: case en_vlt: case en_vle: case en_vgt: case en_vge: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; case en_safe_cond: case en_cond: opt0(&(ep->p[0])); opt0(&(ep->p[1]->p[0])); opt0(&(ep->p[1]->p[1])); if ((ep->p[0]->nodetype==en_icon||ep->p[0]->nodetype==en_cnacon) && (ep->p[1]->p[0]->nodetype==en_icon || ep->p[1]->p[0]->nodetype==en_cnacon) && (ep->p[1]->p[1]->nodetype==en_icon || ep->p[1]->p[1]->nodetype==en_cnacon)) dooper(*node); break; case en_chk: opt0(&(ep->p[0])); opt0(&(ep->p[1])); opt0(&(ep->p[2])); break; case en_asand: case en_asor: case en_asadd: case en_assub: case en_asmul: case en_asdiv: case en_asmod: case en_asrsh: case en_aslsh: case en_fcall: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; case en_assign: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; // en_tempref comes from typecasting case en_void: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype == en_tempref) { (*node)->nodetype = ep->p[1]->nodetype; *node = ep->p[1]; } break; case en_addrof: opt0(&(ep->p[0])); break; case en_list: for (ep = ep->p[2]; ep; ep = ep->p[2]) opt0(&(ep->p[0])); break; } }
void opt0(ENODE ** node) /* * opt0 - delete useless expressions and combine constants. * * opt0 will delete expressions such as x + 0, x - 0, x * 0, * x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to * by node and combine obvious constant operations. It cannot * combine name and label constants but will combine icon type * nodes. */ { ENODE *ep; int sc,mode,val; double dval; ep = *node; if( ep == 0 ) return; switch( (*node)->nodetype ) { case en_b_ref: case en_w_ref: /* optimize unary node */ case en_ub_ref: case en_uw_ref: /* optimize unary node */ case en_l_ref: case en_ul_ref: case en_floatref: case en_doubleref: case en_longdoubleref: case en_cb: case en_cub: case en_cw: case en_cuw: case en_cl: case en_cul: case en_cf: case en_cd: case en_cp: case en_bits: case en_cld: case en_ainc: case en_adec: case en_not: case en_compl: opt0( &((*node)->v.p[0])); return; case en_uminus: opt0( &(ep->v.p[0])); if( isintconst(ep->v.p[0]->nodetype)) { ep->nodetype = ep->v.p[0]->nodetype; ep->v.i = -ep->v.p[0]->v.i; } else if( ep->v.p[0]->nodetype == en_rcon || ep->v.p[0]->nodetype == en_fcon || ep->v.p[0]->nodetype == en_lrcon) { ep->nodetype = ep->v.p[0]->nodetype; ep->v.i = -ep->v.p[0]->v.f; } return; case en_add: case en_sub: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); mode = getmode(ep->v.p[0],ep->v.p[1]); switch (mode) { case 1: case 2: case 3: case 4: dooper(node,mode); break; case 5: if (ep->v.p[0]->v.i == 0) { if (ep->nodetype == en_sub) { *node = makenode(en_uminus,ep->v.p[1],0); } else *node = ep->v.p[1]; } else dooper(node,mode); break; case 6: if (ep->v.p[0]->v.f == 0) { if (ep->nodetype == en_sub) { *node = ep->v.p[1]; ep->v.p[1]->v.f = - ep->v.p[1]->v.f; } else *node = ep->v.p[1]; } else dooper(node,mode); break; case 7: if (ep->v.p[1]->v.i == 0) { *node = ep->v.p[0]; } else dooper(node,mode); break; case 8: if (ep->v.p[1]->v.f == 0) { *node = ep->v.p[0]; } else dooper(node,mode); break; } return; case en_mul: case en_umul: case en_pmul: case en_asmul: case en_asumul: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); mode = getmode(ep->v.p[0],ep->v.p[1]); switch(mode) { case 1: case 2: case 3: case 4: dooper(node,mode); break; case 5: if (!floatrecurse(ep->v.p[1])) { sc = pwrof2(ep->v.p[0]->v.i); if( sc != -1 ) { ENODE *temp = ep->v.p[0]; ep->v.p[0 ] = ep->v.p[1]; ep->v.p[1] = temp; ep->v.p[1]->v.i = sc; switch(ep->nodetype) { case en_mul: ep->nodetype = en_alsh; break; case en_asmul: ep->nodetype = en_asalsh; break; case en_umul: case en_pmul: ep->nodetype = en_lsh; break; case en_asumul: ep->nodetype = en_aslsh; break; } break; } } val = ep->v.p[0]->v.i; if (val == 0) *node = ep->v.p[0]; else if (val == 1) *node = ep->v.p[1]; else if (val == -1) *node = makenode(en_uminus,(char *)ep->v.p[1],0); else dooper(node,mode); break; case 6: dval = ep->v.p[0]->v.f; if (dval == 0) *node = ep->v.p[0]; else if (dval == 1) *node = ep->v.p[1]; else if (dval == -1) *node = makenode(en_uminus,(char *)ep->v.p[1],0); else dooper(node,mode); break; case 7: if (!floatrecurse(ep->v.p[0])) { sc = pwrof2(ep->v.p[1]->v.i); if( sc != -1 ) { ep->v.p[1]->v.i = sc; switch(ep->nodetype) { case en_mul: ep->nodetype = en_alsh; break; case en_asmul: ep->nodetype = en_asalsh; break; case en_umul: case en_pmul: ep->nodetype = en_lsh; break; case en_asumul: ep->nodetype = en_aslsh; break; } break; } } val = ep->v.p[1]->v.i; if (val == 0) *node = ep->v.p[1]; else if (val == 1) *node = ep->v.p[0]; else if (val == -1) *node = makenode(en_uminus,(char *)ep->v.p[0],0); else dooper(node,mode); break; case 8: dval = ep->v.p[1]->v.f; if (dval == 0) *node = ep->v.p[1]; else if (dval == 1) *node = ep->v.p[0]; else if (dval == -1) *node = makenode(en_uminus,(char *)ep->v.p[0],0); else dooper(node,mode); break; } break; case en_pdiv: case en_div: case en_udiv: case en_asdiv: case en_asudiv: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); mode = getmode(ep->v.p[0],ep->v.p[1]); switch(mode) { case 1: case 2: case 3: case 4: dooper(node,mode); break; case 5: if (ep->v.p[0]->v.i == 0) *node = ep->v.p[0]; else dooper(node,mode); break; case 6: if (ep->v.p[0]->v.f == 0) *node = ep->v.p[0]; else dooper(node,mode); break; case 7: if (!floatrecurse(ep->v.p[0])) { sc = pwrof2(ep->v.p[1]->v.i); if( sc != -1 ) { ep->v.p[1]->v.i = sc; switch(ep->nodetype) { case en_div: ep->nodetype = en_arsh; break; case en_asdiv: ep->nodetype = en_asarsh; break; case en_udiv: case en_pdiv: ep->nodetype = en_rsh; break; case en_asudiv: ep->nodetype = en_asrsh; break; } break; } } val = ep->v.p[1]->v.i; if (val == 1) *node = ep->v.p[0]; else if (val == -1) *node = makenode(en_uminus,(char *)ep->v.p[0],0); else dooper(node,mode); break; case 8: dval = ep->v.p[1]->v.f; if (dval == 1) *node = ep->v.p[0]; else if (dval == -1) *node = makenode(en_uminus,(char *)ep->v.p[0],0); else dooper(node,mode); break; } break; case en_mod: case en_umod: case en_asmod: case en_asumod: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); mode = getmode(ep->v.p[0],ep->v.p[1]); switch(mode) { case 7: if (!floatrecurse(ep->v.p[0])) { sc = pwrof2(ep->v.p[1]->v.i); if( sc != -1 ) { ep->v.p[1]->v.i = mod_mask(sc); if (ep->nodetype == en_asmod || ep->nodetype == en_asumod) ep->nodetype = en_asand; else ep->nodetype = en_and; break; } } case 1: case 2: case 3: case 4: case 5: case 6: case 8: dooper(node,mode); } break; case en_and: case en_or: case en_xor: case en_rsh: case en_lsh: case en_arsh: case en_alsh: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); if( isintconst(ep->v.p[0]->nodetype) && isintconst(ep->v.p[1]->nodetype) ) dooper(node,getmode(ep->v.p[0],ep->v.p[1])); break; case en_land: case en_lor: case en_lt: case en_le: case en_ugt: case en_uge: case en_ult: case en_ule: case en_gt: case en_ge: case en_eq: case en_ne: case en_asalsh: case en_asarsh: case en_asand: case en_asor: case en_asxor: case en_asadd: case en_assub: case en_asrsh: case en_aslsh: case en_cond: case en_fcall: case en_void: case en_trapcall: case en_intcall: case en_pfcall: case en_pfcallb: case en_assign: case en_moveblock: case en_stackblock: case en_callblock: case en_fcallb: case en_refassign: case en_pcallblock: opt0(&(ep->v.p[0])); opt0(&(ep->v.p[1])); break; } }
/* * opt0 - delete useless expressions and combine constants. * * opt0 will delete expressions such as x + 0, x - 0, x * 0, * x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to * by node and combine obvious constant operations. It cannot * combine name and label constants but will combine icon type * nodes. */ void opt0(ENODE **node) { ENODE *ep; __int64 val, sc; ep = *node; if( ep == NULL ) return; switch( (*node)->nodetype ) { case en_b_ref: case en_c_ref: case en_h_ref: case en_w_ref: /* optimize unary node */ case en_ub_ref: case en_uc_ref: case en_uh_ref: case en_uw_ref: /* optimize unary node */ case en_flt_ref: case en_dbl_ref: case en_cbc: case en_cbh: case en_cbw: case en_cch: case en_ccw: case en_chw: case en_ainc: case en_adec: case en_not: case en_compl: opt0( &((*node)->p[0])); return; case en_uminus: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = -ep->p[0]->i; } return; case en_add: case en_sub: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } if( ep->p[0]->i == 0 ) { if( ep->nodetype == en_sub ) { ep->p[0] = ep->p[1]; ep->nodetype = en_uminus; } else *node = ep->p[1]; return; } } else if( ep->p[1]->nodetype == en_icon ) { if( ep->p[1]->i == 0 ) { *node = ep->p[0]; return; } } return; case en_mul: case en_mulu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } val = ep->p[0]->i; if( val == 0 ) { *node = ep->p[0]; return; } if( val == 1 ) { *node = ep->p[1]; return; } sc = pwrof2(val); if( sc != -1 ) { swap_nodes(ep); ep->p[1]->i = sc; ep->nodetype = en_shl; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 0 ) { *node = ep->p[1]; return; } if( val == 1 ) { *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; ep->nodetype = en_shl; } } break; case en_div: case en_udiv: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } if( ep->p[0]->i == 0 ) { /* 0/x */ *node = ep->p[0]; return; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 1 ) { /* x/1 */ *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; ep->nodetype = en_shr; } } break; case en_mod: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[1]->nodetype == en_icon ) { if( ep->p[0]->nodetype == en_icon ) { dooper(node); return; } sc = pwrof2(ep->p[1]->i); if( sc != -1 ) { ep->p[1]->i = mod_mask(sc); ep->nodetype = en_and; } } break; case en_and: case en_or: case en_xor: case en_shr: case en_shru: case en_shl: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon ) dooper(node); break; case en_land: case en_lor: case en_ult: case en_ule: case en_ugt: case en_uge: case en_lt: case en_le: case en_gt: case en_ge: case en_eq: case en_ne: case en_asand: case en_asor: case en_asadd: case en_assub: case en_asmul: case en_asdiv: case en_asmod: case en_asrsh: case en_aslsh: case en_cond: case en_fcall: case en_void: case en_assign: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; } }
/* * opt0 - delete useless expressions and combine constants. * * opt0 will delete expressions such as x + 0, x - 0, x * 0, * x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to * by node and combine obvious constant operations. It cannot * combine name and label constants but will combine icon type * nodes. */ static void opt0(ENODE **node) { ENODE *ep; int64_t val, sc; ep = *node; if( ep == (ENODE *)NULL ) return; switch( (*node)->nodetype ) { case en_b_ref: case en_c_ref: case en_h_ref: case en_w_ref: /* optimize unary node */ case en_ub_ref: case en_uc_ref: case en_uh_ref: case en_uw_ref: /* optimize unary node */ case en_flt_ref: case en_dbl_ref: case en_cubw: case en_cucw: case en_cuhw: case en_cubu: case en_cucu: case en_cuhu: case en_cbu: case en_ccu: case en_chu: case en_cbc: case en_cbh: case en_cbw: case en_cch: case en_ccw: case en_chw: case en_ainc: case en_adec: opt0( &((*node)->p[0])); return; case en_compl: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = ~ep->p[0]->i; } return; case en_not: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = !ep->p[0]->i; } return; case en_uminus: opt0( &(ep->p[0])); if( ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = -ep->p[0]->i; } return; case en_tempref: opt0( &(ep->p[0])); if( ep->p[0] && ep->p[0]->nodetype == en_icon ) { ep->nodetype = en_icon; ep->i = ep->p[0]->i; } return; case en_tempfpref: opt0( &(ep->p[0])); if( ep->p[0] && ep->p[0]->nodetype == en_fcon ) { ep->nodetype = en_fcon; ep->f = ep->p[0]->f; } return; case en_add: case en_sub: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } if( ep->p[0]->i == 0 ) { if( ep->nodetype == en_sub ) { ep->p[0] = ep->p[1]; ep->nodetype = en_uminus; } else *node = ep->p[1]; return; } } else if( ep->p[1]->nodetype == en_icon ) { if( ep->p[1]->i == 0 ) { *node = ep->p[0]; return; } } return; case en_mul: case en_mulu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } val = ep->p[0]->i; if( val == 0 ) { *node = ep->p[0]; return; } if( val == 1 ) { *node = ep->p[1]; return; } sc = pwrof2(val); if( sc != -1 ) { swap_nodes(ep); ep->p[1]->i = sc; ep->nodetype = en_shl; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 0 ) { *node = ep->p[1]; return; } if( val == 1 ) { *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; ep->nodetype = en_shl; } } break; case en_div: case en_udiv: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon ) { if( ep->p[1]->nodetype == en_icon ) { dooper(node); return; } if( ep->p[0]->i == 0 ) { /* 0/x */ *node = ep->p[0]; return; } } else if( ep->p[1]->nodetype == en_icon ) { val = ep->p[1]->i; if( val == 1 ) { /* x/1 */ *node = ep->p[0]; return; } sc = pwrof2(val); if( sc != -1 ) { ep->p[1]->i = sc; if ((*node)->nodetype == en_udiv) ep->nodetype = en_shru; else ep->nodetype = ep->p[0]->isUnsigned ? en_shru : en_shr; } } break; case en_mod: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[1]->nodetype == en_icon ) { if( ep->p[0]->nodetype == en_icon ) { dooper(node); return; } sc = pwrof2(ep->p[1]->i); if( sc != -1 ) { ep->p[1]->i = mod_mask(sc); ep->nodetype = en_and; } } break; case en_and: case en_or: case en_xor: case en_shr: case en_shru: case en_asr: case en_shl: case en_shlu: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if( ep->p[0]->nodetype == en_icon && ep->p[1]->nodetype == en_icon ) dooper(node); break; case en_land: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) { dooper(node); break; } break; case en_lor: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) { dooper(node); break; } break; case en_ult: case en_ule: case en_ugt: case en_uge: case en_lt: case en_le: case en_gt: case en_ge: case en_eq: case en_ne: opt0(&(ep->p[0])); opt0(&(ep->p[1])); if (ep->p[0]->nodetype==en_icon && ep->p[1]->nodetype==en_icon) dooper(node); break; case en_feq: case en_fne: case en_flt: case en_fle: case en_fgt: case en_fge: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; case en_cond: opt0(&(ep->p[0])); opt0(&(ep->p[1]->p[0])); opt0(&(ep->p[1]->p[1])); if ((ep->p[0]->nodetype==en_icon||ep->p[0]->nodetype==en_cnacon) && (ep->p[1]->p[0]->nodetype==en_icon || ep->p[1]->p[0]->nodetype==en_cnacon) && (ep->p[1]->p[1]->nodetype==en_icon || ep->p[1]->p[1]->nodetype==en_cnacon)) dooper(node); break; case en_chk: opt0(&(ep->p[0])); opt0(&(ep->p[1])); opt0(&(ep->p[2])); break; case en_asand: case en_asor: case en_asadd: case en_assub: case en_asmul: case en_asdiv: case en_asmod: case en_asrsh: case en_aslsh: case en_fcall: case en_void: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; case en_assign: opt0(&(ep->p[0])); opt0(&(ep->p[1])); break; } }
void invdadd(short m,short n, signed char *in,signed char *work) {short rowcount = pwrof2(m); subinvdadd(m,n,in,work+(rowcount*n)/2,work); if(odd(m) == 1) movearr(m,n,work,in); }
void movearr(short m,short rowlength,signed char *inar,signed char *outar) {long arlength,i; arlength = rowlength*pwrof2(m); for(i=0;i<arlength;i++) outar[i] = inar[i]; }
void initdaddarr(short m,short rowlength,signed char *inar) {long arlength,i; arlength = rowlength*pwrof2(m); for(i=0;i<arlength;i++) inar[i] = 0.0; }