⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tobin.cpp

📁 一个用C++实现的C的Compiler。 代码风格良好。 原作者自己写了这个编译器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
{
	number = to_unsign_number(number);
	if (number < 256)
	{
		ASM_LI(reg, number, p);
	}
	else
	{
		int hi = number / 256;
		int lo = number % 256;
		if (lo >= 128)
		{
			hi = (hi + 1) % 256;
		}
		ASM_LI(reg, hi, p);
		ASM_SLL(reg, reg, 0, p);
		ASM_ADDIU(reg, lo, p);
	}
}

int bin_single_op(string& op, int target_var, int var1, int var2, list <TBinEntry> :: iterator p)
{
	if (op == "ADD")
	{
		ASM_ADDU(var1, var2, target_var, p);
	}
	else if (op == "SUB")
	{
		ASM_SUBU(var1, var2, target_var, p);
	}
	else if (op == "MUL")
	{
		ASM_MULTU(var1, var2, p);
		ASM_MFLO(target_var, p);
	}
	else if (op == "DIV")
	{
		ASM_DIVU(var1, var2, p);
		ASM_MFLO(target_var, p);
	}
	else if (op == "MOD")
	{
		ASM_DIVU(var1, var2, p);
		ASM_MFHI(target_var, p);
	}
	else if (op == "NOT")
	{
		ASM_NOT(target_var, var1, p);
	}
	else if (op == "OR")
	{
		if (target_var == var1)
		{
			ASM_OR(target_var, var2, p);
		}
		else if (target_var == var2)
		{
			ASM_OR(target_var, var1, p);
		}
		else
		{
			ASM_MOVE(target_var, var1, p);
			ASM_OR(target_var, var2, p);
		}
	}
	else if (op == "AND")
	{
		if (target_var == var1)
		{
			ASM_AND(target_var, var2, p);
		}
		else if (target_var == var2)
		{
			ASM_AND(target_var, var1, p);
		}
		else
		{
			ASM_MOVE(target_var, var1, p);
			ASM_AND(target_var, var2, p);
		}
	}
	else if (op == "XOR")
	{
		if (target_var == var1)
		{
			ASM_XOR(target_var, var2, p);
		}
		else if (target_var == var2)
		{
			ASM_XOR(target_var, var1, p);
		}
		else
		{
			ASM_MOVE(target_var, var1, p);
			ASM_XOR(target_var, var2, p);
		}
	}
	else if (op == "SHL")
	{
		if (target_var == var1)
		{
			ASM_SLLV(var2, target_var, p);
		}
		else if (target_var == var2)
		{
			ASM_SLLV(var1, target_var, p);
		}
		else
		{
			ASM_MOVE(target_var, var1, p);
			ASM_SLLV(var2, target_var, p);
		}
	}
	else if (op == "SHR")
	{
		if (target_var == var1)
		{
			ASM_SRLV(var2, target_var, p);
		}
		else if (target_var == var2)
		{
			ASM_SRLV(var1, target_var, p);
		}
		else
		{
			ASM_MOVE(target_var, var1, p);
			ASM_SRLV(var2, target_var, p);
		}
	}
	else if (op == "JMP")
	{
		ASM_B_TEMP(target_var, p);
	}
	else if (op == "JE")
	{
//		printf("HERE\n");
		ASM_SUBU(var1, var2, RegCount, p);
		ASM_BEQZ_TEMP(RegCount, target_var, p);
	}
	else if (op == "JNE")
	{
		ASM_SUBU(var1, var2, RegCount, p);
		ASM_BNEZ_TEMP(RegCount, target_var, p);
	}
	else if (op == "JL")
	{
		ASM_SLTU(var1, var2, p);
		ASM_BTNEZ_TEMP(target_var, p);
	}
	else if (op == "JG")
	{
		ASM_SLTU(var2, var1, p);
		ASM_BTNEZ_TEMP(target_var, p);
	}
	else if (op == "JLE")
	{
		ASM_SLTU(var2, var1, p);
		ASM_BTEQZ_TEMP(target_var, p);
	}
	else if (op == "JGE")
	{
		ASM_SLTU(var1, var2, p);
		ASM_BTEQZ_TEMP(target_var, p);
	}
	else
	{
		printf("Unkown operator : %s\n", op.c_str());
		exit(0);
	}
	return 0;
}

