Add DY, YWORD, and the SY instruction flag
authorH. Peter Anvin <hpa@zytor.com>
Tue, 20 May 2008 18:43:53 +0000 (11:43 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 20 May 2008 18:43:53 +0000 (11:43 -0700)
Add the DY instruction, YWORD keyword, and an SY marker for
instruction sizes.  Add a few more AVX sample instructions.

assemble.c
disasm.c
insns.dat
insns.h
nasm.c
nasm.h
parser.c
preproc.c
tokens.dat

index d10e5b0..63ac21e 100644 (file)
 #include "regflags.c"
 #include "regvals.c"
 
+/* Initialized to zero by the C standard */
+static const uint8_t const_zero_buf[256];
+
 typedef struct {
     int sib_present;                 /* is a SIB byte necessary? */
     int bytes;                       /* # of bytes of offset needed */
@@ -168,6 +171,8 @@ static const char *size_name(int size)
        return "tword";
     case 16:
        return "oword";
+    case 32:
+       return "yword";
     default:
        return "???";
     }
@@ -294,6 +299,9 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
     case I_DO:
        wsize = 16;
        break;
+    case I_DY:
+       wsize = 32;
+       break;
     default:
        break;
     }
@@ -318,7 +326,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
                                 OUT_RAWDATA, 1, NO_SEG, NO_SEG);
                         }
                     } else if (wsize > 8) {
-                        errfunc(ERR_NONFATAL, "integer supplied to a DT or DO"
+                        errfunc(ERR_NONFATAL, "integer supplied to a DT, DO or DY"
                                 " instruction");
                     } else
                         out(offset, segment, &e->offset,
@@ -333,8 +341,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
 
                     if (align) {
                         align = wsize - align;
-                        out(offset, segment,
-                           "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
+                        out(offset, segment, const_zero_buf,
                             OUT_RAWDATA, align, NO_SEG, NO_SEG);
                     }
                     offset += e->stringlen + align;
@@ -630,7 +637,8 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
 
     if (instruction->opcode == I_DB || instruction->opcode == I_DW ||
         instruction->opcode == I_DD || instruction->opcode == I_DQ ||
-       instruction->opcode == I_DT || instruction->opcode == I_DO) {
+       instruction->opcode == I_DT || instruction->opcode == I_DO ||
+       instruction->opcode == I_DY) {
         extop *e;
         int32_t isize, osize, wsize = 0;   /* placate gcc */
 
@@ -654,6 +662,9 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
        case I_DO:
            wsize = 16;
            break;
+       case I_DY:
+           wsize = 32;
+           break;
        default:
            break;
         }
@@ -1483,7 +1494,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
             if (opx->segment == NO_SEG)
                 errfunc(ERR_NONFATAL, "value referenced by FAR is not"
                         " relocatable");
-            data = 0L;
+           data = 0;
             out(offset, segment, &data, OUT_ADDRESS, 2,
                 outfmt->segbase(1 + opx->segment),
                 opx->wrt);
@@ -1957,6 +1968,9 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
        case IF_SO:
            size[i] = BITS128;
            break;
+       case IF_SY:
+           size[i] = BITS256;
+           break;
        case IF_SZ:
            switch (bits) {
            case 16:
@@ -1991,6 +2005,9 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
        case IF_SO:
             asize = BITS128;
            break;
+       case IF_SY:
+            asize = BITS256;
+           break;
        case IF_SZ:
            switch (bits) {
            case 16:
index 711304c..2d93ea6 100644 (file)
--- a/disasm.c
+++ b/disasm.c
@@ -1331,6 +1331,9 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
             if (t & BITS128)
                 slen +=
                     snprintf(output + slen, outbufsize - slen, "oword ");
+            if (t & BITS256)
+                slen +=
+                    snprintf(output + slen, outbufsize - slen, "yword ");
             if (t & FAR)
                 slen += snprintf(output + slen, outbufsize - slen, "far ");
             if (t & NEAR)
index 114569f..ef1ba58 100644 (file)
--- a/insns.dat
+++ b/insns.dat
@@ -25,12 +25,14 @@ DD          ignore                          ignore                                          ignore
 DQ             ignore                          ignore                                          ignore
 DT             ignore                          ignore                                          ignore
 DO             ignore                          ignore                                          ignore
+DY             ignore                          ignore                                          ignore
 RESB           imm                             \340                                            8086
 RESW           ignore                          ignore                                          ignore
 RESD           ignore                          ignore                                          ignore
 RESQ           ignore                          ignore                                          ignore
 REST           ignore                          ignore                                          ignore
 RESO           ignore                          ignore                                          ignore
+RESY           ignore                          ignore                                          ignore
 
 ;# Conventional instructions
 AAA            void                            \1\x37                                          8086,NOLONG
@@ -2023,22 +2025,30 @@ PFRCP           mmxreg,mmxrm                    \323\2\x0F\x0F\110\1\x86                        PENT,3DNOW,SQ,CYRIX
 PFRSQRT                mmxreg,mmxrm                    \323\2\x0F\x0F\110\1\x87                        PENT,3DNOW,SQ,CYRIX
                                                                                                
 ;# Intel AVX instructions
-VPERMILTD2PS   xmmreg,xmmreg,xmmrm,xmmreg      [rvms: vex.nds.128.66.0f3a.w0 48 /r /is4=0]     AVX,SANDYBRIDGE
-VPERMILTD2PS   xmmreg,xmmreg,xmmreg,xmmrm      [rvsm: vex.nds.128.66.0f3a.w1 48 /r /is4=0]     AVX,SANDYBRIDGE
-VPERMILTD2PS   ymmreg,ymmreg,ymmrm,ymmreg      [rvms: vex.nds.256.66.0f3a.w0 48 /r /is4=0]     AVX,SANDYBRIDGE
-VPERMILTD2PS   ymmreg,ymmreg,ymmreg,ymmrm      [rvsm: vex.nds.256.66.0f3a.w1 48 /r /is4=0]     AVX,SANDYBRIDGE
-VPERMILMO2PS   xmmreg,xmmreg,xmmrm,xmmreg      [rvms: vex.nds.128.66.0f3a.w0 48 /r /is4=2]     AVX,SANDYBRIDGE
-VPERMILMO2PS   xmmreg,xmmreg,xmmreg,xmmrm      [rvsm: vex.nds.128.66.0f3a.w1 48 /r /is4=2]     AVX,SANDYBRIDGE
-VPERMILMO2PS   ymmreg,ymmreg,ymmrm,ymmreg      [rvms: vex.nds.256.66.0f3a.w0 48 /r /is4=2]     AVX,SANDYBRIDGE
-VPERMILMO2PS   ymmreg,ymmreg,ymmreg,ymmrm      [rvsm: vex.nds.256.66.0f3a.w1 48 /r /is4=2]     AVX,SANDYBRIDGE
-VPERMILMZ2PS   xmmreg,xmmreg,xmmrm,xmmreg      [rvms: vex.nds.128.66.0f3a.w0 48 /r /is4=3]     AVX,SANDYBRIDGE
-VPERMILMZ2PS   xmmreg,xmmreg,xmmreg,xmmrm      [rvsm: vex.nds.128.66.0f3a.w1 48 /r /is4=3]     AVX,SANDYBRIDGE
-VPERMILMZ2PS   ymmreg,ymmreg,ymmrm,ymmreg      [rvms: vex.nds.256.66.0f3a.w0 48 /r /is4=3]     AVX,SANDYBRIDGE
-VPERMILMZ2PS   ymmreg,ymmreg,ymmreg,ymmrm      [rvsm: vex.nds.256.66.0f3a.w1 48 /r /is4=3]     AVX,SANDYBRIDGE
-VPERMIL2PS     xmmreg,xmmreg,xmmrm,xmmreg,imm  [rvmsi: vex.nds.128.66.0f3a.w0 48 /r /is4]      AVX,SANDYBRIDGE
-VPERMIL2PS     xmmreg,xmmreg,xmmreg,xmmrm,imm  [rvsmi: vex.nds.128.66.0f3a.w1 48 /r /is4]      AVX,SANDYBRIDGE
-VPERMIL2PS     ymmreg,ymmreg,ymmrm,ymmreg,imm  [rvmsi: vex.nds.256.66.0f3a.w0 48 /r /is4]      AVX,SANDYBRIDGE
-VPERMIL2PS     ymmreg,ymmreg,ymmreg,ymmrm,imm  [rvsmi: vex.nds.256.66.0f3a.w1 48 /r /is4]      AVX,SANDYBRIDGE
+VADDPD         xmmreg,xmmreg,xmmrm             [rvm: vex.nds.128.66.0f 58 /r]                  AVX,SANDYBRIDGE,SO
+VADDPD         ymmreg,ymmreg,ymmrm             [rvm: vex.nds.256.66.0f 58 /r]                  AVX,SANDYBRIDGE,SY
+VADDPD         xmmreg,xmmrm                    [r+vm: vex.nds.128.66.0f 58 /r]                 AVX,SANDYBRIDGE,SO
+VADDPD         ymmreg,ymmrm                    [r+vm: vex.nds.256.66.0f 58 /r]                 AVX,SANDYBRIDGE,SY
+VADDPS         xmmreg,xmmreg,xmmrm             [rvm: vex.nds.128.0f 58 /r]                     AVX,SANDYBRIDGE,SO
+VADDPS         ymmreg,ymmreg,ymmrm             [rvm: vex.nds.256.0f 58 /r]                     AVX,SANDYBRIDGE,SY
+VADDPS         xmmreg,xmmrm                    [r+vm: vex.nds.128.0f 58 /r]                    AVX,SANDYBRIDGE,SO
+VADDPS         ymmreg,ymmrm                    [r+vm: vex.nds.256.0f 58 /r]                    AVX,SANDYBRIDGE,SY
+VPERMILTD2PS   xmmreg,xmmreg,xmmrm,xmmreg      [rvms: vex.nds.128.66.0f3a.w0 48 /r /is4=0]     AVX,SANDYBRIDGE,SO
+VPERMILTD2PS   xmmreg,xmmreg,xmmreg,xmmrm      [rvsm: vex.nds.128.66.0f3a.w1 48 /r /is4=0]     AVX,SANDYBRIDGE,SO
+VPERMILTD2PS   ymmreg,ymmreg,ymmrm,ymmreg      [rvms: vex.nds.256.66.0f3a.w0 48 /r /is4=0]     AVX,SANDYBRIDGE,SY
+VPERMILTD2PS   ymmreg,ymmreg,ymmreg,ymmrm      [rvsm: vex.nds.256.66.0f3a.w1 48 /r /is4=0]     AVX,SANDYBRIDGE,SY
+VPERMILMO2PS   xmmreg,xmmreg,xmmrm,xmmreg      [rvms: vex.nds.128.66.0f3a.w0 48 /r /is4=2]     AVX,SANDYBRIDGE,SO
+VPERMILMO2PS   xmmreg,xmmreg,xmmreg,xmmrm      [rvsm: vex.nds.128.66.0f3a.w1 48 /r /is4=2]     AVX,SANDYBRIDGE,SO
+VPERMILMO2PS   ymmreg,ymmreg,ymmrm,ymmreg      [rvms: vex.nds.256.66.0f3a.w0 48 /r /is4=2]     AVX,SANDYBRIDGE,SY
+VPERMILMO2PS   ymmreg,ymmreg,ymmreg,ymmrm      [rvsm: vex.nds.256.66.0f3a.w1 48 /r /is4=2]     AVX,SANDYBRIDGE,SY
+VPERMILMZ2PS   xmmreg,xmmreg,xmmrm,xmmreg      [rvms: vex.nds.128.66.0f3a.w0 48 /r /is4=3]     AVX,SANDYBRIDGE,SO
+VPERMILMZ2PS   xmmreg,xmmreg,xmmreg,xmmrm      [rvsm: vex.nds.128.66.0f3a.w1 48 /r /is4=3]     AVX,SANDYBRIDGE,SO
+VPERMILMZ2PS   ymmreg,ymmreg,ymmrm,ymmreg      [rvms: vex.nds.256.66.0f3a.w0 48 /r /is4=3]     AVX,SANDYBRIDGE,SY
+VPERMILMZ2PS   ymmreg,ymmreg,ymmreg,ymmrm      [rvsm: vex.nds.256.66.0f3a.w1 48 /r /is4=3]     AVX,SANDYBRIDGE,SY
+VPERMIL2PS     xmmreg,xmmreg,xmmrm,xmmreg,imm  [rvmsi: vex.nds.128.66.0f3a.w0 48 /r /is4]      AVX,SANDYBRIDGE,SO
+VPERMIL2PS     xmmreg,xmmreg,xmmreg,xmmrm,imm  [rvsmi: vex.nds.128.66.0f3a.w1 48 /r /is4]      AVX,SANDYBRIDGE,SO
+VPERMIL2PS     ymmreg,ymmreg,ymmrm,ymmreg,imm  [rvmsi: vex.nds.256.66.0f3a.w0 48 /r /is4]      AVX,SANDYBRIDGE,SY
+VPERMIL2PS     ymmreg,ymmreg,ymmreg,ymmrm,imm  [rvsmi: vex.nds.256.66.0f3a.w1 48 /r /is4]      AVX,SANDYBRIDGE,SY
 
 ;# VIA (Centaur) security instructions
 XSTORE         void                            \360\3\x0F\xA7\xC0                              PENT,CYRIX
diff --git a/insns.h b/insns.h
index 474e715..4f954a5 100644 (file)
--- a/insns.h
+++ b/insns.h
@@ -75,7 +75,8 @@ extern const uint8_t nasm_bytecodes[];
 #define IF_SD     0x0000000CUL  /* unsized operands can't be non-dword */
 #define IF_SQ     0x00000010UL  /* unsized operands can't be non-qword */
 #define IF_SO     0x00000014UL  /* unsized operands can't be non-oword */
-#define IF_SZ     0x00000018UL  /* unsized operands must match the bitsize */
+#define IF_SY     0x00000018UL  /* unsized operands can't be non-yword */
+#define IF_SZ     0x0000001CUL  /* unsized operands must match the bitsize */
 #define IF_SMASK  0x0000001CUL  /* mask for unsized argument size */
 #define IF_AR0   0x00000020UL  /* SB, SW, SD applies to argument 0 */
 #define IF_AR1   0x00000040UL  /* SB, SW, SD applies to argument 1 */
diff --git a/nasm.c b/nasm.c
index 85865e8..484993a 100644 (file)
--- a/nasm.c
+++ b/nasm.c
@@ -1486,6 +1486,16 @@ static void assemble_file(char *fname)
                                     TYS_ELEMENTS(output_ins.oprs[0].
                                                  offset) | TY_TBYTE;
                                 break;
+                            case I_RESO:
+                                typeinfo =
+                                    TYS_ELEMENTS(output_ins.oprs[0].
+                                                 offset) | TY_OWORD;
+                                break;
+                            case I_RESY:
+                                typeinfo =
+                                    TYS_ELEMENTS(output_ins.oprs[0].
+                                                 offset) | TY_YWORD;
+                                break;
                             case I_DB:
                                 typeinfo |= TY_BYTE;
                                 break;
@@ -1507,6 +1517,9 @@ static void assemble_file(char *fname)
                            case I_DO:
                                typeinfo |= TY_OWORD;
                                break;
+                           case I_DY:
+                               typeinfo |= TY_YWORD;
+                               break;
                             default:
                                 typeinfo = TY_LABEL;
 
diff --git a/nasm.h b/nasm.h
index 18184d1..f76f87d 100644 (file)
--- a/nasm.h
+++ b/nasm.h
@@ -374,7 +374,7 @@ enum {
  *
  * The bits are assigned as follows:
  *
- * Bits 0-7, 29: sizes
+ * Bits 0-7, 23, 29: sizes
  *  0:  8 bits (BYTE)
  *  1: 16 bits (WORD)
  *  2: 32 bits (DWORD)
@@ -383,6 +383,7 @@ enum {
  *  5: FAR
  *  6: NEAR
  *  7: SHORT
+ * 23: 256 bits (YWORD)
  * 29: 128 bits (OWORD)
  *
  * Bits 8-11 modifiers
@@ -432,11 +433,10 @@ enum {
  * 18: BYTENESS32 (-128..127)
  * 19: BYTENESS64 (-128..127)
  *
- * Bits 20-26: register classes
+ * Bits 20-22, 24-27: register classes
  * 20: REG_CDT (CRx, DRx, TRx)
  * 21: RM_GPR (REG_GPR) (integer register)
  * 22: REG_SREG
- * 23: IP_REG (RIP or EIP) [unused]
  * 24: FPUREG
  * 25: RM_MMX (MMXREG)
  * 26: RM_XMM (XMMREG)
@@ -459,12 +459,13 @@ typedef uint32_t opflags_t;
 #define BITS64         0x00000008U   /* x64 and FPU only */
 #define BITS80         0x00000010U   /* FPU only */
 #define BITS128                0x20000000U
+#define BITS256                0x00800000U
 #define FAR            0x00000020U   /* grotty: this means 16:16 or */
                                        /* 16:32, like in CALL/JMP */
 #define NEAR           0x00000040U
 #define SHORT          0x00000080U   /* and this means what it says :) */
 
-#define SIZE_MASK      0x200000FFU   /* all the size attributes */
+#define SIZE_MASK      0x208000FFU   /* all the size attributes */
 
 /* Modifiers */
 #define MODIFIER_MASK  0x00000f00U
@@ -955,6 +956,7 @@ struct dfmt {
 #define TY_QWORD   0x30
 #define TY_TBYTE   0x38
 #define TY_OWORD   0x40
+#define TY_YWORD   0x48
 #define TY_COMMON  0xE0
 #define TY_SEG     0xE8
 #define TY_EXTERN  0xF0
@@ -975,7 +977,7 @@ enum special_tokens {
     SPECIAL_ENUM_START = PREFIX_ENUM_LIMIT,
     S_ABS = SPECIAL_ENUM_START,
     S_BYTE, S_DWORD, S_FAR, S_LONG, S_NEAR, S_NOSPLIT,
-    S_OWORD, S_QWORD, S_REL, S_SHORT, S_STRICT, S_TO, S_TWORD, S_WORD,
+    S_OWORD, S_QWORD, S_REL, S_SHORT, S_STRICT, S_TO, S_TWORD, S_WORD, S_YWORD,
     SPECIAL_ENUM_LIMIT
 };
 
index 9172fb1..72e4e6c 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -322,6 +322,7 @@ restart_parse:
     if (result->opcode == I_RESB || result->opcode == I_RESW ||
        result->opcode == I_RESD || result->opcode == I_RESQ ||
        result->opcode == I_REST || result->opcode == I_RESO ||
+       result->opcode == I_RESY ||
        result->opcode == I_EQU || result->opcode == I_INCBIN) {
         critical = (pass0 < 2 ? 1 : 2);
 
@@ -331,7 +332,7 @@ restart_parse:
     if (result->opcode == I_DB || result->opcode == I_DW ||
         result->opcode == I_DD || result->opcode == I_DQ ||
         result->opcode == I_DT || result->opcode == I_DO ||
-       result->opcode == I_INCBIN) {
+       result->opcode == I_DY || result->opcode == I_INCBIN) {
         extop *eop, **tail = &result->eops, **fixptr;
         int oper_num = 0;
 
@@ -560,6 +561,11 @@ restart_parse:
                     result->oprs[operand].type |= BITS128;
                 setsize = 1;
                 break;
+            case S_YWORD:
+                if (!setsize)
+                    result->oprs[operand].type |= BITS256;
+                setsize = 1;
+                break;
             case S_TO:
                 result->oprs[operand].type |= TO;
                 break;
@@ -857,7 +863,7 @@ while (operand < MAX_OPERANDS)
     result->oprs[operand++].type = 0;
 
     /*
-     * Transform RESW, RESD, RESQ, REST, RESO into RESB.
+     * Transform RESW, RESD, RESQ, REST, RESO, RESY into RESB.
      */
     switch (result->opcode) {
     case I_RESW:
@@ -880,6 +886,10 @@ while (operand < MAX_OPERANDS)
         result->opcode = I_RESB;
         result->oprs[0].offset *= 16;
         break;
+    case I_RESY:
+        result->opcode = I_RESB;
+        result->oprs[0].offset *= 32;
+        break;
     default:
        break;
     }
index f3ef272..9e97257 100644 (file)
--- a/preproc.c
+++ b/preproc.c
@@ -1744,9 +1744,9 @@ static void undef_smacro(Context *ctx, const char *mname)
  */
 static int parse_size(const char *str) {
     static const char *size_names[] =
-       { "byte", "dword", "oword", "qword", "tword", "word" };
+       { "byte", "dword", "oword", "qword", "tword", "word", "yword" };
     static const int sizes[] =
-       { 0, 1, 4, 16, 8, 10, 2 };
+       { 0, 1, 4, 16, 8, 10, 2, 32 };
 
     return sizes[bsii(str, size_names, elements(size_names))+1];
 }
index 9e22183..6c3ad65 100644 (file)
@@ -35,6 +35,7 @@ strict
 to
 tword
 word
+yword
 
 % TOKEN_FLOAT, 0, 0
 __infinity__