Programs for Programmers

FTN95: Fortran95 for Windows

With Silverfrost FTN95: Fortran for Windows you can create console based, conventional Windows® and Microsoft .NET applications. Silverfrost FTN95 is the only compiler that can produce Microsoft .NET applications that can use the full Fortran 95 language. Silverfrost FTN95 also boasts its world leading CHECKMATE run-time checking technology that finds bugs fast!

 

Silverfrost FTN95 is a full Fortran 95 standards compliant compiler, capable of producing fast executables for Win32, Win64, and for Microsoft .NET. FTN95 ships with the world's best runtime checking and a great range of supporting software. All standard and many vendor-specific legacy language features are supported, so that Fortran projects may be any combination of Fortran 77, Fortran 90 and Fortran 95.

General Features

  • Full Fortran 95 language compatibility
  • Comprehensive integration with Microsoft Visual Studio .NET
  • Standalone editor - Plato3
  • The world's best runtime checking
  • Very fast compilation speed
  • Excellent compile-time diagnostics
  • Full souce level debugging
  • Builds console, Windows® and Microsoft .NET 1.1 and 2.0 applications

Windows® Specific Features

  • Visual Studio .NET integrated debugger
  • Binary compatibility with FTN77 object and library code
  • Complete I/O library compatibility with FTN77
  • Inline Mnemonic Assembler using CODE...EDOC
  • Microsoft Visual C++ Interoperability
  • Salford C/C++ Interoperability
  • GUI building with Salford Clearwin+
  • Full support for REAL*10, COMPLEX*20
  • Virtual Common
  • Small EXE and OBJ files

Microsoft .NET Specific Features

  • Full Fortran .NET debugging facilities
  • Effortless porting of existing Fortran code to .NET
  • No language restrictions
  • Use Salford CHECKMATE technology within .NET programs
  • Fast runtime performance
  • Simple inter-language operability
  • Recompile existing code and use it immediately with .NET
  • No steep .NET learning curve to be negotiated
  • Easily attach a .NET Windows Forms front end to a Fortran backend
  • Create and manipulate .NET objects within Fortran
  • See example .NET code and documentation
 

V8.05

New Features:

  • FTN95 provides some Fortran 2003/2008 features that required the command line option /F2K. These features are now provided by default. In order to restrict the code to Fortran 95 use /-F2K.
  • CODE/EDOC is now available in 64-bit mode
  • The following Fortran 2008 standard intrinsics are now available: ERF,ERFC,ERFC_SCALED,GAMMA,LOG_GAMMA,BESSEL_J0,BESSEL_J1,BESSEL_Y0,BESSEL_Y1,BESSEL_JN,BESSEL_YN. See for example http://fortranwiki.org/fortran/show/bessel_j0.
  • _WIN32 and _WIN64 are prefined for use in conditional compilation CIF. For example, the CIF(_WIN64) block of code will be compiled when the options /64 /fpp are applied on the FTN95 command line. This is particularly useful for CODE/EDOC blocks that require conditional compilation when implemented for both 32 and 64 bit code. In other contexts, an equivalent run-time condition is "IF(KIND(1_7) == 4)THEN".
  • The following undocumented Win32 routines have now been ported to 64 bits: FPOSLONG@, RFPOSLONG@ and FPOS_EOFLONG@. These are similar to FPOS@, RFPOS@ and FPOS_EOF@ but take INTEGER*8 position arguments. Note that other arguments are still INTEGER*2.
  • ClearWin+ can now be used to generate SVG files by calling OPEN_SVG@ before drawing the graphics (this is analogous to generating printer output). SVG is a vector graphics format.
