HP OpenVMS Systems Documentation |
Upgrading Privileged-Code Applications on OpenVMS Alpha and OpenVMS I64 Systems
Part II
|
PTE local_pte; local_pte.pte$v_pfn = pfn; |
PTE_PQ va_pte; pfn = va_pte->pte$v_pfn; |
These references work correctly as common code on Alpha and I64.
Some C code may assume that the PFN field is 32-bits at bit position 32. This is a bad example:
unsigned __int64 pte; pfn = pte >> 32; |
This code must be changed to use the PTE structure and the field pte$v_pfn
as shown in the good programming examples above.
7.1.2 PFN References in C
PFNs are often stored as 32-bit integer variables in existing C code. These are sometimes signed and sometimes unsigned.
An example of an existing PFN:
unsigned int new_pfn; |
A new type is defined in lib_types.h called PFN_T. This type is 32-bits on Alpha and 64-bits on I64.
When modifying your code for 64-bit PFNs, you can use unsigned __int64 or the PFN_T type. This is your choice.
New Code
unsigned __int64 new_pfn; |
Alternate New Code
#include <lib_types.h> PFN_T new_pfn; |
When examining C code, look for casts of PFN fields and variables. Also look for assignment to and from other 32-bit ariables.
Example of Bad Code
pfn = (int)foo; |
You can eliminate the need for a cast or change the cast to unsigned __int64 or PFN_T. This depends on the context of the code in question.
New Code
pfn = (unsigned __int64)foo; |
Alternate New Code
pfn = (PFN_T)foo; |
Using unsigned __int64 is sometimes preferable to PFN_T. This is because the PFN_T typedef includes conditionals for Alpha and IA64. In general, less conditional code is better because it insures that the same code is tested in both cases.
Example
unsigned __int64 pfn; unsigned __int64 pa; int boff; pfn = pte_contents.pte$v_pfn; pa = (pfn << mmg$gl_bwp_width)| boff; |
Code that calculates a physical address from a PFN requires 64-bit arithmetic. The declaration of the pfn variable as unsigned __int64 insures this calculation is done correctly. In the above example, if the pfn variable were switched to type PFN_T, the line that computes the pa variable would execute differently on Alpha and I64 because the size of the pfn variable differs.
A good "rule of thumb" is this: if your code already uses unsigned __int64 as a PFN type, you should probably leave it alone.
7.2 Macro-32 Programming
This section contains instructions for Macro-32 programmers.
7.2.1 PTE Field References in Macro-32
The PTE$V_PFN field is used to reference the PFN stored in a valid or transition PTE. The symbols PTE$V_PFN, PTE$S_PFN and PTE$M_PFN are defined in $PTEDEF. This table shows the symbol values on Alpha and I64.
Symbol Name | Alpha Value | I64 Value |
---|---|---|
PTE$V_PFN | 32 | 24 |
PTE$S_PFN | 32 | 40 |
PTE$M_PFN | ^XFFFFFFFF00000000 | ^XFFFFFFFFFF000000 |
In Macro-32 PFNs can be shifted or extracted from PTEs. Also, PFNs can be shifted or inserted to PTEs.
Good Example 1
; R0 = PFN, R1 = PTE contents, R3 = PTE address EVAX_SRL R1,#PTE$V_PFN,R0 ; Get PFN from PTE EXTZV R1,#PTE$V_PFN,#PTE$S_PFN,R0 |
Good Example 2
; R0 = PFN, R1 = PTE contents, R3 = PTE address EVAX_SLL R0,#PTE$V_PFN,R1 ; Put PFN into PTE position INSV R0,#PTE$V_PFN,#PTE$S_PFN,(R3) ; Store PFN into PTE |
These references work correctly as common code on Alpha and I64. Some Macro-32 code may assume that the PFN field is the upper longword of the PTE.
Bad Example
ASSUME PTE$V_PFN EQ 32 MOVL R0,4(R3) ; Store PFN into PTE |
This code must be changed to use the PTE structure symbols as shown above.
7.2.2 PFN References in Macro-32
PFNs are often treated as longwords in existing Macro-32 code. You must change your code to ensure that the high order 32-bits are not truncated or sign extended.
Existing Code
TSTL R0 ; Is there a PFN? BNEQ 10$ ; If neq, yes |
New Code
EVAX_BNE R0,10$ ; Branch if we have a PFN |
Existing Code
MOVL R0,R7 ; Copy PFN |
New Code
EVAX_OR R0,R31,R7 ; Copy PFN |
Existing Code
INCL R0 ; Next PFN |
New Code
EVAX_ADDQ R0,#1,R0 ; Next PFN |
The above examples work correctly as common code on Alpha and I64. In other cases, you must conditionalize your code because the Alpha has 32-bit storage and I64 has 64-bit storage.
Existing Code
MOVL GSD$L_BASEPFN(R10),R0 ; Read the base PFN |
New Code
.IF DF ALPHA MOVL GSD$I_BASEPFN(R10),R0 ; Read the base PFN .ENDC .IF DF IA64 EVAX_LDQ R0,GSD$I_BASEPFN(R10) ; Read the base PFN .ENDC |
Notice that the new Macro-32 code is awkward. This code could have been common between Alpha and I64 if it were written in C.
To help program conditional code referencing "I" fields in structures, several new macros have been added to lib.mlb.
MACRO-32 Macro | Alpha Code | I64 Code |
---|---|---|
CLEAR$I loc | CLRL loc | EVAX_STQ R31, loc |
LOAD$I Rx, loc | MOVL loc, Rx | EVAX_LDQ Rx, loc |
STORE$I Rx, loc | MOVL Rx, loc | EVAX_STQ Rx, loc |
INCR$I loc | INCL loc | EVAX_ADDQ loc, #1, loc |
DECR$I loc | DECL loc | EVAX_SUBQ loc, #1, loc |
The above example can be programmed with the LOAD$I macro as follows:
LOAD$I R0, GSD$I_BASEPFN(R10) ; Read the base PFN |
Previous | Next | Contents | Index |