Example #1
0
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]);
        }
    }
}
Example #2
0
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);
}
Example #3
0
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;
    }
}
Example #4
0
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;
            }
        }
    }
}
Example #5
0
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;
}
Example #6
0
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;
}
Example #7
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;
    }
}
Example #8
0
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;
        }
}
Example #9
0
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;
                }
}
Example #10
0
BOOLEAN isarithmeticconst(EXPRESSION *exp)
{
    return isintconst(exp) || isfloatconst(exp) || isimaginaryconst(exp) ||
        iscomplexconst(exp);
}
Example #11
0
BOOLEAN isconstzero(TYPE *tp, EXPRESSION *exp)
{
    (void)tp;
    return (isintconst(exp) && exp->v.i == 0);
}
Example #12
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);
            }
        }
    }
}
Example #13
0
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);
            }
        }
    }
}
Example #14
0
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;
}
Example #15
0
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;
    }
}