/* ----------------------------------------------------------------------- * * * Copyright 1996-2012 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ----------------------------------------------------------------------- */ /* * opflags.h - operand flags */ #ifndef NASM_OPFLAGS_H #define NASM_OPFLAGS_H #include "compiler.h" /* * Here we define the operand types. These are implemented as bit * masks, since some are subsets of others; e.g. AX in a MOV * instruction is a special operand type, whereas AX in other * contexts is just another 16-bit register. (Also, consider CL in * shift instructions, DX in OUT, etc.) * * The basic concept here is that * (class & ~operand) == 0 * * if and only if "operand" belongs to class type "class". */ typedef uint64_t opflags_t; #define OP_GENMASK(bits, shift) (((UINT64_C(1) << (bits)) - 1) << (shift)) #define OP_GENBIT(bit, shift) (UINT64_C(1) << ((shift) + (bit))) /* * Type of operand: memory reference, register, etc. * * Bits: 0 - 3 */ #define OPTYPE_SHIFT (0) #define OPTYPE_BITS (4) #define OPTYPE_MASK OP_GENMASK(OPTYPE_BITS, OPTYPE_SHIFT) #define GEN_OPTYPE(bit) OP_GENBIT(bit, OPTYPE_SHIFT) /* * Modifiers. * * Bits: 4 - 6 */ #define MODIFIER_SHIFT (4) #define MODIFIER_BITS (3) #define MODIFIER_MASK OP_GENMASK(MODIFIER_BITS, MODIFIER_SHIFT) #define GEN_MODIFIER(bit) OP_GENBIT(bit, MODIFIER_SHIFT) /* * Register classes. * * Bits: 7 - 16 */ #define REG_CLASS_SHIFT (7) #define REG_CLASS_BITS (10) #define REG_CLASS_MASK OP_GENMASK(REG_CLASS_BITS, REG_CLASS_SHIFT) #define GEN_REG_CLASS(bit) OP_GENBIT(bit, REG_CLASS_SHIFT) /* * Subclasses. Depends on type of operand. * * Bits: 17 - 24 */ #define SUBCLASS_SHIFT (17) #define SUBCLASS_BITS (8) #define SUBCLASS_MASK OP_GENMASK(SUBCLASS_BITS, SUBCLASS_SHIFT) #define GEN_SUBCLASS(bit) OP_GENBIT(bit, SUBCLASS_SHIFT) /* * Special flags. Context dependant. * * Bits: 25 - 31 */ #define SPECIAL_SHIFT (25) #define SPECIAL_BITS (7) #define SPECIAL_MASK OP_GENMASK(SPECIAL_BITS, SPECIAL_SHIFT) #define GEN_SPECIAL(bit) OP_GENBIT(bit, SPECIAL_SHIFT) /* * Sizes of the operands and attributes. * * Bits: 32 - 42 */ #define SIZE_SHIFT (32) #define SIZE_BITS (11) #define SIZE_MASK OP_GENMASK(SIZE_BITS, SIZE_SHIFT) #define GEN_SIZE(bit) OP_GENBIT(bit, SIZE_SHIFT) /* * Bits distribution (counted from 0) * * 6 5 4 3 2 1 * 3210987654321098765432109876543210987654321098765432109876543210 * | * | dword bound * * ............................................................1111 optypes * .........................................................111.... modifiers * ...............................................1111111111....... register classes * .......................................11111111................. subclasses * ................................1111111......................... specials * .....................11111111111................................ sizes */ #define REGISTER GEN_OPTYPE(0) /* register number in 'basereg' */ #define IMMEDIATE GEN_OPTYPE(1) #define REGMEM GEN_OPTYPE(2) /* for r/m, ie EA, operands */ #define MEMORY (GEN_OPTYPE(3) | REGMEM) #define BITS8 GEN_SIZE(0) /* 8 bits (BYTE) */ #define BITS16 GEN_SIZE(1) /* 16 bits (WORD) */ #define BITS32 GEN_SIZE(2) /* 32 bits (DWORD) */ #define BITS64 GEN_SIZE(3) /* 64 bits (QWORD), x64 and FPU only */ #define BITS80 GEN_SIZE(4) /* 80 bits (TWORD), FPU only */ #define BITS128 GEN_SIZE(5) /* 128 bits (OWORD) */ #define BITS256 GEN_SIZE(6) /* 256 bits (YWORD) */ #define BITS512 GEN_SIZE(7) /* 512 bits (ZWORD) */ #define FAR GEN_SIZE(8) /* grotty: this means 16:16 or 16:32, like in CALL/JMP */ #define NEAR GEN_SIZE(9) #define SHORT GEN_SIZE(10) /* and this means what it says :) */ #define TO GEN_MODIFIER(0) /* reverse effect in FADD, FSUB &c */ #define COLON GEN_MODIFIER(1) /* operand is followed by a colon */ #define STRICT GEN_MODIFIER(2) /* do not optimize this operand */ #define REG_CLASS_CDT GEN_REG_CLASS(0) #define REG_CLASS_GPR GEN_REG_CLASS(1) #define REG_CLASS_SREG GEN_REG_CLASS(2) #define REG_CLASS_FPUREG GEN_REG_CLASS(3) #define REG_CLASS_RM_MMX GEN_REG_CLASS(4) #define REG_CLASS_RM_XMM GEN_REG_CLASS(5) #define REG_CLASS_RM_YMM GEN_REG_CLASS(6) #define is_class(class, op) (!((opflags_t)(class) & ~(opflags_t)(op))) #define IS_SREG(op) is_class(REG_SREG, nasm_reg_flags[(op)]) #define IS_FSGS(op) is_class(REG_FSGS, nasm_reg_flags[(op)]) /* Register classes */ #define REG_EA ( REGMEM | REGISTER) /* 'normal' reg, qualifies as EA */ #define RM_GPR ( REG_CLASS_GPR | REGMEM) /* integer operand */ #define REG_GPR ( REG_CLASS_GPR | REGMEM | REGISTER) /* integer register */ #define REG8 ( REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) /* 8-bit GPR */ #define REG16 ( REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) /* 16-bit GPR */ #define REG32 ( REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) /* 32-bit GPR */ #define REG64 ( REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) /* 64-bit GPR */ #define FPUREG ( REG_CLASS_FPUREG | REGISTER) /* floating point stack registers */ #define FPU0 (GEN_SUBCLASS(1) | REG_CLASS_FPUREG | REGISTER) /* FPU stack register zero */ #define RM_MMX ( REG_CLASS_RM_MMX | REGMEM) /* MMX operand */ #define MMXREG ( REG_CLASS_RM_MMX | REGMEM | REGISTER) /* MMX register */ #define RM_XMM ( REG_CLASS_RM_XMM | REGMEM) /* XMM (SSE) operand */ #define XMMREG ( REG_CLASS_RM_XMM | REGMEM | REGISTER) /* XMM (SSE) register */ #define XMM0 (GEN_SUBCLASS(1) | REG_CLASS_RM_XMM | REGMEM | REGISTER) /* XMM register zero */ #define RM_YMM ( REG_CLASS_RM_YMM | REGMEM) /* YMM (AVX) operand */ #define YMMREG ( REG_CLASS_RM_YMM | REGMEM | REGISTER) /* YMM (AVX) register */ #define YMM0 (GEN_SUBCLASS(1) | REG_CLASS_RM_YMM | REGMEM | REGISTER) /* YMM register zero */ #define REG_CDT ( REG_CLASS_CDT | BITS32 | REGISTER) /* CRn, DRn and TRn */ #define REG_CREG (GEN_SUBCLASS(1) | REG_CLASS_CDT | BITS32 | REGISTER) /* CRn */ #define REG_DREG (GEN_SUBCLASS(2) | REG_CLASS_CDT | BITS32 | REGISTER) /* DRn */ #define REG_TREG (GEN_SUBCLASS(3) | REG_CLASS_CDT | BITS32 | REGISTER) /* TRn */ #define REG_SREG ( REG_CLASS_SREG | BITS16 | REGISTER) /* any segment register */ #define REG_CS (GEN_SUBCLASS(1) | REG_CLASS_SREG | BITS16 | REGISTER) /* CS */ #define REG_DESS (GEN_SUBCLASS(2) | REG_CLASS_SREG | BITS16 | REGISTER) /* DS, ES, SS */ #define REG_FSGS (GEN_SUBCLASS(3) | REG_CLASS_SREG | BITS16 | REGISTER) /* FS, GS */ #define REG_SEG67 (GEN_SUBCLASS(4) | REG_CLASS_SREG | BITS16 | REGISTER) /* Unimplemented segment registers */ /* Special GPRs */ #define REG_SMASK SUBCLASS_MASK /* a mask for the following */ #define REG_ACCUM (GEN_SUBCLASS(1) | REG_CLASS_GPR | REGMEM | REGISTER) /* accumulator: AL, AX, EAX, RAX */ #define REG_AL (GEN_SUBCLASS(1) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) #define REG_AX (GEN_SUBCLASS(1) | REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) #define REG_EAX (GEN_SUBCLASS(1) | REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) #define REG_RAX (GEN_SUBCLASS(1) | REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) #define REG_COUNT (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | REGMEM | REGISTER) /* counter: CL, CX, ECX, RCX */ #define REG_CL (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) #define REG_CX (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) #define REG_ECX (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) #define REG_RCX (GEN_SUBCLASS(5) | GEN_SUBCLASS(2) | REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) #define REG_DL (GEN_SUBCLASS(5) | GEN_SUBCLASS(3) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) /* data: DL, DX, EDX, RDX */ #define REG_DX (GEN_SUBCLASS(5) | GEN_SUBCLASS(3) | REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) #define REG_EDX (GEN_SUBCLASS(5) | GEN_SUBCLASS(3) | REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) #define REG_RDX (GEN_SUBCLASS(5) | GEN_SUBCLASS(3) | REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) #define REG_HIGH (GEN_SUBCLASS(5) | GEN_SUBCLASS(4) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) /* high regs: AH, CH, DH, BH */ #define REG_NOTACC GEN_SUBCLASS(5) /* non-accumulator register */ #define REG8NA (GEN_SUBCLASS(5) | REG_CLASS_GPR | BITS8 | REGMEM | REGISTER) /* 8-bit non-acc GPR */ #define REG16NA (GEN_SUBCLASS(5) | REG_CLASS_GPR | BITS16 | REGMEM | REGISTER) /* 16-bit non-acc GPR */ #define REG32NA (GEN_SUBCLASS(5) | REG_CLASS_GPR | BITS32 | REGMEM | REGISTER) /* 32-bit non-acc GPR */ #define REG64NA (GEN_SUBCLASS(5) | REG_CLASS_GPR | BITS64 | REGMEM | REGISTER) /* 64-bit non-acc GPR */ /* special types of EAs */ #define MEM_OFFS (GEN_SUBCLASS(1) | MEMORY) /* simple [address] offset - absolute! */ #define IP_REL (GEN_SUBCLASS(2) | MEMORY) /* IP-relative offset */ /* memory which matches any type of r/m operand */ #define MEMORY_ANY (MEMORY | RM_GPR | RM_MMX | RM_XMM | RM_YMM) /* special type of immediate operand */ #define UNITY (GEN_SUBCLASS(1) | IMMEDIATE) /* for shift/rotate instructions */ #define SBYTE16 (GEN_SUBCLASS(2) | IMMEDIATE) /* for op r16,immediate instrs. */ #define SBYTE32 (GEN_SUBCLASS(3) | IMMEDIATE) /* for op r32,immediate instrs. */ #define SBYTE64 (GEN_SUBCLASS(4) | IMMEDIATE) /* for op r64,immediate instrs. */ #define SDWORD64 (GEN_SUBCLASS(5) | IMMEDIATE) /* for op r64,simm32 instrs. */ #define UDWORD64 (GEN_SUBCLASS(0) | IMMEDIATE) /* for op r64,uimm32 instrs. */ #define BYTENESS (GEN_SUBCLASS(2) | \ GEN_SUBCLASS(3) | \ GEN_SUBCLASS(4)) /* for testing for byteness */ /* special flags */ #define SAME_AS GEN_SPECIAL(0) #endif /* NASM_OPFLAGS_H */