HP OpenVMS Systems Documentation

Content starts here

Porting Applications from HP OpenVMS Alpha to HP OpenVMS Industry Standard 64 for Integrity Servers


Previous Contents Index

4.8.1 Conditionalized Code

This section describes how to conditionalize OpenVMS code when migrating to I64. This code will be compiled for both Alpha and I64, or for VAX, Alpha, and I64. The symbol ALPHA, referred to in the following sections, is new. However, the symbol EVAX has not been eliminated. You do not need to replace EVAX with ALPHA but feel free to do so if convenient. The architecture symbols available for MACRO and BLISS are VAX, EVAX, ALPHA, and I64.

4.8.1.1 MACRO Sources

For Macro-32 source files, the architecture symbols are in ARCH_DEFS.MAR, which is a prefix file specified on the command line. On Alpha, ALPHA and EVAX equal 1 while VAX and I64 are undefined. On I64, I64 equals 1 while VAX, EVAX, and ALPHA are undefined.

The following example show how to conditionalize Macro-32 source code so that it can run on both Alpha and I64 systems.

For Alpha-specific code:


.IF DF ALPHA
       .
       .
       .
.ENDC

For I64-specific code:


.IF DF I64
       .
       .
       .
.ENDC

4.8.1.2 BLISS Sources

For BLISS source files, either BLISS-32 or BLISS-64, the macros VAX, EVAX, ALPHA and I64 are defined in ARCH_DEFS.REQ. On Alpha, EVAX and ALPHA equal 1 while VAX and I64 equal 0. On I64, I64 equals 1 while VAX, EVAX, and ALPHA equal 0. You must require ARCH_DEFS.REQ to use these symbols in BLISS conditionals.

Note

The constructs %BLISS(xxx), %TARGET(xxx), and %HOST(xxx) are not recommended. Do not feel obligated to replace them, but feel free to do so if convenient.

Include the following statement in your source file:


REQUIRE 'SYS$LIBRARY:ARCH_DEFS';

Use the following statements in your source file to conditionalize code so that it can run on both Alpha and I64 systems.

For Alpha-specific code:


%if ALPHA %then
        .
        .
        .
%fi

For I64-specific code:


%if I64 %then
        .
        .
        .
%fi

4.8.1.3 C Sources

For C source files, the symbols __alpha , __ALPHA , __ia64 , and __ia64__ are provided by the compilers on the appropriate platforms. Note that symbols could be defined on the compile command line but that is not the recommended method, nor is using arch_defs.h . Using #ifdef is considered the standard C programming practice.

For Alpha-specific code, use the following:


#ifdef __alpha
        .
        .
        .
#endif

For I64-specific code, use the following:


#ifdef __ia64
        .
        .
        .
#endif

4.8.1.4 Existing Conditionalized Code

Existing conditionalized code must be examined to determine whether changes are required. Here is an example of BLISS code to consider.


%IF VAX %THEN
  vvv
  vvv
%FI

%IF EVAX %THEN
  aaa
  aaa
%FI

If the code is truly architecture specific and you are adding I64 code, then you would add the following case:


%IF I64 %THEN
  iii
  iii
%FI

However, if the existing VAX/EVAX conditionals really reflect 32 bits and not 64 bits or an "old" versus "new" OpenVMS convention (for example, a promoted data structure or different routine to call), then the following method for conditionalizing code might be more appropriate. That is because Alpha and I64 code are the same and 64-bit code need to be distinguished from the VAX code.


%IF VAX %THEN
  vvv
  vvv
%ELSE
  aaa
  aaa
%FI

4.8.2 System Services With Alpha Architecture Dependencies

Certain system services that work well in applications on OpenVMS Alpha do not port successfully to I64. The following sections describe system services and their replacement services.

4.8.2.1 SYS$GOTO_UNWIND

For OpenVMS Alpha, the SYS$GOTO_UNWIND system service accepts a 32-bit invocation context handle by reference. You must change instances of this system service to SYS$GOTO_UNWIND_64, which accepts a 64-bit invocation context. Make sure to alter source code to allocate space for the 64-bit value. Also, different library routines return invocation context handles for OpenVMS I64. For more information, refer to the HP OpenVMS Calling Standard.

SYS$GOTO_UNWIND is most frequently used to support programming language features, so changes are mostly in compilers or run-time libraries. However, any direct use of SYS$GOTO_UNWIND requires change.

4.8.2.2 SYS$LKWSET and SYS$LKWSET_64

The SYS$LKWSET and SYS$LKWSET_64 system services have been modified. For more information, see Section 4.8.9.

4.8.3 Code With Other Dependencies on the Alpha Architecture

This section describes coding practices on Alpha that produce different results on I64 and may require changes to your application.

4.8.3.1 Initialized Overlaid Program Sections

Initialized overlaid program sections are handled differently on I64 systems. On OpenVMS Alpha systems, different portions of an overlaid program section may be initialized by multiple modules. This is not allowed on OpenVMS I64 systems. For more information about this change in behavior, see Section 5.3.1.2.

4.8.3.2 Condition Handlers Use of SS$_HPARITH

On OpenVMS Alpha, SS$_HPARITH is signaled for a number of arithmetic error conditions. On OpenVMS I64, SS$_HPARITH is never signaled for arithmetic error conditions; instead, the more specialized SS$_FLTINV and SS$_FLTDIV error codes are signaled on OpenVMS I64.

Update condition handlers to detect these more specialized error codes. In order to keep code common for both architectures, wherever the code refers to SS$_HPARITH, extend it for OpenVMS I64 to also consider SS$_FLTINV and SS$_FLTDIV.

4.8.3.3 Mechanism Array Data Structure

The mechanism array data structure on OpenVMS I64 is very different from the one on OpenVMS Alpha. The return status code RETVAL has been extended to represent the return status register on both Alpha and I64 platforms. For more information, refer to the HP OpenVMS Calling Standard.

4.8.3.4 Reliance on Alpha Object File Format

If your code relies on the layout of Alpha object files, you will need to modify it, because the object file format produced on OpenVMS I64 systems is different.

The object file format conforms to the 64-bit version of the executable and linkable format (ELF), as described in the System V Application Binary Interface draft of 24 April 2001. This document, published by Caldera, is available on their web site at:


http://www.caldera.com/developers/gabi

The object file format also conforms to the I64 specific extensions described in the Intel® Itanium® Processor-specific Application Binary Interface (ABI), May 2001 edition (document number 245270-003). Extensions and restrictions, necessary to support object file and image file features that are specific to the OpenVMS operating system, will be published in a future release.

The portion of an image which is used by the debugger conforms to the DWARF Version 3 industry standard, which is available at the following location:


http://www.eagercon.com/dwarf/dwarf3std.htm

The debug symbol table representation on OpenVMS I64 is the industry-standard DWARF debug symbol table format described at this location. HP extensions to the DWARF Version 3 format will be published in a future release.

4.8.4 Code that Uses Floating-Point Data Types

OpenVMS Alpha supports VAX floating-point data types and IEEE floating point data types in hardware. OpenVMS I64 supports IEEE floating-point in hardware and VAX floating-point data types in software.

Most of the OpenVMS I64 compilers provide the /FLOAT=D_FLOAT and /FLOAT=G_FLOAT qualifiers to enable you to produce VAX floating-point data types. If you do not specify one of these qualifiers, IEEE floating-point data types will be used.

to specify a default floating-point data types using the I64 BASIC compiler, you use the /REAL_SIZE qualifer.The possible values that can be specified are SINGLE (Ffloat), DOUBLE (Dfloat), GFLOAT, SFLOAT, TFLOAT, and XFLOAT.

You can test an application's behavior with IEEE floating-point values on Alpha by compiling it with an IEEE qualifier on OpenVMS Alpha. If that produces acceptable results, you can build the application on an I64 system using the same qualifier.

When you compile an OpenVMS application that specifies an option to use VAX floating-point on I64, the compiler automatically generates code for converting floating-point formats. Whenever the application performs a sequence of arithmetic operations, this code does the following:

  1. Converts VAX floating-point formats to either IEEE single or IEEE double floating-point formats, as appropriate for the length.
  2. Performs arithmetic operations in IEEE floating-point arithmetic.
  3. Converts the resulting data from IEEE formats back to VAX formats.

Where no arithmetic operations are performed (VAX float fetches followed by stores), conversions do not occur. The code handles such situations as moves.

In a few cases, arithmetic calculations might have different results because of the following differences between VAX and IEEE formats:

  • Values of numbers represented
  • Rounding rules
  • Exception behavior

These differences might cause problems for certain applications.

For more information about the differences between floating-point data types on OpenVMS Alpha and OpenVMS I64 and how these differences might affect ported applications, see Chapter 5 and refer to the "OpenVMS Floating-Point Arithmetic on the Intel® Itanium® Architecture" white paper. See the Related Documents section in the Preface for the web location of this white paper.

