blob: dd34c57bfd14cb4ed33d67a3ac8a0a1350135f6d [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
11namespace v8 {
12namespace 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>".
21const 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.
40const Registers::RegisterAlias Registers::aliases_[] = {
41 {0, "zero"},
42 {23, "cp"},
43 {30, "s8"},
44 {30, "s8_fp"},
45 {kInvalidRegister, NULL}
46};
47
48
49const 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
60int 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
82const 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.
90const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
91 {kInvalidRegister, NULL}
92};
93
94
95const 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
106int 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
131bool 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
171bool 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
197bool 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
217Instruction::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:
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400290 case DEXT:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000291 return kRegisterType;
292 default:
293 return kUnsupported;
294 }
295 break;
296 case COP1: // Coprocessor instructions.
297 switch (RsFieldRawNoAssert()) {
298 case BC1: // Branch on coprocessor condition.
299 case BC1EQZ:
300 case BC1NEZ:
301 return kImmediateType;
302 default:
303 return kRegisterType;
304 }
305 break;
306 case COP1X:
307 return kRegisterType;
308 // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
309 case REGIMM:
310 case BEQ:
311 case BNE:
312 case BLEZ:
313 case BGTZ:
314 case ADDI:
315 case DADDI:
316 case ADDIU:
317 case DADDIU:
318 case SLTI:
319 case SLTIU:
320 case ANDI:
321 case ORI:
322 case XORI:
323 case LUI:
324 case BEQL:
325 case BNEL:
326 case BLEZL:
327 case BGTZL:
328 case BEQZC:
329 case BNEZC:
330 case LB:
331 case LH:
332 case LWL:
333 case LW:
334 case LWU:
335 case LD:
336 case LBU:
337 case LHU:
338 case LWR:
339 case SB:
340 case SH:
341 case SWL:
342 case SW:
343 case SD:
344 case SWR:
345 case LWC1:
346 case LDC1:
347 case SWC1:
348 case SDC1:
349 return kImmediateType;
350 // 26 bits immediate type instructions. e.g.: j imm26.
351 case J:
352 case JAL:
353 return kJumpType;
354 default:
355 return kUnsupported;
356 }
357 return kUnsupported;
358}
359
360
361} } // namespace v8::internal
362
363#endif // V8_TARGET_ARCH_MIPS64