;-*- Mode:Text -*- 22 bit PC: 4MW, 32MB instructions do 22 or 23 if going through map; else 21 is enough. to-do: 1. static low memory, short calls, open-call, t-open-call 2. select old / new frame addresses for destinations 3. meaning of return-destination code vs. destination code return PC saved in Hram: always PC+1 ? call-0: in parallel with normal alu op. 8-10 bit vector same hardware as traps? filled with normal cache "valid" bit status etc.? or single valid bit for whole area? assuming ret-dest register? holds last ret-dest read/written from Hram? add push / pop of return destination to all call / return stuff. figure out when dest-addr reg is clocked. check address setup time for Hram and freelist writes. common stuff so far: H addressed by active for all second cycles? ret-dest clocked every cycle? ;;;; call hardware operations start on the mid-instruction 35ns clock; some complete in one half-cycle, others take both. do any take more than two cycles? all instructions get old frames as sources? by "default", destinations get the new frames. sometimes want old frames as destinations? next instruction always gets new frames. return-destination always gets restored state (state as of before the call). return-then-open: what frames for destination? (between return and open vs. after open?) try bidirectional / tri-state paths for Hram and frame passing ;;;; ALU requires a DEST field: N-bits for frame-select (open, active, return, global ...) 4 bits for offset within frame CALL requires a return-destination: N-bit frame-select; 4-bit offset. RETURN uses return-destination frame and offset as destination instead of normal DEST. CALL has two dest fields: dest and ret-dest RETURN needs no dest field: dest is overridden by ret-dest; ret-dest is unused? does RETURN use same frame-select-space for return-destination field as an ALU op uses for DEST? reg addr mux select input was using clock to select source / dest fields; still select source addrs during read cycle, now select dest or ret-dest during write. normal dest is always from IR; ret-dest is from ret-dest ram output, possibly through ret-dest reg. use ret-dest reg for indirect dest? brute-force: reg addr mux was two-input, selected by clock. source / dest reg addr. now is four-input, selected by clock and ch-op. source / source / dest / ret-dest ? dest is already delayed two clocks from IR to write-cycle; ret-dest is popped from Hret-dest by return instruction. dest is from IR of return instruction; delay twice to get to write cycle. that ret-dest will be selected is known at IR of return instruction, but ret-dest value is not popped from Hret-dest until clock at end of IR cycle, so it is really delayed only one clock. return frame is only valid until next open (same frame is allocated again); would a previous-active option for the active frame reg work OK? ;;;;;;;;;;;;;;;; Frames available as source and destination bases: Open: Frame to store arguments for function that is about to be called. Active: Frame for current function local variables and the arguments the function was called with. Return: Frame in which to store values to be returned by the active function. Global: Frame number comes from instruction. and possibly: Return-destination: Frame and offset come from H(active)-return-dest. (no latch) Indirect: Frame and offset is from previously computed value. ;;;;;;;;;;;;;;;; Function-call operations: Open: Create a new open frame in preparation for a function call. 1. save open and active frames in H(free). 2. allocate a new open frame. Source: before (open frame should not be sourced) Dest: after asserted during second cycle: H(free) <- active, open clocked at end of second cycle: open <- free increment free-pointer Call: Call a function. Make the current open frame become the active frame. IR bits for one source and for ALU operation are used for PC; ALU op or external path is wired to connect source and dest. (use one source and byte op; not ALU op) 1. copy open frame pointer to active frame. (active was saved in OPEN) 2. save the (return) PC and return-destination in the H(active). (new active) 3. jump (set pc) to the code for the function to be called. Source: before (for new active, use open?) Dest: after. (ever write into old active?) clocked at start of second cycle: active <- open asserted during second cycle: H(active) <- current PC, return-destination side effects: next PC selected is 24-bit addr from IR. use separate registers for active-to-ALU and active-to-HRAM. Open-call: Create a new open frame, make it the active frame and call a function. Useful for calling single-argument functions: one instruction can compute an argument into the new open/active frame, store a return-destination, and call a function. Requires lots of IR bits ... 1. save open, active, return PC and ret-dest in H(free). 2. allocate a new open frame and also copy it to active. 3. jump (set PC) to the function to be called. Source: Dest: asserted during second cycle: H(free) <- active, open, ret-PC, ret-dest clocked at end of second cycle: open<- free increment free-pointer clocked at end of next first cycle: (if free can't go directly to open) active <- open Return: Restore the frame environment to that prior to the preceding CALL. Force the return-destination to be used as the dest. 1. copy active frame pointer to return frame. (makes return values addressable through return frame) 2. push active frame pointer onto frame freelist. 3. pop open, active, PC and return-destination saved by preceding CALL. Source: before Dest: after; is forced to be the return-destination. clocked at start of second cycle: return <- active decrement free-pointer asserted during second cycle: free <- active (check free-pointer setup before write) H addressed by active clocked at end of second cycle: retd, pc, active, open <- H(active) (retd is stored in dest-addr reg) Tail-recursive-open: Copy the current open frame into a new frame, in preparation for a tail-recursive call, which will throw away the active frame as if returning and then start a new call by copying open to active. 1. pop open and active frames and PC saved by preceding CALL; save in temporary regs so as to not trash current open, active and PC. 2. allocate a new open frame 3. push temporary open, active and PC in location spec. by the new open frame. Source: before (open should not be sourced) Dest: after asserted during second cycle: H addressed by active clocked at end of second cycle: pctemp, activetemp, open <- H(active) asserted during next first cycle: H(free) <- pctemp, activetemp, open clocked at end of next first cycle: (start of next second cycle) open <- free increment free-pointer Tail-recursive-call: Call a function. Discard the active frame as if returning, and make the current open frame become the active frame. 0. save ret-dest from H(active) in ret-dest-temp ret-dest-temp register, or what? 1. push active frame pointer onto frame freelist 2. copy the open frame pointer to the active frame. 3. copy ret-dest-temp to new H(active) 4. jump (set pc) to the code for the function to be called. Source: before (for new active, use open) Dest: after assumed asserted at during first cycle: H addressed by active clocked at start of second cycle: ret-dest <- H(active) decrement free-pointer asserted during second cycle: free <- active clocked at end of second cycle: active <- open asserted during next first cycle: H(active) <- ret-dest side effects: next PC selected is 24 bits from IR return-then-open: Return as specified by the return PC and return-destination return code, but open a new frame "below" the current active frame. The new frame becomes the open frame; the saved open and active frames from the frame above are saved in H(new-open-frame). The saved active frame becomes the active frame. Do part of RETURN that restores PC and open frame. Preserve active frame; copy return value for active frame directly into a new (free) frame. Open a new frame and store this active and the open frames in the Hram indexed by it. Copy the active frame to the return frame; push the active frame onto the freelist. Copy the saved active frame to the active frame. 1. Pop open and active frames and PC saved in H(active) by preceding CALL, into open, activetemp and PC. 2. allocate a new open frame. 3. save the open and activetemp frames H(open). 4. copy the active frame pointer to the return frame. 5. push the active frame pointer onto the frame freelist. 6. copy the activetemp frame to the active frame. return-then-tail-recursive-open Do a return as specified by a return-destination return code, but t-open a new frame "below" the current active frame and make it be the active frame. Do part of RETURN that restores PC and open frame. Preserve active frame; copy return value for active frame directly into a new (free) frame. Open this new frame and store the return-active and open frames in the Hram indexed by it. Copy the active frame to the return frame; Push the active frame onto the freelist. Copy the return-active frame to the active frame. 1. Pop open and active frames and PC saved by preceding CALL into open, activetemp and PC. 2. allocate a new open frame. 3. copy the saved active, open and PC from H(activetemp) to H(free). 4. copy the active frame pointer to the return frame. 5. push the active frame pointer onto the frame freelist. 6. copy the activetemp frame to the active frame. cancel-open: Undo an open. 1. push the open frame on the freelist. 2. restore active and open from H(open). ;;;;;;;;;;;;;;;; call-hardware operations directly executable from IR: open call open-call return t-open t-call t-open-call call-hardware operations executable only as return-destinations: no-op (normal return) return-then-open return-then-t-open call-hardware operations that specify a return-destination: call open-call call-hardware frame-select inputs: open active return global old-frame-state select inputs: previous open-frame before this instruction open frame in between return-then-open open frame after return-then-open active ...?