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
30#if defined(V8_TARGET_ARCH_MIPS)
31
32#include "constants-mips.h"
33
34namespace v8 {
35namespace 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>".
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
103const 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.
110const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
111  {kInvalidRegister, NULL}
112};
113
114const 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
125int 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// Instruction
149
150bool 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
190bool Instruction::IsLinkingInstruction() const {
191  const int op = OpcodeFieldRaw();
192  switch (op) {
193    case JAL:
194    case REGIMM:
195      switch (RtFieldRaw()) {
196        case BGEZAL:
197        case BLTZAL:
198          return true;
199      default:
200        return false;
201      };
202    case SPECIAL:
203      switch (FunctionFieldRaw()) {
204        case JALR:
205          return true;
206        default:
207          return false;
208      };
209    default:
210      return false;
211  };
212}
213
214
215bool Instruction::IsTrap() const {
216  if (OpcodeFieldRaw() != SPECIAL) {
217    return false;
218  } else {
219    switch (FunctionFieldRaw()) {
220      case BREAK:
221      case TGE:
222      case TGEU:
223      case TLT:
224      case TLTU:
225      case TEQ:
226      case TNE:
227        return true;
228      default:
229        return false;
230    };
231  }
232}
233
234
235Instruction::Type Instruction::InstructionType() const {
236  switch (OpcodeFieldRaw()) {
237    case SPECIAL:
238      switch (FunctionFieldRaw()) {
239        case JR:
240        case JALR:
241        case BREAK:
242        case SLL:
243        case SRL:
244        case SRA:
245        case SLLV:
246        case SRLV:
247        case SRAV:
248        case MFHI:
249        case MFLO:
250        case MULT:
251        case MULTU:
252        case DIV:
253        case DIVU:
254        case ADD:
255        case ADDU:
256        case SUB:
257        case SUBU:
258        case AND:
259        case OR:
260        case XOR:
261        case NOR:
262        case SLT:
263        case SLTU:
264        case TGE:
265        case TGEU:
266        case TLT:
267        case TLTU:
268        case TEQ:
269        case TNE:
270        case MOVZ:
271        case MOVN:
272        case MOVCI:
273          return kRegisterType;
274        default:
275          UNREACHABLE();
276      };
277      break;
278    case SPECIAL2:
279      switch (FunctionFieldRaw()) {
280        case MUL:
281        case CLZ:
282          return kRegisterType;
283        default:
284          UNREACHABLE();
285      };
286      break;
287    case SPECIAL3:
288      switch (FunctionFieldRaw()) {
289        case INS:
290        case EXT:
291          return kRegisterType;
292        default:
293          UNREACHABLE();
294      };
295      break;
296    case COP1:    // Coprocessor instructions
297      switch (RsFieldRawNoAssert()) {
298        case BC1:   // branch on coprocessor condition
299          return kImmediateType;
300        default:
301          return kRegisterType;
302      };
303      break;
304    // 16 bits Immediate type instructions. eg: addi dest, src, imm16
305    case REGIMM:
306    case BEQ:
307    case BNE:
308    case BLEZ:
309    case BGTZ:
310    case ADDI:
311    case ADDIU:
312    case SLTI:
313    case SLTIU:
314    case ANDI:
315    case ORI:
316    case XORI:
317    case LUI:
318    case BEQL:
319    case BNEL:
320    case BLEZL:
321    case BGTZL:
322    case LB:
323    case LH:
324    case LWL:
325    case LW:
326    case LBU:
327    case LHU:
328    case LWR:
329    case SB:
330    case SH:
331    case SWL:
332    case SW:
333    case SWR:
334    case LWC1:
335    case LDC1:
336    case SWC1:
337    case SDC1:
338      return kImmediateType;
339    // 26 bits immediate type instructions. eg: j imm26
340    case J:
341    case JAL:
342      return kJumpType;
343    default:
344      UNREACHABLE();
345  };
346  return kUnsupported;
347}
348
349
350} }   // namespace v8::internal
351
352#endif  // V8_TARGET_ARCH_MIPS
353