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