HP OpenVMS Systems

ask the wizard
Content starts here

Mixing floating point representations? (IEEE, VA

» close window

The Question is:

 
Problem using Vax Float and IEEE float on the same executable.
 
I faced a problem while trying to use two API libraries.  One is compiled
using /IEEE option and the other one uses vax floats.
 
I have done similar things with other API libraries and it works on other
libraries.
 
I wrote a test program to duplicate the problem.
The same behavior is also seen on OVMS/AXP 7.1
 
Problem is: a floating point value passed to the function (which is compiled
with vax float option) the high and low order words are swapped. Main
program is compiled  with IEEE option.
 
floating point is converted to VAX format and it does not work.
The value passed to the subfunction is not right even if conversion is not
applied.
 
restriction:  I have to pass a float by value.  I cannot pass pointers
(since I cannot modify the Third party API)
 
 
 
Here's the source files.
 
 
------- test5.c Start ------
#include <stdio.h>
#include <stdlib.h>
#include <cvtdef.h>
#include <cvt$routines.h>
 
int testsub(float);
 
main()
 
int st,err;
float fval=50.0;
float ieeefval=50.0;
 
 
printf("main: Initial (%e:%#x)\n\n", fval, *((int*)&fval));
 
err = testsub((float)fval);
 
 
st=CVT$CONVERT_FLOAT(&ieeefval, CVT$K_IEEE_S, &fval, CVT$K_VAX_F,
CVT$M_VAX_ROUNDING);
printf("main: ieeefval:%e:%#x  fval:%e:%#x\n\n", (double)ieeefval,
*((int*)&ieeefval), (double)fval, *((int*)&fval));
 
err = testsub((float)fval);
 
 
---- end ------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cvtdef.h>
#include <cvt$routines.h>
 
int testsub(float value)
 
    float ieeefval=0.0;
    float fval=0.0;
    int st=0;
 
    printf("  Initial: testsub(%e:%#x)\n", value, *((int*)&value));
 
    fval=value;
    st=CVT$CONVERT_FLOAT(&fval, CVT$K_VAX_F, &ieeefval, CVT$K_IEEE_S,
CVT$M_ROUND_TO_NEAREST);
    printf("   =     : ieeefval:%e:%#x  fval:%e:%#x\n", (double)ieeefval,
*((int*)&ieeefval), (double)fval, *((int*)&fval));
 
    memcpy((void*)&fval, (void*)&value, sizeof(float));
    st=CVT$CONVERT_FLOAT(&fval, CVT$K_VAX_F, &ieeefval, CVT$K_IEEE_S,
CVT$M_ROUND_TO_NEAREST);
    printf("  memcpy : ieeefval:%e:%#x  fval:%e:%#x\n", (double)ieeefval,
*((int*)&ieeefval), (double)fval, *((int*)&fval));
 
    printf("  Exiting: testsub(%e:%#x)\n\n", value, *((int*)&value));
 
    return 0;
 
---- end ----
 
 
--- The output file ---
ALPHA1$ cc testsub.c /debug=all/noopt/list/float=g_float/ansi/extern=strict
ALPHA1$ CC
TEST5.C/list/noopt/debug=(all)/float=ieee/ieee_mode=DENORM_RES/ansi/exter=st
rict
ALPHA1$ LINK /ALPHA /debug TEST5.OBJ, testsub.obj
ALPHA1$ r test5
main: Initial (5.000000e+01:0x42480000)
 
  Initial: testsub(1.250000e+01:0x4248)
   =     : ieeefval:0.000000e+00:0x41480000  fval:1.250000e+01:0x4248
  memcpy : ieeefval:0.000000e+00:0x41480000  fval:1.250000e+01:0x4248
  Exiting: testsub(1.250000e+01:0x4248)
 
main: ieeefval:5.000000e+01:0x42480000  fval:0.000000e+00:0x4348
 
  Initial: testsub(0.000000e+00:0x43480000)
   =     : ieeefval:0.000000e+00:000  fval:0.000000e+00:0x43480000
  memcpy : ieeefval:0.000000e+00:000  fval:0.000000e+00:0x43480000
  Exiting: testsub(0.000000e+00:0x43480000)
 
------------------
If /noprefix used
------------------
 
ALPHA1$ CC
TEST5.C/list/noopt/debug=(all)/float=ieee/ieee_mode=DENORM_RES/ansi/exter=st
rict/noprefix
ALPHA1$ cc testsub.c
/debug=all/noopt/list/machine/float=g_float/extern=strict/noprefix
ALPHA1$ LINK /ALPHA /debug TEST5.OBJ, testsub.obj,
sys$library:vaxcrtlt.olb/lib, sys$library:vaxcrtl.olb/lib
ALPHA1$ r test5
main: Initial (5.000000e+01:0x42480000)
 
  Initial: testsub(8.130838e-320:0x4248)
   =     : ieeefval:6.763991e-316:0x41480000  fval:8.130838e-320:0x4248
  memcpy : ieeefval:6.763991e-316:0x41480000  fval:8.130838e-320:0x4248
  Exiting: testsub(8.130838e-320:0x4248)
 
main: ieeefval:5.000000e+01:0x42480000  fval:0.000000e+00:0x4348
 
  Initial: testsub(6.971217e-316:0x43480000)
   =     : ieeefval:0.000000e+00:000  fval:6.971217e-316:0x43480000
  memcpy : ieeefval:0.000000e+00:000  fval:6.971217e-316:0x43480000
  Exiting: testsub(6.971217e-316:0x43480000)
 
 
---------------
Listing file
---------------
 
 
                                Source Listing                  13-APR-1999
17:08:31  DEC C V5.5-002                    Page 1
                                                                13-APR-1999
16:21:08  [000000.APITEST]TEST5.C;7
 
	      1 #include <stdio.h>
	    673 #include <stdlib.h>
	   1581 #include <cvtdef.h>
	   1646 #include <cvt$routines.h>
	   1712
	   1713 int testsub(float);
	   1714
	   1715 main()
	   1716 {
	   1717 int st,err;
	   1718 float fval=50.0;
	   1719 float ieeefval=50.0;
	   1720
	   1721
	   1722 printf("main: Initial (%e:%#x)\n\n", fval, *((int*)&fval));
	   1723
	   1724 err = testsub((float)fval);
	   1725
	   1726
	   1727 st=CVT$CONVERT_FLOAT(&ieeefval, CVT$K_IEEE_S, &fval,
CVT$K_VAX_F, CVT$M_VAX_ROUNDING);
	   1728 printf("main: ieeefval:%e:%#x  fval:%e:%#x\n\n",
(double)ieeefval, *((int*)&ieeefval), (double)fval, *((int*)&fval))
	   1728 ;
	   1729
	   1730 err = testsub((float)fval);
	   1731
	   1732 }
 
 
Command Line
------- ----
 
CC
TEST5.C/LIST/NOOPT/DEBUG=(ALL)/FLOAT=IEEE/IEEE_MODE=DENORM_RES/ANSI/EXTER=ST
RICT
 
 
These macros are in effect at the start of the compilation.
----- ------ --- -- ------ -- --- ----- -- --- ------------
 
 __VMS_VERSION="V6.2    "  __DECC_MODE_RELAXED=1  __vms_version="V6.2    "
 VMS_VERSION="V6.2    "  __ALPHA=1  _IEEE_FP=1  __Alpha_AXP=1  vms=1
 __D_FLOAT=0  __DECC=1  __alpha=1  __32BITS=1  __X_FLOAT=1  VMS=1
 vms_version="V6.2    "  __IEEE_FLOAT=1  __vms=1  __G_FLOAT=0  CC$gfloat=0
 __BIASED_FLT_ROUNDS=2  __DECC_VER=50590002  __INITIAL_POINTER_SIZE=0
 __VMS=1  __VMS_VER=60200022  __PRAGMA_ENVIRONMENT=1
 
 
                                Source Listing                  13-APR-1999
17:08:17  DEC C V5.5-002                    Page 1
                                                                13-APR-1999
16:19:40  [000000.APITEST]TESTSUB.C;7
 
	      1 #include <stdio.h>
	    673 #include <stdlib.h>
	   1581 #include <string.h>
	   1982 #include <cvtdef.h>
	   2047 #include <cvt$routines.h>
	   2113
	   2114 int testsub(float value)
	   2115 {
	   2116     float ieeefval=0.0;
	   2117     float fval=0.0;
	   2118     int st=0;
	   2119
	   2120     printf("  Initial: testsub(%e:%#x)\n", value,
*((int*)&value));
	   2121
	   2122     fval=value;
	   2123     st=CVT$CONVERT_FLOAT(&fval, CVT$K_VAX_F, &ieeefval,
CVT$K_IEEE_S, CVT$M_ROUND_TO_NEAREST);
	   2124     printf("   =     : ieeefval:%e:%#x  fval:%e:%#x\n",
(double)ieeefval, *((int*)&ieeefval), (double)fval, *((int*)
	   2124 &fval));
	   2125
	   2126     memcpy((void*)&fval, (void*)&value, sizeof(float));
	   2127     st=CVT$CONVERT_FLOAT(&fval, CVT$K_VAX_F, &ieeefval,
CVT$K_IEEE_S, CVT$M_ROUND_TO_NEAREST);
	   2128     printf("  memcpy : ieeefval:%e:%#x  fval:%e:%#x\n",
(double)ieeefval, *((int*)&ieeefval), (double)fval, *((int*)
	   2128 &fval));
	   2129
	   2130     printf("  Exiting: testsub(%e:%#x)\n\n", value,
*((int*)&value));
	   2131
	   2132     return 0;
	   2133 }
 
 
Command Line
------- ----
 
CC TESTSUB.C/DEBUG=ALL/NOOPT/LIST/FLOAT=G_FLOAT/ANSI/EXTERN=STRICT
 
 
These macros are in effect at the start of the compilation.
----- ------ --- -- ------ -- --- ----- -- --- ------------
 
 __VMS_VERSION="V6.2    "  __DECC_MODE_RELAXED=1  __vms_version="V6.2    "
 VMS_VERSION="V6.2    "  __ALPHA=1  __Alpha_AXP=1  vms=1  __D_FLOAT=0
 __DECC=1  __alpha=1  __32BITS=1  __X_FLOAT=1  VMS=1  vms_version="V6.2    "
 
 __IEEE_FLOAT=0  __vms=1  __G_FLOAT=1  CC$gfloat=1  __BIASED_FLT_ROUNDS=2
 __DECC_VER=50590002  __INITIAL_POINTER_SIZE=0  __VMS=1  __VMS_VER=60200022
 __PRAGMA_ENVIRONMENT=1
 
 
 
------ end output ------
 
 
I also experimented with following options
 
/ansi vs /standard=vaxc
/prefix=all vs /noprefix
/float=g_float vs none
 
 
I don't know if I'm going overboard but I just linked it with full options.
I'm sending that output too.
 
 
 
Thanks
 
 
--------------- LINK OUTPUT ---------
                                                                13-APR-1999
17:59        Linker A11-20                    Page    1
 
                                             +------------------------+
                                             ! Object Module Synopsis !
                                             +------------------------+
 
Module Name     Ident              Bytes      File
Creation Date      Creator
-----------     -----              -----      -----
-------------      -------
TEST5           V1.0                  750 TEST5.OBJ;12
13-APR-1999 17:08  DEC C V5.5-002
TESTSUB         V1.0                  617 TESTSUB.OBJ;12
13-APR-1999 17:08  DEC C V5.5-002
LIBRTL          X01-001                 0 SYS$COMMON:[SYSLIB]LIBRTL.EXE;1
4-MAY-1995 22:30  Linker A11-12
DECC$SHR        T06.2-05                0 SYS$COMMON:[SYSLIB]DECC$SHR.EXE;1
4-MAY-1995 22:33  Linker A11-12
SYS$PUBLIC_VECTORS
                X-33                    0 [SYSLIB]SYS$PUBLIC_VECTORS.EXE;1
4-MAY-1995 22:29  Linker A11-12
 
 
USERDISK2:[000000.APITEST]TEST5.EXE;9           13-APR-1999 17:59
Linker A11-20                    Page    2
 
                                             +------------------------+
                                             ! Image Section Synopsis !
                                             +------------------------+
 
   Cluster      Type Pglts   Base Addr  Disk VBN PFC Protection and Paging
Global Sec. Name   Match     Majorid   Minorid
   -------      ---- -----   ---------  -------- --- ---------------------
----------------   -----     -------   -------
 
DEFAULT_CLUSTER    0     1    00010000          3   0 READ WRITE
NON-SHAREABLE ADDRESS DATA
                   0     2    00020000          4   0 READ ONLY
EXECUTABLE
                   0     1    00030000          6   0 READ WRITE   FIXUP
VECTORS
                 253    20    7FFF0000          0   0 READ WRITE   DEMAND
ZERO
 
LIBRTL             3  1136    00000000-R        0   0 READ ONLY
EXECUTABLE    LIBRTL_001       LESS/EQUAL        1         1
                   2   100    00090000-R        0   0 READ WRITE   COPY ON
REF   LIBRTL_002       LESS/EQUAL        1         1
                   2     8    000A0000-R        0   0 READ WRITE   COPY ON
REF   LIBRTL_003       LESS/EQUAL        1         1
                   3    94    000B0000-R        0   0 READ ONLY
LIBRTL_004       LESS/EQUAL        1         1
                   4     1  P-000C0000-R        0   0 READ WRITE   COPY ON
REF   LIBRTL_005       LESS/EQUAL        1         1
                   2     8    000D0000-R        0   0 READ WRITE   DEMAND
ZERO   LIBRTL_006       LESS/EQUAL        1         1
                   2    11    000E0000-R        0   0 READ WRITE   FIXUP
VECTORS LIBRTL_007       LESS/EQUAL        1         1
 
DECC$SHR           3  2281    00000000-R        0   0 READ ONLY
EXECUTABLE    DECC$SHR_001     LESS/EQUAL        1         1
                   2   216    00120000-R        0   0 READ WRITE   COPY ON
REF   DECC$SHR_002     LESS/EQUAL        1         1
                   2    77    00140000-R        0   0 READ WRITE   COPY ON
REF   DECC$SHR_003     LESS/EQUAL        1         1
                   3    39    00150000-R        0   0 READ ONLY
DECC$SHR_004     LESS/EQUAL        1         1
                   4     1  P-00160000-R        0   0 READ WRITE   COPY ON
REF   DECC$SHR_005     LESS/EQUAL        1         1
                   2    35    00170000-R        0   0 READ WRITE   DEMAND
ZERO   DECC$SHR_006     LESS/EQUAL        1         1
                   2    14    00180000-R        0   0 READ WRITE   FIXUP
VECTORS DECC$SHR_007     LESS/EQUAL        1         1
 
SYS$PUBLIC_VECTORS
                   2    11    00000000-R        0   0 READ ONLY
EXECUTABLE    SYS$PUBLIC_VECTO EQUAL           125  16186164
                   1    33    00004000-R        0   0 READ WRITE   COPY ON
REF   SYS$PUBLIC_VECTO EQUAL           125  16186164
                   2     1    0000C000-R        0   0 READ WRITE   FIXUP
VECTORS SYS$PUBLIC_VECTO EQUAL           125  16186164
 
 
 
	  Key for special characters above:
		+--------------------+
		! R  - Relocatable   !
		! P  - Protected     !
		+--------------------+
 
 
USERDISK2:[000000.APITEST]TEST5.EXE;9           13-APR-1999 17:59
Linker A11-20                    Page    3
 
                                            +--------------------------+
                                            ! Program Section Synopsis !
                                            +--------------------------+
 
Psect Name      Module Name       Base     End           Length
Align                 Attributes
----------      -----------       ----     ---           ------
-----                 ----------
 
$LINK$                          00010000 0001010F 00000110 (        272.)
OCTA  4 NOPIC,CON,REL,LCL,NOSHR,NOEXE,NOWRT,NOVEC,  MOD
                TEST5           00010000 000100BF 000000C0 (        192.)
OCTA  4
                TESTSUB         000100C0 0001010F 00000050 (         80.)
OCTA  4
 
$LITERAL$                       00010110 000101FC 000000ED (        237.)
OCTA  4   PIC,CON,REL,LCL,  SHR,NOEXE,NOWRT,NOVEC,  MOD
                TEST5           00010110 00010151 00000042 (         66.)
OCTA  4
                TESTSUB         00010160 000101FC 0000009D (        157.)
OCTA  4
 
$CODE$                          00020000 0002036B 0000036C (        876.)
OCTA  4   PIC,CON,REL,LCL,  SHR,  EXE,NOWRT,NOVEC,  MOD
                TEST5           00020000 000201EB 000001EC (        492.)
OCTA  4
                TESTSUB         000201F0 0002036B 0000017C (        380.)
OCTA  4
 
$BSS$                           00030000 00030000 00000000 (          0.)
OCTA  4 NOPIC,CON,REL,LCL,NOSHR,NOEXE,  WRT,NOVEC,NOMOD
                TEST5           00030000 00030000 00000000 (          0.)
OCTA  4
                TESTSUB         00030000 00030000 00000000 (          0.)
OCTA  4
 
$DATA$                          00030000 00030000 00000000 (          0.)
OCTA  4 NOPIC,CON,REL,LCL,NOSHR,NOEXE,  WRT,NOVEC,NOMOD
                TEST5           00030000 00030000 00000000 (          0.)
OCTA  4
                TESTSUB         00030000 00030000 00000000 (          0.)
OCTA  4
 
$READONLY$                      00030000 00030000 00000000 (          0.)
OCTA  4   PIC,CON,REL,LCL,  SHR,NOEXE,NOWRT,NOVEC,NOMOD
                TEST5           00030000 00030000 00000000 (          0.)
OCTA  4
                TESTSUB         00030000 00030000 00000000 (          0.)
OCTA  4
 
$READONLY_ADDR$                 00030000 00030000 00000000 (          0.)
OCTA  4   PIC,CON,REL,LCL,NOSHR,NOEXE,NOWRT,NOVEC,NOMOD
                TEST5           00030000 00030000 00000000 (          0.)
OCTA  4
                TESTSUB         00030000 00030000 00000000 (          0.)
OCTA  4
 
 
USERDISK2:[000000.APITEST]TEST5.EXE;9           13-APR-1999 17:59
Linker A11-20                    Page    4
 
                                             +------------------------+
                                             ! Symbol Cross Reference !
                                             +------------------------+
 
Symbol              Value           Defined By              Referenced By
...
------              -----           ----------
-----------------
CVT$CONVERT_FLOAT   00001380-RX       LIBRTL                   TEST5
TESTSUB
DECC$$SHELL_HANDLER 00003A20-RX       DECC$SHR                 TEST5
 
DECC$EXIT           00002000-RX       DECC$SHR                 TEST5
 
DECC$GXPRINTF       000046E0-RX       DECC$SHR                 TESTSUB
 
DECC$MAIN           000007B0-RX       DECC$SHR                 TEST5
 
DECC$TXPRINTF       00004960-RX       DECC$SHR                 TEST5
 
MAIN                00010000-R        TEST5
SYS$IMGSTA          00000340-RX       SYS$PUBLIC_VECTORS
TESTSUB             000100C0-R        TESTSUB                  TEST5
 
__MAIN              00010070-R        TEST5
 
 
USERDISK2:[000000.APITEST]TEST5.EXE;9           13-APR-1999 17:59
Linker A11-20                    Page    5
 
                                                +------------------+
                                                ! Symbols By Value !
                                                +------------------+
 
Value                                   Symbols...
-----                                   ----------
00000340     RX-SYS$IMGSTA
000007B0     RX-DECC$MAIN
00001380     RX-CVT$CONVERT_FLOAT
00002000     RX-DECC$EXIT
00003A20     RX-DECC$$SHELL_HANDLER
000046E0     RX-DECC$GXPRINTF
00004960     RX-DECC$TXPRINTF
00010000      R-MAIN
00010070      R-__MAIN
000100C0      R-TESTSUB
 
 
 
	  Key for special characters above:
		+--------------------+
		! *  - Undefined     !
		! A  - Alias Name    !
		! I  - Internal Name !
		! U  - Universal     !
		! R  - Relocatable   !
		! X  - External      !
		! WK - Weak          !
		+--------------------+
 
 
USERDISK2:[000000.APITEST]TEST5.EXE;9           13-APR-1999 17:59
Linker A11-20                    Page    6
 
                                                 +----------------+
                                                 ! Image Synopsis !
                                                 +----------------+
 
Virtual memory allocated:                         00010000 0003FFFF 00030000
(196608. bytes, 384. pages)
Stack size:                                             20. pages
Image header virtual block limits:                       1.        2. (
2. blocks)
Image binary virtual block limits:                       3.        6. (
4. blocks)
Image name and identification:                    TEST5 V1.0
Number of files:                                         7.
Number of modules:                                       5.
Number of program sections:                             11.
Number of global symbols:                             1767.
Number of cross references:                             18.
Number of image sections:                               21.
User transfer address:                            00010070
Debugger transfer address:                        00000340
Number of code references to shareable images:           7.
Image type:                                       EXECUTABLE.
Map format:                                       FULL WITH CROSS REFERENCE
in file USERDISK2:[000000.APITEST]TEST5.
Estimated map length:                             250. blocks
                                              +---------------------+
                                              ! Link Run Statistics !
                                              +---------------------+
 
Performance Indicators                            Page Faults	CPU Time
Elapsed Time
----------------------                            -----------	--------
------------
    Command processing:                                    23	00:00:00.00
00:00:00.09
    Pass 1:                                               115	00:00:00.17
00:00:00.28
    Allocation/Relocation:                                  8	00:00:00.02
00:00:00.08
    Pass 2:                                                10	00:00:00.05
00:00:00.16
    Map data after object module synopsis:                  3	00:00:00.01
00:00:00.01
    Symbol table output:                                    0	00:00:00.00
00:00:00.04
Total run values:                                         159	00:00:00.25
00:00:00.69
 
Using a working set limited to 6496 pages and 2703 pages of data storage
(excluding image)
 
Total number object records read (both passes):   341
    of which 0 were in libraries and 31 were DEBUG data records containing
2685 bytes
1977 bytes of DEBUG data were written,starting at VBN 7 with 4 blocks
allocated
 
Number of modules extracted explicitly             = 0
    with 0 extracted to resolve undefined symbols
 
1 library searches were for symbols not in the library searched
 
A total of 5 global symbol table records was written
 
LINK/ALPHA/DEBUG/MAP/CROSS/FULL TEST5.OBJ,TESTSUB.OBJ
--------------
 
 


The Answer is :

 
  This problem exists because you are lying to the compiler.  The
  subprogram declares its parameter to be of VAX-floating type, yet the
  main program is passing it as IEEE-floating.  This is no different
  than passing a floating point number to a routine that expects an
  integer -- it does not work.  The C language definition is clear about
  this -- if the type of the argument passed to a routine does not
  match the type the routine expects, the behavior is undefined.
 
  With that said, the OpenVMS Wizard will try to provide a additional
  information about what is going on, and will try to provide ways to
  get the desired result.
 
  When stored in memory, VAX floating and IEEE floating have very
  different formats (the words are swapped).
 
  When a VAX floating point number is loaded into a register on an
  Alpha, the words are swapped (and when stored back to memory, the
  words are again swapped).
 
  In testsub, the variable value is passed in a register.  Because
  the code performs the Alpha STF instruction to store the value to
  the variable fval, the words are swapped as you have told the compiler
  that the value uses VAX floating point.
 
  There are several ways to make this work.  One way would be to pass
  the argument in memory instead of a register.  You could do this
  by passing six dummy argument first -- per the OpenVMS Alpha callling
  standard, the first six arguments are passed via registers.  Another
  way would be to swap the words yourself after the store to fval.  Yet
  another would be in insert an asm that would store the item to memory
  using an IEEE instruction so that no word swap would take place.
  For example including the header file <c_asm.h>, and then replacing
  fval = value with fasm("STS  %f17,0(%r16)", &fval, value) should do
  the trick.
 
  To summarize, great care must be taken if you wish to pass one floating
  type to a routine that expects another.  One has to understand the
  internal representations of the floating point numbers (in both register
  and memory formats) in order to get this to work as desired.
 

answer written or last revised on ( 15-APR-1999 )

» close window