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

📄 codegen.cc

📁 PL/0源码
💻 CC
📖 第 1 页 / 共 3 页
字号:
}syntax_code_t * st_token_t::allocate_registers(void){    return syntax_tree_t::allocate_registers();}syntax_code_t * st_identifier_t::allocate_registers(void){    syntax_tree_t::allocate_registers();    // constants are taken care of in optimize.p,    // so it must be a variable    put_in_register (code_gen_info);    return code_gen_info;}syntax_code_t * st_number_t::allocate_registers(void){    syntax_tree_t::allocate_registers();    code_gen_info->result_register = SCRATCH_REG;    // value is not really in this register, but    // free_register ignores it, and generate_code for UN_OP and    // BIN_OP below allocates a real register if necessary    code_gen_info->result_place = R_NUMBER;    code_gen_info->result_value = value;    code_gen_info->registers_used = 0;    return code_gen_info;}syntax_code_t * st_operator_t::allocate_registers(void){    return syntax_tree_t::allocate_registers();}syntax_code_t * st_unary_op_t::allocate_registers(void){    syntax_code_t * p;    syntax_tree_t::allocate_registers();    if (operand) {    p = operand->allocate_registers();        *code_gen_info = *p;        if (code_gen_info->result_register == SCRATCH_REG) {            // constant; no register!            put_in_register (code_gen_info);        }    }    return code_gen_info;}syntax_code_t * st_binary_op_t::allocate_registers(void){    syntax_code_t *p;    syntax_tree_t::allocate_registers();    if (left_operand) {    p = left_operand->allocate_registers();    *code_gen_info = *p;    if ( code_gen_info->result_register == SCRATCH_REG ) {            // constant; no register!        put_in_register (code_gen_info);    }    }    if (right_operand) {    p = right_operand->allocate_registers();    code_gen_info->registers_used |= p->registers_used;    }    free_register (p->result_register);    return code_gen_info;}syntax_code_t * st_statement_t::allocate_registers(void){    syntax_code_t *p;    syntax_tree_t::allocate_registers();    if (next_statement) {    p = next_statement->allocate_registers();    code_gen_info->registers_used |= p->registers_used;    }    return code_gen_info;}syntax_code_t * st_assignment_t::allocate_registers(void){    syntax_code_t *     right_regs = NULL;    syntax_code_t *     p;    syntax_tree_t::allocate_registers();    if (right_side) {    right_regs = right_side->allocate_registers();    code_gen_info->registers_used = right_regs->registers_used;    }    if (left_side) {    p = left_side->allocate_registers();    code_gen_info->registers_used = p->registers_used;    free_register (p->result_register);    }    if (right_regs) {    free_register(right_regs->result_register);        p->registers_used |= right_regs->registers_used;    }    if (next_statement) {    p = next_statement->allocate_registers();    code_gen_info->registers_used |= p->registers_used;    }    return code_gen_info;}syntax_code_t * st_while_t::allocate_registers(void){    syntax_code_t *p;    syntax_tree_t::allocate_registers();    p = condition->allocate_registers();    code_gen_info->registers_used = p->registers_used;    free_register (p->result_register);    if (body) {    p = body->allocate_registers();    code_gen_info->registers_used |= p->registers_used;    free_register (p->result_register);    }    if (next_statement) {    p = next_statement->allocate_registers();    code_gen_info->registers_used |= p->registers_used;    }    return code_gen_info;}syntax_code_t * st_if_t::allocate_registers(void){    syntax_code_t *p;    syntax_tree_t::allocate_registers();    p = condition->allocate_registers();    code_gen_info->registers_used = p->registers_used;    free_register (p->result_register);    if (body) {    p = body->allocate_registers();    code_gen_info->registers_used |= p->registers_used;    free_register (p->result_register);    }    if (next_statement) {    p = next_statement->allocate_registers();    code_gen_info->registers_used |= p->registers_used;    }    return code_gen_info;}syntax_code_t * st_call_t::allocate_registers(void){    syntax_code_t *p;    syntax_tree_t::allocate_registers();    procedure->allocate_registers();    code_gen_info->registers_used = 0;    if (next_statement) {    p = next_statement->allocate_registers();    code_gen_info->registers_used |= p->registers_used;    }    return code_gen_info;}syntax_code_t * st_declaration_t::allocate_registers(void){    syntax_tree_t::allocate_registers();    if (next_declaration)    next_declaration->allocate_registers();    return code_gen_info;}syntax_code_t * st_block_t::allocate_registers(void){    syntax_tree_t::allocate_registers();    if (declarations)    declarations->allocate_registers();    if (body)    body->allocate_registers();    return code_gen_info;}//////////////////////////////////////////////////////////////////////////////////  Code Generation////  Each node in the syntax tree must implement the generate_code member//  function.  Generate_code outputs the code for the node to the output file//  by using the overloaded code generation function mips_op.  The optional//  member function generate_lcode outputs the code to access the lvalue of//  a node.  It is only used for variables and currently only when making//  assignments.//syntax_code_t * syntax_tree_t::generate_code(void){    dump_syntax_tree(this);    die_compiler("Unexpected call to syntax_tree_t::generate_code");    return code_gen_info;        // doesn't really return; just avoid complaint from g++}syntax_code_t * syntax_tree_t::generate_lcode(mips_register_t data){    UNUSED_PARAM(data);    dump_syntax_tree(this);    die_compiler("Unexpected call to syntax_tree_t::generate_lcode");    return code_gen_info;        // doesn't really return; just avoid complaint from g++}syntax_code_t * st_token_t::generate_code(void){    return code_gen_info;}syntax_code_t * st_identifier_t::generate_code(void){    symbol_code_t *ident_code = symbol_entry->generate_code();    if (ident_code->data_place == R_LABEL) {        if (symbol_entry == input_symbol) {            // Input preserves all regs and is actually a subroutine.            mips_op(M_JAL, ident_code->where.label);            mips_op(M_MOVE, code_gen_info->result_register, SCRATCH_REG);        }        else            mips_op(M_LW, code_gen_info->result_register,                    ident_code->where.label);    }    else if (ident_code->data_place == R_OFFSET) {        mips_op(M_LW, code_gen_info->result_register,                ident_code->where.offset.pos,                ident_code->where.offset.reg);    }    return code_gen_info;}//////////  Generate code for accessing the lvalue of a varaible.  If the "data"//  is ZERO_REG (i.e. 0) then the callee wants the address of the variable,//  if "data" is != ZERO_REG, then the callee wants generate_lcode to store//  the value in "data" into the varaible.//syntax_code_t * st_identifier_t::generate_lcode(mips_register_t data){    symbol_code_t *ident_code = symbol_entry->generate_code();    if (ident_code->data_place == R_LABEL) {        if (data != ZERO_REG) {            // If the destination is not ZERO_REG, then the caller wants            // us to store the value from the register into the symbol.            if (symbol_entry == output_symbol) {                // Output preserves all regs and is actually a subroutine.                mips_op(M_MOVE, OUTPUT_REG, data);                mips_op(M_JAL, ident_code->where.label);            }            else                mips_op(M_SW, data, ident_code->where.label);        }        else {            // If the destination is ZERO_REG, then the caller wants            // us to load the address into a register for later use.            mips_op(M_LA, code_gen_info->result_register,                    ident_code->where.label);        }    }    else if (ident_code->data_place == R_OFFSET) {        if (data != ZERO_REG) {            mips_op(M_SW, data, ident_code->where.offset.pos,                ident_code->where.offset.reg);        }        else {            mips_op(M_LA, code_gen_info->result_register,                    ident_code->where.offset.pos,                    ident_code->where.offset.reg);        }    }    return code_gen_info;}syntax_code_t * st_number_t::generate_code(void){    return code_gen_info;               // Numbers don't use registers or OPs.}syntax_code_t * st_operator_t::generate_code(void){    dump_syntax_tree(this);    die_compiler("Unexpected call to st_operator_t::generate_code");    return code_gen_info;        // doesn't really return; just avoid complaint from g++}syntax_code_t * st_unary_op_t::generate_code(void){    syntax_code_t * operand_code = operand->generate_code();    switch (operand_code->result_place) {    case R_REGISTER:        mips_op(M_MOVE, code_gen_info->result_register,                operand_code->result_register);        break;    case R_NUMBER:        mips_op(M_LI, code_gen_info->result_register,                operand_code->result_value);        break;    default:        dump_syntax_tree(operand);        die_compiler("Unknown result place.");        break;    }    token_attrib_t t = op->get_attributes();    switch (t.get_minor()) {    case MIN_MINUS:        mips_op(M_SUB, code_gen_info->result_register, ZERO_REG,                code_gen_info->result_register);        break;    case MIN_ODD:        mips_op(M_ANDI, code_gen_info->result_register,                code_gen_info->result_register, 1);        break;    default:        ostrstream ost;        ost << "Unknown MINOR unary operator: " << t.get_minor();        die_compiler(ost.str());        break;    }    return code_gen_info;}syntax_code_t * st_binary_op_t::generate_code(void){    syntax_code_t *     left_code;    syntax_code_t *     right_code;    mips_register_t     reg;    left_code = left_operand->generate_code();    right_code = right_operand->generate_code();    switch (left_code->result_place) {    case R_REGISTER:        mips_op(M_MOVE, code_gen_info->result_register,                left_code->result_register);        break;    case R_NUMBER:        mips_op(M_LI, code_gen_info->result_register, left_code->result_value);        break;    default:        dump_syntax_tree(left_operand);        die_compiler("Unknown result place.");        break;    }    switch (right_code->result_place) {    case R_REGISTER:        reg = right_code->result_register;        break;

⌨️ 快捷键说明

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