<> <> Dragon Procedure Call IFU registers PC: program counter (32-bit byte address) L: index of frame start in EU regs S: index of frame end in EU regs SLimit: overflow limit for S IFUStack: stack of pairs EU registers EUStack: 128 registers indexed by S & L Const: 12 registers holding constants Aux: 16 registers (8 "user", 8 "system") Carry: arithmetic carry bit SC: Shifter Control MAR: last rejected mem. address Dragon Procedure Call Direct call (for fastest call sequence) push arguments on EU stack DFC or LFC to the procedure start (PC & L are saved to IFU stack) at entry, use ALS to set L to first argument load the global link as necessary Indirect call (for calls using IR & proc vars) push arguments on EU stack push the proc desc, then call via SFCI (PC & L are saved to IFU stack) at entry, IF nested THEN use SUBB to form static link ELSE use DIS to discard proc desc use ALS to set L to first argument load the global link as necessary Dragon Procedure Call Returning from a procedure store return values in local regs use RET to set S and return to caller (PC & L are restored from IFU stack) in caller, pop return values to destination variables Expected timing (via simulation) direct calls: < 1 indirect calls: < 2 Nested procedures In the parent parent is the scope declaring the nested proc proc desc body is placed in parent frame proc desc is addr of proc desc body When the proc desc is called 1. proc desc is left on the EU stack 2. subtracting the offset forms the static link 3. which is left above the argument words Stack handling Stack overflow detected by hardware EU stack overflow when push beyond limit IFU stack overflow at calls only dumps 1 frame into "nachos", then continues nachos fixed size (20 words: 16 regs + 4 linkage) resident (at least for now) large frames can use several nachos also store stack at process switch single mechanism => simpler possibly less efficient, though Stack underflow uses "bogus PC" which causes special address fault trap (no hardware detection) restores 1 frame from nachos, then continues Timing "typical" overflow/underflow pair: ~30 Fine points Short vs. Long argument & return records more than 12 words forces long arg record long arg record (> 12 words) allocated in caller's FX passed by reference long return record (> 4 words) allocated in caller's FX passed by reference (first argument) more efficient than PrincOps mechanism (but requires strict call/return discipline) Start traps uses "initial bogus link" which is fixed up when module starts (same mechanism as unbound procedure trap) open questions monitor locking desirable? disallow external calls until started? More fine points Loading modules new features 1. PC -> signal handler map 2. fixup of addresses in code & data 3. interface records Multiple global frames per module happens very rarely (soon, never?) can handle by copying the code