Dragon Cedar Runtime XEROX To From DragonCore^.pa Russ Atkinson PARC - CSL Subject Date Dragon Cedar Runtime December 19, 1984 Path Name /Indigo/Dragon/Documentation/DragonCedarRuntime.tioga Last edited by Russ Atkinson on December 19, 1984 11:31:24 pm PST Abstract This document describes the Cedar runtime support for the Dragon architecture. Attributes technical, Cedar, Dragon Dragon Cedar Runtime This document is a DRAFT, and most of the information in it is volatile. This document is also INCOMPLETE, and should be viewed with some suspicion. Revisions are currently being sent through Russ Atkinson. Introduction This document assumes familiarity with the Mesa programming language, the Cedar programming environment, and the following documents: [Indigo]Documentation>DragonMesaChanges.tioga [Indigo]Documentation>DragOps.tioga In this document we present a sketch of the Cedar runtime support on the Dragon architecture. Calls and Returns This section gives tentative information about the strategy used for procedure calls and returns on Dragon. This section was originally derived from DragOps.tioga. Simple call The simple case of calling a procedure first pushes any arguments expected by the procedure, then calls the procedure via DFC or LFC. The first instruction is normally an ALS instruction, which sets L to the base of the arguments. Therefore, the arguments become the initial local variables without moving those arguments. The return PC and the return L are pushed onto the IFU stack by the call. If there is insufficient room to do this, an IFU stack overflow trap is taken after the call has transferred control. Global frames If the procedure needs access to a global frame, then it is the responsibility of the procedure to setup a register with the pointer to the global frame. Current plans are to use the LGF instruction to load the global frame pointer from the global frame table into a local register. The LIQB instruction could be used to setup the global frame pointer in the case where there are few procedures for the frame, but space considerations will normally make it more desirable to use the 3-byte LGF instead of the 5-byte LIQB, since that will save 2 bytes per procedure. Simple return The simple case of returning from a procedure uses the RET opcode, which specifies how much to adjust the stack before returning. If the IFU stack is not empty, then the return PC and L are taken from the IFU stack, and the most recent entry in the IFU stack is discarded. If the IFU stack is empty when a RET is performed, the results are undefined. S is adjusted according to the alpha byte. For cases where the stack should not be adjusted on return the RETN opcode is used. Procedure variables For various reasons covered below, procedure variables are called with one more level of indirection than simple procedures. Procedure variables are implemented as pointers to words that contain the starting address of the procedure. To call through a procedure variable, the procedure variable is pushed, then a call is made to ([S])^ using SFCI. This convention leaves an extra word on the stack, so procedure variable calls must go to a different entry point than simple procedure calls. Nested procedures Nested procedures are implemented by placing the starting address in the local frame extension (the part of the local frame required to be in memory). The procedure variable for this nested procedure will be a pointer to this word. Therefore, on entry to the nested procedure, the address of the frame (plus an offset) will be on the stack, which makes computing the static link easy (a SUBB instruction). Interface function call Interface function calls are both more flexible and more involved than simple procedure calls. Interface records are referred to via positions in the global frame. Procedures exported through those interfaces have procedure variables in various slots of the interface record. To make an interface function call one simply sets up the arguments, fetches the procedure variable from the interface record, and performs a procedure variable call. Multiple global frames Although procedures must be specially compiled to use multiple global frames, there is no additional mechanism beyond forcing all calls to routines with multiple global frames to use the indirect procedure call. The address on top of the stack can then be used to find the global frame (probably via adding a constant). Support for multiple global frames can be delayed until there is need. Coroutines Coroutine calls are handled by traps. The data structures to be used are not yet defined. However, coroutine calls will be roughly as expensive as process switches. Support for coroutine can be delayed until there is need. Processes and Scheduling This section describes support for Mesa processes on Dragon. See [Ivy]Dragon>DragonProcesses.mesa for more details. <> Safe Storage This section describes Dragon specific changes to the Safe Storage facility of Cedar. <> How do we stop the world and trace the stack? This is probably done by the emergency stop feature, which causes every processor to stop dead and save its state. Then we can trace the resident frames. There is some question about tracing the non-resident frame extensions, we can either make them resident (not too bad if they don't take too much space), or counted (yecch!), or have some way to stop all processes that manipulate REFs (complicated, but perhaps the best way, especially since high-priority service processes can run). How do we support Lisp & Smalltalk? (see [Ivy]Dragon>DragonRC.mesa for more details) Smalltalk can use the Cedar allocator and some predetermined range of type codes. Lisp can use the Cedar allocator for everything except CONS cells, which have to be special because they get used so much. References for CONS cells can be distinguished from other REFs by address range. We get fast tests by having CONS cells at the most negative end of the address space, and other REFs at the most positive (their slots can be reversed if desired). Small INTs and small exponent REALs (except for 0.0) can be fit into 32-bit numbers accoridng to the following scheme (using the top three address bits to distinguish). 0: +INT 4: CONS 1: +REAL 5: -REAL 2: +REAL 6: -REAL 3: REF 7: -INT Smalltalk and Lisp get their own initial segments of type space (how much?), and can expand by using the Cedar type allocation facilities. The important part of the type game is that everyone has to deal with RC maps in the same way. CONS cells occupy 9 bytes, 8 of them in the double word pointed to by the reference, and 1 byte in some predictable place in the same place. The odd byte holds the reference count. Abstract machine This section describes the primitives used by the Abstract Machine facility of Cedar. <> Source <-> Object mapping <> We eventually want to support making procedures out of common code and correctly reporting the source position. Also, we should support INLINEs. We will have to be careful about the distinction between context and continuation PCs. Breakpoints <> We must provide a primitive interpreter here, since we cannot proceed the same way we do for the D-machines. It should also be possible to place a breakpoint on a conditional jump and only break on one sense of it! Signals & Errors This section describes the mechanism for handling signals and errors. <> must use general PC range to handler mapping to make everyone happy; this allows Interlisp & Smalltalk to use the same basic facility Traps This section gives tentative information about traps generated by the IFU. The general approach to traps is to have the instruction that generates the trap have no effect, and the return PC for the trap routine be the PC of the trapping instruction. Maskable traps (Reschedule, EU Stack overflow, and IFU stack overflow) disable further maskable traps until they are reenabled (usually via RETT). This section was originally derived from DragOps.tioga. Reschedule The reschedule trap occurs when the RESCHEDULE line is raised and interrupts are enabled. An attempt is made to have idle processors notice the RESCHEDULE line before non-idle processors (this is controlled by software). If the RESCHEDULE line is raised while interrupts are disabled, the reschedule trap will be deferred until interrupts are enabled again. The response to the reschedule trap is quite complex, and will not be covered in this note. EU Stack overflow The stack overflow trap occurs when an attempt to increase the EU stack pointer by 1 (S_S+1) would result in S crossing the stack overflow limit register (and traps are enabled). The limit, which is set by software, must allow sufficient room for the trap handler. The handler for this trap should migrate the eldest frame in the EU and IFU stack registers to memory, then return via RETT. IFU stack overflow The IFU stack overflow trap occurs when an attempt to call a procedure when the IFU stack is full (and stack overflow is enabled). Some number of IFU frames are still available after this trap occurs, so calls can be made by the trap handler. The handler for this trap is the same as for EU stack overflow. Stack underflow The stack underflow trap occurs when a return instruction (RET, RETN, or RETT) tries to return to an empty IFU stack. The trap handler must arrange to migrate a frame from memory to the IFU and EU registers. This is not a true trap, since the IFU stack is left empty on entry to the handler. When the transfer takes place, maskable traps are disabled. ALU fault The ALU fault trap occurs when the ALU detects integer overflow, a bounds check (due to the BNDCK instruction) or a NIL check (due to the NILCK instruction), or Lisp NaN. The handler for ALU fault should turn this trap into the appropriate error, depending on the instruction that raised the fault. EU page fault The EU page fault trap occurs when a reference to unmapped memory is made by the EU. The faulting address is available through a special EU register (MAR). The handler should determine if the page is valid, then either cause the page to be made present, or cause a page fault error. Interrupts are disabled during the trap handler. IFU page fault The IFU page fault trap occurs when a reference to unmapped memory is made by the IFU. The faulting address is available as the return PC. The handler should determine if the page is valid, then either cause the page to be made present, or cause a page fault error. Instruction trap Undefined instructions (also know as Xops) cause instruction traps. There is a separate instruction trap for each opcode. Some instructions are treated as defined in user mode, but not in kernel mode, and these instructions also cause instruction traps when executed in user mode. To permit efficient emulation of extended instruction sets, all Xops behave as procedure calls to an address linearly dependent on the instruction code. Xops have different lengths, depending on the instruction code. Xops of length 2 push Alpha onto the stack (high-order bytes undefined), Xops of length 3 push AlphaBeta onto the stack (high-order bytes undefined), and Xops of length 5 push AlphaBetaGammaDelta. For implementation reasons some undefined operations do not trap, but also do not produce well-defined results. These operations will be detailed when the PLA for the IFU is sufficiently determined. Recent Changes 19 Dec 84 Started DCopyright c 1984 by Xerox Corporation. All rights reserved. Κ•StyleDef”BeginStyle (Cedar) AttachStyle (firstHeadersAfterPage) {0} .cvx .def (root) "format for root nodes" { docStandard 36 pt topMargin 36 pt headerMargin .5 in footerMargin .5 in bottomMargin 1.0 in leftMargin 1.0 in rightMargin 6.5 in lineLength 24 pt topIndent 24 pt topLeading 0 leftIndent 10 pt rightIndent } StyleRule (positionInternalMemoLogo) "Xerox logo: screen" { docStandard 1 pt leading 1 pt topLeading 1 pt bottomLeading } ScreenRule (positionInternalMemoLogo) "for Xerox logo" { docStandard 1 pt leading 1 pt topLeading -0.5 in leftIndent } PrintRule (internalMemoLogo) "Xerox logo: screen" { "Logo" family 18 bp size 20 pt topLeading 20 pt bottomLeading } ScreenRule (internalMemoLogo) "for Xerox logo" { "Logo" family 18 pt size 12 pt leading -28 pt topLeading 36 pt bottomLeading -0.5 in leftIndent } PrintRule (memoHead) "for the To, From, Subject nodes at front of memos" { docStandard AlternateFontFamily 240 pt tabStops } StyleRule EndStyle˜Iblock•Mark insideHeaderšΡbox˜Ipositioninternalmemologo˜Iinternalmemologošœ˜Imemohead˜šΟsœž˜NšœΟtœ ˜Nšœ ˜ N˜N˜N˜—šžœž˜ Nšœ&˜&N˜N˜—Iabstractšž œ7ž œžœ2˜OšžŸœN˜WOšž œ˜#Ititle˜˜Ošœ Οmœ1™