blob: 1fc44b3add98628509c1e78a84e08bd8c840a146 [file] [log] [blame]
Ian Rogerse32ca232012-03-05 10:20:23 -08001/*
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_COMPILER_CODEGEN_X86_X86LIR_H_
18#define ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_
19
20#include "../../Dalvik.h"
21#include "../../CompilerInternals.h"
22
23namespace art {
24
25// Set to 1 to measure cost of suspend check
26#define NO_SUSPEND 0
27
28/*
29 * Runtime register conventions. We consider both x86, x86-64 and x32 (32bit mode x86-64), although
30 * we currently only target x86. The ABI has different conventions and we hope to have a single
31 * convention to simplify code generation. Changing something that is callee save and making it
32 * caller save places a burden on up-calls to save/restore the callee save register, however, there
33 * are few registers that are callee save in the ABI. Changing something that is caller save and
34 * making it callee save places a burden on down-calls to save/restore the callee save register.
Ian Rogersb41b33b2012-03-20 14:22:54 -070035 * For these reasons we aim to match native conventions for caller and callee save. The first 4
36 * registers can be used for byte operations, for this reason they are preferred for temporary
37 * scratch registers.
Ian Rogerse32ca232012-03-05 10:20:23 -080038 *
39 * General Purpose Register:
40 * Native: x86 | x86-64 / x32 | ART
41 * r0/eax: caller save | caller save | caller, Method*, scratch, return value
Ian Rogersb41b33b2012-03-20 14:22:54 -070042 * r1/ecx: caller save | caller save, arg4 | caller, arg1, scratch
43 * r2/edx: caller save | caller save, arg3 | caller, arg2, scratch, high half of long return
44 * r3/ebx: callEE save | callEE save | callER, arg3, scratch
Ian Rogerse32ca232012-03-05 10:20:23 -080045 * r4/esp: stack pointer
46 * r5/ebp: callee save | callee save | callee, available for dalvik register promotion
47 * r6/esi: callEE save | callER save, arg2 | callee, available for dalvik register promotion
48 * r7/edi: callEE save | callER save, arg1 | callee, available for dalvik register promotion
49 * --- x86-64/x32 registers
50 * Native: x86-64 / x32 | ART
51 * r8: caller save, arg5 | caller, scratch
52 * r9: caller save, arg6 | caller, scratch
53 * r10: caller save | caller, scratch
54 * r11: caller save | caller, scratch
55 * r12: callee save | callee, available for dalvik register promotion
56 * r13: callee save | callee, available for dalvik register promotion
57 * r14: callee save | callee, available for dalvik register promotion
58 * r15: callee save | callee, available for dalvik register promotion
59 *
60 * There is no rSELF, instead on x86 fs: has a base address of Thread::Current, whereas on
61 * x86-64/x32 gs: holds it.
62 *
63 * For floating point we don't support CPUs without SSE2 support (ie newer than PIII):
64 * Native: x86 | x86-64 / x32 | ART
65 * XMM0: caller save |caller save, arg1 | caller, float/double return value (except for native x86 code)
66 * XMM1: caller save |caller save, arg2 | caller, scratch
67 * XMM2: caller save |caller save, arg3 | caller, scratch
68 * XMM3: caller save |caller save, arg4 | caller, scratch
69 * XMM4: caller save |caller save, arg5 | caller, scratch
70 * XMM5: caller save |caller save, arg6 | caller, scratch
71 * XMM6: caller save |caller save, arg7 | caller, scratch
72 * XMM7: caller save |caller save, arg8 | caller, scratch
73 * --- x86-64/x32 registers
74 * XMM8 .. 15: caller save
75 *
76 * X87 is a necessary evil outside of ART code:
77 * ST0: x86 float/double native return value, caller save
78 * ST1 .. ST7: caller save
79 *
80 * Stack frame diagram (stack grows down, higher addresses at top):
81 *
82 * +------------------------+
83 * | IN[ins-1] | {Note: resides in caller's frame}
84 * | . |
85 * | IN[0] |
86 * | caller's Method* |
87 * +========================+ {Note: start of callee's frame}
88 * | return address | {pushed by call}
89 * | spill region | {variable sized}
90 * +------------------------+
91 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
92 * +------------------------+
93 * | V[locals-1] |
94 * | V[locals-2] |
95 * | . |
96 * | . |
97 * | V[1] |
98 * | V[0] |
99 * +------------------------+
100 * | 0 to 3 words padding |
101 * +------------------------+
102 * | OUT[outs-1] |
103 * | OUT[outs-2] |
104 * | . |
105 * | OUT[0] |
106 * | curMethod* | <<== sp w/ 16-byte alignment
107 * +========================+
108 */
109
110/* Offset to distingish FP regs */
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700111#define FP_REG_OFFSET 32
Ian Rogerse32ca232012-03-05 10:20:23 -0800112/* Offset to distinguish DP FP regs */
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700113#define FP_DOUBLE (FP_REG_OFFSET + 16)
Ian Rogerse32ca232012-03-05 10:20:23 -0800114/* Offset to distingish the extra regs */
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700115#define EXTRA_REG_OFFSET (FP_DOUBLE + 16)
Ian Rogerse32ca232012-03-05 10:20:23 -0800116/* Reg types */
117#define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
118#define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
119#define EXTRAREG(x) ((x & EXTRA_REG_OFFSET) == EXTRA_REG_OFFSET)
120#define LOWREG(x) ((x & 0x1f) == x)
121#define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
122#define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
Ian Rogersb5d09b22012-03-06 22:14:17 -0800123
Ian Rogerse32ca232012-03-05 10:20:23 -0800124/*
125 * Note: the low register of a floating point pair is sufficient to
126 * create the name of a double, but require both names to be passed to
127 * allow for asserts to verify that the pair is consecutive if significant
128 * rework is done in this area. Also, it is a good reminder in the calling
129 * code that reg locations always describe doubles as a pair of singles.
130 */
131#define S2D(x,y) ((x) | FP_DOUBLE)
132/* Mask to strip off fp flags */
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700133#define FP_REG_MASK 0xF
Ian Rogerse32ca232012-03-05 10:20:23 -0800134/* non-existent Dalvik register */
135#define vNone (-1)
136/* non-existant physical register */
137#define rNone (-1)
138
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700139/* RegisterLocation templates return values (rAX, rAX/rDX or XMM0) */
140// location, wide, defined, fp, core, highWord, home, lowReg, highReg, sRegLow
141#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, rAX, INVALID_REG, INVALID_SREG}
142#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, rAX, rDX, INVALID_SREG}
143#define LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 1, 0, 0, 1, fr0, INVALID_REG, INVALID_SREG}
144#define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 1, 0, 0, 1, fr0, fr1, INVALID_SREG}
Ian Rogerse32ca232012-03-05 10:20:23 -0800145
Elliott Hughes719ace42012-03-09 18:06:03 -0800146enum ResourceEncodingPos {
Ian Rogerse32ca232012-03-05 10:20:23 -0800147 kGPReg0 = 0,
148 kRegSP = 4,
149 kRegLR = -1,
150 kFPReg0 = 16, // xmm0 .. xmm7/xmm15
151 kFPRegEnd = 32,
152 kRegEnd = kFPRegEnd,
153 kCCode = kRegEnd,
154 // The following four bits are for memory disambiguation
155 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
156 kLiteral, // 2 Literal pool (can be fully disambiguated)
157 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
158 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
Elliott Hughes719ace42012-03-09 18:06:03 -0800159};
Ian Rogerse32ca232012-03-05 10:20:23 -0800160
161#define ENCODE_REG_LIST(N) ((u8) N)
162#define ENCODE_REG_SP (1ULL << kRegSP)
163#define ENCODE_CCODE (1ULL << kCCode)
164#define ENCODE_FP_STATUS (1ULL << kFPStatus)
165
166/* Abstract memory locations */
167#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
168#define ENCODE_LITERAL (1ULL << kLiteral)
169#define ENCODE_HEAP_REF (1ULL << kHeapRef)
170#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
171
172#define ENCODE_ALL (~0ULL)
173#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
174 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
175
176#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
177#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
178
179/*
180 * Annotate special-purpose core registers:
181 */
182
Elliott Hughes719ace42012-03-09 18:06:03 -0800183enum NativeRegisterPool {
Ian Rogerse32ca232012-03-05 10:20:23 -0800184 r0 = 0,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800185 rAX = r0,
Ian Rogerse32ca232012-03-05 10:20:23 -0800186 r1 = 1,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800187 rCX = r1,
Ian Rogerse32ca232012-03-05 10:20:23 -0800188 r2 = 2,
189 rDX = r2,
190 r3 = 3,
191 rBX = r3,
192 r4sp = 4,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800193 rSP = r4sp,
194 r4sib_no_index = r4sp,
Ian Rogerse32ca232012-03-05 10:20:23 -0800195 r5 = 5,
196 rBP = r5,
197 r6 = 6,
198 rSI = r6,
199 r7 = 7,
200 rDI = r7,
201 r8 = 8,
202 r9 = 9,
203 r10 = 10,
204 r11 = 11,
205 r12 = 12,
206 r13 = 13,
207 r14 = 14,
208 r15 = 15,
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700209 rRET = 16, // fake return address register for core spill mask
Ian Rogerse32ca232012-03-05 10:20:23 -0800210 fr0 = 0 + FP_REG_OFFSET,
211 fr1 = 1 + FP_REG_OFFSET,
212 fr2 = 2 + FP_REG_OFFSET,
213 fr3 = 3 + FP_REG_OFFSET,
214 fr4 = 4 + FP_REG_OFFSET,
215 fr5 = 5 + FP_REG_OFFSET,
216 fr6 = 6 + FP_REG_OFFSET,
217 fr7 = 7 + FP_REG_OFFSET,
218 fr8 = 8 + FP_REG_OFFSET,
219 fr9 = 9 + FP_REG_OFFSET,
220 fr10 = 10 + FP_REG_OFFSET,
221 fr11 = 11 + FP_REG_OFFSET,
222 fr12 = 12 + FP_REG_OFFSET,
223 fr13 = 13 + FP_REG_OFFSET,
224 fr14 = 14 + FP_REG_OFFSET,
225 fr15 = 15 + FP_REG_OFFSET,
Elliott Hughes719ace42012-03-09 18:06:03 -0800226};
Ian Rogerse32ca232012-03-05 10:20:23 -0800227
228/*
229 * Target-independent aliases
230 */
231
232#define rARG0 rAX
Ian Rogersb41b33b2012-03-20 14:22:54 -0700233#define rARG1 rCX
234#define rARG2 rDX
235#define rARG3 rBX
Ian Rogerse32ca232012-03-05 10:20:23 -0800236#define rRET0 rAX
237#define rRET1 rDX
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700238#define rINVOKE_TGT rAX
Ian Rogerse32ca232012-03-05 10:20:23 -0800239
240#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
241
Ian Rogersb5d09b22012-03-06 22:14:17 -0800242/* X86 condition encodings */
243enum X86ConditionCode {
244 kX86CondO = 0x0, // overflow
245 kX86CondNo = 0x1, // not overflow
246
247 kX86CondB = 0x2, // below
248 kX86CondNae = kX86CondB, // not-above-equal
249 kX86CondC = kX86CondB, // carry
250
251 kX86CondNb = 0x3, // not-below
252 kX86CondAe = kX86CondNb, // above-equal
253 kX86CondNc = kX86CondNb, // not-carry
254
255 kX86CondZ = 0x4, // zero
256 kX86CondEq = kX86CondZ, // equal
257
258 kX86CondNz = 0x5, // not-zero
259 kX86CondNe = kX86CondNz, // not-equal
260
261 kX86CondBe = 0x6, // below-equal
262 kX86CondNa = kX86CondBe, // not-above
263
264 kX86CondNbe = 0x7, // not-below-equal
265 kX86CondA = kX86CondNbe,// above
266
267 kX86CondS = 0x8, // sign
268 kX86CondNs = 0x9, // not-sign
269
270 kX86CondP = 0xA, // 8-bit parity even
271 kX86CondPE = kX86CondP,
272
273 kX86CondNp = 0xB, // 8-bit parity odd
274 kX86CondPo = kX86CondNp,
275
276 kX86CondL = 0xC, // less-than
277 kX86CondNge = kX86CondL, // not-greater-equal
278
279 kX86CondNl = 0xD, // not-less-than
280 kX86CondGe = kX86CondL, // not-greater-equal
281
282 kX86CondLe = 0xE, // less-than-equal
283 kX86CondNg = kX86CondLe, // not-greater
284
285 kX86CondNle = 0xF, // not-less-than
286 kX86CondG = kX86CondNle,// greater
287};
288
Ian Rogerse32ca232012-03-05 10:20:23 -0800289/*
Ian Rogersde797832012-03-06 10:18:10 -0800290 * The following enum defines the list of supported X86 instructions by the
291 * assembler. Their corresponding EncodingMap positions will be defined in
292 * Assemble.cc.
Ian Rogerse32ca232012-03-05 10:20:23 -0800293 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800294enum X86OpCode {
buzbeefc9e6fa2012-03-23 15:14:29 -0700295 kPseudoIntrinsicRetry = -16,
Ian Rogerse32ca232012-03-05 10:20:23 -0800296 kPseudoSuspendTarget = -15,
297 kPseudoThrowTarget = -14,
298 kPseudoCaseLabel = -13,
299 kPseudoMethodEntry = -12,
300 kPseudoMethodExit = -11,
301 kPseudoBarrier = -10,
302 kPseudoExtended = -9,
303 kPseudoSSARep = -8,
304 kPseudoEntryBlock = -7,
305 kPseudoExitBlock = -6,
306 kPseudoTargetLabel = -5,
307 kPseudoDalvikByteCodeBoundary = -4,
308 kPseudoPseudoAlign4 = -3,
309 kPseudoEHBlockLabel = -2,
310 kPseudoNormalBlockLabel = -1,
Ian Rogerse32ca232012-03-05 10:20:23 -0800311 kX86First,
Ian Rogers96ab4202012-03-05 19:51:02 -0800312 kX8632BitData = kX86First, /* data [31..0] */
Ian Rogersb5d09b22012-03-06 22:14:17 -0800313 kX86Bkpt,
314 kX86Nop,
Ian Rogersde797832012-03-06 10:18:10 -0800315 // Define groups of binary operations
Ian Rogersb5d09b22012-03-06 22:14:17 -0800316 // MR - Memory Register - opcode [base + disp], reg
317 // - lir operands - 0: base, 1: disp, 2: reg
318 // AR - Array Register - opcode [base + index * scale + disp], reg
319 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
320 // TR - Thread Register - opcode fs:[disp], reg - where fs: is equal to Thread::Current()
321 // - lir operands - 0: disp, 1: reg
Ian Rogersde797832012-03-06 10:18:10 -0800322 // RR - Register Register - opcode reg1, reg2
323 // - lir operands - 0: reg1, 1: reg2
324 // RM - Register Memory - opcode reg, [base + disp]
325 // - lir operands - 0: reg, 1: base, 2: disp
326 // RA - Register Array - opcode reg, [base + index * scale + disp]
327 // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
Ian Rogersb5d09b22012-03-06 22:14:17 -0800328 // RT - Register Thread - opcode reg, fs:[disp] - where fs: is equal to Thread::Current()
329 // - lir operands - 0: reg, 1: disp
330 // RI - Register Immediate - opcode reg, #immediate
331 // - lir operands - 0: reg, 1: immediate
332 // MI - Memory Immediate - opcode [base + disp], #immediate
333 // - lir operands - 0: base, 1: disp, 2: immediate
334 // AI - Array Immediate - opcode [base + index * scale + disp], #immediate
335 // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
336 // TI - Thread Register - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
337 // - lir operands - 0: disp, 1: imm
Ian Rogers96ab4202012-03-05 19:51:02 -0800338#define BinaryOpCode(opcode) \
Ian Rogersb5d09b22012-03-06 22:14:17 -0800339 opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \
340 opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \
341 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \
342 opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \
343 opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \
344 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \
345 opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \
346 opcode ## 32MR, opcode ## 32AR, opcode ## 32TR, \
347 opcode ## 32RR, opcode ## 32RM, opcode ## 32RA, opcode ## 32RT, \
348 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \
349 opcode ## 32RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8
350 BinaryOpCode(kX86Add),
351 BinaryOpCode(kX86Or),
352 BinaryOpCode(kX86Adc),
353 BinaryOpCode(kX86Sbb),
354 BinaryOpCode(kX86And),
355 BinaryOpCode(kX86Sub),
356 BinaryOpCode(kX86Xor),
357 BinaryOpCode(kX86Cmp),
Ian Rogers96ab4202012-03-05 19:51:02 -0800358#undef BinaryOpCode
Ian Rogersb5d09b22012-03-06 22:14:17 -0800359 kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI,
360 kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI,
361 kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8,
362 kX86Mov8MR, kX86Mov8AR, kX86Mov8TR,
363 kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT,
364 kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI,
365 kX86Mov16MR, kX86Mov16AR, kX86Mov16TR,
366 kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT,
367 kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI,
368 kX86Mov32MR, kX86Mov32AR, kX86Mov32TR,
369 kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT,
370 kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI,
371 kX86Lea32RA,
372 // RC - Register CL - opcode reg, CL
373 // - lir operands - 0: reg, 1: CL
374 // MC - Memory CL - opcode [base + disp], CL
375 // - lir operands - 0: base, 1: disp, 2: CL
376 // AC - Array CL - opcode [base + index * scale + disp], CL
377 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL
378#define BinaryShiftOpCode(opcode) \
379 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \
380 opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \
381 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \
382 opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \
383 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \
384 opcode ## 32RC, opcode ## 32MC, opcode ## 32AC
385 BinaryShiftOpCode(kX86Rol),
386 BinaryShiftOpCode(kX86Ror),
387 BinaryShiftOpCode(kX86Rcl),
388 BinaryShiftOpCode(kX86Rcr),
389 BinaryShiftOpCode(kX86Sal),
390 BinaryShiftOpCode(kX86Shl),
391 BinaryShiftOpCode(kX86Shr),
392 BinaryShiftOpCode(kX86Sar),
393#undef BinaryShiftOpcode
394#define UnaryOpcode(opcode, reg, mem, array) \
395 opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
396 opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
397 opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array
398 UnaryOpcode(kX86Test, RI, MI, AI),
399 UnaryOpcode(kX86Not, R, M, A),
400 UnaryOpcode(kX86Neg, R, M, A),
401 UnaryOpcode(kX86Mul, DaR, DaM, DaA),
402 UnaryOpcode(kX86Imul, DaR, DaM, DaA),
403 UnaryOpcode(kX86Divmod, DaR, DaM, DaA),
404 UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
405#undef UnaryOpcode
406#define Binary0fOpCode(opcode) \
407 opcode ## RR, opcode ## RM, opcode ## RA
408 Binary0fOpCode(kX86Movsd),
409 kX86MovsdMR,
410 kX86MovsdAR,
411 Binary0fOpCode(kX86Movss),
412 kX86MovssMR,
413 kX86MovssAR,
414 Binary0fOpCode(kX86Cvtsi2sd), // int to double
415 Binary0fOpCode(kX86Cvtsi2ss), // int to float
416 Binary0fOpCode(kX86Cvttsd2si), // truncating double to int
417 Binary0fOpCode(kX86Cvttss2si), // truncating float to int
418 Binary0fOpCode(kX86Cvtsd2si), // rounding double to int
419 Binary0fOpCode(kX86Cvtss2si), // rounding float to int
420 Binary0fOpCode(kX86Ucomisd), // unordered double compare
421 Binary0fOpCode(kX86Ucomiss), // unordered float compare
422 Binary0fOpCode(kX86Comisd), // double compare
423 Binary0fOpCode(kX86Comiss), // float compare
Ian Rogersb41b33b2012-03-20 14:22:54 -0700424 Binary0fOpCode(kX86Orps), // or of floating point registers
425 Binary0fOpCode(kX86Xorps), // xor of floating point registers
Ian Rogersb5d09b22012-03-06 22:14:17 -0800426 Binary0fOpCode(kX86Addsd), // double add
427 Binary0fOpCode(kX86Addss), // float add
428 Binary0fOpCode(kX86Mulsd), // double multiply
429 Binary0fOpCode(kX86Mulss), // float multiply
430 Binary0fOpCode(kX86Cvtss2sd), // float to double
431 Binary0fOpCode(kX86Cvtsd2ss), // double to float
432 Binary0fOpCode(kX86Subsd), // double subtract
433 Binary0fOpCode(kX86Subss), // float subtract
Ian Rogersb41b33b2012-03-20 14:22:54 -0700434 Binary0fOpCode(kX86Divsd), // double divide
435 Binary0fOpCode(kX86Divss), // float divide
436 kX86PsllqRI, // shift of floating point registers
Ian Rogersb5d09b22012-03-06 22:14:17 -0800437 Binary0fOpCode(kX86Movdxr), // move into xmm from gpr
438 Binary0fOpCode(kX86Movdrx), // move into reg from xmm
439 kX86Set8R, kX86Set8M, kX86Set8A,// set byte depending on condition operand
Ian Rogersc6f3bb82012-03-21 20:40:33 -0700440 kX86Mfence, // memory barrier
Ian Rogersb5d09b22012-03-06 22:14:17 -0800441 Binary0fOpCode(kX86Imul16), // 16bit multiply
442 Binary0fOpCode(kX86Imul32), // 32bit multiply
443 Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value
444 Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value
445 Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value
446 Binary0fOpCode(kX86Movsx16), // sign-extend 16-bit value
447#undef Binary0fOpCode
Ian Rogersb41b33b2012-03-20 14:22:54 -0700448 kX86Jcc8, kX86Jcc32, // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
449 kX86Jmp8, kX86Jmp32, // jmp rel8/32; lir operands - 0: rel, target assigned
Ian Rogersb5d09b22012-03-06 22:14:17 -0800450 kX86CallR, // call reg; lir operands - 0: reg
451 kX86CallM, // call [base + disp]; lir operands - 0: base, 1: disp
452 kX86CallA, // call [base + index * scale + disp]
453 // lir operands - 0: base, 1: index, 2: scale, 3: disp
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700454 kX86CallT, // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
Ian Rogersb5d09b22012-03-06 22:14:17 -0800455 kX86Ret, // ret; no lir operands
Ian Rogerse32ca232012-03-05 10:20:23 -0800456 kX86Last
Elliott Hughes719ace42012-03-09 18:06:03 -0800457};
Ian Rogerse32ca232012-03-05 10:20:23 -0800458
Ian Rogersde797832012-03-06 10:18:10 -0800459/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800460enum X86EncodingKind {
Ian Rogersb5d09b22012-03-06 22:14:17 -0800461 kData, // Special case for raw data.
462 kNop, // Special case for variable length nop.
463 kNullary, // Opcode that takes no arguments.
464 kReg, kMem, kArray, // R, M and A instruction kinds.
465 kMemReg, kArrayReg, kThreadReg, // MR, AR and TR instruction kinds.
466 kRegReg, kRegMem, kRegArray, kRegThread, // RR, RM, RA and RT instruction kinds.
467 kRegImm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds.
468 kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds.
469 kMovRegImm, // Shorter form move RI.
470 kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate.
471 kShiftRegCl, kShiftMemCl, kShiftArrayCl, // Shift opcode with register CL.
472 kRegRegReg, kRegRegMem, kRegRegArray, // RRR, RRM, RRA instruction kinds.
473 kRegCond, kMemCond, kArrayCond, // R, M, A instruction kinds following by a condition.
474 kJmp, kJcc, kCall, // Branch instruction kinds.
Ian Rogersde797832012-03-06 10:18:10 -0800475 kUnimplemented // Encoding used when an instruction isn't yet implemented.
Elliott Hughes719ace42012-03-09 18:06:03 -0800476};
Ian Rogersde797832012-03-06 10:18:10 -0800477
Ian Rogersde797832012-03-06 10:18:10 -0800478/* Struct used to define the EncodingMap positions for each X86 opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800479struct X86EncodingMap {
Ian Rogersde797832012-03-06 10:18:10 -0800480 X86OpCode opcode; // e.g. kOpAddRI
481 X86EncodingKind kind; // Used to discriminate in the union below
482 int flags;
Ian Rogersb5d09b22012-03-06 22:14:17 -0800483 struct {
484 uint8_t prefix1; // non-zero => a prefix byte
485 uint8_t prefix2; // non-zero => a second prefix byte
486 uint8_t opcode; // 1 byte opcode
487 uint8_t extra_opcode1; // possible extra opcode byte
488 uint8_t extra_opcode2; // possible second extra opcode byte
489 // 3bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
490 // encoding kind
491 uint8_t modrm_opcode;
492 uint8_t ax_opcode; // non-zero => shorter encoding for AX as a destination
493 uint8_t immediate_bytes; // number of bytes of immediate
Ian Rogersde797832012-03-06 10:18:10 -0800494 } skeleton;
495 const char *name;
496 const char* fmt;
Elliott Hughes719ace42012-03-09 18:06:03 -0800497};
Ian Rogersde797832012-03-06 10:18:10 -0800498
499extern X86EncodingMap EncodingMap[kX86Last];
500
buzbeea7678db2012-03-05 15:35:46 -0800501// FIXME: mem barrier type - what do we do for x86?
502#define kSY 0
503#define kST 0
504
Ian Rogerse32ca232012-03-05 10:20:23 -0800505/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800506enum X86OpFeatureFlags {
Ian Rogerse32ca232012-03-05 10:20:23 -0800507 kIsBranch = 0,
508 kRegDef0,
509 kRegDef1,
510 kRegDefSP,
511 kRegDefList0,
512 kRegDefList1,
513 kRegUse0,
514 kRegUse1,
515 kRegUse2,
516 kRegUse3,
517 kRegUseSP,
518 kRegUseList0,
519 kRegUseList1,
520 kNoOperand,
521 kIsUnaryOp,
522 kIsBinaryOp,
523 kIsTertiaryOp,
524 kIsQuadOp,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800525 kIsQuinOp,
526 kIsSextupleOp,
Ian Rogerse32ca232012-03-05 10:20:23 -0800527 kIsIT,
528 kSetsCCodes,
529 kUsesCCodes,
530 kMemLoad,
531 kMemStore,
532 kPCRelFixup,
533// FIXME: add NEEDS_FIXUP to instruction attributes
Elliott Hughes719ace42012-03-09 18:06:03 -0800534};
Ian Rogerse32ca232012-03-05 10:20:23 -0800535
536#define IS_LOAD (1 << kMemLoad)
537#define IS_STORE (1 << kMemStore)
538#define IS_BRANCH (1 << kIsBranch)
539#define REG_DEF0 (1 << kRegDef0)
540#define REG_DEF1 (1 << kRegDef1)
541#define REG_DEF_SP (1 << kRegDefSP)
542#define REG_DEF_LR (1 << kRegDefLR)
543#define REG_DEF_LIST0 (1 << kRegDefList0)
544#define REG_DEF_LIST1 (1 << kRegDefList1)
545#define REG_USE0 (1 << kRegUse0)
546#define REG_USE1 (1 << kRegUse1)
547#define REG_USE2 (1 << kRegUse2)
548#define REG_USE3 (1 << kRegUse3)
549#define REG_USE_SP (1 << kRegUseSP)
550#define REG_USE_PC (1 << kRegUsePC)
551#define REG_USE_LIST0 (1 << kRegUseList0)
552#define REG_USE_LIST1 (1 << kRegUseList1)
553#define NO_OPERAND (1 << kNoOperand)
554#define IS_UNARY_OP (1 << kIsUnaryOp)
555#define IS_BINARY_OP (1 << kIsBinaryOp)
556#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
557#define IS_QUAD_OP (1 << kIsQuadOp)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800558#define IS_QUIN_OP (1 << kIsQuinOp)
559#define IS_SEXTUPLE_OP (1 << kIsSextupleOp)
Ian Rogerse32ca232012-03-05 10:20:23 -0800560#define IS_IT (1 << kIsIT)
561#define SETS_CCODES (1 << kSetsCCodes)
562#define USES_CCODES (1 << kUsesCCodes)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800563#define NEEDS_FIXUP (1 << kPCRelFixup)
Ian Rogerse32ca232012-03-05 10:20:23 -0800564
565/* attributes, included for compatibility */
566#define REG_DEF_FPCS_LIST0 (0)
567#define REG_DEF_FPCS_LIST2 (0)
568
569
570/* Common combo register usage patterns */
571#define REG_USE01 (REG_USE0 | REG_USE1)
572#define REG_USE02 (REG_USE0 | REG_USE2)
573#define REG_USE012 (REG_USE01 | REG_USE2)
574#define REG_USE12 (REG_USE1 | REG_USE2)
575#define REG_USE23 (REG_USE2 | REG_USE3)
576#define REG_DEF01 (REG_DEF0 | REG_DEF1)
577#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
578#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
579#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
580#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
581#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
582#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
583
Ian Rogerse32ca232012-03-05 10:20:23 -0800584/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800585enum X86TargetOptHints {
Ian Rogerse32ca232012-03-05 10:20:23 -0800586 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800587};
Ian Rogerse32ca232012-03-05 10:20:23 -0800588
Ian Rogersb5d09b22012-03-06 22:14:17 -0800589/* Offsets of high and low halves of a 64bit value */
590#define LOWORD_OFFSET 0
591#define HIWORD_OFFSET 4
592
593/* Segment override instruction prefix used for quick TLS access to Thread::Current() */
594#define THREAD_PREFIX 0x64
Ian Rogerse32ca232012-03-05 10:20:23 -0800595
Ian Rogersde797832012-03-06 10:18:10 -0800596#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
Ian Rogersb5d09b22012-03-06 22:14:17 -0800597#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
Ian Rogerse32ca232012-03-05 10:20:23 -0800598
599} // namespace art
600
601#endif // ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_