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