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