![]() |
![]() HP OpenVMS Systemsask the wizard |
![]() |
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.
|