Пример #1
0
 /* 折半查找 */
static void TranslateSwitchBuckets (SwitchBucket *bucketArray, int left, int right, Symbol choice, BBlock currBB, BBlock defBB)
{
	int     mid, len, i;
	AstCaseStatement p;
	BBlock  lhalfBB, rhalfBB;
	BBlock  *dstBBs;
	Symbol  index;

	if (left > right)
		return;

	mid = (left + right) / 2;
	lhalfBB = (left > mid - 1) ?  defBB : CreateBBlock();
	rhalfBB = (mid + 1 > right) ? defBB : CreateBBlock();

	len = bucketArray[mid]->maxVal - bucketArray[mid]->minVal + 1;

	dstBBs = HeapAllocate (CurrentHeap, (len + 1)* sizeof(BBlock));
	for (i = 0; i < len; ++i)
		dstBBs[i] = defBB;
	dstBBs[len] = NULL;

	for (p = bucketArray[mid]->cases; p; p = p->nextCase) { 

		i = p->expr->val.i[0] - bucketArray[mid]->minVal;
		dstBBs[i] = p->respBB;
	}

	if (currBB != NULL) {

		StartBBlock (currBB);
	}
	GenerateBranch (choice->ty, lhalfBB, JL, choice, IntConstant (bucketArray[mid]->minVal));
	StartBBlock (CreateBBlock());
	GenerateBranch (choice->ty, rhalfBB, JG, choice, IntConstant (bucketArray[mid]->maxVal));
	StartBBlock (CreateBBlock());

	if (len != 1) {

		index = CreateTemp (choice->ty);
		GenerateAssign (choice->ty, index, SUB, choice, IntConstant (bucketArray[mid]->minVal));
		GenerateIndirectJump (dstBBs, len, index);
	} else {

		GenerateJump (dstBBs[0]);
	}

	StartBBlock (CreateBBlock ());

    /* 二分递归 */
	TranslateSwitchBuckets (bucketArray, left, mid - 1, choice, lhalfBB, defBB);
	TranslateSwitchBuckets (bucketArray, mid + 1, right, choice, rhalfBB, defBB);
}
Пример #2
0
void Compiler::EmitCall(IRInst inst)
{
	ParameterList argslist = (ParameterList)SRC2;
	Symbol arg;
	int i, stksize = 0;

	for (i = argslist->npara - 1; i >= 0; i--)
	{
		arg = argslist->args[i];
		PushArgument(arg);
		stksize += sizeof(int) * 1;
	}
	// call func
	PutASMCode(X86_CALL, inst->opds);

	// 如果参数不为0, 则返回时需要复原栈顶
	if (stksize != 0) {
		Symbol p;
		p = IntConstant(stksize);
		PutASMCode(X86_REDUCEF, &p);
	}

	if (DST) DST->ref--;
	// 这里DST 不会 DST == NULL,因为根据要求为ID = call ID.

	//函数返回值放在EAX
	//AllocateReg(inst, 0);
	//if (DST->reg != Regs[EAX])
	//{
	//	Move(DST, Regs[EAX]);
	//}
	DST->reg = Regs[EAX];
}
Пример #3
0
void Compiler::EmitPrologue(int varsize)
{
	PutASMCode(PROLOGUE, NULL);

	if (varsize != 0) {
		Symbol sym = IntConstant(varsize*sizeof(int));
		PutASMCode(EXPANDF, &sym);
	}
}
Пример #4
0
/* 
 * ClearInst    -> Clear VarName, constant
 * */
void GenerateClear (Symbol dst, int size)
{
	IRInst inst;

	CALLOC (inst);
	dst->ref++;
	inst->ty      = T(UCHAR);
	inst->opcode  = CLR;
	inst->opds[0] = dst;
	inst->opds[1] = IntConstant (size);
	inst->opds[1]->ref++;
	inst->opds[2] = NULL;
	AppendInst (inst);
}
Пример #5
0
/**
 * Perform algebraic simplification and strenth reduction
 */
