Ticket #428 (Fixed)Thu Oct 06 12:31:22 UTC 2016
Consider using MOVW+MOVT for 32bit constants
Reported by: | Jeffrey Lee (213) | Severity: | Enhancement |
Part: | RISC OS: C/C++ toolchain | Release: | |
Milestone: | Status | Fixed |
Details by Jeffrey Lee (213):
Current versions of objasm are able to use MOVW for 16bit constants, but seem to fall back to using literal pools for 32bit constants.
Although I’m sure there are some situations where using a literal pool makes sense (e.g. same constant needed many times), ARM’s current recommendation seems to be to use MOVW+MOVT wherever possible because it avoids expensive d-cache misses and d-cache pollution, at the cost of some minor bloat of the instruction stream.
https://community.arm.com/groups/processors/blo…
If executable size bloat is an issue for some projects, perhaps a new flag could be added to control whether literal pools or MOVW+MOVT are used.
Changelog:
Modified by Sprow (202) Sat, November 26 2016 - 23:06:00 GMT
I just had a look in DUI0801F which is for ARM’s latest armasm.
For LDR Rn,=value they specifically say that it only ever emits 1 instruction. Not sure why, perhaps so it can be used in jump tables? Their solution seems to be the MOV32 pseudo instruction which always emits 2 instructions, a MOV/MOVT pair.
ObjAsm supports MOV32, so does that solve the requirement?
Modified by Jeffrey Lee (213) Wed, November 30 2016 - 13:47:32 GMT
I was hoping for a solution that would “just work” without needing to change any existing code – so if LDR Rn,=value is restricted to only emitting one instruction then that definitely throws a spanner in the works.
MOV32 may save a bit of typing on the programmer’s part but if you want a “give me this constant the best way possible” pseudo-instruction (the role that LDR Rn,=value was surely intended to fulfil) then MOV32 falls down because it always generates two instructions and it will only work on ARMv7+.
We could create a custom macro to deal with this, but I’m not sure if we’d be able to create one that can tell the difference between fixed values and ones that will require link- or run- time relocation (necessary so we can detect if a manually-emitted MOV/ADR/MOVL can be used, compared to LDR Rn,=value or MOV32)
Modified by Sprow (202) Wed, November 30 2016 - 21:10:02 GMT
Perhaps a different way of thinking about this is not fixate on ObjAsm:
If the C compiler knew how to output MOV32 then that might be more (long term) useful, and wouldn’t have the constraint of following the “only emit N instructions”. According to the ‘Acorn Assembler’ book, the linker knows how to fix up MOV32 instructions if they require relocation.
Modified by Sprow (202) Wed, November 30 2016 - 21:12:13 GMT
…erm I meant “give me this constant the best way possible” rather than specifically always MOV32 there.
Modified by Jeffrey Lee (213) Thu, December 01 2016 - 12:56:34 GMT
Yeah, intelligent MOVW+MOVT use in the C compiler would be great. Possibly https://www.riscosopen.org/bounty/polls/6 is a pre-requisite for that.
Modified by Sprow (202) Sat, March 09 2019 - 22:14:33 GMT
> Yeah, intelligent MOVW+MOVT use in the C compiler would be great.
The first beta of https://www.riscosopen.org/news/articles/2019/0… claims to support MOVW+MOVT and saves approx. 2k off a Titanium ROM – nice.
Modified by Sprow (202) Thu, November 14 2019 - 22:18:52 GMT
- Status changed from Open to Fixed
My copy of DDE29 includes cc 5.79 has this released.