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