📄 main.cc
字号:
delete annote_name_strings; delete annote_opcode_strings; delete annote_place_strings; if (argc < 2) { fprintf(stderr, "No input SUIF file specified.\n"); usage(); exit(1); } if (argc > 3) { fprintf(stderr, "Too many files specified.\n"); usage(); exit(1); } *input_filespec = argv[1]; if (argc == 3) *output_filespec = argv[2]; else *output_filespec = NULL; }static void usage(void){ char *usage_message[] = {"usage: s2c [options] SUIF-file [c-file]\n","\n"," options:\n"," -logic-simp\n"," do simple logical simplification\n"," -pseudo\n"," write pseudo-C if correct C impossible\n"," -keep-casts\n"," keep all SUIF type casts (by default they are folded away when C\n"," would put in implicit casts)\n"," -omit-header\n"," do not write header comments\n"," -no-warn\n"," do not issue any warnings\n"," -always-intnum\n"," never use C type names for integers\n"," -array-exprs\n"," use illegal array expressions\n"," -annotes-all\n"," write all annotations as comments\n"," -annotes-named <name>\n"," write all annotations with the given name\n"," -annotes-opcode <opcode>\n"," write all annotations on instructions with the given opcode\n"," -annotes-object-kind <kind>\n"," write all the annotations on one specific kind of object, where\n"," <kind> is one of the following:\n"," fses all file set entries\n"," nodes all tree nodes (except tree_instr's)\n"," loops all ``loop'' nodes\n"," fors all ``for'' nodes\n"," ifs all ``if'' nodes\n"," blocks all ``block'' nodes\n"," all-instrs all instructions\n"," symtabs all symtabs\n"," all-syms all symbols\n"," vars all variable symbols\n"," proc-syms all procedure symbols\n"," labels all label symbols\n"," var-defs all variable definitions\n"," types all types\n"," -gcc-bug\n"," use a work-around for a gcc bug in initialization of unnamed\n"" bit-fields\n"" -drop-bounds\n"," make for bounds temporaries if they contain loads, uses of\n"," symbols with their addresses possibly taken, including\n"," globals, or SUIF intrinsics that might be turned into\n"," control-flow, such as io_max; the idea is to make sure it is\n"," clear to the back-end C compiler that the bounds are loop\n"," invariant, so loop optimizations such as software pipeling may\n"," be done\n"," -ll-suffix\n"," use ``ll'' and ``ull'' suffixes on integer constants of\n"," ``long long'' and ``unsigned long long'' type respectively\n"," -explicit-zero-init\n"," make zero initializations of static data explicit; by default,\n"," such initializations are left implicit\n"," -limit-escape-sequences\n"," do not produce simple alphabetic escape sequences other than\n"," \\n (i.e. no \\a, \\b, \\f, \\r, \\t, or \\v); this is a " "work-around\n"," for some back-end compilers that don't recognize all the ANSI\n"," C required alphabetic escape sequences (the DEC OSF 3.2 cc\n"," compiler, for example, doesn't recognize \\a)\n"," -fill-field-space-with-char-arrays\n"," use character arrays to pad structures instead of bit fields,\n"," when possible; this is a work-around for back-end compilers\n"," that lay out bit fields differently\n"}; for (size_t line_num = 0; line_num < sizeof(usage_message) / sizeof(char *); ++line_num) { fprintf(stderr, "%s", usage_message[line_num]); }}/* * Initialize the macro table. Most of this was done statically, but the * expansion of the ``rotate'' macro needs to use the size in bits of an * addressable unit in the target machine, which is read in from the SUIF file * by the library. */static void initialize_macro_table(void) { for (int index = 0; macro_table[index].replacement != NULL; ++index) { if (macro_table[index].opcode == io_rot) { char *new_replacement = new char[strlen(macro_table[index].replacement) + 20]; sprintf(new_replacement, macro_table[index].replacement, target.addressable_size); macro_table[index].replacement = new_replacement; } } }static void read_global_annotations(global_symtab *the_globals) { annote_list_iter the_iter(the_globals->annotes()); while (!the_iter.is_empty()) { annote *this_annote = the_iter.step(); if (this_annote->name() == k_s2c_genop_format) { immed_list *format_immeds = this_annote->immeds(); boolean matched = FALSE; if (format_immeds->count() == 2) { immed first_data = (*format_immeds)[0]; immed second_data = (*format_immeds)[1]; if (first_data.is_string() && second_data.is_string()) { register_gen_op(first_data.string(), second_data.string(), TRUE, 0); matched = TRUE; } } else if (format_immeds->count() == 3) { immed first_data = (*format_immeds)[0]; immed second_data = (*format_immeds)[1]; immed third_data = (*format_immeds)[2]; if (first_data.is_string() && second_data.is_integer() && third_data.is_string()) { register_gen_op(first_data.string(), third_data.string(), FALSE, second_data.integer()); matched = TRUE; } } if (!matched) { error_line(1, NULL, "bad format for \"%s\" annotation", k_s2c_genop_format); } } } }static void print_header(void) { if (!omit_header) { time_t systime; fprintf(c_file, "/*\n"); fprintf(c_file, " * This file was created automatically from SUIF\n"); systime = time(NULL); char *time_string = ctime(&systime); char *new_time_string = new char[strlen(time_string)]; strncpy(new_time_string, time_string, strlen(time_string)); new_time_string[strlen(time_string) - 1] = 0; fprintf(c_file, " * on %s.\n", new_time_string); delete[] new_time_string; fprintf(c_file, " *\n"); fprintf(c_file, " * Created by:\n"); fprintf(c_file, " * %s %s %s\n", _suif_prog_base_name, prog_ver_string, prog_who_string); fprintf(c_file, " * Based on SUIF distribution %s\n", libsuif_suif_string); fprintf(c_file, " * Linked with:\n"); library_list_iter library_iter(suif_libraries); while (!library_iter.is_empty()) { suif_library *this_library = library_iter.step(); fprintf(c_file, " * lib%s %s %s\n", this_library->name, this_library->version, this_library->compile_info); } fprintf(c_file, " */\n\n\n"); } boolean definition = FALSE; for (int index = 0; macro_table[index].replacement != NULL; ++index) { if (macro_table[index].used) { fix_macro_name(&(macro_table[index])); fprintf(c_file, "#define %s(x", macro_table[index].op_name); if (macro_table[index].num_operands == 2) fprintf(c_file, ",y"); else assert(macro_table[index].num_operands == 1); fprintf(c_file, ") %s\n", macro_table[index].replacement); definition = TRUE; } } if (definition) fprintf(c_file, "\n"); }/* * Add globals. */void process_globals(ctree *ret, global_symtab *syms){ layout_groups_for_symtab(syms); preprocess_symtab(syms); add_typedecls(ret, syms); add_vardecls(ret, syms); add_symtab_annotes(ret, syms); add_pound_lines_for_object(syms, ret);}/* * Add parameters to a funcdecl ctree. */extern ctree *process_params(proc_sym *psym){ ctree *func = new ctree(ctree_funcdef, psym); sym_node_list_iter snli(psym->block()->proc_syms()->params()); while (!snli.is_empty()) { sym_node *sym = snli.step(); assert(sym->is_var()); var_sym *vs = (var_sym*)sym; assert(vs->is_param()); ctree *var = new ctree(ctree_vardecl, vs); func->addchild(var); } return func;}extern void transform_and_print_ctree(io_class *out, ctree *the_ctree) { /* The order here is important! */ the_ctree->extract_data(); the_ctree->fold_converts(); the_ctree->do_basic_folding(); the_ctree->flatten(); if (log_simp) { the_ctree->cond_simp(); the_ctree->log_simp(); } the_ctree->truncate_zeros_in_static_inits(); the_ctree->print_as_c(out, 0); }/* * Process a procedure from a TREE into a CTREE. */ctree *process_proc(proc_sym *psym){ preprocess_proc(psym->block()); preprocess_symtab(psym->block()->symtab()); ctree *func_tree = process_params(psym); ctree *main_tree = new ctree(ctree_semi); /* * Add local variable declarations to the C tree. */ add_typedecls(main_tree, psym->block()->symtab()); add_vardecls(main_tree, psym->block()->symtab()); add_symtab_annotes(main_tree, psym->block()->symtab()); add_pound_lines_for_object(psym->block()->symtab(), main_tree); /* * Generate a C tree for the instruction list. */ main_tree->addchild(process_node_list(psym->block()->body(), NULL, NULL)); func_tree->addchild(main_tree); return func_tree;}/* * Generate a C tree for a list of tree nodes */extern ctree *process_node_list(tree_node_list *nl, label_sym *target, ctree **conditional_expr){ ctree *ret = new ctree(ctree_semi); ctree *tree; ctree *pending_expr = NULL; label_sym *pending_target = NULL; tree_node_list_iter tnli(nl); while (!tnli.is_empty()) { tree_node *node = tnli.step(); tree = NULL; if ((pending_expr != NULL) && (!node->is_instr())) { ctree *branch_tree = create_branch(pending_target, pending_expr); ret->addchild(branch_tree); pending_expr = NULL; pending_target = NULL; } switch (node->kind()) { case TREE_INSTR: { tree_instr *the_tree_instr = (tree_instr *)node; ctree *pre_instr = NULL; tree = process_base_inst(the_tree_instr->instr(), &pending_expr, &pending_target, &pre_instr); if (pre_instr != NULL) ret->addchild(pre_instr); break; } case TREE_LOOP: tree = process_loop((tree_loop*)node); break; case TREE_FOR: tree = process_for((tree_for*)node); break; case TREE_IF: tree = process_if((tree_if*)node); break; case TREE_BLOCK: tree = process_block((tree_block*)node); break; } if (tree) ret->addchild(tree); } if (pending_expr != NULL) { if ((target == pending_target) && (conditional_expr != NULL)) { *conditional_expr = pending_expr; } else { ctree *branch_tree = create_branch(pending_target, pending_expr); ret->addchild(branch_tree); } } return ret;}extern ctree *process_solo_instr(instruction *the_instr) { ctree *semi_tree = new ctree(ctree_semi); ctree *pending_expr = NULL; label_sym *pending_target = NULL; ctree *pre_instr = NULL; ctree *base_tree = process_base_inst(the_instr, &pending_expr, &pending_target, &pre_instr); if (pre_instr != NULL) semi_tree->addchild(pre_instr); if (base_tree != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -