Support r/m operands for non-integer types

Support r/m operands for non-integer operands types, i.e. mmx or xmm
operands.  This allows mmx and xmm operands to be written more
compactly, speeding up the assembler.
This commit is contained in:
H. Peter Anvin 2007-09-12 20:32:39 -07:00
parent 16b0a33cea
commit 0da6b580eb
4 changed files with 27 additions and 13 deletions

View file

@ -79,6 +79,11 @@ static uint64_t getu64(uint8_t *data)
/* Important: regval must already have been adjusted for rex extensions */
static enum reg_enum whichreg(int32_t regflags, int regval, int rex)
{
if (!(regflags & (REGISTER|REGMEM)))
return 0; /* Registers not permissible?! */
regflags |= REGISTER;
if (!(REG_AL & ~regflags))
return R_AL;
if (!(REG_AX & ~regflags))
@ -119,17 +124,17 @@ static enum reg_enum whichreg(int32_t regflags, int regval, int rex)
if (regval < 0 || regval > 15)
return 0;
if (!((REGMEM | BITS8) & ~regflags)) {
if (!(REG8 & ~regflags)) {
if (rex & REX_P)
return rd_reg8_rex[regval];
else
return rd_reg8[regval];
}
if (!((REGMEM | BITS16) & ~regflags))
if (!(REG16 & ~regflags))
return rd_reg16[regval];
if (!((REGMEM | BITS32) & ~regflags))
if (!(REG32 & ~regflags))
return rd_reg32[regval];
if (!((REGMEM | BITS64) & ~regflags))
if (!(REG64 & ~regflags))
return rd_reg64[regval];
if (!(REG_SREG & ~regflags))
return rd_sreg[regval & 7]; /* Ignore REX */

View file

@ -215,7 +215,9 @@ sub format {
$operands =~ s/memory_offs/mem_offs/g;
$operands =~ s/imm(\d+)/imm|bits$1/g;
$operands =~ s/imm/immediate/g;
$operands =~ s/rm(\d+)/regmem|bits$1/g;
$operands =~ s/rm(\d+)/rm_gpr|bits$1/g;
$operands =~ s/mmxrm/rm_mmx/g;
$operands =~ s/xmmrm/rm_xmm/g;
$num = 3;
$operands = '0,0,0', $num = 0 if $operands eq 'void';
$operands .= ',0', $num-- while $operands !~ /,.*,/;

20
nasm.h
View file

@ -432,12 +432,12 @@ enum {
*
* Bits 20-26: register classes
* 20: REG_CDT (CRx, DRx, TRx)
* 21: REG_GPR (integer register)
* 21: RM_GPR (REG_GPR) (integer register)
* 22: REG_SREG
* 23: IP_REG (RIP or EIP) [unused]
* 24: FPUREG
* 25: MMXREG
* 26: XMMREG
* 25: RM_MMX (MMXREG)
* 26: RM_XMM (XMMREG)
*
* Bits 27-31 are currently unallocated.
*/
@ -470,6 +470,7 @@ enum {
/* Register classes */
#define REG_EA 0x00009000L /* 'normal' reg, qualifies as EA */
#define RM_GPR 0x00208000L /* integer operand */
#define REG_GPR 0x00209000L /* integer register */
#define REG8 0x00209001L /* 8-bit GPR */
#define REG16 0x00209002L /* 16-bit GPR */
@ -480,8 +481,10 @@ enum {
#define EIPREG 0x00801004L /* EIP */
#define FPUREG 0x01001000L /* floating point stack registers */
#define FPU0 0x01011000L /* FPU stack register zero */
#define MMXREG 0x02009000L /* MMX registers */
#define XMMREG 0x04009000L /* XMM Katmai reg */
#define RM_MMX 0x02008000L /* MMX operand */
#define MMXREG 0x02009000L /* MMX register */
#define RM_XMM 0x04008000L /* XMM (SSE) operand */
#define XMMREG 0x04009000L /* XMM (SSE) register */
#define REG_CDT 0x00101004L /* CRn, DRn and TRn */
#define REG_CREG 0x00111004L /* CRn */
#define REG_DREG 0x00121004L /* DRn */
@ -514,8 +517,11 @@ enum {
#define REG_HIGH 0x00289001L /* high regs: AH, CH, DH, BH */
/* special types of EAs */
#define MEM_OFFS 0x00214000L /* simple [address] offset - absolute! */
#define IP_REL 0x00224000L /* IP-relative offset */
#define MEM_OFFS 0x0001c000L /* simple [address] offset - absolute! */
#define IP_REL 0x0002c000L /* IP-relative offset */
/* memory which matches any type of r/m operand */
#define MEMORY_ANY (MEMORY|RM_GPR|RM_MMX|RM_XMM)
/* special type of immediate operand */
#define UNITY 0x00012000L /* for shift/rotate instructions */

View file

@ -667,7 +667,8 @@ insn *parse_line(int pass, char *buffer, insn * result,
return result;
}
result->oprs[operand].type |= MEMORY;
/* It is memory, but it can match any r/m operand */
result->oprs[operand].type |= MEMORY_ANY;
if (b == -1 && (i == -1 || s == 0)) {
int is_rel = globalbits == 64 &&