Hi Bob,
This has turned out to be what appears to be a very obscure binutils bug. I'm working on a test case for it now.
I have a patch for Mips16 llvm which works around the issue for now.
In general, pure risc architectures have no pity for compiler and toolchain developers. Mips16 is way more extreme in this way than mips32.
In mips32, there is no PC register or PC relative instructions.
To make PIC work, they load register T9 with the address of the function that is being called.
For referencing the GOT then, you have to emit this two sequence instruction as the first two instructions of the function so that this T9 register can be used to load from the GOT.
In mips16 there is no PC register either but there are some PC relative instructions so in principle this two instruction sequence can be placed anywhere (and if we know we are calling another mips16 function then we don't need to load T9 even though it's part of the PIC ABI).
Gcc mips16 though always place this sequence as the first two instructions of the function.
In llvm, I did not do that because there is no reason to be tied to that; if it happens it happens but it does not need to be like that and you can end up with slower code in that case. The full got pointer GP load takes 4 instructions so if you have paths in the function which don't make external calls, then you are paying a lot to force all paths to execute this sequence.
But the calculation for these kinds of external symbol offsets is complicated in mips and if you are not careful you can end up with some strange boundary condition errors.
This seems to be what the problem is here.
When the two instruction sequence is placed at the beginning of the function, you are guaranteed that it is longword aligned but in other places in mips16 code, you can have instructions starting on halfword boundaries.
That is what appears to the problem.
In principle, you can put this sequence anywhere but in some strange cases, if it is not longword aligned, the address calculation overflows and comes our wrong.
My patch forces these sequences to be longword aligned and it fixes the problem.
Reed