OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2016, the Dartino project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE.md file. | |
4 | |
5 #ifndef SRC_VM_ASSEMBLER_MIPS_H_ | |
6 #define SRC_VM_ASSEMBLER_MIPS_H_ | |
7 | |
8 #ifndef SRC_VM_ASSEMBLER_H_ | |
9 #error Do not include assembler_mips.h directly; use assembler.h instead. | |
10 #endif | |
11 | |
12 #include "src/shared/assert.h" | |
13 #include "src/shared/utils.h" | |
14 | |
15 namespace dartino { | |
16 | |
17 enum Register { | |
18 ZR = 0, | |
19 AT = 1, | |
20 V0 = 2, | |
21 V1 = 3, | |
22 A0 = 4, | |
23 A1 = 5, | |
24 A2 = 6, | |
25 A3 = 7, | |
26 T0 = 8, | |
27 T1 = 9, | |
28 T2 = 10, | |
29 T3 = 11, | |
30 T4 = 12, | |
31 T5 = 13, | |
32 T6 = 14, | |
33 T7 = 15, | |
34 S0 = 16, | |
35 S1 = 17, | |
36 S2 = 18, | |
37 S3 = 19, | |
38 S4 = 20, | |
39 S5 = 21, | |
40 S6 = 22, | |
41 S7 = 23, | |
42 T8 = 24, | |
43 T9 = 25, | |
44 K0 = 26, // mips kernel reserved register. DO NOT USE. | |
45 K1 = 27, // mips kernel reserved register. DO NOT USE. | |
46 GP = 28, | |
47 SP = 29, | |
48 FP = 30, | |
49 RA = 31, | |
50 }; | |
51 | |
52 enum ScaleFactor { | |
53 TIMES_1 = 0, | |
54 TIMES_2 = 1, | |
55 TIMES_4 = 2, | |
56 TIMES_WORD_SIZE = TIMES_4, | |
57 TIMES_8 = 3 | |
58 }; | |
59 enum ShiftType { SLL, SRL, SLLV, SRLV, SRA, SRAV }; | |
60 | |
61 enum Condition { | |
62 F = 0, // False | |
63 T = 1, // True | |
64 UN = 2, // Unordered | |
65 OR = 3, // Ordered | |
66 EQ = 4, // Equal | |
67 NEQ = 5, // Not Equal | |
68 UEQ = 6, // Unordered or Equal | |
69 OLG = 7, // Ordered or Less than or Greater Than | |
70 OLT = 8, // Ordered Less Than | |
71 UGE = 9, // Unordered or Greater Than or Equal | |
72 ULT = 10, // Unordered or Less Than | |
73 OGE = 11, // Ordered Greater Than or Equal | |
74 OLE = 12, // Ordered Less Than or Equal | |
75 UGT = 13, // Unordered or Greater Than | |
76 ULE = 14, // Unordered or Less Than or Equal | |
77 OGT = 15, // Ordered Greater Than | |
78 SF = 16, // Signaling False | |
79 ST = 17, // Signaling True | |
80 NGLE = 18, // Not Greater Than or Less Than or Equal | |
81 GLE = 19, // Greater Than, or Less Than or Equal | |
82 SEQ = 20, // Signaling Equal | |
83 SNE = 21, // Signaling Not Equal | |
84 NGL = 22, // Not Greater Than or Less Than | |
85 GL = 23, // Greater Than or Less Than | |
86 LT = 24, // Less Than | |
87 NLT = 25, // Not Less Than | |
88 NGE = 26, // Not Greater Than | |
89 GE = 27, // Greater Than or Equal | |
90 LE = 28, // Less Than or Equal | |
91 NLE = 29, // Not Less Than or Equal | |
92 NGT = 30, // Not Greater Than | |
93 GT = 31, // Greater Than | |
94 }; | |
95 | |
96 class Immediate { | |
97 public: | |
98 explicit Immediate(int32_t value) : value_(value) {} | |
99 int32_t value() const { return value_; } | |
100 | |
101 private: | |
102 const int32_t value_; | |
103 }; | |
104 | |
105 class Address { | |
106 public: | |
107 Address(Register base, int32_t offset) | |
108 : base_(base), offset_(offset) {} | |
109 | |
110 Register base() const { return base_; } | |
111 int32_t offset() const { return offset_; } | |
112 | |
113 private: | |
114 const Register base_; | |
115 const int32_t offset_; | |
116 }; | |
117 | |
118 | |
119 class Label { | |
120 public: | |
121 Label() : position_(-1) {} | |
122 | |
123 // Returns the position for a label. Positions are assigned on first use. | |
124 int position() { | |
125 if (position_ == -1) position_ = position_counter_++; | |
126 return position_; | |
127 } | |
128 | |
129 private: | |
130 int position_; | |
131 static int position_counter_; | |
132 }; | |
133 | |
134 #define INSTRUCTION_0(name, format) \ | |
135 void name() { Print(format); } | |
136 | |
137 #define INSTRUCTION_1(name, format, t0) \ | |
138 void name(t0 a0) { Print(format, Wrap(a0)); } | |
139 | |
140 #define INSTRUCTION_2(name, format, t0, t1) \ | |
141 void name(t0 a0, t1 a1) { Print(format, Wrap(a0), Wrap(a1)); } | |
142 | |
143 #define INSTRUCTION_3(name, format, t0, t1, t2) \ | |
144 void name(t0 a0, t1 a1, t2 a2) { \ | |
145 Print(format, Wrap(a0), Wrap(a1), Wrap(a2)); \ | |
146 } | |
147 | |
148 #define INSTRUCTION_4(name, format, t0, t1, t2, t3) \ | |
149 void name(t0 a0, t1 a1, t2 a2, t3 a3) { \ | |
150 Print(format, Wrap(a0), Wrap(a1), Wrap(a2), Wrap(a3)); \ | |
151 } | |
152 | |
153 class Assembler { | |
154 public: | |
155 INSTRUCTION_3(add, "add %r, %r, %r", Register, Register, Register); | |
156 INSTRUCTION_3(addi, "addi %r, %r, %i", Register, Register, const Immediate&); | |
157 INSTRUCTION_3(addu, "addu %r, %r, %r", Register, Register, Register); | |
158 INSTRUCTION_3(addiu, "addiu %r, %r, %i", Register, Register, | |
159 const Immediate&); | |
160 | |
161 INSTRUCTION_3(andi, "andi %r, %r, %i", Register, Register, const Immediate&); | |
162 INSTRUCTION_3(and_, "and %r, %r, %r", Register, Register, Register); | |
163 | |
164 INSTRUCTION_0(break_, "break"); | |
165 | |
166 INSTRUCTION_1(b, "b %s", const char*); | |
167 INSTRUCTION_1(b, "b %l", Label*); | |
168 INSTRUCTION_2(b, "b%c %l", Condition, Label*); | |
169 INSTRUCTION_4(b, "b%c %r, %r, %l", Condition, Register, Register, Label*); | |
170 INSTRUCTION_4(b, "b%c %r, %r, %s", Condition, Register, Register, | |
171 const char*); | |
172 | |
173 INSTRUCTION_1(jal, "jal %s", const char*); | |
174 INSTRUCTION_1(jalr, "jalr %r", Register); | |
175 INSTRUCTION_1(jr, "jr %r", Register); | |
176 | |
177 INSTRUCTION_2(la, "la %r, %s", Register, const char*); | |
178 INSTRUCTION_2(la, "la %r, %l", Register, Label*); | |
179 INSTRUCTION_2(li, "li %r, %i", Register, const Immediate&); | |
180 INSTRUCTION_2(lui, "lui %r, %i", Register, const Immediate&); | |
181 | |
182 INSTRUCTION_2(lb, "lb %r, %a", Register, const Address&); | |
183 INSTRUCTION_2(lbu, "lbu %r, %a", Register, const Address&); | |
184 INSTRUCTION_2(lw, "lw %r, %a", Register, const Address&); | |
185 INSTRUCTION_2(lw, "lw %r, %s", Register, const char*); | |
186 | |
187 INSTRUCTION_2(move, "move %r, %r", Register, Register); | |
188 INSTRUCTION_2(mult, "mult %r, %r", Register, Register); | |
189 | |
190 INSTRUCTION_1(mfhi, "mfhi %r", Register); | |
191 INSTRUCTION_1(mflo, "mflo %r", Register); | |
192 | |
193 INSTRUCTION_0(nop, "nop"); | |
194 INSTRUCTION_2(not_, "nor %r, %r, $0", Register, Register); | |
195 | |
196 INSTRUCTION_3(or_, "or %r, %r, %r", Register, Register, Register); | |
197 | |
198 INSTRUCTION_3(sll, "sll %r, %r, %i", Register, Register, const Immediate&); | |
199 INSTRUCTION_3(sllv, "sllv %r, %r, %r", Register, Register, Register); | |
200 INSTRUCTION_3(sra, "sra %r, %r, %i", Register, Register, const Immediate&); | |
201 INSTRUCTION_3(srav, "srav %r, %r, %r", Register, Register, Register); | |
202 INSTRUCTION_3(srl, "srl %r, %r, %i", Register, Register, const Immediate&); | |
203 | |
204 INSTRUCTION_3(slt, "slt %r, %r, %r", Register, Register, Register); | |
205 INSTRUCTION_3(sltu, "sltu %r, %r, %r", Register, Register, Register); | |
206 | |
207 | |
208 INSTRUCTION_3(sub, "sub %r, %r, %r", Register, Register, Register); | |
209 INSTRUCTION_3(subi, "addi %r, %r, -%i", Register, Register, const Immediate&); | |
210 INSTRUCTION_3(subu, "subu %r, %r, %r", Register, Register, Register); | |
211 | |
212 INSTRUCTION_0(syscall, "syscall"); | |
213 | |
214 INSTRUCTION_2(sb, "sb %r, %a", Register, const Address&); | |
215 INSTRUCTION_2(sw, "sw %r, %a", Register, const Address&); | |
216 | |
217 INSTRUCTION_3(xor_, "xor %r, %r, %r", Register, Register, Register); | |
218 | |
219 | |
220 // Align what follows to a 2^power address. | |
221 void AlignToPowerOfTwo(int power); | |
222 | |
223 void Bind(const char* prefix, const char* name); | |
224 void Bind(Label* label); | |
225 | |
226 void DefineLong(const char* name); | |
227 | |
228 void SwitchToText(); | |
229 | |
230 void BindWithPowerOfTwoAlignment(const char* name, int power); | |
231 void SwitchToData(); | |
232 | |
233 const char* LabelPrefix(); | |
234 | |
235 private: | |
236 void Print(const char* format, ...); | |
237 void PrintAddress(const Address* address); | |
238 | |
239 Condition Wrap(Condition condition) { return condition; } | |
240 Register Wrap(Register reg) { return reg; } | |
241 const char* Wrap(const char* label) { return label; } | |
242 Label* Wrap(Label* label) { return label; } | |
243 const Immediate* Wrap(const Immediate& immediate) { return &immediate; } | |
244 const Address* Wrap(const Address& address) { return &address; } | |
245 }; | |
246 | |
247 #undef INSTRUCTION_0 | |
248 #undef INSTRUCTION_1 | |
249 #undef INSTRUCTION_2 | |
Søren Gjesse
2016/05/26 13:00:19
undef INSTRUCTION_3 and INSTRUCTION_4 as well?
petarj
2016/05/26 14:35:55
Done.
| |
250 | |
251 } // namespace dartino | |
252 | |
253 #endif // SRC_VM_ASSEMBLER_MIPS_H_ | |
OLD | NEW |