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

📄 tobin.cpp

📁 一个用C++实现的C的Compiler。 代码风格良好。 原作者自己写了这个编译器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
		ASM_MOVE(var[0], RegCount + 1, bincode.end());
		int offset = FuncEntry[func_name].determined_size - (VarEntry[var[1]].offset - FuncEntry[func_name].parameter_size);
//		printf("here %d\n", -offset);
		ASM_ADDIU(var[0], -offset, bincode.end());
	}
	else
	{
		printf("Invalid type of second argument of LEA operation.\n");
		exit(0);
	}
}

void build_push(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);
	if (var_count != 1)
	{
		printf("Argument of PUSH operation must be variable.\n");
		exit(0);
	}
	var[0] = tempvar2reg(var[0], p->phi2);
//	printf("PPPPPPPUUUUUUUUUUSSSSSSSSSHHHHHHHH %d\n", var[0]);
	ASM_ADDIU_SP(-1 * __get_sizeof(var_type_uint16), bincode.end());
	ASM_SW_SP(var[0], 0, bincode.end());
//	p->print();
//	if (var[0] == 7)
//		printf("push\n");
}

void build_pop(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);
	if (num_count != 1)
	{
		printf("Argument of POP operation must be constant.\n");
		exit(0);
	}
	if (num[0] > 127)
	{
		printf("Argument of POP operation must be no larger than 127.\n");
	}
	ASM_ADDIU_SP(num[0], bincode.end());
//	p->print();
//	printf("pop\n");
}

void build_ricall(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 RICALL operation must be variables.\n");
		exit(0);
	}
	var[1] = tempvar2reg(var[1], p->phi2);
	var[0] = tempvar2reg(var[0], p->phi3);

	ASM_ADDIU_SP(- __get_sizeof(var_type_uint16) * 2, bincode.end());
	ASM_MFPC(RegCount, bincode.end());
	ASM_ADDIU(RegCount, 4, bincode.end());
	ASM_SW_SP(RegCount, 0, bincode.end());
	ASM_JR(var[1], bincode.end());
	ASM_LW_SP(var[0], __get_sizeof(var_type_uint16), bincode.end());
	ASM_ADDIU_SP(__get_sizeof(var_type_uint16) * 2, bincode.end());
}

void build_ret(int func_name, list <TTACEntry> :: iterator p)
{
	ASM_ADDIU_SP(FuncEntry[p->func_name].determined_size + (FuncEntry[p->func_name].max_color + 1) * __get_sizeof(var_type_uint16), bincode.end());
	ASM_LW_SP(RegCount + 1, 0, bincode.end());
	ASM_ADDIU_SP(__get_sizeof(var_type_uint16), bincode.end());

	if (IDHash_int2ID(func_name) == "main" && !kernel_mode)
	{
		if (p->op == "RET")
		{
			int var[2], num[2];
			int var_count = 0, num_count = 0;
			parse_tac_var(p->var1, var, num, var_count, num_count);
			if (var_count == 1)
			{
				var[0] = tempvar2reg(var[0], p->phi2);
				ASM_MOVE(2, var[0], bincode.end());
			}
			else
			{
				ASM_LI(2, num[0], bincode.end());
			}
		}
		else
			ASM_LI(2, 0, bincode.end());
		ASM_LI(0, 0, bincode.end());
		ASM_INT(3, bincode.end());
	}
	else
	{
		if (p->op == "RET")
		{
			int var[2], num[2];
			int var_count = 0, num_count = 0;
			parse_tac_var(p->var1, var, num, var_count, num_count);
			if (var_count == 1)
			{
	//			printintlist(p->use); printf("\n");
	//			for (int i = 0; i < RegCount; i ++) printf("%d\t", p->phi2[i]);
	//			printf("\n");
				var[0] = tempvar2reg(var[0], p->phi2);
				ASM_SW_SP(var[0], __get_sizeof(var_type_uint16), bincode.end());
			}
			else
			{
				bin_load_immediate(RegCount, num[0], bincode.end());
				ASM_SW_SP(RegCount, __get_sizeof(var_type_uint16), bincode.end());
			}
		}
		ASM_LW_SP(RegCount, 0, bincode.end());
		ASM_JR(RegCount, bincode.end());
	}
}

void build_leafunc(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);
	if (var_count != 1)
	{
		printf("The first argument of LEAFUNC operation must be varaible.\n");
		exit(0);
	}
	var[0] = tempvar2reg(var[0], p->phi3);

	int func_id = IDHash_ID2int(p->var2);
	bin_load_funcaddr(var[0], func_id, bincode.end());
}

void build_begin(list <TTACEntry> :: iterator p)
{
//	printf("begin : %d\n", FuncEntry[p->func_name].determined_size);
	ASM_ADDIU_SP(- __get_sizeof(var_type_uint16), bincode.end());
	ASM_SW_SP(RegCount + 1, 0, bincode.end());
	ASM_ADDIU_SP_30P(RegCount + 1, 0, bincode.end());
	ASM_ADDIU_SP(- (FuncEntry[p->func_name].determined_size + (FuncEntry[p->func_name].max_color + 1) * __get_sizeof(var_type_uint16)), bincode.end());
}

void storevar(int func_name, int reg_name, int var_name, list <TBinEntry> :: iterator p, int sp_bias, int nochange = 0);
void build_rread(int func_name, list <TTACEntry> :: iterator p)
{
	int reg_num, var_name;
	sscanf(p->var1.c_str(), "%d", &reg_num);
	sscanf(p->var2.c_str(), "v%d", &var_name);
	storevar(func_name, reg_num, var_name, bincode.end(), p->sp_bias, 1);
}

void loadvar(int func_name, int reg_name, int var_name, list <TBinEntry> :: iterator p, int sp_bias, int tempreg = RegCount);
void build_rwrite(int func_name, list <TTACEntry> :: iterator p)
{
	int reg_num, var_name;
	sscanf(p->var1.c_str(), "%d", &reg_num);
	sscanf(p->var2.c_str(), "v%d", &var_name);
	loadvar(func_name, reg_num, var_name, bincode.end(), p->sp_bias, reg_num);
}

void build_asm(list <TTACEntry> :: iterator p)
{
	int code;
	sscanf(p->var1.c_str(), "%d", &code);
	bincode.insert(bincode.end(), create_bincode(bincode_type_normal, code));
}

void build_let(list <TTACEntry> :: iterator p)
{
	int var[2], num[2];
	int var_count = 0, num_count = 0;
	if (p->var1[0] != 'v')
	{
		printf("The first argument of LET operation must be variable.");
	}
	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 == 1)
	{
		var[0] = tempvar2reg(var[0], p->phi3);
		bin_load_immediate(var[0], num[0], bincode.end());
	}
	else
	{
		var[0] = tempvar2reg(var[0], p->phi3);
		var[1] = tempvar2reg(var[1], p->phi2);
		if (var[0] != var[1])
		{
			ASM_MOVE(var[0], var[1], bincode.end());
		}
	}
}

void listprintbincode()
{
	printf("bincode : \n");
	for (list <TBinEntry> :: iterator p = bincode.begin(); p != bincode.end(); p ++)
	{
		if (p->bincode_type == bincode_type_normal)
		{
			printf("%d\n", p->code);
		}
	}
	printf("\n");
}

void TAC2Bin(int func_name, list <TTACEntry> :: iterator p)
{
//	p->print(); printf("\n");
	if (p->op == "ADD" || p->op == "SUB" || p->op == "MUL" || p->op == "DIV" || p->op == "MOD" ||
		p->op == "AND" || p->op == "OR" || p->op == "NOT" || p->op == "XOR" || p->op == "SHR" || 
		p->op == "SHL")
	{
		build_computation_op(p);
	}
	else if (p->op == "JE" || p->op == "JNE" || p->op == "JG" || p->op == "JGE" || p->op == "JL" || p->op == "JLE" || p->op == "JMP")
	{
		build_jump_op(p);
	}
	else if (p->op == "LOAD" || p->op == "STORE")
	{
		build_loadstore(p);
	}
	else if (p->op == "LEA")
	{
		build_lea(func_name, p);
	}
	else if (p->op == "PUSH")
	{
		build_push(p);
	}
	else if (p->op == "POP")
	{
		build_pop(p);
	}
	else if (p->op == "RICALL")
	{
		build_ricall(p);
	}
	else if (p->op == "LEAFUNC")
	{
		build_leafunc(p);
	}
	else if (p->op == "RET" || p->op == "EXIT")
	{
		build_ret(func_name, p);
	}
	else if (p->op == "BEGIN")
	{
		build_begin(p);
	}
	else if (p->op == "LET")
	{
		build_let(p);
	}
	else if (p->op == "ASM")
	{
		build_asm(p);
	}
	else if (p->op == "RREAD")
	{
//		printf("here\n");
		build_rread(func_name, p);
	}
	else if (p->op == "RWRITE")
	{
		build_rwrite(func_name, p);
	}
	else if (p->op == "NOP")
	{
	}
	else 
	{
		printf("Unknown TAC operation.\n");
		exit(0);
	}
//	listprintbincode();
}

void func_to_bincode(int func_name)
{
	int sp_bias = 0;
	for (list <TTACEntry> :: iterator p = FuncEntry[func_name].ins.begin(); p != FuncEntry[func_name].ins.end(); p ++)
	{
		p->sp_bias = sp_bias;
//		if (IDHash_int2ID(func_name) == "env_run")
//		{
//			printf("%d --- \n", sp_bias);
//		}
		if (p->op == "PUSH") 
		{
			if (p->var2 == "(null)")
			{
				sp_bias ++;
			}
			else
			{
				int num;
				sscanf(p->var2.c_str(), "%d", &num);
				sp_bias += num;
			}
		}
		if (p->op == "POP") 
		{
			int num;
			sscanf(p->var1.c_str(), "%d", &num);
			sp_bias -= num;
		}
	}

	int first = 1;
	for (list <TTACEntry> :: iterator p = FuncEntry[func_name].ins.begin(); p != FuncEntry[func_name].ins.end(); p ++)
	{
//		p->print();printf("\n");
		bincode.push_back(create_bincode(bincode_type_empty, 0, 0, 0, 0, 0, 0, 0));
		if (first)
		{
			first = 0;
			FuncEntry[func_name].bin_start = bincode.end();
			FuncEntry[func_name].bin_start --;
		}
		p->bin_start = bincode.end();
		p->bin_start --;

//		p->print();
//		printf("\n");
		TAC2Bin(func_name, p);
	}
}

int color2tempvar(int color, list <int>& live)
{
	if (color >= GlobalBaseColor)
	{
		return color - GlobalBaseColor;
	}
	for (list <int> :: iterator p = live.begin(); p != live.end(); p ++)
	{
		if (VarEntry[*p].color == color)
		{
			return *p;
		}
	}
	return -1;
}

void storevar(int func_name, int reg_name, int var_name, list <TBinEntry> :: iterator p, int sp_bias, int nochange)
{
	int tempreg = RegCount; int delta_sp = 0;
	if (nochange)
	{
		tempreg = (reg_name + 1) % (RegCount + 2);
		ASM_ADDIU_SP(- __get_sizeof(var_type_uint16), bincode.end());
		ASM_SW_SP(tempreg, 0, bincode.end());
		delta_sp ++;
//		printf("%d %d\n", reg_name, tempreg);
	}
	if (VarEntry[var_name].var_class == var_class_func_var)
	{
		int offset = 3 * __get_sizeof(var_type_uint16) + VarEntry[var_name].offset;
		if (offset < 32)
		{
			ASM_SW(RegCount + 1, reg_name, offset, p);
		}
		else
		{
			ASM_MOVE(tempreg, RegCount + 1, p);
			ASM_ADDIU(tempreg, offset, p);
			ASM_SW(tempreg, reg_name, 0, p);
		}
	}
	else if (VarEntry[var_name].var_class == var_class_temp_var)
	{
		if (!VarEntry[var_name].lea_marked)
		{
			int offset = (VarEntry[var_name].color + 1) * __get_sizeof(var_type_uint16) + FuncEntry[func_name].determined_size;
			if (sp_bias + sp_add + delta_sp - offset < 128)
			{
//				if (IDHash_int2ID(func_name) == "env_run")
//					printf("%d %d\n", sp_bias, sp_add);
				ASM_SW_SP(reg_name, sp_bias + sp_add + delta_sp - offset, p);
			}
			else
			{
				ASM_MOVE(tempreg, RegCount + 1, p);
				ASM_ADDIU(tempreg, -offset, p);
				ASM_SW(tempreg, reg_name, 0, p);
			}
		}
		else
		{
			int offset = FuncEntry[func_name].determined_size - (VarEntry[var_name].offset - FuncEntry[func_name].parameter_size);
			if (sp_bias + sp_add + delta_sp - offset < 128)
			{
//				if (IDHash_int2ID(func_name) == "env_run")
//					printf("%d %d\n", sp_bias, sp_add);
				ASM_SW_SP(reg_name, sp_bias + sp_add + delta_sp - offset, p);
			}
			else
			{
				ASM_MOVE(tempreg, RegCount + 1, p);
				ASM_ADDIU(tempreg, -offset, p);
				ASM_SW(tempreg, reg_name, 0, p);
			}
		}
	}
	else if (VarEntry[var_name].var_class == var_class_global_var)
	{
		int offset = VarEntry[var_name].offset;
		bin_load_global_var(tempreg, offset, p);
		ASM_SW(tempreg, reg_name, 0, p);
	}
	if (nochange)
	{
		ASM_LW_SP(tempreg, 0, bincode.end());
		ASM_ADDIU_SP(__get_sizeof(var_type_uint16), bincode.end());
	}
}

void loadvar(int func_name, int reg_name, int var_name, list <TBinEntry> :: iterator p, int sp_bias, int tempreg)
{
	if (VarEntry[var_name].var_class == var_class_func_var)
	{
		int offset = 3 * __get_sizeof(var_type_uint16) + VarEntry[var_name].offset;
		if (offset < 32)
		{
			ASM_LW(RegCount + 1, reg_name, offset, p);
		}
		else
		{
			ASM_MOVE(tempreg, RegCount + 1, p);
			ASM_ADDIU(tempreg, offset, p);
			ASM_LW(tempreg, reg_name, 0, p);
		}
	}
	else if (VarEntry[var_name].var_class == var_class_temp_var)
	{
		if (!VarEntry[var_name].lea_marked)
		{
			int offset = (VarEntry[var_name].color + 1) * __get_sizeof(var_type_uint16) + FuncEntry[func_name].determined_size;
//			printf("here %d %d\n", var_name, VarEntry[var_name].color);
//			printf("load %d %d\n", sp_bias, sp_add);
			if (sp_bias + sp_add - offset < 128)
			{
//				if (IDHash_int2ID(func_name) == "env_run" && sp_bias)
//					printf("%d %d*\n", sp_bias, sp_add);
				ASM_LW_SP(reg_name, sp_bias + sp_add - offset, p);
			}
			else
			{
				ASM_MOVE(tempreg, RegCount + 1, p);
				ASM_ADDIU(tempreg, -offset, p);
				ASM_LW(tempreg, reg_name, 0, p);
			}
		}
		else
		{
			int offset = FuncEntry[func_name].determined_size - (VarEntry[var_name].offset - FuncEntry[func_name].parameter_size);
//			printf("load %d %d\n", sp_bias, sp_add);
			if (sp_bias + sp_add - offset < 128)
			{
//				if (IDHash_int2ID(func_name) == "env_run" && sp_bias)
//					printf("%d %d*\n", sp_bias, sp_add);
				ASM_LW_SP(reg_name, sp_bias + sp_add - offset, p);
			}
			else
			{
				ASM_MOVE(tempreg, RegCount + 1, p);
				ASM_ADDIU(tempreg, -offset, p);
				ASM_LW(tempreg, reg_name, 0, p);
			}
		}
	}
	else if (VarEntry[var_name].var_class == var_class_global_var)
	{
		int offset = VarEntry[var_name].offset;
		bin_load_global_var(tempreg, offset, p);
		ASM_LW(tempreg, reg_name, 0, p);
	}
	else if (VarEntry[var_name].var_class == var_class_global_dat)
	{
		int offset = VarEntry[var_name].offset;
		bin_load_global_const(reg_name, offset, p);
	}
}

list <TBinEntry> :: iterator phi_coalesce_sub(int func_name, list <TTACEntry> :: iterator q, list <TTACEntry> :: iterator p)
{
//	printf("%%%%%%%%enter\n");
	list <TBinEntry> :: iterator ret = p->bin_start;
	ret -

⌨️ 快捷键说明

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