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 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 
     62 // List of alias names which can be used when referring to MIPS registers.
     63 const Registers::RegisterAlias Registers::aliases_[] = {
     64   {0, "zero"},
     65   {23, "cp"},
     66   {30, "s8"},
     67   {30, "s8_fp"},
     68   {kInvalidRegister, NULL}
     69 };
     70 
     71 
     72 const char* Registers::Name(int reg) {
     73   const char* result;
     74   if ((0 <= reg) && (reg < kNumSimuRegisters)) {
     75     result = names_[reg];
     76   } else {
     77     result = "noreg";
     78   }
     79   return result;
     80 }
     81 
     82 
     83 int Registers::Number(const char* name) {
     84   // Look through the canonical names.
     85   for (int i = 0; i < kNumSimuRegisters; i++) {
     86     if (strcmp(names_[i], name) == 0) {
     87       return i;
     88     }
     89   }
     90 
     91   // Look through the alias names.
     92   int i = 0;
     93   while (aliases_[i].reg != kInvalidRegister) {
     94     if (strcmp(aliases_[i].name, name) == 0) {
     95       return aliases_[i].reg;
     96     }
     97     i++;
     98   }
     99 
    100   // No register with the reguested name found.
    101   return kInvalidRegister;
    102 }
    103 
    104 
    105 const char* FPURegisters::names_[kNumFPURegisters] = {
    106   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11",
    107   "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21",
    108   "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
    109 };
    110 
    111 
    112 // List of alias names which can be used when referring to MIPS registers.
    113 const FPURegisters::RegisterAlias FPURegisters::aliases_[] = {
    114   {kInvalidRegister, NULL}
    115 };
    116 
    117 
    118 const char* FPURegisters::Name(int creg) {
    119   const char* result;
    120   if ((0 <= creg) && (creg < kNumFPURegisters)) {
    121     result = names_[creg];
    122   } else {
    123     result = "nocreg";
    124   }
    125   return result;
    126 }
    127 
    128 
    129 int FPURegisters::Number(const char* name) {
    130   // Look through the canonical names.
    131   for (int i = 0; i < kNumFPURegisters; i++) {
    132     if (strcmp(names_[i], name) == 0) {
    133       return i;
    134     }
    135   }
    136 
    137   // Look through the alias names.
    138   int i = 0;
    139   while (aliases_[i].creg != kInvalidRegister) {
    140     if (strcmp(aliases_[i].name, name) == 0) {
    141       return aliases_[i].creg;
    142     }
    143     i++;
    144   }
    145 
    146   // No Cregister with the reguested name found.
    147   return kInvalidFPURegister;
    148 }
    149 
    150 
    151 // -----------------------------------------------------------------------------
    152 // Instructions.
    153 
    154 bool Instruction::IsForbiddenInBranchDelay() const {
    155   const int op = OpcodeFieldRaw();
    156   switch (op) {
    157     case J:
    158     case JAL:
    159     case BEQ:
    160     case BNE:
    161     case BLEZ:
    162     case BGTZ:
    163     case BEQL:
    164     case BNEL:
    165     case BLEZL:
    166     case BGTZL:
    167       return true;
    168     case REGIMM:
    169       switch (RtFieldRaw()) {
    170         case BLTZ:
    171         case BGEZ:
    172         case BLTZAL:
    173         case BGEZAL:
    174           return true;
    175         default:
    176           return false;
    177       };
    178       break;
    179     case SPECIAL:
    180       switch (FunctionFieldRaw()) {
    181         case JR:
    182         case JALR:
    183           return true;
    184         default:
    185           return false;
    186       };
    187       break;
    188     default:
    189       return false;
    190   };
    191 }
    192 
    193 
    194 bool Instruction::IsLinkingInstruction() const {
    195   const int op = OpcodeFieldRaw();
    196   switch (op) {
    197     case JAL:
    198       return true;
    199     case REGIMM:
    200       switch (RtFieldRaw()) {
    201         case BGEZAL:
    202         case BLTZAL:
    203           return true;
    204       default:
    205         return false;
    206       };
    207     case SPECIAL:
    208       switch (FunctionFieldRaw()) {
    209         case JALR:
    210           return true;
    211         default:
    212           return false;
    213       };
    214     default:
    215       return false;
    216   };
    217 }
    218 
    219 
    220 bool Instruction::IsTrap() const {
    221   if (OpcodeFieldRaw() != SPECIAL) {
    222     return false;
    223   } else {
    224     switch (FunctionFieldRaw()) {
    225       case BREAK:
    226       case TGE:
    227       case TGEU:
    228       case TLT:
    229       case TLTU:
    230       case TEQ:
    231       case TNE:
    232         return true;
    233       default:
    234         return false;
    235     };
    236   }
    237 }
    238 
    239 
    240 Instruction::Type Instruction::InstructionType() const {
    241   switch (OpcodeFieldRaw()) {
    242     case SPECIAL:
    243       switch (FunctionFieldRaw()) {
    244         case JR:
    245         case JALR:
    246         case BREAK:
    247         case SLL:
    248         case SRL:
    249         case SRA:
    250         case SLLV:
    251         case SRLV:
    252         case SRAV:
    253         case MFHI:
    254         case MFLO:
    255         case MULT:
    256         case MULTU:
    257         case DIV:
    258         case DIVU:
    259         case ADD:
    260         case ADDU:
    261         case SUB:
    262         case SUBU:
    263         case AND:
    264         case OR:
    265         case XOR:
    266         case NOR:
    267         case SLT:
    268         case SLTU:
    269         case TGE:
    270         case TGEU:
    271         case TLT:
    272         case TLTU:
    273         case TEQ:
    274         case TNE:
    275         case MOVZ:
    276         case MOVN:
    277         case MOVCI:
    278           return kRegisterType;
    279         default:
    280           return kUnsupported;
    281       };
    282       break;
    283     case SPECIAL2:
    284       switch (FunctionFieldRaw()) {
    285         case MUL:
    286         case CLZ:
    287           return kRegisterType;
    288         default:
    289           return kUnsupported;
    290       };
    291       break;
    292     case SPECIAL3:
    293       switch (FunctionFieldRaw()) {
    294         case INS:
    295         case EXT:
    296           return kRegisterType;
    297         default:
    298           return kUnsupported;
    299       };
    300       break;
    301     case COP1:    // Coprocessor instructions.
    302       switch (RsFieldRawNoAssert()) {
    303         case BC1:   // Branch on coprocessor condition.
    304           return kImmediateType;
    305         default:
    306           return kRegisterType;
    307       };
    308       break;
    309     case COP1X:
    310       return kRegisterType;
    311     // 16 bits Immediate type instructions. e.g.: addi dest, src, imm16.
    312     case REGIMM:
    313     case BEQ:
    314     case BNE:
    315     case BLEZ:
    316     case BGTZ:
    317     case ADDI:
    318     case ADDIU:
    319     case SLTI:
    320     case SLTIU:
    321     case ANDI:
    322     case ORI:
    323     case XORI:
    324     case LUI:
    325     case BEQL:
    326     case BNEL:
    327     case BLEZL:
    328     case BGTZL:
    329     case LB:
    330     case LH:
    331     case LWL:
    332     case LW:
    333     case LBU:
    334     case LHU:
    335     case LWR:
    336     case SB:
    337     case SH:
    338     case SWL:
    339     case SW:
    340     case SWR:
    341     case LWC1:
    342     case LDC1:
    343     case SWC1:
    344     case SDC1:
    345       return kImmediateType;
    346     // 26 bits immediate type instructions. e.g.: j imm26.
    347     case J:
    348     case JAL:
    349       return kJumpType;
    350     default:
    351       return kUnsupported;
    352   };
    353   return kUnsupported;
    354 }
    355 
    356 
    357 } }   // namespace v8::internal
    358 
    359 #endif  // V8_TARGET_ARCH_MIPS
    360