This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: PATCH: Remove InvMem from MMX/SSE instructions


On Mon, Jul 17, 2006 at 01:12:34PM -0700, H. J. Lu wrote:
> On Mon, Jul 17, 2006 at 06:18:58PM +0930, Alan Modra wrote:
> > On Sun, Jul 16, 2006 at 10:13:29AM -0700, H. J. Lu wrote:
> > > On Sun, Jul 16, 2006 at 01:23:56PM +0930, Alan Modra wrote:
> > > > On Thu, Jul 13, 2006 at 04:09:03PM -0700, H. J. Lu wrote:
> > > > > http://sourceware.org/ml/binutils/2001-05/msg00065.html
> > > > > http://sourceware.org/ml/binutils/2001-05/msg00187.html
> > > > > 
> > > > > use InvMem on source operand to indicate that it must be register. 
> > > > > I don't believe it is correct since RegYYY won't match memory anyway
> > > > > and InvMem is used to indicate how operand should be encoded. This
> > > > > patch removes it.
> > > > 
> > > > It's true that the way the code is currently written that removing this
> > > > flag will not change the insn encoding.  All InvMem does on *source*
> > > > operands of these reg->reg insns is document that the register is
> > > > encoded in the regmem field of the modrm byte.  So why do you want to
> > > > remove documentation?  There is certainly nothing wrong with InvMem on
> > > > these operands.
> > > 
> > > Those operands only take registers and are encoded properly. What
> > > additional information does InvMem provide here?
> > 
> > Didn't you read what I said?  To a programmer reading i386.h, InvMem
> > says that this particular register operand is encoded in the regmem
> > field, and the other register is encoded in the reg field.
> 
> InvMem is only checked on the destination register operand in
> instructions with 2 register operands. It looks like InvMem is really
> used on the destination register operand to indicate how to encode an 
> instruction with 2 register operands.
> 

This patch renames InvMem to RegMem and updates comments.



H.J.
----
gas/

2006-07-17  H.J. Lu  <hongjiu.lu@intel.com>

	* config/tc-i386.c (build_modrm_byte): Check RegMem instead of
	AnyMem. Update comments.

	* config/tc-i386.h (InvMem): Renamed to ...
	(RegMem): This.
	(AnyMem): Updated.

include/opcode/

2006-07-17  H.J. Lu  <hongjiu.lu@intel.com>

	* i386.h (i386_optab): Replace InvMem with RegMem.  Remove
	InvMem from sldt, smsw and str.

--- binutils/gas/config/tc-i386.c.invmem	2006-07-17 13:15:10.000000000 -0700
+++ binutils/gas/config/tc-i386.c	2006-07-17 13:57:28.000000000 -0700
@@ -3351,13 +3351,11 @@ build_modrm_byte ()
       dest = source + 1;
 
       i.rm.mode = 3;
-      /* One of the register operands will be encoded in the i.tm.reg
-	 field, the other in the combined i.tm.mode and i.tm.regmem
-	 fields.  If no form of this instruction supports a memory
-	 destination operand, then we assume the source operand may
-	 sometimes be a memory operand and so we need to store the
+      /* The register destination operand will be encoded in the
+	 i.rm.reg field or in the combined i.rm.mode and i.rm.regmem
+	 fields.  If its RegMem bit is 0, we need to store the
 	 destination in the i.rm.reg field.  */
