📄 main.cc
字号:
semi_tree->addchild(base_tree); if (pending_expr != NULL) semi_tree->addchild(create_branch(pending_target, pending_expr)); if (semi_tree->N() == 1) { ctree *child_tree = semi_tree->child(0); semi_tree->reset_children(); child_tree->copy_comments_from(semi_tree); delete semi_tree; return child_tree; } return semi_tree; }/* * Generate a C tree for a statement of some sort */ctree *operand_to_tree(const operand &op){ switch (op.kind()) { case OPER_SYM: return new ctree(ctree_symconst, op.symbol(), op.symbol()->type()); case OPER_INSTR: { ctree *result = process_expr_inst(op.instr()); result->add_object_comments(op.instr()); return result; } case OPER_NULL: { static boolean warned = FALSE; mistake(&warned, NULL, "illegal null operand"); return new ctree(ctree_macro, "<null>", type_signed); } default: assert_msg(FALSE, ("operand_to_tree - Illegal operand type")); } return NULL;}extern ctree *process_base_inst(instruction *inst, ctree **pending_expr, label_sym **pending_target, ctree **pre_instr){ ctree *tree; if_ops op = inst->opcode(); if ((op == io_mrk) || (op == io_nop)) { ctree *result = NULL; if ((inst->peek_annote(k_s2c_pragma) != NULL) || (inst->peek_annote(k_s2c_pound_line) != NULL)) { result = new ctree(ctree_semi); add_pound_lines_for_object(inst, result); } if (inst->peek_annote(k_s2c_comments) != NULL) { ctree *new_ctree = new ctree(ctree_blank_line); new_ctree->add_object_comments(inst); if (result == NULL) result = new_ctree; else result->addchild(new_ctree); } return result; } if (which_format(op) == inf_bj) { in_bj *the_bj = (in_bj *)inst; if ((pending_expr != NULL) && (pending_target != NULL)) { ctree *new_expr; if (op == io_jmp) { new_expr = ldc_tree(type_signed, immed(1)); } else { new_expr = operand_to_tree(the_bj->src_op()); if (op == io_bfalse) { ctree *not_expr = new ctree(ctree_not); not_expr->addchild(new_expr); new_expr = not_expr; } } new_expr->add_object_comments(the_bj); if ((*pending_expr != NULL) && (*pending_target == the_bj->target())) { ctree *or_expr = new ctree(ctree_logor); or_expr->addchild(*pending_expr); or_expr->addchild(new_expr); *pending_expr = or_expr; return NULL; } ctree *result = NULL; if (*pending_expr != NULL) result = create_branch(*pending_target, *pending_expr); *pending_expr = new_expr; *pending_target = the_bj->target(); return result; } ctree *the_goto = create_goto(the_bj->target()); the_goto->add_object_comments(the_bj); if (op == io_jmp) { return the_goto; } else { ctree *gif = new ctree(ctree_if); ctree *test_ctree = operand_to_tree(the_bj->src_op()); if (op == io_bfalse) { ctree *new_test_ctree = new ctree(ctree_not); new_test_ctree->addchild(test_ctree); test_ctree = new_test_ctree; } gif->addchild(test_ctree); gif->addchild(the_goto); return gif; } } if ((pending_expr != NULL) && (pending_target != NULL)) { if (*pending_expr != NULL) { assert(pre_instr != NULL); *pre_instr = create_branch(*pending_target, *pending_expr); *pending_expr = NULL; *pending_target = NULL; } } switch (which_format(op)) { case inf_rrr: { in_rrr *rrr = (in_rrr *) inst; if (op == io_str || op == io_memcpy) { tree = new ctree(ctree_assign); ctree *indtree = new ctree(ctree_deref); indtree->addchild(operand_to_tree(rrr->src1_op())); tree->addchild(indtree); if (op == io_str) tree->addchild(operand_to_tree(rrr->src2_op())); else { ctree *deref_tree = new ctree(ctree_deref); deref_tree->addchild(operand_to_tree(rrr->src2_op())); tree->addchild(deref_tree); } tree->add_object_comments(rrr); return tree; } else if (op == io_ret) { tree = new ctree(ctree_return); if (!rrr->src1_op().is_null()) tree->addchild(operand_to_tree(rrr->src1_op())); tree->add_object_comments(rrr); return tree; } break; } case inf_lab: { in_lab *lab = (in_lab*)inst; ctree *result_ctree = new ctree(ctree_label, lab->label()); result_ctree->add_object_comments(lab); return result_ctree; } case inf_mbr: { in_mbr *the_mbr = (in_mbr *)inst; ctree *semi_tree = new ctree(ctree_semi); unsigned num_labs = the_mbr->num_labs(); for (unsigned lab_num = 0; lab_num < num_labs; ++lab_num) { ctree *case_tree = new ctree(ctree_case, NULL, i_integer(lab_num) + the_mbr->lower()); semi_tree->addchild(case_tree); ctree *goto_tree = create_goto(the_mbr->label(lab_num)); semi_tree->addchild(goto_tree); } if (the_mbr->default_lab() != NULL) { ctree *case_tree = new ctree(ctree_default); semi_tree->addchild(case_tree); ctree *goto_tree = create_goto(the_mbr->default_lab()); semi_tree->addchild(goto_tree); } ctree *block_tree = new ctree(ctree_block); block_tree->addchild(semi_tree); ctree *switch_tree = new ctree(ctree_switch); switch_tree->addchild(operand_to_tree(the_mbr->src_op())); switch_tree->addchild(block_tree); switch_tree->add_object_comments(the_mbr); return switch_tree; } default: break; } tree = process_expr_inst(inst); tree->add_object_comments(inst); if (inst->dst_op().is_symbol()) { ctree *assgn = new ctree(ctree_assign); assgn->addchild(operand_to_tree(inst->dst_op())); assgn->addchild(tree); return assgn; } return tree;}extern ctree *process_expr_inst(instruction *inst) { ctree *tree; if_ops op = inst->opcode(); assert(op != io_nop); switch (which_format(op)) { case inf_rrr: { in_rrr *rrr = (in_rrr *) inst; if (op == io_cvt) { ctree *operand_tree = operand_to_tree(rrr->src_op()); immed_list *field_immeds = (immed_list *)(rrr->peek_annote(k_fields)); if (field_immeds != NULL) { type_node *src_type = rrr->src_op().type(); if (!src_type->unqual()->is_ptr()) { error_line(1, rrr->parent(), "\"%s\" annotation on convert from non-pointer" " type", k_fields); } ptr_type *src_ptr = (ptr_type *)(src_type->unqual()); type_node *object_type = src_ptr->ref_type(); ctree *object_tree = new ctree(ctree_deref); object_tree->addchild(operand_tree); tree = get_address_with_offset(object_tree, object_type, rrr->result_type(), 0, field_immeds); } else { tree = new ctree(ctree_conv, !keep_casts, rrr->result_type()); tree->addchild(operand_tree); } return tree; } else { if (((op == io_add) || (op == io_sub)) && rrr->result_type()->unqual()->is_ptr()) { operand ptr_op = rrr->src1_op(); operand int_op = rrr->src2_op(); if ((op == io_add) && !ptr_op.type()->unqual()->is_ptr()) { operand temp_op = ptr_op; ptr_op = int_op; int_op = temp_op; } if ((!ptr_op.type()->unqual()->is_ptr()) || (int_op.type()->unqual()->op() != TYPE_INT)) { error_line(1, rrr->parent(), "illegal pointer arithmetic"); } ptr_type *src_ptr_type = (ptr_type *)(ptr_op.type()->unqual()); immed_list *field_immeds = (immed_list *)(rrr->peek_annote(k_fields)); if ((op == io_add) && (field_immeds != NULL)) { int offset; boolean is_const = operand_is_intconst(int_op, &offset); if (!is_const) { error_line(1, rrr->parent(), "\"%s\" annotation on addition of " "non-constant", k_fields); } offset *= target.addressable_size; type_node *object_type = src_ptr_type->ref_type(); ctree *object_tree = new ctree(ctree_deref); object_tree->addchild(operand_to_tree(ptr_op)); tree = get_address_with_offset(object_tree, object_type, rrr->result_type(), offset, field_immeds); return tree; } if (src_ptr_type->ref_type()->size() != target.addressable_size) { /* * In this case, the units SUIF and C use for pointer * arithmetic are different. SUIF always uses bytes while * C uses the size of the thing pointed to. */ int factor = src_ptr_type->ref_type()->size() / target.addressable_size; ctree *int_ctree = operand_to_tree(int_op); if (factor != 0) { boolean folded = FALSE; int_ctree->try_const_div(factor, &folded); if (folded) { tree = new ctree(ctree::ctree_io_to_op(op)); tree->addchild(operand_to_tree(ptr_op)); tree->addchild(int_ctree); return force_type(tree, rrr->result_type()); } } ctree *src_conv_tree = operand_to_tree(ptr_op); src_conv_tree = force_type(src_conv_tree, type_char->ptr_to()); ctree *add_tree = new ctree(ctree::ctree_io_to_op(op)); add_tree->addchild(src_conv_tree); add_tree->addchild(int_ctree); return force_type(add_tree, rrr->result_type()); } } else if ((op == io_sub) && rrr->src1_op().type()->unqual()->is_ptr()) { type_node *src1_type = rrr->src1_op().type()->unqual(); type_node *src2_type = rrr->src2_op().type()->unqual(); if ((!src1_type->is_ptr()) || (!src2_type->is_ptr()) || (rrr->result_type()->unqual()->op() != TYPE_INT)) { error_line(1, rrr->parent(), "illegal pointer arithmetic"); } ptr_type *src1_ptr = (ptr_type *)src1_type; ctree *src1_tree = operand_to_tree(rrr->src1_op()); ctree *src2_tree = operand_to_tree(rrr->src2_op()); src2_tree = force_type(src2_tree, src1_ptr); if (src1_ptr->ref_type()->size() != target.addressable_size) { /* * In this case, the units SUIF and C use for pointer * arithmetic are different. SUIF always uses bytes while * C uses the size of the thing pointed to. */ int factor = src1_ptr->ref_type()->size() / target.addressable_size; if (factor != 0) { ctree *add_tree = new ctree(ctree::ctree_io_to_op(op)); add_tree->addchild(src1_tree); add_tree->addchild(src2_tree);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -