diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2009-10-13 16:23:25 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2009-10-13 16:23:25 +0000 |
commit | 313c53d19e95820f8dfb8e3b22f3753428938c3f (patch) | |
tree | 34e1d25974777e835a08e8875befe243e74180a5 /gas/config | |
parent | 88e3b899d71edaa44be82469cb2e462212a0e406 (diff) | |
download | gdb-313c53d19e95820f8dfb8e3b22f3753428938c3f.zip gdb-313c53d19e95820f8dfb8e3b22f3753428938c3f.tar.gz gdb-313c53d19e95820f8dfb8e3b22f3753428938c3f.tar.bz2 |
gas/
2009-10-13 H.J. Lu <hongjiu.lu@intel.com>
PR gas/10740
* config/tc-i386-intel.c (i386_intel_operand): Handle call
and jump with 2 immediate operands.
* config/tc-i386.c (i386_finalize_immediate): Don't generate
error message if operand string is NULL.
gas/testsuite/
2009-10-13 H.J. Lu <hongjiu.lu@intel.com>
PR gas/10740
* gas/i386/jump.s: Add new tests.
* gas/i386/jump16.s: Likewise.
* gas/i386/jump.d: Updated.
* gas/i386/jump16.d: Likewise.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-i386-intel.c | 45 | ||||
-rw-r--r-- | gas/config/tc-i386.c | 8 |
2 files changed, 50 insertions, 3 deletions
diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c index 5d5e0c1..df749b8 100644 --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -721,6 +721,51 @@ i386_intel_operand (char *operand_string, int got_a_float) if (i.mem_operands >= 2 - !current_templates->start->opcode_modifier.isstring) { + /* Handle + + call 0x9090,0x90909090 + lcall 0x9090,0x90909090 + jmp 0x9090,0x90909090 + ljmp 0x9090,0x90909090 + */ + + if ((current_templates->start->opcode_modifier.jumpintersegment + || current_templates->start->opcode_modifier.jumpdword + || current_templates->start->opcode_modifier.jump) + && this_operand == 1 + && intel_state.seg == NULL + && i.mem_operands == 1 + && i.disp_operands == 1 + && intel_state.op_modifier == O_absent) + { + /* Try to process the first operand as immediate, */ + this_operand = 0; + if (i386_finalize_immediate (exp_seg, i.op[0].imms, + intel_state.reloc_types, + NULL)) + { + this_operand = 1; + expP = &im_expressions[0]; + i.op[this_operand].imms = expP; + *expP = exp; + + /* Try to process the second operand as immediate, */ + if (i386_finalize_immediate (exp_seg, expP, + intel_state.reloc_types, + NULL)) + { + i.mem_operands = 0; + i.disp_operands = 0; + i.imm_operands = 2; + i.types[0].bitfield.mem = 0; + i.types[0].bitfield.disp16 = 0; + i.types[0].bitfield.disp32 = 0; + i.types[0].bitfield.disp32s = 0; + return 1; + } + } + } + as_bad (_("too many memory references for `%s'"), current_templates->start->name); return 0; diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 5c288ea..54edb1b 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -6287,8 +6287,9 @@ i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp, { if (exp->X_op == O_absent || exp->X_op == O_illegal || exp->X_op == O_big) { - as_bad (_("missing or invalid immediate expression `%s'"), - imm_start); + if (imm_start) + as_bad (_("missing or invalid immediate expression `%s'"), + imm_start); return 0; } else if (exp->X_op == O_constant) @@ -6316,7 +6317,8 @@ i386_finalize_immediate (segT exp_seg ATTRIBUTE_UNUSED, expressionS *exp, #endif else if (!intel_syntax && exp->X_op == O_register) { - as_bad (_("illegal immediate register operand %s"), imm_start); + if (imm_start) + as_bad (_("illegal immediate register operand %s"), imm_start); return 0; } else |