mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-25 18:10:23 +08:00
Add support for instructions which always use low 8-bit registers
Add a byte code to explicitly support instructions which only uses the low 8-bit registers (as if a REX prefix always was present.) This is usable for instructions which are officially documented as using "the low byte of a 32-bit register" and so on. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
f9fc3fde55
commit
9472dab6ed
18
assemble.c
18
assemble.c
@ -88,13 +88,14 @@
|
||||
* generates no code in the assembler)
|
||||
* \323 - indicates fixed 64-bit operand size, REX on extensions only.
|
||||
* \324 - indicates 64-bit operand size requiring REX prefix.
|
||||
* \325 - instruction which always uses spl/bpl/sil/dil
|
||||
* \330 - a literal byte follows in the code stream, to be added
|
||||
* to the condition code value of the instruction.
|
||||
* \331 - instruction not valid with REP prefix. Hint for
|
||||
* disassembler only; for SSE instructions.
|
||||
* \332 - REP prefix (0xF2 byte) used as opcode extension.
|
||||
* \333 - REP prefix (0xF3 byte) used as opcode extension.
|
||||
* \334 - LOCK prefix used instead of REX.R
|
||||
* \334 - LOCK prefix used as REX.R (used in non-64-bit mode)
|
||||
* \335 - disassemble a rep (0xF3 byte) prefix as repe not rep.
|
||||
* \336 - force a REP(E) prefix (0xF2) even if not specified.
|
||||
* \337 - force a REPNE prefix (0xF3) even if not specified.
|
||||
@ -996,6 +997,10 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
|
||||
ins->rex |= REX_W;
|
||||
break;
|
||||
|
||||
case 0325:
|
||||
ins->rex |= REX_NH;
|
||||
break;
|
||||
|
||||
case 0330:
|
||||
codes++, length++;
|
||||
break;
|
||||
@ -1117,6 +1122,14 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
|
||||
|
||||
ins->rex &= rex_mask;
|
||||
|
||||
if (ins->rex & REX_NH) {
|
||||
if (ins->rex & REX_H) {
|
||||
errfunc(ERR_NONFATAL, "instruction cannot use high registers");
|
||||
return -1;
|
||||
}
|
||||
ins->rex &= ~REX_P; /* Don't force REX prefix due to high reg */
|
||||
}
|
||||
|
||||
if (ins->rex & REX_V) {
|
||||
int bad32 = REX_R|REX_W|REX_X|REX_B;
|
||||
|
||||
@ -1645,6 +1658,9 @@ static void gencode(int32_t segment, int64_t offset, int bits,
|
||||
ins->rex |= REX_W;
|
||||
break;
|
||||
|
||||
case 0325:
|
||||
break;
|
||||
|
||||
case 0330:
|
||||
*bytes = *codes++ ^ condval[ins->condition];
|
||||
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
|
||||
|
8
disasm.c
8
disasm.c
@ -135,7 +135,7 @@ static enum reg_enum whichreg(int32_t regflags, int regval, int rex)
|
||||
return 0;
|
||||
|
||||
if (!(REG8 & ~regflags)) {
|
||||
if (rex & REX_P)
|
||||
if (rex & (REX_P|REX_NH))
|
||||
return nasm_rd_reg8_rex[regval];
|
||||
else
|
||||
return nasm_rd_reg8[regval];
|
||||
@ -153,7 +153,7 @@ static enum reg_enum whichreg(int32_t regflags, int regval, int rex)
|
||||
if (!(REG_DREG & ~regflags))
|
||||
return nasm_rd_dreg[regval];
|
||||
if (!(REG_TREG & ~regflags)) {
|
||||
if (rex & REX_P)
|
||||
if (regval > 7)
|
||||
return 0; /* TR registers are ill-defined with rex */
|
||||
return nasm_rd_treg[regval];
|
||||
}
|
||||
@ -799,6 +799,10 @@ static int matches(const struct itemplate *t, uint8_t *data,
|
||||
o_used = true;
|
||||
break;
|
||||
|
||||
case 0325:
|
||||
ins->rex |= REX_NH;
|
||||
break;
|
||||
|
||||
case 0330:
|
||||
{
|
||||
int t = *r++, d = *data++;
|
||||
|
1
nasm.h
1
nasm.h
@ -600,6 +600,7 @@ enum ccode { /* condition code names */
|
||||
#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 */
|
||||
|
||||
/*
|
||||
* REX_V "classes" (prefixes which behave like VEX)
|
||||
|
Loading…
x
Reference in New Issue
Block a user