1 // [AsmJit] 2 // Complete JIT Assembler for C++ Language. 3 // 4 // [License] 5 // Zlib - See COPYING file in this package. 6 7 // [Guard] 8 #ifndef _ASMJIT_CORE_DEFS_H 9 #define _ASMJIT_CORE_DEFS_H 10 11 // [Dependencies - AsmJit] 12 #include "../core/build.h" 13 14 // [Api-Begin] 15 #include "../core/apibegin.h" 16 17 namespace AsmJit { 18 19 //! @addtogroup AsmJit_Core 20 //! @{ 21 22 // ============================================================================ 23 // [AsmJit::Global] 24 // ============================================================================ 25 26 enum 27 { 28 //! @brief Invalid operand identifier. 29 kInvalidValue = 0xFFFFFFFFU, 30 //! @brief Minimum reserved bytes in @ref Buffer. 31 kBufferGrow = 32U 32 }; 33 34 static const size_t kInvalidSize = (size_t)-1; 35 36 // ============================================================================ 37 // [AsmJit::kStringBuilderOpType] 38 // ============================================================================ 39 40 //! @brief String builder operation. 41 enum kStringBuilderOpType 42 { 43 //! @brief Replace the current content by a given content. 44 kStringBuilderOpSet = 0, 45 //! @brief Append a given content to the current content. 46 kStringBuilderOpAppend = 1 47 }; 48 49 // ============================================================================ 50 // [AsmJit::kStringBuilderNumType] 51 // ============================================================================ 52 53 enum kStringBuilderNumFlags 54 { 55 kStringBuilderNumShowSign = (1U << 0), 56 kStringBuilderNumShowSpace = (1U << 1), 57 kStringBuilderNumAlternate = (1U << 2), 58 kStringBuilderNumSigned = (1U << 31) 59 }; 60 61 // ============================================================================ 62 // [AsmJit::kLoggerOption] 63 // ============================================================================ 64 65 enum kLoggerFlag 66 { 67 //! @brief Whether logger is enabled or disabled. 68 //! 69 //! Default @c true. 70 kLoggerIsEnabled = 0x00000001, 71 72 //! @brief Whether logger is enabled and can be used. 73 //! 74 //! This value can be set by inherited classes to inform @c Logger that 75 //! assigned stream (or something that can log output) is invalid. If 76 //! @c _used is false it means that there is no logging output and AsmJit 77 //! shouldn't use this logger (because all messages will be lost). 78 //! 79 //! This is designed only to optimize cases that logger exists, but its 80 //! configured not to output messages. The API inside Logging and AsmJit 81 //! should only check this value when needed. The API outside AsmJit should 82 //! check only whether logging is @c _enabled. 83 //! 84 //! Default @c true. 85 kLoggerIsUsed = 0x00000002, 86 87 //! @brief Whether to output instructions also in binary form. 88 kLoggerOutputBinary = 0x00000010, 89 //! @brief Whether to output immediates as hexadecimal numbers. 90 kLoggerOutputHexImmediate = 0x00000020, 91 //! @brief Whether to output displacements as hexadecimal numbers. 92 kLoggerOutputHexDisplacement = 0x00000040 93 }; 94 95 // ============================================================================ 96 // [AsmJit::kCpu] 97 // ============================================================================ 98 99 //! @brief Cpu vendor IDs. 100 //! 101 //! Cpu vendor IDs are specific for AsmJit library. Vendor ID is not directly 102 //! read from cpuid result, instead it's based on CPU vendor string. 103 enum kCpu 104 { 105 //! @brief Unknown CPU vendor. 106 kCpuUnknown = 0, 107 108 //! @brief Intel CPU vendor. 109 kCpuIntel = 1, 110 //! @brief AMD CPU vendor. 111 kCpuAmd = 2, 112 //! @brief National Semiconductor CPU vendor (applies also to Cyrix processors). 113 kCpuNSM = 3, 114 //! @brief Transmeta CPU vendor. 115 kCpuTransmeta = 4, 116 //! @brief VIA CPU vendor. 117 kCpuVia = 5 118 }; 119 120 // ============================================================================ 121 // [AsmJit::kMemAllocType] 122 // ============================================================================ 123 124 //! @brief Types of allocation used by @c AsmJit::MemoryManager::alloc() method. 125 enum kMemAllocType 126 { 127 //! @brief Allocate memory that can be freed by @c AsmJit::MemoryManager::free() 128 //! method. 129 kMemAllocFreeable = 0, 130 //! @brief Allocate permanent memory that will be never freed. 131 kMemAllocPermanent = 1 132 }; 133 134 // ============================================================================ 135 // [AsmJit::kOperandType] 136 // ============================================================================ 137 138 //! @brief Operand types that can be encoded in @c Op operand. 139 enum kOperandType 140 { 141 //! @brief Operand is none, used only internally (not initialized Operand). 142 //! 143 //! This operand is not valid. 144 kOperandNone = 0x00, 145 //! @brief Operand is label. 146 kOperandLabel = 0x01, 147 //! @brief Operand is register. 148 kOperandReg = 0x02, 149 //! @brief Operand is variable. 150 kOperandVar = 0x04, 151 //! @brief Operand is memory. 152 kOperandMem = 0x08, 153 //! @brief Operand is immediate. 154 kOperandImm = 0x10 155 }; 156 157 // ============================================================================ 158 // [AsmJit::kOperandMemType] 159 // ============================================================================ 160 161 //! @brief Type of memory operand. 162 enum kOperandMemType 163 { 164 //! @brief Operand is combination of register(s) and displacement (native). 165 kOperandMemNative = 0, 166 //! @brief Operand is label. 167 kOperandMemLabel = 1, 168 //! @brief Operand is absolute memory location (supported mainly in 32-bit mode) 169 kOperandMemAbsolute = 2, 170 }; 171 172 // ============================================================================ 173 // [AsmJit::kOperandId] 174 // ============================================================================ 175 176 //! @brief Operand ID masks used to determine the operand type. 177 enum kOperandId 178 { 179 //! @brief Operand id type mask (part used for operand type). 180 kOperandIdTypeMask = 0xC0000000, 181 //! @brief Label operand mark id. 182 kOperandIdTypeLabel = 0x40000000, 183 //! @brief Variable operand mark id. 184 kOperandIdTypeVar = 0x80000000, 185 186 //! @brief Operand id value mask (part used for IDs). 187 kOperandIdValueMask = 0x3FFFFFFF 188 }; 189 190 // ============================================================================ 191 // [AsmJit::kRegType / kRegIndex] 192 // ============================================================================ 193 194 enum 195 { 196 //! @brief Mask for register type. 197 kRegTypeMask = 0xFF00, 198 199 //! @brief Mask for register code (index). 200 kRegIndexMask = 0xFF, 201 //! @brief Invalid register index. 202 kRegIndexInvalid = 0xFF 203 }; 204 205 // ============================================================================ 206 // [AsmJit::kCondHint] 207 // ============================================================================ 208 209 //! @brief Condition hint. 210 enum kCondHint 211 { 212 //! @brief No hint. 213 kCondHintNone = 0x00, 214 //! @brief Condition is likely to be taken. 215 kCondHintLikely = 0x01, 216 //! @brief Condition is unlikely to be taken. 217 kCondHintUnlikely = 0x02 218 }; 219 220 // ============================================================================ 221 // [AsmJit::kFuncAnonymous] 222 // ============================================================================ 223 224 enum 225 { 226 //! @brief Maximum allowed arguments per function declaration / call. 227 kFuncArgsMax = 32, 228 //! @brief Invalid stack offset in function or function parameter. 229 kFuncStackInvalid = -1 230 }; 231 232 // ============================================================================ 233 // [AsmJit::kFuncConv] 234 // ============================================================================ 235 236 enum kFuncConv 237 { 238 //! @brief Calling convention is invalid (can't be used). 239 kFuncConvNone = 0 240 }; 241 242 // ============================================================================ 243 // [AsmJit::kFuncHint] 244 // ============================================================================ 245 246 //! @brief Function hints. 247 enum kFuncHint 248 { 249 //! @brief Make naked function (without using ebp/erp in prolog / epilog). 250 kFuncHintNaked = 0 251 }; 252 253 // ============================================================================ 254 // [AsmJit::kFuncFlags] 255 // ============================================================================ 256 257 //! @brief Function flags. 258 enum kFuncFlags 259 { 260 //! @brief Whether another function is called from this function. 261 //! 262 //! If another function is called from this function, it's needed to prepare 263 //! stack for it. If this member is true then it's likely that true will be 264 //! also @c _isEspAdjusted one. 265 kFuncFlagIsCaller = (1U << 0), 266 267 //! @brief Whether the function is finished using @c Compiler::endFunc(). 268 kFuncFlagIsFinished = (1U << 1), 269 270 //! @brief Whether the function is using naked (minimal) prolog / epilog. 271 kFuncFlagIsNaked = (1U << 2) 272 }; 273 274 // ============================================================================ 275 // [AsmJit::kFuncArgsDirection] 276 // ============================================================================ 277 278 //! @brief Function arguments direction. 279 enum kFuncArgsDirection 280 { 281 //! @brief Arguments are passed left to right. 282 //! 283 //! This arguments direction is unusual to C programming, it's used by pascal 284 //! compilers and in some calling conventions by Borland compiler). 285 kFuncArgsLTR = 0, 286 //! @brief Arguments are passed right ro left 287 //! 288 //! This is default argument direction in C programming. 289 kFuncArgsRTL = 1 290 }; 291 292 // ============================================================================ 293 // [AsmJit::kInstCode] 294 // ============================================================================ 295 296 enum kInstCode 297 { 298 //! @brief No instruction. 299 kInstNone = 0 300 }; 301 302 // ============================================================================ 303 // [AsmJit::kVarAllocFlags] 304 // ============================================================================ 305 306 //! @brief Variable alloc mode. 307 enum kVarAllocFlags 308 { 309 //! @brief Allocating variable to read only. 310 //! 311 //! Read only variables are used to optimize variable spilling. If variable 312 //! is some time ago deallocated and it's not marked as changed (so it was 313 //! all the life time read only) then spill is simply NOP (no mov instruction 314 //! is generated to move it to it's home memory location). 315 kVarAllocRead = 0x01, 316 //! @brief Allocating variable to write only (overwrite). 317 //! 318 //! Overwriting means that if variable is in memory, there is no generated 319 //! instruction to move variable from memory to register, because that 320 //! register will be overwritten by next instruction. This is used as a 321 //! simple optimization to improve generated code by @c Compiler. 322 kVarAllocWrite = 0x02, 323 //! @brief Allocating variable to read / write. 324 //! 325 //! Variable allocated for read / write is marked as changed. This means that 326 //! if variable must be later spilled into memory, mov (or similar) 327 //! instruction will be generated. 328 kVarAllocReadWrite = 0x03, 329 330 //! @brief Variable can be allocated in register. 331 kVarAllocRegister = 0x04, 332 //! @brief Variable can be allocated only to a special register. 333 kVarAllocSpecial = 0x08, 334 335 //! @brief Variable can be allocated in memory. 336 kVarAllocMem = 0x10, 337 338 //! @brief Unuse the variable after use. 339 kVarAllocUnuseAfterUse = 0x20 340 }; 341 342 // ============================================================================ 343 // [AsmJit::kVarHint] 344 // ============================================================================ 345 346 //! @brief Variable hint (used by @ref Compiler). 347 //! 348 //! @sa @ref Compiler. 349 enum kVarHint 350 { 351 //! @brief Alloc variable. 352 kVarHintAlloc = 0, 353 //! @brief Spill variable. 354 kVarHintSpill = 1, 355 //! @brief Save variable if modified. 356 kVarHintSave = 2, 357 //! @brief Save variable if modified and mark it as unused. 358 kVarHintSaveAndUnuse = 3, 359 //! @brief Mark variable as unused. 360 kVarHintUnuse = 4 361 }; 362 363 // ============================================================================ 364 // [AsmJit::kVarPolicy] 365 // ============================================================================ 366 367 //! @brief Variable allocation method. 368 //! 369 //! Variable allocation method is used by compiler and it means if compiler 370 //! should first allocate preserved registers or not. Preserved registers are 371 //! registers that must be saved / restored by generated function. 372 //! 373 //! This option is for people who are calling C/C++ functions from JIT code so 374 //! Compiler can recude generating push/pop sequences before and after call, 375 //! respectively. 376 enum kVarPolicy 377 { 378 //! @brief Allocate preserved registers first. 379 kVarPolicyPreservedFirst = 0, 380 //! @brief Allocate preserved registers last (default). 381 kVarPolicyPreservedLast = 1 382 }; 383 384 // ============================================================================ 385 // [AsmJit::kVarState] 386 // ============================================================================ 387 388 //! @brief State of variable. 389 //! 390 //! @note State of variable is used only during make process and it's not 391 //! visible to the developer. 392 enum kVarState 393 { 394 //! @brief Variable is currently not used. 395 kVarStateUnused = 0, 396 //! @brief Variable is in register. 397 //! 398 //! Variable is currently allocated in register. 399 kVarStateReg = 1, 400 //! @brief Variable is in memory location or spilled. 401 //! 402 //! Variable was spilled from register to memory or variable is used for 403 //! memory only storage. 404 kVarStateMem = 2 405 }; 406 407 // ============================================================================ 408 // [AsmJit::kVarType] 409 // ============================================================================ 410 411 enum kVarType 412 { 413 //! @brief Invalid variable type. 414 kVarTypeInvalid = 0xFF 415 }; 416 417 // ============================================================================ 418 // [AsmJit::kScale] 419 // ============================================================================ 420 421 //! @brief Scale which can be used for addressing (it the target instruction 422 //! supports it). 423 //! 424 //! See @c Op and addressing methods like @c byte_ptr(), @c word_ptr(), 425 //! @c dword_ptr(), etc... 426 enum kScale 427 { 428 //! @brief No scale. 429 kScaleNone = 0, 430 //! @brief Scale 2 times (same as shifting to left by 1). 431 kScale2Times = 1, 432 //! @brief Scale 4 times (same as shifting to left by 2). 433 kScale4Times = 2, 434 //! @brief Scale 8 times (same as shifting to left by 3). 435 kScale8Times = 3 436 }; 437 438 // ============================================================================ 439 // [AsmJit::kSize] 440 // ============================================================================ 441 442 //! @brief Size of registers and pointers. 443 enum kSize 444 { 445 //! @brief 1 byte size. 446 kSizeByte = 1, 447 //! @brief 2 bytes size. 448 kSizeWord = 2, 449 //! @brief 4 bytes size. 450 kSizeDWord = 4, 451 //! @brief 8 bytes size. 452 kSizeQWord = 8, 453 //! @brief 10 bytes size. 454 kSizeTWord = 10, 455 //! @brief 16 bytes size. 456 kSizeDQWord = 16 457 }; 458 459 // ============================================================================ 460 // [AsmJit::kRelocMode] 461 // ============================================================================ 462 463 enum kRelocMode 464 { 465 kRelocAbsToAbs = 0, 466 kRelocRelToAbs = 1, 467 kRelocAbsToRel = 2, 468 kRelocTrampoline = 3 469 }; 470 471 // ============================================================================ 472 // [AsmJit::kCompilerItem] 473 // ============================================================================ 474 475 //! @brief Type of @ref CompilerItem. 476 //! 477 //! Each @c CompilerItem contains information about its type. Compiler can 478 //! optimize instruction stream by analyzing items and each type is hint 479 //! for it. The most used/serialized items are instructions 480 //! (@c kCompilerItemInst). 481 enum kCompilerItem 482 { 483 //! @brief Invalid item (can't be used). 484 kCompilerItemNone = 0, 485 //! @brief Item is mark, see @ref CompilerMark. 486 kCompilerItemMark, 487 //! @brief Item is comment, see @ref CompilerComment. 488 kCompilerItemComment, 489 //! @brief Item is embedded data, see @ref CompilerEmbed. 490 kCompilerItemEmbed, 491 //! @brief Item is .align directive, see @ref CompilerAlign. 492 kCompilerItemAlign, 493 //! @brief Item is variable hint (alloc, spill, use, unuse), see @ref CompilerHint. 494 kCompilerItemHint, 495 //! @brief Item is instruction, see @ref CompilerInst. 496 kCompilerItemInst, 497 //! @brief Item is target, see @ref CompilerTarget. 498 kCompilerItemTarget, 499 //! @brief Item is function call, see @ref CompilerFuncCall. 500 kCompilerItemFuncCall, 501 //! @brief Item is function declaration, see @ref CompilerFuncDecl. 502 kCompilerItemFuncDecl, 503 //! @brief Item is an end of the function, see @ref CompilerFuncEnd. 504 kCompilerItemFuncEnd, 505 //! @brief Item is function return, see @ref CompilerFuncRet. 506 kCompilerItemFuncRet 507 }; 508 509 // ============================================================================ 510 // [AsmJit::kError] 511 // ============================================================================ 512 513 //! @brief Error codes. 514 enum kError 515 { 516 //! @brief No error (success). 517 //! 518 //! This is default state and state you want. 519 kErrorOk = 0, 520 521 //! @brief Memory allocation error (@c ASMJIT_MALLOC returned @c NULL). 522 kErrorNoHeapMemory = 1, 523 //! @brief Virtual memory allocation error (@c VirtualMemory returned @c NULL). 524 kErrorNoVirtualMemory = 2, 525 526 //! @brief Unknown instruction. This happens only if instruction code is 527 //! out of bounds. Shouldn't happen. 528 kErrorUnknownInstruction = 3, 529 //! @brief Illegal instruction, usually generated by AsmJit::Assembler 530 //! class when emitting instruction opcode. If this error is generated the 531 //! target buffer is not affected by this invalid instruction. 532 //! 533 //! You can also get this error code if you are under x64 (64-bit x86) and 534 //! you tried to decode instruction using AH, BH, CH or DH register with REX 535 //! prefix. These registers can't be accessed if REX prefix is used and AsmJit 536 //! didn't check for this situation in intrinsics (@c Compiler takes care of 537 //! this and rearrange registers if needed). 538 //! 539 //! Examples that will raise @c kErrorIllegalInstruction error (a is 540 //! @c Assembler instance): 541 //! 542 //! @code 543 //! a.mov(dword_ptr(eax), al); // Invalid address size. 544 //! a.mov(byte_ptr(r10), ah); // Undecodable instruction (AH used with r10 545 //! // which can be encoded only using REX prefix) 546 //! @endcode 547 //! 548 //! @note In debug mode you get assertion failure instead of setting error 549 //! code. 550 kErrorIllegalInstruction = 4, 551 //! @brief Illegal addressing used (unencodable). 552 kErrorIllegalAddressing = 5, 553 //! @brief Short jump instruction used, but displacement is out of bounds. 554 kErrorIllegalShortJump = 6, 555 556 //! @brief No function defined. 557 kErrorNoFunction = 7, 558 //! @brief Function generation is not finished by using @c Compiler::endFunc() 559 //! or something bad happened during generation related to function. This can 560 //! be missing compiler item, etc... 561 kErrorIncompleteFunction = 8, 562 563 //! @brief Compiler can't allocate registers, because all of them are used. 564 //! 565 //! @note AsmJit is able to spill registers so this error really shouldn't 566 //! happen unless all registers have priority 0 (which means never spill). 567 kErrorNoRegisters = 9, 568 //! @brief Compiler can't allocate one register to multiple destinations. 569 //! 570 //! This error can only happen using special instructions like cmpxchg8b and 571 //! others where there are more destination operands (implicit). 572 kErrorOverlappedRegisters = 10, 573 574 //! @brief Tried to call function using incompatible argument. 575 kErrorIncompatibleArgumentType = 11, 576 //! @brief Incompatible return value. 577 kErrorIncompatibleReturnType = 12, 578 579 //! @brief Count of error codes by AsmJit. Can grow in future. 580 kErrorCount 581 }; 582 583 // ============================================================================ 584 // [AsmJit::API] 585 // ============================================================================ 586 587 //! @brief Translates error code (see @c kError) into text representation. 588 ASMJIT_API const char* getErrorString(uint32_t error); 589 590 //! @} 591 592 } // AsmJit namespace 593 594 // [Api-End] 595 #include "../core/apiend.h" 596 597 // [Guard] 598 #endif // _ASMJIT_CORE_DEFS_H 599