*----------------------------------------------------------- Title[Assign.mc...November 23, 1982 5:26 PM...Taft]; * Assignment instructions (PrincOps, chapter 7) *----------------------------------------------------------- % CONTENTS, by order of occurence Immediate instructions LIN1 Load Immediate Negative One LINI Load Immediate Negative Infinity LID0 Load Immediate Double Zero LIn Load Immediate n LIB Load Immediate Byte LINB Load Immediate Negative Byte LIHB Load Immediate High Byte LIW Load Immediate Word Frame instructions LAn Local Address n LAB Local Address Byte LAW Local Address Word LLn Load Local n LLB Load Local Byte LGn Load Global n LGB Load Global Byte LLDn Load Local Double n LLDB Load Local Double Byte LGDn Load Global Double n LGDB Load Global Double Byte SLn Store Local n SLB Store Local Byte SGB Store Global Byte SLDn Store Local Double n SLDB Store Local Double Byte SGDB Store Global Double Byte PLn Put Local n PLB Put Local Byte PLD0 Put Local Double Zero PLDB Put Local Double Byte AL0IB Add Local Zero to Immediate Byte GA0 Global Address n GAB Global Address Byte GAW Global Address Word Pointer instructions Rn Read n RB Read Byte RL0 Read Long Zero RLB Read Long Byte RD0 Read Double Zero RDB Read Double Byte RDL0 Read Double Long Zero RDLB Read Double Long Byte RC Read Code W0 Write Zero WB Write Byte WLB Write Long Byte WDB Write Double Byte WDLB Write Double Long Byte PSB Put Swapped Byte PSD0 Put Swapped Double Zero PSDB Put Swapped Double Byte PSLB Put Swapped Long Byte PSDLB Put Swapped Double Long Byte Contents (cont'd) RIL0n Read Local Indirect Zero n RLIP Read Local Indirect Pair RGIP Read Global Indirect Pair RLILP Read Local Indirect Long Pair RGILP Read Global Indirect Long Pair RLDI00 Read Local Double Indirect Zero Zero RLDIP Read Local Double Indirect Pair RLDILP Read Local Double Indirect Long Pair WLIP Write Local Indirect Pair WLILP Write Local Indirect Long Pair WLDILP Write Local Double Indirect Long Pair String instructions RS Read String RSL Read String Long WS Write String WSL Write String Long Field instructions RF Read Field R0F Read Zero Field RLF Read Long Field RL0F Read Long Zero Field RLFS Read Long Field Stack RCFS Read Code Field Stack RLIPF Read Local Indirect Pair Field RLILPF Read Local Indirect Long Pair Field WF Write Field W0F Write Zero Field WLF Write Long Field WL0F Write Long Zero Field WLFS Write Long Field Stack WS0F Write Swapped Zero Field PSF Put Swapped Field PS0F Put Swapped Zero Field PSLF Put Swapped Long Field Frequently-used exit sequences ExitPushT Push T onto the stack and exit ExitPushMD Push MD onto the stack and exit ExitPushIDPlusT Push ID+T onto the stack and exit ExitReadStackT Fetch word from address T, push it onto the stack, and exit ExitStackMDReadStackT Put MD on stack and then push word fetched from T on stack ExitWriteStackT Store word from stack to address T, pop the stack, and exit ExitWriteDoubleStackT Write 2 words from stack to address T and exit ExitCheckFault Check for fault and exit Subroutines BRHiGetsStackPop Executes BRHi← Stack&-1 BRLoGetsStack Executes BRLo← Stack FetchGetsT Executes PD← Fetch← T % TopLevel; *-------------------------------------------------------------------- IFUR[LIN1, 1]; * Load Immediate Negative One * Push[177777B]; *-------------------------------------------------------------------- Stack+1← T-T-1, NextOpcode; *-------------------------------------------------------------------- IFUR[LINI, 1]; * Load Immediate Negative Infinity * Push[100000B]; *-------------------------------------------------------------------- T← 100000C, Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[LID0, 1]; * Load Immediate Double Zero * PushLong[LONG[0]]; *-------------------------------------------------------------------- Stack+1← T← A0, Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[LI0, 1, N[0]]; * Load Immediate n IFUR[LI1, 1, N[1]]; IFUR[LI2, 1, N[2]]; IFUR[LI3, 1, N[3]]; IFUR[LI4, 1, N[4]]; IFUR[LI5, 1, N[5]]; IFUR[LI6, 1, N[6]]; IFUR[LI7, 1, N[7]]; IFUR[LI8, 1, N[10]]; IFUR[LI9, 1, N[11]]; IFUR[LI10, 1, N[12]]; * Push[n]; IFUR[LIB, 2]; * Load Immediate Byte * Push[GetCodeByte[]]; *-------------------------------------------------------------------- Stack+1← ID, NextOpcode; *-------------------------------------------------------------------- IFUR[LINB, 2]; * Load Immediate Negative Byte * Push[BytePair[377B, GetCodeByte[]]; *-------------------------------------------------------------------- T← (ID) OR (177400C), Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[LIHB, 2]; * Load Immediate High Byte * Push[BytePair[GetCodeByte[], 0]; *-------------------------------------------------------------------- T← ShiftRMask[RTemp0], RisID, Branch[ExitPushT]; * LSH[ID, 10] *-------------------------------------------------------------------- IFUR[LIW, 3]; * Load Immediate Word * Push[GetCodeWord[]]; *-------------------------------------------------------------------- T← ShiftRMask[RTemp0], RisID, * LSH[ID, 10] Branch[ExitPushIDPlusT]; *-------------------------------------------------------------------- IFUR[LA0, 1, N[0]]; * Local Address n IFUR[LA1, 1, N[1]]; IFUR[LA2, 1, N[2]]; IFUR[LA3, 1, N[3]]; IFUR[LA6, 1, N[6]]; IFUR[LA8, 1, N[10]]; * Push[LF + n]; IFUR[LAB, 2]; * Local Address Byte * Push[LF + GetCodeByte[]]; *-------------------------------------------------------------------- T← (ID)+(LFShadow), Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[LAW, 3]; * Local Address Word * Push[LF + GetCodeWord[]]; *-------------------------------------------------------------------- T← ShiftRMask[RTemp0], RisID; * LSH[ID, 10] T← (LFShadow)+T, Branch[ExitPushIDPlusT]; *-------------------------------------------------------------------- IFUR[LL0, 1, MemBase[LF], N[0]]; * Load Local n IFUR[LL1, 1, MemBase[LF], N[1]]; IFUR[LL2, 1, MemBase[LF], N[2]]; IFUR[LL3, 1, MemBase[LF], N[3]]; IFUR[LL4, 1, MemBase[LF], N[4]]; IFUR[LL5, 1, MemBase[LF], N[5]]; IFUR[LL6, 1, MemBase[LF], N[6]]; IFUR[LL7, 1, MemBase[LF], N[7]]; IFUR[LL8, 1, MemBase[LF], N[10]]; IFUR[LL9, 1, MemBase[LF], N[11]]; IFUR[LL10, 1, MemBase[LF], N[12]]; IFUR[LL11, 1, MemBase[LF], N[13]]; * Push[FetchMds[LF+n]↑]; IFUR[LLB, 2, MemBase[LF]]; * Load Local Byte * Push[FetchMds[LF+GetCodeByte[]]↑]; IFUR[LG0, 1, MemBase[GF], N[0]]; * Load Global n IFUR[LG1, 1, MemBase[GF], N[1]]; IFUR[LG2, 1, MemBase[GF], N[2]]; * Push[FetchMds[GF+n]↑]; IFUR[LGB, 2, MemBase[GF]]; * Load Global Byte * Push[FetchMds[GF+GetCodeByte[]]↑]; *-------------------------------------------------------------------- Fetch← ID, Branch[ExitPushMD]; *-------------------------------------------------------------------- IFUR[LLD0, 1, MemBase[LF], N[0]]; * Load Local Double n IFUR[LLD1, 1, MemBase[LF], N[1]]; IFUR[LLD2, 1, MemBase[LF], N[2]]; IFUR[LLD3, 1, MemBase[LF], N[3]]; IFUR[LLD4, 1, MemBase[LF], N[4]]; IFUR[LLD5, 1, MemBase[LF], N[5]]; IFUR[LLD6, 1, MemBase[LF], N[6]]; IFUR[LLD7, 1, MemBase[LF], N[7]]; IFUR[LLD8, 1, MemBase[LF], N[10]]; IFUR[LLD10, 1, MemBase[LF], N[12]]; * Push[FetchMds[LF+n]↑]; Push[FetchMds[LF+n+1]↑]; IFUR[LLDB, 2, MemBase[LF]]; * Load Local Double Byte * alpha: BYTE ← GetCodeByte[]; * Push[FetchMds[LF+alpha]↑]; Push[FetchMds[LF+alpha+1]↑]; IFUR[LGD0, 1, MemBase[GF], N[0]]; * Load Global Double n IFUR[LGD2, 1, MemBase[GF], N[2]]; * Push[FetchMds[GF+n]↑]; Push[FetchMds[GF+n+1]↑]; IFUR[LGDB, 2, MemBase[GF]]; * Load Global Double Byte * alpha: BYTE ← GetCodeByte[]; * Push[FetchMds[GF+alpha]↑]; Push[FetchMds[GF+alpha+1]↑]; *-------------------------------------------------------------------- T← (Fetch← ID)+1, StkP+1, Branch[ExitStackMDReadStackT]; *-------------------------------------------------------------------- IFUR[SL0, 1, MemBase[LF], N[0]]; * Store Local n IFUR[SL1, 1, MemBase[LF], N[1]]; IFUR[SL2, 1, MemBase[LF], N[2]]; IFUR[SL3, 1, MemBase[LF], N[3]]; * StoreMds[LF+n]↑ ← Pop[]; * These are different from the other SLn and SLB in that they don't need * to check for faults because references to the first 4 locals cannot fault. *-------------------------------------------------------------------- Store← ID, DBuf← Stack&-1, NextOpcode; *-------------------------------------------------------------------- IFUR[SL4, 1, MemBase[LF], N[4]]; * Store Local n IFUR[SL5, 1, MemBase[LF], N[5]]; IFUR[SL6, 1, MemBase[LF], N[6]]; IFUR[SL7, 1, MemBase[LF], N[7]]; IFUR[SL8, 1, MemBase[LF], N[10]]; IFUR[SL9, 1, MemBase[LF], N[11]]; IFUR[SL10, 1, MemBase[LF], N[12]]; * StoreMds[LF+n]↑ ← Pop[]; IFUR[SLB, 2, MemBase[LF]]; * Store Local Byte * StoreMds[LF+GetCodeByte[]]↑ ← Pop[]; IFUR[SGB, 2, MemBase[GF]]; * Store Global Byte * StoreMds[GF+GetCodeByte[]]↑ ← Pop[]; *-------------------------------------------------------------------- Store← ID, DBuf← Stack&-1, NextOpcodeCF; *-------------------------------------------------------------------- IFUR[SLD0, 1, MemBase[LF], N[1]]; * Store Local Double n IFUR[SLD1, 1, MemBase[LF], N[2]]; IFUR[SLD2, 1, MemBase[LF], N[3]]; IFUR[SLD3, 1, MemBase[LF], N[4]]; * StoreMds[LF+n+1]↑ ← Pop[]; StoreMds[LF+n]↑ ← Pop[]; * These are different from the other SLDn and SLDB in that they don't need * to check for faults because references to the first 4 locals cannot fault. * SLD3 actually references word 4 which can fault, but then references word 3 which * cannot itself fault but will force any fault on word 4 before the opcode exits. *-------------------------------------------------------------------- T← (Store← ID)-1, DBuf← Stack&-1; Store← T, DBuf← Stack&-1, NextOpcode; *-------------------------------------------------------------------- IFUR[SLD4, 1, MemBase[LF], N[5]]; * Store Local Double n IFUR[SLD5, 1, MemBase[LF], N[6]]; IFUR[SLD6, 1, MemBase[LF], N[7]]; IFUR[SLD8, 1, MemBase[LF], N[11]]; * StoreMds[LF+n+1]↑ ← Pop[]; StoreMds[LF+n]↑ ← Pop[]; *-------------------------------------------------------------------- T← (Store← ID)-1, DBuf← Stack&-1, Branch[ExitWriteStackT]; *-------------------------------------------------------------------- IFUR[SLDB, 2, MemBase[LF]]; * Store Local Double Byte * alpha: BYTE ← GetCodeByte[]; * StoreMds[LF+alpha+1]↑ ← Pop[]; StoreMds[LF+alpha]↑ ← Pop[]; IFUR[SGDB, 2, MemBase[GF]]; * Store Global Double Byte * alpha: BYTE ← GetCodeByte[]; * StoreMds[GF+alpha+1]↑ ← Pop[]; StoreMds[GF+alpha]↑ ← Pop[]; *-------------------------------------------------------------------- T← (ID)+1, Branch[ExitWriteDoubleStackT]; *-------------------------------------------------------------------- IFUR[PL0, 1, MemBase[LF], N[0]]; * Put Local n IFUR[PL1, 1, MemBase[LF], N[1]]; IFUR[PL2, 1, MemBase[LF], N[2]]; IFUR[PL3, 1, MemBase[LF], N[3]]; * StoreMds[LF+n]↑ ← Pop[]; SP ← SP+1; *-------------------------------------------------------------------- Store← ID, DBuf← Stack, NextOpcode; * Refs to first 4 locals cannot fault *-------------------------------------------------------------------- IFUR[PLB, 2, MemBase[LF]]; * Put Local Byte * StoreMds[LF+GetCodeByte[]]↑ ← Pop[]; SP ← SP+1; *-------------------------------------------------------------------- Store← ID, DBuf← Stack, NextOpcodeCF; *-------------------------------------------------------------------- IFUR[PLD0, 1, MemBase[LF], N[1]]; * Put Local Double Zero * StoreMds[LF+1]↑ ← Pop[]; StoreMds[LF]↑ ← Pop[]; *-------------------------------------------------------------------- T← (Store← ID)-1, DBuf← Stack&-1; Store← T, DBuf← Stack&+1, NextOpcode; * Refs to first 4 locals cannot fault *-------------------------------------------------------------------- IFUR[PLDB, 2, MemBase[LF]]; * Put Local Double Byte * alpha: BYTE ← GetCodeByte[]; * StoreMds[GF+alpha+1]↑ ← Pop[]; StoreMds[GF+alpha]↑ ← Pop[]; *-------------------------------------------------------------------- T← (ID)+1; T← (Store← T)-1, DBuf← Stack&-1; Store← T, DBuf← Stack&+1, NextOpcodeCF; *----------------------------------------------------------- IFUR[AL0IB, 2, MemBase[LF], N[0]]; * Add Local Zero to Immediate Byte * Push[FetchMds[LF]↑ + GetCodeByte[]]; *----------------------------------------------------------- Fetch← ID, StkP+1; Stack← (ID)+MD, NextOpcode; *-------------------------------------------------------------------- IFUR[GA0, 1, N[0]]; * Global Address n * Push[GF + n]; IFUR[GAB, 2]; * Global Address Byte * Push[GF + GetCodeByte[]]; *-------------------------------------------------------------------- T← (ID)+(GFShadow), Branch[ExitPushT]; *-------------------------------------------------------------------- IFUR[GAW, 3]; * Global Address Word * Push[GF + GetCodeWord[]]; *-------------------------------------------------------------------- T← ShiftRMask[RTemp0], RisID; * LSH[ID, 10] T← (GFShadow)+T, Branch[ExitPushIDPlusT]; *----------------------------------------------------------- IFUR[R0, 1, MemBase[MDS], N[0]]; * Read n IFUR[R1, 1, MemBase[MDS], N[1]]; * ptr: POINTER ← Pop[]; Push[FetchMds[ptr+n]↑]; IFUR[RB, 2, MemBase[MDS]]; * Read Byte * ptr: POINTER ← Pop[]; Push[FetchMds[ptr+GetCodeByte[]]↑]; *----------------------------------------------------------- IFetch← Stack&-1, Branch[ExitPushMD]; *----------------------------------------------------------- IFUR[RL0, 1, MemBase[LPtr], N[0]]; * Read Long Zero * ptr: LONG POINTER ← PopLong[]; Push[Fetch[ptr]↑]; IFUR[RLB, 2, MemBase[LPtr]]; * Read Long Byte * ptr: LONG POINTER ← PopLong[]; Push[Fetch[ptr+GetCodeByte[]]↑]; *----------------------------------------------------------- BRHi← Stack&-1, Call[BRLoGetsStack]; Fetch← ID, StkP-1, Branch[ExitPushMD]; *----------------------------------------------------------- IFUR[RD0, 1, MemBase[MDS], N[0]]; * Read Double Zero * ptr: POINTER ← Pop[]; * u: UNSPECIFIED ← FetchMds[ptr]↑; v: UNSPECIFIED ← FetchMds[ptr+1]↑; * Push[u]; Push[v]; IFUR[RDB, 2, MemBase[MDS]]; * Read Double Byte: * ptr: POINTER ← Pop[]; * u: UNSPECIFIED ← FetchMds[ptr+alpha]↑; v: UNSPECIFIED ← FetchMds[ptr+alpha+1]↑; * Push[u]; Push[v]; *----------------------------------------------------------- T← (IFetch← Stack)+T+1, TisID, Branch[RDLBTail]; *----------------------------------------------------------- IFUR[RDL0, 1, MemBase[LPtr], N[0]]; * Read Double Long Zero * ptr: LONG POINTER ← PopLong[]; * u: UNSPECIFIED ← Fetch[ptr]↑; v: UNSPECIFIED ← Fetch[ptr+1]↑; * Push[u]; Push[v]; IFUR[RDLB, 2, MemBase[LPtr]]; * Read Double Long Byte * alpha: BYTE ← GetCodeByte[]; ptr: LONG POINTER ← PopLong[]; * u: UNSPECIFIED ← Fetch[ptr+LONG[alpha]]↑; v: UNSPECIFIED ← Fetch[ptr+LONG[alpha]+1]↑; * Push[u]; Push[v]; *----------------------------------------------------------- BRHi← Stack&-1, Call[BRLoGetsStack]; T← (Fetch← ID)+1; * Note: must not clobber stack with first word until we know the fetch of * the second word won't fault. RDLBTail: Fetch← T, T← MD; Stack← T, T← MD, Branch[ExitPushT]; *----------------------------------------------------------- NewOp; ESCEntry[RC], * Read Code * Push[ReadCode[Pop[]+GetCodeByte[]]]; *----------------------------------------------------------- T← (ID)+(Stack&-1), MemBase← CB, Branch[ExitReadStackT]; *----------------------------------------------------------- IFUR[W0, 1, MemBase[MDS], N[0]]; * Write Zero * ptr: POINTER ← Pop[]; StoreMds[ptr]↑ ← Pop[]; IFUR[WB, 2, MemBase[MDS]]; * Write Byte * ptr: POINTER ← Pop[]; StoreMds[ptr+GetCodeByte[]]↑ ← Pop[]; *----------------------------------------------------------- T← (ID)+(Stack&-1), Branch[ExitWriteStackT]; *----------------------------------------------------------- IFUR[WLB, 2, MemBase[LPtr]]; * Write Long Byte * ptr: LONG POINTER ← PopLong[]; Store[ptr+LONG[GetCodeByte[]]]↑ ← Pop[]; *----------------------------------------------------------- BRHi← Stack&-1; BRLo← Stack&-1, Branch[@SL4]; *----------------------------------------------------------- IFUR[WDB, 2, MemBase[MDS]]; * Write Double Byte * alpha: BYTE ← GetCodeByte[]; ptr: POINTER ← Pop[]; * StoreMds[ptr+alpha+1]↑ ← Pop[]; StoreMds[ptr+alpha]↑ ← Pop[]; *----------------------------------------------------------- T← (ID)+(Stack&-1)+1, Branch[ExitWriteDoubleStackT]; *----------------------------------------------------------- IFUR[WDLB, 2, MemBase[LPtr]]; * Write Double Long Byte * alpha: BYTE ← GetCodeByte[]; ptr: LONG POINTER ← PopLong[]; * Store[ptr+LONG[alpha]+1]↑ ← Pop[]; Store[ptr+LONG[alpha]]↑ ← Pop[]; *----------------------------------------------------------- BRHi← Stack&-1; BRLo← Stack&-2; T← (Store← ID)+1, DBuf← Stack&+1; Store← T, DBuf← Stack&-2, NextOpcodeCF; *----------------------------------------------------------- IFUR[PSB, 2, MemBase[MDS]]; * Put Swapped Byte * u: UNSPECIFIED ← Pop[]; ptr: POINTER ← Pop[]; * StoreMds[ptr+GetCodeByte[]]↑ ← u; SP ← SP+1; *----------------------------------------------------------- StkP-1; T← (ID)+(Stack&+1), Branch[ExitWriteStackT]; *----------------------------------------------------------- IFUR[PSD0, 1, MemBase[MDS], N[0]]; * Put Swapped Double Zero * u: UNSPECIFIED ← Pop[]; v: UNSPECIFIED ← Pop[]; ptr: POINTER ← Pop[]; * StoreMds[ptr+1]↑ ← v; StoreMds[ptr]↑ ← u; SP ← SP+1; IFUR[PSDB, 2, MemBase[MDS]]; * Put Swapped Double Byte * alpha: BYTE ← GetCodeByte[]; * u: UNSPECIFIED ← Pop[]; v: UNSPECIFIED ← Pop[]; ptr: POINTER ← Pop[]; * StoreMds[ptr+alpha+1]↑ ← v; StoreMds[ptr+alpha]↑ ← u; SP ← SP+1; *----------------------------------------------------------- StkP-2; T← (ID)+(Stack&+2)+1, Branch[ExitWriteDoubleStackT]; *----------------------------------------------------------- IFUR[PSLB, 2, MemBase[LPtr]]; * Put Swapped Long Byte * u: UNSPECIFIED ← Pop[]; ptr: LONG POINTER ← PopLong[]; * Store[ptr+LONG[GetCodeByte[]]]↑ ← u; SP ← SP+2; *----------------------------------------------------------- T← ID, StkP-1, Call[BRHiGetsStackPop]; BRLo← Stack&+2, Branch[ExitWriteStackT]; *----------------------------------------------------------- IFUR[PSDLB, 2, MemBase[LPtr]]; * Put Swapped Double Long Byte * alpha: BYTE ← GetCodeByte[]; * u: UNSPECIFIED ← Pop[]; v: UNSPECIFIED ← Pop[]; ptr: LONG POINTER ← PopLong[]; * Store[ptr+LONG[alpha]+1]↑ ← v; Store[ptr+LONG[alpha]]↑ ← u; SP ← SP+2; *----------------------------------------------------------- T← (ID)+1, StkP-2, Call[BRHiGetsStackPop]; BRLo← Stack&+3, Branch[ExitWriteDoubleStackT]; *----------------------------------------------------------- IFUR[RLI00, 1, MemBase[LF], N[0]]; * Read Local Indirect Zero n IFUR[RLI01, 1, MemBase[LF], N[1]]; IFUR[RLI02, 1, MemBase[LF], N[2]]; IFUR[RLI03, 1, MemBase[LF], N[3]]; * ptr: POINTER ← FetchMds[LF]↑; Push[FetchMds[ptr+n]↑]; *----------------------------------------------------------- Fetch← 0S, Branch[RxIPTail]; *----------------------------------------------------------- IFUR[RLIP, 2, MemBase[LF], PackedAlpha]; * Read Local Indirect Pair * pair: NibblePair ← GetCodeByte[]; * ptr: POINTER ← FetchMds[LF+pair.left]↑; Push[FetchMds[ptr+pair.right]↑]; IFUR[RGIP, 2, MemBase[GF], PackedAlpha]; * Read Global Indirect Pair * pair: NibblePair ← GetCodeByte[]; * ptr: POINTER ← FetchMds[GF+pair.left]↑; Push[FetchMds[ptr+pair.right]↑]; *----------------------------------------------------------- Fetch← ID; * Fetch from xF+pair.left RxIPTail: RTemp0← MD, MemBase← MDS; IFetch← RTemp0, Branch[ExitPushMD]; * Fetch from MDS+MD+pair.right *----------------------------------------------------------- IFUR[RLILP, 2, MemBase[LF], PackedAlpha]; * Read Local Indirect Long Pair * pair: NibblePair ← GetCodeByte[]; * ptr: LONG POINTER ← FetchDblMds[LF+pair.left]↑; * Push[Fetch[ptr+LONG[pair.right]]↑]; IFUR[RGILP, 2, MemBase[GF], PackedAlpha]; * Read Global Indirect Long Pair * pair: NibblePair ← GetCodeByte[]; * ptr: LONG POINTER ← FetchDblMds[GF+pair.left]↑; * Push[Fetch[ptr+LONG[pair.right]]↑]; *----------------------------------------------------------- T← (Fetch← ID)+1, Call[LongIndirectAddress]; Fetch← ID, Branch[ExitPushMD]; *----------------------------------------------------------- IFUR[RLDI00, 1, MemBase[LF], N[0]]; * Read Local Double Indirect Zero Zero * ptr: POINTER ← FetchMds[LF]↑; * u: UNSPECIFIED ← FetchMds[ptr]↑; v: UNSPECIFIED ← FetchMds[ptr+1]↑; * Push[u]; Push[v]; *----------------------------------------------------------- Fetch← 0S, StkP+1, Branch[RLDIPTail]; *----------------------------------------------------------- IFUR[RLDIP, 2, MemBase[LF], PackedAlpha]; * Read Local Double Indirect Pair * pair: NibblePair ← GetCodeByte[]; * ptr: POINTER ← FetchMds[LF+pair.left]↑; * u: UNSPECIFIED ← FetchMds[ptr+pair.right]↑; v: UNSPECIFIED ← FetchMds[ptr+pair.right+1]↑; * Push[u]; Push[v]; *----------------------------------------------------------- Fetch← ID, StkP+1; * Fetch from LF+pair.left RLDIPTail: RTemp0← MD, MemBase← MDS; T← (IFetch← RTemp0)+T+1, TisID, * Fetch from MDS+MD+pair.right Branch[ExitStackMDReadStackT]; *----------------------------------------------------------- IFUR[RLDILP, 2, MemBase[LF], PackedAlpha]; * Read Local Double Indirect Long Pair * pair: NibblePair ← GetCodeByte[]; * ptr: LONG POINTER ← FetchDblMds[LF+pair.left]↑; * u: UNSPECIFIED ← FetchMds[ptr+pair.right]↑; v: UNSPECIFIED ← FetchMds[ptr+pair.right+1]↑; * Push[u]; Push[v]; *----------------------------------------------------------- T← (Fetch← ID)+1, Call[LongIndirectAddress]; * Fetch from LF+pair.left T← (Fetch← ID)+1, StkP+1, * Fetch from LPtr+pair.right Branch[ExitStackMDReadStackT]; *----------------------------------------------------------- IFUR[WLIP, 2, MemBase[LF], PackedAlpha]; * Write Local Indirect Pair * pair: NibblePair ← GetCodeByte[]; * ptr: POINTER ← FetchMds[L+pair.left]↑; StoreMds[ptr+pair.right]↑ ← Pop[]; *----------------------------------------------------------- Fetch← ID; T← (ID)+MD, MemBase← MDS, Branch[ExitWriteStackT]; *----------------------------------------------------------- IFUR[WLILP, 2, MemBase[LF], PackedAlpha]; * Write Local Indirect Long Pair * pair: NibblePair ← GetCodeByte[]; * ptr: LONG POINTER ← FetchDblMds[L+pair.left]↑; StoreMds[ptr+pair.right]↑ ← Pop[]; *----------------------------------------------------------- T← (Fetch← ID)+1, Call[LongIndirectAddress]; Store← ID, DBuf← Stack&-1, NextOpcodeCF; *----------------------------------------------------------- IFUR[WLDILP, 2, MemBase[LF], PackedAlpha]; * Write Local Double Indirect Long Pair * pair: NibblePair ← GetCodeByte[]; * ptr: LONG POINTER ← FetchDblMds[L+pair.left]↑; * Store[ptr+LONG[pair.right]+1]↑ ← Pop[]; Store[ptr+LONG[pair.right]]↑ ← Pop[]; *----------------------------------------------------------- T← (Fetch← ID)+1, Call[LongIndirectAddress]; T← (ID)+1, Branch[ExitWriteDoubleStackT]; *----------------------------------------------------------- LongIndirectAddress: * Base register setup for long indirect instructions * Entry conditions: * T = address of high word of long pointer (relative to current MemBase) * MD = low word of long pointer * Exit conditions: * MemBase = LPtr, containing the long pointer *----------------------------------------------------------- Subroutine; T← MD, Fetch← T; MemBase← LPtr; T← MD, BRLo← T; BRHi← T, Return; TopLevel; *----------------------------------------------------------- IFUR[RS, 2, MemBase[MDS]]; * Read String * index: CARDINAL ← Pop[]; ptr: POINTER ← Pop[]; * offset: CARDINAL ← GetCodeByte[]+index; word: BytePair ← FetchMds[ptr+offset/2]↑; * Push[IF (offset MOD 2)=0 THEN word.left ELSE word.right]; *----------------------------------------------------------- * Note: the Multiply in the following instructions has the effect of, e.g.: * T← ((ID)+(Stack&-1)) RSH 1 * and additionally the result bit shifted out is captured in Q[0]. * The operation must not generate a carry, and the Q[14] dispatch generated * as a side-effect of Multiply must be neutralized (this is done in StringSetup). T← (ID)+(Stack&-1), Multiply, * T← (index+alpha)/2 Call[StringSetup]; * Returns with ALU = Q T← MD, StkP+1, DblBranch[RLSEven, RLSOdd, ALU>=0]; *----------------------------------------------------------- IFUR[RLS, 2, MemBase[LPtr]]; * Read Long String * index: CARDINAL ← Pop[]; ptr: LONG POINTER ← PopLong[]; * offset: CARDINAL ← GetCodeByte[]+index; word: BytePair ← Fetch[ptr+LONG[offset/2]]↑; * Push[IF (offset MOD 2)=0 THEN word.left ELSE word.right]; *----------------------------------------------------------- T← (ID)+(Stack&-1), Multiply, * T← (index+alpha)/2 Call[LongStringSetup]; * Returns with ALU = Q T← MD, StkP+1, DblBranch[RLSEven, RLSOdd, ALU>=0]; RLSEven: Stack← RSH[T, 10], NextOpcode; RLSOdd: Stack← T AND (377C), NextOpcode; *----------------------------------------------------------- IFUR[WS, 2, MemBase[MDS]]; * Write String * index: CARDINAL ← Pop[]; ptr: POINTER ← Pop[]; data: BYTE ← LowByte[Pop[]]; * offset: CARDINAL ← GetCodeByte[]+index; word: BytePair ← FetchMds[ptr+offset/2]↑; * StoreMds[ptr+offset/2]↑ ← * IF (offset MOD 2)=0 THEN BytePair[data, word.right] ELSE BytePair[word.left, data]; *----------------------------------------------------------- T← (ID)+(Stack&-1), Multiply, * T← (index+alpha)/2 Call[StringSetup]; * Returns with ALU = Q RTemp0← T, DblBranch[WLSEven, WLSOdd, ALU>=0]; *----------------------------------------------------------- IFUR[WLS, 2, MemBase[LPtr]]; * Write Long String * index: CARDINAL ← Pop[]; ptr: LONG POINTER ← PopLong[]; data: BYTE ← LowByte[Pop[]]; * offset: CARDINAL ← GetCodeByte[]+index; word: BytePair ← Fetch[ptr+LONG[offset/2]]↑; * Store[ptr+LONG[offset/2]]↑ ← * IF (offset MOD 2)=0 THEN BytePair[data, word.right] ELSE BytePair[word.left, data]; *----------------------------------------------------------- T← (ID)+(Stack&-1), Multiply, * T← (index+alpha)/2 Call[LongStringSetup]; * Returns with ALU = Q RTemp0← T, DblBranch[WLSEven, WLSOdd, ALU>=0]; WLSEven: T← DPF[Stack&-1, 10, 10, MD], Branch[WLFTail4]; WLSOdd: T← DPF[Stack&-1, 10, 0, MD], Branch[WLFTail4]; *----------------------------------------------------------- StringSetup: * Enter: T = (alpha+index)/2; Q[0] = (alpha+index) MOD 2 * Stack[StkP] = ptr * MemBase = MDS * Multiply dispatch pending * Exit: T = ptr + (alpha+index)/2 * MD = FetchMds[T]↑ * ALU = Q * Stack popped 1 *----------------------------------------------------------- Subroutine; T← T+(Stack&-1), Branch[StringSetupTail]; * T← ptr + (index+alpha)/2 *----------------------------------------------------------- LongStringSetup: * Enter: T = (alpha+index)/2; Q[0] = (alpha+index) MOD 2 * Stack[StkP] = high half of ptr * Stack[StkP-1] = low half of ptr * MemBase = LPtr * Multiply dispatch pending * Exit: T unchanged * LPtr = ptr * MD = Fetch[ptr+T]↑ * ALU = Q * Stack popped 2 *----------------------------------------------------------- Subroutine; BRHi← Stack&-1; BRLo← Stack&-1, DispTable[1, 2, 2]; * Neutralize Multiply dispatch StringSetupTail: PD← Q, Fetch← T, Return, DispTable[1, 2, 2]; * Neutralize Multiply dispatch (StringSetup) TopLevel; *----------------------------------------------------------- IFUR[RF, 3, MemBase[MDS]]; * Read Field * offset: BYTE ← GetCodeByte[]; spec: FieldSpec ← GetCodeByte[]; * ptr: POINTER ← Pop[]; * Push[ReadField[FetchMds[ptr+offset]↑, spec]]; IFUR[R0F, 2, MemBase[MDS], N[0]]; * Read Zero Field * spec: FieldSpec ← GetCodeByte[]; * ptr: POINTER ← Pop[]; * Push[ReadField[FetchMds[ptr]↑, spec]]; *----------------------------------------------------------- T← (ID)+(Stack); RFTail: Fetch← T, Q← StdShC, Branch[RLFTail2]; *----------------------------------------------------------- IFUR[RLF, 3, MemBase[LPtr]]; * Read Long Field * offset: BYTE ← GetCodeByte[]; spec: FieldSpec ← GetCodeByte[]; * ptr: LONG POINTER ← PopLong[]; * Push[ReadField[Fetch[ptr+LONG[offset]]↑, spec]]; IFUR[RL0F, 2, MemBase[LPtr], N[0]]; * Read Long Zero Field * spec: FieldSpec ← GetCodeByte[]; * ptr: LONG POINTER ← PopLong[]; * Push[ReadField[Fetch[ptr]↑, spec]]; *----------------------------------------------------------- BRHi← Stack&-1, Call[BRLoGetsStack]; RLFTail1: Fetch← ID, Q← StdShC; RLFTail2: Stack← MD, RF← ID; RLFTail3: Stack← ShiftLMask[Stack], ShC← Q, NextOpcode; *----------------------------------------------------------- IFUR[RLFS, 1, MemBase[LPtr]]; * Read Long Field Stack * desc: FieldDesc ← Pop[]; * ptr: LONG POINTER ← PopLong[]; * Push[ReadField[Fetch[ptr+LONG[desc.offset]]↑, desc.field]]; *----------------------------------------------------------- T← RSH[Stack&-1, 10], Call[BRHiGetsStackPop]; * T← offset BRLo← Stack&+2; Fetch← T, T← Stack&-2, Branch[RCFSTail]; *----------------------------------------------------------- NewOp; ESCEntry[RCFS], * Read Code Field Stack * desc: FieldDesc ← Pop[]; offset: CARDINAL ← Pop[]; * Push[ReadField[ReadCode[offset+desc.offset], desc.field]]; *----------------------------------------------------------- T← ShiftLMask[Stack&-1]; * T← offset = RSH[T, 10] (ESCEntry: T=Stack[StkP]) T← (Stack&+1)+T, MemBase← CB; Fetch← T, T← Stack&-1; RCFSTail: Q← StdShC; Stack← T← B← MD, RF← T, * No ShC R/T select, so data must be in R and T Branch[RLFTail3]; *----------------------------------------------------------- IFUR[RLIPF, 3, MemBase[LF], PackedAlpha]; * Read Local Indirect Pair Field * pair: NibblePair ← GetCodeByte[]; spec: FieldSpec ← GetCodeByte[]; * ptr: POINTER ← FetchMds[LF+pair.left]↑; * Push[ReadField[FetchMds[ptr+pair.right]↑, spec]]; *----------------------------------------------------------- Fetch← ID, StkP+1; * Fetch from LF+pair.left T← (ID)+MD, MemBase← MDS, Branch[RFTail]; * T← ptr+pair.right *----------------------------------------------------------- IFUR[RLILPF, 3, MemBase[LF], PackedAlpha]; * Read Local Indirect Long Pair Field * pair: NibblePair ← GetCodeByte[]; spec: FieldSpec ← GetCodeByte[]; * ptr: LONG POINTER ← FetchDblMds[LF+pair.left]↑; * Push[ReadField[Fetch[ptr+LONG[pair.right]]↑, spec]]; *----------------------------------------------------------- T← (Fetch← ID)+1, StkP+1; * Fetch from LF+pair.left Fetch← T, Stack&+1← MD; * Push ptr onto stack Stack← MD, MemBase← LPtr, Branch[@RLF]; * Pretend ptr came from stack originally *----------------------------------------------------------- IFUR[WF, 3, MemBase[MDS]]; * Write Field * offset: BYTE ← GetCodeByte[]; spec: FieldSpec ← GetCodeByte[]; * ptr: POINTER ← Pop[]; data: UNSPECIFIED ← Pop[]; * StoreMds[ptr+offset]↑ ← WriteField[FetchMds[ptr+offset]↑, spec, data]; IFUR[W0F, 2, MemBase[MDS], N[0]]; * Write Zero Field * spec: FieldSpec ← GetCodeByte[]; * ptr: POINTER ← Pop[]; data: UNSPECIFIED ← Pop[]; * StoreMds[ptr]↑ ← WriteField[FetchMds[ptr]↑, spec, data]; *----------------------------------------------------------- T← (ID)+(Stack&-1); WFTail: Fetch← T, Q← StdShC, Branch[WLFTail2]; *----------------------------------------------------------- IFUR[WLF, 3, MemBase[LPtr]]; * Write Long Field * offset: BYTE ← GetCodeByte[]; spec: FieldSpec ← GetCodeByte[]; * ptr: LONG POINTER ← PopLong[]; data: UNSPECIFIED ← Pop[]; * Store[ptr+offset]↑ ← WriteField[Fetch[ptr+LONG[offset]]↑, spec, data]; IFUR[WL0F, 2, MemBase[LPtr], N[0]]; * Write Long Zero Field * spec: FieldSpec ← GetCodeByte[]; * ptr: LONG POINTER ← PopLong[]; data: UNSPECIFIED ← Pop[]; * Store[ptr]↑ ← WriteField[FetchMds[ptr]↑, spec, data]; *----------------------------------------------------------- BRHi← Stack&-1; BRLo← Stack&-1; WLFTail1: T← Fetch← ID, Q← StdShC; WLFTail2: RTemp0← T, WF← ID; WLFTail3: T← ShMDBothMasks[Stack&-1], ShC← Q; WLFTail4: Store← RTemp0, DBuf← T, NextOpcodeCF; *----------------------------------------------------------- IFUR[WLFS, 1, MemBase[LPtr]]; * Write Long Field Stack * desc: FieldDesc ← Pop[]; * ptr: LONG POINTER ← PopLong[]; data: UNSPECIFIED ← Pop[]; * Store[ptr+desc.offset]↑ ← WriteField[Fetch[ptr+LONG[desc.offset]]↑, desc.spec, data]; *----------------------------------------------------------- T← WF← Stack&-1, Call[BRHiGetsStackPop]; * T← offset,,desc, WF← desc BRLo← Stack&-1; T← RTemp0← RSH[T, 10]; * T← offset Fetch← T, T← Stack; * No ShC R/T select, so data must be in R and T Q← StdShC, Branch[WLFTail3]; *----------------------------------------------------------- IFUR[WS0F, 2, MemBase[MDS]]; * Write Swapped Zero Field * spec: FieldSpec ← GetCodeByte[]; * data: UNSPECIFIED ← Pop[]; ptr: POINTER ← Pop[]; * StoreMds[ptr]↑ ← WriteField[FetchMds[ptr]↑, spec, data]; *----------------------------------------------------------- WF← ID, StkP-1; RTemp0← Fetch← Stack&+1; Q← StdShC; T← ShMDBothMasks[Stack&-2], ShC← Q, Branch[WLFTail4]; *----------------------------------------------------------- IFUR[PSF, 3, MemBase[MDS]]; * Put Swapped Field * offset: BYTE ← GetCodeByte[]; spec: FieldSpec ← GetCodeByte[]; * data: UNSPECIFIED ← Pop[]; ptr: POINTER ← Pop[]; * StoreMds[ptr+offset]↑ ← WriteField[FetchMds[ptr+offset]↑, spec, data]; SP ← SP+1; IFUR[PS0F, 2, MemBase[MDS], N[0]]; * Put Swapped Zero Field * spec: FieldSpec ← GetCodeByte[]; * data: UNSPECIFIED ← Pop[]; ptr: POINTER ← Pop[]; * StoreMds[ptr]↑ ← WriteField[FetchMds[ptr]↑, spec, data]; SP ← SP+1; *----------------------------------------------------------- StkP-1; T← (ID)+(Stack&+1), Branch[WFTail]; *----------------------------------------------------------- IFUR[PSLF, 3, MemBase[LPtr]]; * Put Swapped Long Field * offset: BYTE ← GetCodeByte[]; spec: FieldSpec ← GetCodeByte[]; * data: UNSPECIFIED ← Pop[]; ptr: LONG POINTER ← PopLong[]; * Store[ptr+offset]↑ ← WriteField[Fetch[ptr+LONG[offset]]↑, spec, data]; SP ← SP+2; *----------------------------------------------------------- StkP-1, Call[BRHiGetsStackPop]; BRLo← Stack&+2, Branch[WLFTail1]; * Frequently-used exit sequences *----------------------------------------------------------- ExitPushT: * Push T onto the stack and exit *----------------------------------------------------------- Stack+1← T, NextOpcode, Global; *----------------------------------------------------------- ExitPushMD: * Push MD onto the stack and exit *----------------------------------------------------------- Stack+1← MD, NextOpcode, Global; *----------------------------------------------------------- ExitPushIDPlusT: * Push ID+T onto the stack and exit *----------------------------------------------------------- Stack+1← (ID)+T, NextOpcode; *----------------------------------------------------------- ExitReadStackT: * Fetch word from address T, push it onto the stack, and exit *----------------------------------------------------------- Fetch← T, Branch[ExitPushMD], Global; *----------------------------------------------------------- ExitStackMDReadStackT: * Put MD on stack and then push word fetched from T on stack *----------------------------------------------------------- Stack← MD, Fetch← T, Branch[ExitPushMD]; *----------------------------------------------------------- ExitWriteStackT: * Store word from stack to address T, pop the stack, and exit *----------------------------------------------------------- Store← T, DBuf← Stack&-1, NextOpcodeCF, Global; *----------------------------------------------------------- ExitWriteDoubleStackT: * Store double word from stack to address (T-1), pop the stack, and exit. * Precisely: Stack[StkP] is stored at T, Stack[StkP-1] is stored at T-1, * and StkP is decremented by 2. *----------------------------------------------------------- T← (Store← T)-1, DBuf← Stack&-1, Branch[ExitWriteStackT]; *----------------------------------------------------------- ExitCheckFault: * Check for fault and exit * Branched to by all NextOpcodeCF after Store← which might fault. *----------------------------------------------------------- T← MD, NextOpcode, Global; * Subroutines *----------------------------------------------------------- BRHiGetsStackPop: * Executes BRHi← Stack&-1 *----------------------------------------------------------- Subroutine; BRHi← Stack&-1, Return, Global; *----------------------------------------------------------- BRLoGetsStack: * Executes BRLo← Stack *----------------------------------------------------------- Subroutine; BRLo← Stack, Return, Global; *----------------------------------------------------------- FetchGetsT: * Executes PD← Fetch← T *----------------------------------------------------------- Subroutine; PD← Fetch← T, Return, Global;