*----------------------------------------------------------- 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 = 0 NL = 1 * Doesn't skip Skips Doesn't skip Skips * None 1 -- 0 -- * SKP -- 6 -- 6 * SZC, SNC 1 7 1 7 * SZR, SNR 1 7 1 6 * SEZ, SBN 2 8 2 7 * 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]; (1552)