mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-19 18:00:23 +08:00
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:
parent
70a13f5a37
commit
dfb918047b
27
assemble.c
27
assemble.c
@ -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:
|
||||
|
3
disasm.c
3
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)
|
||||
|
42
insns.dat
42
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
|
||||
|
3
insns.h
3
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 */
|
||||
|
13
nasm.c
13
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;
|
||||
|
||||
|
12
nasm.h
12
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
|
||||
};
|
||||
|
||||
|
14
parser.c
14
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;
|
||||
}
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ strict
|
||||
to
|
||||
tword
|
||||
word
|
||||
yword
|
||||
|
||||
% TOKEN_FLOAT, 0, 0
|
||||
__infinity__
|
||||
|
Loading…
x
Reference in New Issue
Block a user