© (1998-1999) by Günter Dotzel, ModulaWare
3rd edition, 16-Feb-1999
MaX V4, ModulaWare's 32 bit Modula-2 compiler for OpenVMS Alpha uses a pointer size of 32 bit, but already allows 64 bit whole number arithmetic. OpenVMS Alpha V7.0 or later supports the full 64 bit address space for dynamic data, i.e.: heap. To exploit the 64 bit address space, MaX V5 introduces
The compilation command qualifier /pointersize=x was added, where x, specifying the number of bits, is either 32 or 64.
Independent from the /pointersize value, MaX V5 exports the following types from module SYSTEM
Type with storage size/bytesNote, the types [UN]SIGNED_32 and [UN]SIGNED_64 from SYSTEM were already available in MaX V4.
[UN]SIGNED_32 4 [UN]SIGNED_64 8 PROC_32 4 PROC_64 8 ADDRESS_32 4 ADDRESS_64 8 PROCESS_32 4 PROCESS_64 8
Independent from /pointersize, the pervasive type SIGNED_32 is declared as a subrange of SIGNED_64, with the lower- and upper-bounds specified by their respective minimal and maximal values. The same applies to UNSIGNED_32, which is a subrange of UNSIGNED_64,
Whole number MIN/MAX values:
MIN(SIGNED_32) = -2147483648 MAX(SIGNED_32) = 2147483647 MIN(SIGNED_64) = -9223372036854775808 MAX(SIGNED_64) = 9223372036854775807 MIN(UNSIGNED_32) = 0 MAX(UNSIGNED_32) = 4294967295 MIN(UNSIGNED_64) = 0 MAX(UNSIGNED_64) = 18446744073709551615
Arithmetic with 32 bit and 64 bit whole number values is allowed with any /pointersize in declaration sections and statement part of procedures and module body. Whole number literals and constant expressions are always evaluated in 64 bit mode and they are compatible with [UN]SIGNED_32, if the constant value is in the types range.
Whole number range | Expression compatible withWhen the base-type, also called host-type, in a subrange type declaration is not explicitely specified, its size matches the /pointersize.
[MIN(SIGNED_64) ..MIN(SIGNED_32)-1] | SIGNED_64 [MIN(SIGNED_32) ..-1] | SIGNED_32, SIGNED_64 [0 ..MAX(SIGNED_32)] | [UN]SIGNED_32, [UN]SIGNED_64 [MAX(SIGNED_32)+1 ..MAX(UNSIGNED_32)] | UNSIGNED_32, [UN]SIGNED_64 [MAX(UNSIGNED_32)+1..MAX(SIGNED_64)] | [UN]SIGNED_64 [MAX(SIGNED_32)+1 ..MAX(UNSIGNED_64)] | UNSIGNED_64
Examples of subrange declarations:
Subrange declaration Base-type, when compiled with
/pointersize=32 | /pointersize=64
TYPE
s1 = [0..255]; | UNSIGNED_32 UNSIGNED_64
s2 = [-65536..65535]; | SIGNED_32 SIGNED_64
s3 = [-2147483648..2147483647]; | SIGNED_32 SIGNED_64
s4 = [-2147483648..2147483648]; | not allowed SIGNED_64
s5 = SIGNED_64 |
[-2147483648..2147483648]; | SIGNED_64 SIGNED_64
s6 = SIGNED_32 |
[-2147483648..2147483648]; | not allowed not allowed
The standard Modula-2 expression- and assignment-compatibility rules for subranges and their base-types apply to [UN]SIGNED_32.
The types of the following pervasive identifiers depend on the /pointersize:
/pointersize=32:The size of pointer-, hidden-, and procedure-types, as well as constant procedures is 4 bytes.
INTEGER = SIGNED_32 CARDINAL = UNSIGNED_32 PROC = PROC_32 SYSTEM.ADDRESS = ADDRESS_32 SYSTEM.PROCESS = PROCESS_32
/pointersize=64:The size of pointer-, hidden-, and procedure-types, as well as constant procedures is 8 bytes.
INTEGER = SIGNED_64 CARDINAL = UNSIGNED_64 PROC = PROC_64 SYSTEM.ADDRESS = ADDRESS_64 SYSTEM.PROCESS = PROCESS_64
With /pointersize=32, no checks are made at run-time for [UN]SIGNED_32,
otherwise many existing programs, designed for 32 bit INTEGER/CARDINALs would fail at run-time.
e.g.: SYSTEM.CAST(T, expr) just changes the type if the size of T is equal to the size of expr.
On a 64 bit processor, signed 32 bit whole number values are always represented in their canonical
form, i.e. the sign bit is replicated into the upper 32 bits. A statement sequence of
int32 := -1; (* int32 has the value=0FFFFFFFFFFFFFFFFH, when loaded into a 64 register *) card32 := CAST(card32, int32);would raise an overflow exception in the second assignment, because the value 0FFFFFFFFFFFFFFFFH, being equal to MAX(UNSIGNED_64), is outside the range of UNSIGNED_32. On a 32 bit machine, using 32 bit registers, such subrange check could not be performed.
If a module which contains the declaration of a pointer-, hidden-, or procedure-type T
is compiled with /pointersize=x, the size of T is x DIV 8.
Independent from /pointersize,
in a module which contains the declaration of a pointer-, hidden-, or procedure-variable V:T,
the size of V is SIZE(T).
A procedure variable on OpenVMS Alpha is a pointer to a procedure linkage pair. A procedure linkage pair consists of two entries, a pointer to the procedure descriptor and an entry address, which are both 64 bit addresses, even with /pointersize=32.
Since the pervasive types depend on /pointersize, this also affects the type of the formal parameters in the following pervasive procedures and functions, and the result types of the latter:
32 bit pointers may be assigned to 64 bit pointer variables, but not vice-versa.
Variables of type ADDRESS_32 may be assigned to variables of type ADDRESS_64, but not vice-versa.
The type safety of the Modula-2 language pays-off here already at compile time, in order to avoid errors resulting from address truncation and writing to not-allocated memory which can cause data corruption.
According to the standard OpenVMS calling conventions, all parameters are passed by reference, even if the formal parameter is a value parameter. In the case of a value parameter, the callee is responsible to make a copy on the stack. So in either case, be it a value or variable parameter, if the parameter pointer sizes match, only the parameters address is passed.
This approach allows to have a single module library implementation, where the caller may be in either mode (32 or 64 bit) for most modules, where the module interface does not contain any VARiable formal parameter of pointer type.
If the formal parameter is a 64 bit pointer value parameter and the actual parameter is 32 bit pointer, the pointer value is pushed on the stack as a 64 bit address in canonical form and the stack address is passed as reference. But it is not possible to substitute a 32 bit pointer to a formal variable parameter of 64 bit pointer type, because the called procedure can not know the caller's pointer type size.
Since all address calculations are performed with 64 bit arithmetics, even when compiled with /pointersize=32, the only problem is the pervasive function procedure SYSTEM.ADR, which requires that the argument's address MBSE (must be sign-extended, i.e.: bit 31 must be replicated from bit 32 to bit 63) in 32 bit mode, because the function's result type is ADDRESS_32. This check takes two Alpha instructions. In a module compiled with /pointersize=32, where the substituted actual parameter of the pervasive function SYSTEM.ADR is a formal VAR procedure parameter, the compiler can not check at compile-time, whether the address fits into 32 bits. In this case, a run-time check for MBSE is generated.
If the variable p in module UseBit32 is pointing to an address outside in the 64 bit address space, this address can't be represented in a 32 bit integer variable. In this case (and under the presumption that the implementation module Bit32 was compiled with MaX V5), an exception with the code SS$_ARG_GTR_32_BITS (SYSTEM-F-ARG_GTR_32_BITS, argument greater 32 bit) is signaled, which means that the parameter address is not a 32-bit sign-extended value. This status code was introcduced in OpenVMS 7.0.
DEFINITION MODULE Bit32; PROCEDURE P(VAR x: CHAR): INTEGER; END Bit32.
IMPLEMENTATION MODULE Bit32; IMPORT SYSTEM; PROCEDURE P(VAR x: CHAR): INTEGER; BEGIN RETURN SYSTEM.ADR(x); END P; END Bit32.
MODULE UseBit32; (* to be compiled with /pointersize=64 *) FROM Storage IMPORT ALLOCATE, DEALLOCATE; IMPORT Bit32; VAR p: POINTER TO RECORD x: CHAR END; a: INTEGER; BEGIN NEW(p); a := Bit32.P(p^.x); DISPOSE(p); END UseBit32.
String descriptors (%STDESCR) are used for formal string parameters
when calling a foreign procedure.
Independent from /pointersize,
when an actual parameter is substituted for a %STDESCR
and whenever it is not known at compile time,
whether both, the string's length and its address will fit into a
16/32 bit length/address string descriptor,
the string's address is checked at run-time.
If the address is sign-extended,
a 16/32 bit length/address string descriptor is generated,
otherwise a 64/64 bit length/address string descriptor is constructed.
16/32 bit length/address string descriptor has a size of 8 bytes:
When compiled with /pointersize=32,
string descriptors and SYSTEM.ADR are the only places, where
more code is generated under certain conditions with MaX V5 than with MaX V4.
Using /pointersize=64 also changes the default symbol-file lookup strategy.
If a module M is imported, first M.sym64 is looked-up and if this file
is not found, M.sym is looked-up.
Import of 64 bit pointer-, procedure-, hidden-, and subrange-types or any variables of these
types is not possible, because the compiler never imports .sym64 with /pointersize=32.
The pervasive procedures NEW and DISPOSE are resolved using ALLOCATE and DEALLOCATE,
whose declaration must match the procedure type
The 32 bit version of module Storage, which exports the following substitution procedures:
The following module Storage is proposed for 64 bit and 32/64 bit-mixed pointer applications:
The procedure pair ALLOCATE and ALLOCATE_64 have the same semantics
and use the OpenVMS run-time library procedure
If the module TestNew, which imports module Storage is compiled with /pointersize=32,
NEW and DISPOSE require the 32 bit version of the substitution procedures
ALLOCATE and DEALLOCATE. These are contained in the symbol-file Storage.sym.
When the module TestNew is compiled with /pointersize=64,
NEW and DISPOSE require the 64 bit version of the substitution procedures
ALLOCATE and DEALLOCATE. These are contained in the symbol-file Storage.sym64.
If the compiler does not find Storage.sym64, Storage.sym is looked-up,
which results in the error message "unsatisfying parameters of substituted procedure".
To link the 64 bit version of TestNew, use
by Günter Dotzel
The
Silicon Man by Charles Platt, Tafford Publishing, Houstan, Texas,
USA, 1993.
There are three mysterious science fiction books written by Robert A. Heinlein
(1) The Puppet Master,
about alien invaders, who did not get stopped by shooting fast,
(2) Double Star,
about the impersonation of a key statesman, who mysteriously disappeared, and
(3) The Door into Summer.
Dream your troubles away. Someone cares
to invest your assets and you'd wake up rich in the future.
Yet it wasn't money that motivated Dan Davis, an electronics wizard;
it was the idea of coming back in 30 years, still young and strong,
to confront his old and wrinkled ex-lover, who
betrayed him with the partner he'd trusted. But the best-laid plans...
We
by Yevgeny Zamyatin, 1924(!), first published in
Russia only in 1988, translated by Clarencer Brown into English,
Penguin book, 1993.
Complexity
by M. Mitchell Waldrop, Touchstone Book, 1992.
IMPRESSUM: The ModulaTor is an unrefereed journal. Technical papers are to be
taken as working papers and personal rather than organizational statements.
Items are printed at the discretion of the Editor based upon his judgement on
the interest and relevancy to the readership. Letters, announcements, and
other items of professional interest are selected on the same basis.
Office of publication.
The Editor of The ModulaTor is Günter Dotzel; he can be reached at
[ Home |
Site_index |
Legal |
OpenVMS_compiler |
Alpha_Oberon_System |
ModulaTor |
Bibliography |
Oberon[-2]_links |
Modula-2_links |
General interesting book recommendations ]
RECORD strLen: SHORTWORD; (* 16 bit *)
ident: SHORTWORD; (* := 0; *)
address: SIGNED_32
END
The 64/64 bit length/address string descriptor is a self-identifying structure
with a size of 24 bytes.
RECORD selfId1: SHORTWORD; (* := 1; must be one (MBO) *)
ident: SHORTWORD; (* := 0; *)
selfId2: SIGNED_32 (* := -1; must be minus one (MBMO) *)
strLen: SIGNED_64;
address: SIGNED_64
END
The advantage is that even code compiled with /pointersize=32
is able to handle 64 bit string descriptors.
Symbol-file lookup strategy
Storage allocation
PROCEDURE (VAR ADDRESS, CARDINAL)
independent from the /pointersize.
PROCEDURE ALLOCATE(
VAR p: ADDRESS_32;
size: UNSIGNED_32);
PROCEDURE DEALLOCATE(
VAR p: ADDRESS_32;
size: UNSIGNED_32);
For using mixed pointers, it is recommended to use explicit calls to the substitution procedures.
When compiled with /pointersize=64,
the symbol-file of module Storage is called Storage.sym64 by default.
DEFINITION MODULE Storage;
(* 32/64 Bit Modula-2 Storage handler (heap management),
to be compiled with /pointersize=64
*)
FROM SYSTEM IMPORT
ADDRESS, ADDRESS_32, ADDRESS_64, UNSIGNED_32, UNSIGNED_64;
PROCEDURE ALLOCATE(
VAR p: ADDRESS;
size: CARDINAL);
PROCEDURE DEALLOCATE(
VAR p: ADDRESS;
size: CARDINAL);
PROCEDURE ALLOCATE_64(
VAR p: ADDRESS_64;
size: UNSIGNED_64);
PROCEDURE DEALLOCATE_64(
VAR p: ADDRESS_64;
size: UNSIGNED_64);
PROCEDURE ALLOCATE_32(
VAR p: ADDRESS_32;
size: UNSIGNED_32);
PROCEDURE DEALLOCATE_32(
VAR p: ADDRESS_32;
size: UNSIGNED_32);
END Storage.
PROCEDURE LIB$GET_VM_64* (
numbyt: SYSTEM.UNSIGNED_64;
VAR basadr: SYSTEM.ADDRESS_64): SYSTEM.SIGNED_32;
whereas the procedure pair DEALLOCATE and DEALLOCATE_64 use
PROCEDURE LIB$FREE_VM_64* (
numbyt: SYSTEM.UNSIGNED_64;
basadr: SYSTEM.ADDRESS_64): SYSTEM.SIGNED_32;
When compiled with /pointersize=64,
the object file of the implementation module Storage is called Storage.obj64 by default.
To link the 32 bit version of TestNew, use the link command
MODULE TestNew;
FROM Storage IMPORT ALLOCATE, DEALLOCATE;
VAR p: POINTER TO RECORD x: CHAR END;
BEGIN
NEW(p);
DISPOSE(p);
END TestNew.
$ Link TestNew
which takes Storage from the default object library Modula.OLB.
$ Link TestNew.obj64,Storage.obj64
which is the same as
$ Link TestNew.obj64,Storage
because the file extension is carried over to the rest of the file-name list.
It is also possible to use the 64 bit object library Modula.olb64
$ Link TestNew.obj64,Modula.olb64/lib
or redefine the logical name LNK$Library to use Modula.olb64 by default
$define LNK$Library Modula.olb64
and then link with the command
$ Link TestNew.obj64
Or, if it is desired to work only with 64 bit pointers,
it is also possible to overwrite the object file specification
in the compilation command:
$ MaX TestNew/pointersize=64/object=.obj
Or, to make /pointersize=64 and the object file extension /object=.obj default for
V5MaX compilation command, change the following lines in the command language definition file
v5max-user.cld:
keyword 32 nonnegatable
keyword 64 nonnegatable default
QUALIFIER OBJECT,DEFAULT,VALUE(TYPE=$FILE,default=.obj)
The ModulaTor Forum
Recommended Reading
Lew Platt, CEO of Hewlett-Packard, wrote this fascinating, futuristic fiction
for "stubborn idealists in biology and computer science, searching
even now for ways to free us from the injustice of mortality."
This book is about hackers and the near future in cyberspace.
A person finds himself inside of a computer being manipulated from the outside.
Life can be eternal but death can be as instant as a power failure
or system crash. This computerized reality, populated with
"infomorphs", is described with unprecedented realism.
George Orwell acknowledged
his debt to Zamyatin, giving him the inspiration for his famous story "1984".
We
describes life under the regimented totalitarian society of OneState,
ruled over by the all-powerfull "Benefactor".
We
is the archetype of the modern dystopia or anti-Utopia:
a great prose poem detailing the fate that might befall us
all if we surrender our individual selves to some collective
dream of technology and fail in the vigilance that is the price
for freedom.
In a world where nice guys often finish last, why do humans value trust and
cooperation? The science of complexity studies how single elements, such as
species, spontaneously organize into complicated structures like ecosystems
and economies, almost as if these systems were obeying a hidden yearning for
order. Mitchell Waldrop's groundbeaking, non-fiction bestseller takes the
readers into the hearts and minds of the scientists working at a think tank
called the Santa Fe Institute, to tell the story behind their
revolutionary discoveries.
![]()
Webdesign by www.otolo.com/webworx,
16-Feb-1999