summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-09-18 13:01:32 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-09-18 13:01:32 -0700
commit41c9f6fde06091199f1a95e0c045230baaa25bf4 (patch)
tree35df1b3c570cd4e3611acd94f7e2ee0b51d45f3e
parent5255fd1f36eece1cbf4000ffc3120dbcb9bf5038 (diff)
downloadnasm-41c9f6fde06091199f1a95e0c045230baaa25bf4.tar.gz
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.
-rw-r--r--assemble.c7
-rw-r--r--insns.dat26
-rw-r--r--insns.h1
-rw-r--r--nasm.h10
-rw-r--r--parser.c35
-rw-r--r--tokens.dat1
6 files changed, 56 insertions, 24 deletions
diff --git a/assemble.c b/assemble.c
index ec3b1124..e5384548 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 5214ee52..f95b157e 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 c7fa75a0..b5d6caf7 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 f5d64946..f4afad36 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 16164d77..ca12a097 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 6acaba49..c84b8fb3 100644
--- a/tokens.dat
+++ b/tokens.dat
@@ -23,6 +23,7 @@ far
long
near
nosplit
+oword
qword
rel
short