*-----------------------------------------------------------
Title[A-Group.mc...July 6, 1980 5:15 PM...Taft];
*-----------------------------------------------------------
* The IFU dispatches to separate entry points for each combination of
* source AC and ALU operation, and provides N = destination AC, and
* provides the low-order instruction byte as 2 nibbles (packed-Alpha).
* Timing (cycles):
* 9
*+1 if L, R, or S shift
*+1 if L or R shift and the ALU operation generates a carry
*+ a value taken from the following table:
*NL = 0NL = 1
*Doesn’t skipSkipsDoesn’t skipSkips
* None1--0--
* SKP--6--6
* SZC, SNC1717
* SZR, SNR1716
* SEZ, SBN2827
* Worst case is 19, and average for instructions actually used in
* Bcpl programs is about 13.
KnowRBase[AEmRegs];
TopLevel;
COM0:T← ID, StkP← spAC0, Branch[COMxx];
COM1:T← ID, StkP← spAC1, Branch[COMxx];
COM2:T← ID, StkP← spAC2, Branch[COMxx];
COM3:T← ID, StkP← spAC3, Branch[COMxx];
COMxx:Q← Stack, Call[SetupA];
ETemp← NOT Q, Branch[AGrpNN];
EmIFUArith[200, COM0, nspAC0];
EmIFUArith[210, COM0, nspAC1];
EmIFUArith[220, COM0, nspAC2];
EmIFUArith[230, COM0, nspAC3];
EmIFUArith[240, COM1, nspAC0];
EmIFUArith[250, COM1, nspAC1];
EmIFUArith[260, COM1, nspAC2];
EmIFUArith[270, COM1, nspAC3];
EmIFUArith[300, COM2, nspAC0];
EmIFUArith[310, COM2, nspAC1];
EmIFUArith[320, COM2, nspAC2];
EmIFUArith[330, COM2, nspAC3];
EmIFUArith[340, COM3, nspAC0];
EmIFUArith[350, COM3, nspAC1];
EmIFUArith[360, COM3, nspAC2];
EmIFUArith[370, COM3, nspAC3];
NEG0:T← ID, StkP← spAC0, Branch[NEGxx];
NEG1:T← ID, StkP← spAC1, Branch[NEGxx];
NEG2:T← ID, StkP← spAC2, Branch[NEGxx];
NEG3:T← ID, StkP← spAC3, Branch[NEGxx];
NEGxx:Q← Stack, Call[SetupA];
ETemp← (0S)-Q, Branch[AGrpNN];
EmIFUArith[201, NEG0, nspAC0];
EmIFUArith[211, NEG0, nspAC1];
EmIFUArith[221, NEG0, nspAC2];
EmIFUArith[231, NEG0, nspAC3];
EmIFUArith[241, NEG1, nspAC0];
EmIFUArith[251, NEG1, nspAC1];
EmIFUArith[261, NEG1, nspAC2];
EmIFUArith[271, NEG1, nspAC3];
EmIFUArith[301, NEG2, nspAC0];
EmIFUArith[311, NEG2, nspAC1];
EmIFUArith[321, NEG2, nspAC2];
EmIFUArith[331, NEG2, nspAC3];
EmIFUArith[341, NEG3, nspAC0];
EmIFUArith[351, NEG3, nspAC1];
EmIFUArith[361, NEG3, nspAC2];
EmIFUArith[371, NEG3, nspAC3];
MOV0:T← ID, StkP← spAC0, Branch[MOVxx];
MOV1:T← ID, StkP← spAC1, Branch[MOVxx];
MOV2:T← ID, StkP← spAC2, Branch[MOVxx];
MOV3:T← ID, StkP← spAC3, Branch[MOVxx];
MOVxx:Q← Stack, Call[SetupA];
ETemp← Q, Branch[AGrpNN];
EmIFUArith[202, MOV0, nspAC0];
EmIFUArith[212, MOV0, nspAC1];
EmIFUArith[222, MOV0, nspAC2];
EmIFUArith[232, MOV0, nspAC3];
EmIFUArith[242, MOV1, nspAC0];
EmIFUArith[252, MOV1, nspAC1];
EmIFUArith[262, MOV1, nspAC2];
EmIFUArith[272, MOV1, nspAC3];
EmIFUArith[302, MOV2, nspAC0];
EmIFUArith[312, MOV2, nspAC1];
EmIFUArith[322, MOV2, nspAC2];
EmIFUArith[332, MOV2, nspAC3];
EmIFUArith[342, MOV3, nspAC0];
EmIFUArith[352, MOV3, nspAC1];
EmIFUArith[362, MOV3, nspAC2];
EmIFUArith[372, MOV3, nspAC3];
INC0:T← ID, StkP← spAC0, Branch[INCxx];
INC1:T← ID, StkP← spAC1, Branch[INCxx];
INC2:T← ID, StkP← spAC2, Branch[INCxx];
INC3:T← ID, StkP← spAC3, Branch[INCxx];
INCxx:Q← Stack, Call[SetupA];
ETemp← Q+1, Branch[AGrpNN];
EmIFUArith[203, INC0, nspAC0];
EmIFUArith[213, INC0, nspAC1];
EmIFUArith[223, INC0, nspAC2];
EmIFUArith[233, INC0, nspAC3];
EmIFUArith[243, INC1, nspAC0];
EmIFUArith[253, INC1, nspAC1];
EmIFUArith[263, INC1, nspAC2];
EmIFUArith[273, INC1, nspAC3];
EmIFUArith[303, INC2, nspAC0];
EmIFUArith[313, INC2, nspAC1];
EmIFUArith[323, INC2, nspAC2];
EmIFUArith[333, INC2, nspAC3];
EmIFUArith[343, INC3, nspAC0];
EmIFUArith[353, INC3, nspAC1];
EmIFUArith[363, INC3, nspAC2];
EmIFUArith[373, INC3, nspAC3];
ADC0:T← ID, StkP← spAC0, Branch[ADCxx];
ADC1:T← ID, StkP← spAC1, Branch[ADCxx];
ADC2:T← ID, StkP← spAC2, Branch[ADCxx];
ADC3:T← ID, StkP← spAC3, Branch[ADCxx];
ADCxx:Q← Stack, Call[SetupA];
ETemp← (Stack)-Q-1, Branch[AGrpNN];
EmIFUArith[204, ADC0, nspAC0];
EmIFUArith[214, ADC0, nspAC1];
EmIFUArith[224, ADC0, nspAC2];
EmIFUArith[234, ADC0, nspAC3];
EmIFUArith[244, ADC1, nspAC0];
EmIFUArith[254, ADC1, nspAC1];
EmIFUArith[264, ADC1, nspAC2];
EmIFUArith[274, ADC1, nspAC3];
EmIFUArith[304, ADC2, nspAC0];
EmIFUArith[314, ADC2, nspAC1];
EmIFUArith[324, ADC2, nspAC2];
EmIFUArith[334, ADC2, nspAC3];
EmIFUArith[344, ADC3, nspAC0];
EmIFUArith[354, ADC3, nspAC1];
EmIFUArith[364, ADC3, nspAC2];
EmIFUArith[374, ADC3, nspAC3];
SUB0:T← ID, StkP← spAC0, Branch[SUBxx];
SUB1:T← ID, StkP← spAC1, Branch[SUBxx];
SUB2:T← ID, StkP← spAC2, Branch[SUBxx];
SUB3:T← ID, StkP← spAC3, Branch[SUBxx];
SUBxx:Q← Stack, Call[SetupA];
ETemp← (Stack)-Q, Branch[AGrpNN];
EmIFUArith[205, SUB0, nspAC0];
EmIFUArith[215, SUB0, nspAC1];
EmIFUArith[225, SUB0, nspAC2];
EmIFUArith[235, SUB0, nspAC3];
EmIFUArith[245, SUB1, nspAC0];
EmIFUArith[255, SUB1, nspAC1];
EmIFUArith[265, SUB1, nspAC2];
EmIFUArith[275, SUB1, nspAC3];
EmIFUArith[305, SUB2, nspAC0];
EmIFUArith[315, SUB2, nspAC1];
EmIFUArith[325, SUB2, nspAC2];
EmIFUArith[335, SUB2, nspAC3];
EmIFUArith[345, SUB3, nspAC0];
EmIFUArith[355, SUB3, nspAC1];
EmIFUArith[365, SUB3, nspAC2];
EmIFUArith[375, SUB3, nspAC3];
ADD0:T← ID, StkP← spAC0, Branch[ADDxx];
ADD1:T← ID, StkP← spAC1, Branch[ADDxx];
ADD2:T← ID, StkP← spAC2, Branch[ADDxx];
ADD3:T← ID, StkP← spAC3, Branch[ADDxx];
ADDxx:Q← Stack, Call[SetupA];
ETemp← (Stack)+Q, Branch[AGrpNN];
EmIFUArith[206, ADD0, nspAC0];
EmIFUArith[216, ADD0, nspAC1];
EmIFUArith[226, ADD0, nspAC2];
EmIFUArith[236, ADD0, nspAC3];
EmIFUArith[246, ADD1, nspAC0];
EmIFUArith[256, ADD1, nspAC1];
EmIFUArith[266, ADD1, nspAC2];
EmIFUArith[276, ADD1, nspAC3];
EmIFUArith[306, ADD2, nspAC0];
EmIFUArith[316, ADD2, nspAC1];
EmIFUArith[326, ADD2, nspAC2];
EmIFUArith[336, ADD2, nspAC3];
EmIFUArith[346, ADD3, nspAC0];
EmIFUArith[356, ADD3, nspAC1];
EmIFUArith[366, ADD3, nspAC2];
EmIFUArith[376, ADD3, nspAC3];
AND0:T← ID, StkP← spAC0, Branch[ANDxx];
AND1:T← ID, StkP← spAC1, Branch[ANDxx];
AND2:T← ID, StkP← spAC2, Branch[ANDxx];
AND3:T← ID, StkP← spAC3, Branch[ANDxx];
ANDxx:Q← Stack, Call[SetupA];
ETemp← (Stack) AND Q, Branch[AGrpNN];
EmIFUArith[207, AND0, nspAC0];
EmIFUArith[217, AND0, nspAC1];
EmIFUArith[227, AND0, nspAC2];
EmIFUArith[237, AND0, nspAC3];
EmIFUArith[247, AND1, nspAC0];
EmIFUArith[257, AND1, nspAC1];
EmIFUArith[267, AND1, nspAC2];
EmIFUArith[277, AND1, nspAC3];
EmIFUArith[307, AND2, nspAC0];
EmIFUArith[317, AND2, nspAC1];
EmIFUArith[327, AND2, nspAC2];
EmIFUArith[337, AND2, nspAC3];
EmIFUArith[347, AND3, nspAC0];
EmIFUArith[357, AND3, nspAC1];
EmIFUArith[367, AND3, nspAC2];
EmIFUArith[377, AND3, nspAC3];
* Common code for ALU-class instructions
*-----------------------------------------------------------
SetupA:
* Subroutine called to set up for ALU-class instructions.
* Expects T = destination AC number.
* Returns with a dispatch pending on the high-order 4 bits of alpha
* (Shift and Carry) and with ETemp1 = the low-order 4 bits (NL and Skip).
* Note: BigBDispatch is done peculiarly because assembler doesn’t permit
* BigBDispatch in subroutines--but it’s really OK in conjunction with Return.
*-----------------------------------------------------------
Subroutine;
T← ID, StkP← T, Global;* ID = Shift and Carry fields
ETemp1← ID, B← T, FF64[70], Return; * ID = NL and Skip fields
TopLevel;
*-----------------------------------------------------------
* Dispatch to one of the following immediately after executing the
* ALU operation.
* Note that if a logical operation was executed, the Carry branch condition
* will now be false, because the first instruction of SetupA executed
* ALU← A (arithmetic, thereby resetting Carry) and subsequent instructions
* all executed logical ALU operations which do not affect Carry.
AGrpNN:T← CRY, DblBranch[DoCryN, NoCryN, Carry], DispTable[20], Global;
AGrpZN:T← A0, DblBranch[DoCryN, NoCryN, Carry];
AGrpON:T← T-T-1, DblBranch[DoCryN, NoCryN, Carry];
AGrpCN:T← NOT(CRY), DblBranch[DoCryN, NoCryN, Carry];
AGrpNL:T← CRY, DblBranch[DoCryL, NoCryL, Carry];
AGrpZL:T← A0, DblBranch[DoCryL, NoCryL, Carry];
AGrpOL:T← T-T-1, DblBranch[DoCryL, NoCryL, Carry];
AGrpCL:T← NOT(CRY), DblBranch[DoCryL, NoCryL, Carry];
AGrpNR:T← CRY, DblBranch[DoCryR, NoCryR, Carry];
AGrpZR:T← A0, DblBranch[DoCryR, NoCryR, Carry];
AGrpOR:T← T-T-1, DblBranch[DoCryR, NoCryR, Carry];
AGrpCR:T← NOT(CRY), DblBranch[DoCryR, NoCryR, Carry];
AGrpNS:T← CRY, DblBranch[DoCryS, NoCryS, Carry];
AGrpZS:T← A0, DblBranch[DoCryS, NoCryS, Carry];
AGrpOS:T← T-T-1, DblBranch[DoCryS, NoCryS, Carry];
AGrpCS:T← NOT(CRY), DblBranch[DoCryS, NoCryS, Carry];
*-----------------------------------------------------------
* Shift the result appropriately, and compute a new carry for L or R shift.
* Put the word result in ETemp and the carry in ETemp1.
* Swap bytes
NoCryS:ETemp← LCY[ETemp, ETemp, 10], Branch[NoCryN];
DoCryS:ETemp← LCY[ETemp, ETemp, 10], Branch[DoCryN];
* Left shift
NoCryL:ETemp← LCY[T, ETemp, 1], DblBranch[NewCy1, NewCy0, R<0];
DoCryL:T← NOT T, Branch[NoCryL];
* Right shift
NoCryR:ETemp← RCY[T, ETemp, 1], DblBranch[NewCy1, NewCy0, R odd];
DoCryR:T← NOT T, Branch[NoCryR];
NewCy0:ETemp1← A0, BigBDispatch← ETemp1, Branch[LoadX];
NewCy1:ETemp1← (ETemp1)-(BigBDispatch← ETemp1)-1, Branch[LoadX];
* No shift
NoCryN:ETemp1← T, BigBDispatch← ETemp1, Branch[LoadX];
DoCryN:ETemp1← NOT T, BigBDispatch← ETemp1, Branch[LoadX];
* Common code for ALU-class instructions (cont’d)
* ETemp now has the word result, and ETemp1 the carry bit result.
* A 20-way branch is pending on the NL and Skip fields of the instruction.
* Note: the ←MD is to force any memory reference to complete (and possibly
* fault) -- must do this before changing any permanent state.
LoadX:T← MD, PD← Q← ETemp, Branch[LNSK];
*-----------------------------------------------------------
* Load the results and test the skip condition.
LNSK:CRY← ETemp1, Branch[LNSK1], DispTable[20], Global;
LSKP:T← (RR3)-(PCX’), Branch[LSKPX];
LSZC:CRY← ETemp1, DblBranch[LSKP1C, LNSK1C, R even];
LSNC:CRY← ETemp1, DblBranch[LSKP1, LNSK1, R odd];
LSZR:CRY← ETemp1, DblBranch[LSKP1, LNSK1, ALU=0];
LSNR:CRY← ETemp1, DblBranch[LSKP1C, LNSK1C, ALU#0];
LSEZ:PD← (ETemp1) AND Q, Branch[LSZR];
LSBN:PD← (ETemp1) AND Q, Branch[LSNR];
* Don’t load the results, just test the skip condition.
NSK:IFUJump[0];
SKP:T← (RR3)-(PCX’), Branch[SKP1];
SZC:ETemp1, DblBranch[SKPC, NSKC, R even];
SNC:ETemp1, DblBranch[SKP, NSK, R odd];
SZR:T← (RR3)-(PCX’), DblBranch[SKP1, NSK1, ALU=0];
SNR:T← (RR3)-(PCX’), DblBranch[SKP1C, NSK1C, ALU#0];
SEZ:PD← (ETemp1) AND Q, Branch[SZR];
SBN:PD← (ETemp1) AND Q, Branch[SNR];
*-----------------------------------------------------------
* Tails of skip tests
LSKPX:PCF← T, Branch[LNSK];
LNSK1:Stack← Q, IFUJump[0];
LSKP1:T← (RR3)-(PCX’), Branch[LSKPX];
LNSK1C:Stack← Q, IFUJump[0];
LSKP1C:T← (RR3)-(PCX’), Branch[LSKPX];
NSKC:IFUJump[0];
SKPC:T← (RR3)-(PCX’), Branch[SKP1];
NSK1:IFUJump[0];
SKP1:PCF← T, Branch[SKPX2];
NSK1C:IFUJump[0];
SKP1C:PCF← T;
SKPX2:Branch[NSK];