This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Update x86 assembler
- From: "H.J. Lu" <hjl dot tools at gmail dot com>
- To: binutils at sources dot redhat dot com
- Date: Sat, 16 Feb 2008 08:14:27 -0800
- Subject: PATCH: Update x86 assembler
I am checking in this patch to optimize x86 assembler a little bit.
H.J.
----
gas/
2008-02-16 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (inoutportreg): New.
(process_immext): New.
(md_assemble): Use it.
(update_imm): Use imm16 and imm32s.
(i386_att_operand): Use inoutportreg.
opcodes/
2008-02-16 H.J. Lu <hongjiu.lu@intel.com>
* i386-gen.c (operand_type_init): Add OPERAND_TYPE_INOUTPORTREG.
* i386-init.h: Regenerated.
--- binutils/gas/config/tc-i386.c.foo 2008-02-15 06:06:02.000000000 -0800
+++ binutils/gas/config/tc-i386.c 2008-02-16 08:10:41.000000000 -0800
@@ -1258,6 +1258,8 @@ operand_type_xor (i386_operand_type x, i
static const i386_operand_type acc32 = OPERAND_TYPE_ACC32;
static const i386_operand_type acc64 = OPERAND_TYPE_ACC64;
static const i386_operand_type control = OPERAND_TYPE_CONTROL;
+static const i386_operand_type inoutportreg
+ = OPERAND_TYPE_INOUTPORTREG;
static const i386_operand_type reg16_inoutportreg
= OPERAND_TYPE_REG16_INOUTPORTREG;
static const i386_operand_type disp16 = OPERAND_TYPE_DISP16;
@@ -2393,13 +2395,57 @@ intel_float_operand (const char *mnemoni
return 1;
}
+static void
+process_immext (void)
+{
+ expressionS *exp;
+
+ if (i.tm.cpu_flags.bitfield.cpusse3 && i.operands > 0)
+ {
+ /* SSE3 Instructions have the fixed operands with an opcode
+ suffix which is coded in the same place as an 8-bit immediate
+ field would be. Here we check those operands and remove them
+ afterwards. */
+ unsigned int x;
+
+ for (x = 0; x < i.operands; x++)
+ if (i.op[x].regs->reg_num != x)
+ as_bad (_("can't use register '%s%s' as operand %d in '%s'."),
+ register_prefix,
+ i.op[x].regs->reg_name,
+ x + 1,
+
+ i.tm.name); i.operands = 0;
+ }
+
+ /* These AMD 3DNow! and SSE2 Instructions have an opcode suffix
+ which is coded in the same place as an 8-bit immediate field
+ would be. Here we fake an 8-bit immediate operand from the
+ opcode suffix stored in tm.extension_opcode.
+
+ SSE5 also uses this encoding, for some of its 3 argument
+ instructions. */
+
+ assert (i.imm_operands == 0
+ && (i.operands <= 2
+ || (i.tm.cpu_flags.bitfield.cpusse5
+ && i.operands <= 3)));
+
+ exp = &im_expressions[i.imm_operands++];
+ i.op[i.operands].imms = exp;
+ i.types[i.operands] = imm8;
+ i.operands++;
+ exp->X_op = O_constant;
+ exp->X_add_number = i.tm.extension_opcode;
+ i.tm.extension_opcode = None;
+}
+
/* This is the guts of the machine-dependent assembler. LINE points to a
machine dependent instruction. This function is supposed to emit
the frags/bytes it assembles to. */
void
-md_assemble (line)
- char *line;
+md_assemble (char *line)
{
unsigned int j;
char mnemonic[MAX_MNEM_SIZE];
@@ -2509,48 +2555,7 @@ md_assemble (line)
i.reg_operands--;
if (i.tm.opcode_modifier.immext)
- {
- expressionS *exp;
-
- if (i.tm.cpu_flags.bitfield.cpusse3 && i.operands > 0)
- {
- /* Streaming SIMD extensions 3 Instructions have the fixed
- operands with an opcode suffix which is coded in the same
- place as an 8-bit immediate field would be. Here we check
- those operands and remove them afterwards. */
- unsigned int x;
-
- for (x = 0; x < i.operands; x++)
- if (i.op[x].regs->reg_num != x)
- as_bad (_("can't use register '%s%s' as operand %d in '%s'."),
- register_prefix,
- i.op[x].regs->reg_name,
- x + 1,
- i.tm.name);
- i.operands = 0;
- }
-
- /* These AMD 3DNow! and Intel Katmai New Instructions have an
- opcode suffix which is coded in the same place as an 8-bit
- immediate field would be. Here we fake an 8-bit immediate
- operand from the opcode suffix stored in tm.extension_opcode.
- SSE5 also uses this encoding, for some of its 3 argument
- instructions. */
-
- assert (i.imm_operands == 0
- && (i.operands <= 2
- || (i.tm.cpu_flags.bitfield.cpusse5
- && i.operands <= 3)));
-
- exp = &im_expressions[i.imm_operands++];
- i.op[i.operands].imms = exp;
- operand_type_set (&i.types[i.operands], 0);
- i.types[i.operands].bitfield.imm8 = 1;
- i.operands++;
- exp->X_op = O_constant;
- exp->X_add_number = i.tm.extension_opcode;
- i.tm.extension_opcode = None;
- }
+ process_immext ();
/* For insns with operands there are more diddles to do to the opcode. */
if (i.operands)
@@ -4123,11 +4128,10 @@ update_imm (unsigned int j)
|| operand_type_equal (&overlap, &imm16_32)
|| operand_type_equal (&overlap, &imm16_32s))
{
- operand_type_set (&overlap, 0);
if ((flag_code == CODE_16BIT) ^ (i.prefix[DATA_PREFIX] != 0))
- overlap.bitfield.imm16 = 1;
+ overlap = imm16;
else
- overlap.bitfield.imm32s = 1;
+ overlap = imm32s;
}
if (!operand_type_equal (&overlap, &imm8)
&& !operand_type_equal (&overlap, &imm8s)
@@ -6603,8 +6607,7 @@ i386_att_operand (char *operand_string)
&& i.seg[i.mem_operands] == 0
&& !operand_type_check (i.types[this_operand], disp))
{
- operand_type_set (&i.types[this_operand], 0);
- i.types[this_operand].bitfield.inoutportreg = 1;
+ i.types[this_operand] = inoutportreg;
return 1;
}
--- binutils/opcodes/i386-gen.c.foo 2008-02-14 06:46:47.000000000 -0800
+++ binutils/opcodes/i386-gen.c 2008-02-16 08:01:41.000000000 -0800
@@ -188,6 +188,8 @@ static initializer operand_type_init []
"Reg32|Acc|Dword" },
{ "OPERAND_TYPE_ACC64",
"Reg64|Acc|Qword" },
+ { "OPERAND_TYPE_INOUTPORTREG",
+ "InOutPortReg" },
{ "OPERAND_TYPE_REG16_INOUTPORTREG",
"Reg16|InOutPortReg" },
{ "OPERAND_TYPE_DISP16_32",
--- binutils/opcodes/i386-init.h.foo 2008-02-11 21:35:51.000000000 -0800
+++ binutils/opcodes/i386-init.h 2008-02-16 08:02:14.000000000 -0800
@@ -341,6 +341,11 @@
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, \
0, 0, 0 } }
+#define OPERAND_TYPE_INOUTPORTREG \
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ 0, 0, 0 } }
+
#define OPERAND_TYPE_REG16_INOUTPORTREG \
{ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \