Checking reference manuals:
ARMV4T (ARM7TDMI/ARM9TDMI): Does NOT switch to THUMB mode automatically
ARMV5: Does NOT switch to THUMB mode automatically
ARMV7: Does switch to THUMB mode automatically
Plus if you don't want to switch to thumb, this still works?
https://developer.apple.com/documentation/xcode/writing-arm6...
The article is also entirely about how the PC is a general-purpose register on 32-bit ARM machines. No idea if the 1st gen iPhones or whatever used an idiosyncratic calling convention...but it's moot in the context of this post, because argument passing isn't covered here!
This post really is just about the observation that the PC is a GPR implies that there's a bunch of different ways to get data into it. It's pretty airy. The author was admittedly a first or second year university student at the time, so it's hard to be too mad though.
RISCV unfortunately didn't quite do this well since return uses the same opcode for call, return, and indirect branch and so you have to fully decode the instruction in order to determine whether you should use the RAS or your other predictors. This isn't a problem that can't be overcome (next line predictors help a lot for these early predictions) but it makes something very performance critical just that much harder.
The problem boiled down to the valgrind frontend code that splits things up into basic blocks being incapable of having an instruction be both a conditional jump and a function call / return at the same time. That never happens on x86, but of course this is possible (and totally normal) on 32-bit Arm. Sadly, I ran out of time to try to re-architect this code and had to move on to other projects.
Over 12 years later, it looks like it never did get fixed: https://bugs.kde.org/show_bug.cgi?id=252091
as a bit of pointless trivia, MOV PC, PC does not cause an infinite loop - it skips the instruction immediately following.
So, if you're still developing for an ARM1, not all of these are equivalent. MOV/POP/etc will set the PC and the status register; B/BL will leave the status register bits alone.
* edit: MOV/MOVS determined if the status bits are written to R15.