-      if ((i.tm.operand_types[dest] & AnyMem) == 0)
+      if ((i.tm.operand_types[dest] & RegMem) == 0)
 	{
 	  i.rm.reg = i.op[dest].regs->reg_num;
 	  i.rm.regmem = i.op[source].regs->reg_num;
--- binutils/gas/config/tc-i386.h.invmem	2006-07-17 13:15:10.000000000 -0700
+++ binutils/gas/config/tc-i386.h	2006-07-17 13:43:49.000000000 -0700
@@ -285,12 +285,12 @@ typedef struct
 #define RegXMM	    0x20000000	/* XMM registers in PIII */
 #define EsSeg	    0x40000000	/* String insn operand with fixed es segment */
 
-  /* InvMem is for instructions with a modrm byte that only allow a
-     general register encoding in the i.tm.mode and i.tm.regmem fields,
-     eg. control reg moves.  They really ought to support a memory form,
-     but don't, so we add an InvMem flag to the register operand to
-     indicate that it should be encoded in the i.tm.regmem field.  */
-#define InvMem	    0x80000000
+  /* For instructions with 2 register operands, the destination operand
+     can be encoded in either the i.rm.reg field or the i.rm.mode and
+     i.rm.regmem fields.  We add a RegMem flag to the destination
+     operand to indicate that it should be encoded in the i.rm.regmem
+     field.  */
+#define RegMem	    0x80000000
 
 #define Reg	(Reg8|Reg16|Reg32|Reg64) /* gen'l register */
 #define WordReg (Reg16|Reg32|Reg64)
@@ -298,7 +298,9 @@ typedef struct
 #define Imm	(Imm8|Imm8S|Imm16|Imm32S|Imm32|Imm64) /* gen'l immediate */
 #define EncImm	(Imm8|Imm16|Imm32|Imm32S) /* Encodable gen'l immediate */
 #define Disp	(Disp8|Disp16|Disp32|Disp32S|Disp64) /* General displacement */
-#define AnyMem	(Disp8|Disp16|Disp32|Disp32S|BaseIndex|InvMem)	/* General memory */
+/* FIXME: We add RegMem to AnyMem.  But it only applies to the register
+   destination operand in instructions with 2 register operands.  */
+#define AnyMem	(Disp8|Disp16|Disp32|Disp32S|BaseIndex|RegMem)	/* General memory */
   /* The following aliases are defined because the opcode table
      carefully specifies the allowed memory types for each instruction.
      At the moment we can only tell a memory reference size by the
--- binutils/include/opcode/i386.h.invmem	2006-07-14 09:39:20.000000000 -0700
+++ binutils/include/opcode/i386.h	2006-07-17 13:45:01.000000000 -0700
@@ -98,9 +98,9 @@ static const template i386_optab[] =
    size prefix.  When moving to a 32 bit register, the upper 16 bits
    are set to an implementation defined value (on the Pentium Pro,
    the implementation defined value is zero).  */
-{ "mov",   2,	0x8c, X, 0,	 wl_Suf|Modrm,			{ SReg2, WordReg|InvMem, 0 } },
+{ "mov",   2,	0x8c, X, 0,	 wl_Suf|Modrm,			{ SReg2, WordReg|RegMem, 0 } },
 { "mov",   2,	0x8c, X, 0,	 w_Suf|Modrm|IgnoreSize,	{ SReg2, WordMem, 0 } },
-{ "mov",   2,	0x8c, X, Cpu386, wl_Suf|Modrm,			{ SReg3, WordReg|InvMem, 0 } },
+{ "mov",   2,	0x8c, X, Cpu386, wl_Suf|Modrm,			{ SReg3, WordReg|RegMem, 0 } },
 { "mov",   2,	0x8c, X, Cpu386, w_Suf|Modrm|IgnoreSize,	{ SReg3, WordMem, 0 } },
 { "mov",   2,	0x8e, X, 0,	 wl_Suf|Modrm|IgnoreSize,	{ WordReg, SReg2, 0 } },
 { "mov",   2,	0x8e, X, 0,	 w_Suf|Modrm|IgnoreSize,	{ WordMem, SReg2, 0 } },
@@ -108,11 +108,11 @@ static const template i386_optab[] =
 { "mov",   2,	0x8e, X, Cpu386, w_Suf|Modrm|IgnoreSize,	{ WordMem, SReg3, 0 } },
 /* Move to/from control debug registers.  In the 16 or 32bit modes they are 32bit.  In the 64bit
    mode they are 64bit.*/
-{ "mov",   2, 0x0f20, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,{ Control, Reg32|InvMem, 0} },
-{ "mov",   2, 0x0f20, X, Cpu64,	 q_Suf|D|Modrm|IgnoreSize|NoRex64,{ Control, Reg64|InvMem, 0} },
-{ "mov",   2, 0x0f21, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,{ Debug, Reg32|InvMem, 0} },
-{ "mov",   2, 0x0f21, X, Cpu64,	 q_Suf|D|Modrm|IgnoreSize|NoRex64,{ Debug, Reg64|InvMem, 0} },
-{ "mov",   2, 0x0f24, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,	{ Test, Reg32|InvMem, 0} },
+{ "mov",   2, 0x0f20, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,{ Control, Reg32|RegMem, 0} },
+{ "mov",   2, 0x0f20, X, Cpu64,	 q_Suf|D|Modrm|IgnoreSize|NoRex64,{ Control, Reg64|RegMem, 0} },
+{ "mov",   2, 0x0f21, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,{ Debug, Reg32|RegMem, 0} },
+{ "mov",   2, 0x0f21, X, Cpu64,	 q_Suf|D|Modrm|IgnoreSize|NoRex64,{ Debug, Reg64|RegMem, 0} },
+{ "mov",   2, 0x0f24, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,	{ Test, Reg32|RegMem, 0} },
 { "movabs",2,	0xa0, X, Cpu64, bwlq_Suf|D|W,			{ Disp64, Acc, 0 } },
 { "movabs",2,	0xb0, X, Cpu64,	q_Suf|W|ShortForm,		{ Imm64, Reg64, 0 } },
 
@@ -578,11 +578,11 @@ static const template i386_optab[] =
 {"sgdt",   1, 0x0f01, 0, Cpu64, q_Suf|Modrm|NoRex64,		{ LLongMem, 0, 0} },
 {"sidt",   1, 0x0f01, 1, Cpu286|CpuNo64, wl_Suf|Modrm,		{ WordMem, 0, 0} },
 {"sidt",   1, 0x0f01, 1, Cpu64, q_Suf|Modrm|NoRex64,		{ LLongMem, 0, 0} },
-{"sldt",   1, 0x0f00, 0, Cpu286, wlq_Suf|Modrm,		{ WordReg|InvMem, 0, 0} },
+{"sldt",   1, 0x0f00, 0, Cpu286, wlq_Suf|Modrm,		{ WordReg, 0, 0} },
 {"sldt",   1, 0x0f00, 0, Cpu286, w_Suf|Modrm|IgnoreSize,{ ShortMem, 0, 0} },
-{"smsw",   1, 0x0f01, 4, Cpu286, wlq_Suf|Modrm,		{ WordReg|InvMem, 0, 0} },
+{"smsw",   1, 0x0f01, 4, Cpu286, wlq_Suf|Modrm,		{ WordReg, 0, 0} },
 {"smsw",   1, 0x0f01, 4, Cpu286, w_Suf|Modrm|IgnoreSize,{ ShortMem, 0, 0} },
-{"str",	   1, 0x0f00, 1, Cpu286, wlq_Suf|Modrm,		{ WordReg|InvMem, 0, 0} },
+{"str",	   1, 0x0f00, 1, Cpu286, wlq_Suf|Modrm,		{ WordReg, 0, 0} },
 {"str",	   1, 0x0f00, 1, Cpu286, w_Suf|Modrm|IgnoreSize,{ ShortMem, 0, 0} },
 
 {"verr",   1, 0x0f00, 4, Cpu286, w_Suf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} },
