Add ability to pad code alignment frags with no-ops.
authorNick Clifton <nickc@redhat.com>
Thu, 26 Apr 2001 15:19:21 +0000 (15:19 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 26 Apr 2001 15:19:21 +0000 (15:19 +0000)
gas/ChangeLog
gas/config/tc-arm.c
gas/config/tc-arm.h

index 6bdaec0d7c593c13a04f560733480e142870831a..435498098bf18fe2d44363dd45e04e7390e8ef04 100644 (file)
@@ -1,3 +1,16 @@
+2001-04-26  Nick Clifton  <nickc@cambridge.redhat.com>
+
+       * config/tc-arm.c (arm_handle_align): New Function:  Generate
+       no-op filled alignment frags.
+       (arm_frag_align_code): New Function: Create a code alignment frag.
+       (arm_init_frag): New Function: Initialse the target dependent
+       parts of a frag.
+
+       * config/tc-arm.h (TC_FRAG_TYPE): Define.
+       (TC_FRAG_INIT): Define.
+       (HANDLE_ALIGN): Define.
+       (md_do_align): Define.
+
 2001-04-25  Nick Clifton  <nickc@cambridge.redhat.com>
 
        * config/obj-coff.c (do_linenos_for): Check to see if the filename
index e5f0c136af19898790b2b3bd9c7529282fec3a03..ec51229209c2f5e761502f237eced8dd5c2b967c 100644 (file)
@@ -8780,3 +8780,99 @@ s_arm_elf_cons (nbytes)
 }
 
 #endif /* OBJ_ELF */
+
+/* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
+   of an rs_align_code fragment.  */
+
+void
+arm_handle_align (fragp)
+     fragS *fragp;
+{
+  static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
+  static char const thumb_noop[2] = { 0xc0, 0x46 };
+  static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
+  static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
+
+  int bytes, fix, noop_size;
+  char * p;
+  const char * noop;
+  
+  if (fragp->fr_type != rs_align_code)
+    return;
+
+  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
+  p = fragp->fr_literal + fragp->fr_fix;
+  fix = 0;
+  
+  if (fragp->tc_frag_data)
+    {
+      if (target_big_endian)
+       noop = thumb_bigend_noop;
+      else
+       noop = thumb_noop;
+      noop_size = sizeof (thumb_noop);
+    }
+  else
+    {
+      if (target_big_endian)
+       noop = arm_bigend_noop;
+      else
+       noop = arm_noop;
+      noop_size = sizeof (arm_noop);
+    }
+  
+  if (bytes & (noop_size - 1))
+    {
+      fix = bytes & (noop_size - 1);
+      memset (p, 0, fix);
+      p += fix;
+      bytes -= fix;
+    }
+
+  while (bytes >= noop_size)
+    {
+      memcpy (p, noop, noop_size);
+      p += noop_size;
+      bytes -= noop_size;
+      fix += noop_size;
+    }
+  
+  fragp->fr_fix += fix;
+  fragp->fr_var = noop_size;
+}
+
+/* Called from md_do_align.  Used to create an alignment
+   frag in a code section.  */
+
+void
+arm_frag_align_code (n, max)
+     int n;
+     int max;
+{
+  char * p;
+
+  /* We assume that there will never be a requirment
+     to support alignments greater than 32 bytes.  */
+  if (max > 31)
+    as_fatal (_("alignments in code section > 32 not supported."));
+  
+  p = frag_var (rs_align_code,
+               31,
+               1,
+               (relax_substateT) max,
+               (symbolS *) NULL,
+               (offsetT) n,
+               (char *) NULL);
+  *p = 0;
+
+}
+
+/* Perform target specific initialisation of a frag.  */
+
+void
+arm_init_frag (fragp)
+     fragS *fragp;
+{
+  /* Record whether this frag is in an ARM or a THUMB area.  */
+  fragp->tc_frag_data = thumb_mode;
+}
index 7060333a5b10ff473a5244cde9453bf93c729cea..f955c44248325ef61a3424da98218e3ce5a3072c 100644 (file)
@@ -214,3 +214,21 @@ void armelf_frob_symbol PARAMS ((symbolS *, int *));
 #ifdef OBJ_ELF
 #define DWARF2_LINE_MIN_INSN_LENGTH 2
 #endif
+
+/* For frags in code sections we need to record whether they contain
+   ARM code or THUMB code.  This is that if they have to be aligned,
+   they can contain the correct type of no-op instruction.  */
+#define TC_FRAG_TYPE   int
+#define TC_FRAG_INIT(fragp)    arm_init_frag (fragp)
+extern void arm_init_frag PARAMS ((struct frag *));
+
+#define HANDLE_ALIGN(fragp) arm_handle_align (fragp)
+extern void arm_handle_align PARAMS ((struct frag *));
+
+#define md_do_align(N, FILL, LEN, MAX, LABEL)                                  \
+  if (FILL == NULL && (N) != 0 && ! need_pass_2 && subseg_text_p (now_seg))    \
+    {                                                                          \
+      arm_frag_align_code (N, MAX);                                            \
+      goto LABEL;                                                              \
+    }
+extern void arm_frag_align_code PARAMS ((int, int));