📄 tobin.cpp
字号:
{
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 + -