int computation_calc_unary(string& op, int num)
{
	if (op == "NOT")
	{
		num ^= maxword;
		return num;
	}
	printf("Unkown unary operator : %s\n", op.c_str());
	exit(0);
}

int computation_calc(string& op, int num1, int num2)
{
	if (op == "ADD")
	{
		return num1 + num2;
	}
	else if (op == "SUB")
	{
		return num1 - num2;
	}
	else if (op == "MUL")
	{
		return num1 * num2;
	}
	else if (op == "DIV")
	{
		return num1 / num2;
	}
	else if (op == "MOD")
	{
		return num1 % num2;
	}
	else if (op == "AND")
	{
		return num1 & num2;
	}
	else if (op == "OR")
	{
		return num1 | num2;
	}
	else if (op == "XOR")
	{
		return num1 ^ num2;
	}
	else if (op == "SHL")
	{
		return num1 << num2;
	}
	else if (op == "SHR")
	{
		return num1 >> num2;
	}
	printf("Unknown operator : %s\n", op.c_str());
	exit(0);
}

int jump_calc(string& op, int num1, int num2)
{
	if (op == "JE")
	{
		return (num1 == num2);
	}
	else if (op == "JNE")
	{
		return (num1 != num2);
	}
	else if (op == "JL")
	{
		return (num1 < num2);
	}
	else if (op == "JLE")
	{
		return (num1 <= num2);
	}
	else if (op == "JG")
	{
		return (num1 > num2);
	}
	else if (op == "JGE")
	{
		return (num1 >= num2);
	}
	printf("Unknown operator : %s\n", op.c_str());
	exit(0);
}

void parse_tac_var(string& str, int var[], int num[], int& var_count, int& num_count)
{
	if (str != "(null)")
	{
		if (str[0] == 'v')
		{
			sscanf(str.c_str(), "v%d", var + var_count ++);
		}
		else
		{
			sscanf(str.c_str(), "%d", num + num_count ++);
		}
	}
}

void build_computation_op(list <TTACEntry> :: iterator p)
{
	int var[2], num[2];
	int var_count = 0, num_count = 0, target_reg;

	sscanf(p->var1.c_str(), "v%d", &target_reg);
	parse_tac_var(p->var2, var, num, var_count, num_count);
	parse_tac_var(p->var3, var, num, var_count, num_count);

	target_reg = tempvar2reg(target_reg, p->phi3);
	for (int i = 0; i < var_count; i ++) 
	{
		var[i] = tempvar2reg(var[i], p->phi2);
	}

	if (p->op == "NOT")
	{
		if (var_count == 0)
		{
			int number = computation_calc_unary(p->op, num[0]);
			bin_load_immediate(target_reg, number, bincode.end());
		}
		else
		{
			bin_single_op(p->op, target_reg, var[0], -1, bincode.end());
		}
	}
	else
	{
		if (var_count == 0)
		{
			int number = computation_calc(p->op, num[0], num[1]);
			bin_load_immediate(target_reg, number, bincode.end());
		}
		else if (var_count == 1)
		{
			bin_load_immediate(RegCount, num[0], bincode.end());
			if (num[0] == 0 && p->op == "ADD")
			{
				if (target_reg != var[0])
				{
					ASM_MOVE(target_reg, var[0], bincode.end());
				}
			}
			else
			{
				if (p->var2[0] != 'v')
				{
					bin_single_op(p->op, target_reg, RegCount, var[0], bincode.end());
				}
				else
				{
					bin_single_op(p->op, target_reg, var[0], RegCount, bincode.end());
				}
			}
		}
		else 
		{
			bin_single_op(p->op, target_reg, var[0], var[1], bincode.end());
		}
	}
}

