* config/tc-rx.h (md_do_align): New.
authorDJ Delorie <dj@redhat.com>
Fri, 2 Jul 2010 20:40:28 +0000 (20:40 +0000)
committerDJ Delorie <dj@redhat.com>
Fri, 2 Jul 2010 20:40:28 +0000 (20:40 +0000)
(MAX_MEM_FOR_RS_ALIGN_CODE): New.
* config/tc-rx.c (nops): New.
(rx_handle_align): Use various sized nops to align code.

gas/ChangeLog
gas/config/tc-rx.c
gas/config/tc-rx.h

index 47708c7c4a16bb2d0271b1b474ddc1f4c9074e10..7512c456ae37e13ce01f3bba0ce8298cff2cf800 100644 (file)
@@ -1,5 +1,10 @@
 2010-07-02  DJ Delorie  <dj@redhat.com>
 
+       * config/tc-rx.h (md_do_align): New.
+       (MAX_MEM_FOR_RS_ALIGN_CODE): New.
+       * config/tc-rx.c (nops): New.
+       (rx_handle_align): Use various sized nops to align code.
+
        * config/tc-rx.c (rx_bytesT): Add grown/shrank counters for
        relaxation.
        (rx_relax_frag): Prevent infinite loops of grow/shrink/grow/etc.
index 00101e0318b79116e12d5e8a1d8e0a1601705eee..50b17aec164f948d1ad4e67898f3bf143302b9e5 100644 (file)
@@ -1119,11 +1119,51 @@ md_section_align (segT segment, valueT size)
   return ((size + (1 << align) - 1) & (-1 << align));
 }
 
+                               /* NOP - 1 cycle */
+static unsigned char nop_1[] = { 0x03};
+                               /* MOV.L R0,R0 - 1 cycle */
+static unsigned char nop_2[] = { 0xef, 0x00};
+                               /* MAX R0,R0 - 1 cycle */
+static unsigned char nop_3[] = { 0xfc, 0x13, 0x00 };
+                               /* MUL #1,R0 - 1 cycle */
+static unsigned char nop_4[] = { 0x76, 0x10, 0x01, 0x00 };
+                               /* MUL #1,R0 - 1 cycle */
+static unsigned char nop_5[] = { 0x77, 0x10, 0x01, 0x00, 0x00 };
+                               /* MUL #1,R0 - 1 cycle */
+static unsigned char nop_6[] = { 0x74, 0x10, 0x01, 0x00, 0x00, 0x00 };
+                               /* BRA.S .+7 - 1 cycle */
+static unsigned char nop_7[] = { 0x0F, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
+
+static unsigned char *nops[] = { NULL, nop_1, nop_2, nop_3, nop_4, nop_5, nop_6, nop_7 };
+#define BIGGEST_NOP 7
+
 /* When relaxing, we need to output a reloc for any .align directive
    so that we can retain this alignment as we adjust opcode sizes.  */
 void
 rx_handle_align (fragS * frag)
 {
+  if ((frag->fr_type == rs_align
+       || frag->fr_type == rs_align_code)
+      && subseg_text_p (now_seg))
+    {
+      int count = (frag->fr_next->fr_address
+                  - frag->fr_address   
+                  - frag->fr_fix);
+      unsigned char *base = (unsigned char *)frag->fr_literal + frag->fr_fix;
+
+      if (count > BIGGEST_NOP)
+       {
+         base[0] = 0x2e;
+         base[1] = count;
+         frag->fr_var = 2;
+       }
+      else if (count > 0)
+       {
+         memcpy (base, nops[count], count);
+         frag->fr_var = count;
+       }
+    }
+
   if (linkrelax
       && (frag->fr_type == rs_align
          || frag->fr_type == rs_align_code)
index 592eb35c0d82c3d1447c34a6f2c1f373dd2f1023..6f2db1ca8c52b920d6cfad75d3d1ee4875a7e181 100644 (file)
@@ -75,6 +75,18 @@ extern void rx_cons_fix_new (fragS *, int, int, expressionS *);
 
 #define tc_fix_adjustable(x) 0
 
+#define md_do_align(n, fill, len, max, around)                         \
+  if ((n)                                                              \
+      && !need_pass_2                                                  \
+      && (!(fill)                                                      \
+         || ((char)*(fill) == (char)0x03 && (len) == 1))               \
+      && subseg_text_p (now_seg))                                      \
+    {                                                                  \
+      frag_align_code ((n), (max));                                    \
+      goto around;                                                     \
+    }
+
+#define MAX_MEM_FOR_RS_ALIGN_CODE 8
 #define HANDLE_ALIGN(FRAG) rx_handle_align (FRAG)
 extern void rx_handle_align (fragS *);