Basic System Problem Analysis - August 2003

37
PA-RISC General Registers
The PARISC Instruction Set Reference Manual and the Procedure Calling Convention
manual are pretty hard to come by. They are not at the docs.hp.com web site so it is
worth spending a little time going over some of the basics of the hardware.
DEBUG, DAT and SAT use aliases for certain of the registers, SP, the stack pointer will
always be R30. DP, the data pointer (global variables in a program context) will always
be R27. RP or the procedure return pointer is R2.
The procedure calling convention specifies that the first four argument values being
passed in a procedure call be placed in registers R26 to R23. The first parameter going
into R26 and onward to R23. All additional parameters are placed into the stack frame
that was created by the procedure making the call.
Parameters may require more than one register, a long pointer or LONGINT for example,
will take two registers. If that occurs the registers must be aligned. This may result in one
of the registers being skipped and left unused (more on this in a bit).
GR31 is called the “millicode RP” but it is also where the “BLE” instruction initially
stores the current value of the PC register before making the branch. It moved to R2
immediately after that, in the “delay slot” of the branch.
R0 is a scratch register that contains the value 0. It is cannot be written to but it is legal to
use R0 as a target register when a value is not required. For example, the “NO OP”
instruction (one that does nothing) is 08000240 OR r0, r0, r0. Logically OR R0, through
R0 giving R0… nothing.
PA-RISC instructions are pipelined. Whenever a branch instruction is executed there is a
delay in processing that branch while the target address is fetched. This delay affords the
hardware the opportunity to execute an instruction in that delay slot. The delay can be
nullified. Typically, the long branch code sequence moves R31, the target offset address
of the BLE into R2 (architected “RP”) in this delay slot.
23ed0012 LDIL $91a000,r31
e7e02640 BLE 800(sr4,r31)
081f0242 OR r31,r0,r2
By the way, in DEBUG, DAT or SAT you can manually find out where this branch goes
by doing:
$235 ($70) nmdat > dcs 91a000+#800
SYS $a.91a320
0091a320 tm_unlink_plfd 6bc23fd9 STW r2,-20(sr0,r30)