Reputation: 13
I'm using armcc and arm-gcc for compiling my project for an ARM968 processor.
When returning form a function call, the returning instruction is as follows:
Pop {ri-rj, pc}
All the pushed registers are popped in the same instruction. I want to change the instruction above into something like this:
Pop {ri-rj}
Pop {pc}
Can I instruct the assembler or the compiler to adhere to the rule above in any of the ARM tool chains when using Pop
?
Upvotes: 1
Views: 184
Reputation: 20924
Depending on the exact nature of the problem, and whether you're critically dependent on a handful of newer instructions, another possibility might be to compile for ARMv4T. Prior to ARMv5T, ldm
into the PC was not interworking, so the compiler won't emit that form of return instruction for a v4T target. For some simple test code, compiling with -march=armv5t
generates a stack frame thus:
8: e92d4070 push {r4, r5, r6, lr}
...
4c: d8bd8070 pople {r4, r5, r6, pc}
whereas compiling the same thing with -march=armv4t
uses the same prologue but with an indirect return sequence (the above was a conditional return from inside a loop, now it's also moved out to the end of the function):
48: da000006 ble 68 <func+0x68>
...
68: e8bd4070 pop {r4, r5, r6, lr}
6c: e12fff1e bx lr
Of course, whether that has the same effect as the two separate pops depends on what the underlying bug in the system is - if it's something like the timing between the data fetches of the ldm
and the instruction fetches of the jump itself, then this might be sufficiently equivalent; it could conceivably be something quite different, like a broken memory system truncating AHB bursts above a certain size, so it's the number of registers transferred in a single ldm
that's the issue, but in that case I'd also expect to see problems with things like memcpy
which aren't so easily fixed.
Upvotes: 4
Reputation: 2335
you can tell gcc to stop processing after it has generated the assembler. The you can edit the assembler files manually or by using sed
. Then you pass the assembler file to as
from binutils to assemble it into an object file.
$ cat test.c
#include <stdio.h>
int main(int argc, char *argv[])
{
printf ("hello world\n");
return 0;
}
$ gcc test.c -o test.s -S
cat test.s
.file "test.c"
.section .rodata
.LC0:
.string "hello world"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl $.LC0, %edi
call puts
movl $0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4"
.section .note.GNU-stack,"",@progbits
$ as test.s -o test.o
Upvotes: 0