Live data from Hacker News

ARM immediate value encoding

alisdair.mcdiarmid.org

31–40 of 71 posts

Re: ARM immediate value encoding

#31
post #22

I was left with one question after reading the article: the purpose of the condition field in the instruction.

In the ARM instruction encoding, every arithmetic and logical instruction is "conditional". The destination register is either updated or not depending on the four bit condition field and the state of the condition flags in the processor. As a simple contrived example, consider the following C code: int a[100], b[100], count; ... for (int i=0; i b[i]) count++; } without conditional execution, one might compile this t…

I remember there was a "never" condition, which was present just for completeness; it turns out ARM eventually found that having 2^28 different NOPs would not be a good use of opcode space, so it's now a special extension for newer instructions...

Re: ARM immediate value encoding

#32

This is clever. However... The problem as I see it with this sort of cleverness is that it's difficult to optimize to this. It leads to quite variable best-case and worst-case scenarios and general unpredictability. As, say, a C programmer and not a compiler designer, you might unintentionally pick lots of values that won't fit into the "immediate" scheme (worst-case). Or you might force your design to use numbers th…

These days if what you're writing is in C then you should really know the behaviour of the architecture underneath.

ARM really isn't that hard if you're already thinking like a low level programmer. Things like MIPS were (better) designed for being targeted from higher level languages, but the consequence is a much messier machine language. It's always struck me as amusing that the conventional view is MIPS is minimal, when ARM is really much more so, but it's from outside the Berkeley/Stanford RISC bubble so didn't really get on to their radars for some time.

Re: ARM immediate value encoding

#33

Earlier quoted context omitted.

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.

> I was expecting it to be a lookup table. There's one ISA I've worked with before that does have -2, -1, 0, 1, 2, and some other "commonly used constants" like powers of 2 encoded specially in the immediate. I think it was an 8-bit, but I can't remember exactly which one. Anyone know what I'm referring to?

MSP430?

Re: ARM immediate value encoding

#34
post #3

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

Aside from this kind of trick, I have not worked with a ton of ARM assembly but what I find is very frequently compilers will just put values in the text section close to where they are used and refer to them with some PC-relative thing, rather than using immediate values as often as they might on x86. I have seen this on other RISC platforms as well.

Re: ARM immediate value encoding

#35
post #8

Holy crap. ARM's encoding makes so much sense... compared to what I have waded through at sandpile.org.

The x86 encoding actually makes sense once you begin to write its instructions using octal instead of hexadecimal numbers: http://www.dabo.de/ccc99/www.camp.ccc.de/radio/help.txt (this isn't mentioned in the Intel or AMD docs).

Re: ARM immediate value encoding

#36
The Tensilica guys took this thing an extra step. ie- profile real code to find out what constants are most typically used, enumerate the top n constants, encode the constant with 0..n-1 in the immediate instruction - the immediate value is a hardware based lookup. You can still do arbitrary immediates with longer instructions but you can apparently get some nice code size reductions using this technique.

Re: ARM immediate value encoding

#37
post #22

I was left with one question after reading the article: the purpose of the condition field in the instruction.

In the ARM instruction encoding, every arithmetic and logical instruction is "conditional". The destination register is either updated or not depending on the four bit condition field and the state of the condition flags in the processor. As a simple contrived example, consider the following C code: int a[100], b[100], count; ... for (int i=0; i b[i]) count++; } without conditional execution, one might compile this t…

That's a beautiful explanation. It's one of my favorite things about the ARM instruction set.

That said, it also means debugging becomes a bit more painful. Let's say you want your (cheap) JTAG debugger to halt on the count++ instruction. You can hard break on that particular address in code, but you will always hit that address whether the condition was met or not.

Re: ARM immediate value encoding

#38

Earlier quoted context omitted.

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.

> I was expecting it to be a lookup table. There's one ISA I've worked with before that does have -2, -1, 0, 1, 2, and some other "commonly used constants" like powers of 2 encoded specially in the immediate. I think it was an 8-bit, but I can't remember exactly which one. Anyone know what I'm referring to?

The MSP430 has a constant generator register, which depending on the access mode used will generate offsets and zero. I'm sure there are a few others.

Re: ARM immediate value encoding

#39
Thumb-2 immediate encoding is even more gleeful--in addition to allowing rotation, it also allows for spaced repetition of any 8-bit pattern (common in low level hack patterns, like from [1]) to be encoded in single instructions.

For those interested, check out page 122 of the ARMv7-M architecture reference manual[2]:

  // ThumbExpandImm_C()
  // ==================
  (bits(32), bit) ThumbExpandImm_C(bits(12) imm12, bit carry_in)
    if imm12 == ’00’ then
      case imm12 of
        when ’00’
          imm32 = ZeroExtend(imm12, 32);
        when ’01’
          if imm12 == ’00000000’ then UNPREDICTABLE;
          imm32 = ’00000000’ : imm12 : ’00000000’ : imm12;
        when ’10’
          if imm12 == ’00000000’ then UNPREDICTABLE;
          imm32 = imm12 : ’00000000’ : imm12 : ’00000000’;
        when ’11’
          if imm12 == ’00000000’ then UNPREDICTABLE;
          imm32 = imm12 : imm12 : imm12 : imm12;
      carry_out = carry_in;
  else
    unrotated_value = ZeroExtend(’1’:imm12, 32);
    (imm32, carry_out) = ROR_C(unrotated_value, UInt(imm12));
  return (imm32, carry_out)
[1] http://graphics.stanford.edu/~seander/bithacks.html (worth a read on its own if you're into this kind of thing)

[2] http://web.eecs.umich.edu/~prabal/teaching/eecs373-f10/readi... (no-registration link)

Re: ARM immediate value encoding

#40
I love that the author described the ARM as "elegant, pragmatic, and quirky." It reminds me of Gordon Bell's PCP-6/PDP-10 architecture, but applied to the RISC rather than CISC philosophy.

(well, the PDP-10 was pretty RISC for its day and gave us things like BLT, hence bitblit).

Post reply on HN