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