@@ -1017,12 +1017,12 @@ static const template i386_optab[] =
 {"movq",   2,	0xb0, X, Cpu64,	 NoSuf|W|ShortForm|Size64,{ Imm64, Reg64, 0 } },
 /* The segment register moves accept Reg64 so that a segment register
    can be copied to a 64 bit register, and vice versa.  */
-{"movq",   2,	0x8c, X, Cpu64,  NoSuf|Modrm|Size64,	{ SReg2|SReg3, Reg64|InvMem, 0 } },
+{"movq",   2,	0x8c, X, Cpu64,  NoSuf|Modrm|Size64,	{ SReg2|SReg3, Reg64|RegMem, 0 } },
 {"movq",   2,	0x8e, X, Cpu64,	 NoSuf|Modrm|Size64,	{ Reg64, SReg2|SReg3, 0 } },
 /* Move to/from control debug registers.  In the 16 or 32bit modes they are 32bit.  In the 64bit
    mode they are 64bit.*/
-{"movq",   2, 0x0f20, X, Cpu64,	 NoSuf|D|Modrm|IgnoreSize|NoRex64|Size64,{ Control, Reg64|InvMem, 0} },
-{"movq",   2, 0x0f21, X, Cpu64,	 NoSuf|D|Modrm|IgnoreSize|NoRex64|Size64,{ Debug, Reg64|InvMem, 0} },
+{"movq",   2, 0x0f20, X, Cpu64,	 NoSuf|D|Modrm|IgnoreSize|NoRex64|Size64,{ Control, Reg64|RegMem, 0} },
+{"movq",   2, 0x0f21, X, Cpu64,	 NoSuf|D|Modrm|IgnoreSize|NoRex64|Size64,{ Debug, Reg64|RegMem, 0} },
 /* Real MMX instructions.  */
 {"packssdw", 2, 0x0f6b, X, CpuMMX, NoSuf|IgnoreSize|Modrm, { RegMMX|LongMem, RegMMX, 0 } },
 {"packssdw", 2, 0x660f6b,X,CpuSSE2,NoSuf|IgnoreSize|Modrm,		{ RegXMM|LLongMem, RegXMM, 0 } },


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]