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

📄 codegen.cc

📁 PL/0源码
💻 CC
📖 第 1 页 / 共 3 页
字号:
    case R_NUMBER:        reg = SCRATCH_REG;        mips_op(M_LI, reg, right_code->result_value);        break;    default:        dump_syntax_tree(right_operand);        die_compiler("Unknown result place.");        break;    }    token_attrib_t t = op->get_attributes();    switch (t.get_minor()) {    case MIN_PLUS:        mips_op(M_ADD, code_gen_info->result_register,                code_gen_info->result_register, reg);        break;    case MIN_MINUS:        mips_op(M_SUB, code_gen_info->result_register,                code_gen_info->result_register, reg);        break;    case MIN_TIMES:        mips_op(M_MULT, code_gen_info->result_register, reg);        mips_op(M_MFLO, code_gen_info->result_register);        break;    case MIN_SLASH:        mips_op(M_DIV, code_gen_info->result_register, reg);        mips_op(M_MFLO, code_gen_info->result_register);        break;    case MIN_EQ:        mips_op(M_SEQ, code_gen_info->result_register,                code_gen_info->result_register, reg);        break;    case MIN_NE:        mips_op(M_SNE, code_gen_info->result_register,                code_gen_info->result_register, reg);        break;    case MIN_LT:        mips_op(M_SLT, code_gen_info->result_register,                code_gen_info->result_register, reg);        break;    case MIN_LE:        mips_op(M_SLE, code_gen_info->result_register,                code_gen_info->result_register, reg);        break;    case MIN_GT:        mips_op(M_SGT, code_gen_info->result_register,                code_gen_info->result_register, reg);        break;    case MIN_GE:        mips_op(M_SGE, code_gen_info->result_register,                code_gen_info->result_register, reg);        break;    default:        ostrstream ost;        ost << "Unknown MINOR binary operator: " << t.get_minor();        die_compiler(ost.str());        break;    }    return code_gen_info;}syntax_code_t * st_statement_t::generate_code(void){    dump_syntax_tree(this);    die_compiler("Unexpected call to st_statement_t::generate_code");    return code_gen_info;        // doesn't really return; just avoid complaint from g++}syntax_code_t * st_assignment_t::generate_code(void){    syntax_code_t *     right_code;    mips_register_t     reg;    right_code = right_side->generate_code();    switch (right_code->result_place) {    case R_REGISTER:        reg = right_code->result_register;        break;    case R_NUMBER:        reg = SCRATCH_REG;        mips_op(M_LI, reg, right_code->result_value);        break;    default:        dump_syntax_tree(right_side);        die_compiler("Unknown result place.");        break;    }    left_side->generate_lcode(reg);    if (next_statement)    next_statement->generate_code();    return code_gen_info;}syntax_code_t * st_while_t::generate_code(void){    mips_name_t         l1;    mips_name_t         l2;    syntax_code_t *     cond_code;    next_name(l1, 'l');    next_name(l2, 'l');    mips_op(l1);    cond_code = condition->generate_code();    if (cond_code->result_place == R_REGISTER)        mips_op(M_BEQ, cond_code->result_register, ZERO_REG, l2);    else if (cond_code->result_place == R_NUMBER) {        if (!cond_code->result_value)   // Optimize known loop            mips_op(M_B, l2);    }    else {        dump_syntax_tree(condition);        die_compiler("Unknown result place.");    }    if (body)        body->generate_code();    mips_op(M_J, l1);    mips_op(l2);    if (next_statement)    next_statement->generate_code();    return code_gen_info;}syntax_code_t * st_if_t::generate_code(void){    mips_name_t         l1;    syntax_code_t *     cond_code;    next_name(l1, 'l');    cond_code = condition->generate_code();    if (cond_code->result_place == R_REGISTER)        mips_op(M_BEQ, cond_code->result_register, ZERO_REG, l1);    else if (cond_code->result_place == R_NUMBER) {        if (!cond_code->result_value)   // Optimize known loop            mips_op(M_B, l1);    }    else {        dump_syntax_tree(condition);        die_compiler("Unknown result place.");    }    if (body)        body->generate_code();    mips_op(l1);    if (next_statement)    next_statement->generate_code();    return code_gen_info;}syntax_code_t * st_call_t::generate_code(void){    mips_src_lines (procedure->get_location());    se_procedure_t *symbol =        dynamic_cast<se_procedure_t *>(procedure->get_symbol());        // should never fail    if (symbol->get_scope() != predefined_scope            && symbol->get_scope() != global_scope) {        mips_register_t     addrReg = FP_REG;        scope_number_t      depth = scope_depth(symbol->get_scope());        if (depth > 0)            mips_cm(string("follow the static chain to ")                    + string(token_chars(symbol->get_name())));        for (int i = 0; i < depth; i++) {            mips_op(M_LW, SCRATCH_REG2, STATIC_LINK_OFFSET, addrReg);            addrReg = SCRATCH_REG2;        }        mips_cm("Create static link");        mips_op(M_SW, addrReg, -4, SP_REG);            // WARNING: this puts data beyond the stack pointer,            // which is generally an unsafe thing to do.  It works            // so long as nothing asynchronous (like a signal) occurs.            // It really ought to be changed.    }    symbol_code_t * ident_code = symbol->generate_code();    if (ident_code->data_place == R_LABEL) {        mips_op(M_JAL, ident_code->where.label);    }    else if (ident_code->data_place == R_OFFSET) {        mips_op(M_LA, SCRATCH_REG2, ident_code->where.offset.pos,                ident_code->where.offset.reg);        mips_op(M_JAL, SCRATCH_REG2);    }    if (next_statement)    next_statement->generate_code();    return code_gen_info;}syntax_code_t * st_declaration_t::generate_code(void){    dump_syntax_tree(this);    die_compiler("Unexpected call to st_declaration_t::generate_code");    return code_gen_info;        // doesn't really return; just avoid complaint from g++}syntax_code_t * st_constant_t::generate_code(void){    if (value)        value->generate_code();    if (next_declaration)        next_declaration->generate_code();    return code_gen_info;}syntax_code_t * st_variable_t::generate_code(void){    if (next_declaration)        next_declaration->generate_code();    return code_gen_info;}syntax_code_t * st_procedure_t::generate_code(void){    se_procedure_t *proc_symbol =        dynamic_cast<se_procedure_t *>(identifier->get_symbol());        // should never fail    mips_src_lines(proc_symbol->declaration_location());    open_scope(proc_symbol->get_sub_scope());    if (block) {        block->set_symbol(proc_symbol);        block->generate_code();    }    close_scope();    if (next_declaration)        next_declaration->generate_code();    return code_gen_info;}syntax_code_t * st_block_t::generate_code(void){    int                 frameSize;    int                 staticLinkPart;    int                 subscope;    if (declarations)        declarations->generate_code();    if (symbol)        subscope = symbol->get_sub_scope();    else        subscope = global_scope;    {        ostrstream ost;        ost << "Variables for scope " << subscope;        mips_cm(ost.str());    }    mips_op(M_DATA);    for (symbol_entry_t *p = first_in_scope(subscope)             ; p != NULL; p = p->next()) {        p->generate_data();    }    {        ostrstream ost;        ost << "Code for scope " << subscope;        mips_cm(ost.str());    }    mips_op(M_TEXT);    if (symbol) {        mips_op(M_ENT, symbol->get_code_gen_info()->where.label);        mips_op(symbol->get_code_gen_info()->where.label);    }    else    {        mips_cm("program starts here");        mips_op(M_ENT, "start");        mips_op("start");        mips_op(M_SW, RA_REG, "startret");    }    if (body) {        // non-empty procedure        body->allocate_registers();    }    if (symbol) {        int                 scope;        // prologue:        scope = symbol->get_scope();        frameSize = space_in_scope[subscope] + 8;        if (scope == predefined_scope || scope == global_scope)            //  Don't need space for the static link if the            //  procedure is declared at file level.            staticLinkPart = 0;        else            staticLinkPart = 4;        mips_cm("allocate frame");        mips_op(M_ADDI, SP_REG, SP_REG, -(frameSize + staticLinkPart));        mips_op(M_SW, FP_REG, frameSize - 8, SP_REG);        if (!symbol->is_leaf()) {            mips_cm("non-leaf subroutine");            mips_op(M_SW, RA_REG, frameSize - 4, SP_REG);        }        mips_op(M_ADDI, FP_REG, SP_REG, frameSize - 8);    }    if (body)        body->generate_code();    if (symbol) {        // epilogue:        if (!symbol->is_leaf())            mips_op(M_LW, RA_REG, frameSize - 4, SP_REG);        mips_cm("restore fp");        mips_op(M_LW, FP_REG, frameSize - 8, SP_REG);        mips_cm("discard frame");        mips_op(M_ADDI, SP_REG, SP_REG, frameSize + staticLinkPart);    }    mips_src_finalize();    if (symbol) {        mips_op(M_JR, RA_REG);        mips_op(M_END, symbol->get_code_gen_info()->where.label);    }    else {        mips_op(M_LW, RA_REG, "startret");        mips_op(M_JR, RA_REG);        mips_op(M_END, "start");    }    return code_gen_info;}//////////  Traverse abstract syntax tree and send output to code file//void generate_code(const char * file_name){    code.open(file_name);    if (!code) {        die_compiler (string("Unable to open output file: ")            + string(file_name));    }    switch (compiler_target) {    case T_SGI: code << sgi_prologue << "\n"; break;    case T_SPIM: code << spim_prologue << "\n"; break;    }    code << "\t.file 2,\"" << file_name << "\"\n";    if (ast_root != NULL) {        // non-empty block        allocate_space();        mips_cm("procedures declared here");        mips_op(M_DATA);        mips_op("startret", M_WORD, 0);        ast_root->generate_code();    } else {        mips_cm("empty program");        mips_op(M_TEXT);        mips_op(M_ENT, "start");        mips_op("start");        mips_op(M_JR, RA_REG);        mips_op(M_END, "start");    }}// End of File

⌨️ 快捷键说明

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