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 #if V8_TARGET_ARCH_MIPS64
6
7 #include "src/mips64/constants-mips64.h"
8
9 namespace v8 {
10 namespace internal {
11
12
13 // -----------------------------------------------------------------------------
14 // Registers.
15
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>".
19 const char* Registers::names_[kNumSimuRegisters] = {
20 "zero_reg",
21 "at",
22 "v0", "v1",
23 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
24 "t0", "t1", "t2", "t3",
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
36
37 // List of alias names which can be used when referring to MIPS registers.
38 const Registers::RegisterAlias Registers::aliases_[] = {
39 {0, "zero"},
40 {23, "cp"},
41 {30, "s8"},
42 {30, "s8_fp"},
43 {kInvalidRegister, NULL}
44 };
45
46
Name(int reg)47 const 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
Number(const char * name)58 int 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
80 const char* FPURegisters::names_[kNumFPURegisters] = {
81 "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
86
87 // List of alias names which can be used when referring to MIPS registers.
88 const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
89 {kInvalidRegister, NULL}
90 };
91
92
Name(int creg)93 const char* FPURegisters::Name(int creg) {
94 const char* result;
95 if ((0 <= creg) && (creg < kNumFPURegisters)) {
96 result = names_[creg];
97 } else {
98 result = "nocreg";
99 }
100 return result;
101 }
102
103
Number(const char * name)104 int FPURegisters::Number(const char* name) {
105 // Look through the canonical names.
106 for (int i = 0; i < kNumFPURegisters; i++) {
107 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 // -----------------------------------------------------------------------------
127 // Instructions.
128
IsForbiddenAfterBranchInstr(Instr instr)129 bool Instruction::IsForbiddenAfterBranchInstr(Instr instr) {
130 Opcode opcode = static_cast<Opcode>(instr & kOpcodeMask);
131 switch (opcode) {
132 case J:
133 case JAL:
134 case BEQ:
135 case BNE:
136 case BLEZ: // POP06 bgeuc/bleuc, blezalc, bgezalc
137 case BGTZ: // POP07 bltuc/bgtuc, bgtzalc, bltzalc
138 case BEQL:
139 case BNEL:
140 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, bnvc, bnec
146 case POP66: // beqzc, jic
147 case POP76: // bnezc, jialc
148 return true;
149 case REGIMM:
150 switch (instr & kRtFieldMask) {
151 case BLTZ:
152 case BGEZ:
153 case BLTZAL:
154 case BGEZAL:
155 return true;
156 default:
157 return false;
158 }
159 break;
160 case SPECIAL:
161 switch (instr & kFunctionFieldMask) {
162 case JR:
163 case JALR:
164 return true;
165 default:
166 return false;
167 }
168 break;
169 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;
180 default:
181 return false;
182 }
183 }
184
185
IsLinkingInstruction() const186 bool Instruction::IsLinkingInstruction() const {
187 switch (OpcodeFieldRaw()) {
188 case JAL:
189 return true;
190 case POP76:
191 if (RsFieldRawNoAssert() == JIALC)
192 return true; // JIALC
193 else
194 return false; // BNEZC
195 case REGIMM:
196 switch (RtFieldRaw()) {
197 case BGEZAL:
198 case BLTZAL:
199 return true;
200 default:
201 return false;
202 }
203 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
IsTrap() const216 bool Instruction::IsTrap() const {
217 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
236 } // namespace internal
237 } // namespace v8
238
239 #endif // V8_TARGET_ARCH_MIPS64
240