diff options
author | DJ Delorie <dj@redhat.com> | 2009-04-07 18:21:22 +0000 |
---|---|---|
committer | DJ Delorie <dj@redhat.com> | 2009-04-07 18:21:22 +0000 |
commit | bcb012d3f5c0ea3015854d06f8778224f62bbfb8 (patch) | |
tree | 4257ad672658cb445e1abcf80d828074a8ed14fe /gas | |
parent | 6ce340f181d0192335efd786914c30e7d3277729 (diff) | |
download | gdb-bcb012d3f5c0ea3015854d06f8778224f62bbfb8.zip gdb-bcb012d3f5c0ea3015854d06f8778224f62bbfb8.tar.gz gdb-bcb012d3f5c0ea3015854d06f8778224f62bbfb8.tar.bz2 |
[bfd]
* elf32-h8300.c (elf32_h8_relax_section): Relax MOVA opcodes.
[gas]
* tc-h8300.c (do_a_fix_imm): Pass the insn, force relocs for MOVA
immediates.
(build_bytes): Pass insn to do_a_fix_imm.
[include/opcode]
* h8300.h: Add relaxation attributes to MOVA opcodes.
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/tc-h8300.c | 21 |
2 files changed, 23 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 2c2e59f..b809890 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2009-04-06 DJ Delorie <dj@redhat.com> + + * tc-h8300.c (do_a_fix_imm): Pass the insn, force relocs for MOVA + immediates. + (build_bytes): Pass insn to do_a_fix_imm. + 2009-04-02 Daniel Gutson <dgutson@codesourcery.com> * config/tc-arm.c (arm_cpus): Add entry for ARM Cortex-M0. diff --git a/gas/config/tc-h8300.c b/gas/config/tc-h8300.c index 86b2450..ea94c39 100644 --- a/gas/config/tc-h8300.c +++ b/gas/config/tc-h8300.c @@ -299,7 +299,7 @@ struct h8_op static void clever_message (const struct h8_instruction *, struct h8_op *); static void fix_operand_size (struct h8_op *, int); static void build_bytes (const struct h8_instruction *, struct h8_op *); -static void do_a_fix_imm (int, int, struct h8_op *, int); +static void do_a_fix_imm (int, int, struct h8_op *, int, const struct h8_instruction *); static void check_operand (struct h8_op *, unsigned int, char *); static const struct h8_instruction * get_specific (const struct h8_instruction *, struct h8_op *, int) ; static char *get_operands (unsigned, char *, struct h8_op *); @@ -1273,7 +1273,7 @@ check_operand (struct h8_op *operand, unsigned int width, char *string) (may relax into an 8bit absolute address). */ static void -do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int relaxmode) +do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int relaxmode, const struct h8_instruction *this_try) { int idx; int size; @@ -1313,6 +1313,17 @@ do_a_fix_imm (int offset, int nibble, struct h8_op *operand, int relaxmode) check_operand (operand, 0xffff, t); bytes[0] |= operand->exp.X_add_number >> 8; bytes[1] |= operand->exp.X_add_number >> 0; +#ifdef OBJ_ELF + /* MOVA needs both relocs to relax the second operand properly. */ + if (relaxmode != 0 + && (OP_KIND(this_try->opcode->how) == O_MOVAB + || OP_KIND(this_try->opcode->how) == O_MOVAW + || OP_KIND(this_try->opcode->how) == O_MOVAL)) + { + idx = BFD_RELOC_16; + fix_new_exp (frag_now, offset, 2, &operand->exp, 0, idx); + } +#endif break; case L_24: check_operand (operand, 0xffffff, t); @@ -1576,12 +1587,14 @@ build_bytes (const struct h8_instruction *this_try, struct h8_op *operand) if (x_mode == IMM || x_mode == DISP) do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2, - op_at[i] & 1, operand + i, (x & MEMRELAX) != 0); + op_at[i] & 1, operand + i, (x & MEMRELAX) != 0, + this_try); else if (x_mode == ABS) do_a_fix_imm (output - frag_now->fr_literal + op_at[i] / 2, op_at[i] & 1, operand + i, - (x & MEMRELAX) ? movb + 1 : 0); + (x & MEMRELAX) ? movb + 1 : 0, + this_try); else if (x_mode == PCREL) { |