blob: ddfa891326724b07eb203464cc5e021010b5fe34 [file] [log] [blame]
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001// Copyright 2011 the V8 project authors. All rights reserved.
ager@chromium.org5c838252010-02-19 08:53:10 +00002// 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"
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +000029
30#if defined(V8_TARGET_ARCH_MIPS)
31
ager@chromium.org5c838252010-02-19 08:53:10 +000032#include "constants-mips.h"
33
lrn@chromium.org7516f052011-03-30 08:52:27 +000034namespace v8 {
35namespace internal {
ager@chromium.org5c838252010-02-19 08:53:10 +000036
37
38// -----------------------------------------------------------------------------
karlklose@chromium.org83a47282011-05-11 11:54:09 +000039// Registers.
ager@chromium.org5c838252010-02-19 08:53:10 +000040
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>".
44const 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.
62const Registers::RegisterAlias Registers::aliases_[] = {
63 {0, "zero"},
64 {23, "cp"},
65 {30, "s8"},
66 {30, "s8_fp"},
67 {kInvalidRegister, NULL}
68};
69
70const 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
81int 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
lrn@chromium.org7516f052011-03-30 08:52:27 +0000103const char* FPURegisters::names_[kNumFPURegisters] = {
ager@chromium.org5c838252010-02-19 08:53:10 +0000104 "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.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000110const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
ager@chromium.org5c838252010-02-19 08:53:10 +0000111 {kInvalidRegister, NULL}
112};
113
lrn@chromium.org7516f052011-03-30 08:52:27 +0000114const char* FPURegisters::Name(int creg) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000115 const char* result;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000116 if ((0 <= creg) && (creg < kNumFPURegisters)) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000117 result = names_[creg];
118 } else {
119 result = "nocreg";
120 }
121 return result;
122}
123
124
lrn@chromium.org7516f052011-03-30 08:52:27 +0000125int FPURegisters::Number(const char* name) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000126 // Look through the canonical names.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000127 for (int i = 0; i < kNumFPURegisters; i++) {
ager@chromium.org5c838252010-02-19 08:53:10 +0000128 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// -----------------------------------------------------------------------------
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000148// Instructions.
ager@chromium.org5c838252010-02-19 08:53:10 +0000149
lrn@chromium.org7516f052011-03-30 08:52:27 +0000150bool Instruction::IsForbiddenInBranchDelay() const {
151 const int op = OpcodeFieldRaw();
ager@chromium.org5c838252010-02-19 08:53:10 +0000152 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
lrn@chromium.org7516f052011-03-30 08:52:27 +0000190bool Instruction::IsLinkingInstruction() const {
191 const int op = OpcodeFieldRaw();
ager@chromium.org5c838252010-02-19 08:53:10 +0000192 switch (op) {
193 case JAL:
lrn@chromium.org34e60782011-09-15 07:25:40 +0000194 return true;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000195 case REGIMM:
196 switch (RtFieldRaw()) {
197 case BGEZAL:
198 case BLTZAL:
199 return true;
200 default:
201 return false;
202 };
ager@chromium.org5c838252010-02-19 08:53:10 +0000203 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
lrn@chromium.org7516f052011-03-30 08:52:27 +0000216bool Instruction::IsTrap() const {
ager@chromium.org5c838252010-02-19 08:53:10 +0000217 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
236Instruction::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:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000271 case MOVZ:
272 case MOVN:
273 case MOVCI:
ager@chromium.org5c838252010-02-19 08:53:10 +0000274 return kRegisterType;
275 default:
lrn@chromium.org34e60782011-09-15 07:25:40 +0000276 return kUnsupported;
ager@chromium.org5c838252010-02-19 08:53:10 +0000277 };
278 break;
279 case SPECIAL2:
280 switch (FunctionFieldRaw()) {
281 case MUL:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000282 case CLZ:
283 return kRegisterType;
284 default:
lrn@chromium.org34e60782011-09-15 07:25:40 +0000285 return kUnsupported;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000286 };
287 break;
288 case SPECIAL3:
289 switch (FunctionFieldRaw()) {
290 case INS:
291 case EXT:
ager@chromium.org5c838252010-02-19 08:53:10 +0000292 return kRegisterType;
293 default:
lrn@chromium.org34e60782011-09-15 07:25:40 +0000294 return kUnsupported;
ager@chromium.org5c838252010-02-19 08:53:10 +0000295 };
296 break;
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000297 case COP1: // Coprocessor instructions.
lrn@chromium.org7516f052011-03-30 08:52:27 +0000298 switch (RsFieldRawNoAssert()) {
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000299 case BC1: // Branch on coprocessor condition.
ager@chromium.org5c838252010-02-19 08:53:10 +0000300 return kImmediateType;
301 default:
302 return kRegisterType;
303 };
304 break;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000305 case COP1X:
306 return kRegisterType;
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000307 // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
ager@chromium.org5c838252010-02-19 08:53:10 +0000308 case REGIMM:
309 case BEQ:
310 case BNE:
311 case BLEZ:
312 case BGTZ:
313 case ADDI:
314 case ADDIU:
315 case SLTI:
316 case SLTIU:
317 case ANDI:
318 case ORI:
319 case XORI:
320 case LUI:
321 case BEQL:
322 case BNEL:
323 case BLEZL:
324 case BGTZL:
325 case LB:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000326 case LH:
327 case LWL:
ager@chromium.org5c838252010-02-19 08:53:10 +0000328 case LW:
329 case LBU:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000330 case LHU:
331 case LWR:
ager@chromium.org5c838252010-02-19 08:53:10 +0000332 case SB:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000333 case SH:
334 case SWL:
ager@chromium.org5c838252010-02-19 08:53:10 +0000335 case SW:
lrn@chromium.org7516f052011-03-30 08:52:27 +0000336 case SWR:
ager@chromium.org5c838252010-02-19 08:53:10 +0000337 case LWC1:
338 case LDC1:
339 case SWC1:
340 case SDC1:
341 return kImmediateType;
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000342 // 26 bits immediate type instructions. e.g.: j imm26.
ager@chromium.org5c838252010-02-19 08:53:10 +0000343 case J:
344 case JAL:
345 return kJumpType;
346 default:
lrn@chromium.org34e60782011-09-15 07:25:40 +0000347 return kUnsupported;
ager@chromium.org5c838252010-02-19 08:53:10 +0000348 };
349 return kUnsupported;
350}
351
lrn@chromium.org7516f052011-03-30 08:52:27 +0000352
353} } // namespace v8::internal
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +0000354
355#endif // V8_TARGET_ARCH_MIPS