public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH: Remove InvMem from MMX/SSE instructions
@ 2006-07-13 23:09 H. J. Lu
  2006-07-16  3:54 ` Alan Modra
  0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2006-07-13 23:09 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

Hi Alan,

Your patches

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.


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

	* i386.h (i386_optab): Remove InvMem from maskmovq, movhlps,
	movlhps, movmskps, pextrw, pmovmskb, movmskpd, maskmovdqu,
	movdq2q and movq2dq.

--- include/opcode/i386.h.invmem	2006-06-12 12:50:18.000000000 -0700
+++ include/opcode/i386.h	2006-07-13 15:51:55.000000000 -0700
@@ -1167,20 +1167,20 @@ static const template i386_optab[] =
 {"divps",     2, 0x0f5e,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"divss",     2, 0xf30f5e,  X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|WordMem, RegXMM, 0 } },
 {"ldmxcsr",   1, 0x0fae,    2, CpuSSE, NoSuf|IgnoreSize|Modrm, 	{ WordMem, 0, 0 } },
-{"maskmovq",  2, 0x0ff7,    X, CpuMMX2,NoSuf|IgnoreSize|Modrm,	{ RegMMX|InvMem, RegMMX, 0 } },
+{"maskmovq",  2, 0x0ff7,    X, CpuMMX2,NoSuf|IgnoreSize|Modrm,	{ RegMMX, RegMMX, 0 } },
 {"maxps",     2, 0x0f5f,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"maxss",     2, 0xf30f5f,  X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|WordMem, RegXMM, 0 } },
 {"minps",     2, 0x0f5d,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"minss",     2, 0xf30f5d,  X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|WordMem, RegXMM, 0 } },
 {"movaps",    2, 0x0f28,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"movaps",    2, 0x0f29,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM, RegXMM|LLongMem, 0 } },
-{"movhlps",   2, 0x0f12,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|InvMem, RegXMM, 0 } },
+{"movhlps",   2, 0x0f12,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM, RegXMM, 0 } },
 {"movhps",    2, 0x0f16,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ LLongMem, RegXMM, 0 } },
 {"movhps",    2, 0x0f17,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM, LLongMem, 0 } },
-{"movlhps",   2, 0x0f16,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM|InvMem, RegXMM, 0 } },
+{"movlhps",   2, 0x0f16,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM, RegXMM, 0 } },
 {"movlps",    2, 0x0f12,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ LLongMem, RegXMM, 0 } },
 {"movlps",    2, 0x0f13,    X, CpuSSE, NoSuf|IgnoreSize|Modrm,	{ RegXMM, LLongMem, 0 } },
-{"movmskps",  2, 0x0f50,    X, CpuSSE, lq_Suf|IgnoreSize|Modrm,	{ RegXMM|InvMem, Reg32|Reg64, 0 } },
+{"movmskps",  2, 0x0f50,    X, CpuSSE, lq_Suf|IgnoreSize|Modrm,	{ RegXMM, Reg32|Reg64, 0 } },
 {"movntps",   2, 0x0f2b,    X, CpuSSE, NoSuf|IgnoreSize|Modrm, 	{ RegXMM, LLongMem, 0 } },
 {"movntq",    2, 0x0fe7,    X, CpuMMX2,NoSuf|IgnoreSize|Modrm, 	{ RegMMX, LLongMem, 0 } },
 {"movntdq",   2, 0x660fe7,  X, CpuSSE2,NoSuf|IgnoreSize|Modrm, 	{ RegXMM, LLongMem, 0 } },
@@ -1195,8 +1195,8 @@ static const template i386_optab[] =
 {"pavgb",     2, 0x660fe0,  X, CpuSSE2,NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"pavgw",     2, 0x0fe3,    X, CpuMMX2,NoSuf|IgnoreSize|Modrm,	{ RegMMX|LLongMem, RegMMX, 0 } },
 {"pavgw",     2, 0x660fe3,  X, CpuSSE2,NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
-{"pextrw",    3, 0x0fc5,    X, CpuMMX2,lq_Suf|IgnoreSize|Modrm,	{ Imm8, RegMMX|InvMem, Reg32|Reg64 } },
-{"pextrw",    3, 0x660fc5,  X, CpuSSE2,lq_Suf|IgnoreSize|Modrm,	{ Imm8, RegXMM|InvMem, Reg32|Reg64 } },
+{"pextrw",    3, 0x0fc5,    X, CpuMMX2,lq_Suf|IgnoreSize|Modrm,	{ Imm8, RegMMX, Reg32|Reg64 } },
+{"pextrw",    3, 0x660fc5,  X, CpuSSE2,lq_Suf|IgnoreSize|Modrm,	{ Imm8, RegXMM, Reg32|Reg64 } },
 {"pinsrw",    3, 0x0fc4,    X, CpuMMX2,lq_Suf|IgnoreSize|Modrm,	{ Imm8, Reg32|Reg64|ShortMem, RegMMX } },
 {"pinsrw",    3, 0x660fc4,  X, CpuSSE2,lq_Suf|IgnoreSize|Modrm,	{ Imm8, Reg32|Reg64|ShortMem, RegXMM } },
 {"pmaxsw",    2, 0x0fee,    X, CpuMMX2,NoSuf|IgnoreSize|Modrm,	{ RegMMX|LLongMem, RegMMX, 0 } },
@@ -1207,8 +1207,8 @@ static const template i386_optab[] =
 {"pminsw",    2, 0x660fea,  X, CpuSSE2,NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"pminub",    2, 0x0fda,    X, CpuMMX2,NoSuf|IgnoreSize|Modrm,	{ RegMMX|LLongMem, RegMMX, 0 } },
 {"pminub",    2, 0x660fda,  X, CpuSSE2,NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
-{"pmovmskb",  2, 0x0fd7,    X, CpuMMX2,lq_Suf|IgnoreSize|Modrm,	{ RegMMX|InvMem, Reg32|Reg64, 0 } },
-{"pmovmskb",  2, 0x660fd7,  X, CpuSSE2,lq_Suf|IgnoreSize|Modrm,	{ RegXMM|InvMem, Reg32|Reg64, 0 } },
+{"pmovmskb",  2, 0x0fd7,    X, CpuMMX2,lq_Suf|IgnoreSize|Modrm,	{ RegMMX, Reg32|Reg64, 0 } },
+{"pmovmskb",  2, 0x660fd7,  X, CpuSSE2,lq_Suf|IgnoreSize|Modrm,	{ RegXMM, Reg32|Reg64, 0 } },
 {"pmulhuw",   2, 0x0fe4,    X, CpuMMX2,NoSuf|IgnoreSize|Modrm,	{ RegMMX|LLongMem, RegMMX, 0 } },
 {"pmulhuw",   2, 0x660fe4,  X, CpuSSE2,NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"prefetchnta", 1, 0x0f18,  0, CpuMMX2,NoSuf|IgnoreSize|Modrm, 	{ LLongMem, 0, 0 } },
@@ -1276,7 +1276,7 @@ static const template i386_optab[] =
 {"movhpd",    2, 0x660f17,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM, LLongMem, 0 } },
 {"movlpd",    2, 0x660f12,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ LLongMem, RegXMM, 0 } },
 {"movlpd",    2, 0x660f13,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM, LLongMem, 0 } },
-{"movmskpd",  2, 0x660f50,  X, CpuSSE2, lq_Suf|IgnoreSize|Modrm, { RegXMM|InvMem, Reg32|Reg64, 0 } },
+{"movmskpd",  2, 0x660f50,  X, CpuSSE2, lq_Suf|IgnoreSize|Modrm, { RegXMM, Reg32|Reg64, 0 } },
 {"movntpd",   2, 0x660f2b,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm, 	{ RegXMM, LLongMem, 0 } },
 /* Intel mode string move.  */
 {"movsd",     0, 0xa5,      X, 0, NoSuf|Size32|IsString, { 0, 0, 0} },
@@ -1311,13 +1311,13 @@ static const template i386_optab[] =
 {"cvttsd2si", 2, 0xf20f2c,  X, CpuSSE2, lq_Suf|IgnoreSize|Modrm,{ RegXMM|WordMem, Reg32|Reg64, 0 } },
 {"cvttpd2dq", 2, 0x660fe6,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"cvttps2dq", 2, 0xf30f5b,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
-{"maskmovdqu",2, 0x660ff7,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM|InvMem, RegXMM, 0 } },
+{"maskmovdqu",2, 0x660ff7,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM, RegXMM, 0 } },
 {"movdqa",    2, 0x660f6f,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"movdqa",    2, 0x660f7f,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM, RegXMM|LLongMem, 0 } },
 {"movdqu",    2, 0xf30f6f,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LLongMem, RegXMM, 0 } },
 {"movdqu",    2, 0xf30f7f,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM, RegXMM|LLongMem, 0 } },
-{"movdq2q",    2, 0xf20fd6,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM|InvMem, RegMMX, 0 } },
-{"movq2dq",   2, 0xf30fd6,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegMMX|InvMem, RegXMM, 0 } },
+{"movdq2q",    2, 0xf20fd6,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM, RegMMX, 0 } },
+{"movq2dq",   2, 0xf30fd6,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegMMX, RegXMM, 0 } },
 {"pmuludq",   2, 0x0ff4,    X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegMMX|LongMem, RegMMX, 0 } },
 {"pmuludq",   2, 0x660ff4,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ RegXMM|LongMem, RegXMM, 0 } },
 {"pshufd",    3, 0x660f70,  X, CpuSSE2, NoSuf|IgnoreSize|Modrm,	{ Imm8, RegXMM|LLongMem, RegXMM } },

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PATCH: Remove InvMem from MMX/SSE instructions
  2006-07-13 23:09 PATCH: Remove InvMem from MMX/SSE instructions H. J. Lu
@ 2006-07-16  3:54 ` Alan Modra
  2006-07-16 17:13   ` H. J. Lu
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Modra @ 2006-07-16  3:54 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

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.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PATCH: Remove InvMem from MMX/SSE instructions
  2006-07-16  3:54 ` Alan Modra
