📄 mips.cc
字号:
////////////////////////////////////////////////////////////////////////////////// mips.[h,cc] -- procedures for generating MIPS code//#include <string>#include <strstream>#include <iomanip>#include "inpbuf.h"#include "mips.h"bool generate_comments = false;bool generate_debug_code = false;bool g_peep_hole_optimize = true;target_t compiler_target = T_SPIM;static input_buffer_t * last_src_line = NULL;static int last_src_line_num = 0;static string last_comment;////////// Output source lines up to sl.//void mips_src_lines(location_t sl){ input_buffer_t * line; input_buffer_t * next; string data; int line_num; int this_line_no; if (generate_debug_code) { line = sl.line; if (last_src_line_num == 0) { data = get_line_info(line, last_src_line, last_src_line_num); code << "\t.loc\t2 " << last_src_line_num << "\n" << " #" << last_src_line_num << " " << data; } else { data = get_line_info(line, next, this_line_no); if (this_line_no > last_src_line_num) { line = last_src_line; code << "\t.loc\t2 " << this_line_no << "\n"; do { data = get_line_info(line, next, line_num); if (line_num > last_src_line_num) { code << " #" << setw(4) << line_num << " " << data; } line = next; } while ((line != NULL) && (line_num < this_line_no)); last_src_line = line; last_src_line_num = line_num; } } }}////////// Print remaining source lines.//void mips_src_finalize(void){ input_buffer_t * line; input_buffer_t * next; string data; int line_num; if (generate_debug_code && last_src_line_num != 0) { line = last_src_line; if (line != NULL) { get_line_info(line, next, line_num); code << "\t.loc\t2 " << line_num << "\n"; } while (line != NULL) { data = get_line_info(line, next, line_num); code << " #" << line_num << " " << data; line = next; } }}////////// mips_cm: Prepare a comment for the next opcode.//void mips_cm(string comment){ last_comment = comment;}////////// Attach a comment if there is one to the end of the last opcode.//static void mips_comment(void){ if (!generate_comments || last_comment.length() == 0) code << "\n"; else code << "\t\t# " << last_comment << "\n"; last_comment = "";}////////// generate an opcode name.//static void mips_opcode(const mips_opcode_t op){ switch (op) { case M_JAL: code << "\tjal"; break; case M_JALR: code << "\tjalr"; break; case M_J: code << "\tj"; break; case M_ENT: code << "\t.ent"; break; case M_END: code << "\t.end"; break; case M_FILE: code << "\t.file 2,"; break; case M_JR: code << (compiler_target == T_SPIM ? "\tjr" : "\tj"); break; case M_MFLO: code << "\tmflo"; break; case M_LW: code << "\tlw"; break; case M_SW: code << "\tsw"; break; case M_MOVE: code << "\tmove"; break; case M_MULT: code << "\tmult"; break; case M_DIV: code << "\tdiv"; break; case M_BEQ: code << "\tbeq"; break; case M_BNE: code << "\tbne"; break; case M_SEQ: code << "\tseq"; break; case M_SNE: code << "\tsne"; break; case M_SLT: code << "\tslt"; break; case M_SLE: code << "\tsle"; break; case M_SGT: code << "\tsgt"; break; case M_SGE: code << "\tsge"; break; case M_SUB: code << "\tsub"; break; case M_ADD: code << "\tadd"; break; case M_ADDI: code << "\taddi"; break; case M_ANDI: code << "\tandi"; break; case M_XORI: code << "\txori"; break; case M_LI: code << "\tli"; break; case M_LA: code << "\tla"; break; case M_B: code << "\tb"; break; case M_DATA: code << "\t.data"; break; case M_TEXT: code << "\t.text"; break; case M_WORD: code << "\t.word"; break; default: ostrstream ost; ost << "Bad MIPS opcode: " << op; die_compiler(ost.str()); break; }}////////////////////////////////////////////////////////////////////////////////// mips_op: Generate a MIPS operation instruction.//// This one function is overloaded to generate every class of instructions// used.//////////// generate an instruction with a label. E.g. 'jal output'//void mips_op(const mips_opcode_t op, const mips_name_t label){ mips_opcode(op); code << "\t" << label; mips_comment();}////////// generate a 1-register instruction. E.g. 'jr $31'//void mips_op(const mips_opcode_t op, const mips_register_t r1){ mips_opcode(op); code << "\t$" << r1; mips_comment();}////////// generate a 1-register instruction with a label. E.g. 'lw $31, startret'//void mips_op(const mips_opcode_t op, const mips_register_t r1, const mips_name_t lab){ mips_opcode(op); code << "\t$" << r1 << ", " << lab; mips_comment();}////////// generate a 2-register instruction.//void mips_op(const mips_opcode_t op, const mips_register_t r1, const mips_register_t r2){ if (op == M_MOVE && r1 == r2) // Peephole Opt return; mips_opcode(op); code << "\t$" << r1 << ", $" << r2; mips_comment();}////////// generate a 2-register instruction with a label. E.g. 'beq $8, $0, ll7'//void mips_op(const mips_opcode_t op, const mips_register_t r1, const mips_register_t r2, const mips_name_t lab){ mips_opcode(op); code << "\t$" << r1 << ", $" << r2 << ", " << lab; mips_comment();}////////// generate a 3-register instruction. E.g. 'slt $3, $3, $2'//void mips_op(const mips_opcode_t op, const mips_register_t r1, const mips_register_t r2, const mips_register_t r3){ mips_opcode(op); code << "\t$" << r1 << ", $" << r2 << ", $" << r3; mips_comment();}////////// generate an I-Type instruction. E.g. 'addi $31, $32, 8'//void mips_op(const mips_opcode_t op, const mips_register_t r1, const mips_register_t r2, const int imm){ mips_opcode(op); code << "\t$" << r1 << ", $" << r2 << ", " << imm; mips_comment();}////////// generate an I-Type instruction. E.g. 'lw $31, 8($29)'//void mips_op(const mips_opcode_t op, const mips_register_t r1, const int imm, const mips_register_t r2){ mips_opcode(op); code << "\t$" << r1 << ", " << imm << "($" << r2 << ")"; mips_comment();}////////// generate an I-Type instruction, 1 reg. E.g. 'li $3, 8'//void mips_op(const mips_opcode_t op, const mips_register_t reg, const int imm){ mips_opcode(op); code << "\t$" << reg << ", " << imm; mips_comment();}////////// generate a line with nothing but a label//void mips_op(const mips_name_t lab){ code << lab << ":"; mips_comment();}////////// generate a line with only an instruction. E.g. '.data'//void mips_op(const mips_opcode_t op){ mips_opcode(op); mips_comment();}////////// generate a labeled instruction. E.g. 'vv1: .word 0'//void mips_op(const mips_name_t label, const mips_opcode_t op, const int value){ code << label << ":\t"; mips_opcode(op); code << "\t" << value; mips_comment();}// End of File
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -