Search code examples
cgccassemblypowerpc

Assembler generates negative forms of conditions, not positive one


I wondered why gcc assembler use negative form of conditions instead of positive one. Suppose that we have following C code:

if (x == 10)
{
  x ++;
}

y ++;

When I use gcc to compile and produce object file, the result of assembly code in PowerPC assembly is as follows:

  20:   2c 00 00 0a     cmpwi   r0,10
  24:   40 82 00 10     bne 34 <main+0x34>
  28:   81 3f 00 08     lwz r9,8(r31)
  2c:   38 09 00 01     addi    r0,r9,1
  30:   90 1f 00 08     stw r0,8(r31)
  34:   81 3f 00 0c     lwz r9,12(r31)
  38:   38 09 00 01     addi    r0,r9,1
  3c:   90 1f 00 0c     stw r0,12(r31)

The assembly uses bne while I used equal == in my C code.

EDIT 1:

I know that the code is working perfectly. But I means why assembler use negative form not positive one.

EDIT 2: I am using the compiler with level 0 optimizer and we know that, it is not intelligent. My means from question is that, why assembler couldn't produce assembly such a below:

cmpi x, 10
beq label1
b label2

label1:
add x, x, 1
label2:
add y, y, 1

Could any one please explain what happens?

Thanks in advance.


Solution

  • The reason the the negative form is simple : branching is the opposite of an if. Branching means "skip if", while if means "execute if". So, for an assembly with a conditional branching model, all the if conditions will be negated to translate to a single branch. For an if+else, it doesn't matter because the two can be swapped, but usually the negation is preserved.

    Negating is the intuitive thing here ; take your example :

    if (x == 10)
    {
        x++;
    }
    y++;
    

    When you "run" the code in your head, what do you do ? You look at the condition, and check if it is true. If it is, you do x++, then y++. If it isn't, you jump directly to y++. In other words, you jump (branch) to y++ if the condition is false ; you intuitively negate the condition.