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
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.