Outline summary of bugs that have been fixed:
  • Compile time array bounds check failure has been elevated from WARNING to ERROR when using /CHECK or /BOUNDS_CHECK
  • The SUM intrinsic with a scalar MASK was giving incorrect results
  • The UBOUND intrinsic, when used as an array index was being treated as a vector subscript
  • A substring of an element of a character array was causing a backend failure. (64-bit only)
  • A regression caused the compiler to crash when raising a complex value to the power 0.5. This has been fixed
  • GET_DIB_SIZE@ when used with USE_GDIPLUS_IMAGE_FILES@ was giving a SUCCESS report when attempting to access a non-existent file.
  • Error number 612 was being appied out of context
  • INTENT(OUT) arguments with TYPE initialisation were causing runtime failures when OPTIONAL and not present
  • The WHERE construct was sometimes failing when the body contained an assignment to a temporary array
  • A GO TO statement within an IF construct was giving incorrect results with /OPT
  • A local COMMON block that duplicates a USEd MODULE COMMON block now produces a compile time error report
  • NAMELIST was failing when used in an internal (CONTAINS) subprogram
  • In a certain context a USEd MODULE user TYPE was falsely reported as not being defined
  • A stack leak was causing WRITE statements involving multiple calls to TRIM to fail with /FULL_UNDEF
  • Personal Edition did not allow /64 compile time switch
  • ClearWin+: %ac[Shift+Tab] was not responding as expected.
  • ClearWin+: A standard callback SETF has been added. This is equivalent to the standard callback SET but takes double precision values
  • ClearWin+: The property sheet control %ps was not working correctly when [hot_track] or [ms_style] was used together with a callback function
  • ClearWin+: %ss and browse_for_folder@ were not working for 64-bit applications.

V8.00

New Features:

  • FTN95 can now generate 64 bit executables and DLLs. For details see the 64 bit release notes.
  • The display resulting from the FTN95 command line option /CONFIG has been simplified and now only edits the global FTN95 configuration file. Use a new option /CFG to edit the local FTN95 configuration file
  • ClearWin+: A new function called GlobalMemoryStatus@ has been added to the library. This provides easy access to the Windows API function GlobalMemoryStatusEx.
  • ClearWin+ now makes use of the "DPI awareness" features first available with Windows 8.1. This means that, where possible, ClearWin+ will take advantage of the Windows API features designed to handle high DPI display settings which otherwise can lead to clipped text and blurry images.

 

Version 7.20

New Features:

  • A new KIND value has been introduced for integers. INTEGER(KIND=7) has the size of an address which depends on the type of the executable (32 bit or 64 bit). The same kind value is to be used when /ALT_KINDS is applied
  • ClearWin+: GET_DIB_SIZE@, GET_DIB_BLOCK@ and IMPORT_IMAGE@ have been extended in order to provide access to a wider range of image files via the Microsoft GDI+ library.
  • ClearWin+: A tilde modifier (~) can now be used with %wp with the result that plain text placed on top of the wallpaper will be transparent. In other words the text will have the wallpaper as background.
  • ClearWin+: The previously undocumented function browse_for_folder1@ can be used to open a dialog box with the option to create a new folder.

Outline summary of bugs that have been fixed:

  • FTN95 was calling the wrong library function when the standard intrinsic EXP was used with an extended precision (KIND=3) argument.
  • The PACK and UNPACK standard intrinsics where not working correctly for INTEGER types other than the default.
  • MAXLOC and MINLOC with DIM arguments were not working correctly in a number of contexts.
  • The resource compiler SRC was not handling the VERSION_INFO resource correctly.
  • INTENT(OUT) arguments with TYPE initialisation were not being reset on entry.
  • FTN95 was not reporting an error when the subscript of a subscript-triple was an array.
  • FTN95 was treating an assumed shape INTENT(INOUT) array as INTENT(IN) in certain contexts.
  • FTN95 with /CHECK was not reporting a run time error when assigning a value to a dummy argument where the actual argument was a simple parenthesis e.g. call zzz((A)).
  • An ENTRY routine with no arguments and defined within a MODULE SUBROUTINE was not accessible.
  • /NO_TRUNCATE was giving a false error report for comments beginning with ! or &.
  • A FORMAT statement at the beginning of subroutine with local (CONTAINS) subprograms was falsely reported as missing.
  • An error condition was not being reported when an expression was used as the value of an INTENT(OUT) argument.
  • OPTIONS(NOOPTIMISE) was behaving like OPTIONS(OPTIMISE) whilst OPTIONS(OPTIMISE) with /UNDEF was causing an internal compiler failure.
  • Empty character format and list directed write statement output a line with a single space rather than an empty line.
  • The REC specifier was allowed for READ and WRITE statements on a unit opened for sequential access.
  • Writes starting with '1' on units opened with FORM='PRINTER' didn't output a form feed.
  • A certain PARAMETER initialisation was failing with /ALT_KINDS.
  • A star-sized array argument in an internal function was giving a false run-time bounds check error.
  • The SHAPE intrinsic is now available within a PARAMETER initialisation.
  • Arrays declared with the PARAMETER attribute where not protected from run-time changes.
  • ClearWin+: %ac[Shift+Ins] was over-riding the typing of an underscore character in an edit box. This has been fixed.
  • ClearWin+: %dr (dropped files) has been tidied up so that the clearwin_string@ data is correctly reset and a crash is avoided.
  • ClearWin+: Various reported problems when using UTF8 characters have been resolved.
  • ClearWin+: Previously undocumented functions set_integer_limits@ and set_float_limits@ have been improved. These routines correspond to %il and %fl respectively and allow changes to be made at run time.
  • ClearWin+: The routine set_control_back_colour@ was not working for combinations like %dd%rd. This has been fixed.

