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_MIPS64
8
9 #include "src/mips64/constants-mips64.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", "a4", "a5", "a6", "a7",
26 "t0", "t1", "t2", "t3",
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 DSLL:
226 case DSLL32:
227 case SRL:
228 case DSRL:
229 case DSRL32:
230 case SRA:
231 case DSRA:
232 case DSRA32:
233 case SLLV:
234 case DSLLV:
235 case SRLV:
236 case DSRLV:
237 case SRAV:
238 case DSRAV:
239 case MFHI:
240 case MFLO:
241 case MULT:
242 case DMULT:
243 case MULTU:
244 case DMULTU:
245 case DIV:
246 case DDIV:
247 case DIVU:
248 case DDIVU:
249 case ADD:
250 case DADD:
251 case ADDU:
252 case DADDU:
253 case SUB:
254 case DSUB:
255 case SUBU:
256 case DSUBU:
257 case AND:
258 case OR:
259 case XOR:
260 case NOR:
261 case SLT:
262 case SLTU:
263 case TGE:
264 case TGEU:
265 case TLT:
266 case TLTU:
267 case TEQ:
268 case TNE:
269 case MOVZ:
270 case MOVN:
271 case MOVCI:
272 return kRegisterType;
273 default:
274 return kUnsupported;
275 }
276 break;
277 case SPECIAL2:
278 switch (FunctionFieldRaw()) {
279 case MUL:
280 case CLZ:
281 return kRegisterType;
282 default:
283 return kUnsupported;
284 }
285 break;
286 case SPECIAL3:
287 switch (FunctionFieldRaw()) {
288 case INS:
289 case EXT:
290 return kRegisterType;
291 default:
292 return kUnsupported;
293 }
294 break;
295 case COP1: // Coprocessor instructions.
296 switch (RsFieldRawNoAssert()) {
297 case BC1: // Branch on coprocessor condition.
298 case BC1EQZ:
299 case BC1NEZ:
300 return kImmediateType;
301 default:
302 return kRegisterType;
303 }
304 break;
305 case COP1X:
306 return kRegisterType;
307 // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
308 case REGIMM:
309 case BEQ:
310 case BNE:
311 case BLEZ:
312 case BGTZ:
313 case ADDI:
314 case DADDI:
315 case ADDIU:
316 case DADDIU:
317 case SLTI:
318 case SLTIU:
319 case ANDI:
320 case ORI:
321 case XORI:
322 case LUI:
323 case BEQL:
324 case BNEL:
325 case BLEZL:
326 case BGTZL:
327 case BEQZC:
328 case BNEZC:
329 case LB:
330 case LH:
331 case LWL:
332 case LW:
333 case LWU:
334 case LD:
335 case LBU:
336 case LHU:
337 case LWR:
338 case SB:
339 case SH:
340 case SWL:
341 case SW:
342 case SD:
343 case SWR:
344 case LWC1:
345 case LDC1:
346 case SWC1:
347 case SDC1:
348 return kImmediateType;
349 // 26 bits immediate type instructions. e.g.: j imm26.
350 case J:
351 case JAL:
352 return kJumpType;
353 default:
354 return kUnsupported;
355 }
356 return kUnsupported;
357 }
358
359
360 } } // namespace v8::internal
361
362 #endif // V8_TARGET_ARCH_MIPS64
363