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.
This commit is contained in:
H.J. Lu 2008-02-16 16:16:48 +00:00
parent eaf19029ad
commit 65da13b5e0
5 changed files with 72 additions and 49 deletions

View File

@ -1,3 +1,11 @@
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.
2008-02-14 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-i386.c (operand_type_all_zero): New.

View File

@ -1258,6 +1258,8 @@ operand_type_xor (i386_operand_type x, i386_operand_type y)
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 *mnemonic)
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;
}

View File

@ -1,3 +1,8 @@
2008-02-16 H.J. Lu <hongjiu.lu@intel.com>
* i386-gen.c (operand_type_init): Add OPERAND_TYPE_INOUTPORTREG.
* i386-init.h: Regenerated.
2008-02-14 Nick Clifton <nickc@redhat.com>
PR binutils/5524

View File

@ -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",

View File

@ -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, \