From 731df70d1a9b202e14df95132d8b9c4e6587eb86 Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Fri, 2 Jul 2010 20:40:28 +0000 Subject: * 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. --- gas/ChangeLog | 5 +++++ gas/config/tc-rx.c | 40 ++++++++++++++++++++++++++++++++++++++++ gas/config/tc-rx.h | 12 ++++++++++++ 3 files changed, 57 insertions(+) diff --git a/gas/ChangeLog b/gas/ChangeLog index 47708c7..7512c45 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,10 @@ 2010-07-02 DJ Delorie + * 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. 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) diff --git a/gas/config/tc-rx.h b/gas/config/tc-rx.h index 592eb35..6f2db1c 100644 --- a/gas/config/tc-rx.h +++ b/gas/config/tc-rx.h @@ -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 *); -- cgit v1.1