diff options
-rw-r--r-- | gas/ChangeLog | 8 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 101 | ||||
-rw-r--r-- | opcodes/ChangeLog | 5 | ||||
-rw-r--r-- | opcodes/i386-gen.c | 2 | ||||
-rw-r--r-- | opcodes/i386-init.h | 5 |
5 files changed, 72 insertions, 49 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 87f4c6f..3a28e9b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -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. 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; } diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index d750f8f..e5ef349 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -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 diff --git a/opcodes/i386-gen.c b/opcodes/i386-gen.c index 04413dc..f7e9369 100644 --- a/opcodes/i386-gen.c +++ b/opcodes/i386-gen.c @@ -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", diff --git a/opcodes/i386-init.h b/opcodes/i386-init.h index 831f7f8..0c924e3 100644 --- a/opcodes/i386-init.h +++ b/opcodes/i386-init.h @@ -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, \ |