1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/v8.h"
6
7 #if V8_TARGET_ARCH_MIPS
8
9 #include "src/mips/constants-mips.h"
10
11 namespace v8 {
12 namespace internal {
13
14
15 // -----------------------------------------------------------------------------
16 // Registers.
17
18
19 // These register names are defined in a way to match the native disassembler
20 // formatting. See for example the command "objdump -d <binary file>".
21 const char* Registers::names_[kNumSimuRegisters] = {
22 "zero_reg",
23 "at",
24 "v0", "v1",
25 "a0", "a1", "a2", "a3",
26 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
27 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
28 "t8", "t9",
29 "k0", "k1",
30 "gp",
31 "sp",
32 "fp",
33 "ra",
34 "LO", "HI",
35 "pc"
36 };
37
38
39 // List of alias names which can be used when referring to MIPS registers.
40 const Registers::RegisterAlias Registers::aliases_[] = {
41 {0, "zero"},
42 {23, "cp"},
43 {30, "s8"},
44 {30, "s8_fp"},
45 {kInvalidRegister, NULL}
46 };
47
48
Name(int reg)49 const char* Registers::Name(int reg) {
50 const char* result;
51 if ((0 <= reg) && (reg < kNumSimuRegisters)) {
52 result = names_[reg];
53 } else {
54 result = "noreg";
55 }
56 return result;
57 }
58
59
Number(const char * name)60 int Registers::Number(const char* name) {
61 // Look through the canonical names.
62 for (int i = 0; i < kNumSimuRegisters; i++) {
63 if (strcmp(names_[i], name) == 0) {
64 return i;
65 }
66 }
67
68 // Look through the alias names.
69 int i = 0;
70 while (aliases_[i].reg != kInvalidRegister) {
71 if (strcmp(aliases_[i].name, name) == 0) {
72 return aliases_[i].reg;
73 }
74 i++;
75 }
76
77 // No register with the reguested name found.
78 return kInvalidRegister;
79 }
80
81
82 const char* FPURegisters::names_[kNumFPURegisters] = {
83 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11",
84 "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
85 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
86 };
87
88
89 // List of alias names which can be used when referring to MIPS registers.
90 const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
91 {kInvalidRegister, NULL}
92 };
93
94
Name(int creg)95 const char* FPURegisters::Name(int creg) {
96 const char* result;
97 if ((0 <= creg) && (creg < kNumFPURegisters)) {
98 result = names_[creg];
99 } else {
100 result = "nocreg";
101 }
102 return result;
103 }
104
105
Number(const char * name)106 int FPURegisters::Number(const char* name) {
107 // Look through the canonical names.
108 for (int i = 0; i < kNumFPURegisters; i++) {
109 if (strcmp(names_[i], name) == 0) {
110 return i;
111 }
112 }
113
114 // Look through the alias names.
115 int i = 0;
116 while (aliases_[i].creg != kInvalidRegister) {
117 if (strcmp(aliases_[i].name, name) == 0) {
118 return aliases_[i].creg;
119 }
120 i++;
121 }
122
123 // No Cregister with the reguested name found.
124 return kInvalidFPURegister;
125 }
126
127
128 // -----------------------------------------------------------------------------
129 // Instructions.
130
IsForbiddenInBranchDelay() const131 bool Instruction::IsForbiddenInBranchDelay() const {
132 const int op = OpcodeFieldRaw();
133 switch (op) {
134 case J:
135 case JAL:
136 case BEQ:
137 case BNE:
138 case BLEZ:
139 case BGTZ:
140 case BEQL:
141 case BNEL:
142 case BLEZL:
143 case BGTZL:
144 return true;
145 case REGIMM:
146 switch (RtFieldRaw()) {
147 case BLTZ:
148 case BGEZ:
149 case BLTZAL:
150 case BGEZAL:
151 return true;
152 default:
153 return false;
154 }
155 break;
156 case SPECIAL:
157 switch (FunctionFieldRaw()) {
158 case JR:
159 case JALR:
160 return true;
161 default:
162 return false;
163 }
164 break;
165 default:
166 return false;
167 }
168 }
169
170
IsLinkingInstruction() const171 bool Instruction::IsLinkingInstruction() const {
172 const int op = OpcodeFieldRaw();
173 switch (op) {
174 case JAL:
175 return true;
176 case REGIMM:
177 switch (RtFieldRaw()) {
178 case BGEZAL:
179 case BLTZAL:
180 return true;
181 default:
182 return false;
183 }
184 case SPECIAL:
185 switch (FunctionFieldRaw()) {
186 case JALR:
187 return true;
188 default:
189 return false;
190 }
191 default:
192 return false;
193 }
194 }
195
196
IsTrap() const197 bool Instruction::IsTrap() const {
198 if (OpcodeFieldRaw() != SPECIAL) {
199 return false;
200 } else {
201 switch (FunctionFieldRaw()) {
202 case BREAK:
203 case TGE:
204 case TGEU:
205 case TLT:
206 case TLTU:
207 case TEQ:
208 case TNE:
209 return true;
210 default:
211 return false;
212 }
213 }
214 }
215
216
InstructionType() const217 Instruction::Type Instruction::InstructionType() const {
218 switch (OpcodeFieldRaw()) {
219 case SPECIAL:
220 switch (FunctionFieldRaw()) {
221 case JR:
222 case JALR:
223 case BREAK:
224 case SLL:
225 case SRL:
226 case SRA:
227 case SLLV:
228 case SRLV:
229 case SRAV:
230 case MFHI:
231 case MFLO:
232 case MULT:
233 case MULTU:
234 case DIV:
235 case DIVU:
236 case ADD:
237 case ADDU:
238 case SUB:
239 case SUBU:
240 case AND:
241 case OR:
242 case XOR:
243 case NOR:
244 case SLT:
245 case SLTU:
246 case TGE:
247 case TGEU:
248 case TLT:
249 case TLTU:
250 case TEQ:
251 case TNE:
252 case MOVZ:
253 case MOVN:
254 case MOVCI:
255 return kRegisterType;
256 default:
257 return kUnsupported;
258 }
259 break;
260 case SPECIAL2:
261 switch (FunctionFieldRaw()) {
262 case MUL:
263 case CLZ:
264 return kRegisterType;
265 default:
266 return kUnsupported;
267 }
268 break;
269 case SPECIAL3:
270 switch (FunctionFieldRaw()) {
271 case INS:
272 case EXT:
273 return kRegisterType;
274 default:
275 return kUnsupported;
276 }
277 break;
278 case COP1: // Coprocessor instructions.
279 switch (RsFieldRawNoAssert()) {
280 case BC1: // Branch on coprocessor condition.
281 case BC1EQZ:
282 case BC1NEZ:
283 return kImmediateType;
284 default:
285 return kRegisterType;
286 }
287 break;
288 case COP1X:
289 return kRegisterType;
290 // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
291 case REGIMM:
292 case BEQ:
293 case BNE:
294 case BLEZ:
295 case BGTZ:
296 case ADDI:
297 case DADDI:
298 case ADDIU:
299 case SLTI:
300 case SLTIU:
301 case ANDI:
302 case ORI:
303 case XORI:
304 case LUI:
305 case BEQL:
306 case BNEL:
307 case BLEZL:
308 case BGTZL:
309 case BEQZC:
310 case BNEZC:
311 case LB:
312 case LH:
313 case LWL:
314 case LW:
315 case LBU:
316 case LHU:
317 case LWR:
318 case SB:
319 case SH:
320 case SWL:
321 case SW:
322 case SWR:
323 case LWC1:
324 case LDC1:
325 case SWC1:
326 case SDC1:
327 return kImmediateType;
328 // 26 bits immediate type instructions. e.g.: j imm26.
329 case J:
330 case JAL:
331 return kJumpType;
332 default:
333 return kUnsupported;
334 }
335 return kUnsupported;
336 }
337
338
339 } } // namespace v8::internal
340
341 #endif // V8_TARGET_ARCH_MIPS
342