This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: x86: Decouple base_opcode from opcode_modifier
- From: "H. J. Lu" <hjl at lucon dot org>
- To: binutils at sources dot redhat dot com
- Date: Mon, 12 Mar 2007 14:25:11 -0700
- Subject: PATCH: x86: Decouple base_opcode from opcode_modifier
- References: <20070212155323.GA8495@lucon.org> <20070213232407.GB15831@bubble.grove.modra.org> <20070214001412.GA30144@lucon.org> <20070214015134.GA8541@bubble.grove.modra.org> <20070214020138.GA30518@lucon.org> <20070312190508.GA7845@lucon.org>
On Mon, Mar 12, 2007 at 12:05:08PM -0700, H. J. Lu wrote:
>
> We can use designated initializer in include/opcode/i386.h. We put a
> generated copy of it, i386-inst.h, in gas/config, which doesn't
> use designated initializer. tc-i386.c will include i386-inst.h
> instead of opcode/i386.h. We will put a tool in gas to generate
> gas/config/i386-inst.h from include/opcode/i386.h. We can require
> that such a tool has to be compiled with a C99 compiler.
>
The first problem is that we use the same bits for both base_opcode
and opcode_modifier. That means we can't use bitfileds on
opcode_modifier. I am checking in this patch to decouple
base_opcode from opcode_modifier.
H.J.
---
2007-03-12 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (md_assemble): Use Opcode_XXX instead of XXX
on i.tm.base_opcode.
(match_template): Likewise.
(process_operands): Use ~0x3 mask to match MOV_AX_DISP32.
* config/tc-i386.h (Opcode_D): New.
(Opcode_FloatR): Likewise.
(Opcode_FloatD): Likewise.
(D): Redefined.
(W): Likewise.
(FloatMF): Likewise.
(FloatR): Likewise.
(FloatD): Likewise.
--- gas/config/tc-i386.c.op 2007-02-13 17:26:42.000000000 -0800
+++ gas/config/tc-i386.c 2007-03-12 14:05:07.000000000 -0700
@@ -1766,7 +1766,7 @@ md_assemble (line)
/* Undo SYSV386_COMPAT brokenness when in Intel mode. See i386.h */
if (SYSV386_COMPAT
&& (i.tm.base_opcode & 0xfffffde0) == 0xdce0)
- i.tm.base_opcode ^= FloatR;
+ i.tm.base_opcode ^= Opcode_FloatR;
/* Zap movzx and movsx suffix. The suffix may have been set from
"word ptr" or "byte ptr" on the source operand, but we'll use
@@ -2657,7 +2657,14 @@ match_template (void)
}
/* found_reverse_match holds which of D or FloatDR
we've found. */
- found_reverse_match = t->opcode_modifier & (D | FloatDR);
+ if ((t->opcode_modifier & D))
+ found_reverse_match = Opcode_D;
+ else if ((t->opcode_modifier & FloatD))
+ found_reverse_match = Opcode_FloatD;
+ else
+ found_reverse_match = 0;
+ if ((t->opcode_modifier & FloatR))
+ found_reverse_match |= Opcode_FloatR;
}
else
{
@@ -3322,7 +3329,7 @@ process_operands (void)
default_seg = build_modrm_byte ();
}
- else if ((i.tm.base_opcode & ~(D | W)) == MOV_AX_DISP32)
+ else if ((i.tm.base_opcode & ~0x3) == MOV_AX_DISP32)
{
default_seg = &ds;
}
--- gas/config/tc-i386.h.op 2007-03-09 10:59:28.000000000 -0800
+++ gas/config/tc-i386.h 2007-03-12 14:13:30.000000000 -0700
@@ -159,6 +159,11 @@ typedef struct
/* base_opcode is the fundamental opcode byte without optional
prefix(es). */
unsigned int base_opcode;
+#define Opcode_D 0x2 /* Diretion bit:
+ set if Reg --> Regmem;
+ unset if Regmem --> Reg. */
+#define Opcode_FloatR 0x8 /* Bit to swap src/dest for float insns. */
+#define Opcode_FloatD 0x400 /* Direction bit for float insns. */
/* extension_opcode is the 3 bit extension for group <n> insns.
This field is also used to store the 8-bit opcode suffix for the
@@ -207,19 +212,18 @@ typedef struct
unsigned int opcode_modifier;
/* opcode_modifier bits: */
-#define W 0x1 /* set if operands can be words or dwords
+#define D 0x1 /* has direction bit. */
+#define W 0x2 /* set if operands can be words or dwords
encoded the canonical way */
-#define D 0x2 /* D = 0 if Reg --> Regmem;
- D = 1 if Regmem --> Reg: MUST BE 0x2 */
-#define Modrm 0x4
-#define FloatR 0x8 /* src/dest swap for floats: MUST BE 0x8 */
+#define Modrm 0x4 /* insn has a modrm byte. */
#define ShortForm 0x10 /* register is in low 3 bits of opcode */
-#define FloatMF 0x20 /* FP insn memory format bit, sized by 0x4 */
#define Jump 0x40 /* special case for jump insns. */
#define JumpDword 0x80 /* call and jump */
#define JumpByte 0x100 /* loop and jecxz */
#define JumpInterSegment 0x200 /* special case for intersegment leaps/calls */
-#define FloatD 0x400 /* direction for float insns: MUST BE 0x400 */
+#define FloatMF 0x400 /* FP insn memory format bit, sized by 0x4 */
+#define FloatR 0x800 /* src/dest swap for floats. */
+#define FloatD 0x1000 /* has float insn direction bit. */
#define Size16 0x2000 /* needs size prefix if in 32-bit mode */
#define Size32 0x4000 /* needs size prefix if in 16-bit mode */
#define Size64 0x8000 /* needs size prefix if in 64-bit mode */