/* Problems of the description:
o Is it necessary divider_write_back if floating divide has not
fixed latency? */
%automaton integer multiply float
%unit <integer> e0 e1 load_store_1 load_store_2 store_reservation
%unit <multiply> multiplier multiplier_write_back
%unit <float> fa fm float_divider divider_write_back
%instruction LDL LDQ LDQ_U LDS LDT STL STQ STQ_U STS STT
LDL_L LDQ_L MB WMB STL_C STQ_C FETCH
RS RC HW_MFPR HW_MTPR BLBC BLBS BEQ BNE BLT BLE BGT BGE
FBEQ FBNE FBLT FBLE FBGT FBGE
JMP JSR RET JSR_COROUTINE BSR BR HW_REI CALLPAL
LDAH LDA ADDL ADDLV ADDQ ADDQV S4ADDL S4ADDQ S8ADDL S8ADDQ
S4SUBL S4SUBQ S8SUBL S8SUBQ SUBL SUBLV SUBQ SUBQV
AND BIC BIS ORNOT XOR EQV
SLL SRA SRL EXTBL EXTWL EXTLL EXTQL
EXTWH EXTLH EXTQH INSBL INSWL INSLL INSQL INSWH INSLH INSQH
MSKBL MSKWL MSKLL MSKQL MSKWH MSKLH MSKQH ZAP ZAPNOT
CMOVEQ CMOVNE CMOVLBS CMOVLT CMOVGE CMOVLBC CMOVLE CMOVGT
CMPEQ CMPLT CMPLE CMPULT CMPULE CMPBGE
MULL MULLV MULL1 MULLV1 MULL2 MULLV2
MULQ MULQV MULQ1 MULQV1 MULQ2 MULQV2 UMULH UMULH1 UMULH2
ADDS ADDT SUBS SUBT CPYSN CPYSE CVTLQ CVTQL CVTTQ
FCMOVEQ FCMOVNE FCMOVLE FCMOVLT FCMOVGE FCMOVGT
DIVS DIVT MULS MULT CPYS RPCC TRAPB UNOP
%%
/* Class LD:
o An instruction of class LD can not be simulteniously issued with
an instruction of class ST;
o An instruction of class LD can not be issued in the second cycle
after an instruction of class ST is issued. */
LDL, LDQ, LDQ_U, LDS, LDT:
(e0 + multiplier_write_back | e1) + (load_store_1 | load_store_2)
+ store_reservation
;
/* Class ST:
o An instruction of class LD can not be simulteniously issued with
an instruction of class ST;
o An instruction of class LD can not be issued in the second cycle
after an instruction of class ST is issued. */
STL, STQ, STQ_U, STS, STT:
e0 + multiplier_write_back + load_store_1 + load_store_2 %nothing
store_reservation
;
/* Class MBX */
LDL_L, LDQ_L, MB, WMB, STL_C, STQ_C, FETCH:
e0 + multiplier_write_back
;
/* Class RX */
RS, RC: e0 + multiplier_write_back
;
/* Class MXPR */
HW_MFPR, HW_MTPR: %nothing
;
/* Class IBR */
BLBC, BLBS, BEQ, BNE, BLT, BLE, BGT, BGE: e1
;
/* Class FBR */
FBEQ, FBNE, FBLT, FBLE, FBGT, FBGE: fa
;
/* Class JSR */
JMP, JSR, RET, JSR_COROUTINE, BSR, BR, HW_REI, CALLPAL: e1
;
/* Class IADD */
LDAH, LDA, ADDL, ADDLV, ADDQ, ADDQV, S4ADDL, S4ADDQ, S8ADDL, S8ADDQ,
S4SUBL, S4SUBQ, S8SUBL, S8SUBQ, SUBL, SUBLV, SUBQ, SUBQV:
e0 + multiplier_write_back
;
/* Class ILOG */
AND, BIC, BIS, ORNOT, XOR, EQV : (e0 + multiplier_write_back | e1)
;
/* Class SHIFT */
SLL, SRA, SRL, EXTBL, EXTWL, EXTLL, EXTQL,
EXTWH, EXTLH, EXTQH, INSBL, INSWL, INSLL, INSQL, INSWH, INSLH, INSQH,
MSKBL, MSKWL, MSKLL, MSKQL, MSKWH, MSKLH, MSKQH, ZAP, ZAPNOT:
e0 + multiplier_write_back
;
/* Class CMOV */
CMOVEQ, CMOVNE, CMOVLBS, CMOVLT, CMOVGE, CMOVLBC, CMOVLE, CMOVGT:
(e0 + multiplier_write_back | e1)
;
/* Class ICMP */
CMPEQ, CMPLT, CMPLE, CMPULT, CMPULE, CMPBGE:
(e0 + multiplier_write_back | e1)
;
/* Class IMULL:
o Thirty-two-bit multiplies have an 8-cycle latency, and the
multiplier can start a second multiply after 4 cycles, provided
that the second multiply has no data dependency on the first;
o No instruction can be issued to pipe e0 exactly two cycles before
an integer multiplication complete. */
MULL, MULLV: e0 + multiplier_write_back + multiplier*4 %nothing*2
multiplier_write_back
;
/* Class IMULL with 1 cycle delay */
MULL1, MULLV1: e0 + multiplier_write_back %nothing + multiplier*4
%nothing*2 multiplier_write_back
;
/* Class IMULL with 2 cycles delay */
MULL2, MULLV2: e0 + multiplier_write_back %nothing*2 + multiplier*4
%nothing*2 multiplier_write_back
;
/* Class IMULQ:
o Sixty-for-bit signed multiplies have an 12-cycle latency, and the
multiplier can start a second multiply after 8 cycles, provided
that the second multiply has no data dependency on the first;
o No instruction can be issued to pipe e0 exactly two cycles before
an integer multiplication complete. */
MULQ, MULQV: e0 + multiplier_write_back + multiplier*8 %nothing*2
multiplier_write_back
;
/* Class IMULQ with 1 cycle delay */
MULQ1, MULQV1: e0 + multiplier_write_back %nothing + multiplier*8
%nothing*2 multiplier_write_back
;
/* Class IMULQ with 2 cycles delay */
MULQ2, MULQV2: e0 + multiplier_write_back %nothing*2 + multiplier*8
%nothing*2 multiplier_write_back
;
/* Class IMULH
o Sixty-for-bit unsigend multiplies have an 14-cycle latency, and
the multiplier can start a second multiply after 8 cycles, provided
that the second multiply has no data dependency on the first;
o No instruction can be issued to pipe e0 exactly two cycles before
an integer multiplication complete. */
UMULH: e0 + multiplier_write_back + multiplier*8 %nothing*4
multiplier_write_back
;
/* Class IMULH with 1 cycle delay */
UMULH1: e0 + multiplier_write_back %nothing + multiplier*8 %nothing*4
multiplier_write_back
;
/* Class IMULH with 2 cycles delay */
UMULH2: e0 + multiplier_write_back %nothing*2 + multiplier*8 %nothing*4
multiplier_write_back
;
/* Class FADD */
ADDS, ADDT, SUBS, SUBT, CPYSN, CPYSE, CVTLQ, CVTQL, CVTTQ,
FCMOVEQ, FCMOVNE, FCMOVLE, FCMOVLT, FCMOVGE, FCMOVGT:
fa + divider_write_back
;
/* Class FDIV:
o 2.4 bits per cycle average rate. The next floating divide can be
issued in the same cycle the result of the previous divide's result
is avialable.
o Instruction issue to teh add pipeline continues whaile a divide
is in progress until the result is ready. At that point the issue
stage in the instruction umit stalls one cycle to allow the
quotient to be sent the round adder and then be written into the
register file. */
DIVS: fa + float_divider*18 + divider_write_back
;
/* Class FDIV:
o 2.4 bits per cycle average rate. The next floating divide can be
issued in the same cycle the result of the previous divide's result
is avialable.
o Instruction issue to teh add pipeline continues whaile a divide
is in progress until the result is ready. At that point the issue
stage in the instruction umit stalls one cycle to allow the
quotient to be sent the round adder and then be written into the
register file. */
DIVT: fa + float_divider*30 + divider_write_back
;
/* Class FMUL */
MULS, MULT: fm
;
/* Class FCPYS */
CPYS: (fa + divider_write_back | fm)
;
/* Class MISC */
RPCC, TRAPB: e0 + multiplier_write_back
;
/* Class UNOP */
UNOP: %nothing
;