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_MIPS64
8
9#include "src/mips64/constants-mips64.h"
10
11namespace v8 {
12namespace 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>".
21const char* Registers::names_[kNumSimuRegisters] = {
22  "zero_reg",
23  "at",
24  "v0", "v1",
25  "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
26  "t0", "t1", "t2", "t3",
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.
40const Registers::RegisterAlias Registers::aliases_[] = {
41  {0, "zero"},
42  {23, "cp"},
43  {30, "s8"},
44  {30, "s8_fp"},
45  {kInvalidRegister, NULL}
46};
47
48
49const 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
60int 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
82const 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.
90const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
91  {kInvalidRegister, NULL}
92};
93
94
95const 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
106int 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
131bool 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
171bool 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
197bool 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
217Instruction::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 DSLL:
226        case DSLL32:
227        case SRL:
228        case DSRL:
229        case DSRL32:
230        case SRA:
231        case DSRA:
232        case DSRA32:
233        case SLLV:
234        case DSLLV:
235        case SRLV:
236        case DSRLV:
237        case SRAV:
238        case DSRAV:
239        case MFHI:
240        case MFLO:
241        case MULT:
242        case DMULT:
243        case MULTU:
244        case DMULTU:
245        case DIV:
246        case DDIV:
247        case DIVU:
248        case DDIVU:
249        case ADD:
250        case DADD:
251        case ADDU:
252        case DADDU:
253        case SUB:
254        case DSUB:
255        case SUBU:
256        case DSUBU:
257        case AND:
258        case OR:
259        case XOR:
260        case NOR:
261        case SLT:
262        case SLTU:
263        case TGE:
264        case TGEU:
265        case TLT:
266        case TLTU:
267        case TEQ:
268        case TNE:
269        case MOVZ:
270        case MOVN:
271        case MOVCI:
272          return kRegisterType;
273        default:
274          return kUnsupported;
275      }
276      break;
277    case SPECIAL2:
278      switch (FunctionFieldRaw()) {
279        case MUL:
280        case CLZ:
281          return kRegisterType;
282        default:
283          return kUnsupported;
284      }
285      break;
286    case SPECIAL3:
287      switch (FunctionFieldRaw()) {
288        case INS:
289        case EXT:
290          return kRegisterType;
291        default:
292          return kUnsupported;
293      }
294      break;
295    case COP1:    // Coprocessor instructions.
296      switch (RsFieldRawNoAssert()) {
297        case BC1:   // Branch on coprocessor condition.
298        case BC1EQZ:
299        case BC1NEZ:
300          return kImmediateType;
301        default:
302          return kRegisterType;
303      }
304      break;
305    case COP1X:
306      return kRegisterType;
307    // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
308    case REGIMM:
309    case BEQ:
310    case BNE:
311    case BLEZ:
312    case BGTZ:
313    case ADDI:
314    case DADDI:
315    case ADDIU:
316    case DADDIU:
317    case SLTI:
318    case SLTIU:
319    case ANDI:
320    case ORI:
321    case XORI:
322    case LUI:
323    case BEQL:
324    case BNEL:
325    case BLEZL:
326    case BGTZL:
327    case BEQZC:
328    case BNEZC:
329    case LB:
330    case LH:
331    case LWL:
332    case LW:
333    case LWU:
334    case LD:
335    case LBU:
336    case LHU:
337    case LWR:
338    case SB:
339    case SH:
340    case SWL:
341    case SW:
342    case SD:
343    case SWR:
344    case LWC1:
345    case LDC1:
346    case SWC1:
347    case SDC1:
348      return kImmediateType;
349    // 26 bits immediate type instructions. e.g.: j imm26.
350    case J:
351    case JAL:
352      return kJumpType;
353    default:
354      return kUnsupported;
355  }
356  return kUnsupported;
357}
358
359
360} }   // namespace v8::internal
361
362#endif  // V8_TARGET_ARCH_MIPS64
363