📄 tacsupport.cpp
字号:
expr.res_oprd.data.id = tmpvar_name;
expr.var_type = var_type_bool;
}
}
void __value2cond(TExpr& expr)
{
if (!expr.cond)
{
__valueNOptr(expr);
expr.cond = 1;
expr.YesChain.clear();
expr.NoChain.clear();
if (__oprd_chk_constant(expr.res_oprd.oper_type)) // Boolean Constant
{
TACInstructionListBackAddBlank(expr.ins, 1); // Jump to XXX
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);
if (expr.res_oprd.oper_type == TAC_oper_type_constint && expr.res_oprd.data.cint == 0 ||
expr.res_oprd.oper_type == TAC_oper_type_constdouble && expr.res_oprd.data.cdouble == 0)
{
expr.NoChain.push_back(expr.ins.end);
}
else
{
expr.YesChain.push_back(expr.ins.end);
}
}
else
{
TACInstructionListBackAddBlank(expr.ins, 1); // IF (res == 0) Jump to XXX
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JE, expr.res_oprd.data.id, var_name_NULL, var_name_NULL);
expr.ins.end->b.oper_type = TAC_oper_type_constint;
expr.ins.end->b.data.cint = 0;
expr.NoChain.push_back(expr.ins.end);
TACInstructionListBackAddBlank(expr.ins, 1); // Jump to XXX
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);
expr.YesChain.push_back(expr.ins.end);
}
}
}
void __valueNOconst(TExpr& expr, int target_var_type)
{
if (!expr.cond && __oprd_chk_constant(expr.res_oprd.oper_type))
{
int tmpvar_name = TACNewTempVar(target_var_type);
TACInstructionListBackAddBlank(expr.ins, 1);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_LET, tmpvar_name, var_name_NULL, var_name_NULL);
expr.ins.end->b = expr.res_oprd;
expr.res_oprd = expr.ins.end->a;
}
}
inline int __op_src2tac(int op_type)
{
if (op_type == TAC_SRC_relational_EQL) return TAC_OP_JE;
if (op_type == TAC_SRC_relational_NEQ) return TAC_OP_JNE;
if (op_type == TAC_SRC_relational_LES) return TAC_OP_JL;
if (op_type == TAC_SRC_relational_LEQ) return TAC_OP_JLE;
if (op_type == TAC_SRC_relational_GTR) return TAC_OP_JG;
if (op_type == TAC_SRC_relational_GEQ) return TAC_OP_JGE;
if (op_type == TAC_SRC_calculational_ADD) return TAC_OP_ADD;
if (op_type == TAC_SRC_calculational_MINUS) return TAC_OP_SUB;
if (op_type == TAC_SRC_calculational_MUL) return TAC_OP_MUL;
if (op_type == TAC_SRC_calculational_DIV) return TAC_OP_DIV;
if (op_type == TAC_SRC_calculational_MOD) return TAC_OP_MOD;
if (op_type == TAC_SRC_calculational_AND) return TAC_OP_AND;
if (op_type == TAC_SRC_calculational_OR) return TAC_OP_OR;
if (op_type == TAC_SRC_calculational_NOT) return TAC_OP_NOT;
if (op_type == TAC_SRC_calculational_XOR) return TAC_OP_XOR;
if (op_type == TAC_SRC_calculational_SHL) return TAC_OP_SHL;
if (op_type == TAC_SRC_calculational_SHR) return TAC_OP_SHR;
return -1;
}
void TACInstructionListJoin(const TInstructionList ins1, const TInstructionList ins2, TInstructionList& ins)
{
if (ins1.begin == NULL)
{
ins = ins2;
}
else
{
ins = ins1;
if (ins2.begin != NULL)
{
ins.end->next = ins2.begin;
ins.end = ins2.end;
}
}
ins.BreakChain = ins1.BreakChain;
ins.BreakChain.insert(ins.BreakChain.end(), ins2.BreakChain.begin(), ins2.BreakChain.end());
}
inline int __constant_relation_i(int oprd1, int oprd2, int op_type)
{
if (op_type == TAC_SRC_relational_LES) return oprd1 < oprd2;
if (op_type == TAC_SRC_relational_LEQ) return oprd1 <= oprd2;
if (op_type == TAC_SRC_relational_GTR) return oprd1 > oprd2;
if (op_type == TAC_SRC_relational_GEQ) return oprd1 >= oprd2;
if (op_type == TAC_SRC_relational_EQL) return oprd1 == oprd2;
if (op_type == TAC_SRC_relational_NEQ) return oprd1 != oprd2;
return -1;
}
inline int __constant_calculation_i(int oprd1, int oprd2, int op_type)
{
if (op_type == TAC_SRC_calculational_ADD) return oprd1 + oprd2;
if (op_type == TAC_SRC_calculational_MINUS) return oprd1 - oprd2;
if (op_type == TAC_SRC_calculational_MUL) return oprd1 * oprd2;
if (op_type == TAC_SRC_calculational_DIV) return oprd1 / oprd2;
if (op_type == TAC_SRC_calculational_MOD) return oprd1 % oprd2;
if (op_type == TAC_SRC_calculational_AND) return oprd1 & oprd2;
if (op_type == TAC_SRC_calculational_OR) return oprd1 | oprd2;
if (op_type == TAC_SRC_calculational_XOR) return oprd1 ^ oprd2;
if (op_type == TAC_SRC_calculational_SHL) return oprd1 << oprd2;
if (op_type == TAC_SRC_calculational_SHR) return oprd1 >> oprd2;
return 0;
}
void TACCondExprCombine(TExpr& expr1, TExpr& expr2, int op_type, TExpr& expr)
{
expr.cond = 1;
expr.YesChain.clear();
expr.NoChain.clear();
expr.ins.clear();
if (__op_chk_relational(op_type))
{
__cond2value(expr1);
__cond2value(expr2);
__valueNOptr(expr1);
__valueNOptr(expr2);
if (__oprd_chk_constant(expr1.res_oprd.oper_type) && __oprd_chk_constant(expr2.res_oprd.oper_type)) // Constant Folding
{
int tmpres;
tmpres = __constant_relation_i(expr1.res_oprd.data.cint, expr2.res_oprd.data.cint, op_type);
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);
if (tmpres)
{
expr.YesChain.push_back(expr.ins.end);
}
else
{
expr.NoChain.push_back(expr.ins.end);
}
return;
}
TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);
int TAC_op_type = __op_src2tac(op_type);
TACInstructionListBackAddBlank(expr.ins); // IF (res1 relational_op res2) Jump to XXX
TACInstructionCreate_3struct(*expr.ins.end, TAC_op_type, expr1.res_oprd, expr2.res_oprd, TACNULLOperand);
expr.YesChain.push_back(expr.ins.end);
TACInstructionListBackAddBlank(expr.ins); // Jump to XXX
TACInstructionCreate_3var(*expr.ins.end, TAC_OP_JMP, var_name_NULL, var_name_NULL, var_name_NULL);
expr.NoChain.push_back(expr.ins.end);
return;
}
if (__op_chk_logical(op_type))
{
__value2cond(expr1);
__value2cond(expr2);
if (op_type == TAC_SRC_logical_AND)
{
int tmplabel = TACNewLabel();
TACInstructionListFrontAddBlank(expr2.ins);
TACInstructionCreate_3var(*expr2.ins.begin, TAC_OP_LABEL, tmplabel, var_name_NULL, var_name_NULL);
expr2.ins.begin->a.oper_type = TAC_oper_type_label;
TACFillInstructionChain(expr1.YesChain, tmplabel); // IF (res1) Jump to RES2
TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);
expr.YesChain = expr2.YesChain; // if (res2) FINAL TRUE
expr.NoChain = expr1.NoChain;
expr.NoChain.insert(expr.NoChain.end(), expr2.NoChain.begin(), expr2.NoChain.end()); // Jump Outs
return;
}
if (op_type == TAC_SRC_logical_OR)
{
int tmplabel = TACNewLabel();
TACInstructionListFrontAddBlank(expr2.ins);
TACInstructionCreate_3var(*expr2.ins.begin, TAC_OP_LABEL, tmplabel, var_name_NULL, var_name_NULL);
expr2.ins.begin->a.oper_type = TAC_oper_type_label;
TACFillInstructionChain(expr1.NoChain, tmplabel); // IF (!res1) Jump to RES2
TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);
expr.YesChain = expr1.YesChain;
expr.YesChain.insert(expr.YesChain.end(), expr2.YesChain.begin(), expr2.YesChain.end()); // Jump Outs
expr.NoChain = expr2.NoChain; // if (!res2) FINAL FALSE
return;
}
}
}
void TACCondExprUnary(TExpr& expr1, int op_type, TExpr& expr)
{
__value2cond(expr1);
expr.cond = 1;
if (op_type == TAC_SRC_logical_NOT)
{
expr.ins = expr1.ins;
expr.NoChain = expr1.YesChain;
expr.YesChain = expr1.NoChain;
return;
}
}
void TACExprCombine(TExpr& expr1, TExpr& expr2, int op_type, TExpr& expr)
{
if (SymbolListType[expr1.var_type].type_number == type_number_array)
{
__varADDref(expr1);
}
if (SymbolListType[expr1.var_type].type_number == type_number_pointer)
{
if (op_type == TAC_SRC_calculational_ADD)
{
TACPtrMakeExprOffset(expr1, expr2, __get_sizeof(SymbolListType[expr1.var_type].ret_type_id));
expr = expr1;
}
else if (op_type == TAC_SRC_calculational_MINUS)
{
TACPtrMakeExprOffset(expr1, expr2, __get_sizeof(SymbolListType[expr1.var_type].ret_type_id), 1);
expr = expr1;
}
return;
}
__cond2value(expr1);
__cond2value(expr2);
__valueNOptr(expr1);
__valueNOptr(expr2);
expr.cond = 0;
expr.ins.clear();
expr.var_type = expr1.var_type;
expr.ptr = 0;
if (__oprd_chk_constant(expr1.res_oprd.oper_type) && __oprd_chk_constant(expr2.res_oprd.oper_type)) // Constant Folding
{
expr.res_oprd.oper_type = TAC_oper_type_constint;
expr.res_oprd.data.cint = __constant_calculation_i(expr1.res_oprd.data.cint, expr2.res_oprd.data.cint, op_type);
return;
}
int TAC_op_type = __op_src2tac(op_type);
TOperand res_oprd;
if (expr1.res_oprd.oper_type == TAC_oper_type_variable
&& TempVar_TAC_Allocate[expr1.res_oprd.data.id].temp_sign)
{
res_oprd = expr1.res_oprd;
}
else
{
if (expr2.res_oprd.oper_type == TAC_oper_type_variable
&& TempVar_TAC_Allocate[expr2.res_oprd.data.id].temp_sign)
{
res_oprd = expr2.res_oprd;
}
else
{
res_oprd.oper_type = TAC_oper_type_variable;
res_oprd.data.id = TACNewTempVar(var_type_int);
}
}
TACInstructionListJoin(expr1.ins, expr2.ins, expr.ins);
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, TAC_op_type, res_oprd, expr1.res_oprd, expr2.res_oprd);
expr.res_oprd = res_oprd;
}
void TACExprUnary(TExpr& expr1, int op_type, TExpr& expr)
{
__cond2value(expr1);
__valueNOptr(expr1);
expr.cond = 0;
expr.ptr = 0;
expr.var_type = expr1.var_type;
expr.ins.clear();
if (op_type == TAC_SRC_calculational_MINUS)
{
if (__oprd_chk_constant(expr1.res_oprd.oper_type)) // Constant Folding
{
expr.res_oprd = expr1.res_oprd;
expr.res_oprd.data.cint = -expr.res_oprd.data.cint;
return;
}
expr.ins = expr1.ins;
TOperand firstoprd;
firstoprd.oper_type = TAC_oper_type_constint;
firstoprd.data.cint = 0;
if (!TempVar_TAC_Allocate[expr1.res_oprd.data.id].temp_sign)
{
expr.res_oprd.oper_type = TAC_oper_type_variable;
expr.res_oprd.data.id = TACNewTempVar(var_type_int);
}
else
{
expr.res_oprd = expr1.res_oprd;
}
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_SUB, expr.res_oprd, firstoprd, expr1.res_oprd);
return;
}
else if (op_type == TAC_SRC_calculational_NOT)
{
if (__oprd_chk_constant(expr1.res_oprd.oper_type)) // Constant Folding
{
expr.res_oprd = expr1.res_oprd;
expr.res_oprd.data.cint = ~expr.res_oprd.data.cint;
return;
}
expr.ins = expr1.ins;
if (!TempVar_TAC_Allocate[expr1.res_oprd.data.id].temp_sign)
{
expr.res_oprd.oper_type = TAC_oper_type_variable;
expr.res_oprd.data.id = TACNewTempVar(var_type_int);
}
else
{
expr.res_oprd = expr1.res_oprd;
}
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_NOT, expr.res_oprd, expr1.res_oprd, TACNULLOperand);
return;
}
}
void TACPtrMakeConstOffset(TExpr& expr, int offset)
{
__2tmpVar(expr);
__valueNOconst(expr, var_type_int);
TACInstructionListBackAddBlank(expr.ins);
if (offset >= 0)
{
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_ADD, expr.res_oprd, expr.res_oprd, TACNULLOperand);
}
else
{
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_SUB, expr.res_oprd, expr.res_oprd, TACNULLOperand);
}
expr.ins.end->c.oper_type = TAC_oper_type_constint;
if (offset >= 0)
{
expr.ins.end->c.data.cint = offset;
}
else
{
expr.ins.end->c.data.cint = -offset;
}
}
void TACPtrMakeExprOffset(TExpr& expr, TExpr& offset, int unit_size, int backward)
{
__cond2value(offset);
__2tmpVar(expr);
__valueNOconst(expr, var_type_int);
__2tmpVar(offset);
__valueNOconst(offset, var_type_int);
int last = 0;
int now = 0;
TACInstructionListJoin(expr.ins, offset.ins, expr.ins);
while (unit_size != 0)
{
if (unit_size & 1)
{
if (now != last)
{
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, TAC_OP_SHL , offset.res_oprd, offset.res_oprd, TACNULLOperand);
expr.ins.end->c.oper_type = TAC_oper_type_constint;
expr.ins.end->c.data.cint = (now - last) % 8;
}
TACInstructionListBackAddBlank(expr.ins);
TACInstructionCreate_3struct(*expr.ins.end, backward ? TAC_OP_SUB : TAC_OP_ADD, expr.res_oprd, expr.res_oprd, offset.res_oprd);
last = now;
}
unit_size /= 2;
now ++;
}
}
void TACFindArrayAddr(TExpr& expr1, TExpr& expr2, TExpr& expr)
{
__cond2value(expr2);
__valueNOptr(expr2);
expr = expr1;
if (SymbolListType[expr.var_type].type_number == type_number_array)
{
__varADDref(expr);
}
else
{
__valueNOptr(expr);
}
// printf ("Take arraysub, to %s\n", expr.var_type >= 0 ? IDHash_int2ID(expr.var_type).c_str() : "basic");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -