Home | History | Annotate | Download | only in mips
      1 // Copyright 2011 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 // Instructions.
    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       return true;
    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 Instruction::Type Instruction::InstructionType() const {
    237   switch (OpcodeFieldRaw()) {
    238     case SPECIAL:
    239       switch (FunctionFieldRaw()) {
    240         case JR:
    241         case JALR:
    242         case BREAK:
    243         case SLL:
    244         case SRL:
    245         case SRA:
    246         case SLLV:
    247         case SRLV:
    248         case SRAV:
    249         case MFHI:
    250         case MFLO:
    251         case MULT:
    252         case MULTU:
    253         case DIV:
    254         case DIVU:
    255         case ADD:
    256         case ADDU:
    257         case SUB:
    258         case SUBU:
    259         case AND:
    260         case OR:
    261         case XOR:
    262         case NOR:
    263         case SLT:
    264         case SLTU:
    265         case TGE:
    266         case TGEU:
    267         case TLT:
    268         case TLTU:
    269         case TEQ:
    270         case TNE:
    271         case MOVZ:
    272         case MOVN:
    273         case MOVCI:
    274           return kRegisterType;
    275         default:
    276           return kUnsupported;
    277       };
    278       break;
    279     case SPECIAL2:
    280       switch (FunctionFieldRaw()) {
    281         case MUL:
    282         case CLZ:
    283           return kRegisterType;
    284         default:
    285           return kUnsupported;
    286       };
    287       break;
    288     case SPECIAL3:
    289       switch (FunctionFieldRaw()) {
    290         case INS:
    291         case EXT:
    292           return kRegisterType;
    293         default:
    294           return kUnsupported;
    295       };
    296       break;
    297     case COP1:    // Coprocessor instructions.
    298       switch (RsFieldRawNoAssert()) {
    299         case BC1:   // Branch on coprocessor condition.
    300           return kImmediateType;
    301         default:
    302           return kRegisterType;
    303       };
    304       break;
    305     // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
    306     case REGIMM:
    307     case BEQ:
    308     case BNE:
    309     case BLEZ:
    310     case BGTZ:
    311     case ADDI:
    312     case ADDIU:
    313     case SLTI:
    314     case SLTIU:
    315     case ANDI:
    316     case ORI:
    317     case XORI:
    318     case LUI:
    319     case BEQL:
    320     case BNEL:
    321     case BLEZL:
    322     case BGTZL:
    323     case LB:
    324     case LH:
    325     case LWL:
    326     case LW:
    327     case LBU:
    328     case LHU:
    329     case LWR:
    330     case SB:
    331     case SH:
    332     case SWL:
    333     case SW:
    334     case SWR:
    335     case LWC1:
    336     case LDC1:
    337     case SWC1:
    338     case SDC1:
    339       return kImmediateType;
    340     // 26 bits immediate type instructions. e.g.: j imm26.
    341     case J:
    342     case JAL:
    343       return kJumpType;
    344     default:
    345       return kUnsupported;
    346   };
    347   return kUnsupported;
    348 }
    349 
    350 
    351 } }   // namespace v8::internal
    352 
    353 #endif  // V8_TARGET_ARCH_MIPS
    354