Symbol Simplify(Type ty, int opcode, Symbol src1, Symbol src2)
{
	VariableSymbol t;
	Symbol p1, p2;
	int c1, c2;

	if (IsRealType(ty))
		goto add_value;

	if (src2 == NULL || (src2->kind != SK_Constant && opcode != SUB))
		goto add_value;

	switch (opcode)
	{
	case ADD:
		// a + 0 = a
		if (src2->val.i[0] == 0)
			return src1;

		// a + c1 + c2 = a + (c1 + c2)
		// a - c1 + c2 = a + (-c1 + c2)
		p1 = src1; c1 = 0;
		if (src1->kind == SK_Temp)
		{
			t = AsVar(src1);

			if (t->def->src2 && t->def->src2->kind == SK_Constant && 
			    (t->def->op == ADD || t->def->op == SUB))
			{
				p1 = t->def->src1;
				c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0];
			}
		}
		if (c1 != 0)
		{
			src1 = p1;
			src2 = IntConstant(c1 + src2->val.i[0]);
		}
		break;

	case SUB:
		// a - 0 = a
		if (src2->kind == SK_Constant && src2->val.i[0] == 0)
			return src1;

		// put source operand into v + c format (v maybe NULL, c maybe 0)
		p1 = src1; c1 = 0;
		if (src1->kind == SK_Temp)
		{
			t = AsVar(src1);
			if (t->def->src2 && t->def->src2->kind == SK_Constant && 
			    (t->def->op == ADD || t->def->op == SUB))
			{
				p1 = t->def->src1;
				c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0];
			}
		}
		else if (src1->kind == SK_Constant)
		{
			p1 = NULL;
			c1 = src1->val.i[0];
		}
		p2 = src2; c2 = 0;
		if (src2->kind == SK_Temp)
		{
			t = AsVar(src2);
			if (t->def->src2 && t->def->src2->kind == SK_Constant && 
			    (t->def->op == ADD || t->def->op == SUB))
			{
				p2 = t->def->src1;
				c2 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0];
			}
		}
		else if (src2->kind == SK_Constant)
		{
			p2 = NULL;
			c2 = src2->val.i[0];
		}

		if (p1 == p2)
		{
			// (a + c1) - (a + c2) = c1 - c2
			return IntConstant(c1 - c2);
		}
		else if (p1 == NULL)
		{
			// c1 - (a + c2) = (c1 - c2) - a
			src1 = IntConstant(c1 - c2);
			src2 = p2;
		}
		else if (p2 == NULL)
		{
			// (a + c1) - c2 = a + (c1 - c2)
			src1 = p1;
			opcode = ADD;
			src2 = IntConstant(c1 - c2);
		}
		break;

	case MUL:
	case DIV:
		// a * 1 = a; a / 1 = a;
		if (src2->val.i[0] == 1)
			return src1;

		// a * 2 power of n = a >> n
		c1 = Power2(src2->val.i[0]);
		if (c1 != 0)
		{
			src2 = IntConstant(c1);
			opcode = opcode == MUL ? LSH : RSH;
		}
		break;

	case MOD:
		// a % 1 = 0
		if (src2->val.i[0] == 1)
			return IntConstant(0);

		// a % 2 power of n = a & (2 power of n - 1)
		c1 = Power2(src2->val.i[0]);
		if (c1 != 0)
		{
			src2 = IntConstant(src2->val.i[0] - 1);
			opcode = BAND;
		}
		break;

	case LSH:
	case RSH:
		// a >> 0 = a << 0 = a
		if (src2->val.i[0] == 0)
			return src1;
		break;

	case BOR:
		// a | 0 = a; a | -1 = -1
		if (src2->val.i[0] == 0)
			return src1;
		if (src2->val.i[0] == -1)
			return src2;
		break;

	case BXOR:
		// a ^ 0 = a
		if (src2->val.i[0] == 0)
			return src1;
		break;

	case BAND:
		// a & 0 = 0, a & -1 = a
		if (src2->val.i[0] == 0)
			return IntConstant(0);
		if (src2->val.i[0] == -1)
			return src1;
		break;

	default:
		break;
	}

