HandCodingPseudos.mesa
Copyright © 1984, 1985 by Xerox Corporation. All rights reserved.
Russ Atkinson (RRA) July 16, 1985 1:17:58 am PDT
DIRECTORY
DragOpsCross USING [FieldDescriptor, ProcessorRegister, Word],
HandCoding,
HandCodingSupport USING [Area],
IO USING [STREAM],
Rope USING [ROPE],
SymTab USING [Ref];
HandCodingPseudos: CEDAR DEFINITIONS = BEGIN OPEN DragOpsCross, HandCoding;
Pseudo-Op Declarations
Labelling
Label: TYPE = REF LabelRep;
LabelRep: TYPE = RECORD [
area: HandCodingSupport.Area, -- area for definition of label (NIL if undefined)
name: Rope.ROPE, -- the global name (if any) for this label
offset: INT, -- offset for definition of label
uses: REF-- uses of label that need fixing (internal)
];
SetLabel: PROC [label: Label];
GenLabel: PROC RETURNS [label: Label];
GenLabelHere: PROC RETURNS [label: Label];
UseLabel8A: PROC [label: Label] RETURNS [Lit8];
Use a label in the Alpha byte
UseLabel8B: PROC [label: Label] RETURNS [Lit8];
Use a label in the Beta byte
UseLabel16: PROC [label: Label] RETURNS [Lit16];
UseLabel32: PROC [label: Label] RETURNS [Word];
MakeLabelGlobal: PROC [name: Rope.ROPE, label: Label];
GetGlobalLabel: PROC [name: Rope.ROPE] RETURNS [Label];
GetGlobalLabelTable: PROC [area: HandCodingSupport.Area ← NIL] RETURNS [SymTab.Ref];
ShowGlobalLabelTable: PROC [st: IO.STREAM, sortNames: BOOLTRUE, area: HandCodingSupport.Area ← NIL];
shows the global label table for the given area to the given stream. If sortNames, then the labels come out sorted by name, otherwise sorted by address.
Macros
LReg: PROC [reg: RegSpec];
PReg: PROC [reg: RegSpec];
SReg: PROC [reg: RegSpec];
AddReg: PROC [reg: RegSpec, const: ConstSpec];
SubReg: PROC [reg: RegSpec, const: ConstSpec];
SetRegConst: PROC [reg: RegSpec, const: ConstSpec];
MoveReg: PROC [dst,src: RegSpec];
MoveRegI: PROC [dst,src: RegSpec, const: ConstSpec];
LRegI: PROC [reg: RegSpec, const: ConstSpec];
IndexedJump: PROC [dest: Label, long: BOOLFALSE, back: BOOLFALSE];
Uses the top of stack as a jump offset from the given label, and jumps there (popping the stack, of course). If long, then the label given can be more than 127 bytes away (32K bytes, actually). If back, then the dest label must occur before the jump, else it must occur after.
ProcedureEntry: PROC [label: Label, args: [0..15], dontChangeRL: BOOLFALSE];
Notes procedure entry.
NOT dontChangeRL => generate procedure entry instruction
ProcedureExit: PROC [rets: [0..15], dontChangeSP: BOOLFALSE, enableTraps: BOOLFALSE];
generates the procedure return instruction
dontChangeSP => RETN
enableTraps => RETT
ELSE => RET
SetupField: PROC [fd: DragOpsCross.FieldDescriptor];
generates shifter control from the given field descriptor pieces
ExtractField: PROC [first: [0..31], bits: [0..31]];
generates the appropriate instruction to extract the specified bits from [S]
ShiftLeft: PROC [bits: [0..31]];
generates the appropriate instruction to shift [S] left by bits
IFU primitives (mostly translate to LIFUR, LEUR, SIFUR, SEUR)
LoadProcessorReg: PROC [which: DragOpsCross.ProcessorRegister];
Loads the specified processor register onto the stack.
StoreProcessorReg: PROC [which: DragOpsCross.ProcessorRegister];
Pops the stack into the specified processor register.
EnableTraps: PROC;
... enables reschedule interrupts and stack overflow.
DisableTraps: PROC;
... disables reschedule interrupts and stack overflow.
CauseReschedule: PROC;
... causes a reschedule interrupt when interrupts are next enabled (possibly immediately). The state of traps enabled/disabled is not changed.
CauseReset: PROC;
... causes a reset trap.
GetSPLimit: PROC;
... enables/disables stack overflow trapping.
SetSPLimit: PROC;
... enables/disables stack overflow trapping.
The following pseudos are for convenience only. The IFU forces us to spend mucho cycles and bytes to determine these simple things (sigh).
GetL: PROC;
... returns the current value of L.
SetL: PROC;
... sets the current value of L.
GetYoungestPC: PROC;
... pushes the youngest PC entry in the IFU stack (into [S]).
GetYoungestL: PROC;
... pushes the L part of the youngest IFU stack entry.
GetEldestPC: PROC;
... pushes the eldest PC in the IFU stack and removes the eldest entry from the IFU stack. The results are undefined if there was no PC to get.
GetEldestL: PROC;
... pushes the L part of the eldest IFU stack entry.
SetYoungestPC: PROC;
... sets the youngest PC entry in the IFU stack (from [S]). S←S-1.
SetYoungestL: PROC;
... sets the youngest L entry in the IFU stack (from [S]). S←S-1.
SetEldestPC: PROC;
... causes a new eldest IFU stack entry to be created and sets the PC part of that entry (from [S]). S←S-1.
SetEldestL: PROC;
... sets the L part of the eldest IFU stack entry (from [S]).
Interaction with the interpreter
Pause: PROC;
... Instructs the interpreter to pause. This emits the X0 operation.
Halt: PROC [code: CARDINAL];
... Instructs the interpreter to halt. The code will be evident in the instruction trace. This emits the X377 operation.
END.