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:
H. Peter Anvin 2007-09-18 13:01:32 -07:00
parent 5255fd1f36
commit 41c9f6fde0
6 changed files with 56 additions and 24 deletions

View File

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

View File

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

View File

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

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

View File

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

View File

@ -23,6 +23,7 @@ far
long
near
nosplit
oword
qword
rel
short