summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--assemble.c2
-rw-r--r--disasm.c2
-rw-r--r--nasm.c9
-rw-r--r--nasm.h201
4 files changed, 143 insertions, 71 deletions
diff --git a/assemble.c b/assemble.c
index e887d9a..4669ebd 100644
--- a/assemble.c
+++ b/assemble.c
@@ -1504,7 +1504,7 @@ static int matches(struct itemplate *itemp, insn * instruction, int bits)
if (itemp->opd[i] & ~instruction->oprs[i].type ||
((itemp->opd[i] & SIZE_MASK) &&
((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK))) {
- if ((itemp->opd[i] & ~instruction->oprs[i].type & NON_SIZE) ||
+ if ((itemp->opd[i] & ~instruction->oprs[i].type & ~SIZE_MASK) ||
(instruction->oprs[i].type & SIZE_MASK))
return 0;
else
diff --git a/disasm.c b/disasm.c
index 26273d8..8ba6295 100644
--- a/disasm.c
+++ b/disasm.c
@@ -472,7 +472,7 @@ static int matches(struct itemplate *t, uint8_t *data, int asize,
}
if (segsize != osize) {
ins->oprs[c - 064].type =
- (ins->oprs[c - 064].type & NON_SIZE)
+ (ins->oprs[c - 064].type & ~SIZE_MASK)
| ((osize == 16) ? BITS16 : BITS32);
}
} else if (c >= 070 && c <= 072) {
diff --git a/nasm.c b/nasm.c
index a6c3d2f..5949992 100644
--- a/nasm.c
+++ b/nasm.c
@@ -1123,10 +1123,11 @@ static void assemble_file(char *fname)
*/
if (output_ins.operands >= 2 &&
- (output_ins.oprs[1].opflags & OPFLAG_FORWARD))
- {
- output_ins.oprs[1].type &=
- ~(ONENESS | BYTENESS);
+ (output_ins.oprs[1].opflags & OPFLAG_FORWARD) &&
+ !(IMMEDIATE & ~output_ins.oprs[1].type))
+ {
+ /* Remove special properties bits */
+ output_ins.oprs[1].type &= ~REG_SMASK;
}
} /* pass == 2 */
diff --git a/nasm.h b/nasm.h
index 92f678e..94c6929 100644
--- a/nasm.h
+++ b/nasm.h
@@ -370,78 +370,149 @@ enum {
* 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" is of type "class".
+ *
+ * The bits are assigned as follows:
+ *
+ * Bits 0-7: sizes
+ * 0: 8 bits (BYTE)
+ * 1: 16 bits (WORD)
+ * 2: 32 bits (DWORD)
+ * 3: 64 bits (QWORD)
+ * 4: 80 bits (TWORD)
+ * 5: FAR
+ * 6: NEAR
+ * 7: SHORT
+ *
+ * Bits 8-11: modifiers
+ * 8: TO
+ * 9: COLON
+ * 10: STRICT
+ * 11: (reserved)
+ *
+ * Bits 12-15: type of operand
+ * 12: REGISTER
+ * 13: IMMEDIATE
+ * 14: MEMORY (always has REGMEM attribute as well)
+ * 15: (reserved)
+ *
+ * Bits 16-19: subclasses
+ * With REG_CDT:
+ * 16: REG_CREG (CRx)
+ * 17: REG_DREG (DRx)
+ * 18: REG_TREG (TRx)
+
+ * With REGNORM == REGMEM|REGISTER:
+ * 16: REG_ACCUM (AL, AX, EAX, RAX) or
+ * 17: REG_COUNT (CL, CX, ECX, RCX)
+ * 18: REG_DATA (DL, DX, EDX, RDX)
+ *
+ * With REG_SREG:
+ * 16: REG_CS
+ * 17: REG_DESS (DS, ES, SS)
+ * 18: REG_FSGS
+ * 19: REG_SEG67
+ *
+ * With FPUREG:
+ * 16: FPU0
+ *
+ * With MEMORY:
+ * 16: MEM_OFFS (this is a simple offset)
+ *
+ * With IMMEDIATE:
+ * 16: UNITY (1)
+ * 17: BYTENESS (-128..127)
+ *
+ * Bits 20-26: register classes
+ * 20: REG_CDT (CRx, DRx, TRx)
+ * 21: REGMEM (GPR or memory operand)
+ * 22: REG_SREG
+ * 23: IP_REG (RIP or EIP)
+ * 24: FPUREG
+ * 25: MMXREG
+ * 26: XMMREG
+ *
+ * Bits 27-31 are currently unallocated.
*/
-/* size, and other attributes, of the operand */
-#define BITS8 0x00000001L
-#define BITS16 0x00000002L
-#define BITS32 0x00000004L
-#define BITS64 0x00000008L /* x64 and FPU only */
-#define BITS80 0x00000010L /* FPU only */
-#define FAR 0x00000020L /* grotty: this means 16:16 or */
+/* Size, and other attributes, of the operand */
+#define BITS8 0x00000001L
+#define BITS16 0x00000002L
+#define BITS32 0x00000004L
+#define BITS64 0x00000008L /* x64 and FPU only */
+#define BITS80 0x00000010L /* FPU only */
+#define FAR 0x00000020L /* grotty: this means 16:16 or */
/* 16:32, like in CALL/JMP */
-#define NEAR 0x00000040L
-#define SHORT 0x00000080L /* and this means what it says :) */
-
-#define SIZE_MASK 0x000000FFL /* all the size attributes */
-#define NON_SIZE (~SIZE_MASK)
-
-#define TO 0x00000100L /* reverse effect in FADD, FSUB &c */
-#define COLON 0x00000200L /* operand is followed by a colon */
-#define STRICT 0x00000400L /* do not optimize this operand */
-
-/* type of operand: memory reference, register, etc. */
-#define MEMORY 0x00204000L
-#define REGISTER 0x00001000L /* register number in 'basereg' */
-#define IMMEDIATE 0x00002000L
-
-#define REGMEM 0x00200000L /* for r/m, ie EA, operands */
-#define REGNORM 0x00201000L /* 'normal' reg, qualifies as EA */
-#define REG8 0x00201001L
-#define REG16 0x00201002L
-#define REG32 0x00201004L
-#define REG64 0x00201008L /* x64 registers */
-#define RIPREG 0x0020100CL /* RIP register */
-#define MMXREG 0x00201010L /* MMX registers */
-#define XMMREG 0x00201011L /* XMM Katmai reg */
-#define FPUREG 0x01000000L /* floating point stack registers */
-#define FPU0 0x01000800L /* FPU stack register zero */
-
-/* special register operands: these may be treated differently */
-#define REG_SMASK 0x00070000L /* a mask for the following */
-#define REG_ACCUM 0x00211000L /* accumulator: AL, AX or EAX */
-#define REG_AL 0x00211001L /* REG_ACCUM | BITSxx */
-#define REG_AX 0x00211002L /* ditto */
-#define REG_EAX 0x00211004L /* and again */
-#define REG_RAX 0x00211008L /* and again */
-#define REG_COUNT 0x00221000L /* counter: CL, CX, ECX or RCX */
-#define REG_CL 0x00221001L /* REG_COUNT | BITSxx */
-#define REG_CX 0x00221002L /* ditto */
-#define REG_ECX 0x00221004L /* another one */
-#define REG_RCX 0x00221008L /* another one */
-#define REG_DL 0x00241001L
-#define REG_DX 0x00241002L
-#define REG_EDX 0x00241004L
-#define REG_RDX 0x00241008L
-#define REG_RIP 0x0027100CL /* RIP relative addressing */
-#define REG_SREG 0x00081002L /* any segment register */
-#define REG_CS 0x01081002L /* CS */
-#define REG_DESS 0x02081002L /* DS, ES, SS (non-CS 86 registers) */
-#define REG_FSGS 0x04081002L /* FS, GS (386 extended registers) */
-#define REG_SEG67 0x08081002L /* Non-implemented segment registers */
-#define REG_CDT 0x00101004L /* CRn, DRn and TRn */
-#define REG_CREG 0x08101004L /* CRn */
-#define REG_DREG 0x10101004L /* DRn */
-#define REG_TREG 0x20101004L /* TRn */
+#define NEAR 0x00000040L
+#define SHORT 0x00000080L /* and this means what it says :) */
+
+#define SIZE_MASK 0x000000FFL /* all the size attributes */
+
+/* Modifiers */
+#define MODIFIER_MASK 0x00000f00L
+#define TO 0x00000100L /* reverse effect in FADD, FSUB &c */
+#define COLON 0x00000200L /* operand is followed by a colon */
+#define STRICT 0x00000400L /* do not optimize this operand */
+
+/* Type of operand: memory reference, register, etc. */
+#define OPTYPE_MASK 0x0000f000L
+#define REGISTER 0x00001000L /* register number in 'basereg' */
+#define IMMEDIATE 0x00002000L
+#define MEMORY 0x00204000L
+
+#define REGMEM 0x00200000L /* for r/m, ie EA, operands */
+#define REGNORM 0x00201000L /* 'normal' reg, qualifies as EA */
+#define REG8 0x00201001L
+#define REG16 0x00201002L
+#define REG32 0x00201004L
+#define REG64 0x00201008L
+#define IP_REG 0x00800000L /* RIP or EIP register */
+#define RIPREG 0x00800008L /* RIP */
+#define EIPREG 0x00800004L /* EIP */
+#define FPUREG 0x01000000L /* floating point stack registers */
+#define MMXREG 0x02000008L /* MMX registers */
+#define XMMREG 0x04000001L /* XMM Katmai reg */
+#define FPU0 0x01001000L /* FPU stack register zero */
+
+/* Special GPRs */
+#define REG_SMASK 0x000f0000L /* a mask for the following */
+#define REG_ACCUM 0x00211000L /* accumulator: AL, AX, EAX, RAX */
+#define REG_AL 0x00211001L
+#define REG_AX 0x00211002L
+#define REG_EAX 0x00211004L
+#define REG_RAX 0x00211008L
+#define REG_COUNT 0x00221000L /* counter: CL, CX, ECX, RCX */
+#define REG_CL 0x00221001L
+#define REG_CX 0x00221002L
+#define REG_ECX 0x00221004L
+#define REG_RCX 0x00221008L
+#define REG_DL 0x00241001L /* data: DL, DX, EDX, RDX */
+#define REG_DX 0x00241002L
+#define REG_EDX 0x00241004L
+#define REG_RDX 0x00241008L
+#define REG_RIP 0x0027100CL /* RIP relative addressing */
+
+/* Register classes */
+#define REG_CDT 0x00101004L /* CRn, DRn and TRn */
+#define REG_CREG 0x00111004L /* CRn */
+#define REG_DREG 0x00121004L /* DRn */
+#define REG_TREG 0x00141004L /* TRn */
+#define REG_SREG 0x00401002L /* any segment register */
+#define REG_CS 0x00411002L /* CS */
+#define REG_DESS 0x00421002L /* DS, ES, SS */
+#define REG_FSGS 0x00441002L /* FS, GS */
+#define REG_SEG67 0x00481002L /* Unimplemented segment registers */
/* special type of EA */
-#define MEM_OFFS 0x00604000L /* simple [address] offset */
+#define MEM_OFFS 0x00214000L /* simple [address] offset */
/* special type of immediate operand */
-#define ONENESS 0x00800000L /* so UNITY == IMMEDIATE | ONENESS */
-#define UNITY 0x00802000L /* for shift/rotate instructions */
-#define BYTENESS 0x40000000L /* so SBYTE == IMMEDIATE | BYTENESS */
-#define SBYTE 0x40002000L /* for op r16/32,immediate instrs. */
+#define UNITY 0x00012000L /* for shift/rotate instructions */
+#define SBYTE 0x00022000L /* for op r16/32,immediate instrs. */
/* Register names automatically generated from regs.dat */
#include "regs.h"