1 #ifndef DRIVER_H 2 #define DRIVER_H 3 4 #include <iostream> 5 #include <sstream> 6 #include <stdint.h> 7 #include <string> 8 #include <unordered_map> 9 #include <vector> 10 #include "mips32.tab.hh" 11 #include "lexer.h" 12 13 namespace ns { 14 15 struct Driver { 16 public: runDriver17 void run(std::istream& is, bool tl, bool tp) { 18 lexer.switch_streams(&is); 19 lexer.set_debug(tl); 20 loc.initialize(); 21 22 yyParser parser(*this); 23 parser.set_debug_level(tp); 24 25 pc = 0; 26 labels.clear(); 27 abs_refs.clear(); 28 refs.clear(); 29 hex.clear(); 30 error = parser.parse() != 0; 31 32 for (const auto& r : refs) { 33 if (error) { 34 return; 35 } 36 resolve_ref(r.first, r.second, false); 37 } 38 for (const auto& r : abs_refs) { 39 if (error) { 40 return; 41 } 42 resolve_ref(r.first, r.second, true); 43 } 44 } 45 bindDriver46 bool bind(const std::string& label) { 47 if (labels.find(label) != labels.end()) { 48 return false; 49 } 50 labels[label] = pc; 51 return true; 52 } 53 emit_branchDriver54 void emit_branch(uint32_t op, uint32_t rs, uint32_t rt, const std::string& label) { 55 refs[pc] = label; 56 emit_itype(op, rs, rt, 0x0); 57 } 58 emit_breakDriver59 void emit_break(uint32_t code) { 60 const auto inst = (code << 6) | 0xd; 61 hex.push_back(inst); 62 pc += 4; 63 } 64 emit_itypeDriver65 void emit_itype(uint32_t op, uint32_t rs, uint32_t rt, uint32_t imm) { 66 const auto inst = (op << 26) | (rs << 21) | (rt << 16) | imm; 67 hex.push_back(inst); 68 pc += 4; 69 } 70 emit_jtypeDriver71 void emit_jtype(uint32_t op, const std::string& label) { 72 const auto inst = (op << 26) | 0x0; 73 abs_refs[pc] = label; 74 hex.push_back(inst); 75 pc += 4; 76 } 77 emit_nopDriver78 void emit_nop() { 79 hex.push_back(0); 80 pc += 4; 81 } 82 emit_rtypeDriver83 void emit_rtype(uint32_t op, uint32_t rs, uint32_t rt, uint32_t rd, uint32_t shamt, uint32_t func) { 84 const auto inst = (op << 26) | (rs << 21) | (rt << 16) | (rd << 11) | (shamt << 6) | func; 85 hex.push_back(inst); 86 pc += 4; 87 } 88 set_whyDriver89 void set_why(const location& l, const std::string& m) { 90 std::ostringstream oss; 91 oss << l << ": " << m; 92 why = oss.str(); 93 } 94 resolve_refDriver95 void resolve_ref(uint32_t pc, const std::string& target, bool jump) { 96 auto ptr = (uint16_t*)(&hex[pc/4]); 97 auto itr = labels.find(target); 98 if (itr == labels.end()) { 99 error = true; 100 set_why(loc, "Reference to undefined label"); 101 } else if (jump) { 102 *ptr = itr->second/4; 103 } else { 104 *ptr = (itr->second - (pc + 4))/4; 105 } 106 } 107 108 yyLexer lexer; 109 location loc; 110 111 bool error; 112 std::string why; 113 114 uint32_t pc; 115 std::unordered_map<std::string, uint32_t> labels; 116 std::unordered_map<uint32_t, std::string> abs_refs; 117 std::unordered_map<uint32_t, std::string> refs; 118 std::vector<uint32_t> hex; 119 }; 120 121 } // namespace ns 122 123 #endif 124