⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gen.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* file "gen.cc" of the snoot program for SUIF *//*  Copyright (c) 1994 Stanford University    All rights reserved.    This software is provided under the terms described in    the "suif_copyright.h" include file. */#include <suif_copyright.h>/* *  The back end of the front end. * *  For help in understanding this code, read the documentation contained *  in this file after reading "A Code Generation Interface for ANSI C" *  by Fraser and Hanson from the lcc documentation. * *  History: * *        ? - 12/1992  Originally written and maintained for Old SUIF *                         by Rob French <rfrench@cs.stanford.edu>. *  12/1992 -  8/1993  Maintained and rewritten for New SUIF by *                         Todd Smith <tsmith@cs.stanford.edu>. *   8/1993 -  ?       Maintained and rewritten for even newer SUIF by *                        Chris Wilson <cwilson@cs.stanford.edu> * */#define RCS_BASE_FILE gen_cc#include <stdlib.h>#include <string.h>#include <ctype.h>#include <suif1.h>#include "c.h"RCS_BASE(    "$Id: gen.cc,v 1.2 1999/08/25 03:28:20 brm Exp $")/* * Some symbol names will have to be generated.  The following * prefixes are used in naming various types of symbols.  If the * "passing type" of a parameter is not the same as the type inside * the called function, then it sends us the "passed parameter" and * the "real parameter"; the passed parameter gets a prefix and is * converted to the real one at the beginning of the function. * Temporary globals are given numbers in defsymbol(), to which the * prefix is prepended.  The last number given is kept in * curr_tmp_global. */static char *tmp_string_prefix = "__tmp_string_";static char *tmp_param_prefix  = "__tmp_param_";int curr_tmp_global = -1;file_set_entry *outf;              // this is where all the output goesproc_sym *curr_proc = NULL;        // pointer to object for current procedure/* *  The Stacks * *  We need three stacks to keep track of necessary information in a *  procedure: *    1) list_stack *        This is the stack of nested instruction lists which have *        currently been suspended.  The one in current use is stored *        in curr_list.  New lists are created for new blocks and for *        the various parts of SUIF macros (if's, loop's, and for's, *        via domacrocmd()).  curr_list is used for appending *        instructions as they are created. *    2) symtab_stack *        This is the stack of nested symbol tables which have *        currently been suspended, which corresponds exactly to the *        stack of currently suspended blocks.  The one in current use *        is stored in curr_symtab.  New symbol tables are created *        only for new blocks.  curr_symtab and symbol tables in the *        stack are used for entering local variables. *    3) block_num_stack *        This stack is a stack of block numbers that coincides with *        symtab_stack.  A sequence of blocks with the same parent *        block is numbered 0...? in the position in this stack *        corresponding to that nesting depth; thus, the numbers on *        the stack up to the current nesting depth give each block a *        unique hierarchical name.  symtab_stack functions handle *        this stuff and always keep the current number for use in *        curr_block_num. */const int MAX_NESTING = 1000;          // Maximum number of nested lists or                                       //  symbol tablestree_node_list *curr_list = NULL;tree_node_list *list_stack[MAX_NESTING];int list_stack_ptr = -1;block_symtab *curr_symtab = NULL;block_symtab *symtab_stack[MAX_NESTING];int symtab_stack_ptr = -1;int block_num_stack[MAX_NESTING+2];int curr_block_num = -1;/* * The top block of a function is created in start_function(), so * when stabblock() is called the first time, we don't want to create * it again.  This boolean tells if stabblock() has skipped it yet. * It is also used at the end of functions when blocks are ended. */int skipped_top_block = 0;int curr_nesting_level = -1;       // 0 == top block of a function#define MAXARGS 1000               // Maximum number of procedure argumentsint num_args = 0;operand args[MAXARGS];             // store up the arguments before a callvoid append_instr(instruction *instr);static void finalize_suif_proc(proc_sym *the_proc);static void finalize_suif_node(tree_node *the_node, void *);static void finalize_suif_instr(instruction *the_instr, void *);static annote *make_line_annote(Coordinate *location);/******************************************************************** * FUNCTIONS FOR HANDLING STACKS                                    * ********************************************************************/void symtab_stack_init(void)  { block_num_stack[1] = -1; }int symtab_stack_empty(void)  { return (symtab_stack_ptr == -1); }void symtab_stack_push(block_symtab *b)  {    assert(symtab_stack_ptr < MAX_NESTING-1);    symtab_stack[++symtab_stack_ptr] = b;    curr_block_num = ++(block_num_stack[symtab_stack_ptr+1]);    block_num_stack[symtab_stack_ptr+2] = -1;  }block_symtab *symtab_stack_pop(void)  {    assert(symtab_stack_ptr > -1);    curr_block_num = block_num_stack[symtab_stack_ptr];    return symtab_stack[symtab_stack_ptr--];  }void list_stack_push(tree_node_list *tnl)  {    assert(list_stack_ptr < MAX_NESTING-1);    list_stack[++list_stack_ptr] = tnl;  }tree_node_list *list_stack_pop(void)  {    assert(list_stack_ptr > -1);    return list_stack[list_stack_ptr--];  }/******************************************************************** * MISCELLANEOUS USEFUL FUNCTIONS                                   * * 1. functions dealing with scopes and symbol tables               * ********************************************************************/// returns currently active symbol tableextern base_symtab *get_current_symtab(void)  {    return ((curr_symtab == NULL) ? ((base_symtab *)(outf->symtab())) :                                    ((base_symtab *)curr_symtab));  }/******************************************************************** * LCC BACK-END FUNCTIONS FOR FUNCTION DEFINITION                   * ********************************************************************//* * addition to lcc interface; called a little while before function() * in order to set up the current procedure before defsymbol() is * called with some important information */extern void start_function(Symbol f, Symbol callee[],                           type_node *caller_types[], int num_params,                           Coordinate *block_location)  {    assert(f->suif_symbol != NULL);    /*     *  function symbol should have already been sent to defsymbol();     *  set up all its characteristics, and make sure it isn't marked as     *  extern     */    curr_proc = (proc_sym *) f->suif_symbol;    curr_proc->set_src_lang(src_c);    assert(symtab_stack_empty());    assert(curr_nesting_level == -1);    // set up function to receive symbols, types, code    tree_block *b = curr_proc->block();    curr_list = b->body();    curr_symtab = b->symtab();    symtab_stack_init();    curr_nesting_level = 0;    skipped_top_block = 0;    b->annotes()->append(make_line_annote(block_location));    /* parameters are in reverse order */    for (int param_num = num_params; param_num > 0; --param_num)      {        Symbol s = callee[param_num - 1];        var_sym *the_var = curr_symtab->new_var(s->type, s->name);        the_var->set_userdef();        s->suif_symbol = the_var;        if (s->sclass == REGISTER)            the_var->append_annote(k_is_declared_reg, new immed_list);        var_sym *the_param = the_var;        if (s->type->unqual() != caller_types[param_num - 1]->unqual())          {            char *temp_name =                    new char[strlen(tmp_param_prefix) + strlen(s->name) + 1];            strcpy(temp_name, tmp_param_prefix);            strcat(temp_name, s->name);            the_param =                    curr_symtab->new_var(caller_types[param_num - 1],                                         temp_name);            operand param_op =                    fold_real_1op_rrr(io_cvt, the_var->type()->unqual(),                                      operand(the_param));            curr_list->append(create_assignment(the_var, param_op));            delete[] temp_name;          }        the_param->set_param();        curr_proc->block()->proc_syms()->params()->append(the_param);      }    annote *a = new annote(k_enable_exceptions);    a->immeds()->append("int_divide-by-0");    curr_proc->block()->annotes()->append(a);  }void function(void)  {    // clean up after the function    curr_symtab = NULL;    curr_list = NULL;    assert(symtab_stack_empty());    assert(curr_nesting_level == 0);    curr_nesting_level = -1;    finalize_suif_proc(curr_proc);    curr_proc->write_proc(outf);    curr_proc->flush_proc();  }/******************************************************************** * BEGINNING/END OF BLOCK FUNCTIONS                                 * ********************************************************************/// enter/exit a block in the emit phase, with its user-defined localsvoid stabblock(int enter_or_exit)  {    // block entry code    if (enter_or_exit == '{')      {        // if we just started a procedure and created its top block,        //   then skip it and don't do anything here        if (curr_nesting_level == 0 && !skipped_top_block)            skipped_top_block = 1;        // otherwise, push current list/symtab and create a child block        else          {            list_stack_push(curr_list);            symtab_stack_push(curr_symtab);            tree_node_list *new_list = new tree_node_list;            block_symtab *new_symtab =                    new block_symtab(stringf("%d", curr_block_num));            tree_block *b = new tree_block(new_list, new_symtab);            curr_list->append(b);            curr_list = new_list;            if (curr_symtab != NULL)                curr_symtab->add_child(new_symtab);            curr_symtab = new_symtab;            curr_nesting_level++;          }      }    // block exit code    else if (enter_or_exit == '}')      {        // if we are ending a procedure, then reset skipped_top_block        //   and don't do anything yet

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -