📄 main.cc
字号:
ctree *const_tree = ldc_tree(rrr->result_type(), immed(factor)); tree = new ctree(ctree_mult); tree->addchild(add_tree); tree->addchild(const_tree); } else { ctree *src1_conv = force_type(src1_tree, type_char->ptr_to()); ctree *src2_conv = force_type(src2_tree, type_char->ptr_to()); tree = new ctree(ctree::ctree_io_to_op(op)); tree->addchild(src1_conv); tree->addchild(src2_conv); } } else { tree = new ctree(ctree::ctree_io_to_op(op)); tree->addchild(src1_tree); tree->addchild(src2_tree); } return force_type(tree, rrr->result_type()); } if (op == io_cpy) { return force_type(operand_to_tree(rrr->src_op()), rrr->result_type()); } int index; for (index = 0; macro_table[index].replacement != NULL; ++index) { if (macro_table[index].opcode == op) { tree = new ctree(ctree_macro, macro_table[index].op_name); assert(macro_table[index].used || in_comment || in_pound_line); break; } } if (macro_table[index].replacement == NULL) tree = new ctree(ctree::ctree_io_to_op(op)); fix_relational_op(rrr); tree->addchild(operand_to_tree(rrr->src1_op())); if (!rrr->src2_op().is_null()) tree->addchild(operand_to_tree(rrr->src2_op())); return force_type(tree, rrr->result_type()); } } case inf_ldc: { in_ldc *the_ldc = (in_ldc *)inst; immed_list *field_immeds = (immed_list *)(the_ldc->peek_annote(k_fields)); tree = ldc_tree(the_ldc->result_type(), the_ldc->value(), field_immeds); return tree; } case inf_array: { in_array *ar = (in_array *)inst; ctree *artree = new ctree(ctree_subscr); ctree *base_tree = operand_to_tree(ar->base_op()); /* * In SUIF, the type of the base operand of an array instruction * should be a pointer to an array of the element type. In C it * should be either a pointer to or an array of the element type * directly. If C were to use the SUIF type, it would do the * arithmetic wrong, using the size of the whole array (which might * not even be known) as the unit of the index. * We'll put in the cast here, though it may be optimized away by * another part of the program if C would do an implicit conversion * anyway. */ type_node *base_type = ar->base_op().type()->unqual(); if (!base_type->is_ptr()) { error_line(1, inst->parent(), "base of array reference is not a pointer"); } ptr_type *base_ptr = (ptr_type *)base_type; type_node *base_ref = base_ptr->ref_type()->unqual(); if (!base_ref->is_array()) { error_line(1, inst->parent(), "base of array reference is not a pointer to an array"); } array_type *base_array = (array_type *)base_ref; boolean flatten = array_flattening_needed(ar, base_array); type_node *element_type = base_array->elem_type(); if (flatten) { for (unsigned dim_num = ar->dims(); dim_num > 1; --dim_num) { if (!element_type->unqual()->is_array()) { error_line(1, ar->parent(), "array type mismatches array reference " "instruction"); } array_type *elem_array = (array_type *)(element_type->unqual()); element_type = elem_array->elem_type(); } } if (ar->elem_size() == 0) { error_line(1, ar->parent(), "array reference with unknown element size cannot be " "converted into C"); } ptr_type *new_ptr = element_type->ptr_to(); artree->addchild(force_type(base_tree, new_ptr)); if (flatten) { ctree *index_tree = operand_to_tree(ar->index(0)); unsigned num_dims = ar->dims(); for (unsigned dim_num = 1; dim_num < num_dims; ++dim_num) { ctree *mul_tree = new ctree(ctree_mult); mul_tree->addchild(index_tree); mul_tree->addchild(operand_to_tree(ar->bound(dim_num))); index_tree = new ctree(ctree_add); index_tree->addchild(mul_tree); index_tree->addchild(operand_to_tree(ar->index(dim_num))); } if (!ar->offset_op().is_null()) { ctree *sub_tree = new ctree(ctree_sub); sub_tree->addchild(index_tree); sub_tree->addchild(operand_to_tree(ar->offset_op())); index_tree = sub_tree; } artree->addchild(index_tree); } else { for (unsigned dim_num = 0; dim_num < ar->dims(); ++dim_num) artree->addchild(operand_to_tree(ar->index(dim_num))); } type_node *final_elem_type = base_array; unsigned num_dims = ar->dims(); for (unsigned dim_num = 0; dim_num < num_dims; ++dim_num) { if (!final_elem_type->unqual()->is_array()) { error_line(1, ar->parent(), "array type mismatches array reference " "instruction"); } array_type *this_array = (array_type *)(final_elem_type->unqual()); final_elem_type = this_array->elem_type(); } immed_list *field_immeds = (immed_list *)(ar->peek_annote(k_fields)); tree = get_address_with_offset(artree, final_elem_type, ar->result_type(), ar->offset(), field_immeds); return tree; } case inf_cal: { in_cal *cal = (in_cal*)inst; tree = new ctree(ctree_funcall); tree->addchild(operand_to_tree(cal->addr_op())); for (unsigned arg_num = 0; arg_num < cal->num_args(); ++arg_num) tree->addchild(operand_to_tree(cal->argument(arg_num))); return tree; } case inf_gen: { in_gen *the_gen = (in_gen *)inst; tree = new ctree(ctree_macro, the_gen->name(), the_gen->result_type()); immed_list *arg_immeds = (immed_list *)(the_gen->peek_annote(k_builtin_args)); if (arg_immeds == NULL) { for (unsigned src_num = 0; src_num < the_gen->num_srcs(); ++src_num) { tree->addchild(operand_to_tree(the_gen->src_op(src_num))); } } else { immed_list_iter arg_iter(arg_immeds); while (!arg_iter.is_empty()) { immed this_arg = arg_iter.step(); if (this_arg.is_type()) { ctree *type_tree = new ctree(ctree_type_ref, FALSE, this_arg.type()); tree->addchild(type_tree); } else if (this_arg.is_string()) { ctree *string_tree = new ctree(ctree_strconst, this_arg.string()); tree->addchild(string_tree); } else if (this_arg.is_integer()) { unsigned arg_num = this_arg.integer(); if (arg_num < the_gen->num_srcs()) { tree->addchild(operand_to_tree(the_gen->src_op( arg_num))); } else { error_line(1, inst->owner(), "badly formed \"%s\" annote", k_builtin_args); } } else { error_line(1, inst->owner(), "badly formed \"%s\" annote", k_builtin_args); } } } return tree; } default: assert(FALSE); return NULL; } }/* * Generate C code for a loop (while, do...while) */ctree *process_loop(tree_loop *loop){ label_sym *old_continue = current_continue; label_sym *old_break = current_break; current_break = loop->brklab(); ctree *conditional_expr = NULL; ctree *test_tree = process_node_list(loop->test(), loop->toplab(), &conditional_expr); if ((test_tree->getop() == ctree_semi) && (test_tree->N() == 0)) current_continue = loop->contlab(); ctree *body_tree = process_node_list(loop->body(), NULL, NULL); ctree *tree = new ctree(ctree_do); tree->add_object_comments(loop); ctree *block_body = new ctree(ctree_block); ctree *body_list = new ctree(ctree_semi); block_body->addchild(body_list); if (loop->toplab()->get_annote(k_s2c_label_name_used) != NULL) body_list->addchild(new ctree(ctree_label, loop->toplab())); body_list->addchild(body_tree); if (loop->contlab()->get_annote(k_s2c_label_name_used) != NULL) body_list->addchild(new ctree(ctree_label, loop->contlab())); body_list->addchild(test_tree); tree->addchild(block_body); if (conditional_expr == NULL) conditional_expr = ldc_tree(type_signed, immed(0)); tree->addchild(conditional_expr); current_continue = old_continue; current_break = old_break; return tree;}/* * Generate C code for a for loop */ctree *process_for(tree_for *tfor){ label_sym *old_continue = current_continue; label_sym *old_break = current_break; current_break = tfor->brklab(); current_continue = tfor->contlab(); ctree *tree = new ctree(ctree_for); tree->add_object_comments(tfor); ctree *lbpart = new ctree(ctree_assign); lbpart->addchild(ctree_for_for_index(tfor->index())); lbpart->addchild(operand_to_tree(tfor->lb_op())); tree->addchild(lbpart); boolean is_signed = FALSE; if (tfor->index()->type()->is_base()) { base_type *the_base_type = (base_type *)(tfor->index()->type()); is_signed = the_base_type->is_signed(); } if ((((tfor->test() == FOR_SGT) || (tfor->test() == FOR_SGTE) || (tfor->test() == FOR_SLT) || (tfor->test() == FOR_SLTE)) && !is_signed) || ((tfor->test() == FOR_UGT) || (tfor->test() == FOR_UGTE) || (tfor->test() == FOR_ULT) || (tfor->test() == FOR_ULTE)) && is_signed) { error_line(1, tfor, "sign of index doesn't match TREE_FOR test"); } ctree_op comparison_op; switch (tfor->test()) { case FOR_EQ: comparison_op = ctree_eq; break; case FOR_NEQ: comparison_op = ctree_neq; break; case FOR_SGT: case FOR_UGT: comparison_op = ctree_gt; break; case FOR_SGTE: case FOR_UGTE: comparison_op = ctree_gte; break; case FOR_SLT: case FOR_ULT: comparison_op = ctree_lt; break; case FOR_SLTE: case FOR_ULTE: comparison_op = ctree_lte; break; case FOR_SGELE: case FOR_UGELE: error_line(0, tfor, "GELE test in TREE_FOR found:"); error_line(0, tfor, " This is non-standard SUIF; it must be"); error_line(0, tfor, " run through the ``porky -defaults''"); error_line(1, tfor, " pass before s2c can handle it."); default: assert(FALSE); } ctree *reltest = new ctree(comparison_op); reltest->addchild(ctree_for_for_index(tfor->index())); reltest->addchild(operand_to_tree(tfor->ub_op())); tree->addchild(reltest); int thestep; ctree *steptree = NULL; if (tfor->step_is_constant(&thestep)) { if (thestep == 1) { steptree = new ctree(ctree_postinc); steptree->addchild(ctree_for_for_index(tfor->index())); } else if (thestep == -1) { steptree = new ctree(ctree_postdec); steptree->addchild(ctree_for_for_index(tfor->index())); } else { if (thestep >= 0) { if (thestep == 0) warning_line(tfor, "``for'' loop with zero step size"); steptree = new ctree(ctree_addassign); steptree->addchild(ctree_for_for_index(tfor->index())); steptree->addchild(ldc_tree(tfor->index()->type(), immed(thestep))); } else { steptree = new ctree(ctree_subassign); steptree->addchild(ctree_for_for_index(tfor->index())); steptree->addchild(ldc_tree(tfor->index()->type(), immed(-thestep))); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -