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