예제 #1
0
void Optimizer::deleteUselessMovs(AsmCode& code){
	for (int i = 0; i < code.size(); i++){
		if (*code[i] != cmdMOV || !code[i]->usedRegister(EAX))
			continue;
		AsmCmd2* cmd = dynamic_cast<AsmCmd2*>(code[i]);
		if (cmd->secondArg()->usedRegister(EAX))
			continue;
		if (*cmd->firstArg() != EAX)
			continue;
		int idx = i + 1;
		bool deletingNedeed = true;
		while (idx < code.size() && deletingNedeed){
			if (code[idx]->usedRegister(EAX))
				if (*code[idx] != cmdMOV)
					deletingNedeed = false;
				else {
					AsmCmd2* tmp = dynamic_cast<AsmCmd2*>(code[idx]);
					if (tmp->secondArg()->usedRegister(EAX)	|| dynamic_cast<AsmIndirectArg*>(tmp->firstArg()))
						deletingNedeed = false;
					else
						break;
				}
			idx++;
		}
		if (deletingNedeed)
			code.deleteRange(i, i);
	}
}
void BinOpNode::generateLvalue(AsmCode& code){
	string value = token->Value;
	if (value == "+"){
		
			SymbolType *type = left->getType();
		if (dynamic_cast<ArraySymbol*>(type))
			left->generateLvalue(code);
		else if (dynamic_cast<PointerSymbol*>(type))
			left->generate(code);
		SymbolType *t = type->upType();
			right->generate(code);
		
			code.add(_POP, _EAX)
				.add(_MOV, _EBX, to_string(t->byteSize()))
				.add(_IMUL, _EAX, _EBX)
				.add(_POP, _EBX)
				.add(_ADD, _EAX, _EBX)
				.add(_PUSH, _EAX);
			t = t->upType();
		
		
	}
	else	if (isAssing(token)){ 
		generate(code);
		code.add(_POP, _EAX);
		left->generateLvalue(code);
	}
	else
		throw MyException("Compiler error");
}
void FuncCallNode::generate(AsmCode& code){
	code.add(_SUB, _ESP, to_string(symbol->value->byteSize()));
	for (int i = args.size() - 1; i > -1; i--)
		args[i]->generate(code);
	code.add(_CALL, new AsmLabelArg("f_" + name->token->Value))
		.add(_ADD, _ESP, to_string(symbol->params->byteSize()));
}
void UnOpNode::generate(AsmCode & code) {
	SymbolType* type = operand->getType();


	string op = token->Value;

	if (op == "++" || op == "--" || op == "*" || op == "&") 
		operand->generateLvalue(code);
	else 
		operand->generate(code);

	if (token->Value == "*"){
		if (dynamic_cast<PointerSymbol*>(type))
			code.add(_POP, _EAX)
				.add(_MOV, new AsmRegArg(_EBX), new AsmIndirectArg(_EAX))
				.add(_PUSH, _EBX);
		else
			code.add(_POP, _EAX)
				.add(_MOV, new AsmRegArg(_EBX), new AsmIndirectArg(_EAX))
				.add(_PUSH, new AsmIndirectArg(_EBX));
		
	}



	else if (token->Value == "!"){

		code.add(_POP, _EAX)
			.add(_XOR, _EBX, _EBX)
			.add(_CMP, _EAX, 0)
			.add(_SETE, _BL)
			.add(_PUSH, _EBX);

	}


	else if (token->Value == "+"){

	}

	else if (token->Value == "-"){
		code.add(_POP, _EAX)
			.add(_NEG, _EAX)
			.add(_PUSH, _EAX);

	}

	else if (token->Value == "++"){
		generateOperationIncDec(type, code, _INC);

	}

	else if (token->Value == "--"){
		generateOperationIncDec(type, code, _DEC);


	}
}
void FuncSymbol::generate(AsmCode &code, const string &str) const {
	code.add(new AsmLabelArg("f_" + str))
		.add(_PUSH, _EBP)
		.add(_MOV, _EBP, _ESP);
	body->generate(code);
	code.add(_MOV, _ESP, _EBP)
		.add(_POP, _EBP)
		.add(_RET, new AsmIntArg("0"));
}
void IdentifierNode::generateLvalue(AsmCode &code) {
	if (var->global)
		code.add(_PUSH, new AsmMemoryArg("var_" + var->name, true));
	else
		code.add(_MOV, _EAX, _EBP)
		.add(_MOV, _EBX, to_string(var->offset))
		.add(_ADD, _EAX, _EBX);
        code.add(_PUSH, _EAX);
}
예제 #7
0
void SymVarGlobal::Generate(AsmCode& asmCode, unsigned) const
{
   if (type->GetSize() > 4) {
      GenerateLValue(asmCode, 0);
      asmCode.PushMemory(type->GetSize());
   } else {
      asmCode.AddCmd(PUSH, AsmMemory(varLabel, 0, szDWORD));
   }
}
예제 #8
0
void IdentifierNode::generateLvalue(AsmCode &code) {
	if(var->global)
		code.add(cmdPUSH, makeArgMemory("var_" + var->name, true));
	else
		code.add(cmdMOV, EAX, EBP)
			.add(cmdMOV, EBX, var->offset)
			.add(cmdADD, EAX, EBX)
			.add(cmdPUSH, EAX);
}
예제 #9
0
bool PushPop2MovOptimization::optimize(AsmCode& code, int index){
	if(	prepare(code[index], code[index + 1]) && *cmd1 == cmdPUSH && *cmd2 == cmdPOP 
		&& !(cmd1->argument()->isMemory() && cmd2->argument()->isMemory())){
		AsmCmd* optCmd = new AsmCmd2(cmdMOV, cmd2->argument(), cmd1->argument());
		code.deleteRange(index, index + 1);
		code.insert(optCmd, index);	
		return true;
	} 
	return false;
}
예제 #10
0
void IdentifierNode::generate(AsmCode &code) {
	int size = var->byteSize();
	int steps = size / 4 + (size % 4 != 0);
	if (var->global)
		for (int i = 0; i < steps; i++)
			code.add(cmdPUSH, makeArgMemory("dword ptr [var_" + var->name + " + " + to_string(4 * (steps - i - 1)) +"]"));
	else
		for (int i = 0; i < steps; i++)
			code.add(cmdPUSH, makeIndirectArg(EBP, var->offset + 4 * (steps - i - 1)));
}
static void generateOperationAssing(SymbolType * type, AsmCode & code, Commands cmd, Registers reg = _EAX) {
	code.add(_POP, _EBX)
		.add(_POP, _ECX);

	if (type->getType() == CharType) {
		code.add(_XOR, _EAX, _EAX)
			.add(_MOV, new AsmRegArg(_AL), new AsmIndirectArg(_ECX));

	}
	else {
		code.add(_MOV, new AsmRegArg(_EAX), new AsmIndirectArg(_ECX));
	}

	code.add(_XOR, _EDX, _EDX);

	if (cmd == _IDIV || cmd == _IMUL) code.add(cmd, _EBX);
	else code.add(cmd, _EAX, _EBX);
	if (type->getType() == CharType) {
	Registers byteReg = reg == _EAX ? _AL : _DL;
		code.add(_MOV, new AsmIndirectArg(_ECX), new AsmRegArg(byteReg))
			.add(_XOR, reg, reg)
			.add(_MOV, new AsmRegArg(byteReg), new AsmIndirectArg(_ECX));

	}
	else {
		code.add(_MOV, new AsmIndirectArg(_ECX), new AsmRegArg(reg));
	}

	code.add(_PUSH, reg);
}
예제 #12
0
bool AddZero2MovOptimization::optimize(AsmCode& code, int index){
	if( prepare(code[index], code[index + 1], code[index + 2])
		&& *cmd1 == cmdMOV && *cmd2 == cmdMOV && *cmd3 == cmdADD 
		&& (*cmd1->secondArg() == 0 || *cmd2->secondArg() == 0)){
			AsmCmd2* optCmd = new AsmCmd2(cmdMOV, cmd3->firstArg(), *cmd1->secondArg() == 0 ? cmd2->secondArg() : cmd1->secondArg());
			code.deleteRange(index, index + 2);
			code.insert(optCmd, index);
			return true;
	} 
	return false;
}
예제 #13
0
bool RegRegCMP2RegIntCmpOptimization::optimize(AsmCode& code, int index){
	if(	prepare(code[index], code[index + 1]) 
		&& *cmd1 == cmdMOV && cmd2 && *cmd2 == cmdCMP
		&& *cmd1->firstArg() == cmd2->secondArg()){
			AsmCmd2* optCmd = new AsmCmd2(cmdCMP, cmd2->firstArg(), cmd1->secondArg());
			code.deleteRange(index, index + 1);
			code.insert(optCmd, index);
			return true;
	} 
	return false;
}
예제 #14
0
bool MovPush2PushOptimization::optimize(AsmCode& code, int index){
	if (prepare(code[index], code[index + 1]) 
		&& *cmd1 == cmdMOV && *cmd1->firstArg() == EAX
		&& *cmd2 == cmdPUSH && *cmd1->firstArg() == cmd2->argument()){
			AsmCmd1* optCmd = new AsmCmd1(cmdPUSH, cmd1->secondArg());
			code.deleteRange(index, index + 1);
			code.insert(optCmd, index);
			return true;
	}  
	return false;
}
static void generateOperation(AsmCode & code, Commands cmd, Registers reg = _EAX) {
	code.add(_POP, _EBX)
		.add(_POP, _EAX)

		.add(_XOR, _EDX, _EDX);

	if (cmd == _IDIV || cmd == _IMUL) code.add(cmd, _EBX);
	else code.add(cmd, _EAX, _EBX);

	code.add(_PUSH, reg);
}
예제 #16
0
bool CompactAdditionOptimization::optimize(AsmCode& code, int index){
	if(	prepare(code[index], code[index + 1], code[index + 2])
		&& *cmd1 == cmdMOV && *cmd2 == cmdMOV && *cmd1->firstArg() == EBX 
		&& *cmd1->secondArg() == cmd2->firstArg() && *cmd3 == cmdADD 
		&& *cmd3->firstArg() == cmd2->firstArg() && *cmd3->secondArg() == cmd1->firstArg()){
			AsmCmd2* optCmd = new AsmCmd2(cmdMOV, makeArg(EBX), cmd2->secondArg());
			code.deleteRange(index, index + 1);
			code.insert(optCmd, index);
			return true;
	} 
	return false;
}
예제 #17
0
bool MovChainOptimization::optimize(AsmCode& code, int index){
	if (prepare(code[index], code[index + 1]) 
		&& *cmd1 == cmdMOV && *cmd1->firstArg() == EAX 
		&& *cmd2 == cmdMOV && *cmd2->secondArg() == cmd1->firstArg()
		&& !(cmd1->secondArg()->isMemory() && cmd2->firstArg()->isMemory()) ){
			AsmCmd* optCmd = new AsmCmd2(cmdMOV, cmd2->firstArg(), cmd1->secondArg());
			code.deleteRange(index, index + 1);
			code.insert(optCmd, index);
			return true;
	}
	return false;
}
예제 #18
0
bool PopToUpPushToDown::Action(AsmCode& code, AsmCmd1* cmd, int i, int inc)
{
    int j = i;
    while (0 < j && j + 1 < code.Size()
        && !UsesStack(code[j + inc])
        && !IsArgument(cmd->GetArgument(), code[j + inc]))
    {
        j += inc;
    }
    code.Move(i, j);
    return j != i;
}
예제 #19
0
bool Neg2MovOppositeOptimization::optimize(AsmCode& code, int index){
	if (prepare(code[index], code[index + 1]) 
		&& *cmd1 == cmdMOV && *cmd1->firstArg() == EAX
		&& *cmd2 == cmdNEG && *cmd2->argument() == EAX
		&& dynamic_cast<AsmImmediateArg*>(cmd1->secondArg())){
			int val = dynamic_cast<AsmImmediateArg*>(cmd1->secondArg())->value;
			AsmCmd2* optCmd = new AsmCmd2(cmdMOV, makeArg(EAX), makeArg(-val));
			code.deleteRange(index, index + 1);
			code.insert(optCmd, index);
			return true;
	}
	return false;
}
예제 #20
0
void Optimizer::pushDownPopUp(AsmCode& code){
	for (int i = 0; i < code.size(); i++){
		AsmCmd1* cmd = dynamic_cast<AsmCmd1*>(code[i]);
		int j = i;
		if (cmd && *cmd == cmdPUSH){			
			while (j + 1 < code.size() && !code[j + 1]->changeStack() && !code[j + 1]->operateWith(cmd->argument()))
				j++;
			code.move(i, j);
		} else if (cmd && *cmd == cmdPOP) {
			while (j - 1 > -1 && !code[j - 1]->changeStack() && !code[j - 1]->operateWith(cmd->argument()))
				j--;
			code.move(i, j);
		}
	}
}
예제 #21
0
void SymVarConst::GenerateValue(AsmCode& asm_code) const
{
    if (value.GetType() == INT_CONST)
    {
        asm_code.AddCmd(ASM_PUSH, value.GetIntValue());
    }
    else if (value.GetType() == REAL_CONST)
    {
        stringstream s;
        s << value.GetName();
        float f;
        int* p = (int*)&f;
        s >> f;
        asm_code.AddCmd(ASM_PUSH, *p);
    }
예제 #22
0
bool MultIntByInt2MovOptimization::optimize(AsmCode& code, int index){
	if(	prepare(code[index], code[index + 1], code[index + 2])
		&& *cmd1 == cmdMOV && *cmd2 == cmdMOV
		&& *cmd1->firstArg() == EAX && *cmd2->firstArg() == EBX
		&& cmd1->secondArg()->isImmediate() && cmd2->secondArg()->isImmediate()
		&& *cmd3 == cmdIMUL){
			int val1 = dynamic_cast<AsmImmediateArg*>(cmd1->secondArg())->value,
				val2 = dynamic_cast<AsmImmediateArg*>(cmd2->secondArg())->value;
			AsmCmd2* optCmd = new AsmCmd2(cmdMOV, cmd3->firstArg(), makeArg(val1 * val2));
			code.deleteRange(index, index + 2);
			code.insert(optCmd, index);
			return true;
	}
	return false;
}
예제 #23
0
//-----------------------------------------------------------------------------
bool AddSubZero::Optimize(AsmCode& code, int index)
{
    if (index == code.Size())
    {
        return false;
    }

    AsmCmd2* cmd = dynamic_cast<AsmCmd2*>(code[index]);
    if (cmd && (*cmd == cmdSUB || *cmd == cmdADD) && *cmd->GetSecond() == "0")
    {
        code.Delete(index);
        return true;
    }

    return false;
}
예제 #24
0
bool AddSubESPZeroOptimization::optimize(AsmCode &code, int index){
	if (prepare(code[index]) && *cmd1->firstArg() == ESP && *cmd1->secondArg() == 0){
		code.deleteRange(index, index);
		return true;
	}
	return false;
}
static void generateOperationShift(AsmCode & code, Commands cmd) {
	code.add(_POP, _EAX)
		.add(_POP, _EBX)
		.add(_MOV, _ECX, _EAX)
		.add(cmd, _EBX, _CL)
		.add(_PUSH, _EBX);
}
예제 #26
0
bool Jmp2NextLineOptimization::optimize(AsmCode& code, int index){
	if (prepare(code[index], code[index + 1]) && *cmd1->argument() == cmd2->label){
		code.deleteRange(index, index);
		return true;
	}
	return false;	
}
void ArrNode::generate(AsmCode &code){
    generateLvalue(code);
	code.add(_PUSH, new AsmIndirectArg(_EAX))
		.add(_POP, _EAX)
		.add(_POP, _ECX)
		.add(_PUSH, new AsmRegArg(_EAX));

}
예제 #28
0
bool PushPop2NilOptimization::optimize(AsmCode& code, int index){
	if(	prepare(code[index], code[index + 1]) && *cmd1 == cmdPUSH && *cmd2 == cmdPOP 
		&& cmd1->argument()->isRegister() && *cmd1->argument() == cmd2->argument())	{
			code.deleteRange(index, index + 1);
			return true;
	}
	return false;
}
static void generateCmp(AsmCode & code, Commands cmd) {
	code.add(_POP, _EBX)
		.add(_POP, _EAX)
		.add(_XOR, _ECX, _ECX)
		.add(_CMP, _EAX, _EBX)
		.add(cmd, _CL)
		.add(_PUSH, _ECX);
}
static void generateOperationIncDec(SymbolType* type, AsmCode & code, Commands cmd) {
	code.add(_POP, _EAX);

	if (type->getType() == CharType) {
		code.add(_XOR, _EBX, _EBX)
			.add(_MOV, new AsmRegArg(_BL), new AsmIndirectArg(_EAX));

	}
	else {
		code.add(_MOV, new AsmRegArg(_EBX), new AsmIndirectArg(_EAX));
	}

	code.add(cmd, _EBX);

	if (type->getType() == CharType) {
		code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_BL))
			.add(_XOR, _EBX, _EBX)
			.add(_MOV, new AsmRegArg(_BL), new AsmIndirectArg(_EAX))
			.add(_PUSH, new AsmRegArg(_EAX));


	}
	else {
		code.add(_MOV, new AsmIndirectArg(_EAX), new AsmRegArg(_EBX));
	}

	code.add(_PUSH, _EBX);
}