void AliasUses(BITINT *bits, IMODE *im, BOOLEAN rhs) { if (im) { if (rhs) { if (im->offset->type == en_tempref) { ormap(bits, tempInfo[im->offset->v.sp->value.i]->modifiedBy); if (im->mode == i_direct) { im = LookupLoadTemp(im, im); } setbit(bits, termMap[im->offset->v.sp->value.i]); } else if (im->mode == i_direct) { ALIASNAME *an = LookupMem(im); ALIASADDRESS *aa ; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); while (aa->merge) aa = aa->merge; if (aa->modifiedBy) ormap(bits, aa->modifiedBy); im = GetLoadTemp(im); if (im) { setbit(bits, termMap[im->offset->v.sp->value.i]); } } else if (im->mode == i_immed && !isintconst(im->offset) && !iscomplexconst(im->offset) && !isfloatconst(im->offset) && im->offset->type != en_labcon) { ALIASNAME *an = LookupMem(im); ALIASADDRESS *aa ; aa = LookupAddress(an, 0); while (aa->merge) aa = aa->merge; if (aa->modifiedBy) ormap(bits, aa->modifiedBy); im = im->offset->v.sp->imvalue; if (im) { im = GetLoadTemp(im); if (im) { setbit(bits, termMap[im->offset->v.sp->value.i]); } } } } else { setbit(bits, termMap[im->offset->v.sp->value.i]); } } }
int getmode(ENODE *ep1,ENODE *ep2) /* * get the constant mode of a pair of nodes * 0 = Neither node is a constant * 1 = icon,icon * 2 = icon,rcon * 3 = rcon,icon * 4 = rcon,rcon * 5 = icon,nothing * 6 = rcon,nothing * 7 = nothing,icon * 8 = nothing,rcon */ { int mode = 0; if (isintconst(ep1->nodetype) ) if (ep2) { if (isintconst(ep2->nodetype)) mode = 1; else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2->nodetype == en_fcon) mode = 2; else mode = 5; } else mode = 5; else if (ep1->nodetype == en_rcon || ep1->nodetype == en_lrcon || ep1->nodetype == en_fcon) if (ep2) { if (isintconst(ep2->nodetype)) mode = 3; else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2->nodetype == en_fcon) mode = 4; else mode = 6; } else mode = 6; else if (ep2) if (isintconst(ep2->nodetype)) mode = 7; else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2->nodetype == en_fcon) mode = 8; return(mode); }
BOOLEAN isconstaddress(EXPRESSION *exp) { switch(exp->type) { case en_add: case en_arrayadd: case en_structadd: return (isconstaddress(exp->left) || isintconst(exp->left)) && (isconstaddress(exp->right) || isintconst(exp->right)); case en_global: case en_label: case en_pc: case en_labcon: return TRUE; case en_func: return !exp->v.func->ascall; case en_threadlocal: default: return FALSE; } }
static void HandleParm(QUAD *head) { if (head->dc.left->size == ISZ_ADDR) { // temp, mem ALIASLIST *result = NULL, **base = NULL, *addr; if (head->temps & TEMP_LEFT) { base = &tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; } else if (!isintconst(head->dc.left->offset)) { ALIASNAME *an; ALIASADDRESS *aa; switch (head->dc.left->offset->type) { case en_labcon: case en_global: case en_label: case en_pc: case en_threadlocal: return; default: break; } an = LookupMem(head->dc.left->offset->v.sp->imvalue); if (head->dc.left->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); base = &aa->pointsto; } if (base) { addr = *base; AliasUnionParm(&parmList, (*base)); while (addr) { if (addr->address->name->byUIV) { if (!IntersectsUIV(addr->address->pointsto)) { ALIASNAME *an = LookupAliasName(addr->address->name, 0); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&addr->address->pointsto, al); } } addr = addr->next; } } } }
static int InferStride(IMODE *im) { QUAD * q = tempInfo[im->offset->v.sp->value.i]->instructionDefines; if (q) { if (q->dc.opcode == i_lsl) { if ((q->temps & TEMP_LEFT) && q->dc.left->mode == i_direct) { if (q->dc.right->mode == i_immed && isintconst(q->dc.right->offset)) return 1 << q->dc.right->offset->v.i; } } else if (q->dc.opcode == i_mul || q->dc.opcode == i_add || q->dc.opcode == i_sub) { IMODE *one = q->dc.left; IMODE *two = q->dc.right; if (one->mode == i_immed && isintconst(one->offset)) { IMODE *three = one; one = two; two = three; } if (one->mode == i_direct && one->offset->type == en_tempref) { if (two->mode == i_immed && isintconst(two->offset)) { if ( q->dc.opcode == i_add || q->dc.opcode == i_sub) return InferStride(one); return two->offset->v.i; } } } } return 1; }
static int InferOffset(IMODE *im) { QUAD * q = tempInfo[im->offset->v.sp->value.i]->instructionDefines; if (q) { if (q->dc.opcode == i_add) { if ((q->temps & TEMP_LEFT) && q->dc.left->mode == i_direct) { if (q->dc.right->mode == i_immed && isintconst(q->dc.right->offset)) return q->dc.right->offset->v.i; } else if ((q->temps & TEMP_RIGHT) && q->dc.right->mode == i_direct) { if (q->dc.left->mode == i_immed && isintconst(q->dc.left->offset)) return q->dc.left->offset->v.i; } } else if (q->dc.opcode == i_sub) { if ((q->temps & TEMP_LEFT) && q->dc.left->mode == i_direct) { if (q->dc.right->mode == i_immed && isintconst(q->dc.right->offset)) return -q->dc.right->offset->v.i; } } else if (q->dc.opcode == i_lsl) { if (q->dc.right->mode == i_immed && isintconst(q->dc.right->offset)) if (q->temps & TEMP_LEFT) return InferOffset(q->dc.left) << q->dc.right->offset->v.i; } else if (q->dc.opcode == i_mul) { if (q->dc.left->mode == i_immed && isintconst(q->dc.left->offset)) if (q->temps & TEMP_RIGHT) return InferOffset(q->dc.right) * q->dc.left->offset->v.i; if (q->dc.right->mode == i_immed && isintconst(q->dc.right->offset)) if (q->temps & TEMP_LEFT) return InferOffset(q->dc.left) * q->dc.right->offset->v.i; } } return 0; }
BOOLEAN fittedConst(TYPE *tp, EXPRESSION *exp) { int n; if (!isint(tp) || !isintconst(exp)) return FALSE; n = getSize(basetype(tp)->type); switch (n) { case 8: if (isunsigned(tp)) { if (exp->v.i < 0 || exp->v.i > 255) return FALSE; } else { if (exp->v.i < - 128 || exp->v.i > 127) return FALSE; } break; case 16: if (isunsigned(tp)) { if (exp->v.i < 0 || exp->v.i > 65535) return FALSE; } else { if (exp->v.i < - 32768 || exp->v.i > 32767) return FALSE; } break; default: return TRUE; } }
void fold_const2(ENODE ** node) /* * reorganize an expression for optimal constant grouping. */ { ENODE *ep; long i; ep = *node; if( ep == 0 ) return; switch (ep->nodetype) { case en_add: if (ep->v.p[0]->nodetype == en_cp && isintconst(ep->v.p[0]->v.p[0]->nodetype)) { ep->v.p[0]->v.p[0]->v.i += xfold2(ep->v.p[1]); return; } else if (ep->v.p[1]->nodetype == en_cp && isintconst(ep->v.p[1]->v.p[0]->nodetype)) { ep->v.p[1]->v.p[0]->v.i += xfold2(ep->v.p[1]); return; } else if( isintconst(ep->v.p[0]->nodetype)) { ep->v.p[0]->v.i += xfold2(ep->v.p[1]); return; } else if( isintconst(ep->v.p[1]->nodetype)) { ep->v.p[1]->v.i += xfold2(ep->v.p[0]); return; } break; case en_sub: if (ep->v.p[0]->nodetype == en_cp && isintconst(ep->v.p[0]->v.p[0]->nodetype == en_icon)) { ep->v.p[0]->v.p[0]->v.i -= xfold2(ep->v.p[1]); return; } else if (ep->v.p[1]->nodetype == en_cp && isintconst(ep->v.p[1]->v.p[0]->nodetype)) { ep->v.p[1]->v.p[0]->v.i -= xfold2(ep->v.p[1]); return; } else if( isintconst(ep->v.p[0]->nodetype)) { ep->v.p[0]->v.i -= xfold2(ep->v.p[1]); return; } else if( isintconst(ep->v.p[1]->nodetype)) { ep->v.p[1]->v.i -= xfold2(ep->v.p[0]); return; } break; case en_or: if(isintconst( ep->v.p[0]->nodetype) ) { ep->v.p[0]->v.i |= xfold2(ep->v.p[1]); return; } else if(isintconst( ep->v.p[1]->nodetype) ) { ep->v.p[1]->v.i |= xfold2(ep->v.p[0]); return; } break; case en_xor: if( isintconst(ep->v.p[0]->nodetype)) { ep->v.p[0]->v.i ^= xfold2(ep->v.p[1]); return; } else if( isintconst(ep->v.p[1]->nodetype)) { ep->v.p[1]->v.i ^= xfold2(ep->v.p[0]); return; } break; } i = xfold2(ep); if( i != 0 ) { ep = xalloc(sizeof(ENODE)); ep->nodetype = en_icon; ep->v.i = i; ep = makenode(en_add,ep,*node); *node = ep; } }
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; } }
BOOLEAN isarithmeticconst(EXPRESSION *exp) { return isintconst(exp) || isfloatconst(exp) || isimaginaryconst(exp) || iscomplexconst(exp); }
BOOLEAN isconstzero(TYPE *tp, EXPRESSION *exp) { (void)tp; return (isintconst(exp) && exp->v.i == 0); }
static void HandleAdd(QUAD *head) { if ((head->ans->size == ISZ_ADDR) && (head->temps & TEMP_ANS)) { if (head->dc.opcode == i_add && head->dc.left->mode == i_immed) { if (head->temps & TEMP_RIGHT) { if (isintconst(head->dc.left->offset)) { // C + R ALIASLIST *scan = tempInfo[head->dc.right->offset->v.sp->value.i]->pointsto; ALIASLIST *result = NULL; BOOLEAN xchanged = changed; while (scan) { ALIASADDRESS *addr = LookupAddress(scan->address->name, scan->address->offset + head->dc.left->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = addr; AliasUnion(&result, al); scan = scan->next; } changed = xchanged; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, result); } else { // p + R if (head->dc.left->offset->type != en_labcon) // needed for exports { ALIASNAME *nm = LookupMem(head->dc.left->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; Infer(head->ans, head->dc.right, al); } } } else if (head->dc.right->mode == i_immed) { if (!isintconst(head->dc.left->offset) && head->dc.left->offset->type != en_labcon) { // p + C ALIASNAME *nm = LookupMem(head->dc.left->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, head->dc.right->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto,al); } else if (!isintconst(head->dc.right->offset) && head->dc.right->offset->type != en_labcon) { // C + p ALIASNAME *nm = LookupMem(head->dc.right->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, head->dc.left->offset->v.i); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, al); } } } else if (head->dc.right->mode == i_immed) { if (head->temps & TEMP_LEFT) { if (isintconst(head->dc.right->offset)) { // R+C int c = head->dc.opcode == i_add ? head->dc.right->offset->v.i : -head->dc.right->offset->v.i; ALIASLIST *scan = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; ALIASLIST *result = NULL; BOOLEAN xchanged = changed; while (scan) { ALIASADDRESS *addr = LookupAddress(scan->address->name, scan->address->offset + c); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = addr; AliasUnion(&result, al); scan = scan->next; } changed = xchanged; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, result); } else { // R + p if (head->dc.right->offset->type != en_labcon) // needed for exports { ALIASNAME *nm = LookupMem(head->dc.right->offset->v.sp->imvalue); ALIASADDRESS *aa = LookupAddress(nm, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; Infer(head->ans, head->dc.left, al); } } } } else if ((head ->temps & (TEMP_LEFT | TEMP_RIGHT)) == (TEMP_LEFT | TEMP_RIGHT)) { // R+R ALIASLIST *src; IMODE *one = head->dc.left; IMODE *two = head->dc.right; if (two->size == ISZ_ADDR) { IMODE *three = one; one = two; two = three; } if (one->size == ISZ_ADDR) { // now one has the pointer, two has something else src = tempInfo[one->offset->v.sp->value.i]->pointsto; Infer(head->ans, two, src); } } } }
static void HandleAssn(QUAD *head) { if (head->ans == head->dc.left) return; if (head->ans->mode == i_ind) { if (head->temps & TEMP_LEFT) { // ind, temp ALIASLIST *addr; ALIASLIST *src = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; addr = tempInfo[head->ans->offset->v.sp->value.i]->pointsto; while (addr) { AliasUnion(&addr->address->pointsto, src); addr = addr->next; } } else if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon ) { // ind, immed ALIASLIST *addr; ALIASNAME *an = LookupMem(head->ans->offset->v.sp->imvalue); ALIASADDRESS *aa; if (head->ans->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); addr = tempInfo[head->ans->offset->v.sp->value.i]->pointsto; while (addr) { AliasUnion(&addr->address->pointsto, aa->pointsto); addr = addr->next; } } } else if (head->dc.left->mode == i_ind && (head->temps & TEMP_ANS)) { // temp, ind ALIASLIST *result = NULL; ALIASLIST *addr = tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto; BOOLEAN xchanged = changed; while (addr) { if (addr->address->name->byUIV) { if (!IntersectsUIV(addr->address->pointsto)) { ALIASNAME *an = LookupAliasName(addr->address->name, addr->address->offset); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa; AliasUnion(&addr->address->pointsto, al); } } AliasUnion(&result, addr->address->pointsto); addr = addr->next; } changed = xchanged; tempInfo[head->ans->offset->v.sp->value.i]->pointsto = result; } else if (head->ans->size == ISZ_ADDR) { if (!(head->temps & TEMP_ANS) && !head->ans->retval) { if (head->temps & TEMP_LEFT) { // mem, temp ALIASLIST *al; ALIASNAME *an = LookupMem(head->ans); ALIASADDRESS *aa; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&aa->pointsto, tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto); } else if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon ) { // mem, immed ALIASNAME *an2 = LookupMem(head->dc.left); ALIASADDRESS *aa2 = LookupAddress(an2, 0); ALIASNAME *an = LookupMem(head->ans->offset->v.sp->imvalue); ALIASADDRESS *aa; ALIASLIST *al = aAlloc(sizeof(ALIASLIST)); al->address = aa2; if (head->ans->mode == i_direct) an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&aa->pointsto, al); } } else if (head->temps & TEMP_ANS) { if (head->dc.left->mode == i_immed && head->dc.left->size == ISZ_ADDR && head->dc.left->offset->type != en_labcon&& !isintconst(head->dc.left->offset) ) { // temp, immed BOOLEAN xchanged = changed; ALIASNAME *an = LookupMem(head->dc.left); ALIASADDRESS *aa = LookupAddress(an, 0); ALIASLIST *al = (ALIASLIST *)aAlloc(sizeof(ALIASLIST)); al->address = aa; tempInfo[head->ans->offset->v.sp->value.i]->pointsto = NULL; AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, al); changed = xchanged; } else if (head->dc.left->retval) { AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, parmList); } else if (!(head->temps & TEMP_LEFT) && head->dc.left->mode == i_direct) { // temp, mem ALIASLIST *result = NULL; ALIASNAME *an = LookupMem(head->dc.left); ALIASADDRESS *aa; ALIASLIST *addr; BOOLEAN xchanged = changed; an = LookupAliasName(an, 0); aa = LookupAddress(an, 0); AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, aa->pointsto); changed = xchanged; } else if (head->temps & TEMP_LEFT) { // temp, temp AliasUnion(&tempInfo[head->ans->offset->v.sp->value.i]->pointsto, tempInfo[head->dc.left->offset->v.sp->value.i]->pointsto); } } } }
static char * mangleExpressionInternal (char *buf, EXPRESSION *exp) { while (castvalue(exp)) exp = exp->left; if (isintconst(exp)) { if (exp->type == en_const) { sprintf(buf, "%lld&", exp->v.sp->value.i); } else { sprintf(buf, "%lld&", exp->v.i); } if (buf[0] == '-') buf[0] = '_'; } else { BOOLEAN nonpointer = FALSE; while (lvalue(exp)) { nonpointer = TRUE; exp = exp->left; } switch (exp->type) { case en_nullptr: *buf++ = 'n'; *buf = 0; break; case en_arrayadd: case en_structadd: case en_add: *buf++ = 'p'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_sub: *buf++ = 's'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_mul: case en_umul: case en_arraymul: *buf++ = 'm'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_umod: case en_mod: *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_div: case en_udiv: case en_arraydiv: *buf++ = 'd'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_lsh: case en_arraylsh: *buf++ = 'h'; *buf++ = 'l'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_rsh: case en_ursh: *buf++ = 'h'; *buf++ = 'r'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_cond: *buf++ = 'C'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right->left); buf = mangleExpressionInternal(buf, exp->right->right); *buf = 0; break; case en_assign: *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_eq: *buf++ = 'c'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ne: *buf++ = 'c'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_uminus: *buf++ = 'u'; buf = mangleExpressionInternal(buf, exp->left); break; case en_not: *buf++ = 'l'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); break; case en_compl: *buf++ = 'b'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); *buf = 0; break; case en_ascompl: *buf++ = 'a'; *buf++ = 'n'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ult: case en_lt: *buf++ = 'c'; *buf++ = 'l'; *buf++ = 't'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ule: case en_le: *buf++ = 'c'; *buf++ = 'l'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_ugt: case en_gt: *buf++ = 'c'; *buf++ = 'g'; *buf++ = 't'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_uge: case en_ge: *buf++ = 'c'; *buf++ = 'g'; *buf++ = 'e'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_and: *buf++ = 'b'; *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_land: *buf++ = 'l'; *buf++ = 'a'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_or: *buf++ = 'b'; *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_lor: *buf++ = 'l'; *buf++ = 'o'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_xor: *buf++ = 'b'; *buf++ = 'x'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_autoinc: *buf++ = 'i'; *buf++ = 'p'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_autodec: *buf++ = 'i'; *buf++ = 's'; buf = mangleExpressionInternal(buf, exp->left); buf = mangleExpressionInternal(buf, exp->right); *buf = 0; break; case en_templateselector: { TEMPLATESELECTOR *tsl = exp->v.templateSelector, *find = tsl->next->next; SYMBOL *ts = tsl->next->sym; *buf++ = 't'; *buf++ = 's'; if (tsl->next->isTemplate && tsl->next->templateParams) // may be an empty variadic { buf = mangleTemplate(buf, ts, tsl->next->templateParams); } while (find) { *buf++ = 't'; buf = lookupName(buf, find->name); find = find->next; } *buf = 0; break; } case en_templateparam: *buf++ = 't'; *buf++ = 'p'; buf = lookupName(buf,exp->v.sp->name); *buf = 0; break; case en_funcret: buf = mangleExpressionInternal(buf, exp->left); *buf = 0; break; case en_func: if (exp->v.func->ascall) { INITLIST *args = exp->v.func->arguments; *buf++ = 'f'; buf = lookupName(buf, exp->v.func->sp->name); while(args) { *buf++='f'; buf = mangleExpressionInternal(buf, args->exp); args = args->next; } } else { *buf++ = 'e'; *buf++ = '&'; strcpy(buf, exp->v.func->sp->name); buf += strlen(buf); *buf++ = '$'; buf = mangleType( buf, exp->v.func->sp->tp, TRUE); } break; case en_pc: case en_global: case en_label: case en_const: if (isfunction(exp->v.sp->tp)) { *buf++ = 'e'; *buf++ = '&'; strcpy(buf, exp->v.sp->name); buf += strlen(buf); *buf++ = '$'; buf = mangleType( buf, exp->v.sp->tp, TRUE); } else { *buf++ = 'g'; if (!nonpointer) *buf++ = '&'; strcpy(buf, exp->v.sp->name); *buf++ = '$'; *buf = 0; } break; default: *buf = 0; break; } } buf += strlen(buf); return buf; }
static void scan_gotos(QUAD *head) /* * make a list of goto statements */ { while (head) { switch (head->dc.opcode) { case i_jc: case i_jnc: case i_jbe: case i_ja: case i_je: case i_jne: case i_jge: case i_jg: case i_jle: case i_jl: if (head->dc.left->mode == i_immed && head->dc.right->mode == i_immed && !(chosenAssembler->msil)) { if (isintconst(head->dc.left->offset) && isintconst(head->dc.right->offset)) { LLONG_TYPE l = head->dc.left->offset->v.i; LLONG_TYPE r = head->dc.right->offset->v.i; int ok ; switch (head->dc.opcode) { case i_jc: ok = (ULLONG_TYPE)l < (ULLONG_TYPE)r; break ; case i_jnc: ok = (ULLONG_TYPE)l >= (ULLONG_TYPE)r; break ; case i_jbe: ok = (ULLONG_TYPE)l <= (ULLONG_TYPE)r; break ; case i_ja: ok = (ULLONG_TYPE)l > (ULLONG_TYPE)r; break ; case i_je: ok = l == r; break ; case i_jne: ok = l != r; break ; case i_jge: ok = l >= r; break ; case i_jg: ok = l > r; break ; case i_jle: ok = l <= r; break ; case i_jl: ok = l < r; break ; default: break; } if (ok) { head->dc.opcode = i_goto; head->dc.left = head->dc.right = NULL; head->temps &= ~(TEMP_LEFT | TEMP_RIGHT); } else RemoveInstruction(head); } } case i_swbranch: case i_coswitch: case i_goto: golist[head->dc.v.label - firstLabel] = head; break; default: break; } head = head->fwd; } }