Add DY, YWORD, and the SY instruction flag

Add the DY instruction, YWORD keyword, and an SY marker for
instruction sizes.  Add a few more AVX sample instructions.
This commit is contained in:
H. Peter Anvin 2008-05-20 11:43:53 -07:00
parent 70a13f5a37
commit dfb918047b
9 changed files with 88 additions and 31 deletions

View File

@ -119,6 +119,9 @@
#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:

View File

@ -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)

View File

@ -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

View File

@ -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 */

13
nasm.c
View File

@ -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;

12
nasm.h
View File

@ -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
};

View File

@ -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;
}

View File

@ -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];
}

View File

@ -35,6 +35,7 @@ strict
to
tword
word
yword
% TOKEN_FLOAT, 0, 0
__infinity__