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