mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-21 03:14:19 +08:00
Implement "oword" (128 bits) as a first-class size
Implement oword, reso, do, as well as the SO flag to instructions. No instructions are actually flagged with SO yet, but this allows us to specify 128-bit sizes in instruction patterns.
This commit is contained in:
parent
5255fd1f36
commit
41c9f6fde0
@ -1720,6 +1720,9 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
|
||||
case IF_SQ:
|
||||
size[i] = BITS64;
|
||||
break;
|
||||
case IF_SO:
|
||||
size[i] = BITS128;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1742,6 +1745,10 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
|
||||
asize = BITS64;
|
||||
oprs = itemp->operands;
|
||||
break;
|
||||
case IF_SO:
|
||||
asize = BITS128;
|
||||
oprs = itemp->operands;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
26
insns.dat
26
insns.dat
@ -14,6 +14,22 @@
|
||||
; see the comment at the top of assemble.c. For a detailed description
|
||||
; of the flags (fourth field), please see insns.h.
|
||||
;
|
||||
|
||||
; Special instructions...
|
||||
DB ignore ignore ignore
|
||||
DW ignore ignore ignore
|
||||
DD ignore ignore ignore
|
||||
DQ ignore ignore ignore
|
||||
DT ignore ignore ignore
|
||||
DO 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
|
||||
|
||||
; Conventional instructions
|
||||
AAA void \1\x37 8086,NOLONG
|
||||
AAD void \2\xD5\x0A 8086,NOLONG
|
||||
AAD imm \1\xD5\24 8086,SB,NOLONG
|
||||
@ -270,8 +286,6 @@ CWD void \320\1\x99 8086
|
||||
CWDE void \321\1\x98 386
|
||||
DAA void \1\x27 8086,NOLONG
|
||||
DAS void \1\x2F 8086,NOLONG
|
||||
DB ignore ignore ignore
|
||||
DD ignore ignore ignore
|
||||
DEC reg16 \320\10\x48 8086,NOLONG
|
||||
DEC reg32 \321\10\x48 386,NOLONG
|
||||
DEC rm8 \300\1\xFE\201 8086
|
||||
@ -282,9 +296,6 @@ DIV rm8 \300\1\xF6\206 8086
|
||||
DIV rm16 \320\300\1\xF7\206 8086
|
||||
DIV rm32 \321\300\1\xF7\206 386
|
||||
DIV rm64 \324\300\1\xF7\206 X64
|
||||
DQ ignore ignore ignore
|
||||
DT ignore ignore ignore
|
||||
DW ignore ignore ignore
|
||||
EMMS void \2\x0F\x77 PENT,MMX
|
||||
ENTER imm,imm \1\xC8\30\25 186
|
||||
EQU imm \0 8086
|
||||
@ -1029,11 +1040,6 @@ RDMSR void \2\x0F\x32 PENT,PRIV
|
||||
RDPMC void \2\x0F\x33 P6
|
||||
RDTSC void \2\x0F\x31 PENT
|
||||
RDTSCP void \3\x0F\x01\xF9 X64
|
||||
RESB imm \340 8086
|
||||
RESD ignore ignore ignore
|
||||
RESQ ignore ignore ignore
|
||||
REST ignore ignore ignore
|
||||
RESW ignore ignore ignore
|
||||
RET void \1\xC3 8086
|
||||
RET imm \1\xC2\30 8086,SW
|
||||
RETF void \1\xCB 8086
|
||||
|
1
insns.h
1
insns.h
@ -68,6 +68,7 @@ extern const struct itemplate * const * const itable[];
|
||||
#define IF_SW 0x00000008UL /* unsized operands can't be non-word */
|
||||
#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_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 */
|
||||
|
10
nasm.h
10
nasm.h
@ -375,7 +375,7 @@ enum {
|
||||
*
|
||||
* The bits are assigned as follows:
|
||||
*
|
||||
* Bits 0-7: sizes
|
||||
* Bits 0-7, 29: sizes
|
||||
* 0: 8 bits (BYTE)
|
||||
* 1: 16 bits (WORD)
|
||||
* 2: 32 bits (DWORD)
|
||||
@ -384,6 +384,7 @@ enum {
|
||||
* 5: FAR
|
||||
* 6: NEAR
|
||||
* 7: SHORT
|
||||
* 29: 128 bits (OWORD)
|
||||
*
|
||||
* Bits 8-11 modifiers
|
||||
* 8: TO
|
||||
@ -454,12 +455,13 @@ typedef uint32_t opflags_t;
|
||||
#define BITS32 0x00000004L
|
||||
#define BITS64 0x00000008L /* x64 and FPU only */
|
||||
#define BITS80 0x00000010L /* FPU only */
|
||||
#define BITS128 0x20000000L
|
||||
#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 SIZE_MASK 0x200000FFL /* all the size attributes */
|
||||
|
||||
/* Modifiers */
|
||||
#define MODIFIER_MASK 0x00000f00L
|
||||
@ -959,8 +961,8 @@ struct dfmt {
|
||||
*/
|
||||
|
||||
enum special_tokens {
|
||||
S_ABS, S_BYTE, S_DWORD, S_FAR, S_LONG, S_NEAR, S_NOSPLIT, S_QWORD, S_REL,
|
||||
S_SHORT, S_STRICT, S_TO, S_TWORD, S_WORD
|
||||
S_ABS, 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
|
||||
};
|
||||
|
||||
/*
|
||||
|
35
parser.c
35
parser.c
@ -175,23 +175,25 @@ insn *parse_line(int pass, char *buffer, insn * result,
|
||||
* For the moment, EQU has the same difficulty, so we'll
|
||||
* include that.
|
||||
*/
|
||||
if (result->opcode == I_RESB || result->opcode == I_RESW || result->opcode == I_RESD || result->opcode == I_RESQ || result->opcode == I_REST || result->opcode == I_EQU || result->opcode == I_INCBIN) { /* fbk */
|
||||
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_EQU || result->opcode == I_INCBIN) {
|
||||
critical = pass0;
|
||||
} else
|
||||
critical = (pass == 2 ? 2 : 0);
|
||||
|
||||
if (result->opcode == I_DB ||
|
||||
result->opcode == I_DW ||
|
||||
result->opcode == I_DD ||
|
||||
result->opcode == I_DQ ||
|
||||
result->opcode == I_DT || result->opcode == I_INCBIN) {
|
||||
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) {
|
||||
extop *eop, **tail = &result->eops, **fixptr;
|
||||
int oper_num = 0;
|
||||
|
||||
result->eops_float = FALSE;
|
||||
|
||||
/*
|
||||
* Begin to read the DB/DW/DD/DQ/DT/INCBIN operands.
|
||||
* Begin to read the DB/DW/DD/DQ/DT/DO/INCBIN operands.
|
||||
*/
|
||||
while (1) {
|
||||
i = stdscan(NULL, &tokval);
|
||||
@ -234,6 +236,8 @@ insn *parse_line(int pass, char *buffer, insn * result,
|
||||
eop->stringlen = 8;
|
||||
else if (result->opcode == I_DT)
|
||||
eop->stringlen = 10;
|
||||
else if (result->opcode == I_DO)
|
||||
eop->stringlen = 16;
|
||||
else {
|
||||
error(ERR_NONFATAL, "floating-point constant"
|
||||
" encountered in `D%c' instruction",
|
||||
@ -245,8 +249,7 @@ insn *parse_line(int pass, char *buffer, insn * result,
|
||||
*/
|
||||
eop->stringlen = 0;
|
||||
}
|
||||
eop =
|
||||
nasm_realloc(eop, sizeof(extop) + eop->stringlen);
|
||||
eop = nasm_realloc(eop, sizeof(extop) + eop->stringlen);
|
||||
tail = &eop->next;
|
||||
*fixptr = eop;
|
||||
eop->stringval = (char *)eop + sizeof(extop);
|
||||
@ -384,6 +387,11 @@ insn *parse_line(int pass, char *buffer, insn * result,
|
||||
result->oprs[operand].type |= BITS80;
|
||||
setsize = 1;
|
||||
break;
|
||||
case S_OWORD:
|
||||
if (!setsize)
|
||||
result->oprs[operand].type |= BITS128;
|
||||
setsize = 1;
|
||||
break;
|
||||
case S_TO:
|
||||
result->oprs[operand].type |= TO;
|
||||
break;
|
||||
@ -440,6 +448,9 @@ insn *parse_line(int pass, char *buffer, insn * result,
|
||||
case S_TWORD:
|
||||
result->oprs[operand].type |= BITS80;
|
||||
break;
|
||||
case S_OWORD:
|
||||
result->oprs[operand].type |= BITS128;
|
||||
break;
|
||||
default:
|
||||
error(ERR_NONFATAL,
|
||||
"invalid operand size specification");
|
||||
@ -751,7 +762,7 @@ insn *parse_line(int pass, char *buffer, insn * result,
|
||||
result->oprs[operand++].type = 0;
|
||||
|
||||
/*
|
||||
* Transform RESW, RESD, RESQ, REST into RESB.
|
||||
* Transform RESW, RESD, RESQ, REST, RESO into RESB.
|
||||
*/
|
||||
switch (result->opcode) {
|
||||
case I_RESW:
|
||||
@ -770,6 +781,10 @@ insn *parse_line(int pass, char *buffer, insn * result,
|
||||
result->opcode = I_RESB;
|
||||
result->oprs[0].offset *= 10;
|
||||
break;
|
||||
case I_RESO:
|
||||
result->opcode = I_RESB;
|
||||
result->oprs[0].offset *= 16;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ far
|
||||
long
|
||||
near
|
||||
nosplit
|
||||
oword
|
||||
qword
|
||||
rel
|
||||
short
|
||||
|
Loading…
Reference in New Issue
Block a user