📄 tobin.cpp
字号:
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", ®_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", ®_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 + -