add_value:
	return TryAddValue(ty, opcode, src1, src2);
}
Пример #6
0
/* 算数优化 */
Symbol Simplify (Type ty, int opcode, Symbol src1, Symbol src2)
{
	VariableSymbol  t;
	Symbol          p1, p2;
	int             c1, c2;

    /* 浮点 */
	if (IsRealType (ty))
		goto add_value;

	if (src2 == NULL || (src2->kind != SK_Constant && opcode != SUB))
		goto add_value;

    /* 以下是 加, 减, 乘, 除, 取余, 左移, 右移, 按位操作的优化 */
	switch (opcode) {

    	case ADD: {
		
            /* a + 0 = a */
		    if (src2->val.i[0] == 0)
			    return src1;

		    /* a + c1 + c2 = a + (c1 + c2) */
    		/* a - c1 + c2 = a + (-c1 + c2) */
		    p1 = src1; c1 = 0;
    		if (src1->kind == SK_Temp) {

                t = AsVar(src1);
    			if (t->def->src2 && t->def->src2->kind == SK_Constant && 
    			    (t->def->op == ADD || t->def->op == SUB)) {

    				p1 = t->def->src1;
	    			c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0];
			    }
		    }
		
            if (c1 != 0) {

    			src1 = p1;
                /* 合并c1, c2 */
	    		src2 = IntConstant (c1 + src2->val.i[0]);
		    }
        }break;

    	case SUB: {

    		/* a - 0 = a */
	    	if (src2->kind == SK_Constant && src2->val.i[0] == 0)
		    	return src1;

    		// put source operand into v + c format (v maybe NULL, c maybe 0)
    		p1 = src1; c1 = 0;
	    	if (src1->kind == SK_Temp) {

    			t = AsVar(src1);
	    		if (t->def->src2 && t->def->src2->kind == SK_Constant && 
		    	    (t->def->op == ADD || t->def->op == SUB)) {

    				p1 = t->def->src1;
	    			c1 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0];
		    	}
		    } else if (src1->kind == SK_Constant) {

    			p1 = NULL;
	    		c1 = src1->val.i[0];
		    }

    		p2 = src2; c2 = 0;
	    	if (src2->kind == SK_Temp) {

    			t = AsVar(src2);
	    		if (t->def->src2 && t->def->src2->kind == SK_Constant && 
		    	    (t->def->op == ADD || t->def->op == SUB)) {

    				p2 = t->def->src1;
	    			c2 = (t->def->op == ADD ? 1 : -1) * t->def->src2->val.i[0];
		    	}
		    } else if (src2->kind == SK_Constant) {

    			p2 = NULL;
	    		c2 = src2->val.i[0];
		    }

		    if (p1 == p2) {

    			/* (a + c1) - (a + c2) = c1 - c2 */
	    		return IntConstant (c1 - c2);
		    } else if (p1 == NULL) {

                /* c1 - (a + c2) = (c1 - c2) - a */
			    src1 = IntConstant (c1 - c2);
			    src2 = p2;
		    } else if (p2 == NULL) {

    			/* (a + c1) - c2 = a + (c1 - c2) */
	    		src1    = p1;
		    	opcode  = ADD;
			    src2    = IntConstant(c1 - c2);
		    }
        }break;

    	case MUL: case DIV: {

    		/* a * 1 = a; a / 1 = a; */
	    	if (src2->val.i[0] == 1)
		    	return src1;

    		/* a * 2 power of n = a >> n */
	    	c1 = Power2 (src2->val.i[0]);
		    if (c1 != 0) {
			
                /* 转换乘除为位移操作 */
                src2   = IntConstant (c1);
			    opcode = opcode == MUL ? LSH : RSH;
		    }
        }break;

	    case MOD: {

		    /* a % 1 = 0 */
		    if (src2->val.i[0] == 1)
			    return IntConstant (0);

    		/* a % 2 power of n = a & (2 power of n - 1) */
	    	c1 = Power2 (src2->val.i[0]);
		    if (c1 != 0) {

    			src2 = IntConstant (src2->val.i[0] - 1);
	    		opcode = BAND;
		    }
        }break;

    	case LSH: case RSH: {

    		/* a >> 0 = a << 0 = a */
	    	if (src2->val.i[0] == 0)
		    	return src1;
    	}break;

    	case BOR: {

            /* a | 0 = a; a | -1 = -1 */
    		if (src2->val.i[0] == 0)
	    		return src1;
		    if (src2->val.i[0] == -1)
			    return src2;
        }break;

    	case BXOR: {
	
            /* a ^ 0 = a */
		    if (src2->val.i[0] == 0)
    			return src1;
        }break;

    	case BAND: {

            /* a & 0 = 0, a & -1 = a */
    		if (src2->val.i[0] == 0)
	    		return IntConstant(0);
            if (src2->val.i[0] == -1)
			    return src1;
        }break;

    	default: break;
	}

add_value:
    /* 构造值添加到符号表中,并返回 */
	return TryAddValue (ty, opcode, src1, src2);
}