Version 7.10

New Features:

  • Microsoft Visual Studio 2013 plugin
  • Anti-aliasing and opacity effects can now be included in ClearWin+ %gr line drawing (see ClearWin+ enhancements file for details).
  • A new web browser control %wb has been added to ClearWin+, providing full access to the Internet Explorer engine.
  • The IMPORT statement has been added as part of the Fortran 2003 standard.
  • ClearWin+: %ob now takes the options [rounded] and [thin_margin]
  • ClearWin+: clearwin_info@("TOOLTIP_HWND") now returns the HWND for Microsoft style tooltips (but not infotips)
  • ClearWin+: An new subroutine CLEARWIN_OPTION@ has been added in order to gather together various ClearWin+ options into one routine.
  • ClearWin+: %ch can now take the options [vscrollbar] and/or [hscrollbar] in order to display a scrolling window containing controls.
  • ClearWin+: A new format code %id has been added in order to specify the button number (ID) of the next %bt, %tt or %bb button.

Outline summary of bugs that have been fixed:

  • The /ISO command line option previously did not generate an error report when a TYPE or PARAMETER within an INTERFACE was inherited from the host.
  • Using /UNDEF with certain CHARACTER variable members of a user TYPE was causing an access violation.
  • The intrinsic function ISHFT was producing incorrect results for INTEGER*2 arguments.
  • Some duplicated double precision value arguments where not being passed correctly.
  • ALLOCATE was using the wrong address for the STAT variable when it was presented as an array element.
  • UBOUND was giving an incorrect result for zero-sized array sections.
  • /CHECK was giving a false run time error when a module function was passed as an argument.
  • TYPE initialisation in certain multiple MODULEs caused the compiler to crash.
  • A SEQUENCEd TYPE was giving a type mis-match error in a user ASSIGNMENT procedure.
  • Win32 MOD intrinsic was failing when the first argument was LOC(a).
  • /DUMP when used with /NO_OFFSETS was not dumping the variables in the best place.
  • /CHECK was giving a false run time error for functions returning an array.
  • An incomplete TYPE definition was not being reported as an error until it was used.
  • /CHECK was giving a false run time error for array arguments with the TARGET attribute.
  • INTENT(OUT) was not working correctly for array arguments with default TYPE initialisation.
  • "USE mod ONLY: aa=>bb" was giving incorrect results when aa was also declared in mod.
  • ClearWin+: %th[ms_style] did not allow multiline tooltips. This has been fixed.
  • ClearWin+: A certain user callback associated with %ls was found to raise an underflow exception under Windows 7. This has been fixed.

Version 7.00

New Features:

  • ClearWin+ is now available in the form of a 64 bit DLL called clearwin64.dll for use with third party 64 bit compilers. Routines in this library that previously ended with the @ symbol now end with $. In order to allow parallel development, FTN95 has been extended so that routines such as winio@ can now end in $ as an alternative to @. Also new standard modules are provided so that all ClearWin+ library routines for FTN95 can take this alternative form. For further information, search for "64 bit" in ftn95.chm.
  • ClearWin+ now accepts UTF-8 encoded character strings.
  • EXPORT_IMAGE@ and IMPORT_IMAGE@ now accept .PNG files and resources.
  • Four new library routines (START_THREAD@, WAIT_FOR_THREAD@, LOCK@ and UNLOCK@) have been added in order to initiate and manage Win32 threads.
  • The default ClearWin+ colour mode has been changed from "VGA colours" to "RGB colours".
  • ClearWin+: A new format code %em has been introduced to allow you to put icons in the left hand column of menus.
  • ClearWin+: A new format code %nw has been introduced. %nw takes one argument and this is the handle (%hw) of a window that has already been created
  • %ac[Ctrl+1] etc. added to list of accelerator keys allowed
  • The options [colour=] and [color=] have been added to %gr.
  • %th[balloon] now provides a tooltip in the form of a balloon.
  • %rd now takes the option [radix=n] where n is an integer in the range 2 to 36.
  • %ob now takes the option [rounded] to provide rounded corners
  • clearwin_info@("TOOLTIP_HWND") now returns the HWND for Microsoft style tooltips
  • Visual Studio 2012 plugin

Outline summary of bugs that have been fixed:

  • Local use of a name that duplicates the name of an intrinsic (e.g. SUM) was confusing the compiler.
  • FTN95 was allowing the intrinsic function TRIM to be elemental.
  • Regression at FTN95 version 6.0: SIZE(x, dim) was failing for assumed-size arrays.
  • FORALL is now allowed to use the same index as an outer DO contsruct.
  • /CHECK was giving an access violation at runtime when the FORALL index was passed to it as an argument.
  • An exclamation mark in column 73 was giving a false line truncation warning.
  • A false runtimne error was being issued when using /FULL_UNDEF for a certain generic routine.
  • MAXVAL,MINVAL,MAXLOC and MINLOC intrinsics did not report a compilation error when used with assumed-size arrays.
  • USE ONLY was not hiding a MODULE subroutine.
  • DRAW_FILLED_POLYGON@ was failing when used repeatedly with a very large number of different colours.
  • ClearWin+: %th[ms_style] did not allow multiline tooltips.

 

Out-of-the-box FTN95 provides lots of development options.  Here is a list of straight-forward questions and answers:

Do I need to buy Visual Studio to use FTN95? No
Do I need to know about Microsoft .NET to use FTN95? No
Does FTN95 support .NET 2.0 and Visual Studio 2005? Yes
I have my own editor and just want to use FTN95 from a command-line...can I do that? Yes
Can I use the personal edition to evaluate FTN95 for the company I work for? Yes

 64-bit release notes:

 

Introduction

FTN95 creates 64 bit executables and DLLs when:

a) the option /64 is used on the FTN95 command line,
b) SLINK64 is used in place of SLINK
c) salflibc64.dll and clearwin64.dll are used in place of salflibc.dll.

FTN95

This initial 64 bit full release does not allow you to combine /64 with /optimise nor /check (nor options that imply /check). It includes a beta version of the 64 bit debugger called SDBG64 that can be used together with /debug etc. on the FTN95 command line. Developers can still use /check etc. without /64 in order to test for run-time faults during development.

Extended precision (REAL*10) is not available when creating 64 bit applications.

SLINK64

SLINK64 can be used in:

a) command line mode
b) interactive mode or
c) script file mode

Here is an example of using command line mode...

   FTN95 prog.f95 /64
   FTN95 sub.f95  /64
   SLINK64 prog.obj sub.obj /file:prog.exe

Here is an example of using interactive mode...

   SLINK64
   $ lo prog.obj
   $ lo sub.obj
   $ file prog.exe

Here is an example of using a script file...

   SLINK64 @prog.inf

where prog.inf contains...

   lo prog.obj
   lo sub.obj
   file prog.exe

For further information see below or type...

SLINK64 /help

SLINK64 automatically scans commonly used Windows DLLs. If a Windows function located in (say) xxx.dll is reported as missing then the DLL should be loaded by using a script command of the form

   lo C:\Windows\Sysnative\xxx.dll
where C:\Windows illustrates the value of the %windir% environment variable.

Note that the initial release of SLINK64 can construct executables and DLLs but not static libraries.

SDBG64

The 64 bit debugger is provided as a beta release for users to test. It operates in essentially the same way as the corresponding 32 bit debugger.

ClearWin+

64 bit ClearWin+ was previously available for use with third party compilers via clearwin64.dll. This DLL has now been extended for use with 64 bit FTN95. Users who have already adapted their code for use with third-party compilers can continue to use their modified code. Alternatively native FTN95/ClearWin+ code can be used without change apart from the following exceptions:

  • 64 bit Microsoft Windows HANDLEs are addresses (64 bit integers). So if a Windows handle is used explicitly in Fortran code, it will currently appear as a 32 (KIND=3) integer and must become a 64 bit (KIND=4) integer for 64 bit applications. FTN95 has a special KIND value (7) that is interpreted as KIND=3 for 32 bit applications and KIND=4 for 64 bit applications. Alternatively INTEGER(KIND=CW_HANDLE) can be used together with standard INCLUDE and MOD files because CW_HANDLE is defined as a parameter with value 7. Windows HANDLEs are mainly used with %lc, %hw and some direct calls to the Windows API.
  • The function CLEARWIN_INFO@ now returns an INTEGER(KIND=7) value.
  • 64 bit ClearWin+ does not currently support SIMPLEPLOT (%pl). Also a few very old graphics routines have not been ported to 64 bit ClearWin+.
  • The function cpu_clock@ is not available for 64 bit applications and has been replaced by rdtsc_val@...INTEGER(KIND=4) FUNCTION RDTSC_VAL@()

SRC

Use the command line option /r for 64 bit applications and link the resulting .res file (together with the .obj files) via SLINK64.

Current experience suggests that using the "default.manifest" in a resource script causes the resulting 64 bit application to fail to load. However, a user supplied manifest file can improve the appearance. The text of a suitable manifest file is presented below.

RESOURCES

A RESOURCES directive can be used at the end of a 64 bit Fortran main program but it only has effect when used with FTN95 command line options /LINK or /LGO. Otherwise a separate call to SRC is required. (For Win32 main programs, FTN95 automatically adds the resources to the main object file).

Silverfrost INCLUDE and MOD files

Silverfrost INCLUDE files have been modified so that Microsoft HANDLEs have type INTEGER(KIND=7).

Silverfrost MOD files can be used without change provided they are updated to those in this release.

Note that user FTN95 MOD files for 64 bit applications may differ from those for 32 bit applications. So FTN95 uses the extension .mod64 for 64 bit MOD files whilst retaining teh extension .mod for 32 bit MOD files. The corresponding object files always differ and the respective linker (SLINK or SLINK64) will reject object files of the wrong kind.

By default FTN95 uses the extension .obj for both 64 bit and 32 bit object files. For projects, both Plato and Visual Studio retain the default extension and use a system of sub-folders in order to create executables for different platforms (such as Win32, x64 and .NET) and for differenct configurations (such as Debug, CheckMate and Release).

Users who prefer to build their applications using batch and/or makefiles can adopt a similar sub-folder approach to that used by Plato and Visual Studio. Alternatively, 64 bit object files can be given a different extension (e.g. .o64) by using /BINARY (together with the object file name) on the FTN95 command line. In that way, 64 bit and 32 bit object files could reside in the same folder.

Plato

The associated release of Plato is configured by default to use FTN95 when you select "Release x64" on the main toolbar. Previously this used gFortran. The default can be changed from the Options dialog.

Plato can launch the 64 bit debugger as an external application.

Redistributing

Like salflibc.dll, salflibc64.dll and clearwin64.dll can be freely redistributed with your applications and DLLs.

Additional notes on porting from 32 bit to 64 bit applications

1) When using the standard Fortran SIZE intrinsic, FTN95 with /64 returns a 64 bit integer despite the fact that this is not strictly Standard conforming. In certain very special circumstances, this change can cause existing code to fail. For example, failure will occur if SIZE(x) appears as the value of an argument to an overloaded subprogram (i.e. a subprogram that has various definitions depending on the types of its arguments). A new command line option /SIZE32 is provided in order to resolve this conflict.

2) It is possible that there may a some slight loss of precision when porting from 32 bit to 64 bit calculations. This is mainly because some FTN95 32 bit mode floating point calculations actually use hidden extended precision on the way to producing double or single precision results. It is therefore possible that the process of porting to 64 bits may expose a numerically unstable calculation (i.e. one that depends critically on the level of round-off error). In the same way, in extreme cases it is possible that new exceptions may appear at runtime due to floating point overflow. Overflow can occur directly or as the result of dividing by a value that has underflowed to zero. In some cases it is possible to resolve these issues by using a scaling factor in the calculations.

