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/compiler_internals.h"
     21 
     22 namespace art {
     23 
     24 /*
     25  * Runtime register conventions.
     26  *
     27  * zero is always the value 0
     28  * at is scratch (normally used as temp reg by assembler)
     29  * v0, v1 are scratch (normally hold subroutine return values)
     30  * a0-a3 are scratch (normally hold subroutine arguments)
     31  * t0-t8 are scratch
     32  * t9 is scratch (normally used for function calls)
     33  * s0 (rMIPS_SUSPEND) is reserved [holds suspend-check counter]
     34  * s1 (rMIPS_SELF) is reserved [holds current &Thread]
     35  * s2-s7 are callee save (promotion target)
     36  * k0, k1 are reserved for use by interrupt handlers
     37  * gp is reserved for global pointer
     38  * sp is reserved
     39  * s8 is callee save (promotion target)
     40  * ra is scratch (normally holds the return addr)
     41  *
     42  * Preserved across C calls: s0-s8
     43  * Trashed across C calls: at, v0-v1, a0-a3, t0-t9, gp, ra
     44  *
     45  * Floating pointer registers
     46  * NOTE: there are 32 fp registers (16 df pairs), but currently
     47  *       only support 16 fp registers (8 df pairs).
     48  * f0-f15
     49  * df0-df7, where df0={f0,f1}, df1={f2,f3}, ... , df7={f14,f15}
     50  *
     51  * f0-f15 (df0-df7) trashed across C calls
     52  *
     53  * For mips32 code use:
     54  *      a0-a3 to hold operands
     55  *      v0-v1 to hold results
     56  *      t0-t9 for temps
     57  *
     58  * All jump/branch instructions have a delay slot after it.
     59  *
     60  *  Stack frame diagram (stack grows down, higher addresses at top):
     61  *
     62  * +------------------------+
     63  * | IN[ins-1]              |  {Note: resides in caller's frame}
     64  * |       .                |
     65  * | IN[0]                  |
     66  * | caller's Method*       |
     67  * +========================+  {Note: start of callee's frame}
     68  * | spill region           |  {variable sized - will include lr if non-leaf.}
     69  * +------------------------+
     70  * | ...filler word...      |  {Note: used as 2nd word of V[locals-1] if long]
     71  * +------------------------+
     72  * | V[locals-1]            |
     73  * | V[locals-2]            |
     74  * |      .                 |
     75  * |      .                 |
     76  * | V[1]                   |
     77  * | V[0]                   |
     78  * +------------------------+
     79  * |  0 to 3 words padding  |
     80  * +------------------------+
     81  * | OUT[outs-1]            |
     82  * | OUT[outs-2]            |
     83  * |       .                |
     84  * | OUT[0]                 |
     85  * | cur_method*            | <<== sp w/ 16-byte alignment
     86  * +========================+
     87  */
     88 
     89 
     90 #define LOWORD_OFFSET 0
     91 #define HIWORD_OFFSET 4
     92 #define rARG0 rA0
     93 #define rs_rARG0 rs_rA0
     94 #define rARG1 rA1
     95 #define rs_rARG1 rs_rA1
     96 #define rARG2 rA2
     97 #define rs_rARG2 rs_rA2
     98 #define rARG3 rA3
     99 #define rs_rARG3 rs_rA3
    100 #define rRESULT0 rV0
    101 #define rs_rRESULT0 rs_rV0
    102 #define rRESULT1 rV1
    103 #define rs_rRESULT1 rs_rV1
    104 
    105 #define rFARG0 rF12
    106 #define rs_rFARG0 rs_rF12
    107 #define rFARG1 rF13
    108 #define rs_rFARG1 rs_rF13
    109 #define rFARG2 rF14
    110 #define rs_rFARG2 rs_rF14
    111 #define rFARG3 rF15
    112 #define rs_rFARG3 rs_rF15
    113 #define rFRESULT0 rF0
    114 #define rs_rFRESULT0 rs_rF0
    115 #define rFRESULT1 rF1
    116 #define rs_rFRESULT1 rs_rF1
    117 
    118 // Regs not used for Mips.
    119 #define rMIPS_LR RegStorage::kInvalidRegVal
    120 #define rMIPS_PC RegStorage::kInvalidRegVal
    121 
    122 enum MipsResourceEncodingPos {
    123   kMipsGPReg0   = 0,
    124   kMipsRegSP    = 29,
    125   kMipsRegLR    = 31,
    126   kMipsFPReg0   = 32,  // only 16 fp regs supported currently.
    127   kMipsFPRegEnd   = 48,
    128   kMipsRegHI    = kMipsFPRegEnd,
    129   kMipsRegLO,
    130   kMipsRegPC,
    131   kMipsRegEnd   = 51,
    132 };
    133 
    134 #define ENCODE_MIPS_REG_LIST(N)      (static_cast<uint64_t>(N))
    135 #define ENCODE_MIPS_REG_SP           (1ULL << kMipsRegSP)
    136 #define ENCODE_MIPS_REG_LR           (1ULL << kMipsRegLR)
    137 #define ENCODE_MIPS_REG_PC           (1ULL << kMipsRegPC)
    138 #define ENCODE_MIPS_REG_HI           (1ULL << kMipsRegHI)
    139 #define ENCODE_MIPS_REG_LO           (1ULL << kMipsRegLO)
    140 
    141 // Set FR_BIT to 0
    142 // This bit determines how the CPU access FP registers.
    143 #define FR_BIT   0
    144 
    145 enum MipsNativeRegisterPool {
    146   rZERO = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  0,
    147   rAT   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  1,
    148   rV0   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  2,
    149   rV1   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  3,
    150   rA0   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  4,
    151   rA1   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  5,
    152   rA2   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  6,
    153   rA3   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  7,
    154   rT0   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  8,
    155   rT1   = RegStorage::k32BitSolo | RegStorage::kCoreRegister |  9,
    156   rT2   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
    157   rT3   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
    158   rT4   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
    159   rT5   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
    160   rT6   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
    161   rT7   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
    162   rS0   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
    163   rS1   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 17,
    164   rS2   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 18,
    165   rS3   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 19,
    166   rS4   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 20,
    167   rS5   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 21,
    168   rS6   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 22,
    169   rS7   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 23,
    170   rT8   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 24,
    171   rT9   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 25,
    172   rK0   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 26,
    173   rK1   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 27,
    174   rGP   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 28,
    175   rSP   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 29,
    176   rFP   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 30,
    177   rRA   = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 31,
    178 
    179   rF0  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  0,
    180   rF1  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  1,
    181   rF2  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  2,
    182   rF3  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  3,
    183   rF4  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  4,
    184   rF5  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  5,
    185   rF6  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  6,
    186   rF7  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  7,
    187   rF8  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  8,
    188   rF9  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint |  9,
    189   rF10 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 10,
    190   rF11 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 11,
    191   rF12 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 12,
    192   rF13 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 13,
    193   rF14 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 14,
    194   rF15 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 15,
    195 #if 0
    196   /*
    197    * TODO: The shared resource mask doesn't have enough bit positions to describe all
    198    * MIPS registers.  Expand it and enable use of fp registers 16 through 31.
    199    */
    200   rF16 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 16,
    201   rF17 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 17,
    202   rF18 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 18,
    203   rF19 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 19,
    204   rF20 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 20,
    205   rF21 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 21,
    206   rF22 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 22,
    207   rF23 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 23,
    208   rF24 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 24,
    209   rF25 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 25,
    210   rF26 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 26,
    211   rF27 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 27,
    212   rF28 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 28,
    213   rF29 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 29,
    214   rF30 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 30,
    215   rF31 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 31,
    216 #endif
    217 #if (FR_BIT == 0)
    218   rD0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  0,
    219   rD1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  2,
    220   rD2  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  4,
    221   rD3  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  6,
    222   rD4  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  8,
    223   rD5  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
    224   rD6  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
    225   rD7  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
    226 #if 0  // TODO: expand resource mask to enable use of all MIPS fp registers.
    227   rD8  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 16,
    228   rD9  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 18,
    229   rD10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 20,
    230   rD11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 22,
    231   rD12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 24,
    232   rD13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 26,
    233   rD14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 28,
    234   rD15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 30,
    235 #endif
    236 #else
    237   rD0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  0,
    238   rD1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  1,
    239   rD2  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  2,
    240   rD3  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  3,
    241   rD4  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  4,
    242   rD5  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  5,
    243   rD6  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  6,
    244   rD7  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  7,
    245 #if 0  // TODO: expand resource mask to enable use of all MIPS fp registers.
    246   rD8  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  8,
    247   rD9  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint |  9,
    248   rD10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
    249   rD11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 11,
    250   rD12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
    251   rD13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 13,
    252   rD14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
    253   rD15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 15,
    254 #endif
    255 #endif
    256 };
    257 
    258 constexpr RegStorage rs_rZERO(RegStorage::kValid | rZERO);
    259 constexpr RegStorage rs_rAT(RegStorage::kValid | rAT);
    260 constexpr RegStorage rs_rV0(RegStorage::kValid | rV0);
    261 constexpr RegStorage rs_rV1(RegStorage::kValid | rV1);
    262 constexpr RegStorage rs_rA0(RegStorage::kValid | rA0);
    263 constexpr RegStorage rs_rA1(RegStorage::kValid | rA1);
    264 constexpr RegStorage rs_rA2(RegStorage::kValid | rA2);
    265 constexpr RegStorage rs_rA3(RegStorage::kValid | rA3);
    266 constexpr RegStorage rs_rT0(RegStorage::kValid | rT0);
    267 constexpr RegStorage rs_rT1(RegStorage::kValid | rT1);
    268 constexpr RegStorage rs_rT2(RegStorage::kValid | rT2);
    269 constexpr RegStorage rs_rT3(RegStorage::kValid | rT3);
    270 constexpr RegStorage rs_rT4(RegStorage::kValid | rT4);
    271 constexpr RegStorage rs_rT5(RegStorage::kValid | rT5);
    272 constexpr RegStorage rs_rT6(RegStorage::kValid | rT6);
    273 constexpr RegStorage rs_rT7(RegStorage::kValid | rT7);
    274 constexpr RegStorage rs_rS0(RegStorage::kValid | rS0);
    275 constexpr RegStorage rs_rS1(RegStorage::kValid | rS1);
    276 constexpr RegStorage rs_rS2(RegStorage::kValid | rS2);
    277 constexpr RegStorage rs_rS3(RegStorage::kValid | rS3);
    278 constexpr RegStorage rs_rS4(RegStorage::kValid | rS4);
    279 constexpr RegStorage rs_rS5(RegStorage::kValid | rS5);
    280 constexpr RegStorage rs_rS6(RegStorage::kValid | rS6);
    281 constexpr RegStorage rs_rS7(RegStorage::kValid | rS7);
    282 constexpr RegStorage rs_rT8(RegStorage::kValid | rT8);
    283 constexpr RegStorage rs_rT9(RegStorage::kValid | rT9);
    284 constexpr RegStorage rs_rK0(RegStorage::kValid | rK0);
    285 constexpr RegStorage rs_rK1(RegStorage::kValid | rK1);
    286 constexpr RegStorage rs_rGP(RegStorage::kValid | rGP);
    287 constexpr RegStorage rs_rSP(RegStorage::kValid | rSP);
    288 constexpr RegStorage rs_rFP(RegStorage::kValid | rFP);
    289 constexpr RegStorage rs_rRA(RegStorage::kValid | rRA);
    290 
    291 constexpr RegStorage rs_rMIPS_LR(RegStorage::kInvalid);     // Not used for MIPS.
    292 constexpr RegStorage rs_rMIPS_PC(RegStorage::kInvalid);     // Not used for MIPS.
    293 constexpr RegStorage rs_rMIPS_COUNT(RegStorage::kInvalid);  // Not used for MIPS.
    294 
    295 constexpr RegStorage rs_rF0(RegStorage::kValid | rF0);
    296 constexpr RegStorage rs_rF1(RegStorage::kValid | rF1);
    297 constexpr RegStorage rs_rF2(RegStorage::kValid | rF2);
    298 constexpr RegStorage rs_rF3(RegStorage::kValid | rF3);
    299 constexpr RegStorage rs_rF4(RegStorage::kValid | rF4);
    300 constexpr RegStorage rs_rF5(RegStorage::kValid | rF5);
    301 constexpr RegStorage rs_rF6(RegStorage::kValid | rF6);
    302 constexpr RegStorage rs_rF7(RegStorage::kValid | rF7);
    303 constexpr RegStorage rs_rF8(RegStorage::kValid | rF8);
    304 constexpr RegStorage rs_rF9(RegStorage::kValid | rF9);
    305 constexpr RegStorage rs_rF10(RegStorage::kValid | rF10);
    306 constexpr RegStorage rs_rF11(RegStorage::kValid | rF11);
    307 constexpr RegStorage rs_rF12(RegStorage::kValid | rF12);
    308 constexpr RegStorage rs_rF13(RegStorage::kValid | rF13);
    309 constexpr RegStorage rs_rF14(RegStorage::kValid | rF14);
    310 constexpr RegStorage rs_rF15(RegStorage::kValid | rF15);
    311 
    312 constexpr RegStorage rs_rD0(RegStorage::kValid | rD0);
    313 constexpr RegStorage rs_rD1(RegStorage::kValid | rD1);
    314 constexpr RegStorage rs_rD2(RegStorage::kValid | rD2);
    315 constexpr RegStorage rs_rD3(RegStorage::kValid | rD3);
    316 constexpr RegStorage rs_rD4(RegStorage::kValid | rD4);
    317 constexpr RegStorage rs_rD5(RegStorage::kValid | rD5);
    318 constexpr RegStorage rs_rD6(RegStorage::kValid | rD6);
    319 constexpr RegStorage rs_rD7(RegStorage::kValid | rD7);
    320 
    321 // TODO: reduce/eliminate use of these.
    322 #define rMIPS_SUSPEND rS0
    323 #define rs_rMIPS_SUSPEND rs_rS0
    324 #define rMIPS_SELF rS1
    325 #define rs_rMIPS_SELF rs_rS1
    326 #define rMIPS_SP rSP
    327 #define rs_rMIPS_SP rs_rSP
    328 #define rMIPS_ARG0 rARG0
    329 #define rs_rMIPS_ARG0 rs_rARG0
    330 #define rMIPS_ARG1 rARG1
    331 #define rs_rMIPS_ARG1 rs_rARG1
    332 #define rMIPS_ARG2 rARG2
    333 #define rs_rMIPS_ARG2 rs_rARG2
    334 #define rMIPS_ARG3 rARG3
    335 #define rs_rMIPS_ARG3 rs_rARG3
    336 #define rMIPS_FARG0 rFARG0
    337 #define rs_rMIPS_FARG0 rs_rFARG0
    338 #define rMIPS_FARG1 rFARG1
    339 #define rs_rMIPS_FARG1 rs_rFARG1
    340 #define rMIPS_FARG2 rFARG2
    341 #define rs_rMIPS_FARG2 rs_rFARG2
    342 #define rMIPS_FARG3 rFARG3
    343 #define rs_rMIPS_FARG3 rs_rFARG3
    344 #define rMIPS_RET0 rRESULT0
    345 #define rs_rMIPS_RET0 rs_rRESULT0
    346 #define rMIPS_RET1 rRESULT1
    347 #define rs_rMIPS_RET1 rs_rRESULT1
    348 #define rMIPS_INVOKE_TGT rT9
    349 #define rs_rMIPS_INVOKE_TGT rs_rT9
    350 #define rMIPS_COUNT RegStorage::kInvalidRegVal
    351 
    352 // RegisterLocation templates return values (r_V0, or r_V0/r_V1).
    353 const RegLocation mips_loc_c_return
    354     {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
    355      RegStorage(RegStorage::k32BitSolo, rV0), INVALID_SREG, INVALID_SREG};
    356 const RegLocation mips_loc_c_return_wide
    357     {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
    358      RegStorage(RegStorage::k64BitPair, rV0, rV1), INVALID_SREG, INVALID_SREG};
    359 const RegLocation mips_loc_c_return_float
    360     {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
    361      RegStorage(RegStorage::k32BitSolo, rF0), INVALID_SREG, INVALID_SREG};
    362 // FIXME: move MIPS to k64Bitsolo for doubles
    363 const RegLocation mips_loc_c_return_double
    364     {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
    365      RegStorage(RegStorage::k64BitPair, rF0, rF1), INVALID_SREG, INVALID_SREG};
    366 
    367 enum MipsShiftEncodings {
    368   kMipsLsl = 0x0,
    369   kMipsLsr = 0x1,
    370   kMipsAsr = 0x2,
    371   kMipsRor = 0x3
    372 };
    373 
    374 // MIPS sync kinds (Note: support for kinds other than kSYNC0 may not exist).
    375 #define kSYNC0        0x00
    376 #define kSYNC_WMB     0x04
    377 #define kSYNC_MB      0x01
    378 #define kSYNC_ACQUIRE 0x11
    379 #define kSYNC_RELEASE 0x12
    380 #define kSYNC_RMB     0x13
    381 
    382 // TODO: Use smaller hammer when appropriate for target CPU.
    383 #define kST kSYNC0
    384 #define kSY kSYNC0
    385 
    386 /*
    387  * The following enum defines the list of supported Thumb instructions by the
    388  * assembler. Their corresponding EncodingMap positions will be defined in
    389  * Assemble.cc.
    390  */
    391 enum MipsOpCode {
    392   kMipsFirst = 0,
    393   kMips32BitData = kMipsFirst,  // data [31..0].
    394   kMipsAddiu,  // addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
    395   kMipsAddu,  // add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001].
    396   kMipsAnd,   // and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100].
    397   kMipsAndi,  // andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0].
    398   kMipsB,     // b o   [0001000000000000] o[15..0].
    399   kMipsBal,   // bal o [0000010000010001] o[15..0].
    400   // NOTE: the code tests the range kMipsBeq thru kMipsBne, so adding an instruction in this
    401   //       range may require updates.
    402   kMipsBeq,   // beq s,t,o [000100] s[25..21] t[20..16] o[15..0].
    403   kMipsBeqz,  // beqz s,o [000100] s[25..21] [00000] o[15..0].
    404   kMipsBgez,  // bgez s,o [000001] s[25..21] [00001] o[15..0].
    405   kMipsBgtz,  // bgtz s,o [000111] s[25..21] [00000] o[15..0].
    406   kMipsBlez,  // blez s,o [000110] s[25..21] [00000] o[15..0].
    407   kMipsBltz,  // bltz s,o [000001] s[25..21] [00000] o[15..0].
    408   kMipsBnez,  // bnez s,o [000101] s[25..21] [00000] o[15..0].
    409   kMipsBne,   // bne s,t,o [000101] s[25..21] t[20..16] o[15..0].
    410   kMipsDiv,   // div s,t [000000] s[25..21] t[20..16] [0000000000011010].
    411 #if __mips_isa_rev >= 2
    412   kMipsExt,   // ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000].
    413 #endif
    414   kMipsJal,   // jal t [000011] t[25..0].
    415   kMipsJalr,  // jalr d,s [000000] s[25..21] [00000] d[15..11] hint[10..6] [001001].
    416   kMipsJr,    // jr s [000000] s[25..21] [0000000000] hint[10..6] [001000].
    417   kMipsLahi,  // lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi.
    418   kMipsLalo,  // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo.
    419   kMipsLui,   // lui t,imm16 [00111100000] t[20..16] imm16[15..0].
    420   kMipsLb,    // lb t,o(b) [100000] b[25..21] t[20..16] o[15..0].
    421   kMipsLbu,   // lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0].
    422   kMipsLh,    // lh t,o(b) [100001] b[25..21] t[20..16] o[15..0].
    423   kMipsLhu,   // lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0].
    424   kMipsLw,    // lw t,o(b) [100011] b[25..21] t[20..16] o[15..0].
    425   kMipsMfhi,  // mfhi d [0000000000000000] d[15..11] [00000010000].
    426   kMipsMflo,  // mflo d [0000000000000000] d[15..11] [00000010010].
    427   kMipsMove,  // move d,s [000000] s[25..21] [00000] d[15..11] [00000100101].
    428   kMipsMovz,  // movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010].
    429   kMipsMul,   // mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010].
    430   kMipsNop,   // nop [00000000000000000000000000000000].
    431   kMipsNor,   // nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111].
    432   kMipsOr,    // or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101].
    433   kMipsOri,   // ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0].
    434   kMipsPref,  // pref h,o(b) [101011] b[25..21] h[20..16] o[15..0].
    435   kMipsSb,    // sb t,o(b) [101000] b[25..21] t[20..16] o[15..0].
    436 #if __mips_isa_rev >= 2
    437   kMipsSeb,   // seb d,t [01111100000] t[20..16] d[15..11] [10000100000].
    438   kMipsSeh,   // seh d,t [01111100000] t[20..16] d[15..11] [11000100000].
    439 #endif
    440   kMipsSh,    // sh t,o(b) [101001] b[25..21] t[20..16] o[15..0].
    441   kMipsSll,   // sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000].
    442   kMipsSllv,  // sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100].
    443   kMipsSlt,   // slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010].
    444   kMipsSlti,  // slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0].
    445   kMipsSltu,  // sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011].
    446   kMipsSra,   // sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011].
    447   kMipsSrav,  // srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111].
    448   kMipsSrl,   // srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010].
    449   kMipsSrlv,  // srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110].
    450   kMipsSubu,  // subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011].
    451   kMipsSw,    // sw t,o(b) [101011] b[25..21] t[20..16] o[15..0].
    452   kMipsXor,   // xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110].
    453   kMipsXori,  // xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0].
    454   kMipsFadds,  // add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000].
    455   kMipsFsubs,  // sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001].
    456   kMipsFmuls,  // mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010].
    457   kMipsFdivs,  // div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011].
    458   kMipsFaddd,  // add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000].
    459   kMipsFsubd,  // sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001].
    460   kMipsFmuld,  // mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010].
    461   kMipsFdivd,  // div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011].
    462   kMipsFcvtsd,  // cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000].
    463   kMipsFcvtsw,  // cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000].
    464   kMipsFcvtds,  // cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001].
    465   kMipsFcvtdw,  // cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001].
    466   kMipsFcvtws,  // cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100].
    467   kMipsFcvtwd,  // cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100].
    468   kMipsFmovs,  // mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110].
    469   kMipsFmovd,  // mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110].
    470   kMipsFlwc1,  // lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0].
    471   kMipsFldc1,  // ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0].
    472   kMipsFswc1,  // swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0].
    473   kMipsFsdc1,  // sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0].
    474   kMipsMfc1,  // mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000].
    475   kMipsMtc1,  // mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000].
    476   kMipsDelta,  // Psuedo for ori t, s, <label>-<label>.
    477   kMipsDeltaHi,  // Pseudo for lui t, high16(<label>-<label>).
    478   kMipsDeltaLo,  // Pseudo for ori t, s, low16(<label>-<label>).
    479   kMipsCurrPC,  // jal to .+8 to materialize pc.
    480   kMipsSync,    // sync kind [000000] [0000000000000000] s[10..6] [001111].
    481   kMipsUndefined,  // undefined [011001xxxxxxxxxxxxxxxx].
    482   kMipsLast
    483 };
    484 
    485 // Instruction assembly field_loc kind.
    486 enum MipsEncodingKind {
    487   kFmtUnused,
    488   kFmtBitBlt,    /* Bit string using end/start */
    489   kFmtDfp,       /* Double FP reg */
    490   kFmtSfp,       /* Single FP reg */
    491   kFmtBlt5_2,    /* Same 5-bit field to 2 locations */
    492 };
    493 
    494 // Struct used to define the snippet positions for each MIPS opcode.
    495 struct MipsEncodingMap {
    496   uint32_t skeleton;
    497   struct {
    498     MipsEncodingKind kind;
    499     int end;   // end for kFmtBitBlt, 1-bit slice end for FP regs.
    500     int start;  // start for kFmtBitBlt, 4-bit slice end for FP regs.
    501   } field_loc[4];
    502   MipsOpCode opcode;
    503   uint64_t flags;
    504   const char *name;
    505   const char* fmt;
    506   int size;   // Note: size is in bytes.
    507 };
    508 
    509 extern MipsEncodingMap EncodingMap[kMipsLast];
    510 
    511 #define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
    512 #define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
    513 #define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763))  // 2 offsets must fit.
    514 
    515 }  // namespace art
    516 
    517 #endif  // ART_COMPILER_DEX_QUICK_MIPS_MIPS_LIR_H_
    518