@ 2006-07-16 17:13   ` H. J. Lu
  2006-07-17  8:49     ` Alan Modra
  0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2006-07-16 17:13 UTC (permalink / raw)
  To: binutils

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?

I am trying to clean up the usage of InvMem. The commennt says:

  /* 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

However, there are

{"sldt",   1, 0x0f00, 0, Cpu286, wlq_Suf|Modrm,         { WordReg|InvMem, 0, 0} },
{"smsw",   1, 0x0f01, 4, Cpu286, wlq_Suf|Modrm,         { WordReg|InvMem, 0, 0} },
{"str",    1, 0x0f00, 1, Cpu286, wlq_Suf|Modrm,         { WordReg|InvMem, 0, 0} },

Those instructions take memory operand. InvMem seems to be used for something
else.


H.J.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PATCH: Remove InvMem from MMX/SSE instructions
  2006-07-16 17:13   ` H. J. Lu
@ 2006-07-17  8:49     ` Alan Modra
  2006-07-17 20:12       ` H. J. Lu
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Modra @ 2006-07-17  8:49 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

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.

> I am trying to clean up the usage of InvMem. The commennt says:
> 
>   /* 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
> 
> However, there are
> 
> {"sldt",   1, 0x0f00, 0, Cpu286, wlq_Suf|Modrm,         { WordReg|InvMem, 0, 0} },
> {"smsw",   1, 0x0f01, 4, Cpu286, wlq_Suf|Modrm,         { WordReg|InvMem, 0, 0} },
> {"str",    1, 0x0f00, 1, Cpu286, wlq_Suf|Modrm,         { WordReg|InvMem, 0, 0} },
> 
> Those instructions take memory operand.

Not this entry in the opcode table though.

> InvMem seems to be used for something else.

See above.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PATCH: Remove InvMem from MMX/SSE instructions
  2006-07-17  8:49     ` Alan Modra
@ 2006-07-17 20:12       ` H. J. Lu
  2006-07-17 21:14         ` H. J. Lu
  0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2006-07-17 20:12 UTC (permalink / raw)
  To: binutils

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.


H.J.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: PATCH: Remove InvMem from MMX/SSE instructions
  2006-07-17 20:12       ` H. J. Lu
@ 2006-07-17 21:14         ` H. J. Lu
  2006-07-18 20:01           ` RFC: Use long long in x86 assembler H. J. Lu
  0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2006-07-17 21:14 UTC (permalink / raw)
  To: binutils

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 } },

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RFC: Use long long in x86 assembler
  2006-07-17 21:14         ` H. J. Lu
@ 2006-07-18 20:01           ` H. J. Lu
  2006-07-18 22:48             ` Alan Modra
  0 siblings, 1 reply; 8+ messages in thread
From: H. J. Lu @ 2006-07-18 20:01 UTC (permalink / raw)
  To: binutils

On Mon, Jul 17, 2006 at 02:14:25PM -0700, H. J. Lu wrote:
> 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.
> 
> 

I really don't like it since InvMem/RegMem is included in AnyMem,
but it is really meanful in the destination register operand. It
really belongs to opcode_modifier. I'd like to add a bit to
opcode_modifier. But that means long long will be used since there
is no unused bit in opcode_modifier. I timed "make check" in gas on
both x86 and x86-64. I got

1. On x86-64:

int: 18.57s user 5.17s system 85% cpu 27.738 total
long long: 18.70s user 5.18s system 85% cpu 27.802 total

2. On x86:

int: 14.19s user 2.24s system 83% cpu 19.726 total
long long: 14.29s user 2.13s system 88% cpu 18.593 total

The difference is quite small. Any objections to use long long in x86
assemblers?



H.J.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RFC: Use long long in x86 assembler
  2006-07-18 20:01           ` RFC: Use long long in x86 assembler H. J. Lu
@ 2006-07-18 22:48             ` Alan Modra
  0 siblings, 0 replies; 8+ messages in thread
From: Alan Modra @ 2006-07-18 22:48 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Tue, Jul 18, 2006 at 01:01:21PM -0700, H. J. Lu wrote:
> The difference is quite small. Any objections to use long long in x86
> assemblers?

You are making totally unnecessary changes.  I object.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-07-18 22:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-07-13 23:09 PATCH: Remove InvMem from MMX/SSE instructions H. J. Lu
2006-07-16  3:54 ` Alan Modra
2006-07-16 17:13   ` H. J. Lu
2006-07-17  8:49     ` Alan Modra
2006-07-17 20:12       ` H. J. Lu
2006-07-17 21:14         ` H. J. Lu
2006-07-18 20:01           ` RFC: Use long long in x86 assembler H. J. Lu
2006-07-18 22:48             ` Alan Modra

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).