• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 
30 #if defined(V8_TARGET_ARCH_MIPS)
31 
32 #include "constants-mips.h"
33 
34 namespace v8 {
35 namespace internal {
36 
37 
38 // -----------------------------------------------------------------------------
39 // Registers.
40 
41 
42 // These register names are defined in a way to match the native disassembler
43 // formatting. See for example the command "objdump -d <binary file>".
44 const char* Registers::names_[kNumSimuRegisters] = {
45   "zero_reg",
46   "at",
47   "v0", "v1",
48   "a0", "a1", "a2", "a3",
49   "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
50   "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
51   "t8", "t9",
52   "k0", "k1",
53   "gp",
54   "sp",
55   "fp",
56   "ra",
57   "LO", "HI",
58   "pc"
59 };
60 
61 // List of alias names which can be used when referring to MIPS registers.
62 const Registers::RegisterAlias Registers::aliases_[] = {
63   {0, "zero"},
64   {23, "cp"},
65   {30, "s8"},
66   {30, "s8_fp"},
67   {kInvalidRegister, NULL}
68 };
69 
Name(int reg)70 const char* Registers::Name(int reg) {
71   const char* result;
72   if ((0 <= reg) && (reg < kNumSimuRegisters)) {
73     result = names_[reg];
74   } else {
75     result = "noreg";
76   }
77   return result;
78 }
79 
80 
Number(const char * name)81 int Registers::Number(const char* name) {
82   // Look through the canonical names.
83   for (int i = 0; i < kNumSimuRegisters; i++) {
84     if (strcmp(names_[i], name) == 0) {
85       return i;
86     }
87   }
88 
89   // Look through the alias names.
90   int i = 0;
91   while (aliases_[i].reg != kInvalidRegister) {
92     if (strcmp(aliases_[i].name, name) == 0) {
93       return aliases_[i].reg;
94     }
95     i++;
96   }
97 
98   // No register with the reguested name found.
99   return kInvalidRegister;
100 }
101 
102 
103 const char* FPURegisters::names_[kNumFPURegisters] = {
104   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11",
105   "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
106   "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
107 };
108 
109 // List of alias names which can be used when referring to MIPS registers.
110 const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
111   {kInvalidRegister, NULL}
112 };
113 
Name(int creg)114 const char* FPURegisters::Name(int creg) {
115   const char* result;
116   if ((0 <= creg) && (creg < kNumFPURegisters)) {
117     result = names_[creg];
118   } else {
119     result = "nocreg";
120   }
121   return result;
122 }
123 
124 
Number(const char * name)125 int FPURegisters::Number(const char* name) {
126   // Look through the canonical names.
127   for (int i = 0; i < kNumFPURegisters; i++) {
128     if (strcmp(names_[i], name) == 0) {
129       return i;
130     }
131   }
132 
133   // Look through the alias names.
134   int i = 0;
135   while (aliases_[i].creg != kInvalidRegister) {
136     if (strcmp(aliases_[i].name, name) == 0) {
137       return aliases_[i].creg;
138     }
139     i++;
140   }
141 
142   // No Cregister with the reguested name found.
143   return kInvalidFPURegister;
144 }
145 
146 
147 // -----------------------------------------------------------------------------
148 // Instructions.
149 
IsForbiddenInBranchDelay() const150 bool Instruction::IsForbiddenInBranchDelay() const {
151   const int op = OpcodeFieldRaw();
152   switch (op) {
153     case J:
154     case JAL:
155     case BEQ:
156     case BNE:
157     case BLEZ:
158     case BGTZ:
159     case BEQL:
160     case BNEL:
161     case BLEZL:
162     case BGTZL:
163       return true;
164     case REGIMM:
165       switch (RtFieldRaw()) {
166         case BLTZ:
167         case BGEZ:
168         case BLTZAL:
169         case BGEZAL:
170           return true;
171         default:
172           return false;
173       };
174       break;
175     case SPECIAL:
176       switch (FunctionFieldRaw()) {
177         case JR:
178         case JALR:
179           return true;
180         default:
181           return false;
182       };
183       break;
184     default:
185       return false;
186   };
187 }
188 
189 
IsLinkingInstruction() const190 bool Instruction::IsLinkingInstruction() const {
191   const int op = OpcodeFieldRaw();
192   switch (op) {
193     case JAL:
194       return true;
195     case REGIMM:
196       switch (RtFieldRaw()) {
197         case BGEZAL:
198         case BLTZAL:
199           return true;
200       default:
201         return false;
202       };
203     case SPECIAL:
204       switch (FunctionFieldRaw()) {
205         case JALR:
206           return true;
207         default:
208           return false;
209       };
210     default:
211       return false;
212   };
213 }
214 
215 
IsTrap() const216 bool Instruction::IsTrap() const {
217   if (OpcodeFieldRaw() != SPECIAL) {
218     return false;
219   } else {
220     switch (FunctionFieldRaw()) {
221       case BREAK:
222       case TGE:
223       case TGEU:
224       case TLT:
225       case TLTU:
226       case TEQ:
227       case TNE:
228         return true;
229       default:
230         return false;
231     };
232   }
233 }
234 
235 
InstructionType() const236 Instruction::Type Instruction::InstructionType() const {
237   switch (OpcodeFieldRaw()) {
238     case SPECIAL:
239       switch (FunctionFieldRaw()) {
240         case JR:
241         case JALR:
242         case BREAK:
243         case SLL:
244         case SRL:
245         case SRA:
246         case SLLV:
247         case SRLV:
248         case SRAV:
249         case MFHI:
250         case MFLO:
251         case MULT:
252         case MULTU:
253         case DIV:
254         case DIVU:
255         case ADD:
256         case ADDU:
257         case SUB:
258         case SUBU:
259         case AND:
260         case OR:
261         case XOR:
262         case NOR:
263         case SLT:
264         case SLTU:
265         case TGE:
266         case TGEU:
267         case TLT:
268         case TLTU:
269         case TEQ:
270         case TNE:
271         case MOVZ:
272         case MOVN:
273         case MOVCI:
274           return kRegisterType;
275         default:
276           return kUnsupported;
277       };
278       break;
279     case SPECIAL2:
280       switch (FunctionFieldRaw()) {
281         case MUL:
282         case CLZ:
283           return kRegisterType;
284         default:
285           return kUnsupported;
286       };
287       break;
288     case SPECIAL3:
289       switch (FunctionFieldRaw()) {
290         case INS:
291         case EXT:
292           return kRegisterType;
293         default:
294           return kUnsupported;
295       };
296       break;
297     case COP1:    // Coprocessor instructions.
298       switch (RsFieldRawNoAssert()) {
299         case BC1:   // Branch on coprocessor condition.
300           return kImmediateType;
301         default:
302           return kRegisterType;
303       };
304       break;
305     // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
306     case REGIMM:
307     case BEQ:
308     case BNE:
309     case BLEZ:
310     case BGTZ:
311     case ADDI:
312     case ADDIU:
313     case SLTI:
314     case SLTIU:
315     case ANDI:
316     case ORI:
317     case XORI:
318     case LUI:
319     case BEQL:
320     case BNEL:
321     case BLEZL:
322     case BGTZL:
323     case LB:
324     case LH:
325     case LWL:
326     case LW:
327     case LBU:
328     case LHU:
329     case LWR:
330     case SB:
331     case SH:
332     case SWL:
333     case SW:
334     case SWR:
335     case LWC1:
336     case LDC1:
337     case SWC1:
338     case SDC1:
339       return kImmediateType;
340     // 26 bits immediate type instructions. e.g.: j imm26.
341     case J:
342     case JAL:
343       return kJumpType;
344     default:
345       return kUnsupported;
346   };
347   return kUnsupported;
348 }
349 
350 
351 } }   // namespace v8::internal
352 
353 #endif  // V8_TARGET_ARCH_MIPS
354