blob: 6ca430a15780d94ec00b8fd1d2c1f6d38ed4c859 [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Andrei Popescu31002712010-02-23 13:46:05 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#if V8_TARGET_ARCH_MIPS
Leon Clarkef7060e22010-06-03 12:02:55 +01006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/mips/constants-mips.h"
Andrei Popescu31002712010-02-23 13:46:05 +00008
Steve Block44f0eee2011-05-26 01:26:41 +01009namespace v8 {
10namespace internal {
Andrei Popescu31002712010-02-23 13:46:05 +000011
12
13// -----------------------------------------------------------------------------
Ben Murdoch257744e2011-11-30 15:57:28 +000014// Registers.
Andrei Popescu31002712010-02-23 13:46:05 +000015
16
17// These register names are defined in a way to match the native disassembler
18// formatting. See for example the command "objdump -d <binary file>".
19const char* Registers::names_[kNumSimuRegisters] = {
20 "zero_reg",
21 "at",
22 "v0", "v1",
23 "a0", "a1", "a2", "a3",
24 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
25 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
26 "t8", "t9",
27 "k0", "k1",
28 "gp",
29 "sp",
30 "fp",
31 "ra",
32 "LO", "HI",
33 "pc"
34};
35
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036
Andrei Popescu31002712010-02-23 13:46:05 +000037// List of alias names which can be used when referring to MIPS registers.
38const Registers::RegisterAlias Registers::aliases_[] = {
39 {0, "zero"},
40 {23, "cp"},
41 {30, "s8"},
42 {30, "s8_fp"},
43 {kInvalidRegister, NULL}
44};
45
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046
Andrei Popescu31002712010-02-23 13:46:05 +000047const char* Registers::Name(int reg) {
48 const char* result;
49 if ((0 <= reg) && (reg < kNumSimuRegisters)) {
50 result = names_[reg];
51 } else {
52 result = "noreg";
53 }
54 return result;
55}
56
57
58int Registers::Number(const char* name) {
59 // Look through the canonical names.
60 for (int i = 0; i < kNumSimuRegisters; i++) {
61 if (strcmp(names_[i], name) == 0) {
62 return i;
63 }
64 }
65
66 // Look through the alias names.
67 int i = 0;
68 while (aliases_[i].reg != kInvalidRegister) {
69 if (strcmp(aliases_[i].name, name) == 0) {
70 return aliases_[i].reg;
71 }
72 i++;
73 }
74
75 // No register with the reguested name found.
76 return kInvalidRegister;
77}
78
79
Steve Block44f0eee2011-05-26 01:26:41 +010080const char* FPURegisters::names_[kNumFPURegisters] = {
Andrei Popescu31002712010-02-23 13:46:05 +000081 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11",
82 "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
83 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
84};
85
Ben Murdochb8a8cc12014-11-26 15:28:44 +000086
Andrei Popescu31002712010-02-23 13:46:05 +000087// List of alias names which can be used when referring to MIPS registers.
Steve Block44f0eee2011-05-26 01:26:41 +010088const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
Andrei Popescu31002712010-02-23 13:46:05 +000089 {kInvalidRegister, NULL}
90};
91
Ben Murdochb8a8cc12014-11-26 15:28:44 +000092
Steve Block44f0eee2011-05-26 01:26:41 +010093const char* FPURegisters::Name(int creg) {
Andrei Popescu31002712010-02-23 13:46:05 +000094 const char* result;
Steve Block44f0eee2011-05-26 01:26:41 +010095 if ((0 <= creg) && (creg < kNumFPURegisters)) {
Andrei Popescu31002712010-02-23 13:46:05 +000096 result = names_[creg];
97 } else {
98 result = "nocreg";
99 }
100 return result;
101}
102
103
Steve Block44f0eee2011-05-26 01:26:41 +0100104int FPURegisters::Number(const char* name) {
Andrei Popescu31002712010-02-23 13:46:05 +0000105 // Look through the canonical names.
Steve Block44f0eee2011-05-26 01:26:41 +0100106 for (int i = 0; i < kNumFPURegisters; i++) {
Andrei Popescu31002712010-02-23 13:46:05 +0000107 if (strcmp(names_[i], name) == 0) {
108 return i;
109 }
110 }
111
112 // Look through the alias names.
113 int i = 0;
114 while (aliases_[i].creg != kInvalidRegister) {
115 if (strcmp(aliases_[i].name, name) == 0) {
116 return aliases_[i].creg;
117 }
118 i++;
119 }
120
121 // No Cregister with the reguested name found.
122 return kInvalidFPURegister;
123}
124
125
126// -----------------------------------------------------------------------------
Ben Murdoch257744e2011-11-30 15:57:28 +0000127// Instructions.
Andrei Popescu31002712010-02-23 13:46:05 +0000128
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000129bool Instruction::IsForbiddenAfterBranchInstr(Instr instr) {
130 Opcode opcode = static_cast<Opcode>(instr & kOpcodeMask);
131 switch (opcode) {
Andrei Popescu31002712010-02-23 13:46:05 +0000132 case J:
133 case JAL:
134 case BEQ:
135 case BNE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136 case BLEZ: // POP06 bgeuc/bleuc, blezalc, bgezalc
137 case BGTZ: // POP07 bltuc/bgtuc, bgtzalc, bltzalc
Andrei Popescu31002712010-02-23 13:46:05 +0000138 case BEQL:
139 case BNEL:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000140 case BLEZL: // POP26 bgezc, blezc, bgec/blec
141 case BGTZL: // POP27 bgtzc, bltzc, bltc/bgtc
142 case BC:
143 case BALC:
144 case POP10: // beqzalc, bovc, beqc
145 case POP30: // bnezalc, bvnc, bnec
146 case POP66: // beqzc, jic
147 case POP76: // bnezc, jialc
Andrei Popescu31002712010-02-23 13:46:05 +0000148 return true;
149 case REGIMM:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000150 switch (instr & kRtFieldMask) {
Andrei Popescu31002712010-02-23 13:46:05 +0000151 case BLTZ:
152 case BGEZ:
153 case BLTZAL:
154 case BGEZAL:
155 return true;
156 default:
157 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158 }
Andrei Popescu31002712010-02-23 13:46:05 +0000159 break;
160 case SPECIAL:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000161 switch (instr & kFunctionFieldMask) {
Andrei Popescu31002712010-02-23 13:46:05 +0000162 case JR:
163 case JALR:
164 return true;
165 default:
166 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000167 }
Andrei Popescu31002712010-02-23 13:46:05 +0000168 break;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000169 case COP1:
170 switch (instr & kRsFieldMask) {
171 case BC1:
172 case BC1EQZ:
173 case BC1NEZ:
174 return true;
175 break;
176 default:
177 return false;
178 }
179 break;
Andrei Popescu31002712010-02-23 13:46:05 +0000180 default:
181 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182 }
Andrei Popescu31002712010-02-23 13:46:05 +0000183}
184
185
Steve Block44f0eee2011-05-26 01:26:41 +0100186bool Instruction::IsLinkingInstruction() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000187 switch (OpcodeFieldRaw()) {
Andrei Popescu31002712010-02-23 13:46:05 +0000188 case JAL:
Ben Murdoch589d6972011-11-30 16:04:58 +0000189 return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000190 case POP76:
191 if (RsFieldRawNoAssert() == JIALC)
192 return true; // JIALC
193 else
194 return false; // BNEZC
Steve Block44f0eee2011-05-26 01:26:41 +0100195 case REGIMM:
196 switch (RtFieldRaw()) {
197 case BGEZAL:
198 case BLTZAL:
199 return true;
200 default:
201 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000202 }
Andrei Popescu31002712010-02-23 13:46:05 +0000203 case SPECIAL:
204 switch (FunctionFieldRaw()) {
205 case JALR:
206 return true;
207 default:
208 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000209 }
Andrei Popescu31002712010-02-23 13:46:05 +0000210 default:
211 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000212 }
Andrei Popescu31002712010-02-23 13:46:05 +0000213}
214
215
Steve Block44f0eee2011-05-26 01:26:41 +0100216bool Instruction::IsTrap() const {
Andrei Popescu31002712010-02-23 13:46:05 +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;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000231 }
Andrei Popescu31002712010-02-23 13:46:05 +0000232 }
233}
234
235
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000236} // namespace internal
237} // namespace v8
Leon Clarkef7060e22010-06-03 12:02:55 +0100238
239#endif // V8_TARGET_ARCH_MIPS