Home | History | Annotate | Download | only in x86
      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_X86_X86_LIR_H_
     18 #define ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_
     19 
     20 #include "dex/compiler_internals.h"
     21 
     22 namespace art {
     23 
     24 /*
     25  * Runtime register conventions. We consider both x86, x86-64 and x32 (32bit mode x86-64). The ABI
     26  * has different conventions and we capture those here. Changing something that is callee save and
     27  * making it caller save places a burden on up-calls to save/restore the callee save register,
     28  * however, there are few registers that are callee save in the ABI. Changing something that is
     29  * caller save and making it callee save places a burden on down-calls to save/restore the callee
     30  * save register. For these reasons we aim to match native conventions for caller and callee save.
     31  * On x86 only the first 4 registers can be used for byte operations, for this reason they are
     32  * preferred for temporary scratch registers.
     33  *
     34  * General Purpose Register:
     35  *  Native: x86    | x86-64 / x32 | ART x86                                         | ART x86-64
     36  *  r0/eax: caller | caller       | caller, Method*, scratch, return value          | caller, scratch, return value
     37  *  r1/ecx: caller | caller, arg4 | caller, arg1, scratch                           | caller, arg3, scratch
     38  *  r2/edx: caller | caller, arg3 | caller, arg2, scratch, high half of long return | caller, arg2, scratch
     39  *  r3/ebx: callEE | callEE       | callER, arg3, scratch                           | callee, promotable
     40  *  r4/esp: stack pointer
     41  *  r5/ebp: callee | callee       | callee, promotable                              | callee, promotable
     42  *  r6/esi: callEE | callER, arg2 | callee, promotable                              | caller, arg1, scratch
     43  *  r7/edi: callEE | callER, arg1 | callee, promotable                              | caller, Method*, scratch
     44  *  ---  x86-64/x32 registers
     45  *  Native: x86-64 / x32      | ART
     46  *  r8:     caller save, arg5 | caller, arg4, scratch
     47  *  r9:     caller save, arg6 | caller, arg5, scratch
     48  *  r10:    caller save       | caller, scratch
     49  *  r11:    caller save       | caller, scratch
     50  *  r12:    callee save       | callee, available for register promotion (promotable)
     51  *  r13:    callee save       | callee, available for register promotion (promotable)
     52  *  r14:    callee save       | callee, available for register promotion (promotable)
     53  *  r15:    callee save       | callee, available for register promotion (promotable)
     54  *
     55  * There is no rSELF, instead on x86 fs: has a base address of Thread::Current, whereas on
     56  * x86-64/x32 gs: holds it.
     57  *
     58  * For floating point we don't support CPUs without SSE2 support (ie newer than PIII):
     59  *  Native: x86  | x86-64 / x32 | ART x86                    | ART x86-64
     60  *  XMM0: caller | caller, arg1 | caller, float return value | caller, arg1, float return value
     61  *  XMM1: caller | caller, arg2 | caller, scratch            | caller, arg2, scratch
     62  *  XMM2: caller | caller, arg3 | caller, scratch            | caller, arg3, scratch
     63  *  XMM3: caller | caller, arg4 | caller, scratch            | caller, arg4, scratch
     64  *  XMM4: caller | caller, arg5 | caller, scratch            | caller, arg5, scratch
     65  *  XMM5: caller | caller, arg6 | caller, scratch            | caller, arg6, scratch
     66  *  XMM6: caller | caller, arg7 | caller, scratch            | caller, arg7, scratch
     67  *  XMM7: caller | caller, arg8 | caller, scratch            | caller, arg8, scratch
     68  *  ---  x86-64/x32 registers
     69  *  XMM8 .. 11: caller save available as scratch registers for ART.
     70  *  XMM12 .. 15: callee save available as promoted registers for ART.
     71  *  This change (XMM12..15) is for QCG only, for others they are caller save.
     72  *
     73  * X87 is a necessary evil outside of ART code for x86:
     74  *  ST0:  x86 float/double native return value, caller save
     75  *  ST1 .. ST7: caller save
     76  *
     77  *  Stack frame diagram (stack grows down, higher addresses at top):
     78  *
     79  * +------------------------+
     80  * | IN[ins-1]              |  {Note: resides in caller's frame}
     81  * |       .                |
     82  * | IN[0]                  |
     83  * | caller's Method*       |
     84  * +========================+  {Note: start of callee's frame}
     85  * | return address         |  {pushed by call}
     86  * | spill region           |  {variable sized}
     87  * +------------------------+
     88  * | ...filler word...      |  {Note: used as 2nd word of V[locals-1] if long]
     89  * +------------------------+
     90  * | V[locals-1]            |
     91  * | V[locals-2]            |
     92  * |      .                 |
     93  * |      .                 |
     94  * | V[1]                   |
     95  * | V[0]                   |
     96  * +------------------------+
     97  * |  0 to 3 words padding  |
     98  * +------------------------+
     99  * | OUT[outs-1]            |
    100  * | OUT[outs-2]            |
    101  * |       .                |
    102  * | OUT[0]                 |
    103  * | cur_method*            | <<== sp w/ 16-byte alignment
    104  * +========================+
    105  */
    106 
    107 enum X86ResourceEncodingPos {
    108   kX86GPReg0   = 0,
    109   kX86RegSP    = 4,
    110   kX86FPReg0   = 16,  // xmm0 .. xmm7/xmm15.
    111   kX86FPRegEnd = 32,
    112   kX86FPStack  = 33,
    113   kX86RegEnd   = kX86FPStack,
    114 };
    115 
    116 // FIXME: for 64-bit, perhaps add an X86_64NativeRegisterPool enum?
    117 enum X86NativeRegisterPool {
    118   r0             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 0,
    119   r0q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 0,
    120   rAX            = r0,
    121   r1             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 1,
    122   r1q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 1,
    123   rCX            = r1,
    124   r2             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 2,
    125   r2q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 2,
    126   rDX            = r2,
    127   r3             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 3,
    128   r3q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 3,
    129   rBX            = r3,
    130   r4sp_32        = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 4,
    131   rX86_SP_32     = r4sp_32,
    132   r4sp_64        = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 4,
    133   rX86_SP_64     = r4sp_64,
    134   r5             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 5,
    135   r5q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 5,
    136   rBP            = r5,
    137   r5sib_no_base  = r5,
    138   r6             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 6,
    139   r6q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 6,
    140   rSI            = r6,
    141   r7             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 7,
    142   r7q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 7,
    143   rDI            = r7,
    144   r8             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 8,
    145   r8q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 8,
    146   r9             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 9,
    147   r9q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 9,
    148   r10            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
    149   r10q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 10,
    150   r11            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
    151   r11q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 11,
    152   r12            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
    153   r12q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 12,
    154   r13            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
    155   r13q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 13,
    156   r14            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
    157   r14q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 14,
    158   r15            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
    159   r15q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 15,
    160   // fake return address register for core spill mask.
    161   rRET           = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
    162 
    163   // xmm registers, single precision view.
    164   fr0  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 0,
    165   fr1  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 1,
    166   fr2  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 2,
    167   fr3  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 3,
    168   fr4  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 4,
    169   fr5  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 5,
    170   fr6  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 6,
    171   fr7  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 7,
    172   fr8  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 8,
    173   fr9  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 9,
    174   fr10 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 10,
    175   fr11 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 11,
    176   fr12 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 12,
    177   fr13 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 13,
    178   fr14 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 14,
    179   fr15 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 15,
    180 
    181   // xmm registers, double precision aliases.
    182   dr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 0,
    183   dr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 1,
    184   dr2  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 2,
    185   dr3  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 3,
    186   dr4  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 4,
    187   dr5  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 5,
    188   dr6  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 6,
    189   dr7  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 7,
    190   dr8  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 8,
    191   dr9  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 9,
    192   dr10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
    193   dr11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 11,
    194   dr12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
    195   dr13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 13,
    196   dr14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
    197   dr15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 15,
    198 
    199   // xmm registers, quad precision aliases
    200   xr0  = RegStorage::k128BitSolo | 0,
    201   xr1  = RegStorage::k128BitSolo | 1,
    202   xr2  = RegStorage::k128BitSolo | 2,
    203   xr3  = RegStorage::k128BitSolo | 3,
    204   xr4  = RegStorage::k128BitSolo | 4,
    205   xr5  = RegStorage::k128BitSolo | 5,
    206   xr6  = RegStorage::k128BitSolo | 6,
    207   xr7  = RegStorage::k128BitSolo | 7,
    208   xr8  = RegStorage::k128BitSolo | 8,
    209   xr9  = RegStorage::k128BitSolo | 9,
    210   xr10 = RegStorage::k128BitSolo | 10,
    211   xr11 = RegStorage::k128BitSolo | 11,
    212   xr12 = RegStorage::k128BitSolo | 12,
    213   xr13 = RegStorage::k128BitSolo | 13,
    214   xr14 = RegStorage::k128BitSolo | 14,
    215   xr15 = RegStorage::k128BitSolo | 15,
    216 
    217   // TODO: as needed, add 256, 512 and 1024-bit xmm views.
    218 };
    219 
    220 constexpr RegStorage rs_r0(RegStorage::kValid | r0);
    221 constexpr RegStorage rs_r0q(RegStorage::kValid | r0q);
    222 constexpr RegStorage rs_rAX = rs_r0;
    223 constexpr RegStorage rs_r1(RegStorage::kValid | r1);
    224 constexpr RegStorage rs_r1q(RegStorage::kValid | r1q);
    225 constexpr RegStorage rs_rCX = rs_r1;
    226 constexpr RegStorage rs_r2(RegStorage::kValid | r2);
    227 constexpr RegStorage rs_r2q(RegStorage::kValid | r2q);
    228 constexpr RegStorage rs_rDX = rs_r2;
    229 constexpr RegStorage rs_r3(RegStorage::kValid | r3);
    230 constexpr RegStorage rs_r3q(RegStorage::kValid | r3q);
    231 constexpr RegStorage rs_rBX = rs_r3;
    232 constexpr RegStorage rs_rX86_SP_64(RegStorage::kValid | r4sp_64);
    233 constexpr RegStorage rs_rX86_SP_32(RegStorage::kValid | r4sp_32);
    234 extern RegStorage rs_rX86_SP;
    235 constexpr RegStorage rs_r5(RegStorage::kValid | r5);
    236 constexpr RegStorage rs_r5q(RegStorage::kValid | r5q);
    237 constexpr RegStorage rs_rBP = rs_r5;
    238 constexpr RegStorage rs_r6(RegStorage::kValid | r6);
    239 constexpr RegStorage rs_r6q(RegStorage::kValid | r6q);
    240 constexpr RegStorage rs_rSI = rs_r6;
    241 constexpr RegStorage rs_r7(RegStorage::kValid | r7);
    242 constexpr RegStorage rs_r7q(RegStorage::kValid | r7q);
    243 constexpr RegStorage rs_rDI = rs_r7;
    244 constexpr RegStorage rs_rRET(RegStorage::kValid | rRET);
    245 constexpr RegStorage rs_r8(RegStorage::kValid | r8);
    246 constexpr RegStorage rs_r8q(RegStorage::kValid | r8q);
    247 constexpr RegStorage rs_r9(RegStorage::kValid | r9);
    248 constexpr RegStorage rs_r9q(RegStorage::kValid | r9q);
    249 constexpr RegStorage rs_r10(RegStorage::kValid | r10);
    250 constexpr RegStorage rs_r10q(RegStorage::kValid | r10q);
    251 constexpr RegStorage rs_r11(RegStorage::kValid | r11);
    252 constexpr RegStorage rs_r11q(RegStorage::kValid | r11q);
    253 constexpr RegStorage rs_r12(RegStorage::kValid | r12);
    254 constexpr RegStorage rs_r12q(RegStorage::kValid | r12q);
    255 constexpr RegStorage rs_r13(RegStorage::kValid | r13);
    256 constexpr RegStorage rs_r13q(RegStorage::kValid | r13q);
    257 constexpr RegStorage rs_r14(RegStorage::kValid | r14);
    258 constexpr RegStorage rs_r14q(RegStorage::kValid | r14q);
    259 constexpr RegStorage rs_r15(RegStorage::kValid | r15);
    260 constexpr RegStorage rs_r15q(RegStorage::kValid | r15q);
    261 
    262 constexpr RegStorage rs_fr0(RegStorage::kValid | fr0);
    263 constexpr RegStorage rs_fr1(RegStorage::kValid | fr1);
    264 constexpr RegStorage rs_fr2(RegStorage::kValid | fr2);
    265 constexpr RegStorage rs_fr3(RegStorage::kValid | fr3);
    266 constexpr RegStorage rs_fr4(RegStorage::kValid | fr4);
    267 constexpr RegStorage rs_fr5(RegStorage::kValid | fr5);
    268 constexpr RegStorage rs_fr6(RegStorage::kValid | fr6);
    269 constexpr RegStorage rs_fr7(RegStorage::kValid | fr7);
    270 constexpr RegStorage rs_fr8(RegStorage::kValid | fr8);
    271 constexpr RegStorage rs_fr9(RegStorage::kValid | fr9);
    272 constexpr RegStorage rs_fr10(RegStorage::kValid | fr10);
    273 constexpr RegStorage rs_fr11(RegStorage::kValid | fr11);
    274 constexpr RegStorage rs_fr12(RegStorage::kValid | fr12);
    275 constexpr RegStorage rs_fr13(RegStorage::kValid | fr13);
    276 constexpr RegStorage rs_fr14(RegStorage::kValid | fr14);
    277 constexpr RegStorage rs_fr15(RegStorage::kValid | fr15);
    278 
    279 constexpr RegStorage rs_dr0(RegStorage::kValid | dr0);
    280 constexpr RegStorage rs_dr1(RegStorage::kValid | dr1);
    281 constexpr RegStorage rs_dr2(RegStorage::kValid | dr2);
    282 constexpr RegStorage rs_dr3(RegStorage::kValid | dr3);
    283 constexpr RegStorage rs_dr4(RegStorage::kValid | dr4);
    284 constexpr RegStorage rs_dr5(RegStorage::kValid | dr5);
    285 constexpr RegStorage rs_dr6(RegStorage::kValid | dr6);
    286 constexpr RegStorage rs_dr7(RegStorage::kValid | dr7);
    287 constexpr RegStorage rs_dr8(RegStorage::kValid | dr8);
    288 constexpr RegStorage rs_dr9(RegStorage::kValid | dr9);
    289 constexpr RegStorage rs_dr10(RegStorage::kValid | dr10);
    290 constexpr RegStorage rs_dr11(RegStorage::kValid | dr11);
    291 constexpr RegStorage rs_dr12(RegStorage::kValid | dr12);
    292 constexpr RegStorage rs_dr13(RegStorage::kValid | dr13);
    293 constexpr RegStorage rs_dr14(RegStorage::kValid | dr14);
    294 constexpr RegStorage rs_dr15(RegStorage::kValid | dr15);
    295 
    296 constexpr RegStorage rs_xr0(RegStorage::kValid | xr0);
    297 constexpr RegStorage rs_xr1(RegStorage::kValid | xr1);
    298 constexpr RegStorage rs_xr2(RegStorage::kValid | xr2);
    299 constexpr RegStorage rs_xr3(RegStorage::kValid | xr3);
    300 constexpr RegStorage rs_xr4(RegStorage::kValid | xr4);
    301 constexpr RegStorage rs_xr5(RegStorage::kValid | xr5);
    302 constexpr RegStorage rs_xr6(RegStorage::kValid | xr6);
    303 constexpr RegStorage rs_xr7(RegStorage::kValid | xr7);
    304 constexpr RegStorage rs_xr8(RegStorage::kValid | xr8);
    305 constexpr RegStorage rs_xr9(RegStorage::kValid | xr9);
    306 constexpr RegStorage rs_xr10(RegStorage::kValid | xr10);
    307 constexpr RegStorage rs_xr11(RegStorage::kValid | xr11);
    308 constexpr RegStorage rs_xr12(RegStorage::kValid | xr12);
    309 constexpr RegStorage rs_xr13(RegStorage::kValid | xr13);
    310 constexpr RegStorage rs_xr14(RegStorage::kValid | xr14);
    311 constexpr RegStorage rs_xr15(RegStorage::kValid | xr15);
    312 
    313 extern X86NativeRegisterPool rX86_ARG0;
    314 extern X86NativeRegisterPool rX86_ARG1;
    315 extern X86NativeRegisterPool rX86_ARG2;
    316 extern X86NativeRegisterPool rX86_ARG3;
    317 extern X86NativeRegisterPool rX86_ARG4;
    318 extern X86NativeRegisterPool rX86_ARG5;
    319 extern X86NativeRegisterPool rX86_FARG0;
    320 extern X86NativeRegisterPool rX86_FARG1;
    321 extern X86NativeRegisterPool rX86_FARG2;
    322 extern X86NativeRegisterPool rX86_FARG3;
    323 extern X86NativeRegisterPool rX86_FARG4;
    324 extern X86NativeRegisterPool rX86_FARG5;
    325 extern X86NativeRegisterPool rX86_FARG6;
    326 extern X86NativeRegisterPool rX86_FARG7;
    327 extern X86NativeRegisterPool rX86_RET0;
    328 extern X86NativeRegisterPool rX86_RET1;
    329 extern X86NativeRegisterPool rX86_INVOKE_TGT;
    330 extern X86NativeRegisterPool rX86_COUNT;
    331 
    332 extern RegStorage rs_rX86_ARG0;
    333 extern RegStorage rs_rX86_ARG1;
    334 extern RegStorage rs_rX86_ARG2;
    335 extern RegStorage rs_rX86_ARG3;
    336 extern RegStorage rs_rX86_ARG4;
    337 extern RegStorage rs_rX86_ARG5;
    338 extern RegStorage rs_rX86_FARG0;
    339 extern RegStorage rs_rX86_FARG1;
    340 extern RegStorage rs_rX86_FARG2;
    341 extern RegStorage rs_rX86_FARG3;
    342 extern RegStorage rs_rX86_FARG4;
    343 extern RegStorage rs_rX86_FARG5;
    344 extern RegStorage rs_rX86_FARG6;
    345 extern RegStorage rs_rX86_FARG7;
    346 extern RegStorage rs_rX86_RET0;
    347 extern RegStorage rs_rX86_RET1;
    348 extern RegStorage rs_rX86_INVOKE_TGT;
    349 extern RegStorage rs_rX86_COUNT;
    350 
    351 // RegisterLocation templates return values (r_V0, or r_V0/r_V1).
    352 const RegLocation x86_loc_c_return
    353     {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
    354      RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
    355 const RegLocation x86_loc_c_return_wide
    356     {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
    357      RegStorage(RegStorage::k64BitPair, rAX, rDX), INVALID_SREG, INVALID_SREG};
    358 const RegLocation x86_loc_c_return_ref
    359     {kLocPhysReg, 0, 0, 0, 0, 0, 1, 0, 1,
    360      RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
    361 const RegLocation x86_64_loc_c_return_ref
    362     {kLocPhysReg, 0, 0, 0, 0, 0, 1, 0, 1,
    363      RegStorage(RegStorage::k64BitSolo, rAX), INVALID_SREG, INVALID_SREG};
    364 const RegLocation x86_64_loc_c_return_wide
    365     {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
    366      RegStorage(RegStorage::k64BitSolo, rAX), INVALID_SREG, INVALID_SREG};
    367 const RegLocation x86_loc_c_return_float
    368     {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
    369      RegStorage(RegStorage::k32BitSolo, fr0), INVALID_SREG, INVALID_SREG};
    370 const RegLocation x86_loc_c_return_double
    371     {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
    372      RegStorage(RegStorage::k64BitSolo, dr0), INVALID_SREG, INVALID_SREG};
    373 
    374 /*
    375  * The following enum defines the list of supported X86 instructions by the
    376  * assembler. Their corresponding EncodingMap positions will be defined in
    377  * Assemble.cc.
    378  */
    379 enum X86OpCode {
    380   kX86First = 0,
    381   kX8632BitData = kX86First,  // data [31..0].
    382   kX86Bkpt,
    383   kX86Nop,
    384   // Define groups of binary operations
    385   // MR - Memory Register  - opcode [base + disp], reg
    386   //             - lir operands - 0: base, 1: disp, 2: reg
    387   // AR - Array Register   - opcode [base + index * scale + disp], reg
    388   //             - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
    389   // TR - Thread Register  - opcode fs:[disp], reg - where fs: is equal to Thread::Current()
    390   //             - lir operands - 0: disp, 1: reg
    391   // RR - Register Register  - opcode reg1, reg2
    392   //             - lir operands - 0: reg1, 1: reg2
    393   // RM - Register Memory  - opcode reg, [base + disp]
    394   //             - lir operands - 0: reg, 1: base, 2: disp
    395   // RA - Register Array   - opcode reg, [base + index * scale + disp]
    396   //             - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
    397   // RT - Register Thread  - opcode reg, fs:[disp] - where fs: is equal to Thread::Current()
    398   //             - lir operands - 0: reg, 1: disp
    399   // RI - Register Immediate - opcode reg, #immediate
    400   //             - lir operands - 0: reg, 1: immediate
    401   // MI - Memory Immediate   - opcode [base + disp], #immediate
    402   //             - lir operands - 0: base, 1: disp, 2: immediate
    403   // AI - Array Immediate  - opcode [base + index * scale + disp], #immediate
    404   //             - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
    405   // TI - Thread Immediate  - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
    406   //             - lir operands - 0: disp, 1: imm
    407 #define BinaryOpCode(opcode) \
    408   opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \
    409   opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \
    410   opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \
    411   opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \
    412   opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \
    413   opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \
    414   opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \
    415   opcode ## 32MR, opcode ## 32AR, opcode ## 32TR,  \
    416   opcode ## 32RR, opcode ## 32RM, opcode ## 32RA, opcode ## 32RT, \
    417   opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \
    418   opcode ## 32RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8, \
    419   opcode ## 64MR, opcode ## 64AR, opcode ## 64TR,  \
    420   opcode ## 64RR, opcode ## 64RM, opcode ## 64RA, opcode ## 64RT, \
    421   opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, opcode ## 64TI, \
    422   opcode ## 64RI8, opcode ## 64MI8, opcode ## 64AI8, opcode ## 64TI8
    423   BinaryOpCode(kX86Add),
    424   BinaryOpCode(kX86Or),
    425   BinaryOpCode(kX86Adc),
    426   BinaryOpCode(kX86Sbb),
    427   BinaryOpCode(kX86And),
    428   BinaryOpCode(kX86Sub),
    429   BinaryOpCode(kX86Xor),
    430   BinaryOpCode(kX86Cmp),
    431 #undef BinaryOpCode
    432   kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI,
    433   kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI,
    434   kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8,
    435   kX86Imul64RRI, kX86Imul64RMI, kX86Imul64RAI,
    436   kX86Imul64RRI8, kX86Imul64RMI8, kX86Imul64RAI8,
    437   kX86Mov8MR, kX86Mov8AR, kX86Mov8TR,
    438   kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT,
    439   kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI,
    440   kX86Mov16MR, kX86Mov16AR, kX86Mov16TR,
    441   kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT,
    442   kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI,
    443   kX86Mov32MR, kX86Mov32AR, kX86Mov32TR,
    444   kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT,
    445   kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI,
    446   kX86Lea32RM,
    447   kX86Lea32RA,
    448   kX86Mov64MR, kX86Mov64AR, kX86Mov64TR,
    449   kX86Mov64RR, kX86Mov64RM, kX86Mov64RA, kX86Mov64RT,
    450   kX86Mov64RI32, kX86Mov64RI64, kX86Mov64MI, kX86Mov64AI, kX86Mov64TI,
    451   kX86Lea64RM,
    452   kX86Lea64RA,
    453   // RRC - Register Register ConditionCode - cond_opcode reg1, reg2
    454   //             - lir operands - 0: reg1, 1: reg2, 2: CC
    455   kX86Cmov32RRC,
    456   kX86Cmov64RRC,
    457   // RMC - Register Memory ConditionCode - cond_opcode reg1, [base + disp]
    458   //             - lir operands - 0: reg1, 1: base, 2: disp 3: CC
    459   kX86Cmov32RMC,
    460   kX86Cmov64RMC,
    461 
    462   // RC - Register CL - opcode reg, CL
    463   //          - lir operands - 0: reg, 1: CL
    464   // MC - Memory CL   - opcode [base + disp], CL
    465   //          - lir operands - 0: base, 1: disp, 2: CL
    466   // AC - Array CL  - opcode [base + index * scale + disp], CL
    467   //          - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL
    468 #define BinaryShiftOpCode(opcode) \
    469   opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \
    470   opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \
    471   opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \
    472   opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \
    473   opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \
    474   opcode ## 32RC, opcode ## 32MC, opcode ## 32AC, \
    475   opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, \
    476   opcode ## 64RC, opcode ## 64MC, opcode ## 64AC
    477   BinaryShiftOpCode(kX86Rol),
    478   BinaryShiftOpCode(kX86Ror),
    479   BinaryShiftOpCode(kX86Rcl),
    480   BinaryShiftOpCode(kX86Rcr),
    481   BinaryShiftOpCode(kX86Sal),
    482   BinaryShiftOpCode(kX86Shr),
    483   BinaryShiftOpCode(kX86Sar),
    484 #undef BinaryShiftOpcode
    485   kX86Cmc,
    486   kX86Shld32RRI,
    487   kX86Shld32MRI,
    488   kX86Shrd32RRI,
    489   kX86Shrd32MRI,
    490   kX86Shld64RRI,
    491   kX86Shld64MRI,
    492   kX86Shrd64RRI,
    493   kX86Shrd64MRI,
    494 #define UnaryOpcode(opcode, reg, mem, array) \
    495   opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
    496   opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
    497   opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array, \
    498   opcode ## 64 ## reg, opcode ## 64 ## mem, opcode ## 64 ## array
    499   UnaryOpcode(kX86Test, RI, MI, AI),
    500   kX86Test32RR,
    501   kX86Test64RR,
    502   kX86Test32RM,
    503   UnaryOpcode(kX86Not, R, M, A),
    504   UnaryOpcode(kX86Neg, R, M, A),
    505   UnaryOpcode(kX86Mul,  DaR, DaM, DaA),
    506   UnaryOpcode(kX86Imul, DaR, DaM, DaA),
    507   UnaryOpcode(kX86Divmod,  DaR, DaM, DaA),
    508   UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
    509   kx86Cdq32Da,
    510   kx86Cqo64Da,
    511   kX86Bswap32R,
    512   kX86Bswap64R,
    513   kX86Push32R, kX86Pop32R,
    514 #undef UnaryOpcode
    515 #define Binary0fOpCode(opcode) \
    516   opcode ## RR, opcode ## RM, opcode ## RA
    517   Binary0fOpCode(kX86Movsd),
    518   kX86MovsdMR,
    519   kX86MovsdAR,
    520   Binary0fOpCode(kX86Movss),
    521   kX86MovssMR,
    522   kX86MovssAR,
    523   Binary0fOpCode(kX86Cvtsi2sd),  // int to double
    524   Binary0fOpCode(kX86Cvtsi2ss),  // int to float
    525   Binary0fOpCode(kX86Cvtsqi2sd),  // long to double
    526   Binary0fOpCode(kX86Cvtsqi2ss),  // long to float
    527   Binary0fOpCode(kX86Cvttsd2si),  // truncating double to int
    528   Binary0fOpCode(kX86Cvttss2si),  // truncating float to int
    529   Binary0fOpCode(kX86Cvttsd2sqi),  // truncating double to long
    530   Binary0fOpCode(kX86Cvttss2sqi),  // truncating float to long
    531   Binary0fOpCode(kX86Cvtsd2si),  // rounding double to int
    532   Binary0fOpCode(kX86Cvtss2si),  // rounding float to int
    533   Binary0fOpCode(kX86Ucomisd),  // unordered double compare
    534   Binary0fOpCode(kX86Ucomiss),  // unordered float compare
    535   Binary0fOpCode(kX86Comisd),   // double compare
    536   Binary0fOpCode(kX86Comiss),   // float compare
    537   Binary0fOpCode(kX86Orpd),     // double logical OR
    538   Binary0fOpCode(kX86Orps),     // float logical OR
    539   Binary0fOpCode(kX86Andpd),    // double logical AND
    540   Binary0fOpCode(kX86Andps),    // float logical AND
    541   Binary0fOpCode(kX86Xorpd),    // double logical XOR
    542   Binary0fOpCode(kX86Xorps),    // float logical XOR
    543   Binary0fOpCode(kX86Addsd),    // double ADD
    544   Binary0fOpCode(kX86Addss),    // float ADD
    545   Binary0fOpCode(kX86Mulsd),    // double multiply
    546   Binary0fOpCode(kX86Mulss),    // float multiply
    547   Binary0fOpCode(kX86Cvtsd2ss),  // double to float
    548   Binary0fOpCode(kX86Cvtss2sd),  // float to double
    549   Binary0fOpCode(kX86Subsd),    // double subtract
    550   Binary0fOpCode(kX86Subss),    // float subtract
    551   Binary0fOpCode(kX86Divsd),    // double divide
    552   Binary0fOpCode(kX86Divss),    // float divide
    553   Binary0fOpCode(kX86Punpckldq),  // Interleave low-order double words
    554   Binary0fOpCode(kX86Sqrtsd),   // square root
    555   Binary0fOpCode(kX86Pmulld),   // parallel integer multiply 32 bits x 4
    556   Binary0fOpCode(kX86Pmullw),   // parallel integer multiply 16 bits x 8
    557   Binary0fOpCode(kX86Mulps),    // parallel FP multiply 32 bits x 4
    558   Binary0fOpCode(kX86Mulpd),    // parallel FP multiply 64 bits x 2
    559   Binary0fOpCode(kX86Paddb),    // parallel integer addition 8 bits x 16
    560   Binary0fOpCode(kX86Paddw),    // parallel integer addition 16 bits x 8
    561   Binary0fOpCode(kX86Paddd),    // parallel integer addition 32 bits x 4
    562   Binary0fOpCode(kX86Addps),    // parallel FP addition 32 bits x 4
    563   Binary0fOpCode(kX86Addpd),    // parallel FP addition 64 bits x 2
    564   Binary0fOpCode(kX86Psubb),    // parallel integer subtraction 8 bits x 16
    565   Binary0fOpCode(kX86Psubw),    // parallel integer subtraction 16 bits x 8
    566   Binary0fOpCode(kX86Psubd),    // parallel integer subtraction 32 bits x 4
    567   Binary0fOpCode(kX86Subps),    // parallel FP subtraction 32 bits x 4
    568   Binary0fOpCode(kX86Subpd),    // parallel FP subtraction 64 bits x 2
    569   Binary0fOpCode(kX86Pand),     // parallel AND 128 bits x 1
    570   Binary0fOpCode(kX86Por),      // parallel OR 128 bits x 1
    571   Binary0fOpCode(kX86Pxor),     // parallel XOR 128 bits x 1
    572   Binary0fOpCode(kX86Phaddw),   // parallel horizontal addition 16 bits x 8
    573   Binary0fOpCode(kX86Phaddd),   // parallel horizontal addition 32 bits x 4
    574   Binary0fOpCode(kX86Haddpd),   // parallel FP horizontal addition 64 bits x 2
    575   Binary0fOpCode(kX86Haddps),   // parallel FP horizontal addition 32 bits x 4
    576   kX86PextrbRRI,                // Extract 8 bits from XMM into GPR
    577   kX86PextrwRRI,                // Extract 16 bits from XMM into GPR
    578   kX86PextrdRRI,                // Extract 32 bits from XMM into GPR
    579   kX86PextrbMRI,                // Extract 8 bits from XMM into memory
    580   kX86PextrwMRI,                // Extract 16 bits from XMM into memory
    581   kX86PextrdMRI,                // Extract 32 bits from XMM into memory
    582   kX86PshuflwRRI,               // Shuffle 16 bits in lower 64 bits of XMM.
    583   kX86PshufdRRI,                // Shuffle 32 bits in XMM.
    584   kX86ShufpsRRI,                // FP Shuffle 32 bits in XMM.
    585   kX86ShufpdRRI,                // FP Shuffle 64 bits in XMM.
    586   kX86PsrawRI,                  // signed right shift of floating point registers 16 bits x 8
    587   kX86PsradRI,                  // signed right shift of floating point registers 32 bits x 4
    588   kX86PsrlwRI,                  // logical right shift of floating point registers 16 bits x 8
    589   kX86PsrldRI,                  // logical right shift of floating point registers 32 bits x 4
    590   kX86PsrlqRI,                  // logical right shift of floating point registers 64 bits x 2
    591   kX86PsllwRI,                  // left shift of floating point registers 16 bits x 8
    592   kX86PslldRI,                  // left shift of floating point registers 32 bits x 4
    593   kX86PsllqRI,                  // left shift of floating point registers 64 bits x 2
    594   kX86Fild32M,                  // push 32-bit integer on x87 stack
    595   kX86Fild64M,                  // push 64-bit integer on x87 stack
    596   kX86Fld32M,                   // push float on x87 stack
    597   kX86Fld64M,                   // push double on x87 stack
    598   kX86Fstp32M,                  // pop top x87 fp stack and do 32-bit store
    599   kX86Fstp64M,                  // pop top x87 fp stack and do 64-bit store
    600   kX86Fst32M,                   // do 32-bit store
    601   kX86Fst64M,                   // do 64-bit store
    602   kX86Fprem,                    // remainder from dividing of two floating point values
    603   kX86Fucompp,                  // compare floating point values and pop x87 fp stack twice
    604   kX86Fstsw16R,                 // store FPU status word
    605   Binary0fOpCode(kX86Mova128),  // move 128 bits aligned
    606   kX86Mova128MR, kX86Mova128AR,  // store 128 bit aligned from xmm1 to m128
    607   Binary0fOpCode(kX86Movups),   // load unaligned packed single FP values from xmm2/m128 to xmm1
    608   kX86MovupsMR, kX86MovupsAR,   // store unaligned packed single FP values from xmm1 to m128
    609   Binary0fOpCode(kX86Movaps),   // load aligned packed single FP values from xmm2/m128 to xmm1
    610   kX86MovapsMR, kX86MovapsAR,   // store aligned packed single FP values from xmm1 to m128
    611   kX86MovlpsRM, kX86MovlpsRA,   // load packed single FP values from m64 to low quadword of xmm
    612   kX86MovlpsMR, kX86MovlpsAR,   // store packed single FP values from low quadword of xmm to m64
    613   kX86MovhpsRM, kX86MovhpsRA,   // load packed single FP values from m64 to high quadword of xmm
    614   kX86MovhpsMR, kX86MovhpsAR,   // store packed single FP values from high quadword of xmm to m64
    615   Binary0fOpCode(kX86Movdxr),   // move into xmm from gpr
    616   Binary0fOpCode(kX86Movqxr),   // move into xmm from 64 bit gpr
    617   kX86MovqrxRR, kX86MovqrxMR, kX86MovqrxAR,  // move into 64 bit reg from xmm
    618   kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR,  // move into reg from xmm
    619   kX86MovsxdRR, kX86MovsxdRM, kX86MovsxdRA,  // move 32 bit to 64 bit with sign extension
    620   kX86Set8R, kX86Set8M, kX86Set8A,  // set byte depending on condition operand
    621   kX86Mfence,                   // memory barrier
    622   Binary0fOpCode(kX86Imul16),   // 16bit multiply
    623   Binary0fOpCode(kX86Imul32),   // 32bit multiply
    624   Binary0fOpCode(kX86Imul64),   // 64bit multiply
    625   kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR,  // compare and exchange
    626   kX86LockCmpxchgMR, kX86LockCmpxchgAR, kX86LockCmpxchg64AR,  // locked compare and exchange
    627   kX86LockCmpxchg64M, kX86LockCmpxchg64A,  // locked compare and exchange
    628   kX86XchgMR,  // exchange memory with register (automatically locked)
    629   Binary0fOpCode(kX86Movzx8),   // zero-extend 8-bit value
    630   Binary0fOpCode(kX86Movzx16),  // zero-extend 16-bit value
    631   Binary0fOpCode(kX86Movsx8),   // sign-extend 8-bit value
    632   Binary0fOpCode(kX86Movsx16),  // sign-extend 16-bit value
    633   Binary0fOpCode(kX86Movzx8q),   // zero-extend 8-bit value to quad word
    634   Binary0fOpCode(kX86Movzx16q),  // zero-extend 16-bit value to quad word
    635   Binary0fOpCode(kX86Movsx8q),   // sign-extend 8-bit value to quad word
    636   Binary0fOpCode(kX86Movsx16q),  // sign-extend 16-bit value to quad word
    637 #undef Binary0fOpCode
    638   kX86Jcc8, kX86Jcc32,  // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
    639   kX86Jmp8, kX86Jmp32,  // jmp rel8/32; lir operands - 0: rel, target assigned
    640   kX86JmpR,             // jmp reg; lir operands - 0: reg
    641   kX86Jecxz8,           // jcexz rel8; jump relative if ECX is zero.
    642   kX86JmpT,             // jmp fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
    643 
    644   kX86CallR,            // call reg; lir operands - 0: reg
    645   kX86CallM,            // call [base + disp]; lir operands - 0: base, 1: disp
    646   kX86CallA,            // call [base + index * scale + disp]
    647                         // lir operands - 0: base, 1: index, 2: scale, 3: disp
    648   kX86CallT,            // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
    649   kX86CallI,            // call <relative> - 0: disp; Used for core.oat linking only
    650   kX86Ret,              // ret; no lir operands
    651   kX86StartOfMethod,    // call 0; pop reg; sub reg, # - generate start of method into reg
    652                         // lir operands - 0: reg
    653   kX86PcRelLoadRA,      // mov reg, [base + index * scale + PC relative displacement]
    654                         // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table
    655   kX86PcRelAdr,         // mov reg, PC relative displacement; lir operands - 0: reg, 1: table
    656   kX86RepneScasw,       // repne scasw
    657   kX86Last
    658 };
    659 
    660 /* Instruction assembly field_loc kind */
    661 enum X86EncodingKind {
    662   kData,                                    // Special case for raw data.
    663   kNop,                                     // Special case for variable length nop.
    664   kNullary,                                 // Opcode that takes no arguments.
    665   kRegOpcode,                               // Shorter form of R instruction kind (opcode+rd)
    666   kReg, kMem, kArray,                       // R, M and A instruction kinds.
    667   kMemReg, kArrayReg, kThreadReg,           // MR, AR and TR instruction kinds.
    668   kRegReg, kRegMem, kRegArray, kRegThread,  // RR, RM, RA and RT instruction kinds.
    669   kRegRegStore,                             // RR following the store modrm reg-reg encoding rather than the load.
    670   kRegImm, kMemImm, kArrayImm, kThreadImm,  // RI, MI, AI and TI instruction kinds.
    671   kRegRegImm, kRegMemImm, kRegArrayImm,     // RRI, RMI and RAI instruction kinds.
    672   kMovRegImm,                               // Shorter form move RI.
    673   kMovRegQuadImm,                           // 64 bit move RI
    674   kRegRegImmStore,                          // RRI following the store modrm reg-reg encoding rather than the load.
    675   kMemRegImm,                               // MRI instruction kinds.
    676   kShiftRegImm, kShiftMemImm, kShiftArrayImm,  // Shift opcode with immediate.
    677   kShiftRegCl, kShiftMemCl, kShiftArrayCl,     // Shift opcode with register CL.
    678   // kRegRegReg, kRegRegMem, kRegRegArray,    // RRR, RRM, RRA instruction kinds.
    679   kRegCond, kMemCond, kArrayCond,          // R, M, A instruction kinds following by a condition.
    680   kRegRegCond,                             // RR instruction kind followed by a condition.
    681   kRegMemCond,                             // RM instruction kind followed by a condition.
    682   kJmp, kJcc, kCall,                       // Branch instruction kinds.
    683   kPcRel,                                  // Operation with displacement that is PC relative
    684   kMacro,                                  // An instruction composing multiple others
    685   kUnimplemented                           // Encoding used when an instruction isn't yet implemented.
    686 };
    687 
    688 /* Struct used to define the EncodingMap positions for each X86 opcode */
    689 struct X86EncodingMap {
    690   X86OpCode opcode;      // e.g. kOpAddRI
    691   // The broad category the instruction conforms to, such as kRegReg. Identifies which LIR operands
    692   // hold meaning for the opcode.
    693   X86EncodingKind kind;
    694   uint64_t flags;
    695   struct {
    696   uint8_t prefix1;       // Non-zero => a prefix byte.
    697   uint8_t prefix2;       // Non-zero => a second prefix byte.
    698   uint8_t opcode;        // 1 byte opcode.
    699   uint8_t extra_opcode1;  // Possible extra opcode byte.
    700   uint8_t extra_opcode2;  // Possible second extra opcode byte.
    701   // 3-bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
    702   // encoding kind.
    703   uint8_t modrm_opcode;
    704   uint8_t ax_opcode;  // Non-zero => shorter encoding for AX as a destination.
    705   uint8_t immediate_bytes;  // Number of bytes of immediate.
    706   // Does the instruction address a byte register? In 32-bit mode the registers ah, bh, ch and dh
    707   // are not used. In 64-bit mode the REX prefix is used to normalize and allow any byte register
    708   // to be addressed.
    709   bool r8_form;
    710   } skeleton;
    711   const char *name;
    712   const char* fmt;
    713 };
    714 
    715 
    716 // FIXME: mem barrier type - what do we do for x86?
    717 #define kSY 0
    718 #define kST 0
    719 
    720 // Offsets of high and low halves of a 64bit value.
    721 #define LOWORD_OFFSET 0
    722 #define HIWORD_OFFSET 4
    723 
    724 // Segment override instruction prefix used for quick TLS access to Thread::Current().
    725 #define THREAD_PREFIX 0x64
    726 #define THREAD_PREFIX_GS 0x65
    727 
    728 // 64 Bit Operand Size
    729 #define REX_W 0x48
    730 // Extension of the ModR/M reg field
    731 #define REX_R 0x44
    732 // Extension of the SIB index field
    733 #define REX_X 0x42
    734 // Extension of the ModR/M r/m field, SIB base field, or Opcode reg field
    735 #define REX_B 0x41
    736 // An empty REX prefix used to normalize the byte operations so that they apply to R4 through R15
    737 #define REX 0x40
    738 // Mask extracting the least 3 bits of r0..r15
    739 #define kRegNumMask32 0x07
    740 // Value indicating that base or reg is not used
    741 #define NO_REG 0
    742 
    743 #define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
    744 #define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
    745 #define IS_SIMM32(v) ((INT64_C(-2147483648) <= (v)) && ((v) <= INT64_C(2147483647)))
    746 
    747 extern X86EncodingMap EncodingMap[kX86Last];
    748 extern X86ConditionCode X86ConditionEncoding(ConditionCode cond);
    749 
    750 }  // namespace art
    751 
    752 #endif  // ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_
    753