Home | History | Annotate | Download | only in mips
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_
     18 #define ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_
     19 
     20 #include "dex/reg_location.h"
     21 #include "dex/reg_storage.h"
     22 
     23 namespace art {
     24 
     25 /*
     26  * Runtime register conventions.
     27  *
     28  *          mips32            | mips64
     29  * $0:      zero is always the value 0
     30  * $1:      at is scratch (normally used as temp reg by assembler)
     31  * $2,$3:   v0, v1 are scratch (normally hold subroutine return values)
     32  * $4-$7:   a0-a3 are scratch (normally hold subroutine arguments)
     33  * $8-$11:  t0-t3 are scratch | a4-a7 are scratch (normally hold subroutine arguments)
     34  * $12-$15: t4-t7 are scratch | t0-t3 are scratch
     35  * $16:     s0 (rSUSPEND) is reserved [holds suspend-check counter]
     36  * $17:     s1 (rSELF) is reserved [holds current &Thread]
     37  * $18-$23: s2-s7 are callee save (promotion target)
     38  * $24:     t8 is scratch
     39  * $25:     t9 is scratch (normally used for function calls)
     40  * $26,$27: k0, k1 are reserved for use by interrupt handlers
     41  * $28:     gp is reserved for global pointer
     42  * $29:     sp is reserved
     43  * $30:     s8 is callee save (promotion target)
     44  * $31:     ra is scratch (normally holds the return addr)
     45  *
     46  * Preserved across C calls: s0-s8
     47  * Trashed across C calls (mips32): at, v0-v1, a0-a3, t0-t9, gp, ra
     48  * Trashed across C calls (mips64): at, v0-v1, a0-a7, t0-t3, t8, t9, gp, ra
     49  *
     50  * Floating pointer registers (mips32)
     51  * NOTE: there are 32 fp registers (16 df pairs), but currently
     52  *       only support 16 fp registers (8 df pairs).
     53  * f0-f15
     54  * df0-df7, where df0={f0,f1}, df1={f2,f3}, ... , df7={f14,f15}
     55  *
     56  * f0-f15 (df0-df7) trashed across C calls
     57  *
     58  * Floating pointer registers (mips64)
     59  * NOTE: there are 32 fp registers.
     60  * f0-f31
     61  *
     62  * For mips32 code use:
     63  *      a0-a3 to hold operands
     64  *      v0-v1 to hold results
     65  *      t0-t9 for temps
     66  *
     67  * For mips64 code use:
     68  *      a0-a7 to hold operands
     69  *      v0-v1 to hold results
     70  *      t0-t3, t8-t9 for temps
     71  *
     72  * All jump/branch instructions have a delay slot after it.
     73  *
     74  * Stack frame diagram (stack grows down, higher addresses at top):
     75  *
     76  * +------------------------+
     77  * | IN[ins-1]              |  {Note: resides in caller's frame}
     78  * |       .                |
     79  * | IN[0]                  |
     80  * | caller's Method*       |
     81  * +========================+  {Note: start of callee's frame}
     82  * | spill region           |  {variable sized - will include lr if non-leaf.}
     83  * +------------------------+
     84  * | ...filler word...      |  {Note: used as 2nd word of V[locals-1] if long]
     85  * +------------------------+
     86  * | V[locals-1]            |
     87  * | V[locals-2]            |
     88  * |      .                 |
     89  * |      .                 |
     90  * | V[1]                   |
     91  * | V[0]                   |
     92  * +------------------------+
     93  * |  0 to 3 words padding  |
     94  * +------------------------+
     95  * | OUT[outs-1]            |
     96  * | OUT[outs-2]            |
     97  * |       .                |
     98  * | OUT[0]                 |
     99  * | cur_method*            | <<== sp w/ 16-byte alignment
    100  * +========================+
    101  */
    102 
    103 
    104 #define LOWORD_OFFSET 0
    105 #define HIWORD_OFFSET 4
    106 
    107 #define rFARG0 rF12
    108 #define rs_rFARG0 rs_rF12
    109 #define rFARG1 rF13
    110 #define rs_rFARG1 rs_rF13
    111 #define rFARG2 rF14
    112 #define rs_rFARG2 rs_rF14
    113 #define rFARG3 rF15
    114 #define rs_rFARG3 rs_rF15
    115 
    116 enum MipsResourceEncodingPos {
    117   kMipsGPReg0   = 0,
    118   kMipsRegSP    = 29,
    119   kMipsRegLR    = 31,
    120   kMipsFPReg0   = 32,  // only 16 fp regs supported currently.
    121   kMipsFPRegEnd   = 48,
    122   kMipsRegHI    = kMipsFPRegEnd,
    123   kMipsRegLO,
    124   kMipsRegPC,
    125   kMipsRegEnd   = 51,
    126   // Mips64 related:
    127   kMips64FPRegEnd = 64,
    128   kMips64RegPC    = kMips64FPRegEnd,
    129   kMips64RegEnd   = 65,
    130 };
    131 
    132 #define ENCODE_MIPS_REG_LIST(N)      (static_cast<uint64_t>(N))
    133 #define ENCODE_MIPS_REG_SP           (1ULL << kMipsRegSP)
    134 #define ENCODE_MIPS_REG_LR           (1ULL << kMipsRegLR)
    135 #define ENCODE_MIPS_REG_PC           (1ULL << kMipsRegPC)
    136 #define ENCODE_MIPS_REG_HI           (1ULL << kMipsRegHI)
    137 #define ENCODE_MIPS_REG_LO           (1ULL << kMipsRegLO)
    138 
    139 // Set FR_BIT to 0
    140 // This bit determines how the CPU access FP registers.
    141 #define FR_BIT   0
    142 
    143 enum MipsNativeRegisterPool {  // private marker to avoid generate-operator-out.py from processing.
    144   rZERO  = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  0,
    145   rZEROd = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  0,
    146   rAT    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  1,
    147   rATd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  1,
    148   rV0    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  2,
    149   rV0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  2,
    150   rV1    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  3,
    151   rV1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  3,
    152   rA0    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  4,
    153   rA0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  4,
    154   rA1    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  5,
    155   rA1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  5,
    156   rA2    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  6,
    157   rA2d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  6,
    158   rA3    = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  7,
    159   rA3d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  7,
    160   rT0_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  8,
    161   rA4    = rT0_32,
    162   rA4d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  8,
    163   rT1_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  9,
    164   rA5    = rT1_32,
    165   rA5d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister |  9,
    166   rT2_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
    167   rA6    = rT2_32,
    168   rA6d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 10,
    169   rT3_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
    170   rA7    = rT3_32,
    171   rA7d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 11,
    172   rT4_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
    173   rT0    = rT4_32,
    174   rT0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 12,
    175   rT5_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
    176   rT1    = rT5_32,
    177   rT1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 13,
    178   rT6_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
    179   rT2    = rT6_32,
    180   rT2d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 14,
    181   rT7_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
    182   rT3    = rT7_32,
    183   rT3d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 15,
    184   rS0    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
    185   rS0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 16,
    186   rS1    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 17,
    187   rS1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 17,
    188   rS2    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 18,
    189   rS2d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 18,
    190   rS3    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 19,
    191   rS3d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 19,
    192   rS4    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 20,
    193   rS4d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 20,
    194   rS5    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 21,
    195   rS5d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 21,
    196   rS6    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 22,
    197   rS6d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 22,
    198   rS7    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 23,
    199   rS7d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 23,
    200   rT8    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 24,
    201   rT8d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 24,
    202   rT9    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 25,
    203   rT9d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 25,
    204   rK0    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 26,
    205   rK0d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 26,
    206   rK1    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 27,
    207   rK1d   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 27,
    208   rGP    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 28,
    209   rGPd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 28,
    210   rSP    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 29,
    211   rSPd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 29,
    212   rFP    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 30,
    213   rFPd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 30,
    214   rRA    = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 31,
    215   rRAd   = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 31,
    216 
    217   rF0  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  0,
    218   rF1  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  1,
    219   rF2  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  2,
    220   rF3  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  3,
    221   rF4  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  4,
    222   rF5  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  5,
    223   rF6  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  6,
    224   rF7  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  7,
    225   rF8  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  8,
    226   rF9  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  9,
    227   rF10 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 10,
    228   rF11 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 11,
    229   rF12 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 12,
    230   rF13 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 13,
    231   rF14 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 14,
    232   rF15 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 15,
    233 
    234   rF16 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 16,
    235   rF17 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 17,
    236   rF18 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 18,
    237   rF19 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 19,
    238   rF20 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 20,
    239   rF21 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 21,
    240   rF22 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 22,
    241   rF23 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 23,
    242   rF24 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 24,
    243   rF25 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 25,
    244   rF26 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 26,
    245   rF27 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 27,
    246   rF28 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 28,
    247   rF29 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 29,
    248   rF30 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 30,
    249   rF31 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 31,
    250 
    251 #if 0
    252   /*
    253    * TODO: The shared resource mask doesn't have enough bit positions to describe all
    254    * MIPS registers.  Expand it and enable use of fp registers 16 through 31.
    255    */
    256   rF16 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 16,
    257   rF17 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 17,
    258   rF18 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 18,
    259   rF19 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 19,
    260   rF20 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 20,
    261   rF21 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 21,
    262   rF22 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 22,
    263   rF23 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 23,
    264   rF24 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 24,
    265   rF25 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 25,
    266   rF26 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 26,
    267   rF27 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 27,
    268   rF28 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 28,
    269   rF29 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 29,
    270   rF30 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 30,
    271   rF31 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 31,
    272 #endif
    273   // Double precision registers where the FPU is in 32-bit mode.
    274   rD0_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  0,
    275   rD1_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  2,
    276   rD2_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  4,
    277   rD3_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  6,
    278   rD4_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  8,
    279   rD5_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
    280   rD6_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
    281   rD7_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
    282 #if 0  // TODO: expand resource mask to enable use of all MIPS fp registers.
    283   rD8_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 16,
    284   rD9_fr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 18,
    285   rD10_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 20,
    286   rD11_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 22,
    287   rD12_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 24,
    288   rD13_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 26,
    289   rD14_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 28,
    290   rD15_fr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 30,
    291 #endif
    292   // Double precision registers where the FPU is in 64-bit mode.
    293   rD0_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  0,
    294   rD1_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  2,
    295   rD2_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  4,
    296   rD3_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  6,
    297   rD4_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  8,
    298   rD5_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
    299   rD6_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
    300   rD7_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
    301 #if 0  // TODO: expand resource mask to enable use of all MIPS fp registers.
    302   rD8_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 16,
    303   rD9_fr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 18,
    304   rD10_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 20,
    305   rD11_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 22,
    306   rD12_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 24,
    307   rD13_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 26,
    308   rD14_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 28,
    309   rD15_fr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 30,
    310 #endif
    311 
    312   rD0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  0,
    313   rD1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  1,
    314   rD2  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  2,
    315   rD3  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  3,
    316   rD4  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  4,
    317   rD5  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  5,
    318   rD6  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  6,
    319   rD7  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  7,
    320   rD8  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  8,
    321   rD9  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  9,
    322   rD10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
    323   rD11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 11,
    324   rD12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
    325   rD13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 13,
    326   rD14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
    327   rD15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 15,
    328   rD16 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 16,
    329   rD17 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 17,
    330   rD18 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 18,
    331   rD19 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 19,
    332   rD20 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 20,
    333   rD21 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 21,
    334   rD22 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 22,
    335   rD23 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 23,
    336   rD24 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 24,
    337   rD25 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 25,
    338   rD26 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 26,
    339   rD27 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 27,
    340   rD28 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 28,
    341   rD29 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 29,
    342   rD30 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 30,
    343   rD31 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 31,
    344 };
    345 
    346 constexpr RegStorage rs_rZERO(RegStorage::kValid | rZERO);
    347 constexpr RegStorage rs_rAT(RegStorage::kValid | rAT);
    348 constexpr RegStorage rs_rV0(RegStorage::kValid | rV0);
    349 constexpr RegStorage rs_rV1(RegStorage::kValid | rV1);
    350 constexpr RegStorage rs_rA0(RegStorage::kValid | rA0);
    351 constexpr RegStorage rs_rA1(RegStorage::kValid | rA1);
    352 constexpr RegStorage rs_rA2(RegStorage::kValid | rA2);
    353 constexpr RegStorage rs_rA3(RegStorage::kValid | rA3);
    354 constexpr RegStorage rs_rT0_32(RegStorage::kValid | rT0_32);
    355 constexpr RegStorage rs_rA4 = rs_rT0_32;
    356 constexpr RegStorage rs_rT1_32(RegStorage::kValid | rT1_32);
    357 constexpr RegStorage rs_rA5 = rs_rT1_32;
    358 constexpr RegStorage rs_rT2_32(RegStorage::kValid | rT2_32);
    359 constexpr RegStorage rs_rA6 = rs_rT2_32;
    360 constexpr RegStorage rs_rT3_32(RegStorage::kValid | rT3_32);
    361 constexpr RegStorage rs_rA7 = rs_rT3_32;
    362 constexpr RegStorage rs_rT4_32(RegStorage::kValid | rT4_32);
    363 constexpr RegStorage rs_rT0 = rs_rT4_32;
    364 constexpr RegStorage rs_rT5_32(RegStorage::kValid | rT5_32);
    365 constexpr RegStorage rs_rT1 = rs_rT5_32;
    366 constexpr RegStorage rs_rT6_32(RegStorage::kValid | rT6_32);
    367 constexpr RegStorage rs_rT2 = rs_rT6_32;
    368 constexpr RegStorage rs_rT7_32(RegStorage::kValid | rT7_32);
    369 constexpr RegStorage rs_rT3 = rs_rT7_32;
    370 constexpr RegStorage rs_rS0(RegStorage::kValid | rS0);
    371 constexpr RegStorage rs_rS1(RegStorage::kValid | rS1);
    372 constexpr RegStorage rs_rS2(RegStorage::kValid | rS2);
    373 constexpr RegStorage rs_rS3(RegStorage::kValid | rS3);
    374 constexpr RegStorage rs_rS4(RegStorage::kValid | rS4);
    375 constexpr RegStorage rs_rS5(RegStorage::kValid | rS5);
    376 constexpr RegStorage rs_rS6(RegStorage::kValid | rS6);
    377 constexpr RegStorage rs_rS7(RegStorage::kValid | rS7);
    378 constexpr RegStorage rs_rT8(RegStorage::kValid | rT8);
    379 constexpr RegStorage rs_rT9(RegStorage::kValid | rT9);
    380 constexpr RegStorage rs_rK0(RegStorage::kValid | rK0);
    381 constexpr RegStorage rs_rK1(RegStorage::kValid | rK1);
    382 constexpr RegStorage rs_rGP(RegStorage::kValid | rGP);
    383 constexpr RegStorage rs_rSP(RegStorage::kValid | rSP);
    384 constexpr RegStorage rs_rFP(RegStorage::kValid | rFP);
    385 constexpr RegStorage rs_rRA(RegStorage::kValid | rRA);
    386 
    387 constexpr RegStorage rs_rZEROd(RegStorage::kValid | rZEROd);
    388 constexpr RegStorage rs_rATd(RegStorage::kValid | rATd);
    389 constexpr RegStorage rs_rV0d(RegStorage::kValid | rV0d);
    390 constexpr RegStorage rs_rV1d(RegStorage::kValid | rV1d);
    391 constexpr RegStorage rs_rA0d(RegStorage::kValid | rA0d);
    392 constexpr RegStorage rs_rA1d(RegStorage::kValid | rA1d);
    393 constexpr RegStorage rs_rA2d(RegStorage::kValid | rA2d);
    394 constexpr RegStorage rs_rA3d(RegStorage::kValid | rA3d);
    395 constexpr RegStorage rs_rA4d(RegStorage::kValid | rA4d);
    396 constexpr RegStorage rs_rA5d(RegStorage::kValid | rA5d);
    397 constexpr RegStorage rs_rA6d(RegStorage::kValid | rA6d);
    398 constexpr RegStorage rs_rA7d(RegStorage::kValid | rA7d);
    399 constexpr RegStorage rs_rT0d(RegStorage::kValid | rT0d);
    400 constexpr RegStorage rs_rT1d(RegStorage::kValid | rT1d);
    401 constexpr RegStorage rs_rT2d(RegStorage::kValid | rT2d);
    402 constexpr RegStorage rs_rT3d(RegStorage::kValid | rT3d);
    403 constexpr RegStorage rs_rS0d(RegStorage::kValid | rS0d);
    404 constexpr RegStorage rs_rS1d(RegStorage::kValid | rS1d);
    405 constexpr RegStorage rs_rS2d(RegStorage::kValid | rS2d);
    406 constexpr RegStorage rs_rS3d(RegStorage::kValid | rS3d);
    407 constexpr RegStorage rs_rS4d(RegStorage::kValid | rS4d);
    408 constexpr RegStorage rs_rS5d(RegStorage::kValid | rS5d);
    409 constexpr RegStorage rs_rS6d(RegStorage::kValid | rS6d);
    410 constexpr RegStorage rs_rS7d(RegStorage::kValid | rS7d);
    411 constexpr RegStorage rs_rT8d(RegStorage::kValid | rT8d);
    412 constexpr RegStorage rs_rT9d(RegStorage::kValid | rT9d);
    413 constexpr RegStorage rs_rK0d(RegStorage::kValid | rK0d);
    414 constexpr RegStorage rs_rK1d(RegStorage::kValid | rK1d);
    415 constexpr RegStorage rs_rGPd(RegStorage::kValid | rGPd);
    416 constexpr RegStorage rs_rSPd(RegStorage::kValid | rSPd);
    417 constexpr RegStorage rs_rFPd(RegStorage::kValid | rFPd);
    418 constexpr RegStorage rs_rRAd(RegStorage::kValid | rRAd);
    419 
    420 constexpr RegStorage rs_rF0(RegStorage::kValid | rF0);
    421 constexpr RegStorage rs_rF1(RegStorage::kValid | rF1);
    422 constexpr RegStorage rs_rF2(RegStorage::kValid | rF2);
    423 constexpr RegStorage rs_rF3(RegStorage::kValid | rF3);
    424 constexpr RegStorage rs_rF4(RegStorage::kValid | rF4);
    425 constexpr RegStorage rs_rF5(RegStorage::kValid | rF5);
    426 constexpr RegStorage rs_rF6(RegStorage::kValid | rF6);
    427 constexpr RegStorage rs_rF7(RegStorage::kValid | rF7);
    428 constexpr RegStorage rs_rF8(RegStorage::kValid | rF8);
    429 constexpr RegStorage rs_rF9(RegStorage::kValid | rF9);
    430 constexpr RegStorage rs_rF10(RegStorage::kValid | rF10);
    431 constexpr RegStorage rs_rF11(RegStorage::kValid | rF11);
    432 constexpr RegStorage rs_rF12(RegStorage::kValid | rF12);
    433 constexpr RegStorage rs_rF13(RegStorage::kValid | rF13);
    434 constexpr RegStorage rs_rF14(RegStorage::kValid | rF14);
    435 constexpr RegStorage rs_rF15(RegStorage::kValid | rF15);
    436 
    437 constexpr RegStorage rs_rF16(RegStorage::kValid | rF16);
    438 constexpr RegStorage rs_rF17(RegStorage::kValid | rF17);
    439 constexpr RegStorage rs_rF18(RegStorage::kValid | rF18);
    440 constexpr RegStorage rs_rF19(RegStorage::kValid | rF19);
    441 constexpr RegStorage rs_rF20(RegStorage::kValid | rF20);
    442 constexpr RegStorage rs_rF21(RegStorage::kValid | rF21);
    443 constexpr RegStorage rs_rF22(RegStorage::kValid | rF22);
    444 constexpr RegStorage rs_rF23(RegStorage::kValid | rF23);
    445 constexpr RegStorage rs_rF24(RegStorage::kValid | rF24);
    446 constexpr RegStorage rs_rF25(RegStorage::kValid | rF25);
    447 constexpr RegStorage rs_rF26(RegStorage::kValid | rF26);
    448 constexpr RegStorage rs_rF27(RegStorage::kValid | rF27);
    449 constexpr RegStorage rs_rF28(RegStorage::kValid | rF28);
    450 constexpr RegStorage rs_rF29(RegStorage::kValid | rF29);
    451 constexpr RegStorage rs_rF30(RegStorage::kValid | rF30);
    452 constexpr RegStorage rs_rF31(RegStorage::kValid | rF31);
    453 
    454 constexpr RegStorage rs_rD0_fr0(RegStorage::kValid | rD0_fr0);
    455 constexpr RegStorage rs_rD1_fr0(RegStorage::kValid | rD1_fr0);
    456 constexpr RegStorage rs_rD2_fr0(RegStorage::kValid | rD2_fr0);
    457 constexpr RegStorage rs_rD3_fr0(RegStorage::kValid | rD3_fr0);
    458 constexpr RegStorage rs_rD4_fr0(RegStorage::kValid | rD4_fr0);
    459 constexpr RegStorage rs_rD5_fr0(RegStorage::kValid | rD5_fr0);
    460 constexpr RegStorage rs_rD6_fr0(RegStorage::kValid | rD6_fr0);
    461 constexpr RegStorage rs_rD7_fr0(RegStorage::kValid | rD7_fr0);
    462 
    463 constexpr RegStorage rs_rD0_fr1(RegStorage::kValid | rD0_fr1);
    464 constexpr RegStorage rs_rD1_fr1(RegStorage::kValid | rD1_fr1);
    465 constexpr RegStorage rs_rD2_fr1(RegStorage::kValid | rD2_fr1);
    466 constexpr RegStorage rs_rD3_fr1(RegStorage::kValid | rD3_fr1);
    467 constexpr RegStorage rs_rD4_fr1(RegStorage::kValid | rD4_fr1);
    468 constexpr RegStorage rs_rD5_fr1(RegStorage::kValid | rD5_fr1);
    469 constexpr RegStorage rs_rD6_fr1(RegStorage::kValid | rD6_fr1);
    470 constexpr RegStorage rs_rD7_fr1(RegStorage::kValid | rD7_fr1);
    471 
    472 constexpr RegStorage rs_rD0(RegStorage::kValid | rD0);
    473 constexpr RegStorage rs_rD1(RegStorage::kValid | rD1);
    474 constexpr RegStorage rs_rD2(RegStorage::kValid | rD2);
    475 constexpr RegStorage rs_rD3(RegStorage::kValid | rD3);
    476 constexpr RegStorage rs_rD4(RegStorage::kValid | rD4);
    477 constexpr RegStorage rs_rD5(RegStorage::kValid | rD5);
    478 constexpr RegStorage rs_rD6(RegStorage::kValid | rD6);
    479 constexpr RegStorage rs_rD7(RegStorage::kValid | rD7);
    480 constexpr RegStorage rs_rD8(RegStorage::kValid | rD8);
    481 constexpr RegStorage rs_rD9(RegStorage::kValid | rD9);
    482 constexpr RegStorage rs_rD10(RegStorage::kValid | rD10);
    483 constexpr RegStorage rs_rD11(RegStorage::kValid | rD11);
    484 constexpr RegStorage rs_rD12(RegStorage::kValid | rD12);
    485 constexpr RegStorage rs_rD13(RegStorage::kValid | rD13);
    486 constexpr RegStorage rs_rD14(RegStorage::kValid | rD14);
    487 constexpr RegStorage rs_rD15(RegStorage::kValid | rD15);
    488 constexpr RegStorage rs_rD16(RegStorage::kValid | rD16);
    489 constexpr RegStorage rs_rD17(RegStorage::kValid | rD17);
    490 constexpr RegStorage rs_rD18(RegStorage::kValid | rD18);
    491 constexpr RegStorage rs_rD19(RegStorage::kValid | rD19);
    492 constexpr RegStorage rs_rD20(RegStorage::kValid | rD20);
    493 constexpr RegStorage rs_rD21(RegStorage::kValid | rD21);
    494 constexpr RegStorage rs_rD22(RegStorage::kValid | rD22);
    495 constexpr RegStorage rs_rD23(RegStorage::kValid | rD23);
    496 constexpr RegStorage rs_rD24(RegStorage::kValid | rD24);
    497 constexpr RegStorage rs_rD25(RegStorage::kValid | rD25);
    498 constexpr RegStorage rs_rD26(RegStorage::kValid | rD26);
    499 constexpr RegStorage rs_rD27(RegStorage::kValid | rD27);
    500 constexpr RegStorage rs_rD28(RegStorage::kValid | rD28);
    501 constexpr RegStorage rs_rD29(RegStorage::kValid | rD29);
    502 constexpr RegStorage rs_rD30(RegStorage::kValid | rD30);
    503 constexpr RegStorage rs_rD31(RegStorage::kValid | rD31);
    504 
    505 // RegisterLocation templates return values (r_V0, or r_V0/r_V1).
    506 const RegLocation mips_loc_c_return
    507     {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
    508      RegStorage(RegStorage::k32BitSolo, rV0), INVALID_SREG, INVALID_SREG};
    509 const RegLocation mips64_loc_c_return_ref
    510     {kLocPhysReg, 0, 0, 0, 0, 0, 1, 0, 1,
    511      RegStorage(RegStorage::k64BitSolo, rV0d), INVALID_SREG, INVALID_SREG};
    512 const RegLocation mips_loc_c_return_wide
    513     {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
    514      RegStorage(RegStorage::k64BitPair, rV0, rV1), INVALID_SREG, INVALID_SREG};
    515 const RegLocation mips64_loc_c_return_wide
    516     {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
    517      RegStorage(RegStorage::k64BitSolo, rV0d), INVALID_SREG, INVALID_SREG};
    518 const RegLocation mips_loc_c_return_float
    519     {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
    520      RegStorage(RegStorage::k32BitSolo, rF0), INVALID_SREG, INVALID_SREG};
    521 // FIXME: move MIPS to k64Bitsolo for doubles
    522 const RegLocation mips_loc_c_return_double_fr0
    523     {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
    524      RegStorage(RegStorage::k64BitPair, rF0, rF1), INVALID_SREG, INVALID_SREG};
    525 const RegLocation mips_loc_c_return_double_fr1
    526     {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
    527      RegStorage(RegStorage::k64BitSolo, rF0), INVALID_SREG, INVALID_SREG};
    528 const RegLocation mips64_loc_c_return_double
    529     {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
    530      RegStorage(RegStorage::k64BitSolo, rD0), INVALID_SREG, INVALID_SREG};
    531 
    532 enum MipsShiftEncodings {
    533   kMipsLsl = 0x0,
    534   kMipsLsr = 0x1,
    535   kMipsAsr = 0x2,
    536   kMipsRor = 0x3
    537 };
    538 
    539 // MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist).
    540 #define kSYNC0        0x00
    541 #define kSYNC_WMB     0x04
    542 #define kSYNC_MB      0x01
    543 #define kSYNC_ACQUIRE 0x11
    544 #define kSYNC_RELEASE 0x12
    545 #define kSYNC_RMB     0x13
    546 
    547 // TODO: Use smaller hammer when appropriate for target CPU.
    548 #define kST kSYNC0
    549 #define kSY kSYNC0
    550 
    551 /*
    552  * The following enum defines the list of supported mips instructions by the
    553  * assembler. Their corresponding EncodingMap positions will be defined in
    554  * assemble_mips.cc.
    555  */
    556 enum MipsOpCode {
    557   kMipsFirst = 0,
    558   // The following are common mips32r2, mips32r6 and mips64r6 instructions.
    559   kMips32BitData = kMipsFirst,  // data [31..0].
    560   kMipsAddiu,      // addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
    561   kMipsAddu,       // add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001].
    562   kMipsAnd,        // and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100].
    563   kMipsAndi,       // andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0].
    564   kMipsB,          // b o   [0001000000000000] o[15..0].
    565   kMipsBal,        // bal o [0000010000010001] o[15..0].
    566   // NOTE : the code tests the range kMipsBeq thru kMipsBne, so adding an instruction in this
    567   // range may require updates.
    568   kMipsBeq,        // beq s,t,o [000100] s[25..21] t[20..16] o[15..0].
    569   kMipsBeqz,       // beqz s,o [000100] s[25..21] [00000] o[15..0].
    570   kMipsBgez,       // bgez s,o [000001] s[25..21] [00001] o[15..0].
    571   kMipsBgtz,       // bgtz s,o [000111] s[25..21] [00000] o[15..0].
    572   kMipsBlez,       // blez s,o [000110] s[25..21] [00000] o[15..0].
    573   kMipsBltz,       // bltz s,o [000001] s[25..21] [00000] o[15..0].
    574   kMipsBnez,       // bnez s,o [000101] s[25..21] [00000] o[15..0].
    575   kMipsBne,        // bne s,t,o [000101] s[25..21] t[20..16] o[15..0].
    576   kMipsExt,        // ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000].
    577   kMipsFaddd,      // add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000].
    578   kMipsFadds,      // add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000].
    579   kMipsFsubd,      // sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001].
    580   kMipsFsubs,      // sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001].
    581   kMipsFdivd,      // div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011].
    582   kMipsFdivs,      // div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011].
    583   kMipsFmuld,      // mul.d d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010].
    584   kMipsFmuls,      // mul.s d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010].
    585   kMipsFcvtsd,     // cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000].
    586   kMipsFcvtsw,     // cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000].
    587   kMipsFcvtds,     // cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001].
    588   kMipsFcvtdw,     // cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001].
    589   kMipsFcvtwd,     // cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100].
    590   kMipsFcvtws,     // cvt.w.s d,s [01000110000] [00000] s[15..11] d[10..6] [100100].
    591   kMipsFmovd,      // mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110].
    592   kMipsFmovs,      // mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110].
    593   kMipsFnegd,      // neg.d d,s [01000110001] [00000] s[15..11] d[10..6] [000111].
    594   kMipsFnegs,      // neg.s d,s [01000110000] [00000] s[15..11] d[10..6] [000111].
    595   kMipsFldc1,      // ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0].
    596   kMipsFlwc1,      // lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0].
    597   kMipsFsdc1,      // sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0].
    598   kMipsFswc1,      // swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0].
    599   kMipsJal,        // jal t [000011] t[25..0].
    600   kMipsJalr,       // jalr d,s [000000] s[25..21] [00000] d[15..11] hint[10..6] [001001].
    601   kMipsJr,         // jr s [000000] s[25..21] [0000000000] hint[10..6] [001000].
    602   kMipsLahi,       // lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi.
    603   kMipsLalo,       // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo.
    604   kMipsLui,        // lui t,imm16 [00111100000] t[20..16] imm16[15..0].
    605   kMipsLb,         // lb t,o(b) [100000] b[25..21] t[20..16] o[15..0].
    606   kMipsLbu,        // lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0].
    607   kMipsLh,         // lh t,o(b) [100001] b[25..21] t[20..16] o[15..0].
    608   kMipsLhu,        // lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0].
    609   kMipsLw,         // lw t,o(b) [100011] b[25..21] t[20..16] o[15..0].
    610   kMipsMove,       // move d,s [000000] s[25..21] [00000] d[15..11] [00000100101].
    611   kMipsMfc1,       // mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000].
    612   kMipsMtc1,       // mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000].
    613   kMipsMfhc1,      // mfhc1 t,s [01000100011] t[20..16] s[15..11] [00000000000].
    614   kMipsMthc1,      // mthc1 t,s [01000100111] t[20..16] s[15..11] [00000000000].
    615   kMipsNop,        // nop [00000000000000000000000000000000].
    616   kMipsNor,        // nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111].
    617   kMipsOr,         // or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101].
    618   kMipsOri,        // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
    619   kMipsPref,       // pref h,o(b) [101011] b[25..21] h[20..16] o[15..0].
    620   kMipsSb,         // sb t,o(b) [101000] b[25..21] t[20..16] o[15..0].
    621   kMipsSeb,        // seb d,t [01111100000] t[20..16] d[15..11] [10000100000].
    622   kMipsSeh,        // seh d,t [01111100000] t[20..16] d[15..11] [11000100000].
    623   kMipsSh,         // sh t,o(b) [101001] b[25..21] t[20..16] o[15..0].
    624   kMipsSll,        // sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000].
    625   kMipsSllv,       // sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100].
    626   kMipsSlt,        // slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010].
    627   kMipsSlti,       // slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0].
    628   kMipsSltu,       // sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011].
    629   kMipsSra,        // sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011].
    630   kMipsSrav,       // srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111].
    631   kMipsSrl,        // srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010].
    632   kMipsSrlv,       // srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110].
    633   kMipsSubu,       // subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011].
    634   kMipsSw,         // sw t,o(b) [101011] b[25..21] t[20..16] o[15..0].
    635   kMipsSync,       // sync kind [000000] [0000000000000000] s[10..6] [001111].
    636   kMipsXor,        // xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110].
    637   kMipsXori,       // xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0].
    638 
    639   // The following are mips32r2 instructions.
    640   kMipsR2Div,      // div s,t [000000] s[25..21] t[20..16] [0000000000011010].
    641   kMipsR2Mul,      // mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010].
    642   kMipsR2Mfhi,     // mfhi d [0000000000000000] d[15..11] [00000010000].
    643   kMipsR2Mflo,     // mflo d [0000000000000000] d[15..11] [00000010010].
    644   kMipsR2Movz,     // movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010].
    645 
    646   // The following are mips32r6 and mips64r6 instructions.
    647   kMipsR6Div,      // div d,s,t [000000] s[25..21] t[20..16] d[15..11] [00010011010].
    648   kMipsR6Mod,      // mod d,s,t [000000] s[25..21] t[20..16] d[15..11] [00011011010].
    649   kMipsR6Mul,      // mul d,s,t [000000] s[25..21] t[20..16] d[15..11] [00010011000].
    650 
    651   // The following are mips64r6 instructions.
    652   kMips64Daddiu,   // daddiu t,s,imm16 [011001] s[25..21] t[20..16] imm16[15..11].
    653   kMips64Daddu,    // daddu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101101].
    654   kMips64Dahi,     // dahi s,imm16 [000001] s[25..21] [00110] imm16[15..11].
    655   kMips64Dati,     // dati s,imm16 [000001] s[25..21] [11110] imm16[15..11].
    656   kMips64Daui,     // daui t,s,imm16 [011101] s[25..21] t[20..16] imm16[15..11].
    657   kMips64Ddiv,     // ddiv  d,s,t [000000] s[25..21] t[20..16] d[15..11] [00010011110].
    658   kMips64Dmod,     // dmod  d,s,t [000000] s[25..21] t[20..16] d[15..11] [00011011110].
    659   kMips64Dmul,     // dmul  d,s,t [000000] s[25..21] t[20..16] d[15..11] [00010011100].
    660   kMips64Dmfc1,    // dmfc1 t,s [01000100001] t[20..16] s[15..11] [00000000000].
    661   kMips64Dmtc1,    // dmtc1 t,s [01000100101] t[20..16] s[15..11] [00000000000].
    662   kMips64Drotr32,  // drotr32 d,t,a [00000000001] t[20..16] d[15..11] a[10..6] [111110].
    663   kMips64Dsll,     // dsll    d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111000].
    664   kMips64Dsll32,   // dsll32  d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111100].
    665   kMips64Dsrl,     // dsrl    d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111010].
    666   kMips64Dsrl32,   // dsrl32  d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111110].
    667   kMips64Dsra,     // dsra    d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111011].
    668   kMips64Dsra32,   // dsra32  d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [111111].
    669   kMips64Dsllv,    // dsllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000010100].
    670   kMips64Dsrlv,    // dsrlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000010110].
    671   kMips64Dsrav,    // dsrav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000010111].
    672   kMips64Dsubu,    // dsubu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101111].
    673   kMips64Ld,       // ld  t,o(b) [110111] b[25..21] t[20..16] o[15..0].
    674   kMips64Lwu,      // lwu t,o(b) [100111] b[25..21] t[20..16] o[15..0].
    675   kMips64Sd,       // sd t,o(b) [111111] b[25..21] t[20..16] o[15..0].
    676 
    677   // The following are pseudoinstructions.
    678   kMipsDelta,      // Psuedo for ori t, s, <label>-<label>.
    679   kMipsDeltaHi,    // Pseudo for lui t, high16(<label>-<label>).
    680   kMipsDeltaLo,    // Pseudo for ori t, s, low16(<label>-<label>).
    681   kMipsCurrPC,     // jal to .+8 to materialize pc.
    682   kMipsUndefined,  // undefined [011001xxxxxxxxxxxxxxxx].
    683   kMipsLast
    684 };
    685 std::ostream& operator<<(std::ostream& os, const MipsOpCode& rhs);
    686 
    687 // Instruction assembly field_loc kind.
    688 enum MipsEncodingKind {
    689   kFmtUnused,
    690   kFmtBitBlt,    // Bit string using end/start.
    691   kFmtDfp,       // Double FP reg.
    692   kFmtSfp,       // Single FP reg.
    693   kFmtBlt5_2,    // Same 5-bit field to 2 locations.
    694 };
    695 std::ostream& operator<<(std::ostream& os, const MipsEncodingKind& rhs);
    696 
    697 // Struct used to define the snippet positions for each MIPS opcode.
    698 struct MipsEncodingMap {
    699   uint32_t skeleton;
    700   struct {
    701     MipsEncodingKind kind;
    702     int end;   // end for kFmtBitBlt, 1-bit slice end for FP regs.
    703     int start;  // start for kFmtBitBlt, 4-bit slice end for FP regs.
    704   } field_loc[4];
    705   MipsOpCode opcode;
    706   uint64_t flags;
    707   const char *name;
    708   const char* fmt;
    709   int size;   // Note: size is in bytes.
    710 };
    711 
    712 extern MipsEncodingMap EncodingMap[kMipsLast];
    713 
    714 #define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
    715 #define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
    716 #define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763))  // 2 offsets must fit.
    717 
    718 }  // namespace art
    719 
    720 #endif  // ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_
    721