so.c:
void thumb_fun(void);
void arm_fun ( void )
{
thumb_fun();
}
x.s:
.thumb
bl arm_fun
b .
.globl thumb_fun
.thumb_func
thumb_fun:
bx lr
Build and disassemble:
Disassembly of section .text:
00001000 <thumb_fun-0x6>:
1000: f000 f80a bl 1018 <__arm_fun_from_thumb>
1004: e7fe b.n 1004 <thumb_fun-0x2>
00001006 <thumb_fun>:
1006: 4770 bx lr
00001008 <arm_fun>:
1008: e92d4010 push {r4, lr}
100c: eb000003 bl 1020 <__thumb_fun_from_arm>
1010: e8bd4010 pop {r4, lr}
1014: e12fff1e bx lr
00001018 <__arm_fun_from_thumb>:
1018: 4778 bx pc
101a: e7fd b.n 1018 <__arm_fun_from_thumb>
101c: eafffff9 b 1008 <arm_fun>
00001020 <__thumb_fun_from_arm>:
1020: e59fc000 ldr ip, [pc] ; 1028 <__thumb_fun_from_arm+0x8>
1024: e12fff1c bx ip
1028: 00001007 .word 0x00001007
102c: 00000000 .word 0x00000000
If I link with --use-blx
Disassembly of section .text:
00008000 <thumb_fun-0x6>:
8000: f000 e802 blx 8008 <arm_fun>
8004: e7fe b.n 8004 <thumb_fun-0x2>
00008006 <thumb_fun>:
8006: 4770 bx lr
00008008 <arm_fun>:
8008: ea000000 b 8010 <__thumb_fun_from_arm>
800c: 00000000 andeq r0, r0, r0
00008010 <__thumb_fun_from_arm>:
8010: e51ff004 ldr pc, [pc, #-4] ; 8014 <__thumb_fun_from_arm+0x4>
8014: 00008007 .word 0x00008007
I don't have a built llvm with linker right now that takes an eternity to build. I would assume it is similar.
I think as answered in comments that the abi reserves a register for things like these.
blx had issues in an early core if I remember right so the tools just did not use it.
My clang build for armv4t completed on this machine.
Disassembly of section .text:
000200e4 <thumb_fun-0x6>:
200e4: f000 e802 blx 200ec <arm_fun>
200e8: e7fe b.n 200e8 <thumb_fun-0x2>
000200ea <thumb_fun>:
200ea: 4770 bx lr
000200ec <arm_fun>:
200ec: eaffffff b 200f0 <__ARMv5ABSLongThunk_thumb_fun>
000200f0 <__ARMv5ABSLongThunk_thumb_fun>:
200f0: e51ff004 ldr pc, [pc, #-4] ; 200f4 <__ARMv5ABSLongThunk_thumb_fun+0x4>
200f4: 000200eb .word 0x000200eb
To get a good llvm linker you need to build a cross tool not just take the prebuilt for your platform. The last couple or so major revs have had problems cross building anyway, so have resorted to gcc style build for a specific architecture and that resolved a lot of my clang/llvm problems. Other than having to build for each and the time it takes to build.
So I do not have an armv7-a that I have tried to build for llvm yet. I suspect you would get the same result. Note I did not try armv7a either for the gcc above. In part, what do the linkers do, and as you can see you could have easily done this yourself. But as answered in comments, it generates a trampoline or I guess folks call it a veneer.
llvm/clang armv7a:
Disassembly of section .text:
000200e4 <thumb_fun-0x6>:
200e4: f000 e802 blx 200ec <arm_fun>
200e8: e7fe b.n 200e8 <thumb_fun-0x2>
000200ea <thumb_fun>:
200ea: 4770 bx lr
000200ec <arm_fun>:
200ec: eaffffff b 200f0 <__ARMv7ABSLongThunk_thumb_fun>
000200f0 <__ARMv7ABSLongThunk_thumb_fun>:
200f0: e300c0eb movw ip, #235 ; 0xeb
200f4: e340c002 movt ip, #2
200f8: e12fff1c bx ip
with gnu tools -march=armv7-a:
00001000 <thumb_fun-0x6>:
1000: f000 e802 blx 1008 <arm_fun>
1004: e7fe b.n 1004 <thumb_fun-0x2>
00001006 <thumb_fun>:
1006: 4770 bx lr
00001008 <arm_fun>:
1008: ea000000 b 1010 <__thumb_fun_from_arm>
100c: 00000000 andeq r0, r0, r0
00001010 <__thumb_fun_from_arm>:
1010: e51ff004 ldr pc, [pc, #-4] ; 1014 <__thumb_fun_from_arm+0x4>
1014: 00001007 .word 0x00001007