From 41c9f6fde06091199f1a95e0c045230baaa25bf4 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 18 Sep 2007 13:01:32 -0700 Subject: [PATCH] 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. --- assemble.c | 7 +++++++ insns.dat | 26 ++++++++++++++++---------- insns.h | 1 + nasm.h | 10 ++++++---- parser.c | 35 +++++++++++++++++++++++++---------- tokens.dat | 1 + 6 files changed, 56 insertions(+), 24 deletions(-) diff --git a/assemble.c b/assemble.c index ec3b112..e538454 100644 --- a/assemble.c +++ b/assemble.c @@ -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; } diff --git a/insns.dat b/insns.dat index 5214ee5..f95b157 100644 --- a/insns.dat +++ b/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 diff --git a/insns.h b/insns.h index c7fa75a..b5d6caf 100644 --- a/insns.h +++ b/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 */ diff --git a/nasm.h b/nasm.h index f5d6494..f4afad3 100644 --- a/nasm.h +++ b/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 }; /* diff --git a/parser.c b/parser.c index 16164d7..ca12a09 100644 --- a/parser.c +++ b/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; } diff --git a/tokens.dat b/tokens.dat index 6acaba4..c84b8fb 100644 --- a/tokens.dat +++ b/tokens.dat @@ -23,6 +23,7 @@ far long near nosplit +oword qword rel short -- 2.7.4