void build_jump_op(list <TTACEntry> :: iterator p)
{
	int var[2], num[2];
	int var_count = 0, num_count = 0;

	if (p->op != "JMP")
	{
		parse_tac_var(p->var1, var, num, var_count, num_count);
		parse_tac_var(p->var2, var, num, var_count, num_count);

		for (int i = 0; i < var_count; i ++) 
		{
			var[i] = tempvar2reg(var[i], p->phi2);
		}

		int label_name;
		sscanf(p->var3.c_str(), "L%d", &label_name);
		if (var_count == 0)
		{
			int jmp = jump_calc(p->op, num[0], num[1]);
			if (jmp)
			{
				p->op = "JMP";
				p->var1 = p->var3;
			}
			else
			{
				p->op = "NOP";
				p->use.clear(); p->def.clear();
			}
		}
		else if (var_count == 1)
		{
			if (num[0] == 0 && (p->op == "JE" || p->op == "JNE"))
			{
				if (p->op == "JE")
				{
					ASM_BEQZ_TEMP(var[0], label_name, bincode.end());
				}
				else
				{
					ASM_BNEZ_TEMP(var[0], label_name, bincode.end());
				}
			}
			else
			{
				bin_load_immediate(RegCount, num[0], bincode.end());
				if (p->var1[0] != 'v')
				{
					bin_single_op(p->op, label_name, RegCount, var[0], bincode.end());
				}
				else
				{
					bin_single_op(p->op, label_name, var[0], RegCount, bincode.end());
				}
			}
		}
		else 
		{
			bin_single_op(p->op, label_name, var[0], var[1], bincode.end());
		}
	}
	if (p->op == "JMP")
	{
		int label_name;
		sscanf(p->var1.c_str(), "L%d", &label_name);
		bin_single_op(p->op, label_name, -1, -1, bincode.end());
	}
}

void build_loadstore(list <TTACEntry> :: iterator p)
{
	int var[2], num[2];
	int var_count = 0, num_count = 0, target_reg;

	if (p->op == "LOAD")
	{
		sscanf(p->var1.c_str(), "v%d", &target_reg);
		if (VarEntry[target_reg].var_type >= 0)
		{
			printf("Attempt to LOAD a non-basic typed variable.\n");
			exit(0);
		}
		parse_tac_var(p->var2, var, num, var_count, num_count);

		target_reg = tempvar2reg(target_reg, p->phi3);
		for (int i = 0; i < var_count; i ++) 
		{
			var[i] = tempvar2reg(var[i], p->phi2);
		}

		if (var_count == 0)
		{
			bin_load_immediate(RegCount, num[0], bincode.end());
			ASM_LW(RegCount, target_reg, 0, bincode.end());
		}
		else
		{
			ASM_LW(var[0], target_reg, 0, bincode.end());
		}
	}
	else if (p->op == "STORE")
	{
		if (p->var2[0] != 'v')
		{
			printf("Second argument of STORE operation is not a variable.\n");
			exit(0);
		}
		else
		{
			int tmpvar_name;
			sscanf(p->var2.c_str(), "%v%d", &tmpvar_name);
			if (VarEntry[tmpvar_name].var_type >= 0)
			{
				printf("Attempt to STORE a non-basic typed variables.\n");
				exit(0);
			}
		}
		parse_tac_var(p->var1, var, num, var_count, num_count);
		parse_tac_var(p->var2, var, num, var_count, num_count);

		for (int i = 0; i < var_count; i ++) 
		{
			var[i] = tempvar2reg(var[i], p->phi2);
		}
		if (var_count == 1)
		{
			bin_load_immediate(RegCount, num[0], bincode.end());
			ASM_SW(RegCount, var[0], 0, bincode.end());
		}
		else
		{
			ASM_SW(var[0], var[1], 0, bincode.end());
		}
	}
	else
	{
		printf("Unknown operator : %s\n", p->op.c_str());
		exit(0);
	}
}

void build_lea(int func_name, list <TTACEntry> :: iterator p)
{
	int var[2], num[2];
	int var_count = 0, num_count = 0;
	parse_tac_var(p->var1, var, num, var_count, num_count);
	parse_tac_var(p->var2, var, num, var_count, num_count);
	
	if (var_count != 2)
	{
		printf("Arguments of LEA operation must be variables.\n");
		exit(0);
	}
	var[0] = tempvar2reg(var[0], p->phi3);

	if (VarEntry[var[1]].var_class == var_class_global_var)
	{
		bin_load_global_var(var[0], VarEntry[var[1]].offset, bincode.end());
	}
	else if (VarEntry[var[1]].var_class == var_class_func_var)
	{
		ASM_MOVE(var[0], RegCount + 1, bincode.end());
		ASM_ADDIU(var[0], __get_sizeof(var_type_uint16) + __get_sizeof(var_type_uint16) * 2 + VarEntry[var[1]].offset, bincode.end());
	}
	else if (VarEntry[var[1]].var_class == var_class_temp_var && VarEntry[var[1]].lea_marked)
	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -