예제 #1
0
void identity_record::clean_up()
{
    if (idset_to_var_map)
    {
        Symbol* lSym;
        for (auto it = idset_to_var_map->begin(); it != idset_to_var_map->end(); ++it)
        {
            lSym = it->second;
            if (lSym) thisAgent->symbolManager->symbol_remove_ref(&lSym);
        }
        delete idset_to_var_map;
    }
    if (identities_in_chunk) delete identities_in_chunk;

    clear_mappings();
    delete instantiation_mappings;
    delete identity_joins;

}
예제 #2
0
파일: gen_code.c 프로젝트: jwrona/VYPe
void generate_code(struct tac * tac_mapped, FILE * f_out) {
	// gather data to be declared in the end
	unsigned n_strings = count_string_literals(tac_mapped);
	unsigned n_vars = count_vars(tac_mapped);
	char ** p_lit_strings = malloc(sizeof(char*) * n_strings);
	unsigned i_string = 0;

	int * func_params;
	count_func_params(tac_mapped, &func_params);
	int n_pushes = 0;

	// create mappings between variables and registers
	int * var_mapping; int * reg_mapping;
	unsigned res_reg, op1_reg, op2_reg;
	create_variable_mapping(n_vars, &var_mapping);
	create_register_mapping(&reg_mapping);

	// id counter for auxiliary labels
	generic_label_id = 0;

	// initial settings
	fprintf(f_out,".text\n");
	fprintf(f_out,".org 0\n");
	fprintf(f_out,"li $sp,0x00800000\n");
	fprintf(f_out,"la $28,heap\n");

	// call main and break after it's finished
	fprintf(f_out,"jal label1\n");
	fprintf(f_out,"break\n");	

	for (unsigned i = 0; i < tac_mapped->instructions_cnt; i++) {
		struct tac_instruction inst = tac_mapped->instructions[i];
		switch (inst.operator) {
			case OPERATOR_LABEL:
				clear_mappings(var_mapping, n_vars, reg_mapping, f_out);
				fprintf(f_out, "\nlabel%d:\n",inst.op1.value.num);
				break;
			case OPERATOR_ASSIGN:
				if ((inst.data_type == DATA_TYPE_STRING) && 
				    (inst.op1.type == OPERAND_TYPE_LITERAL)) { //string literal
					p_lit_strings[i_string] = inst.op1.value.string_val;
					res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
					fprintf(f_out, "\tla $%d,str%d\n", res_reg, i_string);
					i_string++;
				}
				else if (inst.data_type == DATA_TYPE_STRING) { //string
					// not doing deep copy, because we cannot change the string anyway
					res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
					op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
					fprintf(f_out, "\taddi $%d,$%d,0\n", res_reg, op1_reg);
				}
				else if (inst.op1.type == OPERAND_TYPE_LITERAL) { // int or char literal
					res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
					fprintf(f_out, "\tli $%d,%d\n", res_reg, get_op_val(inst, 1));
				}
				else { // int or char
					res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
					op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
					fprintf(f_out, "\taddi $%d,$%d,0\n", res_reg, op1_reg);
				}	
				break;
			case OPERATOR_SLT:
				if (inst.data_type == DATA_TYPE_STRING) {
					compare_strings(inst, var_mapping, reg_mapping, f_out, OPERATOR_SLT);
					break;
				}
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tslt $%d,$%d,$%d\n", res_reg, op1_reg, op2_reg);
				break;
			case OPERATOR_SLET:
				if (inst.data_type == DATA_TYPE_STRING) {
					compare_strings(inst, var_mapping, reg_mapping, f_out, OPERATOR_SLET);
					break;
				}
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tslt $%d,$%d,$%d\n", res_reg, op2_reg, op1_reg);
				fprintf(f_out, "\tlui $25,0xFFFF\n");
				fprintf(f_out, "\tori $25,$25,0xFFFE\n");
				fprintf(f_out, "\tnor $%d,$%d,$25\n", res_reg, res_reg);
				break;
			case OPERATOR_SGET:
				if (inst.data_type == DATA_TYPE_STRING) {
					compare_strings(inst, var_mapping, reg_mapping, f_out, OPERATOR_SGET);
					break;
				}
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tslt $%d,$%d,$%d\n", res_reg, op1_reg, op2_reg);
				fprintf(f_out, "\tlui $25,0xFFFF\n");
				fprintf(f_out, "\tori $25,$25,0xFFFE\n");
				fprintf(f_out, "\tnor $%d,$%d,$25\n", res_reg, res_reg);
				break;
			case OPERATOR_SGT:
				if (inst.data_type == DATA_TYPE_STRING) {
					compare_strings(inst, var_mapping, reg_mapping, f_out, OPERATOR_SGT);
					break;
				}
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tslt $%d,$%d,$%d\n", res_reg, op2_reg, op1_reg);
				break;
			case OPERATOR_SE:
				if (inst.data_type == DATA_TYPE_STRING) {
					compare_strings(inst, var_mapping, reg_mapping, f_out, OPERATOR_SE);
					break;
				}
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tsub $%d,$%d,$%d\n", res_reg, op1_reg, op2_reg);
				fprintf(f_out, "\tsltu $%d,$zero,$%d\n", res_reg, res_reg);
				fprintf(f_out, "\tlui $25,0xFFFF\n");
				fprintf(f_out, "\tori $25,$25,0xFFFE\n");
				fprintf(f_out, "\tnor $%d,$%d,$25\n", res_reg, res_reg);
				break;
			case OPERATOR_SNE:
				if (inst.data_type == DATA_TYPE_STRING) {
					compare_strings(inst, var_mapping, reg_mapping, f_out, OPERATOR_SNE);
					break;
				}
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tsub $%d,$%d,$%d\n", res_reg, op1_reg, op2_reg);
				fprintf(f_out, "\tsltu $%d,$zero,$%d\n", res_reg, res_reg);
				break;
			case OPERATOR_BZERO:
				clear_mappings(var_mapping, n_vars, reg_mapping, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				fprintf(f_out, "\tbeq $%d, $0, label%d\n", op1_reg, inst.op2.value.num);
				break;
			case OPERATOR_NEG:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				fprintf(f_out, "\tsltu $%d,$zero,$%d\n", res_reg, op1_reg);
				fprintf(f_out, "\tlui $25,0xFFFF\n");
				fprintf(f_out, "\tori $25,$25,0xFFFE\n");
				fprintf(f_out, "\tnor $%d,$%d,$25\n", res_reg, res_reg);
				break;
			case OPERATOR_AND:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\taddi $%d,$zero,0\n", res_reg);
				fprintf(f_out, "\tbeq $%d, $0, labelgen%d\n", op1_reg, generic_label_id);
				fprintf(f_out, "\tbeq $%d, $0, labelgen%d\n", op2_reg, generic_label_id);
				fprintf(f_out, "\taddi $%d,$zero,1\n", res_reg);
				fprintf(f_out, "\nlabelgen%d:\n",generic_label_id);
				generic_label_id++;
				break;
			case OPERATOR_OR:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\taddi $%d,$zero,1\n", res_reg);
				fprintf(f_out, "\tbne $%d, $0, labelgen%d\n", op1_reg, generic_label_id);
				fprintf(f_out, "\tbne $%d, $0, labelgen%d\n", op2_reg, generic_label_id);
				fprintf(f_out, "\taddi $%d,$zero,0\n", res_reg);
				fprintf(f_out, "\nlabelgen%d:\n",generic_label_id);
				generic_label_id++;
				break;
			case OPERATOR_JUMP:
				clear_mappings(var_mapping, n_vars, reg_mapping, f_out);
				fprintf(f_out, "\tj label%d\n",inst.op1.value.num);
				break;
			case OPERATOR_SUB:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tsub $%d,$%d,$%d\n", res_reg, op1_reg, op2_reg);
				break;
			case OPERATOR_ADD:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tadd $%d,$%d,$%d\n", res_reg, op1_reg, op2_reg);
				break;
			case OPERATOR_DIV:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tdiv $%d,$%d\n", op1_reg, op2_reg);
				fprintf(f_out, "\tmflo $%d\n", res_reg);
				break;
			case OPERATOR_MOD:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tdiv $%d,$%d\n", op1_reg, op2_reg);
				fprintf(f_out, "\tmfhi $%d\n", res_reg);
				break;
			case OPERATOR_MUL:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				op2_reg = get_register(var_mapping, reg_mapping, inst.op2.value.num, inst, f_out);
				fprintf(f_out, "\tmul $%d,$%d,$%d\n", res_reg, op1_reg, op2_reg);
				break;
			case OPERATOR_POP:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				fprintf(f_out, "\tlw $%d,0($fp)\n", res_reg);
				fprintf(f_out,"\taddi $fp,$fp,4\n");
				break;
			case OPERATOR_PUSH:
				// push param on stack
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				fprintf(f_out,"\taddi $sp,$sp,-4\n");
				fprintf(f_out,"\tsw $%d,0($sp)\n",op1_reg);
				n_pushes++;
				break;
			case OPERATOR_CALL:
				n_pushes -= func_params[inst.op1.value.num];

				if ((inst.op1.value.num >=2) && inst.op1.value.num <= 8) {
					// built in function
					generate_built_in(inst.op1.value.num, n_pushes, tac_mapped, i, 
								func_params, f_out, reg_mapping, var_mapping);
					if (inst.op1.value.num == 2) n_pushes = 0;
					break;
				}
				// push old FP
				fprintf(f_out,"\taddi $sp,$sp,-4\n");
				fprintf(f_out,"\tsw $fp,0($sp)\n");
				// set new FP 
				fprintf(f_out,"\taddi $fp,$sp,4\n");
				// push old RA
				fprintf(f_out,"\taddi $sp,$sp,-4\n");
				fprintf(f_out,"\tsw $ra,0($sp)\n");
				// push vars
				clear_mappings(var_mapping, n_vars, reg_mapping, f_out);
				fprintf(f_out,"\tjal push_registers\n");
				// call
				fprintf(f_out,"\tjal label%d\n",inst.op1.value.num);
				// pop vars
				clear_mappings(var_mapping, n_vars, reg_mapping, f_out);
				fprintf(f_out,"\tjal pop_registers\n");
				// pop ra
				fprintf(f_out,"\tlw $ra,0($sp)\n");
				fprintf(f_out,"\taddi $sp,$sp,4\n");
				// pop fp + params	
				fprintf(f_out,"\taddi $25,$fp,0\n");
				fprintf(f_out,"\tlw $fp,0($sp)\n");
				fprintf(f_out,"\taddi $sp,$25,0\n");
				// save return value
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				fprintf(f_out,"\taddi $%d,$2,0\n",res_reg);
				break;
			case OPERATOR_RETURN:
				if (inst.op1.type == OPERAND_TYPE_LITERAL) {
					if (inst.data_type == DATA_TYPE_STRING) {
						p_lit_strings[i_string] = inst.op1.value.string_val;
						fprintf(f_out, "\tla $2,str%d\n", i_string);
						i_string++;
					}
					else {
						fprintf(f_out,"\tli $2,%d\n",get_op_val(inst,1));
						fprintf(f_out, "\tjr $ra\n");
					}
				}
				else {
					op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
					fprintf(f_out,"\taddi $2,$%d,0\n",op1_reg);
					fprintf(f_out, "\tjr $ra\n");
				}
				break;
			case OPERATOR_CAST_INT_TO_CHAR:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				fprintf(f_out, "\tli $%d,0\n",res_reg);
				fprintf(f_out, "\taddi $%d,$%d,0\n",res_reg,op1_reg);
				fprintf(f_out, "\tli $25,0x00FF\n");
				fprintf(f_out, "\tand $%d,$%d,$25\n",res_reg,res_reg);
				break;
			case OPERATOR_CAST_CHAR_TO_INT:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				fprintf(f_out, "\tli $%d,0\n",res_reg);
				fprintf(f_out, "\taddi $%d,$%d,0\n",res_reg,op1_reg);
				//fprintf(f_out, "\tli $25,0x000F\n");
				//fprintf(f_out, "\tand $%d,$%d,$25\n",res_reg,res_reg);
				break;
			case OPERATOR_CAST_CHAR_TO_STRING:
				res_reg = get_register(var_mapping, reg_mapping, inst.res_num, inst, f_out);
				op1_reg = get_register(var_mapping, reg_mapping, inst.op1.value.num, inst, f_out);
				fprintf(f_out, "\taddi $%d,$28,0\n",res_reg);
				fprintf(f_out, "\tsb $%d,0($%d)\n",op1_reg,res_reg);
				fprintf(f_out, "\tsb $0,1($%d)\n",res_reg);
				fprintf(f_out, "\taddi $28,$28,2\n");
				break;
			default:
				fprintf(f_out, "\tMISSING INSTR\n");
				break;
		}
	}

	// generate push_registers function
	fprintf(f_out,"\npush_registers:\n");
	for (unsigned i_reg = 0; i_reg < n_vars; i_reg++) {
		fprintf(f_out,"\taddi $sp,$sp,-4\n");
		fprintf(f_out,"\tla $25,var%d\n",i_reg);
		fprintf(f_out,"\tlw $8,0($25)\n");
		fprintf(f_out,"\tsw $8,0($sp)\n");
	}
	fprintf(f_out,"\tjr $ra\n");

	// generate pop_registers function
	fprintf(f_out,"\npop_registers:\n");
	for (int i_reg = n_vars-1; i_reg >= 0; i_reg--) {
		fprintf(f_out,"\tla $25,var%d\n",i_reg);
		fprintf(f_out,"\tlw $8,0($sp)\n");
		fprintf(f_out,"\tsw $8,0($25)\n");
		fprintf(f_out,"\taddi $sp,$sp,4\n");
	}
	fprintf(f_out,"\tjr $ra\n");

	// print data - strings + variables
	fprintf(f_out,"\n.data\n");
	print_string_literals(f_out, p_lit_strings, n_strings);
	print_vars(f_out, n_vars);
	fprintf(f_out,"\n.align 4\n");
	fprintf(f_out,"\nheap:\n");

	free(func_params);

	// dealocate register and variable mappings
	destroy_mappings(reg_mapping, var_mapping);
}