# calculate branch target address powerpc

I want to know how next instruction address (NIA) is calculated for BL instruction. Lets assume that there is such instruction:

``````.text:100004C8    BL sub_10000670.
``````

This command in hex is:

``````48 00 01 A9
``````

Here we have that current instruction address (CIA) is `100004C8` and NIA is `10000670`. So accroding to this book (page 33 in pdf) we have to concatenate LI (in our case it is `6A`) and `0B00`, sign extend it and sunm with 32 high ordered bits of `NIA`. The formula is

``````NIA = CIA + EXTS(LI || 0B00).

NIA - CIA = 10000670 - 100004C8 = 1A8.
``````

How can i get from `1A8` my `LI = 6A` value? What do i misunderstand?

## 2 Answers

NIA = CIA + EXTS(LI || 0B00)

The `||` notation denotes concatenation. So if you take LI

0x6A -> 0b1101010

And add two zeroes:

0b1101010 || 0b00 -> 0b110101000 -> 0x1A8

You get: NIA = 0x100004C8 + 0x1A8 = 10000670

• Thank you for your answer! And what should i do, if NIA less then CIA? For example. NIA = 1000029C, CIA = 1000052C, and instruction in hex = 4B FF FD 6D? Jan 25 '20 at 16:13
• In that case LI is treated as a signed number and is sign extended (this is what SEXT notation means) Jan 25 '20 at 16:19
• yeah, it was clear...thanks! Jan 25 '20 at 16:54

base16 0x480001a9 == base2 1001000000000000000000110101001

chop of 5 upper bits and two lower bits for LI = 000000000000000001101010 = 0x6a

shift left 0x6a by two 0x6a << 2 = 0x1a8

add current instruction Address 0x100004c8 to the result 0x10000670 is the Target Address

since LK = 1 put 0x100004cc in link register

a simple python demo (edited to add negative )

``````instruction = [0x480001a9,0x4BFFFD6D]
CIA = [0x100004c8,0x1000052C]
for i in range(0,len(instruction),1):
asbin = bin(instruction[i])
print (hex(instruction[i]) +' = '+ asbin)
print ("length of asbin = " + str(len(asbin)))
Displacement  = ((int( '0b'+ asbin[8:31] ,2) << 2) & 0xffff )
if((Displacement & 0x8000) == 0x8000):
Displacement = -(0x10000-Displacement)
print hex(Displacement)
NIA = hex(CIA[i] + Displacement)
print (NIA)
``````

executed

``````0x480001a9 = 0b1001000000000000000000110101001
length of asbin = 33
0x1a8
0x10000670
0x4bfffd6d = 0b1001011111111111111110101101101
length of asbin = 33
-0x294
0x10000298
``````
• edited the code to address your comment take a look Jan 25 '20 at 17:45