diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2011-07-07 16:58:22 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2011-07-07 16:58:22 -0700 |
commit | fc561203fde370a5ab9db2d089053de51f8a5e04 (patch) | |
tree | 647ebb93b1706cc67d036804ffd3ae5e78134e18 | |
parent | 573aea590e2eb6d0cb4116c10a2a8fbdecf6a80f (diff) | |
download | nasm-fc561203fde370a5ab9db2d089053de51f8a5e04.tar.gz nasm-fc561203fde370a5ab9db2d089053de51f8a5e04.tar.bz2 nasm-fc561203fde370a5ab9db2d089053de51f8a5e04.zip |
Remove support for DREX encoding
The DREX encoding never hit production silicon, and has been replaced
by VEX/XOP encoding, so remove support for it.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r-- | assemble.c | 67 | ||||
-rw-r--r-- | disasm.c | 45 | ||||
-rwxr-xr-x | insns.pl | 14 | ||||
-rw-r--r-- | nasm.h | 8 |
4 files changed, 12 insertions, 122 deletions
@@ -66,13 +66,6 @@ * \150..\153 - an immediate dword or signed byte for operand 0..3 * \154..\157 - or 2 (s-field) into opcode byte if operand 0..3 * is a signed byte rather than a dword. Opcode byte follows. - * \160..\163 - this instruction uses DREX rather than REX, with the - * OC0 field set to 0, and the dest field taken from - * operand 0..3. - * \164..\167 - this instruction uses DREX rather than REX, with the - * OC0 field set to 1, and the dest field taken from - * operand 0..3. - * \171 - placement of DREX suffix in the absence of an EA * \172\ab - the register number from operand a in bits 7..4, with * the 4-bit immediate from operand b in bits 3..0. * \173\xab - the register number from operand a in bits 7..4, with @@ -908,21 +901,6 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, length++; break; - case4(0160): - length++; - ins->rex |= REX_D; - ins->drexdst = regval(opx); - break; - - case4(0164): - length++; - ins->rex |= REX_D|REX_OC; - ins->drexdst = regval(opx); - break; - - case 0171: - break; - case 0172: case 0173: case 0174: @@ -940,14 +918,14 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, case4(0260): ins->rex |= REX_V; - ins->drexdst = regval(opx); + ins->vexreg = regval(opx); ins->vex_cm = *codes++; ins->vex_wlp = *codes++; break; case 0270: ins->rex |= REX_V; - ins->drexdst = 0; + ins->vexreg = 0; ins->vex_cm = *codes++; ins->vex_wlp = *codes++; break; @@ -1178,7 +1156,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, break; } - if (bits != 64 && ((ins->rex & bad32) || ins->drexdst > 7)) { + if (bits != 64 && ((ins->rex & bad32) || ins->vexreg > 7)) { errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode"); return -1; } @@ -1186,17 +1164,6 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, length += 3; else length += 2; - } else if (ins->rex & REX_D) { - if (ins->rex & REX_H) { - errfunc(ERR_NONFATAL, "cannot use high register in drex instruction"); - return -1; - } - if (bits != 64 && ((ins->rex & (REX_R|REX_W|REX_X|REX_B)) || - ins->drexdst > 7)) { - errfunc(ERR_NONFATAL, "invalid operands in non-64-bit mode"); - return -1; - } - length++; } else if (ins->rex & REX_REAL) { if (ins->rex & REX_H) { errfunc(ERR_NONFATAL, "cannot use high register in rex instruction"); @@ -1219,7 +1186,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits, } #define EMIT_REX() \ - if (!(ins->rex & (REX_D|REX_V)) && (ins->rex & REX_REAL) && (bits == 64)) { \ + if (!(ins->rex & REX_V) && (ins->rex & REX_REAL) && (bits == 64)) { \ ins->rex = (ins->rex & REX_REAL)|REX_P; \ out(offset, segment, &ins->rex, OUT_RAWDATA, 1, NO_SEG, NO_SEG); \ ins->rex = 0; \ @@ -1499,20 +1466,6 @@ static void gencode(int32_t segment, int64_t offset, int bits, offset++; break; - case4(0160): - case4(0164): - break; - - case 0171: - bytes[0] = - (ins->drexdst << 4) | - (ins->rex & REX_OC ? 0x08 : 0) | - (ins->rex & (REX_R|REX_X|REX_B)); - ins->rex = 0; - out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG); - offset++; - break; - case 0172: c = *codes++; opx = &ins->oprs[c >> 3]; @@ -1588,13 +1541,13 @@ static void gencode(int32_t segment, int64_t offset, int bits, bytes[0] = (ins->vex_cm >> 6) ? 0x8f : 0xc4; bytes[1] = (ins->vex_cm & 31) | ((~ins->rex & 7) << 5); bytes[2] = ((ins->rex & REX_W) << (7-3)) | - ((~ins->drexdst & 15)<< 3) | (ins->vex_wlp & 07); + ((~ins->vexreg & 15)<< 3) | (ins->vex_wlp & 07); out(offset, segment, &bytes, OUT_RAWDATA, 3, NO_SEG, NO_SEG); offset += 3; } else { bytes[0] = 0xc5; bytes[1] = ((~ins->rex & REX_R) << (7-2)) | - ((~ins->drexdst & 15) << 3) | (ins->vex_wlp & 07); + ((~ins->vexreg & 15) << 3) | (ins->vex_wlp & 07); out(offset, segment, &bytes, OUT_RAWDATA, 2, NO_SEG, NO_SEG); offset += 2; } @@ -1858,14 +1811,6 @@ static void gencode(int32_t segment, int64_t offset, int bits, if (ea_data.sib_present) *p++ = ea_data.sib; - /* DREX suffixes come between the SIB and the displacement */ - if (ins->rex & REX_D) { - *p++ = (ins->drexdst << 4) | - (ins->rex & REX_OC ? 0x08 : 0) | - (ins->rex & (REX_R|REX_X|REX_B)); - ins->rex = 0; - } - s = p - bytes; out(offset, segment, bytes, OUT_RAWDATA, s, NO_SEG, NO_SEG); @@ -197,24 +197,6 @@ static enum reg_enum whichreg(opflags_t regflags, int regval, int rex) } /* - * Process a DREX suffix - */ -static uint8_t *do_drex(uint8_t *data, insn *ins) -{ - uint8_t drex = *data++; - operand *dst = &ins->oprs[ins->drexdst]; - - if ((drex & 8) != ((ins->rex & REX_OC) ? 8 : 0)) - return NULL; /* OC0 mismatch */ - ins->rex = (ins->rex & ~7) | (drex & 7); - - dst->segment = SEG_RMREG; - dst->basereg = drex >> 4; - return data; -} - - -/* * Process an effective address (ModRM) specification. */ static uint8_t *do_ea(uint8_t *data, int modrm, int asize, @@ -231,11 +213,6 @@ static uint8_t *do_ea(uint8_t *data, int modrm, int asize, if (mod != 3 && asize != 16 && rm == 4) sib = *data++; - if (ins->rex & REX_D) { - data = do_drex(data, ins); - if (!data) - return NULL; - } rex = ins->rex; if (mod == 3) { /* pure register version */ @@ -621,22 +598,6 @@ static int matches(const struct itemplate *t, uint8_t *data, } break; - case4(0160): - ins->rex |= REX_D; - ins->drexdst = op1; - break; - - case4(0164): - ins->rex |= REX_D|REX_OC; - ins->drexdst = op1; - break; - - case 0171: - data = do_drex(data, ins); - if (!data) - return false; - break; - case 0172: { uint8_t ximm = *data++; @@ -705,7 +666,7 @@ static int matches(const struct itemplate *t, uint8_t *data, int vexwlp = *r++; ins->rex |= REX_V; - if ((prefix->rex & (REX_V|REX_D|REX_P)) != REX_V) + if ((prefix->rex & (REX_V|REX_P)) != REX_V) return false; if ((vexm & 0x1f) != prefix->vex_m) @@ -945,8 +906,8 @@ static int matches(const struct itemplate *t, uint8_t *data, if (!vex_ok && (ins->rex & REX_V)) return false; - /* REX cannot be combined with DREX or VEX */ - if ((ins->rex & (REX_D|REX_V)) && (prefix->rex & REX_P)) + /* REX cannot be combined with VEX */ + if ((ins->rex & REX_V) && (prefix->rex & REX_P)) return false; /* @@ -649,7 +649,6 @@ sub startseq($$) { # r = register field in the modr/m # m = modr/m # v = VEX "v" field -# d = DREX "dst" field # i = immediate # s = register field of is4/imz2 field # - = implicit (unencoded) operand @@ -811,19 +810,6 @@ sub byte_code_compile($$) { push(@codes, defined($oppos{'v'}) ? 0260+($oppos{'v'} & 3) : 0270, ($c << 6)+$m, ($w << 4)+($l << 2)+$p); $prefix_ok = 0; - } elsif ($op =~ /^\/drex([01])$/) { - my $oc0 = $1; - if (!defined($oppos{'d'})) { - die "$fname: $line: DREX without a 'd' operand\n"; - } - # Note the use of *unshift* here, as opposed to *push*. - # This is because NASM want this byte code at the start of - # the instruction sequence, but the AMD documentation puts - # this at (roughly) the position of the drex byte itself. - # This allows us to match the AMD documentation and still - # do the right thing. - unshift(@codes, 0160+($oppos{'d'} & 3)+($oc0 ? 4 : 0)); - unshift(@codes, 05) if ($oppos{'d'} & 4); } elsif ($op =~ /^(ib\,s|ib|ibx|ib\,w|iw|iwd|id|idx|iwdq|rel|rel8|rel16|rel32|iq|seg|ibw|ibd|ibd,s)$/) { if (!defined($oppos{'i'})) { die "$fname: $line: $op without 'i' operand\n"; @@ -439,10 +439,8 @@ enum ccode { /* condition code names */ #define REX_L 0x20 /* Use LOCK prefix instead of REX.R */ #define REX_P 0x40 /* REX prefix present/required */ #define REX_H 0x80 /* High register present, REX forbidden */ -#define REX_D 0x0100 /* Instruction uses DREX instead of REX */ -#define REX_OC 0x0200 /* DREX suffix has the OC0 bit set */ -#define REX_V 0x0400 /* Instruction uses VEX/XOP instead of REX */ -#define REX_NH 0x0800 /* Instruction which doesn't use high regs */ +#define REX_V 0x0100 /* Instruction uses VEX/XOP instead of REX */ +#define REX_NH 0x0200 /* Instruction which doesn't use high regs */ /* * REX_V "classes" (prefixes which behave like VEX) @@ -558,7 +556,7 @@ typedef struct insn { /* an instruction itself */ int32_t times; /* repeat count (TIMES prefix) */ bool forw_ref; /* is there a forward reference? */ int rex; /* Special REX Prefix */ - int drexdst; /* Destination register for DREX/VEX suffix */ + int vexreg; /* Register encoded in VEX prefix */ int vex_cm; /* Class and M field for VEX prefix */ int vex_wlp; /* W, P and L information for VEX prefix */ } insn; |