PPC branch instr address limit +/- 32MB?


PPC branch instr address limit +/- 32MB?

1,830 次查看
Contributor I

Branch instruction provides only 24 bits to specify absolute address, and 23 +1(sign bit) in case of relative address.so it limits the range of memory address i can jump to +/-32 MB if i use relative address
i want to jump to memory location which maybe out of range of the +/- 32 MB range.so, is there any other way i can use branch instruction to jump to any address without any limit?
One solution i thought was to load the absolute address (a word long address) into some register, but how do i load 1 complete word into a register cause of the 4-byte restriction on instruction size?

0 项奖励
2 回复数

548 次查看
Contributor I

You can load the 32 bits address into either CTR or LR register and make a 'bcrt' or 'blr'.

You can find more information into ERFFRM.pdf or your core documenation ( E200ZxRM.pdf)


You wirte C code, there comiler directive to force "far" address for function call.


Presonnally in my bootloader, I load the application start address into the LR and execute a blr to jump.

0 项奖励

548 次查看
Specialist I

Disassemble someone else's code to find out how it is done.


Your question about loading a 32-bit address exposes the bigger problem of loading ANY 32-bit value into a register.


This is always done with code like:


        lis     r4, CFG_DEFAULT_MBAR@h        lis     r3,     START_REG(CFG_BOOTCS_START)@h        ori     r3, r3, START_REG(CFG_BOOTCS_START)@l        stw     r3, 0x4(r4)             /* CS0 start */        lis     r3,     STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@h        ori     r3, r3, STOP_REG(CFG_BOOTCS_START, CFG_BOOTCS_SIZE)@l        stw     r3, 0x8(r4)             /* CS0 stop */        lis     r3,     0x02010000@h        ori     r3, r3, 0x02010000@l        stw     r3, 0x54(r4)            /* CS0 and Boot enable */

 It often seems that most of the opcodes used in PPC programming are "fake ones" or part of the "simplified nmemonics" set, which makes finding them in the instruction list really hard sometimes.


Note "lis" is one of these. There is no native "load immediate" in this CPU, so "lis rD, value" is really "addis, rD, 0, value".


Likewise the "@h" and "@l" means "the upper half of" and "the lower half of", EXCEPT when it is ""@ha" which adjusts for the carry out from the lower half when it is "negative" and when using "lis" followed by "addi" instead of "ori". This is because "addi" takes a 16 bit value and sign-extends it. "lis" and "ori" are simpler, but there are some reasons why "addi" is preferred (with all the problems it causes).


Another option is to have all of your constants in a table pointed to by one register and then load them all in one instruction relative to that pointer.


You have to at least start with "Programming Environments Manual for 32-Bit Implementations of the PowerPC Architecture," which you can download. Where you find out about "@ha" and friends I don't know. Google won't help me search for "@ha".


Also note the common practice of loading an address register with a pointer to "somewhere near" where you want and then indexing +-32k off that register, as in the stores on (r4) above.




0 项奖励