1 // Copyright 2010 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include "v8.h" 29 30 #if defined(V8_TARGET_ARCH_MIPS) 31 32 #include "constants-mips.h" 33 34 namespace v8 { 35 namespace internal { 36 37 38 // ----------------------------------------------------------------------------- 39 // Registers 40 41 42 // These register names are defined in a way to match the native disassembler 43 // formatting. See for example the command "objdump -d <binary file>". 44 const char* Registers::names_[kNumSimuRegisters] = { 45 "zero_reg", 46 "at", 47 "v0", "v1", 48 "a0", "a1", "a2", "a3", 49 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", 50 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", 51 "t8", "t9", 52 "k0", "k1", 53 "gp", 54 "sp", 55 "fp", 56 "ra", 57 "LO", "HI", 58 "pc" 59 }; 60 61 // List of alias names which can be used when referring to MIPS registers. 62 const Registers::RegisterAlias Registers::aliases_[] = { 63 {0, "zero"}, 64 {23, "cp"}, 65 {30, "s8"}, 66 {30, "s8_fp"}, 67 {kInvalidRegister, NULL} 68 }; 69 70 const char* Registers::Name(int reg) { 71 const char* result; 72 if ((0 <= reg) && (reg < kNumSimuRegisters)) { 73 result = names_[reg]; 74 } else { 75 result = "noreg"; 76 } 77 return result; 78 } 79 80 81 int Registers::Number(const char* name) { 82 // Look through the canonical names. 83 for (int i = 0; i < kNumSimuRegisters; i++) { 84 if (strcmp(names_[i], name) == 0) { 85 return i; 86 } 87 } 88 89 // Look through the alias names. 90 int i = 0; 91 while (aliases_[i].reg != kInvalidRegister) { 92 if (strcmp(aliases_[i].name, name) == 0) { 93 return aliases_[i].reg; 94 } 95 i++; 96 } 97 98 // No register with the reguested name found. 99 return kInvalidRegister; 100 } 101 102 103 const char* FPURegisters::names_[kNumFPURegisters] = { 104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", 105 "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", 106 "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" 107 }; 108 109 // List of alias names which can be used when referring to MIPS registers. 110 const FPURegisters::RegisterAlias FPURegisters::aliases_[] = { 111 {kInvalidRegister, NULL} 112 }; 113 114 const char* FPURegisters::Name(int creg) { 115 const char* result; 116 if ((0 <= creg) && (creg < kNumFPURegisters)) { 117 result = names_[creg]; 118 } else { 119 result = "nocreg"; 120 } 121 return result; 122 } 123 124 125 int FPURegisters::Number(const char* name) { 126 // Look through the canonical names. 127 for (int i = 0; i < kNumFPURegisters; i++) { 128 if (strcmp(names_[i], name) == 0) { 129 return i; 130 } 131 } 132 133 // Look through the alias names. 134 int i = 0; 135 while (aliases_[i].creg != kInvalidRegister) { 136 if (strcmp(aliases_[i].name, name) == 0) { 137 return aliases_[i].creg; 138 } 139 i++; 140 } 141 142 // No Cregister with the reguested name found. 143 return kInvalidFPURegister; 144 } 145 146 147 // ----------------------------------------------------------------------------- 148 // Instruction 149 150 bool Instruction::IsForbiddenInBranchDelay() const { 151 const int op = OpcodeFieldRaw(); 152 switch (op) { 153 case J: 154 case JAL: 155 case BEQ: 156 case BNE: 157 case BLEZ: 158 case BGTZ: 159 case BEQL: 160 case BNEL: 161 case BLEZL: 162 case BGTZL: 163 return true; 164 case REGIMM: 165 switch (RtFieldRaw()) { 166 case BLTZ: 167 case BGEZ: 168 case BLTZAL: 169 case BGEZAL: 170 return true; 171 default: 172 return false; 173 }; 174 break; 175 case SPECIAL: 176 switch (FunctionFieldRaw()) { 177 case JR: 178 case JALR: 179 return true; 180 default: 181 return false; 182 }; 183 break; 184 default: 185 return false; 186 }; 187 } 188 189 190 bool Instruction::IsLinkingInstruction() const { 191 const int op = OpcodeFieldRaw(); 192 switch (op) { 193 case JAL: 194 case REGIMM: 195 switch (RtFieldRaw()) { 196 case BGEZAL: 197 case BLTZAL: 198 return true; 199 default: 200 return false; 201 }; 202 case SPECIAL: 203 switch (FunctionFieldRaw()) { 204 case JALR: 205 return true; 206 default: 207 return false; 208 }; 209 default: 210 return false; 211 }; 212 } 213 214 215 bool Instruction::IsTrap() const { 216 if (OpcodeFieldRaw() != SPECIAL) { 217 return false; 218 } else { 219 switch (FunctionFieldRaw()) { 220 case BREAK: 221 case TGE: 222 case TGEU: 223 case TLT: 224 case TLTU: 225 case TEQ: 226 case TNE: 227 return true; 228 default: 229 return false; 230 }; 231 } 232 } 233 234 235 Instruction::Type Instruction::InstructionType() const { 236 switch (OpcodeFieldRaw()) { 237 case SPECIAL: 238 switch (FunctionFieldRaw()) { 239 case JR: 240 case JALR: 241 case BREAK: 242 case SLL: 243 case SRL: 244 case SRA: 245 case SLLV: 246 case SRLV: 247 case SRAV: 248 case MFHI: 249 case MFLO: 250 case MULT: 251 case MULTU: 252 case DIV: 253 case DIVU: 254 case ADD: 255 case ADDU: 256 case SUB: 257 case SUBU: 258 case AND: 259 case OR: 260 case XOR: 261 case NOR: 262 case SLT: 263 case SLTU: 264 case TGE: 265 case TGEU: 266 case TLT: 267 case TLTU: 268 case TEQ: 269 case TNE: 270 case MOVZ: 271 case MOVN: 272 case MOVCI: 273 return kRegisterType; 274 default: 275 UNREACHABLE(); 276 }; 277 break; 278 case SPECIAL2: 279 switch (FunctionFieldRaw()) { 280 case MUL: 281 case CLZ: 282 return kRegisterType; 283 default: 284 UNREACHABLE(); 285 }; 286 break; 287 case SPECIAL3: 288 switch (FunctionFieldRaw()) { 289 case INS: 290 case EXT: 291 return kRegisterType; 292 default: 293 UNREACHABLE(); 294 }; 295 break; 296 case COP1: // Coprocessor instructions 297 switch (RsFieldRawNoAssert()) { 298 case BC1: // branch on coprocessor condition 299 return kImmediateType; 300 default: 301 return kRegisterType; 302 }; 303 break; 304 // 16 bits Immediate type instructions. eg: addi dest, src, imm16 305 case REGIMM: 306 case BEQ: 307 case BNE: 308 case BLEZ: 309 case BGTZ: 310 case ADDI: 311 case ADDIU: 312 case SLTI: 313 case SLTIU: 314 case ANDI: 315 case ORI: 316 case XORI: 317 case LUI: 318 case BEQL: 319 case BNEL: 320 case BLEZL: 321 case BGTZL: 322 case LB: 323 case LH: 324 case LWL: 325 case LW: 326 case LBU: 327 case LHU: 328 case LWR: 329 case SB: 330 case SH: 331 case SWL: 332 case SW: 333 case SWR: 334 case LWC1: 335 case LDC1: 336 case SWC1: 337 case SDC1: 338 return kImmediateType; 339 // 26 bits immediate type instructions. eg: j imm26 340 case J: 341 case JAL: 342 return kJumpType; 343 default: 344 UNREACHABLE(); 345 }; 346 return kUnsupported; 347 } 348 349 350 } } // namespace v8::internal 351 352 #endif // V8_TARGET_ARCH_MIPS 353