"pop {pc}" vs "ldr r15, [r13], #4" - Thumb2
when compiling a function using -O3 -Ofast in Thumb2 mode on Cortex-A7 core, the compiler resorts to using 32-bit "ldr r15, [r13], #4" in the return logic instead of the shorter 16-bit "pop {pc}" insn.
note: -O3 -Os also uses ldr... so not a size vs speed issue)
is there a reason why 'pop {pc}' is not used?
below is a nonsense function that demos issue
char *foo(char *s);
char *trivial(char *s)
{
char x[2];
*(x + 0) = 'x';
s = foo(x);
*(s + 2) = 'y';
return s;
}
617 0002 00BF .section .text._
618 .align 2
619 .global _Z7trivialPc
620 .thumb
621 .thumb_func
622 .type _Z7trivialPc, %function
623 _Z7trivialPc:
624 .fnstart
625 .LFB3:
626 @ args = 0, pretend = 0, frame = 8
627 @ frame_needed = 0, uses_anonymous_args = 0
628 0000 00B5 push {lr}
629 .save {lr}
630 .pad #12
631 0002 83B0 sub sp, sp, #12
632 0004 02A8 add r0, sp, #8
633 0006 7823 movs r3, #120
634 0008 00F8083D strb r3, [r0, #-8]!
635 000c 6846 mov r0, sp
636 000e FFF7FEFF bl _Z3fooPc
637 0012 7923 movs r3, #121
638 0014 8370 strb r3, [r0, #2]
639 0016 03B0 add sp, sp, #12
640 @ sp needed
641 0018 5DF804FB ldr pc, [sp], #4 <<<<<<<< why not 'pop {pc}' used here
642 .fnend
643 .size _Z7trivialPc, .-_Z7trivialPc
note: the 'pop {r15}' insn must be real and valid since i see the following when i disassemble libgcc.a code
10008e7c <__restore_
__restore_
10008e7c: f100 0134 add.w r1, r0, #52 ; 0x34
10008e80: e891 0038 ldmia.w r1, {r3, r4, r5}
10008e84: 469c mov r12, r3
10008e86: 46a6 mov r14, r4
10008e88: f84c 5d04 str.w r5, [r12, #-4]!
10008e8c: e890 0fff ldmia.w r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11}
10008e90: 46e5 mov r13, r12
10008e92: bd00 pop {r15}
i am using latest 2014-q3 release of g++ or gcc - have same issue.
Question information
- Language:
- English Edit question
- Status:
- Answered
- Assignee:
- No assignee Edit question
- Last query:
- Last reply:
Can you help with this problem?
Provide an answer of your own, or ask Bill Dittmann for more information if necessary.