diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2010-04-21 18:09:52 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2010-04-21 18:09:52 +0000 |
commit | 3c7b9c2c544319e9f148ef013e8706b1e484e4d5 (patch) | |
tree | 6f1bf375050d2bb96297c3f1a815a953ef3fc252 /gas/config/tc-i386-intel.c | |
parent | 0b66f3173809e422f3dfbab2a8afff7fb9fc0ef3 (diff) | |
download | gdb-3c7b9c2c544319e9f148ef013e8706b1e484e4d5.zip gdb-3c7b9c2c544319e9f148ef013e8706b1e484e4d5.tar.gz gdb-3c7b9c2c544319e9f148ef013e8706b1e484e4d5.tar.bz2 |
Properly handle ".equ symbol, reg + NUM" in x86 Intel syntax.
gas/
2010-04-21 H.J. Lu <hongjiu.lu@intel.com>
PR gas/11509
* config/tc-i386-intel.c (i386_intel_simplify_register): New.
(i386_intel_simplify): Use i386_is_register and
i386_intel_simplify_register. Set X_md for O_register and
check X_md for O_constant.
(i386_intel_operand): Use i386_is_register.
* config/tc-i386.c (i386_is_register): New.
(x86_cons): Initialize the X_md field. Use i386_is_register.
(parse_register): Use i386_is_register.
(tc_x86_parse_to_dw2regnum): Likewise.
gas/testsuite/
2010-04-21 H.J. Lu <hongjiu.lu@intel.com>
PR gas/11509
* gas/i386/equ.s: Add tests for ".equ symbol, reg + NUM".
* gas/i386/equ.d: Updated.
Diffstat (limited to 'gas/config/tc-i386-intel.c')
-rw-r--r-- | gas/config/tc-i386-intel.c | 101 |
1 files changed, 64 insertions, 37 deletions
diff --git a/gas/config/tc-i386-intel.c b/gas/config/tc-i386-intel.c index b3cdcd3..cb99518 100644 --- a/gas/config/tc-i386-intel.c +++ b/gas/config/tc-i386-intel.c @@ -233,6 +233,49 @@ static INLINE void i386_intel_fold (expressionS *e, symbolS *sym) } } +static int +i386_intel_simplify_register (expressionS *e) +{ + int reg_num; + + if (this_operand < 0 || intel_state.in_offset) + { + as_bad (_("invalid use of register")); + return 0; + } + + if (e->X_op == O_register) + reg_num = e->X_add_number; + else + reg_num = e->X_md - 1; + + if (!intel_state.in_bracket) + { + if (i.op[this_operand].regs) + { + as_bad (_("invalid use of register")); + return 0; + } + if (i386_regtab[reg_num].reg_type.bitfield.sreg3 + && i386_regtab[reg_num].reg_num == RegFlat) + { + as_bad (_("invalid use of pseudo-register")); + return 0; + } + i.op[this_operand].regs = i386_regtab + reg_num; + } + else if (!intel_state.base && !intel_state.in_scale) + intel_state.base = i386_regtab + reg_num; + else if (!intel_state.index) + intel_state.index = i386_regtab + reg_num; + else + { + /* esp is invalid as index */ + intel_state.index = i386_regtab + REGNAM_EAX + 4; + } + return 2; +} + static int i386_intel_simplify (expressionS *); static INLINE int i386_intel_simplify_symbol(symbolS *sym) @@ -304,7 +347,8 @@ static int i386_intel_simplify (expressionS *e) intel_state.op_modifier = e->X_op; /* FALLTHROUGH */ case O_short: - if (symbol_get_value_expression (e->X_add_symbol)->X_op == O_register) + if (i386_is_register (symbol_get_value_expression (e->X_add_symbol), + 1)) { as_bad (_("invalid use of register")); return 0; @@ -315,7 +359,8 @@ static int i386_intel_simplify (expressionS *e) break; case O_full_ptr: - if (symbol_get_value_expression (e->X_op_symbol)->X_op == O_register) + if (i386_is_register (symbol_get_value_expression (e->X_op_symbol), + 1)) { as_bad (_("invalid use of register")); return 0; @@ -328,40 +373,6 @@ static int i386_intel_simplify (expressionS *e) i386_intel_fold (e, e->X_op_symbol); break; - case O_register: - if (this_operand < 0 || intel_state.in_offset) - { - as_bad (_("invalid use of register")); - return 0; - } - if (!intel_state.in_bracket) - { - if (i.op[this_operand].regs) - { - as_bad (_("invalid use of register")); - return 0; - } - if (i386_regtab[e->X_add_number].reg_type.bitfield.sreg3 - && i386_regtab[e->X_add_number].reg_num == RegFlat) - { - as_bad (_("invalid use of pseudo-register")); - return 0; - } - i.op[this_operand].regs = i386_regtab + e->X_add_number; - } - else if (!intel_state.base && !intel_state.in_scale) - intel_state.base = i386_regtab + e->X_add_number; - else if (!intel_state.index) - intel_state.index = i386_regtab + e->X_add_number; - else - { - /* esp is invalid as index */ - intel_state.index = i386_regtab + REGNAM_EAX + 4; - } - e->X_op = O_constant; - e->X_add_number = 0; - return 2; - case O_multiply: if (this_operand >= 0 && intel_state.in_bracket) { @@ -418,6 +429,22 @@ static int i386_intel_simplify (expressionS *e) break; } + + case O_register: + ret = i386_intel_simplify_register (e); + if (ret == 2) + { + gas_assert (e->X_add_number < (unsigned short) -1); + e->X_md = (unsigned short) e->X_add_number + 1; + e->X_op = O_constant; + e->X_add_number = 0; + } + return ret; + + case O_constant: + if (e->X_md) + return i386_intel_simplify_register (e); + /* FALLTHROUGH */ default: if (e->X_add_symbol && !i386_intel_simplify_symbol (e->X_add_symbol)) @@ -832,7 +859,7 @@ i386_intel_operand (char *operand_string, int got_a_float) break; intel_state.seg = expP->X_add_symbol; } - if (expP->X_op != O_register) + if (!i386_is_register (expP, 1)) { as_bad (_("segment register name expected")); return 0; |