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 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 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 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 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 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 186 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 216 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