IFUPLAInstrDecode:
CEDAR
DEFINITIONS
IMPORTS Basics =
BEGIN
instrDecodePLA: PLAOps.PLA;
InstrDecodeProc: PROC[args: InstrDecodeIn] RETURNS[result: InstrDecodeOut];
CondEffect: TYPE = IFUPLAMainPipeControl.CondEffect;
fixedMicroJump: Dragon.HexByte = IFUPLAMainPipeControl.fixedMicroJump;
InstrDecodeIn:
TYPE =
RECORD [
-- default must be zero for use initializing sigificance arg
beta: Dragon.HexByte ← 0,
alpha: Dragon.HexByte ← 0,
op: DragOpsCross.Inst ← LOOPHOLE[0],
state: Dragon.HexByte ← 0,
popPending: BOOL ← FALSE,
pushPending: BOOL ← FALSE,
userMode0: BOOL ← FALSE,
instReady: BOOL ← FALSE,
reset: BOOL ← FALSE ];
InstrDecodeOut:
TYPE =
RECORD [
instStarting0: BOOL ← FALSE,
nextMacro: NextMacro ← get,
microCycleNext: MicroCycleNext ← clear,
protMicroCycle: BOOL ← FALSE, -- multicycle exceptions
pcNext: PCNext ← incr,
pcBusSrc: PCBusSrc ← pc,
pcPipeSrc: PCPipeSrc ← thisPC, -- pipe3 if stage3 normal
kPadsIn0: BOOL ← FALSE,
push0: BOOL ← FALSE,
pop0: BOOL ← FALSE,
x1ADstSLimit: BOOL ← FALSE,
x1ASrcSLimit: BOOL ← FALSE,
x1ADstStatus: BOOL ← FALSE,
x2ASrcStatus0: BOOL ← FALSE,
x1ADstStack: BOOL ← FALSE,
x1ASrcStack: BOOL ← FALSE,
x1ASrcStackL: BOOL ← FALSE,
x1ASrcStackP: BOOL ← FALSE,
xBusStackL: BOOL ← FALSE, -- otherwise PC
xBusStackEldest: BOOL ← FALSE, -- otherwise youngest
aReg: ABReg ← constantZero,
bReg: ABReg ← constantZero,
cReg: CReg ← inhibitStore,
cIsField0: BOOL ← FALSE,
flagSrc: FlagSrc ← same,
lSource: LSource ← [ l, zero ],
sSource: SSource ← [ s, deltaS ],
popSa: BOOL ← FALSE,
popSb: BOOL ← FALSE,
pushSc: BOOL ← FALSE,
x2ALitSource: X2ALitSource ← none,
kIsRtOp0: BOOL ← FALSE,
fCtlIsRtOp0: BOOL ← FALSE,
aluOp: Dragon.ALUOps ← Or,
aluOpIsOp47: BOOL ← FALSE,
condSel: Dragon.CondSelects ← False,
condSelIsOp57: BOOL ← FALSE,
condEffect0: CondEffect ← macroTrap,
dPCmnd: Dragon.PBusCommands ← NoOp,
dPCmndIsRd0: BOOL ← FALSE,
dPCmndSel: DPCmndSel ← normal
];
InstrDecodeOut6:
TYPE =
RECORD [
nextMacro: NextMacro ← get,
pcNext: PCNext ← incr,
pcBusSrc: PCBusSrc ← pc,
pcPipeSrc: PCPipeSrc ← thisPC,
x2ALitSource: X2ALitSource ← none,
kIsRtOp0: BOOL ← FALSE,
push0: BOOL ← FALSE ];
InstrDecodeOut5:
TYPE =
RECORD [
microCycleNext: MicroCycleNext ← clear,
instStarting0: BOOL ← FALSE,
protMicroCycle: BOOL ← FALSE, -- multicycle exceptions
pop0: BOOL ← FALSE,
dPCmndIsRd0: BOOL ← FALSE,
dPCmnd: Dragon.PBusCommands ← NoOp,
dPCmndSel: DPCmndSel ← normal ];
InstrDecodeOut4:
TYPE =
RECORD [
flagSrc: FlagSrc ← same,
lSource: LSource ← [ l, zero ],
sSource: SSource ← [ s, deltaS ],
popSa: BOOL ← FALSE,
popSb: BOOL ← FALSE ];
InstrDecodeOut3:
TYPE =
RECORD [
kPadsIn0: BOOL ← FALSE,
fCtlIsRtOp0: BOOL ← FALSE,
pushSc: BOOL ← FALSE,
cReg: CReg ← inhibitStore ];
InstrDecodeOut2:
TYPE =
RECORD [
bReg: ABReg ← constantZero ];
InstrDecodeOut1:
TYPE =
RECORD [
aReg: ABReg ← constantZero ];
InstrDecodeOut0:
TYPE =
RECORD [
aluOp: Dragon.ALUOps ← Or,
condSel: Dragon.CondSelects ← False,
condEffect0: CondEffect ← macroTrap,
x1ADstSLimit: BOOL ← FALSE,
x1ASrcSLimit: BOOL ← FALSE,
x1ASrcStackL: BOOL ← FALSE,
x1ASrcStackP: BOOL ← FALSE,
x1ADstStack: BOOL ← FALSE,
aluOpIsOp47: BOOL ← FALSE,
condSelIsOp57: BOOL ← FALSE,
x1ASrcStack: BOOL ← FALSE,
xBusStackL: BOOL ← FALSE, -- otherwise PC
xBusStackEldest: BOOL ← FALSE, -- otherwise youngest
cIsField0: BOOL ← FALSE ];
InstrDecodeOutCount: INT = 7;
DefaultMicro: InstrDecodeOut = [];
NoOpMicro: InstrDecodeOut = [
nextMacro: hold,
pcNext: fromPCBus,
microCycleNext: next];
Delayed: InstrDecodeOut = [
nextMacro: hold,
pcNext: fromPCBus,
microCycleNext: hold,
condEffect0: bubble ];
Trap: InstrDecodeOut = [
nextMacro: jump,
pcNext: fromPCBus,
pcBusSrc: trapGen,
push0: TRUE ];
SingleByteXop: InstrDecodeOut = [
nextMacro: jump,
pcNext: fromPCBus,
pcBusSrc: xopGen,
pcPipeSrc: seqPC,
push0: TRUE ];
MultiByteXop: InstrDecodeOut = [
nextMacro: jump,
pcNext: fromPCBus,
pcBusSrc: xopGen,
pcPipeSrc: seqPC,
push0: TRUE,
x2ALitSource: alpBetGamDel,
cReg: [s, offset, one],
pushSc: TRUE ];
A decoded enumerated type can be used to directly generate multiplex controls.
The type can be coded as {0, 1} or {0, 1, 2, 4, 8 ...} or {0, 3, 5, 9, 17 ...}.
The first and last cases have the advantage that zero can be used a default multiplex control (lsb = 0 => no other bit is true).
In all cases it's possible to name the bits and/or their inverses using the enumerated type element names.
NextMacro: TYPE = MACHINE DEPENDENT {get(0), jump(3), hold(5)};
MicroCycleNext: TYPE = MACHINE DEPENDENT {clear(0), next(3), hold(5)};
PCNext: TYPE = MACHINE DEPENDENT {incr(0), fromPCBus(1)};
PCBusSrc:
TYPE =
MACHINE
DEPENDENT {
pc ( 0), offSetPC ( 3), stack ( 5), alpBetGamDel ( 9),
x (17), pipe3 (33), trapGen (65), xopGen (129) };
PCPipeSrc: TYPE = MACHINE DEPENDENT {thisPC(0), seqPC(3), offSetPC(5)};
DPCmndSel: TYPE = MACHINE DEPENDENT {normal(0), beta(1)};
FlagSrc: TYPE = MACHINE DEPENDENT {same(0), clear(3), lev3(5), stack(9)};
X2ALitSource:
TYPE =
MACHINE
DEPENDENT {
none(0), zero(3), alpha(5), alphaBeta(9), alpBetGamDel(17)};
ABReg:
TYPE =
RECORD
[lt: ABCSourceLt, rt: ABCSourceRt, off: PlusOffset ← zero, mod: Mod ← full];
CReg:
TYPE =
RECORD
[lt: ABCSourceLt, rt: ABCSourceRt, off: MinusOffset ← minus4, mod: Mod ← full];
Mod: TYPE = MACHINE DEPENDENT {full(0), half(1)};
ABCSourceLt:
TYPE =
MACHINE
DEPENDENT {
cBase(0), aBase(3), zero(5), -- Mod = full
s(9), l(17) -- Mod = half
};
ABCSourceRt:
TYPE =
MACHINE
DEPENDENT {
offset(0), alpha(3), alpha47(5),
op47(9), beta(17), beta03(33), beta47(65)};
PlusOffset:
TYPE =
MACHINE
DEPENDENT {
zero(0), one(1), two(2), three(3),
minus4(4), minus3(5), minus2(6), minus1(7)};
MinusOffset:
TYPE =
MACHINE
DEPENDENT {
minus4(0), minus3(1), minus2(2), minus1(3),
zero(4), one(5), two(6), three(7)};
LSource: TYPE = RECORD [ lt: LSourceLt, rt: LSourceRt ];
LSourceLt: TYPE = MACHINE DEPENDENT {l(0), s(3), zero(5), l3(9)};
LSourceRt: TYPE = MACHINE DEPENDENT {zero(0), alpha(3), stack(5), one(9)};
SSource: TYPE = RECORD [ lt: SSourceLt, rt: SSourceRt ];
SSourceLt: TYPE = MACHINE DEPENDENT {s(0), l(3), s2(5), s3(9)};
SSourceRt: TYPE = MACHINE DEPENDENT {deltaS(0), alpha(3), zero(5), one(9)};
These must agree with DragOpsCross.ProcessorRegister
abStackTop: ABReg = [ s , offset, zero ];
cStackTop: CReg = [ s , offset, zero ];
constantZero: ABReg = [ cBase , offset, zero ];
inhibitStore: CReg = [ cBase , offset, minus4 ];
fromIfuXBus: ABReg = [ cBase , offset, minus3 ];
toIfuXBus: CReg = [ cBase , offset, minus3 ];
euField: CReg = [ cBase , offset, minus1 ];
ByteTopSig:
PROC[topBits:
CARDINAL]
RETURNS[byte: Dragon.HexByte] =
INLINE
{RETURN[Basics.BITAND[Basics.BITSHIFT[377B, (8-topBits)], 377B]]};
InstrTopSig:
PROC[topBits:
CARDINAL]
RETURNS[DragOpsCross.Inst] =
INLINE
{RETURN[LOOPHOLE[ByteTopSig[topBits]]]};
Used by InstrDecode
GenInstrDecodePLA1: GenInstrDecodePLAProc;
GenInstrDecodePLA2: GenInstrDecodePLAProc;
GenInstrDecodePLA3: GenInstrDecodePLAProc;
GenInstrDecodePLA4: GenInstrDecodePLAProc;
GenInstrDecodePLA5: GenInstrDecodePLAProc;
GenInstrDecodePLAProc:
TYPE =
PROC [
BE:
IDBE, Set: IDSet, old: PLAOps.BoolExpr]
RETURNS[current: PLAOps.BoolExpr];
IDBE: TYPE = PROC [m, d: InstrDecodeIn] RETURNS[PLAOps.BoolExpr];
IDSet: TYPE = PROC[s: PLAOps.BoolExpr ←NIL, m, d: InstrDecodeIn ←[], out: InstrDecodeOut];
END.