Further information about SLINK64

The SINK64 command line

SLINK64 can be used in 3 ways...

1) It can use a series of commands from a file (recommended). The commands are placed in a file with the .inf or .link suffix, and is invoked thus:

SLINK64 file.inf

2) It can be used interactively, using the same commands as in (1).

3) It can be used from the command line. This can be derived from the command specifications. Thus the command lo <obj file> can be coded on the command line as /lo <obj file>

SLINK64 commands

  • load(lo) <file> - Loads the file, which must be FTN95/SCC 64-bit object code.
  • map <file> - Requests a link map, to be placed in the specified file. If the file argument is omitted, the map is placed in a file whose name is derived from the name of the DLL or EXE file being created.
  • file <exe or dll file> - Completes the linking operation and puts the result in the given file name. Note that the choice of suffix (DLL or EXE) determines the type of file created. Currently all entry points in the code are exported in the case of a DLL.
  • windows - This command forces the creation of a WINDOWS application, which does not use a console. This is normally used in conjunction with ClearWin+ code.
  • load(lo) <file.dll> - Uses the entry points in the specified DLL to satisfy calls in the code. The DLL must be avaiable at run-time.
  • load(lo) <file.res> - Loads a resource file created with SRC using the /r switch. This is the same SRC command used in 32-bit mode except that the /r switch must be used.
  • image_base <hex address> - Specifies the base address for the link (not normally required, and can be overwritten at run time by Windows).
  • stack_size <hex number> - Specifies the stack size. The default value is 0x1000000 (16 MB).
  • alias <name> <alias> - Sets up an alias to an external name when making a DLL. Note that the names are case sensitive. This was added to enable gFortran to call a DLL built with FTN95. It circumvents the problem that gFortran uses lower case names while FTN95 uses upper case names! It may have other specialised uses.
  • help - Prints out abbreviated help information to the console.
  • quit(q) - Quits SLINK64 without saving anything.

Typical use

SLINK64 is automatically called when /link or /lgo is used on the FTN95 command line. The name of the executable or DLL can be supplied after /link (this is optional for executables but mandatory for DLLs). Also /stack can be included followed by the stack size as a number of megabytes. /map can also be used in this context.

The WINAPP directive in the Fortran code creates a Windows application and this directive can optionally be followed by the name of a resource script. Alternatively a resource script can be included by placing the script after the main program by using the RESOURCES directive.

Here are the required SLINK64 commands for three slightly more complicated scenarios:

1) To link a simple program that uses a DLL:

The file (say) ExtraDLL.dll is scanned for entry points but it isn't incorporated in MyProgram.exe - so MyProgram.exe will require the DLL somewhere on the path at runtime.

     lo MyProgram.obj
     lo ExtraDLL.dll
     file MyProgram.exe

2) To link a number of files to create a DLL that exports all subroutine/function names:

     lo file1.obj
     lo file2.obj
     lo file3.obj
     file MyLibrary.dll

3) To create a windows program with some ClearWin+ code that uses resources:

The resources are prepared by:

   
     SRC MyResources.rc /r
Then the slink commands are:

   
     lo MyProgram.obj
     lo MyResources.res
     windows
     file MyProgram.exe

Further general information about 64 bit FTN95

Programs compiled with FTN95 using the /64 option, use the AMD64 instruction set (subsequently adopted by Intel, and referred to as x64 or x86_64) which is almost universally available on modern PC's. This code cannot be mixed with legacy 32-bit code, nor can it access legacy 32-bit DLL's. 64-bit object files must be linked using the new utility SLINK64. This object file format is incompatible with all third-party link utilities.

The default size of INTEGER variables remains unchanged (231-1), so INTEGER*8 (8-byte) variables must be used to index extremely large arrays. These variables are implemented in a more efficient and natural way in 64 bits. Note that some arrays that would not fit in the old 4GB limit may still be indexable using default sized integers, for example a REAL*8 array of 2,000,000,000 elements would occupy nearly 16GB of memory, but could be indexed using default integers.

The main value of 64-bit compilation is that the available address space has increased from 4GB to approximately 1.8 x 1019 bytes! This means that for the foreseeable future (possibly forever!), the size of programs will be limited only by the amount of physical memory available on a system.

