aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-i386.c
diff options
context:
space:
mode:
Diffstat (limited to 'gas/config/tc-i386.c')
-rw-r--r--gas/config/tc-i386.c101
1 files changed, 52 insertions, 49 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 79f4a76..9190fcf 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -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;
}