Hacker News new | past | comments | ask | show | jobs | submit login

The ARM approach is clever, but you only load 8 bits. Suppose you need a 32-bit constant - it's going to take 4 instructions. Compared to the halfword instructions, you do win with certain awkward constants such as 3<<15. That's why neither approach is as good as having variable-length instructions ;)

This made me wonder how common such constants are. So I grabbed some code I've been working on recently, for which I happened to have assembly language output, and searched for every immediate constant. (This must be the first time I've found a good use for gcc's nasty AT&T x64 syntax.)

My code targets x64, so take the "analysis" with a pinch of salt. Out of the 8982 instructions that had immediate operands, there were 819 unique 32-bit constants. 762 (93%) were high-halfword or low-halfword only, so they could have been loaded with one halfword instruction. By comparison, only 392 (48%) could been loaded with one instruction on ARM.

Ten constants were better for ARM, in that they would take two halfword instructions to form, but only one MOV or MVN: ['0x00ffffff', '0x03ffffff', '0x0fffffff', '0x3fffffff', '0x7fffffe8', '0x7ffffffe', '0x7fffffff', '0x80000003', '0xfffffffe', '0xffffffff']. These ten constants were used by 84 instructions out of the 8982.




Modern ARM has load halfword insns too, so you can use those or the 8-bit imm encoding depending on the constant.

For a full 32 bit value prior to movw/movt you'd most likely load it from a constant pool rather than do a 4 insn sequence. (Some 32 bit values can be done with clever choice of 8imm sequences -- there's an algorithm you can use as a compiler to say "given this value can I create it in 3 or less insns?", which is worth the effort if you're targeting a pre-movw ARM cpu.)




Consider applying for YC's W25 batch! Applications are open till Nov 12.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: