summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2011-07-07 16:58:22 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2011-07-07 16:58:22 -0700
commitfc561203fde370a5ab9db2d089053de51f8a5e04 (patch)
tree647ebb93b1706cc67d036804ffd3ae5e78134e18
parent573aea590e2eb6d0cb4116c10a2a8fbdecf6a80f (diff)
downloadnasm-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.c67
-rw-r--r--disasm.c45
-rwxr-xr-xinsns.pl14
-rw-r--r--nasm.h8
4 files changed, 12 insertions, 122 deletions
diff --git a/assemble.c b/assemble.c
index ed5ef8e..17def3a 100644
--- a/assemble.c
+++ b/assemble.c
@@ -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);
diff --git a/disasm.c b/disasm.c
index 5943966..5c9d6db 100644
--- a/disasm.c
+++ b/disasm.c
@@ -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;
/*
diff --git a/insns.pl b/insns.pl
index 0b29757..6db1c82 100755
--- a/insns.pl
+++ b/insns.pl
@@ -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";
diff --git a/nasm.h b/nasm.h
index 453a57c..f8f62be 100644
--- a/nasm.h
+++ b/nasm.h
@@ -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;