PrincOpsUtils.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Levin on September 20, 1983 10:57 am
Birrell, July 8, 1983 1:16 pm
Russ Atkinson (RRA) February 27, 1985 8:05:00 pm PST
Doug Wyatt, February 26, 1985 3:17:11 pm PST
Utilities for Basic Data Structures
Conversion among various memory size measures
The following procedures are coded in an obscure way to avoid invoking software-implemented arithmetic. This will all go away when the commented code sequences are introduced (in Trinity).
PagesForWords:
SAFE
PROC [words:
INT]
RETURNS [pages: PageCount]
= TRUSTED INLINE {
RETURN[Basics.DoubleShiftRight[[li[li: words+(wordsPerPage-1)]], logWordsPerPage].li]
};
WordsForPages:
SAFE
PROC [pages: PageCount]
RETURNS [words:
INT]
= TRUSTED INLINE {
RETURN[Basics.DoubleShiftLeft[[li[li: pages]], logWordsPerPage].li]
};
PagesForBytes:
SAFE
PROC [bytes:
INT]
RETURNS [pages: PageCount]
= TRUSTED INLINE {
RETURN[Basics.DoubleShiftRight[[li[li: bytes+(bytesPerPage-1)]], logBytesPerPage].li]
};
BytesForPages:
SAFE
PROC [pages: PageCount]
RETURNS [bytes:
INT]
= TRUSTED INLINE {
RETURN[Basics.DoubleShiftLeft[[li[li: pages]], logBytesPerPage].li]
};
Conversion among various memory address measures
The following procedures are coded to avoid invoking software-implemented arithmetic.
AddressForPageNumber:
SAFE
PROC [page: PageNumber]
RETURNS [address:
LONG
POINTER]
= TRUSTED INLINE {
RETURN[Basics.DoubleShiftLeft[[li[li: page]], logWordsPerPage].lp]
};
PageNumberForAddress:
SAFE
PROC [address:
LONG
POINTER]
RETURNS [page: PageNumber]
= TRUSTED INLINE {
RETURN[Basics.DoubleShiftRight[ [lp[address]], logWordsPerPage].li]
};
Block copying utilities
LongMove:
PROC [from:
LONG POINTER, nwords:
CARDINAL, to:
LONG POINTER]
= INLINE {
Trinity instructions will make this more efficient in the overlapping case.
Ordered:
PROC [lp:
LONG
POINTER]
RETURNS [
LONG
ORDERED
POINTER] =
MACHINE CODE {};
IF Ordered[to]
IN [Ordered[from]..Ordered[from]+nwords)
THEN FOR i: CARDINAL DECREASING IN [0..nwords) DO (to+i)^ ← (from+i)^; ENDLOOP
ELSE LongCopy[from: from, to: to, nwords: nwords];
};
Copy:
PROC [from:
POINTER, nwords:
CARDINAL, to:
POINTER]
= MACHINE CODE {zBLT};
ByteBlt:
PROC [to, from: ByteBltBlock]
RETURNS [nBytes:
CARDINAL];
This will be a machine code procedure in Trinity.
LongCopy:
PROC [from:
LONG
POINTER, nwords:
CARDINAL, to:
LONG
POINTER]
= MACHINE CODE {zBLTL};
Logic utilities (same as in Basics)
BitOp:
TYPE =
PROC [
WORD,
WORD]
RETURNS [
WORD];
BITAND: BitOp
= MACHINE CODE {zAND};
BITOR: BitOp
= MACHINE CODE {zOR};
BITXOR: BitOp
= MACHINE CODE {zXOR};
BITNOT:
PROC [
WORD]
RETURNS [
WORD]
= MACHINE CODE {zLIN1; zXOR};
BITSHIFT:
PROC [value:
WORD, count:
INTEGER]
RETURNS [
WORD]
= MACHINE CODE {zSHIFT};
Long Pointer Manipulation
LowHalf:
PROC [u:
LONG
POINTER]
RETURNS [
POINTER]
= INLINE {RETURN[LOOPHOLE[LOOPHOLE[u, Basics.LongNumber].lo]]};
HighHalf:
PROC [u:
LONG
POINTER]
RETURNS [
CARDINAL]
= INLINE {RETURN[LOOPHOLE[u, Basics.LongNumber].hi]};
MakeLongPointer:
PROC [low:
POINTER, high:
CARDINAL]
RETURNS [
LONG
POINTER]
= INLINE {
RETURN[LOOPHOLE[Basics.LongNumber[pair[lo: LOOPHOLE[low], hi: high]]]]};
Miscellaneous
LongZero:
PROC [where:
LONG
POINTER, nwords:
CARDINAL]
= MACHINE CODE { zMISC, aZERO; zPOP; zPOP};
PUSH:
PROC
RETURNS [
WORD]
= MACHINE CODE {zPUSH};
GetClockPulses:
SAFE
PROC
RETURNS [
CARD]
= TRUSTED MACHINE CODE {zMISC, aRCLK};
VERSION:
SAFE
PROC
RETURNS [VersionResult]
= TRUSTED MACHINE CODE {zMISC, aVERSION};
Utilities for BitBlt and TextBlt (wizards only)
AlignedBBTable:
PROC [ip:
POINTER
TO BBTableSpace]
RETURNS [b: BBptr]
= INLINE {
align:
TYPE =
MACHINE
DEPENDENT
RECORD [
s: [0..WORD.LAST/BBTableAlignment), z: [0..BBTableAlignment)];
b ← LOOPHOLE[ip + BBTableAlignment - 1];
LOOPHOLE[b, align].z ← 0;
};
BITBLT:
PROC [ptr: BBptr]
= MACHINE CODE {zBITBLT};
AlignedTextBltArg:
PROC [ip:
POINTER
TO TextBltArgSpace]
RETURNS [p:
POINTER
TO TextBltArg]
= INLINE {
align:
TYPE =
MACHINE
DEPENDENT
RECORD [
s: [0..WORD.LAST/TextBltArgAlignment), z: [0..TextBltArgAlignment)];
p ← LOOPHOLE[ip + TextBltArgAlignment - 1];
LOOPHOLE[p, align].z ← 0;
};
TextBlt:
PROC [
index:
CARDINAL, bitPos:
CARDINAL, micaPos:
CARDINAL,
count:
INTEGER, ptr:
POINTER
TO TextBltArg]
RETURNS [
newIndex:
CARDINAL, newBitPos:
CARDINAL, newMicaPos:
CARDINAL,
newCount:
INTEGER, result: TextBltResult
]
= MACHINE CODE {zMISC, aTEXTBLT};
Utilities for Xfer data structures (wizards only)
Control links
GetReturnLink:
PROC
RETURNS [ControlLink]
= MACHINE CODE {zLLB, returnOffset};
SetReturnLink:
PROC [ControlLink]
= MACHINE CODE {zSLB, returnOffset};
IsBound:
SAFE
PROC [link: ControlLink]
RETURNS [
BOOL]
= TRUSTED INLINE {RETURN[link ~= UnboundLink AND link ~= NullLink]};
Local Frames
GetReturnFrame:
PROC
RETURNS [FrameHandle]
= LOOPHOLE[GetReturnLink];
SetReturnFrame:
PROC [FrameHandle]
= LOOPHOLE[SetReturnLink];
MyLocalFrame:
PROC
RETURNS [FrameHandle]
= MACHINE CODE {zLADRB, 0};
MakeFsi:
SAFE
PROC [words: [0..MaxFrameSize]]
RETURNS [fsi: FrameSizeIndex]
= TRUSTED INLINE {
FOR fsi
IN [0..LastAVSlot)
DO
IF FrameVec[fsi] >= words THEN RETURN;
ENDLOOP;
ERROR
};
FrameSize:
SAFE
PROC [fsi: FrameSizeIndex[0..LargeReturnSlot)]
RETURNS [[0..MaxFrameSize]]
= TRUSTED INLINE {RETURN[FrameVec[fsi]]};
Global Frames
MyGlobalFrame:
PROC
RETURNS [GlobalFrameHandle]
= MACHINE CODE {zGADRB, 0};
GlobalFrame:
SAFE
PROC [link: ControlLink]
RETURNS [GlobalFrameHandle];
GlobalFrameAndEntryPoint:
SAFE
PROC [link: ControlLink]
RETURNS [gf: GlobalFrameHandle, ep:
CARDINAL];
Code segments
Codebase:
PROC [frame: GlobalFrameHandle]
RETURNS [PrefixHandle]
= INLINE { c: FrameCodeBase ← frame.code; c.out ← FALSE; RETURN[c.cseg] };
Allocation Vector
Alloc:
PROC [FrameSizeIndex]
RETURNS [
POINTER]
= MACHINE CODE {zALLOC};
Free:
PROC [
POINTER]
= MACHINE CODE {zFREE};
Utilities for Process data structures (wizards only)
ConditionPointer: TYPE = LONG POINTER TO CONDITION;
ShortConditionPointer: TYPE = POINTER TO CONDITION;
MonitorPointer: TYPE = LONG POINTER TO MONITORLOCK;
ShortMonitorPointer: TYPE = POINTER TO MONITORLOCK;
Process Data Area access
PsbHandleToIndex:
SAFE
PROC [handle: PsbHandle]
RETURNS [PsbIndex]
= TRUSTED INLINE {RETURN[LOOPHOLE[handle, CARDINAL]/SIZE[ProcessStateBlock]]};
PsbIndexToHandle:
SAFE
PROC [index: PsbIndex]
RETURNS [PsbHandle]
= TRUSTED INLINE {RETURN[LOOPHOLE[index*SIZE[ProcessStateBlock]]]};
PsbIndexToProcess:
SAFE
PROC [index: PsbIndex]
RETURNS [
PROCESS]
= TRUSTED INLINE {RETURN[LOOPHOLE[index]]};
ProcessToPsbIndex:
SAFE
PROC [process:
PROCESS]
RETURNS [PsbIndex]
= TRUSTED INLINE {RETURN[LOOPHOLE[process]]};
Monitors and Condition Variables
Enter:
PROC [ShortMonitorPointer]
RETURNS [success:
BOOL]
= MACHINE CODE {zME};
LongEnter:
PROC [MonitorPointer]
RETURNS [success:
BOOL]
= MACHINE CODE {zME};
Exit:
PROC [ShortMonitorPointer]
= MACHINE CODE {zMXD};
LongExit:
PROC [MonitorPointer]
= MACHINE CODE {zMXD};
Wait:
PROC [ShortMonitorPointer, ShortConditionPointer,
--timeout:--
CARDINAL]
= MACHINE CODE {zMXW};
LongWait:
PROC [MonitorPointer, ConditionPointer,
--timeout:--
CARDINAL]
= MACHINE CODE {zMXW};
ReEnter:
PROC [ShortMonitorPointer, ShortConditionPointer]
RETURNS [success:
BOOL]
= MACHINE CODE {zMRE};
LongReEnter:
PROC [MonitorPointer, ConditionPointer]
RETURNS [success:
BOOL]
= MACHINE CODE {zMRE};
Notify:
PROC [ShortConditionPointer]
= MACHINE CODE {zNOTIFY};
LongNotify:
PROC [ConditionPointer]
= MACHINE CODE {zNOTIFY};
Broadcast:
PROC [ShortConditionPointer]
= MACHINE CODE {zBCAST};
LongBroadcast:
PROC [ConditionPointer]
= MACHINE CODE {zBCAST};
Requeue:
PROC [from: QueueHandle, to: QueueHandle, p: PsbHandle]
= MACHINE CODE {zREQUEUE};
EnableAndRequeue:
PROC [from: QueueHandle, to: QueueHandle, p: PsbHandle]
= MACHINE CODE {
Note: this depends on having one instruction after enabling.
zDWDC;
zREQUEUE;
};
Interrupts
DisableInterrupts:
PROC
= MACHINE CODE {zIWDC};
EnableInterrupts:
PROC
= MACHINE CODE {zDWDC};
AllocateNakedCondition:
PROC
RETURNS [cv: ConditionPointer, mask:
WORD];
This procedure allocates one of the sixteen naked notify condition variables, initializes it with the default timeout, and returns a long pointer and wakeup mask with an appropriate bit set.
DeallocateNakedCondition:
PROC [cv: ConditionPointer];
This procedure deallocates a naked notify condition variable previously allocated with AllocateNakedCondition.
Miscellaneous (wizards only)
WriteMDS:
PROC [mdsi:
CARDINAL]
= MACHINE CODE {zWR, MDSreg};
ReadPSB:
PROC
RETURNS [currentProcess: PsbHandle]
= MACHINE CODE {zRR, PSBreg};
WritePSB:
PROC [currentProcess: PsbHandle]
= MACHINE CODE {zWR, PSBreg};
ReadPTC:
SAFE
PROC
RETURNS [time: Ticks]
= TRUSTED MACHINE CODE {zRR, PTCreg};
WritePTC:
SAFE
PROC [time: Ticks]
= TRUSTED MACHINE CODE {zWR, PTCreg};
ReadWDC:
SAFE
PROC
RETURNS [countDisabled:
CARDINAL]
= TRUSTED MACHINE CODE {zRR, WDCreg};
WriteWDC:
PROC [countDisabled:
CARDINAL]
= MACHINE CODE {zWR, WDCreg};
ReadATP,
ReadOTP:
PROC
RETURNS [ControlLink]
= MACHINE CODE {zLLB, 3B};
ReadXTS:
SAFE
PROC
RETURNS [XferTrapStatus]
= TRUSTED MACHINE CODE {zRR, XTSreg};
WriteXTS:
PROC [XferTrapStatus]
= MACHINE CODE {zWR, XTSreg};
ReadXTP:
PROC
RETURNS [ControlLink]
= MACHINE CODE {zLLB, 3};