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