C2CProposedRuntimeSupport.tioga
Copyright Ó 1987, 1988 by Xerox Corporation. All rights reserved.
Christian Jacobi, January 5, 1988 11:02:36 am PST
Christian Jacobi, March 3, 1988 1:58:43 pm PST
Edits to
[luther.alpine]<CHauser.pa>MimosaBugs>PortableCedarRuntimeSupport.mesa
I did reverse the order of parameters...
Naming convention? prefix?
The following procedures right away...
MoveWords: PROC [dst: PTR, src: PTR, nWords: NAT];
Moves words from the source to the destination. The caller does not assure disjointness.
MoveWordsDisjoint: PROC [dst: PTR, src: PTR, nWords: NAT];
Moves words from the source to the destination. For efficiency, no check is made for overlapping variables, but the caller assures disjointness.
EqualWords: PROC [x: PTR, y: PTR, nWords: NAT] RETURNS [BOOL];
Tests the two multi-word variables for equality.
MoveBytesDisjoint: PROC [dst: PTR, src: PTR, nBytes: NAT];
Moves bytes from the source to the destination. For efficiency, no check is made for overlapping variables, but the caller assures disjointness.
ExtractField: PROC [base: PTR, offset: INT, bits: [0..bitsPerWord]] RETURNS [Word];
Extracts the field from any base pointer at any bit offset. The word returned is the field right-justified with zero bits on the left.
DepositField: PROC [base: PTR, offset: INT, bits: [0..bitsPerWord], word: Word];
Deposits the field to any base pointer at any bit offset. The word given has the bits right-justified. The other bits are ignored.
MoveField: PROC [dst: PTR, dstOffset: INT, src: PTR, srcOffset: INT, bits: NAT];
Moves field that is bits wide from the src address (plus srcOffset bits) to the dst address (plus dstOffset bits). The caller does not assures disjointness.
EqualFields: PROC [x: PTR, xOffset: INT, y: PTR, yOffset: INT, bits: NAT] RETURNS [BOOL];
Tests fields for equality.
The following procedures are not used the next 3 days...
Efficiency matters less, I believe they wont be used in inner most loops
FillFields: PROC [dst: PTR, dstOffset: INT, bits: [0..bitsPerWord], times: NAT, value: Word];
Fills contiguos fields that each are bits wide in the dst address (plus dstOffset bits) for times number of fields. The fill value will be right-justified in value.
FillLongFields: PROC [dst: PTR, dstOffset: INT, src: PTR, srcOffset: INT, bits: NAT, times: NAT];
Fills contiguos fields that each are bits wide in the dst address (plus dstOffset bits) for times number of fields. The fill value is taken from the src address (plus srcOffset bits).
FillWords: PROC [dst: PTR, times: NAT, value: Word];
Fills times words at the destination with value.
FillLongWords: PROC [dst, src: PTR, nWords: NAT, times: NAT];
Fills times nWords fields at the destination (dst) with the nWords field at the source (src).
C2CSafeStorageRuntimeSupport.tioga
Copyright Ó 1987, 1988 by Xerox Corporation. All rights reserved.
Christian Jacobi, January 5, 1988 11:02:36 am PST
Try of a match between IntCodeDefs.CedarSelector and PortableCedarRuntimeSupport; Made by proposing changes to the SafeStorage section in PortableCedarRuntimeSupport. Types as in original PortableCedarRuntimeSupport.
Please reply whether reasonable.
Christian
CedarSelector: TYPE = {
A CedarSelector is usually applied by name to allow for special implementations. It should also be possible to apply it by reference. The basic Cedar operators are separate to make it easier to omit these features for XDE versions of the Mimosa compiler.
simpleAssign,
lhs ← rhs
increments source RCs, decrements dest RCs, and moves the word
lhs is first argument, and should be the address of the destination
rhs is second argument
AssignRef: PROC [dstPtr: RefPtr, src: REF];
Atomically assigns a reference to a reference-containing cell.
simpleAssignInit,
lhs ← rhs
like simpleAssign, but the destination RCs are not decremented
AssignRefInit: PROC [dstPtr: RefPtr, src: REF];
Atomically assigns a reference to a reference-containing cell for initialization, without first decrementing RCs of destination.
complexAssign,
lhs ← rhs
increments source RCs, decrements dest RCs, and moves the words
lhs is first argument, and should be the address of the destination
rhs is second argument
type of lhs is given by the third argument
AssignRefComposite: PROC [dst: PTR, src: PTR, type: Type, sz: NAT];
Performs dst^ ← src^, treating the copied variable as being of the specified type (containing refs). Reference-counted fields are treated properly. This operation is definitely not atomic. AssignRefCompositeFault will be raised if an an improper assignment is attempted (i.e. assignment to a variant record).
sz: size in words.
complexAssignInit,
lhs ← rhs
like complexAssign, but the destination RCs are not decremented
AssignRefCompositeInit: PROC [dst: PTR, src: PTR, type: Type, sz: NAT];
Performs dst^ ← src^, treating the copied variable as being of the specified type. Reference-counted fields are treated properly. This operation is definitely not atomic. AssignRefCompositeFault will be raised if an an improper assignment is attempted (i.e. assignment to a variant record). Assumes this is an initialization of dst^ and therefore does not decrease RCs of destination.
sz: size in words.
new,
NEW[T]
T is first arg, nWords is second arg
(only used for zone-less NEW)
NewObject: PROC [nWords: INT, type: Type] RETURNS [REF];
Allocates a new object of the given type from the default zone, using at least nWords of storage, and initializing the type appropriately.
The c2c back-end will never see a zone z # NIL
code,
for CODE[T]
info gives the internal type index for T
For PrincOps the type code is determined at loader time and stuffed into a position in the global frame. This should be OK for Dragon as well.
The c2c back-end will never see this construct
narrow,
for NARROW[ref, T]
ref is first arg, info specifies T
This operation raises a NarrowRefFault if ref # NIL and referentType[ref] # T.
Narrow: PROC [ref: REF, type: Type] RETURNS [REF];
Checks to determine that the type of the object is equal to the given type, then returns the original reference. When ref = NIL, NIL is returned and no checking is performed. Raises NarrowFault if the types are different. Useful for NARROW.
referentType,
get the referent type from a REF (first arg)
This operation is used in WITH ref SELECT ... statements and ISTYPE expressions. NIL has a reserved referent type that never matches the type of an object.
GetReferentType: PROC [ref: REF] RETURNS [Type];
Gets the referent type of an object from a reference to that object. Returns nullType for ref = NIL. Useful for WITH ref SELECT FROM ...
procCheck
check a procedure (first arg) for assignability in the safe language
A procedure descriptor must contain enough information to be able to check for safe assignment. In systems that do not support retained frames all nested procedures are not safely assignable to locations that may be longer lived than the procedures.
For Dragon, a procedure descriptor is always a pointer to the starting PC of the procedure. The word following the PC could be used to indicate the assignability of the procedure.
CheckProc: PROC [proc: ProcAny] RETURNS [ProcAny];
Returns same procedure.
Checks the procedure for being assignable. Raises NestedProcError if the proc is nested.
};
C2CMoreRuntimeSupport.tioga
Copyright Ó 1987, 1988 by Xerox Corporation. All rights reserved.
Christian Jacobi, January 5, 1988 11:03:26 am PST
Mark,
could I hand you some more runtime functions to be programmed?
You once handed me some of those procedures in C; I did store those in /ivy/jacobi/temp/FromMark.c.
However, I think it might be more confortable to have this stuff in the CedarBoot.
This, and preceding runtime procedure requests are/will be stored with /indigo/mimosa/top/c2c.df until we find a better place.
Thanks, Christian
Debugging Aids
will be removed as soon as the need of such low level debugging features disappears
DebugPutChar: PROC [ch: CHAR];
writes character to some output file/device and flush. The character
appears even if the program crashes immediately afterwards.
Comforts
RaiseBoundsFault: PROC [];
raises the BoundsFault error
raised when index or subrange out of range
{
ERROR BoundsFault
};
This is not a comfort now, but it will be when the Signaler procedures will be available.
Optimize space; not speed.
RaiseAbstractionFault: PROC [];
raises an error
placed by Cedar to C in places where the code generator thinks the pc can NEVER be.
{
ERROR AbstractionFault
};
Optimize space; not speed.
BoundsCheck: PROC [arg: INT, limit: NAT] RETURNS [sameArg: NAT];
returns arg when arg is in the range [0..limit]
raises the BoundsFault error otherwise
{
IF arg<0 OR arg>limit THEN ERROR BoundsFault;
sameArg ← arg
};
NilCheck: PROC [ptr: PTR] RETURNS [samePtr: PTR];
returns pointer if non nil
raises the NIL access error otherwise
{
IF ptr=NIL THEN ERROR NILAccess;
samePtr ← ptr
};
Frame allocation
Although frames are normally in registers, there are various cases where frame extensions must be placed in actual storage. The compiler uses these routines to allocate and free the parts of local frames that must be in memory.
ExtensionAlloc: PROC [nWords: INT] RETURNS [PTR];
Allocates a frame extension large enough to hold nWords worth of data.
ExtensionFree: PROC [ptr: PTR] RETURNS [PTRNIL];
Frees a frame extension obtained by ExtensionAlloc. Ignores ptr = NIL. Always returns NIL for convenience of assigning back to the link.
NO MORE TRUE
Frame extensions are allocated in a LIFO stack per process.
However, currently it is possible that a free operation get lost.
For now its ok to just allocate frame extensions and forget about freeing [or use the garbage collector]
ArithmeticRuntimeSupport.tioga
Copyright Ó 1987, 1988 by Xerox Corporation. All rights reserved.
Christian Jacobi, January 5, 1988 11:04:15 am PST
If these routines are implemented as macros, the arguments must not be evaluated twice unless specified.
The compiler generates calls to these procedures using unsigned as type for the parameters or returns; to get the real numbers, the parameter must be loopholed, NOT casted.
By usingunsigned the c2c compiler ensures that the C compiler will not convert these parameters to double precision.
Once in the glorious future we will also need 64 bits.
SignedPwr: PROC [a, b: INT32] RETURNS [INT32];
UnsignedPwr: PROC [a, b: CARD32] RETURNS [CARD32];
FloatInt: PROC [i: INT32] RETURNS [REAL32];
FloatCard: PROC [i: CARD32] RETURNS [REAL32];
RealNeg: PROC [a: REAL32] RETURNS [REAL32];
RealAbs: PROC [a: REAL32] RETURNS [REAL32];
may re-evaluate arguments
RealAdd: PROC [a, b: REAL32] RETURNS [REAL32];
RealSub: PROC [a, b: REAL32] RETURNS [REAL32];
(a-b)
RealMul: PROC [a, b: REAL32] RETURNS [REAL32];
RealDiv: PROC [a, b: REAL32] RETURNS [REAL32];
(a/b)
RealMin: PROC [a, b: REAL32] RETURNS [REAL32];
may re-evaluate arguments
RealMax: PROC [a, b: REAL32] RETURNS [REAL32];
may re-evaluate arguments
RealPwr: PROC [a, b: REAL32] RETURNS [REAL32];
RealGt: PROC [a, b: REAL32] RETURNS [BOOL];
(a>b)
RealGe: PROC [a, b: REAL32] RETURNS [BOOL];
(a>=b)
RealEq: PROC [a, b: REAL32] RETURNS [BOOL];
(a=b)