CirioMemory.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Laurie Horton, February 24, 1992 4:36 pm PST
Last tweaked by Mike Spreitzer September 19, 1991 9:38 am PDT
Philip James, February 25, 1992 9:24 am PST
DIRECTORY Basics, CirioNubAccess, Rope;
CirioMemory: CEDAR DEFINITIONS
= BEGIN
ROPE: TYPE ~ Rope.ROPE;
BitAddr
A BitAddr represents a position in or length of memory.
BitAddr: TYPE ~ RECORD [aus: CARD, bits: INT];
The first part is in Addressing Units (ie, increments of debuggee pointers). ABS[bits] < bitsPerAu.
zeroBA: BitAddr ~ [0, 0];
unspecdBA: BitAddr ~ [CARD.LAST, INT.LAST];
ptrSize: BitAddr ~ [4, 0];
bitsPerAu: NAT ~ 8;
bitsPerPtr: NAT ~ 32;
BaCons: PROC [aus: CARD, bits: INT] RETURNS [BitAddr]
~ INLINE {IF bits/bitsPerAu >= 0 OR aus > ABS[bits/bitsPerAu] THEN
RETURN[[aus+bits/bitsPerAu, bits MOD bitsPerAu]] ELSE
RETURN[[0, aus*bitsPerAu+bits]]};
BaAsAbs: PROC [ba: BitAddr] RETURNS [BitAddr];
Result is equivalent to arg, and has non-negative bits.
BaAdd: PROC [a, b: BitAddr] RETURNS [BitAddr]
~ INLINE {RETURN BaCons[a.aus+b.aus, a.bits+b.bits]};
BaAddOffset: PROC [ba: BitAddr, bits: INT] RETURNS [BitAddr]
~ INLINE {RETURN BaCons[ba.aus, ba.bits+bits]};
BaSub: PROC [a, b: BitAddr] RETURNS [BitAddr]
~ INLINE {RETURN BaCons[a.aus-b.aus, a.bits-b.bits]};
BaMul: PROC [ba: BitAddr, by: CARD] RETURNS [BitAddr]
~ INLINE {RETURN BaCons[ba.aus*by, ba.bits*by]};
BaCompare: PROC [a, b: BitAddr] RETURNS [Basics.Comparison];
BitsToBa: PROC [bits: INT] RETURNS [BitAddr]
~ INLINE {RETURN BaCons[0, bits]};
BaToBits: PROC [ba: BitAddr] RETURNS [CARD]
~ INLINE {RETURN[ba.aus*bitsPerAu + ba.bits]};
AusToBa: PROC [aus: CARD] RETURNS [BitAddr]
~ INLINE {RETURN[[aus, 0]]};
BaToAus: PROC [ba: BitAddr] RETURNS [CARD]
~ INLINE {IF ba.bits#0 THEN ERROR; RETURN[ba.aus]};
PtrToBa: PROC [ptr: CARD] RETURNS [BitAddr]
~ INLINE {RETURN[[LOOPHOLE[ptr], 0]]};
BaToPtr: PROC [ba: BitAddr] RETURNS [CARD]
~ INLINE {IF ba.bits#0 THEN ERROR; RETURN[LOOPHOLE[ba.aus]]};
BitStretch: TYPE ~ RECORD [start, size: BitAddr];
Some BitStretchs may have size=unspecdBA, meaning the length is unknown.
unspecdBS: BitStretch ~ [unspecdBA, unspecdBA];
BsCompose: PROC [main, inner: BitStretch] RETURNS [within: BOOL, compd: BitStretch];
inner is interpreted relative to main; compd tells whether all of compd lies within main.
Mem
Mems are Node time information. They define a piece of memory with perhaps some structure. At the moment, there are two aspects of Memness: Frame and Simple. A Simple Mem represents a contiguous sequence of bits in memory; while the start of the sequence is always definite, the length may not be known (unspecdBA represents the unknown length). A Frame Mem represents a stack frame of a procedure at some level of abstraction. A Mem may be both Simple and Frame (this is needed for global vars, 'cause they are layed out simply, except for procedure constants). When reading and writing less than a whole CARD, the least significant bitSize bits are the significant ones.
Mem: TYPE = RECORD[class: MemClass, data: REF ANY];
noMem: Mem = [NIL, NIL];
MemClass: TYPE ~ REF MemClassPrivate;
MemClassPrivate: TYPE ~ RECORD [
Every Mem can:
CreateSimple: PROC [data: REF ANY, stretch: BitStretch, keepFrame: BOOL] RETURNS [Mem],
Create another one, at the given absolute address, with the given size. If keepFrame, the result has the same Frameness as the argument; if NOT keepFrame, the result is purely simple.
A Simple Mem can:
Subfield: PROC [data: REF ANY, rel: BitStretch] RETURNS [Mem],
Result has same Framness as arg; this is needed so that SelectVarLoc can return a Simple+Frame Mem for Cedar global variables.
Shift: PROC [data: REF ANY, offset: BitAddr] RETURNS [Mem],
Used for pointer addition; size and Frameness don't change.
GetStretch: PROC [data: REF ANY] RETURNS [BitStretch],
Read: PROC [data: REF ANY, bitSize: CARD, offset: BitAddr] RETURNS [CARD],
Write: PROC [data: REF ANY, bits: CARD, bitSize: CARD, offset: BitAddr],
A Frame Mem can:
ReadPtrReg: PROC [data: REF ANY, ptrReg: PtrReg] RETURNS [BitStretch],
ReadSegmentReg: PROC [data: REF ANY, segName: ROPE, segNum: INT] RETURNS [BitStretch],
Both procedures raise Error when the segment or pointer is undefined.
SetPtrReg: PROC [data: REF ANY, ptrReg: PtrReg, val: BitStretch]
Since Mems are nominally immutable, this should only be called as part of constructing one.
];
PtrReg: TYPE ~ {
fp --frame pointer--,
sp --stack pointer--,
fe --frame extension pointer--
};
Error: ERROR [msg: ROPE];
MemSubfield: PROC [mem: Mem, rel: BitStretch] RETURNS [Mem]
~ INLINE {RETURN mem.class.Subfield[mem.data, rel]};
MemShift: PROC [mem: Mem, offset: BitAddr] RETURNS [Mem]
~ INLINE {RETURN mem.class.Shift[mem.data, offset]};
MemIndirect: PROC [mem: Mem, size: BitAddr ← unspecdBA, offset: BitAddr ← zeroBA] RETURNS [Mem];
MemGetStretch: PROC [mem: Mem] RETURNS [BitStretch]
~ INLINE {RETURN mem.class.GetStretch[mem.data]};
MemGetSize: PROC [mem: Mem] RETURNS [BitAddr]
~ INLINE {RETURN [mem.class.GetStretch[mem.data].size]};
MemGetStart: PROC [mem: Mem] RETURNS [BitAddr]
~ INLINE {RETURN [mem.class.GetStretch[mem.data].start]};
MemRead: PROC [mem: Mem, bitSize: CARD, offset: BitAddr] RETURNS [CARD]
~ INLINE {RETURN mem.class.Read[mem.data, bitSize, offset]};
MemWrite: PROC [mem: Mem, bits: CARD, bitSize: CARD, offset: BitAddr]
~ INLINE {mem.class.Write[mem.data, bits, bitSize, offset]};
MemPtrRegIndirect: PROC [mem: Mem, ptrReg: PtrReg, size, offset: BitAddr, keepFrame: BOOL] RETURNS [Mem];
MemReadPtrReg: PROC [mem: Mem, ptrReg: PtrReg] RETURNS [BitStretch]
~ INLINE {RETURN mem.class.ReadPtrReg[mem.data, ptrReg]};
MemReadSegReg: PROC [mem: Mem, segName: ROPE, segNum: INT] RETURNS [BitStretch]
~ INLINE {RETURN mem.class.ReadSegmentReg[mem.data, segName, segNum]};
MemSelectSegment: PROC [mem: Mem, segName: ROPE, segNum: INT, keepFrame: BOOL] RETURNS [Mem];
CreateSimpleMem: PROC[addr: CirioNubAccess.RemoteAddress, size: BitAddr ← unspecdBA] RETURNS[Mem];
Create a Simple Mem.
MakeDualMem: PROC [nub: CirioNubAccess.Handle, fp, sp: CARD ← invalidPtr, text, data, bss, fep, simple: BitStretch ← unspecdBS] RETURNS [mem: Mem];
Create a Mem that is Frame and maybe Simple. Caller can decline to define some registers by passing invalidPtr or unspecdBS.
invalidPtr: CARD = CARD.LAST;
END.