Fix region length calculations when regions end with .align padding.
[deliverable/binutils-gdb.git] / gas / config / tc-m68hc11.c
index c6a4dd5acb5c37497c164b372ca19f8167147647..780f773fc91bc1a93863118b1b1e9fcd4d4c2927 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-m68hc11.c -- Assembler code for the Motorola 68HC11 & 68HC12.
-   Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Written by Stephane Carrez (stcarrez@nerim.fr)
 
    This file is part of GAS, the GNU Assembler.
@@ -233,7 +233,7 @@ static short flag_print_opcodes = 0;
 static struct hash_control *m68hc11_hash;
 
 /* Current cpu (either cpu6811 or cpu6812).  This is determined automagically
-   by 'get_default_target' by looking at default BFD vector.  This is overriden
+   by 'get_default_target' by looking at default BFD vector.  This is overridden
    with the -m<cpu> option.  */
 static int current_architecture = 0;
 
@@ -1569,7 +1569,7 @@ build_jump_insn (struct m68hc11_opcode *opcode, operand operands[],
   fragS *frag;
   int where;
 
-  /* The relative branch convertion is not supported for
+  /* The relative branch conversion is not supported for
      brclr and brset.  */
   assert ((opcode->format & M6811_OP_BITMASK) == 0);
   assert (nb_operands == 1);
@@ -1719,7 +1719,7 @@ build_dbranch_insn (struct m68hc11_opcode *opcode, operand operands[],
   char *f;
   unsigned long n;
 
-  /* The relative branch convertion is not supported for
+  /* The relative branch conversion is not supported for
      brclr and brset.  */
   assert ((opcode->format & M6811_OP_BITMASK) == 0);
   assert (nb_operands == 2);
@@ -1951,18 +1951,43 @@ build_indexed_byte (operand *op, int format ATTRIBUTE_UNUSED, int move_insn)
               sym = make_expr_symbol (&op->exp);
               off = 0;
             }
-         frag_var (rs_machine_dependent, 2, 2,
-                   ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
-                   sym, off, f);
+         /* movb/movw cannot be relaxed.  */
+         if (move_insn)
+           {
+             byte <<= 6;
+             number_to_chars_bigendian (f, byte, 1);
+             fix_new (frag_now, f - frag_now->fr_literal, 1,
+                      sym, off, 0, BFD_RELOC_M68HC12_5B);
+             return 1;
+           }
+         else
+           {
+             number_to_chars_bigendian (f, byte, 1);
+             frag_var (rs_machine_dependent, 2, 2,
+                       ENCODE_RELAX (STATE_INDEXED_OFFSET, STATE_UNDF),
+                       sym, off, f);
+           }
        }
       else
        {
          f = frag_more (1);
-         number_to_chars_bigendian (f, byte, 1);
-         frag_var (rs_machine_dependent, 2, 2,
-                   ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
-                   op->exp.X_add_symbol,
-                   op->exp.X_add_number, f);
+         /* movb/movw cannot be relaxed.  */
+         if (move_insn)
+           {
+             byte <<= 6;
+             number_to_chars_bigendian (f, byte, 1);
+             fix_new (frag_now, f - frag_now->fr_literal, 1,
+                      op->exp.X_add_symbol, op->exp.X_add_number, 0, BFD_RELOC_M68HC12_5B);
+             return 1;
+           }
+         else
+           {
+             number_to_chars_bigendian (f, byte, 1);
+             frag_var (rs_machine_dependent, 2, 2,
+                       ENCODE_RELAX (STATE_INDEXED_PCREL, STATE_UNDF),
+                       op->exp.X_add_symbol,
+                       op->exp.X_add_number, f);
+           }
        }
       return 3;
     }
@@ -2058,7 +2083,7 @@ build_reg_mode (operand *op, int format)
 }
 
 /* build_insn takes a pointer to the opcode entry in the opcode table,
-   the array of operand expressions and builds the correspding instruction.
+   the array of operand expressions and builds the corresponding instruction.
    This operation only deals with non relative jumps insn (need special
    handling).  */
 static void
@@ -3287,6 +3312,17 @@ md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       where[0] = where[0] | (value & 0x07);
       break;
 
+    case BFD_RELOC_M68HC12_5B:
+      if (value < -16 || value > 15)
+       as_bad_where (fixP->fx_file, fixP->fx_line,
+                     _("Offset out of 5-bit range for movw/movb insn: %ld"),
+                     value);
+      if (value >= 0)
+       where[0] |= value;
+      else 
+       where[0] |= (0x10 | (16 + value));
+      break;
+
     case BFD_RELOC_M68HC11_RL_JUMP:
     case BFD_RELOC_M68HC11_RL_GROUP:
     case BFD_RELOC_VTABLE_INHERIT:
This page took 0.024871 seconds and 4 git commands to generate.