{File name FixedLoadStore.mc Description: Mesa Load and Store op-codes Author: Sandman Created: February 16, 1980 Last edited: Fiala 16-May-86 15:10:04 Sturgis: 14-Jun-84 15:35:18 Sandman, January 27, 1981 5:56 PM Garner, April 1, 1980 12:20 PM} {The Load mesa op-codes consist of the following: OP val bytes stk time LL0 10'b 1 +1 1 LL1 11'b 1 +1 1 LL2 12'b 1 +1 1 LL3 13'b 1 +1 1 LL4 14'b 1 +1 1 LL5 15'b 1 +1 1 LL6 16'b 1 +1 1 LL7 17'b 1 +1 1 LLB 20'b 2 +1 1 LLDB 21'b 2 +2 2 LG0 37'b 1 +1 1 LG1 40'b 1 +1 1 LG2 41'b 1 +1 1 LG3 42'b 1 +1 1 LG4 43'b 1 +1 1 LG5 44'b 1 +1 1 LG6 45'b 1 +1 1 LG7 46'b 1 +1 1 LGB 47'b 2 +1 1 LGDB 50'b 2 +2 2 LI0 56'b 1 +1 1 LI1 57'b 1 +1 1 LI2 60'b 1 +1 1 LI3 61'b 1 +1 1 LI4 62'b 1 +1 1 LI5 63'b 1 +1 1 LI6 64'b 1 +1 1 LIN1 65'b 1 +1 1 LINI 66'b 1 +1 1 LIB 67'b 2 +1 1 LIW 70'b 3 +1 2 LINB 71'b 2 +1 1 LADRB 72'b 2 +1 2 GADRB 73'b 2 +1 2 LCO 74'b 3 +1 2 LP 161'b 1 +1 1 The Store mesa op-codes consist of the following: OP val bytes stk time SL0 22'b 1 -1 1 SL1 23'b 1 -1 1 SL2 24'b 1 -1 1 SL3 25'b 1 -1 1 SL4 26'b 1 -1 1 SL5 27'b 1 -1 1 SL6 30'b 1 -1 1 SL7 31'b 1 -1 1 SLB 32'b 2 -1 1 SLDB 162'b 2 -2 2 SG0 51'b 1 -1 1 SG1 52'b 1 -1 1 SG2 53'b 1 -1 1 SG3 54'b 1 -1 1 SGB 55'b 2 -1 1 SGDB 163'b 2 -2 2 PL0 34'b 1 0 1 PL1 35'b 1 0 1 PL2 36'b 1 0 1 PL3 37'b 1 0 1} {Times for memory operations are + 2 if page cross + 2 if fix map flags} {L2 CarryMapRets} Set[L2.Lcarry, 1]; Set[L2.LDcarry, 5]; Set[L2.Scarry, 0]; Set[L2.SLDcarry, 9]; Set[L2.SGDcarry, 0D]; {1 mod 4} {***************************************************************************** LLn{n:[0..7]} Load Local n 1 click *****************************************************************************} @LL0: MAR ← Q ← [rhL, L+4], L1 ← L1r.PopOnly, push, GOTO[LLns], c1, opcode[10'b]; @LL1: MAR ← Q ← [rhL, L+5], L1 ← L1r.PopOnly, push, GOTO[LLns], c1, opcode[11'b]; @LL2: MAR ← Q ← [rhL, L+6], L1 ← L1r.PopOnly, push, GOTO[LLns], c1, opcode[12'b]; @LL3: MAR ← Q ← [rhL, L+7], L1 ← L1r.PopOnly, push, GOTO[LLns], c1, opcode[13'b]; @LL4: MAR ← Q ← [rhL, L+8], L1 ← L1r.PopOnly, push, GOTO[LLns], c1, opcode[14'b]; @LL5: MAR ← Q ← [rhL, L+9], L1 ← L1r.PopOnly, push, GOTO[LLns], c1, opcode[15'b]; @LL6: MAR ← Q ← [rhL, L+0A], L1 ← L1r.PopOnly, push, GOTO[LLns], c1, opcode[16'b]; @LL7: MAR ← Q ← [rhL, L+0B], L1 ← L1r.PopOnly, push, GOTO[LLns], c1, opcode[17'b]; LLns: STK ← TOS, PC ← PC + PC16, IBDisp, L2←L2.Lcarry, BRANCH[LLTail,LLcarry,1], c2; LLTail: TOS ← MD, push, fZpop, DISPNI[OpTable], c3; LLcarry: TT ← UvL, GOTO[CarryMap], c3; {***************************************************************************** LLB Load Local Byte 1 click *****************************************************************************} @LLB: MAR ← Q ← [rhL, L+ib], L1 ← L1r.PopDec, push, GOTO[LLBs], c1, opcode[20'b]; LLBs: STK ← TOS, PC ← PC + 1, IBDisp, L2←L2.Lcarry, BRANCH[LLTail,LLcarry,1], c2; {***************************************************************************** Load Carry Logic (shared between LLx and LGx) *****************************************************************************} CarryMap: Noop, c1; CarryFix: Q ← Q - TT, L2Disp, c2; Q ← Q and 0FF, RET[CarryMapRets], c3; LcarryMap: Map ← Q ← [rhMDS, TT+Q], c1, at[Or[L2.Lcarry,2], 10, CarryMapRets]; PC ← PC-PC16, c2; Rx ← rhRx ← MD, XRefBr, GOTO[RedoR], c3; {***************************************************************************** LGn{n:[0..7]} Load Global n 1 click *****************************************************************************} @LG0: MAR ← Q ← [rhG, G+3], L1 ← L1r.PopOnly, push, GOTO[LGns], c1, opcode[37'b]; @LG1: MAR ← Q ← [rhG, G+4], L1 ← L1r.PopOnly, push, GOTO[LGns], c1, opcode[40'b]; @LG2: MAR ← Q ← [rhG, G+5], L1 ← L1r.PopOnly, push, GOTO[LGns], c1, opcode[41'b]; @LG3: MAR ← Q ← [rhG, G+6], L1 ← L1r.PopOnly, push, GOTO[LGns], c1, opcode[42'b]; @LG4: MAR ← Q ← [rhG, G+7], L1 ← L1r.PopOnly, push, GOTO[LGns], c1, opcode[43'b]; @LG5: MAR ← Q ← [rhG, G+8], L1 ← L1r.PopOnly, push, GOTO[LGns], c1, opcode[44'b]; @LG6: MAR ← Q ← [rhG, G+9], L1 ← L1r.PopOnly, push, GOTO[LGns], c1, opcode[45'b]; @LG7: MAR ← Q ← [rhG, G+0A], L1 ← L1r.PopOnly, push, GOTO[LGns], c1, opcode[46'b]; LGns: STK ← TOS, PC ← PC + PC16, IBDisp, L2←L2.Lcarry, BRANCH[LGTail,LGcarry,1], c2; LGTail: TOS ← MD, push, fZpop, DISPNI[OpTable], c3; LGcarry: TT ← UvG, GOTO[CarryMap], c3; {***************************************************************************** LGB Load Global Byte 1 click *****************************************************************************} @LGB: MAR ← Q ← [rhG, G+ib], L1 ← L1r.PopDec, push, GOTO[LGBs], c1, opcode[47'b]; LGBs: STK ← TOS, PC ← PC + 1, IBDisp, L2←L2.Lcarry, BRANCH[LGTail,LGcarry,1], c2; {***************************************************************************** LLDB Load Local Double Byte 2 clicks *****************************************************************************} @LLDB: MAR ← Q ← [rhL, L + ib], push, L1 ← L1r.PopDec, c1, opcode[21'b]; STK ← TOS, PC ← PC + PC16, L2 ← L2.LDcarry, BRANCH[$, LLDBcarry,1], c2; T ← MD, c3; MAR ← Q ← [rhL, Q + 1], push, L1 ← L1r.Pop2DecDec, c1; STK ← T, IBDisp, PC ← PC + PC16, L2 ← L2.Lcarry, BRANCH[LLTail, LLcarry, 1], c2; LLDBcarry: TT ← UvL, GOTO[CarryMap], c3; {***************************************************************************** LGDB Load Global Double Byte 2 clicks *****************************************************************************} @LGDB: MAR ← Q ← [rhG, G + ib], push, L1 ← L1r.PopDec, c1, opcode[50'b]; STK ← TOS, PC ← PC + PC16, L2 ← L2.LDcarry, BRANCH[$, LGDBcarry,1], c2; T ← MD, c3; MAR ← Q ← [rhG, Q + 1], push, L1 ← L1r.Pop2DecDec, c1; LGDBx: STK ← T, IBDisp, PC ← PC + PC16, L2 ← L2.Lcarry, BRANCH[$, LGDBCarry2, 1], c2; TOS ← MD, push, fZpop, DISPNI[OpTable], c3; LGDBcarry: TT ← UvG, GOTO[CarryMap], c3; {***************************************************************************** Load Double Carry Logic (shared by LLDx and LGDx) *****************************************************************************} {First word on next page => remap page and get both words} LDcarryMap: Map ← Q ← [rhMDS, TT + Q], c1, at[Or[L2.LDcarry,2], 10, CarryMapRets]; L0 ← L0.LDcarry, c2; Rx ← rhRx ← MD, XRefBr, c3; LDcarry: MAR ← [rhRx, Q + 0], BRANCH[LDcarryMapUD, $], c1, at[L0.LDcarry,10,RMapFixCaller]; Noop, c2; T ← MD, c3; MAR ← [rhRx, Q + 1], push, GOTO[LGDBx], c1; LDcarryMapUD: CALL[RMapFix], {will return to LDcarry} c2; {***************************************************************************** Sturgis: 14-Jun-84 15:44:44 The following is additional carry logic for the case of second word in a page that page faults. The reason that this fix is so bad is that there are at least two case tables that are full, and so I have had to duplicate a lot of code here. The two case tables that are full are the RFixForTrap table, and RMapFixCaller. The bug is that in the incorrect code, L1 was set to L1r.Pop2DecDec, to be used in the case of a fault, but in fact the value should have been Pop2Dec, but there is no such value, and the table is full. The reason it should have been Pop2Dec is that some joint code has temporarily subtracted 1 from the pc. Unfortunately, I can not simply replace this joint code, as the subroutine it uses has a full return list. So I must also duplicate the subroutine. It is possible that no one else uses L1r.Pop2DecDec, in which I could replace this case with the one I want. However, it seems too painful to check this. In the following I leave some indication of where the code is borrowed from. Fiala: 24-Apr-86 18:33:00 Found that the stack item underneath the value pushed by LGDB was getting smashed when the double-word fetched by LGDB straddled a page boundary. Changed the first fetch of both LGDB and LLDB to use T rather than TOS for MD. *****************************************************************************} {LGcarry} LGDBCarry2: TT ← UvG, c3; {CarryMap} Noop, c1; Q ← Q - TT, c2; Q ← Q and 0FF, c3; {LcarryMap} Map ← Q ← [rhMDS, TT + Q], c1; Noop, c2; Rx ← rhRx ← MD, XRefBr, c3; {Read.RedoR} LGDBCarry3: MAR ← [rhRx, Q + 0], BRANCH[LGDBCarry4, $], c1; IBDisp, c2; {LLTail} TOS ← MD, push, fZpop, DISPNI[OpTable], c3; {Read.RMapUD} LGDBCarry4: Noop, c2; {CommonSubs.RMapFix} Xbus ← Rx LRot0, XwdDisp, L3 ← L3.rhMDS.Q, c3; Map ← [rhMDS,Q], DISP2[LGDBFixRFlags], c1; LGDBFixRFlags: MDR ← Rx or 10, GOTO[LGDBCarry5], c2, at[0,4]; MDR ← Rx or 10, GOTO[LGDBCarry5], c2, at[1,4, LGDBFixRFlags]; MDR ← Rx or 10, GOTO[LGDBCarry5], c2, at[2,4, LGDBFixRFlags]; T ← qPageFault, L1Disp, GOTO[RTrap], c2, at[3,4, LGDBFixRFlags]; LGDBCarry5: Xbus ← 1, XDisp, GOTO[LGDBCarry3], c3; {***************************************************************************** LIn{n:[0..6]} Load Immeadiate n 1 click *****************************************************************************} @LI0: T ← 0, push, GOTO[LInTail], c1, opcode[56'b]; @LI1: T ← 1, push, GOTO[LInTail], c1, opcode[57'b]; @LI2: T ← 2, push, GOTO[LInTail], c1, opcode[60'b]; @LI3: T ← 3, push, GOTO[LInTail], c1, opcode[61'b]; @LI4: T ← 4, push, GOTO[LInTail], c1, opcode[62'b]; @LI5: T ← 5, push, GOTO[LInTail], c1, opcode[63'b]; @LI6: T ← 6, push, GOTO[LInTail], c1, opcode[64'b]; LInTail: STK ← TOS, PC ← PC + PC16, IBDisp, c2; PushT: TOS ← T, push, fZpop, DISPNI[OpTable], c3; {***************************************************************************** LIN1 Load Immeadiate Negative One 1 click *****************************************************************************} @LIN1: T ← T xor ~T, push, GOTO[LInTail], c1, opcode[65'b]; {***************************************************************************** LINI Load Immeadiate Negative Infinity 1 click *****************************************************************************} @LINI: T ← RShift1 0, SE ← 1, push, GOTO[LInTail], c1, opcode[66'b]; {***************************************************************************** LIB Load Immeadiate Byte 1 click *****************************************************************************} @LIB: T ← ib, push, c1, opcode[67'b]; STK ← TOS, PC ← PC + 1, IBDisp, GOTO[PushT], c2; {***************************************************************************** LIW Load Immeadiate Word 2 clicks *****************************************************************************} @LIW: T ← ib, push, c1, opcode[70'b]; LIWx: PC ← PC + 1, c2; T ← T LRot8, c3; T ← T or ib, GOTO[LInTail], c1; {***************************************************************************** LINB Load Immeadiate Negative Byte 1 click *****************************************************************************} @LINB: Q ← ib, push, c1, opcode[71'b]; STK ← TOS, PC ← PC + 1, push, fZpop, IBDisp, c2; TOS ← Q xor ~0FF, DISPNI[OpTable], c3; {***************************************************************************** LADRB Local Address Byte 2 clicks *****************************************************************************} @LADRB: TT ← UvL, c1, opcode[72'b]; LADRBx: T ← ib, push, c2; PC ← PC + PC16, c3; T ← TT + T, GOTO[LInTail], c1; {***************************************************************************** GADRB Global Address Byte 2 clicks *****************************************************************************} @GADRB: TT ← UvG, GOTO[LADRBx], c1, opcode[73'b]; {***************************************************************************** LCO Load Code Offset 2 clicks *****************************************************************************} @LCO: T ← ib, push, GOTO[LIWx], c1, opcode[74'b]; {***************************************************************************** LP Lengthen Pointer 2 click *****************************************************************************} @LP: [] ← TOS, ZeroBr, fXpop, push, c1, opcode[161'b]; BRANCH[LPnot, LPnil], c2; LPnot: T ← UvMDS, GOTO[LPTail], c3; LPnil: T ← 0, GOTO[LPTail], c3; LPTail: push, GOTO[LInTail], c1; {***************************************************************************** SLn{n:[0..7]} Store Local n 1 click *****************************************************************************} @SL0: MAR ← Q ← [rhL, L+4], L1 ← L1w.DecOnly, push, GOTO[SLns], c1, opcode[22'b]; @SL1: MAR ← Q ← [rhL, L+5], L1 ← L1w.DecOnly, push, GOTO[SLns], c1, opcode[23'b]; @SL2: MAR ← Q ← [rhL, L+6], L1 ← L1w.DecOnly, push, GOTO[SLns], c1, opcode[24'b]; @SL3: MAR ← Q ← [rhL, L+7], L1 ← L1w.DecOnly, push, GOTO[SLns], c1, opcode[25'b]; @SL4: MAR ← Q ← [rhL, L+8], L1 ← L1w.DecOnly, push, GOTO[SLns], c1, opcode[26'b]; @SL5: MAR ← Q ← [rhL, L+9], L1 ← L1w.DecOnly, push, GOTO[SLns], c1, opcode[27'b]; @SL6: MAR ← Q ← [rhL, L+0A], L1 ← L1w.DecOnly, push, GOTO[SLns], c1, opcode[30'b]; @SL7: MAR ← Q ← [rhL, L+0B], L1 ← L1w.DecOnly, push, GOTO[SLns], c1, opcode[31'b]; SLns: MDR ← STK ← TOS, PC ← PC + PC16, pop, IBDisp, BRANCH[$,SLcarry,1], c2; SLTail: TOS ← STK, pop, DISPNI[OpTable], c3; SLcarry: TT ← UvL, L2←L2.Scarry, GOTO[CarryMap], c3; {***************************************************************************** SLB Store Local Byte 1 click *****************************************************************************} @SLB: MAR ← Q ← [rhL, L+ib], L1 ← L1w.DecDec, push, GOTO[SLBs], c1, opcode[32'b]; SLBs: MDR ← STK ← TOS, PC ← PC + 1, pop, IBDisp, BRANCH[SLTail,SLcarry,1], c2; {***************************************************************************** PLn{n:[0..3]} Put Local n 1 click *****************************************************************************} {no page carry possible on local 0-3} @PL0: MAR ← Q ← [rhL, L+4], fXpop, push, GOTO[PLns], c1, opcode[33'b]; @PL1: MAR ← Q ← [rhL, L+5], fXpop, push, GOTO[PLns], c1, opcode[34'b]; @PL2: MAR ← Q ← [rhL, L+6], fXpop, push, GOTO[PLns], c1, opcode[35'b]; @PL3: MAR ← Q ← [rhL, L+7], fXpop, push, GOTO[PLns], c1, opcode[36'b]; PLns: MDR ← TOS, PC ← PC + PC16, IBDisp, CANCELBR[DISPNIonly,0], c2; {***************************************************************************** Store Carry Logic (shared between SLx and SGx) *****************************************************************************} ScarryMap: Map ← Q ← [rhMDS, TT+Q], {map next page} c1, at[L2.Scarry, 10, CarryMapRets]; L0 ← L0.Scarry, c2; Rx ← rhRx ← MD, XwdDisp, c3; Scarry: MAR ← [rhRx, Q+0], DISP2[ScarryMapUD], c1, at[L0.Scarry,10,WMapFixCaller]; ScarryMapUD: CALL[WMapFix], {will return to Scarry} c2, at[0, 4, ScarryMapUD]; CALL[WMapFix], {WP fault} c2, at[2, 4, ScarryMapUD]; CALL[WMapFix], {Page fault} c2, at[3, 4, ScarryMapUD]; SGStore: MDR ← TOS, IBDisp, CANCELBR[SLTail,0], c2, at[1, 4, ScarryMapUD]; {***************************************************************************** SGn{n:[0..7]} Store Global n 1 click *****************************************************************************} @SG0: Q ← G + 3, PgCarryBr, L1 ← L1w.DecOnly, GOTO[SGns], c1, opcode[51'b]; @SG1: Q ← G + 4, PgCarryBr, L1 ← L1w.DecOnly, GOTO[SGns], c1, opcode[52'b]; @SG2: Q ← G + 5, PgCarryBr, L1 ← L1w.DecOnly, GOTO[SGns], c1, opcode[53'b]; @SG3: Q ← G + 6, PgCarryBr, L1 ← L1w.DecOnly, GOTO[SGns], c1, opcode[54'b]; SGns: Xbus ← rhG, XwdDisp, push, BRANCH[SGnNoCross, SGnCross], c2; SGnNoCross: STK ← TOS, pop, PC ← PC + PC16, DISP2[SGMapFix], c3; SGMapFix: TT ← UvG, L2 ← L2.Scarry, GOTO[SGMapFixx], c1, at[0, 4, SGMapFix]; TT ← UvG, L2 ← L2.Scarry, GOTO[SGMapFixx], c1, at[2, 4, SGMapFix]; TT ← UvG, L2 ← L2.Scarry, GOTO[SGMapFixx], c1, at[3, 4, SGMapFix]; MAR ← [rhG, Q + 0], GOTO[SGStore], c1, at[1, 4, SGMapFix]; SGMapFixx: Q ← Q - TT, c2; Q ← Q and 0FF, c3; Map ← [rhMDS, TT], c1; L2Disp, c2; rhG ← MD, RET[CarryMapRets], c3; SGnCross: STK ← TOS, pop, PC ← PC + PC16, CANCELBR[SGCrossFix,3], c3; SGCrossFix: TT ← UvG, L2 ← L2.Scarry, GOTO[SGMapFixx], c1; {***************************************************************************** SGB Store Global Byte 1 click *****************************************************************************} @SGB: Q ← G + ib, PgCarryBr, L1 ← L1w.DecDec, c1, opcode[55'b]; SGBs: Xbus ← rhG, XwdDisp, push, BRANCH[SGbNoCross, SGbCross], c2; SGbNoCross: STK ← TOS, pop, PC ← PC + 1, DISP2[SGMapFix], c3; SGbCross: STK ← TOS, pop, PC ← PC + 1, CANCELBR[SGCrossFix,3], c3; {***************************************************************************** SLDB Store Local Double Byte 2 clicks *****************************************************************************} @SLDB: MAR ← Q ← [rhL, L + ib], L1 ← L1w.NoFixes, c1, opcode[162'b]; MDR ← STK, push, L2 ← L2.SLDcarry, BRANCH[$, SLDBcarry,1], c2; PC ← PC + PC16, STK ← TOS, pop, c3; SLDB2: MAR ← Q ← [rhL, Q + 1], pop, L1 ← L1w.PushDecDec, c1; SLDB2x: MDR ← TOS, PC ← PC + PC16, IBDisp, BRANCH[SLTail,SLcarry,1], c2; SLDBcarry: TT ← UvL, GOTO[CarryMap], c3; {***************************************************************************** SGDB Store Global Double Byte 2 clicks *****************************************************************************} @SGDB: Q ← G + ib + 1, PgCarryBr, L2←L2.SGDcarry, c1, opcode[163'b]; Xbus ← rhG, Q ← Q - 1, XwdDisp, push, BRANCH[$,SGDBcarry], c2; STK ← TOS, pop, DISP2[SGDBMapFix], c3; SGDBMapFix: TT ← UvG, CALL[SGMapFixx], c1, at[0, 4, SGDBMapFix]; TT ← UvG, CALL[SGMapFixx], c1, at[2, 4, SGDBMapFix]; TT ← UvG, CALL[SGMapFixx], c1, at[3, 4, SGDBMapFix]; SGDBMapOK: MAR ← Q ← [rhG, Q + 0], c1, at[1, 4, SGDBMapFix]; MDR ← STK, c2; PC ← PC + PC16, c3; MAR ← [rhG, Q + 1], pop, GOTO[SLDB2x], c1; T ← TOS, L1 ← L1w.PushDec, c1, at[L2.SGDcarry, 10, CarryMapRets]; Q ← TT + Q, GOTO[WDBx], c2; SGDBcarry: STK ← TOS, pop, CANCELBR[$,3], c3; TT ← UvG, CALL[SGMapFixx], c1; {***************************************************************************** Store Double Carry Logic (shared by SLDx) *****************************************************************************} {First word on next page => remap page and store both words} SDcarryMap: Map ← Q ← [rhMDS, TT+Q], c1, at[Or[L2.SLDcarry,2], 10, CarryMapRets]; L0 ← L0.SDcarry, c2; Rx ← rhRx ← MD, XwdDisp {XDirtyDisp}, pop, c3; SDcarry: MAR ← [rhRx, Q+0], DISP2[SDcarryMapUD] {BRANCH[SDcarryMapUD, $, 1]}, c1, at[L0.SDcarry,10,WMapFixCaller]; SDcarryMapUD: CALL[WMapFix], {will return to SDcarry} c2, at[0, 4, SDcarryMapUD]; CALL[WMapFix], {WP fault} c2, at[2, 4, SDcarryMapUD]; CALL[WMapFix], {Page fault} c2, at[3, 4, SDcarryMapUD]; MDR ← STK, push, c2, at[1, 4, SDcarryMapUD]; STK ← TOS, PC ← PC + PC16, pop, c3; MAR ← [rhRx, Q+1], pop, c1; MDR ← TOS, PC ← PC + PC16, IBDisp, CANCELBR[SLTail,0], c2; {14-Jun-84 15:36:28: Sturgis: repair nasty bug in LGDB, that occurs when second word is in a new page, and that page is not mapped in. The fix is gross, see comments in the opcode Fiala 24 April 1986 Another fix to LGDB, which was smashing the item underneath when the first and second words of the double-word crossed a page boundary. Fiala 16-May-86 15:03:35 Changes for the 4MB storage mod; changes at SG0..SG3 were particularly awful, likely source of bugs. }