mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-01-18 16:25:05 +08:00
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>
This commit is contained in:
parent
573aea590e
commit
fc561203fd
67
assemble.c
67
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);
|
||||
|
||||
|
45
disasm.c
45
disasm.c
@ -196,24 +196,6 @@ static enum reg_enum whichreg(opflags_t regflags, int regval, int rex)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@ -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;
|
||||
|
||||
/*
|
||||
|
14
insns.pl
14
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";
|
||||
|
8
nasm.h
8
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;
|
||||
|
Loading…
Reference in New Issue
Block a user