aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-rx.c
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2010-07-02 20:40:28 +0000
committerDJ Delorie <dj@redhat.com>2010-07-02 20:40:28 +0000
commit731df70d1a9b202e14df95132d8b9c4e6587eb86 (patch)
tree08f3f8ff76e3c1b39e70898d11ffeb4fb603fffa /gas/config/tc-rx.c
parent44a808b1a4654298565c602cb7847ec34e0f722a (diff)
downloadgdb-731df70d1a9b202e14df95132d8b9c4e6587eb86.zip
gdb-731df70d1a9b202e14df95132d8b9c4e6587eb86.tar.gz
gdb-731df70d1a9b202e14df95132d8b9c4e6587eb86.tar.bz2
* 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.
Diffstat (limited to 'gas/config/tc-rx.c')
-rw-r--r--gas/config/tc-rx.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gas/config/tc-rx.c b/gas/config/tc-rx.c
index 00101e0..50b17ae 100644
--- a/gas/config/tc-rx.c
+++ b/gas/config/tc-rx.c
@@ -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)