compiler_enums.h revision b28c1c06236751aa5c9e64dcb68b3c940341e496
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_COMPILER_ENUMS_H_
18#define ART_COMPILER_DEX_COMPILER_ENUMS_H_
19
20#include "dex_instruction.h"
21
22namespace art {
23
24enum RegisterClass {
25  kInvalidRegClass,
26  kCoreReg,
27  kFPReg,
28  kRefReg,
29  kAnyReg,
30};
31std::ostream& operator<<(std::ostream& os, const RegisterClass& rhs);
32
33enum BitsUsed {
34  kSize32Bits,
35  kSize64Bits,
36  kSize128Bits,
37  kSize256Bits,
38  kSize512Bits,
39  kSize1024Bits,
40};
41std::ostream& operator<<(std::ostream& os, const BitsUsed& rhs);
42
43enum SpecialTargetRegister {
44  kSelf,            // Thread pointer.
45  kSuspend,         // Used to reduce suspend checks for some targets.
46  kLr,
47  kPc,
48  kSp,
49  kArg0,
50  kArg1,
51  kArg2,
52  kArg3,
53  kArg4,
54  kArg5,
55  kArg6,
56  kArg7,
57  kFArg0,
58  kFArg1,
59  kFArg2,
60  kFArg3,
61  kFArg4,
62  kFArg5,
63  kFArg6,
64  kFArg7,
65  kFArg8,
66  kFArg9,
67  kFArg10,
68  kFArg11,
69  kFArg12,
70  kFArg13,
71  kFArg14,
72  kFArg15,
73  kRet0,
74  kRet1,
75  kInvokeTgt,
76  kHiddenArg,
77  kHiddenFpArg,
78  kCount
79};
80std::ostream& operator<<(std::ostream& os, const SpecialTargetRegister& code);
81
82enum RegLocationType {
83  kLocDalvikFrame = 0,  // Normal Dalvik register
84  kLocPhysReg,
85  kLocCompilerTemp,
86  kLocInvalid
87};
88std::ostream& operator<<(std::ostream& os, const RegLocationType& rhs);
89
90enum BBType {
91  kNullBlock,
92  kEntryBlock,
93  kDalvikByteCode,
94  kExitBlock,
95  kExceptionHandling,
96  kDead,
97};
98std::ostream& operator<<(std::ostream& os, const BBType& code);
99
100// Shared pseudo opcodes - must be < 0.
101enum LIRPseudoOpcode {
102  kPseudoExportedPC = -16,
103  kPseudoSafepointPC = -15,
104  kPseudoIntrinsicRetry = -14,
105  kPseudoSuspendTarget = -13,
106  kPseudoThrowTarget = -12,
107  kPseudoCaseLabel = -11,
108  kPseudoMethodEntry = -10,
109  kPseudoMethodExit = -9,
110  kPseudoBarrier = -8,
111  kPseudoEntryBlock = -7,
112  kPseudoExitBlock = -6,
113  kPseudoTargetLabel = -5,
114  kPseudoDalvikByteCodeBoundary = -4,
115  kPseudoPseudoAlign4 = -3,
116  kPseudoEHBlockLabel = -2,
117  kPseudoNormalBlockLabel = -1,
118};
119std::ostream& operator<<(std::ostream& os, const LIRPseudoOpcode& rhs);
120
121enum ExtendedMIROpcode {
122  kMirOpFirst = kNumPackedOpcodes,
123  kMirOpPhi = kMirOpFirst,
124
125  // @brief Copy from one VR to another.
126  // @details
127  // vA: destination VR
128  // vB: source VR
129  kMirOpCopy,
130
131  // @brief Used to do float comparison with less-than bias.
132  // @details Unlike cmpl-float, this does not store result of comparison in VR.
133  // vA: left-hand side VR for comparison.
134  // vB: right-hand side VR for comparison.
135  kMirOpFusedCmplFloat,
136
137  // @brief Used to do float comparison with greater-than bias.
138  // @details Unlike cmpg-float, this does not store result of comparison in VR.
139  // vA: left-hand side VR for comparison.
140  // vB: right-hand side VR for comparison.
141  kMirOpFusedCmpgFloat,
142
143  // @brief Used to do double comparison with less-than bias.
144  // @details Unlike cmpl-double, this does not store result of comparison in VR.
145  // vA: left-hand side wide VR for comparison.
146  // vB: right-hand side wide VR for comparison.
147  kMirOpFusedCmplDouble,
148
149  // @brief Used to do double comparison with greater-than bias.
150  // @details Unlike cmpl-double, this does not store result of comparison in VR.
151  // vA: left-hand side wide VR for comparison.
152  // vB: right-hand side wide VR for comparison.
153  kMirOpFusedCmpgDouble,
154
155  // @brief Used to do comparison of 64-bit long integers.
156  // @details Unlike cmp-long, this does not store result of comparison in VR.
157  // vA: left-hand side wide VR for comparison.
158  // vB: right-hand side wide VR for comparison.
159  kMirOpFusedCmpLong,
160
161  // @brief This represents no-op.
162  kMirOpNop,
163
164  // @brief Do a null check on the object register.
165  // @details The backends may implement this implicitly or explicitly. This MIR is guaranteed
166  // to have the correct offset as an exception thrower.
167  // vA: object register
168  kMirOpNullCheck,
169
170  kMirOpRangeCheck,
171  kMirOpDivZeroCheck,
172  kMirOpCheck,
173  kMirOpCheckPart2,
174  kMirOpSelect,
175
176  // Vector opcodes:
177  // TypeSize is an encoded field giving the element type and the vector size.
178  // It is encoded as OpSize << 16 | (number of bits in vector)
179  //
180  // Destination and source are integers that will be interpreted by the
181  // backend that supports Vector operations.  Backends are permitted to support only
182  // certain vector register sizes.
183  //
184  // At this point, only two operand instructions are supported.  Three operand instructions
185  // could be supported by using a bit in TypeSize and arg[0] where needed.
186
187  // @brief MIR to move constant data to a vector register
188  // vA: destination
189  // vB: number of bits in register
190  // args[0]~args[3]: up to 128 bits of data for initialization
191  kMirOpConstVector,
192
193  // @brief MIR to move a vectorized register to another
194  // vA: destination
195  // vB: source
196  // vC: TypeSize
197  kMirOpMoveVector,
198
199  // @brief Packed multiply of units in two vector registers: vB = vB .* vC using vA to know the type of the vector.
200  // vA: destination and source
201  // vB: source
202  // vC: TypeSize
203  kMirOpPackedMultiply,
204
205  // @brief Packed addition of units in two vector registers: vB = vB .+ vC using vA to know the type of the vector.
206  // vA: destination and source
207  // vB: source
208  // vC: TypeSize
209  kMirOpPackedAddition,
210
211  // @brief Packed subtraction of units in two vector registers: vB = vB .- vC using vA to know the type of the vector.
212  // vA: destination and source
213  // vB: source
214  // vC: TypeSize
215  kMirOpPackedSubtract,
216
217  // @brief Packed shift left of units in two vector registers: vB = vB .<< vC using vA to know the type of the vector.
218  // vA: destination and source
219  // vB: amount to shift
220  // vC: TypeSize
221  kMirOpPackedShiftLeft,
222
223  // @brief Packed signed shift right of units in two vector registers: vB = vB .>> vC using vA to know the type of the vector.
224  // vA: destination and source
225  // vB: amount to shift
226  // vC: TypeSize
227  kMirOpPackedSignedShiftRight,
228
229  // @brief Packed unsigned shift right of units in two vector registers: vB = vB .>>> vC using vA to know the type of the vector.
230  // vA: destination and source
231  // vB: amount to shift
232  // vC: TypeSize
233  kMirOpPackedUnsignedShiftRight,
234
235  // @brief Packed bitwise and of units in two vector registers: vB = vB .& vC using vA to know the type of the vector.
236  // vA: destination and source
237  // vB: source
238  // vC: TypeSize
239  kMirOpPackedAnd,
240
241  // @brief Packed bitwise or of units in two vector registers: vB = vB .| vC using vA to know the type of the vector.
242  // vA: destination and source
243  // vB: source
244  // vC: TypeSize
245  kMirOpPackedOr,
246
247  // @brief Packed bitwise xor of units in two vector registers: vB = vB .^ vC using vA to know the type of the vector.
248  // vA: destination and source
249  // vB: source
250  // vC: TypeSize
251  kMirOpPackedXor,
252
253  // @brief Reduce a 128-bit packed element into a single VR by taking lower bits
254  // @details Instruction does a horizontal addition of the packed elements and then adds it to VR
255  // vA: destination and source VR (not vector register)
256  // vB: source (vector register)
257  // vC: TypeSize
258  kMirOpPackedAddReduce,
259
260  // @brief Extract a packed element into a single VR.
261  // vA: destination VR (not vector register)
262  // vB: source (vector register)
263  // vC: TypeSize
264  // arg[0]: The index to use for extraction from vector register (which packed element)
265  kMirOpPackedReduce,
266
267  // @brief Create a vector value, with all TypeSize values equal to vC
268  // vA: destination vector register
269  // vB: source VR (not vector register)
270  // vC: TypeSize
271  kMirOpPackedSet,
272
273  // @brief Reserve a range of vector registers.
274  // vA: Start vector register to reserve.
275  // vB: Inclusive end vector register to reserve.
276  // @note: The backend may choose to map vector numbers used in vector opcodes.
277  //  Reserved registers are removed from the list of backend temporary pool.
278  kMirOpReserveVectorRegisters,
279
280  // @brief Free a range of reserved vector registers
281  // vA: Start vector register to unreserve.
282  // vB: Inclusive end vector register to unreserve.
283  // @note: All currently reserved vector registers are returned to the temporary pool.
284  kMirOpReturnVectorRegisters,
285
286  // @brief Create a memory barrier.
287  // vA: a constant defined by enum MemBarrierKind.
288  kMirOpMemBarrier,
289
290  // @brief Used to fill a vector register with array values.
291  // @details Just as with normal arrays, access on null object register must ensure NullPointerException
292  // and invalid index must ensure ArrayIndexOutOfBoundsException. Exception behavior must be the same
293  // as the aget it replaced and must happen at same index. Therefore, it is generally recommended that
294  // before using this MIR, it is proven that exception is guaranteed to not be thrown and marked with
295  // MIR_IGNORE_NULL_CHECK and MIR_IGNORE_RANGE_CHECK.
296  // vA: destination vector register
297  // vB: array register
298  // vC: index register
299  // arg[0]: TypeSize (most other vector opcodes have this in vC)
300  kMirOpPackedArrayGet,
301
302  // @brief Used to store a vector register into array.
303  // @details Just as with normal arrays, access on null object register must ensure NullPointerException
304  // and invalid index must ensure ArrayIndexOutOfBoundsException. Exception behavior must be the same
305  // as the aget it replaced and must happen at same index. Therefore, it is generally recommended that
306  // before using this MIR, it is proven that exception is guaranteed to not be thrown and marked with
307  // MIR_IGNORE_NULL_CHECK and MIR_IGNORE_RANGE_CHECK.
308  // vA: source vector register
309  // vB: array register
310  // vC: index register
311  // arg[0]: TypeSize (most other vector opcodes have this in vC)
312  kMirOpPackedArrayPut,
313
314  kMirOpLast,
315};
316
317enum MIROptimizationFlagPositions {
318  kMIRIgnoreNullCheck = 0,
319  kMIRNullCheckOnly,
320  kMIRIgnoreRangeCheck,
321  kMIRRangeCheckOnly,
322  kMIRClassIsInitialized,
323  kMIRClassIsInDexCache,
324  kMirIgnoreDivZeroCheck,
325  kMIRInlined,                        // Invoke is inlined (ie dead).
326  kMIRInlinedPred,                    // Invoke is inlined via prediction.
327  kMIRCallee,                         // Instruction is inlined from callee.
328  kMIRIgnoreSuspendCheck,
329  kMIRDup,
330  kMIRMark,                           // Temporary node mark can be used by
331                                      // opt passes for their private needs.
332  kMIRStoreNonTemporal,
333  kMIRLastMIRFlag,
334};
335
336// For successor_block_list.
337enum BlockListType {
338  kNotUsed = 0,
339  kCatch,
340  kPackedSwitch,
341  kSparseSwitch,
342};
343std::ostream& operator<<(std::ostream& os, const BlockListType& rhs);
344
345enum AssemblerStatus {
346  kSuccess,
347  kRetryAll,
348};
349std::ostream& operator<<(std::ostream& os, const AssemblerStatus& rhs);
350
351enum OpSize {
352  kWord,            // Natural word size of target (32/64).
353  k32,
354  k64,
355  kReference,       // Object reference; compressed on 64-bit targets.
356  kSingle,
357  kDouble,
358  kUnsignedHalf,
359  kSignedHalf,
360  kUnsignedByte,
361  kSignedByte,
362};
363std::ostream& operator<<(std::ostream& os, const OpSize& kind);
364
365enum OpKind {
366  kOpMov,
367  kOpCmov,
368  kOpMvn,
369  kOpCmp,
370  kOpLsl,
371  kOpLsr,
372  kOpAsr,
373  kOpRor,
374  kOpNot,
375  kOpAnd,
376  kOpOr,
377  kOpXor,
378  kOpNeg,
379  kOpAdd,
380  kOpAdc,
381  kOpSub,
382  kOpSbc,
383  kOpRsub,
384  kOpMul,
385  kOpDiv,
386  kOpRem,
387  kOpBic,
388  kOpCmn,
389  kOpTst,
390  kOpRev,
391  kOpRevsh,
392  kOpBkpt,
393  kOpBlx,
394  kOpPush,
395  kOpPop,
396  kOp2Char,
397  kOp2Short,
398  kOp2Byte,
399  kOpCondBr,
400  kOpUncondBr,
401  kOpBx,
402  kOpInvalid,
403};
404std::ostream& operator<<(std::ostream& os, const OpKind& rhs);
405
406enum MoveType {
407  kMov8GP,      // Move 8-bit general purpose register.
408  kMov16GP,     // Move 16-bit general purpose register.
409  kMov32GP,     // Move 32-bit general purpose register.
410  kMov64GP,     // Move 64-bit general purpose register.
411  kMov32FP,     // Move 32-bit FP register.
412  kMov64FP,     // Move 64-bit FP register.
413  kMovLo64FP,   // Move low 32-bits of 64-bit FP register.
414  kMovHi64FP,   // Move high 32-bits of 64-bit FP register.
415  kMovU128FP,   // Move 128-bit FP register to/from possibly unaligned region.
416  kMov128FP = kMovU128FP,
417  kMovA128FP,   // Move 128-bit FP register to/from region surely aligned to 16-bytes.
418  kMovLo128FP,  // Move low 64-bits of 128-bit FP register.
419  kMovHi128FP,  // Move high 64-bits of 128-bit FP register.
420};
421std::ostream& operator<<(std::ostream& os, const MoveType& kind);
422
423enum ConditionCode {
424  kCondEq,  // equal
425  kCondNe,  // not equal
426  kCondCs,  // carry set
427  kCondCc,  // carry clear
428  kCondUlt,  // unsigned less than
429  kCondUge,  // unsigned greater than or same
430  kCondMi,  // minus
431  kCondPl,  // plus, positive or zero
432  kCondVs,  // overflow
433  kCondVc,  // no overflow
434  kCondHi,  // unsigned greater than
435  kCondLs,  // unsigned lower or same
436  kCondGe,  // signed greater than or equal
437  kCondLt,  // signed less than
438  kCondGt,  // signed greater than
439  kCondLe,  // signed less than or equal
440  kCondAl,  // always
441  kCondNv,  // never
442};
443std::ostream& operator<<(std::ostream& os, const ConditionCode& kind);
444
445// Target specific condition encodings
446enum ArmConditionCode {
447  kArmCondEq = 0x0,  // 0000
448  kArmCondNe = 0x1,  // 0001
449  kArmCondCs = 0x2,  // 0010
450  kArmCondCc = 0x3,  // 0011
451  kArmCondMi = 0x4,  // 0100
452  kArmCondPl = 0x5,  // 0101
453  kArmCondVs = 0x6,  // 0110
454  kArmCondVc = 0x7,  // 0111
455  kArmCondHi = 0x8,  // 1000
456  kArmCondLs = 0x9,  // 1001
457  kArmCondGe = 0xa,  // 1010
458  kArmCondLt = 0xb,  // 1011
459  kArmCondGt = 0xc,  // 1100
460  kArmCondLe = 0xd,  // 1101
461  kArmCondAl = 0xe,  // 1110
462  kArmCondNv = 0xf,  // 1111
463};
464std::ostream& operator<<(std::ostream& os, const ArmConditionCode& kind);
465
466enum X86ConditionCode {
467  kX86CondO   = 0x0,    // overflow
468  kX86CondNo  = 0x1,    // not overflow
469
470  kX86CondB   = 0x2,    // below
471  kX86CondNae = kX86CondB,  // not-above-equal
472  kX86CondC   = kX86CondB,  // carry
473
474  kX86CondNb  = 0x3,    // not-below
475  kX86CondAe  = kX86CondNb,  // above-equal
476  kX86CondNc  = kX86CondNb,  // not-carry
477
478  kX86CondZ   = 0x4,    // zero
479  kX86CondEq  = kX86CondZ,  // equal
480
481  kX86CondNz  = 0x5,    // not-zero
482  kX86CondNe  = kX86CondNz,  // not-equal
483
484  kX86CondBe  = 0x6,    // below-equal
485  kX86CondNa  = kX86CondBe,  // not-above
486
487  kX86CondNbe = 0x7,    // not-below-equal
488  kX86CondA   = kX86CondNbe,  // above
489
490  kX86CondS   = 0x8,    // sign
491  kX86CondNs  = 0x9,    // not-sign
492
493  kX86CondP   = 0xa,    // 8-bit parity even
494  kX86CondPE  = kX86CondP,
495
496  kX86CondNp  = 0xb,    // 8-bit parity odd
497  kX86CondPo  = kX86CondNp,
498
499  kX86CondL   = 0xc,    // less-than
500  kX86CondNge = kX86CondL,  // not-greater-equal
501
502  kX86CondNl  = 0xd,    // not-less-than
503  kX86CondGe  = kX86CondNl,  // not-greater-equal
504
505  kX86CondLe  = 0xe,    // less-than-equal
506  kX86CondNg  = kX86CondLe,  // not-greater
507
508  kX86CondNle = 0xf,    // not-less-than
509  kX86CondG   = kX86CondNle,  // greater
510};
511std::ostream& operator<<(std::ostream& os, const X86ConditionCode& kind);
512
513enum DividePattern {
514  DivideNone,
515  Divide3,
516  Divide5,
517  Divide7,
518};
519std::ostream& operator<<(std::ostream& os, const DividePattern& pattern);
520
521/**
522 * @brief Memory barrier types (see "The JSR-133 Cookbook for Compiler Writers").
523 * @details We define the combined barrier types that are actually required
524 * by the Java Memory Model, rather than using exactly the terminology from
525 * the JSR-133 cookbook.  These should, in many cases, be replaced by acquire/release
526 * primitives.  Note that the JSR-133 cookbook generally does not deal with
527 * store atomicity issues, and the recipes there are not always entirely sufficient.
528 * The current recipe is as follows:
529 * -# Use AnyStore ~= (LoadStore | StoreStore) ~= release barrier before volatile store.
530 * -# Use AnyAny barrier after volatile store.  (StoreLoad is as expensive.)
531 * -# Use LoadAny barrier ~= (LoadLoad | LoadStore) ~= acquire barrierafter each volatile load.
532 * -# Use StoreStore barrier after all stores but before return from any constructor whose
533 *    class has final fields.
534 * -# Use NTStoreStore to order non-temporal stores with respect to all later
535 *    store-to-memory instructions.  Only generated together with non-temporal stores.
536 */
537enum MemBarrierKind {
538  kAnyStore,
539  kLoadAny,
540  kStoreStore,
541  kAnyAny,
542  kNTStoreStore,
543};
544std::ostream& operator<<(std::ostream& os, const MemBarrierKind& kind);
545
546enum OpFeatureFlags {
547  kIsBranch = 0,
548  kNoOperand,
549  kIsUnaryOp,
550  kIsBinaryOp,
551  kIsTertiaryOp,
552  kIsQuadOp,
553  kIsQuinOp,
554  kIsSextupleOp,
555  kIsIT,
556  kIsMoveOp,
557  kMemLoad,
558  kMemStore,
559  kMemVolatile,
560  kMemScaledx0,
561  kMemScaledx2,
562  kMemScaledx4,
563  kPCRelFixup,  // x86 FIXME: add NEEDS_FIXUP to instruction attributes.
564  kRegDef0,
565  kRegDef1,
566  kRegDef2,
567  kRegDefA,
568  kRegDefD,
569  kRegDefFPCSList0,
570  kRegDefFPCSList2,
571  kRegDefList0,
572  kRegDefList1,
573  kRegDefList2,
574  kRegDefLR,
575  kRegDefSP,
576  kRegUse0,
577  kRegUse1,
578  kRegUse2,
579  kRegUse3,
580  kRegUse4,
581  kRegUseA,
582  kRegUseC,
583  kRegUseD,
584  kRegUseB,
585  kRegUseFPCSList0,
586  kRegUseFPCSList2,
587  kRegUseList0,
588  kRegUseList1,
589  kRegUseLR,
590  kRegUsePC,
591  kRegUseSP,
592  kSetsCCodes,
593  kUsesCCodes,
594  kUseFpStack,
595  kUseHi,
596  kUseLo,
597  kDefHi,
598  kDefLo
599};
600std::ostream& operator<<(std::ostream& os, const OpFeatureFlags& rhs);
601
602enum SelectInstructionKind {
603  kSelectNone,
604  kSelectConst,
605  kSelectMove,
606  kSelectGoto
607};
608std::ostream& operator<<(std::ostream& os, const SelectInstructionKind& kind);
609
610// LIR fixup kinds for Arm
611enum FixupKind {
612  kFixupNone,
613  kFixupLabel,       // For labels we just adjust the offset.
614  kFixupLoad,        // Mostly for immediates.
615  kFixupVLoad,       // FP load which *may* be pc-relative.
616  kFixupCBxZ,        // Cbz, Cbnz.
617  kFixupTBxZ,        // Tbz, Tbnz.
618  kFixupPushPop,     // Not really pc relative, but changes size based on args.
619  kFixupCondBranch,  // Conditional branch
620  kFixupT1Branch,    // Thumb1 Unconditional branch
621  kFixupT2Branch,    // Thumb2 Unconditional branch
622  kFixupBlx1,        // Blx1 (start of Blx1/Blx2 pair).
623  kFixupBl1,         // Bl1 (start of Bl1/Bl2 pair).
624  kFixupAdr,         // Adr.
625  kFixupMovImmLST,   // kThumb2MovImm16LST.
626  kFixupMovImmHST,   // kThumb2MovImm16HST.
627  kFixupAlign4,      // Align to 4-byte boundary.
628};
629std::ostream& operator<<(std::ostream& os, const FixupKind& kind);
630
631enum VolatileKind {
632  kNotVolatile,      // Load/Store is not volatile
633  kVolatile          // Load/Store is volatile
634};
635std::ostream& operator<<(std::ostream& os, const VolatileKind& kind);
636
637enum WideKind {
638  kNotWide,      // Non-wide view
639  kWide,         // Wide view
640  kRef           // Ref width
641};
642std::ostream& operator<<(std::ostream& os, const WideKind& kind);
643
644}  // namespace art
645
646#endif  // ART_COMPILER_DEX_COMPILER_ENUMS_H_
647