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