Home | History | Annotate | Download | only in mips64
      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