Chromium Code Reviews| 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 |