Arrays that are ALLOCATEd, or which are in COMMON or in MODULEs can exceed the 4GB limit, except that initialised arrays must fit within the .EXE or .DLL file to which they belong, and the the size of these files cannot extend beyond the 4GB limit. This is a Microsoft limit, but is fairly reasonable, since the time needed to load a 4GB file would be excessive!

COMMON blocks and MODULE arrays are allocated dynamically as a program starts in order to enjoy no 4GB restrictions. This is applied to all such storage blocks, because a program may exceed the 4GB limit even though each individual array lies within this limit.

Local arrays (static or dynamic) are restricted as in 32 bits. This is because it is not feasible to extend the hardware stack to sizes > 4GB, and SAVE'd variables must fit within the EXE or DLL file to which they belong. Users who require a very large local array, should put it in a COMMON block or MODULE referenced by only the one routine.

Since the code can be distributed across multiple DLL's plus an EXE file, the code itself is also not limited to 4GB - although this is not usually a serious concern.

The various 64-bit Windows operating systems provide less than the full 1.8 x 1019 address space, and the size of this space varies somewhat with the available physical memory on the system. Nevertheless, these limits are very generous and will increase as physical memory becomes more plentiful. In part, these limits are due to the fact that the paging mechanism itself requires memory.

For further information see https://msdn.microsoft.com/en-us/library/aa366778.aspx.

The pair of DLL's SALFLIBC64.DLL and CLEARWIN64.DLL in 64 bits take the place of the 32 bits SALFLIBC.DLL. Currently CLEARWIN64.DLL (which contains much more than ClearWin+) is compiled with Microsoft C++. In the future this may be absorbed into SALFLIBC64.DLL but will remain independent for use with third-party compilers.

Perhaps surprisingly, FTN95.exe and SLINK64.exe are 32-bit executables, and so still require access to SALFLIBC.DLL at compile time.

Note that the extra executables and DLL's to support 64-bit mode can coexist with those that support 32-bit operations because they have different names.

Contents of a clrwin.manifest file...

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="Win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0"
                        processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
    </dependentAssembly>
  </dependency>
</assembly>

64-bit CODE/EDOC in FTN95

The AMD 64-bit architecture

This architecture was invented by AMD, and was later adopted by by Intel when their own Itanium 64-bit architecture was not received with enthusiasm. Intel use the term x86-64. It is the basis of most modern PCs, and is targeted by FTN95 when the /64 switch is used.

The AMD 64-bit architecture has 16 general purpose integer registers:

RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15.

The bottom eight registers correspond to the 32-bit register set, and retain some of the same functionality. Thus RSP is the stack pointer and descends as the stack expands, RCX, RSI and RDI are used for string operations just as they are in 32-bits, and RAX is used by convention to return integer function values. RBP does not correspond in function to EBP, however it is given a special function in Silverfrost code (explained later), and should not be modified in normal circumstances.

All these registers hold 64 bits (8 bytes) and can therefore hold a pointer to anywhere in the 64-bit address space.

64-bit programs can access two sets of different floating point registers - the old floating point stack of eight 80-bit registers, and a set of registers designated XMM0 - XMM15, and known as the SSE registers. These registers can hold multiple values simultaneously - foour REAL*4 floating point values, or two REAL*8 values. They can also hold integer values. Thus these registers are 16 bytes in width. These registers do not 'know' what data they contain - so it is up to the programmer to keep track. In particular, if you load a REAL*8 value into an XMM register and wish to store it as a REAL*4, you must first use the appropriate conversion instruction.

Strangely, the old coprocessor stack instructions, do offer some functionality that is not present in the newer SSE instruction set - for example SIN and COS can be evaluated in one instruction.

Silverfrost CODE/EDOC conventions

Let us start with a simple executable example of a 64-bit CODE/EDOC sequence that simply sums a vector of REAL*8 values. It is not meant to be optimal because it does not use the parallel execution facilities of the SSE registers.

      REAL*8 vec(3),ans
      DATA vec/3.0d0,4.0d0,5.0d0/
      CALL sum(vec,3,ans)
      PRINT*,ans
      END   
      
      SUBROUTINE sum(vec,n,ans)
      INTEGER n
      REAL*8 vec,ans
      CODE
       MOV_Q     RDX,=VEC   ! The '=' denotes a (non-immediate) constant or, as in this case, the address of an argument
       MOV_Q     R14,=N     ! Remember all addresses are 64-bit - hence the use of MOV_Q
       MOVSX_Q   R14,[R14]  ! Instructions and register names are case insensitive
                            ! N is only a 32-bit integer, so it is sign extended to 64 bits
       XORPD     XMM0,XMM0  ! This is one way to zeroise an XMM register it does a bitwise exclusive OR
