Hi all,This PR is about GCC emiting 'bx lr' instructions when compiling with -march=armv2 or armv3(!). It should be using a move into the pc instead on those architectures. The cause I found for it is that the functions are marked with the ARM_FT_INTERWORKED type and hence in the output_return_instruction function they use 'bx lr'. Rather than changing output_return_instruction to check for the architecture level when outputting the string I think the correct thing to do is to disable interworking when the target does not support any Thumb at all, like these old architectures. Is that correct thinking?
Anyway, with this patch the functions are given the ARM_FT_NORMAL type and use 'mov pc, lr' to return.
Tested arm-none-eabi. What do people think? Thanks, Kyrill 2014-01-16 Kyrylo Tkachov <kyrylo.tkac...@arm.com> PR target/64405 * config/arm/arm.c (arm_option_override): Disable interworking if Thumb is not available. 2014-01-16 Kyrylo Tkachov <kyrylo.tkac...@arm.com> PR target/64405 * gcc.target/arm/pr64405_1.c: New test.
commit 0321a5f2b4912501a5c5acb90b8d0315a1031625 Author: Kyrylo Tkachov <kyrylo.tkac...@arm.com> Date: Fri Jan 9 11:09:53 2015 +0000 [ARM] PR target/64405 Disable TARGET_INTERWORK when Thumb is not available diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index dd8df46..b142823 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2878,9 +2878,11 @@ arm_option_override (void) /* BPABI targets use linker tricks to allow interworking on cores without thumb support. */ - if (TARGET_INTERWORK && !((insn_flags & FL_THUMB) || TARGET_BPABI)) + if (TARGET_INTERWORK && !(insn_flags & FL_THUMB)) { - warning (0, "target CPU does not support interworking" ); + if (!TARGET_BPABI) + warning (0, "target CPU does not support interworking" ); + target_flags &= ~MASK_INTERWORK; } diff --git a/gcc/testsuite/gcc.target/arm/pr64405_1.c b/gcc/testsuite/gcc.target/arm/pr64405_1.c new file mode 100644 index 0000000..1aeebb1 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr64405_1.c @@ -0,0 +1,25 @@ +/* { dg-do assemble } */ +/* { dg-options "-O -march=armv3" } */ + +#define byte unsigned char + +void convert_image(byte *in, byte *out, int size) { + int i; + for(i = 0; i < size; i++) { + byte r = in[0]; + byte g = in[1]; + byte b = in[2]; + byte c, m, y, k, tmp; + c = 255 - r; + m = 255 - g; + y = 255 - b; + tmp = m + y; + k = c - tmp; + out[0] = c - k; + out[1] = m - k; + out[2] = y - k; + out[3] = k; + in += 3; + out += 4; + } +}