Live data from Hacker News

ARM immediate value encoding

alisdair.mcdiarmid.org

1–10 of 71 posts

Re: ARM immediate value encoding

#2
The set of representable ARM immediates is really nice. It's wonderfully useful for writing soft-float and math library routines, where you have very common values with just some high-order bits set:

    0x3f800000 // encoding of 1.0f
The set of immediate encodings, together with "shifts for free on most operations" (which are closely related features, as the OP points out), went a long way toward preserving my sanity when writing assembly.

Worth noting: thumb-2 immediates have a different (and even more interesting) encoding scheme. arm64 immediates are pretty interesting too (there the set of representable immediates is different depending on the instruction domain).

Re: ARM immediate value encoding

#4
post #3

So arm compilers must prefer to, for example, XOR with 0x10000000 rather than AND with 0xEFFFFFFF?

AND with 0xefffffff would become BIC ("bit clear", aka "and not") with 0x10000000. But yes, the basic idea of your comment is correct. Fortunately, compilers are quite good at this sort of thing.

Re: ARM immediate value encoding

#7

Very cool and clever scheme. But what happens to immediates that can't be encoded that way?

There are a few options for producing other values:

1. load them from a constant pool in memory (often this is put nearly inline in the instruction stream so that it can be addressed via a small constant offset from PC). If your code doesn't saturate the LSU locally, this is usually the best option.

2. assemble them via bitwise or arithmetic combinations of literals that you can represent (or already in-register values that you know something about). If you can do it with just a few operations, and the LSU is otherwise occupied, you should do this instead. This is also preferred on some limited cores that can dual-issue logical and arithmetic ops but not LSU ops.

3. in recent revisions of the instruction set, there are a pair of instructions MOVW and MOVT; MOVW conjures a 16b immediate, and MOVT sets the high 16b, so with these two instructions you can conjure any 32b value.

There is a bit of subtlety to choosing the correct approach. Some assemblers provide a "conjure this value" pseudo-operation where the assembler will choose what it thinks is the best option to materialize a constant; that way the programmer doesn't need to worry about these details. This looks something like the following:

    LDR R0, =0xff0000ff
the assembler might actually stash the constant somewhere and generate a load instruction, or it might instead do:

    MOV R0,     0xff000000
    ORR R0, R0, 0x000000ff
and assemble the value via a couple instructions with immediates.

Re: ARM immediate value encoding

#9

The set of representable ARM immediates is really nice. It's wonderfully useful for writing soft-float and math library routines, where you have very common values with just some high-order bits set: 0x3f800000 // encoding of 1.0f The set of immediate encodings, together with "shifts for free on most operations" (which are closely related features, as the OP points out), went a long way toward preserving my sanity wh…

Honestly, with so few bits, I was expecting it to be a lookup table. (Yep, I've never wrote ARM assembly.)

But then, this way you have a nice set of imediates (as you said), and can set any value at all with at most 3 instructions at the rare case you need something different.

Re: ARM immediate value encoding

#10
If I've interpreted this correctly, it means that all values between 256 and 65535 can't be encoded this way since they all have the form

0x0000nn00

with a nonzero nn, and those are the bits that can't be gotten to from rotating.

Post reply on HN