1      ADDSD     XMM0,[RDX]
       ADD_Q     RDX,8      ! This uses an immediate constant
       DEC_Q     R14
       JNE       $1         ! Labels are denoted by a '$'
       MOV_Q     RCX,=ans     
       MOVDQU    [RCX],XMM0 ! Store away the accumulated answer in the argument ANS
      EDOC
      END

This illustrates a variety of points

1) The instructions that operate on the integer registers can operate on 1, 2, 4, or 8 byte operands. These are distinguished by a suffix, thus the MOV instruction takes the forms MOV_B, MOV_H, MOV, MOV_Q.

2) Unlike the 32-bit code/edoc, the register name does not change when the operation operates on a smaller number of bytes.

3) Operations that work on 4 bytes of a register (MOV, ADD, etc) also clear the upper 4 bytes of the register, whereas 2-byte and 1-byte instructions do not change the other bytes of the register. This is a feature of the hardware, not a Silverfrost convention.

4) Labels are prefixed by a '$' when used, just as is the case in 32-bit mode.

5) When accessing a Fortran argument, you need to first access its address (an 8-byte quantity). The notation =N is used to access the address of argument N. The '=' notation can also be used to address a constant in memory, for example:

	   
                     MOVSD    XMM3,=2.0d0
6) The MOVSX_Q instruction sign extends a 32-bit integer to 64-bits. In situations where a number is known to be non-negative. This extension can be obtained for free using point 3 above.

In general a good way to learn to write instructions inside CODE/EDOC is to compile simple code samples with the /EXPLIST option, which will display the instructions generated by the compiler line by line in essentially the same format that you will use.

Referencing COMMON, MODULE, and ALLOCATE'd variables

Because most COMMON blocks are allocated as the program starts up (as are large arrays in MODULE's) the simplest way to access these objects, as well as explicitly ALLOCATE'd arrays, is to take their address before entering the CODE/EDOC. For example:

        COMMON/FRED/alpha,beta(100),gamma
        INTEGER*8 alpha,beta,gamma
        INTEGER*8 addressof_beta
        addressof_beta=loc(beta)
        CODE
         MOV_Q    R10,addressof_beta
         MOV_Q    [R10+8],42   !This sets beta(2) to the value 42

The 64-bit address space

The 32-bit address space provided a theoretical maximum 232 (4 x 109) addressable bytes. Correspondingly, the 64-bit address space offers a theoretical maximum 264 (1.8 x 1019) addressable bytes. This means that, rather like in the early days of the 32-bit architecture, when a typical computer might have vastly less than 232 bytes (4 GB) of memory, the virtual address space is only very sparsely populated.

Indeed, the 64-bit virtual address space is so large that it isn't possible to provide page tables to cover the address space. This means that the amount of virtual address space available to a program is determined in a way that depends on the version of Windows in use, and the total amount of main memory on the computer (say 16 GB). This number is still extremely large. However, it is relevant if you use calls to VirtualAlloc to access high memory addresses in an absolute way.

Using the SSE registers for parallel computation

Instructions like MOVDQA will load a pair of REAL*8 numbers into an XMM register. Since these numbers are just bits, the instruction can also be used to move four REAL*4 numbers into an XMM register. However this instruction will fault if the data is not 16-bit aligned. This is problematic because REAL*4 and REAL*8 numbers are aligned wherever possible (EQUIVALENCE can prevent alignment) to 4 and 8 bytes respectively. In practice it turns out that the MOVDQU (which is reputed to be slower than MOVDQA) seems to run at the same speed for aligned data, and only somewhat slower for non-aligned data, but generates no alignment faults.

FURTHER INFORMATION:

FTN95 from the Command Line
Plato3 - The Driving Force Behind FTN95
Create Windows® programs in Fortran with ClearWin+
FTN95 Support Forums
Licencing


Silverfrost FTN95 available from Polyhedron Software