x86_lir.h revision 2c1ed456dcdb027d097825dd98dbe48c71599b6c
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 22namespace 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 .. 15: caller save available as scratch registers for ART. 70 * 71 * X87 is a necessary evil outside of ART code for x86: 72 * ST0: x86 float/double native return value, caller save 73 * ST1 .. ST7: caller save 74 * 75 * Stack frame diagram (stack grows down, higher addresses at top): 76 * 77 * +------------------------+ 78 * | IN[ins-1] | {Note: resides in caller's frame} 79 * | . | 80 * | IN[0] | 81 * | caller's Method* | 82 * +========================+ {Note: start of callee's frame} 83 * | return address | {pushed by call} 84 * | spill region | {variable sized} 85 * +------------------------+ 86 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long] 87 * +------------------------+ 88 * | V[locals-1] | 89 * | V[locals-2] | 90 * | . | 91 * | . | 92 * | V[1] | 93 * | V[0] | 94 * +------------------------+ 95 * | 0 to 3 words padding | 96 * +------------------------+ 97 * | OUT[outs-1] | 98 * | OUT[outs-2] | 99 * | . | 100 * | OUT[0] | 101 * | cur_method* | <<== sp w/ 16-byte alignment 102 * +========================+ 103 */ 104 105// Offset to distingish FP regs. 106#define X86_FP_REG_OFFSET 32 107// Offset to distinguish DP FP regs. 108#define X86_FP_DOUBLE (X86_FP_REG_OFFSET + 16) 109// Offset to distingish the extra regs. 110#define X86_EXTRA_REG_OFFSET (X86_FP_DOUBLE + 16) 111// Reg types. 112#define X86_REGTYPE(x) (x & (X86_FP_REG_OFFSET | X86_FP_DOUBLE)) 113#define X86_FPREG(x) ((x & X86_FP_REG_OFFSET) == X86_FP_REG_OFFSET) 114#define X86_EXTRAREG(x) ((x & X86_EXTRA_REG_OFFSET) == X86_EXTRA_REG_OFFSET) 115#define X86_DOUBLEREG(x) ((x & X86_FP_DOUBLE) == X86_FP_DOUBLE) 116#define X86_SINGLEREG(x) (X86_FPREG(x) && !X86_DOUBLEREG(x)) 117 118/* 119 * Note: the low register of a floating point pair is sufficient to 120 * create the name of a double, but require both names to be passed to 121 * allow for asserts to verify that the pair is consecutive if significant 122 * rework is done in this area. Also, it is a good reminder in the calling 123 * code that reg locations always describe doubles as a pair of singles. 124 */ 125#define X86_S2D(x, y) ((x) | X86_FP_DOUBLE) 126/* Mask to strip off fp flags */ 127#define X86_FP_REG_MASK 0xF 128 129enum X86ResourceEncodingPos { 130 kX86GPReg0 = 0, 131 kX86RegSP = 4, 132 kX86FPReg0 = 16, // xmm0 .. xmm7/xmm15. 133 kX86FPRegEnd = 32, 134 kX86RegEnd = kX86FPRegEnd, 135}; 136 137#define ENCODE_X86_REG_LIST(N) (static_cast<uint64_t>(N)) 138#define ENCODE_X86_REG_SP (1ULL << kX86RegSP) 139 140enum X86NativeRegisterPool { 141 r0 = 0, 142 rAX = r0, 143 r1 = 1, 144 rCX = r1, 145 r2 = 2, 146 rDX = r2, 147 r3 = 3, 148 rBX = r3, 149 r4sp = 4, 150 rX86_SP = r4sp, 151 r4sib_no_index = r4sp, 152 r5 = 5, 153 rBP = r5, 154 r5sib_no_base = r5, 155 r6 = 6, 156 rSI = r6, 157 r7 = 7, 158 rDI = r7, 159#ifndef TARGET_REX_SUPPORT 160 rRET = 8, // fake return address register for core spill mask. 161#else 162 r8 = 8, 163 r9 = 9, 164 r10 = 10, 165 r11 = 11, 166 r12 = 12, 167 r13 = 13, 168 r14 = 14, 169 r15 = 15, 170 rRET = 16, // fake return address register for core spill mask. 171#endif 172 fr0 = 0 + X86_FP_REG_OFFSET, 173 fr1 = 1 + X86_FP_REG_OFFSET, 174 fr2 = 2 + X86_FP_REG_OFFSET, 175 fr3 = 3 + X86_FP_REG_OFFSET, 176 fr4 = 4 + X86_FP_REG_OFFSET, 177 fr5 = 5 + X86_FP_REG_OFFSET, 178 fr6 = 6 + X86_FP_REG_OFFSET, 179 fr7 = 7 + X86_FP_REG_OFFSET, 180 fr8 = 8 + X86_FP_REG_OFFSET, 181 fr9 = 9 + X86_FP_REG_OFFSET, 182 fr10 = 10 + X86_FP_REG_OFFSET, 183 fr11 = 11 + X86_FP_REG_OFFSET, 184 fr12 = 12 + X86_FP_REG_OFFSET, 185 fr13 = 13 + X86_FP_REG_OFFSET, 186 fr14 = 14 + X86_FP_REG_OFFSET, 187 fr15 = 15 + X86_FP_REG_OFFSET, 188}; 189 190#define rX86_ARG0 rAX 191#define rX86_ARG1 rCX 192#define rX86_ARG2 rDX 193#define rX86_ARG3 rBX 194#define rX86_FARG0 rAX 195#define rX86_FARG1 rCX 196#define rX86_FARG2 rDX 197#define rX86_FARG3 rBX 198#define rX86_RET0 rAX 199#define rX86_RET1 rDX 200#define rX86_INVOKE_TGT rAX 201#define rX86_LR INVALID_REG 202#define rX86_SUSPEND INVALID_REG 203#define rX86_SELF INVALID_REG 204#define rX86_COUNT rCX 205#define rX86_PC INVALID_REG 206 207// RegisterLocation templates return values (r_V0, or r_V0/r_V1). 208const RegLocation x86_loc_c_return 209 {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, 210 RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG}; 211const RegLocation x86_loc_c_return_wide 212 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, kVectorNotUsed, 213 RegStorage(RegStorage::k64BitPair, rAX, rDX), INVALID_SREG, INVALID_SREG}; 214// TODO: update to use k32BitVector (must encode in 7 bits, including fp flag). 215const RegLocation x86_loc_c_return_float 216 {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, kVectorLength4, 217 RegStorage(RegStorage::k32BitSolo, fr0), INVALID_SREG, INVALID_SREG}; 218// TODO: update to use k64BitVector (must encode in 7 bits, including fp flag). 219const RegLocation x86_loc_c_return_double 220 {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, kVectorLength8, 221 RegStorage(RegStorage::k64BitPair, fr0, fr1), INVALID_SREG, INVALID_SREG}; 222 223/* 224 * The following enum defines the list of supported X86 instructions by the 225 * assembler. Their corresponding EncodingMap positions will be defined in 226 * Assemble.cc. 227 */ 228enum X86OpCode { 229 kX86First = 0, 230 kX8632BitData = kX86First, // data [31..0]. 231 kX86Bkpt, 232 kX86Nop, 233 // Define groups of binary operations 234 // MR - Memory Register - opcode [base + disp], reg 235 // - lir operands - 0: base, 1: disp, 2: reg 236 // AR - Array Register - opcode [base + index * scale + disp], reg 237 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg 238 // TR - Thread Register - opcode fs:[disp], reg - where fs: is equal to Thread::Current() 239 // - lir operands - 0: disp, 1: reg 240 // RR - Register Register - opcode reg1, reg2 241 // - lir operands - 0: reg1, 1: reg2 242 // RM - Register Memory - opcode reg, [base + disp] 243 // - lir operands - 0: reg, 1: base, 2: disp 244 // RA - Register Array - opcode reg, [base + index * scale + disp] 245 // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp 246 // RT - Register Thread - opcode reg, fs:[disp] - where fs: is equal to Thread::Current() 247 // - lir operands - 0: reg, 1: disp 248 // RI - Register Immediate - opcode reg, #immediate 249 // - lir operands - 0: reg, 1: immediate 250 // MI - Memory Immediate - opcode [base + disp], #immediate 251 // - lir operands - 0: base, 1: disp, 2: immediate 252 // AI - Array Immediate - opcode [base + index * scale + disp], #immediate 253 // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate 254 // TI - Thread Immediate - opcode fs:[disp], imm - where fs: is equal to Thread::Current() 255 // - lir operands - 0: disp, 1: imm 256#define BinaryOpCode(opcode) \ 257 opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \ 258 opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \ 259 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \ 260 opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \ 261 opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \ 262 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \ 263 opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \ 264 opcode ## 32MR, opcode ## 32AR, opcode ## 32TR, \ 265 opcode ## 32RR, opcode ## 32RM, opcode ## 32RA, opcode ## 32RT, \ 266 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \ 267 opcode ## 32RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8 268 BinaryOpCode(kX86Add), 269 BinaryOpCode(kX86Or), 270 BinaryOpCode(kX86Adc), 271 BinaryOpCode(kX86Sbb), 272 BinaryOpCode(kX86And), 273 BinaryOpCode(kX86Sub), 274 BinaryOpCode(kX86Xor), 275 BinaryOpCode(kX86Cmp), 276#undef BinaryOpCode 277 kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI, 278 kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI, 279 kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8, 280 kX86Mov8MR, kX86Mov8AR, kX86Mov8TR, 281 kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT, 282 kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI, 283 kX86Mov16MR, kX86Mov16AR, kX86Mov16TR, 284 kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT, 285 kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI, 286 kX86Mov32MR, kX86Mov32AR, kX86Mov32TR, 287 kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT, 288 kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI, 289 kX86Lea32RM, 290 kX86Lea32RA, 291 // RRC - Register Register ConditionCode - cond_opcode reg1, reg2 292 // - lir operands - 0: reg1, 1: reg2, 2: CC 293 kX86Cmov32RRC, 294 // RC - Register CL - opcode reg, CL 295 // - lir operands - 0: reg, 1: CL 296 // MC - Memory CL - opcode [base + disp], CL 297 // - lir operands - 0: base, 1: disp, 2: CL 298 // AC - Array CL - opcode [base + index * scale + disp], CL 299 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL 300#define BinaryShiftOpCode(opcode) \ 301 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \ 302 opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \ 303 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \ 304 opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \ 305 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \ 306 opcode ## 32RC, opcode ## 32MC, opcode ## 32AC 307 BinaryShiftOpCode(kX86Rol), 308 BinaryShiftOpCode(kX86Ror), 309 BinaryShiftOpCode(kX86Rcl), 310 BinaryShiftOpCode(kX86Rcr), 311 BinaryShiftOpCode(kX86Sal), 312 BinaryShiftOpCode(kX86Shr), 313 BinaryShiftOpCode(kX86Sar), 314#undef BinaryShiftOpcode 315 kX86Cmc, 316 kX86Shld32RRI, 317 kX86Shrd32RRI, 318#define UnaryOpcode(opcode, reg, mem, array) \ 319 opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \ 320 opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \ 321 opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array 322 UnaryOpcode(kX86Test, RI, MI, AI), 323 kX86Test32RR, 324 UnaryOpcode(kX86Not, R, M, A), 325 UnaryOpcode(kX86Neg, R, M, A), 326 UnaryOpcode(kX86Mul, DaR, DaM, DaA), 327 UnaryOpcode(kX86Imul, DaR, DaM, DaA), 328 UnaryOpcode(kX86Divmod, DaR, DaM, DaA), 329 UnaryOpcode(kX86Idivmod, DaR, DaM, DaA), 330 kx86Cdq32Da, 331 kX86Bswap32R, 332 kX86Push32R, kX86Pop32R, 333#undef UnaryOpcode 334#define Binary0fOpCode(opcode) \ 335 opcode ## RR, opcode ## RM, opcode ## RA 336 Binary0fOpCode(kX86Movsd), 337 kX86MovsdMR, 338 kX86MovsdAR, 339 Binary0fOpCode(kX86Movss), 340 kX86MovssMR, 341 kX86MovssAR, 342 Binary0fOpCode(kX86Cvtsi2sd), // int to double 343 Binary0fOpCode(kX86Cvtsi2ss), // int to float 344 Binary0fOpCode(kX86Cvttsd2si), // truncating double to int 345 Binary0fOpCode(kX86Cvttss2si), // truncating float to int 346 Binary0fOpCode(kX86Cvtsd2si), // rounding double to int 347 Binary0fOpCode(kX86Cvtss2si), // rounding float to int 348 Binary0fOpCode(kX86Ucomisd), // unordered double compare 349 Binary0fOpCode(kX86Ucomiss), // unordered float compare 350 Binary0fOpCode(kX86Comisd), // double compare 351 Binary0fOpCode(kX86Comiss), // float compare 352 Binary0fOpCode(kX86Orps), // or of floating point registers 353 Binary0fOpCode(kX86Xorps), // xor of floating point registers 354 Binary0fOpCode(kX86Addsd), // double add 355 Binary0fOpCode(kX86Addss), // float add 356 Binary0fOpCode(kX86Mulsd), // double multiply 357 Binary0fOpCode(kX86Mulss), // float multiply 358 Binary0fOpCode(kX86Cvtsd2ss), // double to float 359 Binary0fOpCode(kX86Cvtss2sd), // float to double 360 Binary0fOpCode(kX86Subsd), // double subtract 361 Binary0fOpCode(kX86Subss), // float subtract 362 Binary0fOpCode(kX86Divsd), // double divide 363 Binary0fOpCode(kX86Divss), // float divide 364 Binary0fOpCode(kX86Punpckldq), // Interleave low-order double words 365 kX86PsrlqRI, // right shift of floating point registers 366 kX86PsllqRI, // left shift of floating point registers 367 kX86SqrtsdRR, // sqrt of floating point register 368 kX86Fild32M, // push 32-bit integer on x87 stack 369 kX86Fild64M, // push 64-bit integer on x87 stack 370 kX86Fstp32M, // pop top x87 fp stack and do 32-bit store 371 kX86Fstp64M, // pop top x87 fp stack and do 64-bit store 372 Binary0fOpCode(kX86Movups), // load unaligned packed single FP values from xmm2/m128 to xmm1 373 kX86MovupsMR, kX86MovupsAR, // store unaligned packed single FP values from xmm1 to m128 374 Binary0fOpCode(kX86Movaps), // load aligned packed single FP values from xmm2/m128 to xmm1 375 kX86MovapsMR, kX86MovapsAR, // store aligned packed single FP values from xmm1 to m128 376 kX86MovlpsRM, kX86MovlpsRA, // load packed single FP values from m64 to low quadword of xmm 377 kX86MovlpsMR, kX86MovlpsAR, // store packed single FP values from low quadword of xmm to m64 378 kX86MovhpsRM, kX86MovhpsRA, // load packed single FP values from m64 to high quadword of xmm 379 kX86MovhpsMR, kX86MovhpsAR, // store packed single FP values from high quadword of xmm to m64 380 Binary0fOpCode(kX86Movdxr), // move into xmm from gpr 381 kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR, // move into reg from xmm 382 kX86Set8R, kX86Set8M, kX86Set8A, // set byte depending on condition operand 383 kX86Mfence, // memory barrier 384 Binary0fOpCode(kX86Imul16), // 16bit multiply 385 Binary0fOpCode(kX86Imul32), // 32bit multiply 386 kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR, // compare and exchange 387 kX86LockCmpxchgMR, kX86LockCmpxchgAR, // locked compare and exchange 388 kX86LockCmpxchg8bM, kX86LockCmpxchg8bA, // locked compare and exchange 389 Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value 390 Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value 391 Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value 392 Binary0fOpCode(kX86Movsx16), // sign-extend 16-bit value 393#undef Binary0fOpCode 394 kX86Jcc8, kX86Jcc32, // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned 395 kX86Jmp8, kX86Jmp32, // jmp rel8/32; lir operands - 0: rel, target assigned 396 kX86JmpR, // jmp reg; lir operands - 0: reg 397 kX86Jecxz8, // jcexz rel8; jump relative if ECX is zero. 398 kX86CallR, // call reg; lir operands - 0: reg 399 kX86CallM, // call [base + disp]; lir operands - 0: base, 1: disp 400 kX86CallA, // call [base + index * scale + disp] 401 // lir operands - 0: base, 1: index, 2: scale, 3: disp 402 kX86CallT, // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp 403 kX86CallI, // call <relative> - 0: disp; Used for core.oat linking only 404 kX86Ret, // ret; no lir operands 405 kX86StartOfMethod, // call 0; pop reg; sub reg, # - generate start of method into reg 406 // lir operands - 0: reg 407 kX86PcRelLoadRA, // mov reg, [base + index * scale + PC relative displacement] 408 // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table 409 kX86PcRelAdr, // mov reg, PC relative displacement; lir operands - 0: reg, 1: table 410 kX86RepneScasw, // repne scasw 411 kX86Last 412}; 413 414/* Instruction assembly field_loc kind */ 415enum X86EncodingKind { 416 kData, // Special case for raw data. 417 kNop, // Special case for variable length nop. 418 kNullary, // Opcode that takes no arguments. 419 kPrefix2Nullary, // Opcode that takes no arguments, but 2 prefixes. 420 kRegOpcode, // Shorter form of R instruction kind (opcode+rd) 421 kReg, kMem, kArray, // R, M and A instruction kinds. 422 kMemReg, kArrayReg, kThreadReg, // MR, AR and TR instruction kinds. 423 kRegReg, kRegMem, kRegArray, kRegThread, // RR, RM, RA and RT instruction kinds. 424 kRegRegStore, // RR following the store modrm reg-reg encoding rather than the load. 425 kRegImm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds. 426 kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds. 427 kMovRegImm, // Shorter form move RI. 428 kRegRegImmRev, // RRI with first reg in r/m 429 kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate. 430 kShiftRegCl, kShiftMemCl, kShiftArrayCl, // Shift opcode with register CL. 431 kRegRegReg, kRegRegMem, kRegRegArray, // RRR, RRM, RRA instruction kinds. 432 kRegCond, kMemCond, kArrayCond, // R, M, A instruction kinds following by a condition. 433 kRegRegCond, // RR instruction kind followed by a condition. 434 kJmp, kJcc, kCall, // Branch instruction kinds. 435 kPcRel, // Operation with displacement that is PC relative 436 kMacro, // An instruction composing multiple others 437 kUnimplemented // Encoding used when an instruction isn't yet implemented. 438}; 439 440/* Struct used to define the EncodingMap positions for each X86 opcode */ 441struct X86EncodingMap { 442 X86OpCode opcode; // e.g. kOpAddRI 443 X86EncodingKind kind; // Used to discriminate in the union below 444 uint64_t flags; 445 struct { 446 uint8_t prefix1; // non-zero => a prefix byte 447 uint8_t prefix2; // non-zero => a second prefix byte 448 uint8_t opcode; // 1 byte opcode 449 uint8_t extra_opcode1; // possible extra opcode byte 450 uint8_t extra_opcode2; // possible second extra opcode byte 451 // 3bit opcode that gets encoded in the register bits of the modrm byte, use determined by the 452 // encoding kind 453 uint8_t modrm_opcode; 454 uint8_t ax_opcode; // non-zero => shorter encoding for AX as a destination 455 uint8_t immediate_bytes; // number of bytes of immediate 456 } skeleton; 457 const char *name; 458 const char* fmt; 459}; 460 461 462// FIXME: mem barrier type - what do we do for x86? 463#define kSY 0 464#define kST 0 465 466// Offsets of high and low halves of a 64bit value. 467#define LOWORD_OFFSET 0 468#define HIWORD_OFFSET 4 469 470// Segment override instruction prefix used for quick TLS access to Thread::Current(). 471#define THREAD_PREFIX 0x64 472 473#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127)) 474#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767)) 475 476extern X86EncodingMap EncodingMap[kX86Last]; 477extern X86ConditionCode X86ConditionEncoding(ConditionCode cond); 478 479} // namespace art 480 481#endif // ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_ 482