Note

Since the floating-point white paper was written, the default /IEEE_MODE has changed from FAST to DENORM_RESULTS. This means that, by default, floating-point operations might silently generate values that print as Infinity or Nan (the industry-standard behavior) instead of issuing a fatal run-time error as they would using VAX format float or /IEEE_MODE=FAST. Also, the smallest-magnitude nonzero value in this mode is much smaller because results are permitted to enter the denormal range instead of being flushed to zero as soon as the value is too small to represent with normalization. This default is the same default established by I64 at process startup.

4.8.4.1 LIB$WAIT Problem and Solution

The use of LIB$WAIT in code ported to OpenVMS I64 can cause unexpected results. An example in C follows.


float wait_time = 2.0;
lib$wait(&wait_time);

On OpenVMS I64 systems, this code sends an S_FLOATING into LIB$WAIT. LIB$WAIT expects an F_FLOATING, and gives a FLTINV exception.

LIB$WAIT can accept three arguments. The previous code sequence can be rewritten with LIB$WAIT using three arguments to run correctly on both I64 and Alpha systems. The following revised code works correctly when compiled without the /FLOAT qualifier:


#ifdef __ia64
 int float_type = 4;  /* use S_FLOAT for I64 */
#else
 int float_type = 0;  /* use F_FLOAT for Alpha */
#endif
 float wait_time = 2.0;
 lib$wait(&wait_time,0,&float_type);

A better coding method is to include LIBWAITDEF (from SYS$STARLET_C.TLB) in your application and then specify the floating point data types by name. This code can be maintained more easily.

LIBWAITDEF includes the following symbols:

  • LIB$K_VAX_F
  • LIB$K_VAX_D
  • LIB$K_VAX_G
  • LIB$K_VAX_H
  • LIB$K_IEEE_S
  • LIB$K_IEEE_T

The following example shows how to include libwaitdef.h in the code and how to specify the floating-point data type names. This example also assumes that the program is not compiled with /FLOAT.


#include <libwaitdef.h>
.
.
.
#ifdef __ia64
 int float_type = LIB$K_IEEE_S;  /* use S_FLOAT for IPF */
#else
 int float_type = LIB$K_VAX_F;  /* use F_FLOAT for Alpha */
#endif
 float wait_time = 2.0;
 lib$wait(&wait_time,0,&float_type);

4.8.5 Incorrect Command Table Declaration

An incorrect declaration of a command table in code ported to OpenVMS I64 can cause unexpected results. For example, for an application, the Command Definition Utility is used to create an object module from a CLD file. The application then calls CLI$DCL_PARSE to parse command lines. CLI$DCL_PARSE may fail with:


%CLI-E-INVTAB, command tables have invalid format - see documentation

The code must be modified so that the command table is defined as an external data object.

For example, if in an application, on VAX and Alpha, the command table (DFSCP_CLD) is incorrectly declared in a BLISS module as:


EXTERNAL ROUTINE DFSCP_CLD

This should be changed to


EXTERNAL DFSCP_CLD

Or if it was in a FORTRAN module incorrectly declared as:


EXTERNAL DFSCP_CLD

then it should be changed to


INTEGER DFSCP_CLD
CDEC$ ATTRIBUTES EXTERN :: DFSCP_CLD

Similarly, in an application written in C, if the command tables previously were defined as follows:


int jams_master_cmd();

The code should be changed to be an external reference:


extern void* jams_master_cmd;

The changed, correct declaration works on all platforms: VAX, Alpha or I64.

4.8.6 Code that Uses Threads

OpenVMS I64 supports all the thread interfaces that have been supported on OpenVMS since thread support was first introduced. Most OpenVMS Alpha code that uses threads can be ported to OpenVMS I64 without change. This section describes the exceptions. The major porting issue for code that uses threads is the usage of stack space. I64 code uses much more stack space than does equivalent Alpha code. Therefore, a threaded program that works on Alpha might get stack overflow failures on I64.

The default stack size is larger on OpenVMS I64 to help alleviate overflow problems. If the application requests a specific stack size, then the change to the default will be irrelevant, and the application source code might need to be changed to request more stack. HP recommends starting with an increase of three 8-Kb pages (24576 bytes).

Another side effect of the increased stack size requirement is increased demand on the P0 address region. Thread stacks are allocated from the P0 heap. Larger stacks might cause the process to exceed its memory quotas. In an extreme case, the P0 region could fill completely, in which case the process might need to reduce the number of threads in use concurrently (or make other changes to lessen the demand for P0 memory).

HP recommends that you familiarize yourself with the most recent improvements to thread support in OpenVMS, as documented in the HP OpenVMS Version 8.2 Release Notes. One change to the POSIX Threads C language header file PTHREAD_EXCEPTION.H caused problems when porting an application that relied on its former behavior.

The DCL command THREADCP is not supported on OpenVMS I64. For OpenVMS I64, the DCL commands SET IMAGE and SHOW IMAGE can be used to check and modify the state of threads-related image header flags, similar to the THREADCP command on OpenVMS Alpha. For details, refer to the HP OpenVMS DCL Dictionary.

The THREADCP command is documented in the Guide to the POSIX Threads Library.

If you want to change the setting of threads-related image flags, you need to use the new command SET IMAGE. For example:


$ SET IMAGE/FLAGS=(MKTHREADS,UPCALLS) FIRST.EXE

4.8.6.1 Thread Routines cma_delay and cma_time_get_expiration

Two legacy threads API library routines, cma_delay and cma_time_get_expiration, accept a floating point format parameter using the VAX F FLOAT format. Any application modules that call either of these routines must be compiled with either the /FLOAT=D_FLOAT or the /FLOAT=G_FLOAT qualifier to get VAX F FLOAT support. (However, if your application also uses double precision binary data, then you must use the /FLOAT=G_FLOAT qualifier.) For more information about floating point support, consult your compiler's documentation.

If a C language module (which uses either cma_delay or cma_time_get_expiration) is compiled by mistake in an IEEE floating-point mode, a compiler warning similar to the following will be displayed:


cma_delay (
    ^
%CC-W-LONGEXTERN, The external identifier name exceeds 31
characters; truncated to "CMA_DELAY_NEEDS_VAX_FLOAT______".

If an object file which triggered such a warning is linked, the linker will display an undefined-symbol message for this symbol. (If a linker-produced image was subsequently executed, the calls to these routines would fail with an ACCVIO.) These compiler and linker diagnostics are intended to alert you to the fact that these CMA routines require the use of VAX format floating-point values, and that the compilation was done in a manner that does not satisfy this requirement.

Note

These routines are no longer documented in user documentation but are still supported for use in legacy applications.

4.8.7 Code With Unaligned Data

HP recommends that you align your data naturally to achieve optimal performance for data referencing. Unaligned data can seriously degrade performance on both OpenVMS Alpha and OpenVMS I64.

Data is naturally aligned when its address is an integral multiple of the size of the data in bytes. For example, a longword is naturally aligned at any address that is a multiple of 4, and a quadword is naturally aligned at any address that is a multiple of 8. A structure is naturally aligned when all its members are naturally aligned.

Because natural alignment is not always possible, OpenVMS I64 systems provide help to manage the impact of unaligned data references. Alpha and I64 compilers automatically correct most potential alignment problems and flag others.

In addition to performance degradation, unaligned shared data can cause a program to execute incorrectly. Therefore, you must align shared data naturally. Shared data might be between threads of a single process, between a process and ASTs, or between several processes in a global section.

Finding the Problem

To find instances of unaligned data, you can use a qualifier provided by most I64 compilers that allows the compiler to report compile-time references to unaligned data.

Table 4-1 Compiler Switches for Reporting Compile-Time Reference
Compiler Switch
BLISS /CHECK=ALIGNMENT
C /WARN=ENABLE=ALIGNMENT
Fortran /WARNING=ALIGNMENT
HP Pascal /USAGE=PERFORMANCE

Additional assistance, such as an OpenVMS Debugger qualifier to reveal unaligned data at run time, is planned for a future release.

Eliminating the Problem

To eliminate unaligned data, you can use one or more of the following methods:

  • Compile with natural alignment, or, when language semantics do not provide for this, move data to be naturally aligned. Where filler is inserted to ensure that data remains aligned, there is a penalty in increased memory size. A useful technique for ensuring naturally aligned data while conserving memory is to declare longer variables first.
  • Use high-level-language instructions that force natural alignment within data structures.
  • Align data items on quadword boundaries.

Note

Software that is converted to natural alignment may be incompatible with other software that is running translated in the same OpenVMS Cluster environment or over a network. For example:
  • An existing file format may specify records with unaligned data.
  • A translated image may pass unaligned data to, or expect it from, a native image.
In such cases, you must adapt all parts of the application to expect the same type of data, either aligned or unaligned.


Previous Next Contents Index