1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
|
#include "compiler/Scheduler.h"
#include "compiler/PCode.h"
#include "compiler/PCodeInfo.h"
// https://archive.org/details/bitsavers_motorolaPosManualNov94_22719504
typedef enum Stage {
SCIU, // Single-Cycle Integer Unit 1
SCIU2, // Single-Cycle Integer Unit 2
MCIU, // Multiple-Cycle Integer Unit
FPU1, // Floating Point Unit
FPU2,
FPU3,
LSU1, // Load/Store Unit
LSU2,
BPU, // Branch Prediction Unit
NumStages
} Stage;
static struct {
// the instruction currently in this pipeline stage
PCode *instr;
// how many cycles are left for this instruction to finish
int remaining;
} pipeline[NumStages];
enum {
MaxEntries = 16
};
static struct {
// how many entries remain unused in the queue
unsigned int free;
// how many entries are currently used in the queue
unsigned int used;
// the index of the next instruction that will be retired
unsigned int nextToRetire;
// the index of the next free slot that will be used when an instruction is dispatched
unsigned int nextFreeSlot;
// circular array of entries in the completion queue
struct {
PCode *instr;
int completed;
} entries[MaxEntries];
} completionbuffers;
static PCode *sciu_completed_instruction;
static PCode *sciu2_completed_instruction;
static struct {
// the initial stage for this instruction
Stage stage;
// the total amount of cycles required by this instruction
char latency;
// how long it takes to finish each stage
char cycles[3];
// does this instruction serialise?
char serializes;
} instruction_timing[OPCODE_MAX] = {
BPU, 0, 0, 0, 0, 1, // PC_B
BPU, 0, 0, 0, 0, 1, // PC_BL
BPU, 0, 0, 0, 0, 1, // PC_BC
BPU, 0, 0, 0, 0, 1, // PC_BCLR
BPU, 0, 0, 0, 0, 1, // PC_BCCTR
BPU, 0, 0, 0, 0, 1, // PC_BT
BPU, 0, 0, 0, 0, 1, // PC_BTLR
BPU, 0, 0, 0, 0, 1, // PC_BTCTR
BPU, 0, 0, 0, 0, 1, // PC_BF
BPU, 0, 0, 0, 0, 1, // PC_BFLR
BPU, 0, 0, 0, 0, 1, // PC_BFCTR
BPU, 0, 0, 0, 0, 1, // PC_BDNZ
BPU, 0, 0, 0, 0, 1, // PC_BDNZT
BPU, 0, 0, 0, 0, 1, // PC_BDNZF
BPU, 0, 0, 0, 0, 1, // PC_BDZ
BPU, 0, 0, 0, 0, 1, // PC_BDZT
BPU, 0, 0, 0, 0, 1, // PC_BDZF
BPU, 0, 0, 0, 0, 1, // PC_BLR
BPU, 0, 0, 0, 0, 1, // PC_BCTR
BPU, 0, 0, 0, 0, 1, // PC_BCTRL
BPU, 0, 0, 0, 0, 1, // PC_BLRL
LSU1, 2, 1, 1, 0, 0, // PC_LBZ
LSU1, 2, 1, 1, 0, 0, // PC_LBZU
LSU1, 2, 1, 1, 0, 0, // PC_LBZX
LSU1, 2, 1, 1, 0, 0, // PC_LBZUX
LSU1, 2, 1, 1, 0, 0, // PC_LHZ
LSU1, 2, 1, 1, 0, 0, // PC_LHZU
LSU1, 2, 1, 1, 0, 0, // PC_LHZX
LSU1, 2, 1, 1, 0, 0, // PC_LHZUX
LSU1, 2, 1, 1, 0, 0, // PC_LHA
LSU1, 2, 1, 1, 0, 0, // PC_LHAU
LSU1, 2, 1, 1, 0, 0, // PC_LHAX
LSU1, 2, 1, 1, 0, 0, // PC_LHAUX
LSU1, 2, 1, 1, 0, 0, // PC_LHBRX
LSU1, 2, 1, 1, 0, 0, // PC_LWZ
LSU1, 2, 1, 1, 0, 0, // PC_LWZU
LSU1, 2, 1, 1, 0, 0, // PC_LWZX
LSU1, 2, 1, 1, 0, 0, // PC_LWZUX
LSU1, 2, 1, 1, 0, 0, // PC_LWBRX
LSU1, 2, 1, 1, 0, 0, // PC_LMW
LSU1, 3, 1, 1, 0, 0, // PC_STB
LSU1, 3, 1, 1, 0, 0, // PC_STBU
LSU1, 3, 1, 1, 0, 0, // PC_STBX
LSU1, 3, 1, 1, 0, 0, // PC_STBUX
LSU1, 3, 1, 1, 0, 0, // PC_STH
LSU1, 3, 1, 1, 0, 0, // PC_STHU
LSU1, 3, 1, 1, 0, 0, // PC_STHX
LSU1, 3, 1, 1, 0, 0, // PC_STHUX
LSU1, 3, 1, 1, 0, 0, // PC_STHBRX
LSU1, 3, 1, 1, 0, 0, // PC_STW
LSU1, 3, 1, 1, 0, 0, // PC_STWU
LSU1, 3, 1, 1, 0, 0, // PC_STWX
LSU1, 3, 1, 1, 0, 0, // PC_STWUX
LSU1, 3, 1, 1, 0, 0, // PC_STWBRX
LSU1, 2, 1, 1, 0, 0, // PC_STMW
LSU1, 2, 1, 1, 0, 0, // PC_DCBF
LSU1, 2, 1, 1, 0, 0, // PC_DCBST
LSU1, 2, 1, 1, 0, 0, // PC_DCBT
LSU1, 2, 1, 1, 0, 0, // PC_DCBTST
LSU1, 2, 1, 1, 0, 0, // PC_DCBZ
SCIU, 1, 1, 0, 0, 0, // PC_ADD
SCIU, 1, 1, 0, 0, 0, // PC_ADDC
SCIU, 1, 1, 0, 0, 0, // PC_ADDE
SCIU, 1, 1, 0, 0, 0, // PC_ADDI
SCIU, 1, 1, 0, 0, 0, // PC_ADDIC
SCIU, 1, 1, 0, 0, 0, // PC_ADDICR
SCIU, 1, 1, 0, 0, 0, // PC_ADDIS
SCIU, 1, 1, 0, 0, 0, // PC_ADDME
SCIU, 1, 1, 0, 0, 0, // PC_ADDZE
MCIU, 20, 20, 0, 0, 0, // PC_DIVW
MCIU, 20, 20, 0, 0, 0, // PC_DIVWU
MCIU, 4, 4, 0, 0, 0, // PC_MULHW
MCIU, 4, 4, 0, 0, 0, // PC_MULHWU
MCIU, 3, 3, 0, 0, 0, // PC_MULLI
MCIU, 4, 4, 0, 0, 0, // PC_MULLW
SCIU, 1, 1, 0, 0, 0, // PC_NEG
SCIU, 1, 1, 0, 0, 0, // PC_SUBF
SCIU, 1, 1, 0, 0, 0, // PC_SUBFC
SCIU, 1, 1, 0, 0, 0, // PC_SUBFE
SCIU, 1, 1, 0, 0, 0, // PC_SUBFIC
SCIU, 1, 1, 0, 0, 0, // PC_SUBFME
SCIU, 1, 1, 0, 0, 0, // PC_SUBFZE
SCIU, 3, 1, 0, 0, 0, // PC_CMPI
SCIU, 3, 1, 0, 0, 0, // PC_CMP
SCIU, 3, 1, 0, 0, 0, // PC_CMPLI
SCIU, 3, 1, 0, 0, 0, // PC_CMPL
SCIU, 1, 1, 0, 0, 0, // PC_ANDI
SCIU, 1, 1, 0, 0, 0, // PC_ANDIS
SCIU, 1, 1, 0, 0, 0, // PC_ORI
SCIU, 1, 1, 0, 0, 0, // PC_ORIS
SCIU, 1, 1, 0, 0, 0, // PC_XORI
SCIU, 1, 1, 0, 0, 0, // PC_XORIS
SCIU, 1, 1, 0, 0, 0, // PC_AND
SCIU, 1, 1, 0, 0, 0, // PC_OR
SCIU, 1, 1, 0, 0, 0, // PC_XOR
SCIU, 1, 1, 0, 0, 0, // PC_NAND
SCIU, 1, 1, 0, 0, 0, // PC_NOR
SCIU, 1, 1, 0, 0, 0, // PC_EQV
SCIU, 1, 1, 0, 0, 0, // PC_ANDC
SCIU, 1, 1, 0, 0, 0, // PC_ORC
SCIU, 1, 1, 0, 0, 0, // PC_EXTSB
SCIU, 1, 1, 0, 0, 0, // PC_EXTSH
SCIU, 1, 1, 0, 0, 0, // PC_CNTLZW
SCIU, 1, 1, 0, 0, 0, // PC_RLWINM
SCIU, 1, 1, 0, 0, 0, // PC_RLWNM
SCIU, 1, 1, 0, 0, 0, // PC_RLWIMI
SCIU, 1, 1, 0, 0, 0, // PC_SLW
SCIU, 1, 1, 0, 0, 0, // PC_SRW
SCIU, 1, 1, 0, 0, 0, // PC_SRAWI
SCIU, 1, 1, 0, 0, 0, // PC_SRAW
BPU, 1, 1, 0, 0, 0, // PC_CRAND
BPU, 1, 1, 0, 0, 0, // PC_CRANDC
BPU, 1, 1, 0, 0, 0, // PC_CREQV
BPU, 1, 1, 0, 0, 0, // PC_CRNAND
BPU, 1, 1, 0, 0, 0, // PC_CRNOR
BPU, 1, 1, 0, 0, 0, // PC_CROR
BPU, 1, 1, 0, 0, 0, // PC_CRORC
BPU, 1, 1, 0, 0, 0, // PC_CRXOR
BPU, 1, 1, 0, 0, 0, // PC_MCRF
MCIU, 1, 1, 0, 0, 0, // PC_MTXER
MCIU, 1, 1, 0, 0, 0, // PC_MTCTR
MCIU, 1, 1, 0, 0, 0, // PC_MTLR
MCIU, 1, 1, 0, 0, 0, // PC_MTCRF
MCIU, 1, 1, 0, 0, 0, // PC_MTMSR
MCIU, 1, 1, 0, 0, 0, // PC_MTSPR
MCIU, 1, 1, 0, 0, 0, // PC_MFMSR
MCIU, 1, 1, 0, 0, 0, // PC_MFSPR
MCIU, 3, 3, 0, 0, 0, // PC_MFXER
MCIU, 3, 3, 0, 0, 0, // PC_MFCTR
MCIU, 3, 3, 0, 0, 0, // PC_MFLR
MCIU, 3, 3, 0, 0, 0, // PC_MFCR
FPU1, 3, 1, 1, 1, 0, // PC_MFFS
FPU1, 3, 1, 1, 1, 0, // PC_MTFSF
LSU1, 1, 0, 0, 0, 1, // PC_EIEIO
LSU1, 1, 0, 0, 0, 1, // PC_ISYNC
LSU1, 1, 0, 0, 0, 1, // PC_SYNC
LSU1, 1, 1, 0, 0, 1, // PC_RFI
SCIU, 1, 1, 0, 0, 0, // PC_LI
SCIU, 1, 1, 0, 0, 0, // PC_LIS
SCIU, 1, 1, 0, 0, 0, // PC_MR
SCIU, 1, 1, 0, 0, 0, // PC_NOP
SCIU, 1, 1, 0, 0, 0, // PC_NOT
LSU1, 3, 1, 1, 0, 0, // PC_LFS
LSU1, 3, 1, 1, 0, 0, // PC_LFSU
LSU1, 3, 1, 1, 0, 0, // PC_LFSX
LSU1, 3, 1, 1, 0, 0, // PC_LFSUX
LSU1, 3, 1, 1, 0, 0, // PC_LFD
LSU1, 3, 1, 1, 0, 0, // PC_LFDU
LSU1, 3, 1, 1, 0, 0, // PC_LFDX
LSU1, 3, 1, 1, 0, 0, // PC_LFDUX
LSU1, 3, 1, 1, 0, 0, // PC_STFS
LSU1, 3, 1, 1, 0, 0, // PC_STFSU
LSU1, 3, 1, 1, 0, 0, // PC_STFSX
LSU1, 3, 1, 1, 0, 0, // PC_STFSUX
LSU1, 3, 1, 1, 0, 0, // PC_STFD
LSU1, 3, 1, 1, 0, 0, // PC_STFDU
LSU1, 3, 1, 1, 0, 0, // PC_STFDX
LSU1, 3, 1, 1, 0, 0, // PC_STFDUX
FPU1, 3, 1, 1, 1, 0, // PC_FMR
FPU1, 3, 1, 1, 1, 0, // PC_FABS
FPU1, 3, 1, 1, 1, 0, // PC_FNEG
FPU1, 3, 1, 1, 1, 0, // PC_FNABS
FPU1, 3, 1, 1, 1, 0, // PC_FADD
FPU1, 3, 1, 1, 1, 0, // PC_FADDS
FPU1, 3, 1, 1, 1, 0, // PC_FSUB
FPU1, 3, 1, 1, 1, 0, // PC_FSUBS
FPU1, 3, 1, 1, 1, 0, // PC_FMUL
FPU1, 3, 1, 1, 1, 0, // PC_FMULS
FPU1, 32, 32, 0, 0, 0, // PC_FDIV
FPU1, 18, 18, 0, 0, 0, // PC_FDIVS
FPU1, 3, 1, 1, 1, 0, // PC_FMADD
FPU1, 3, 1, 1, 1, 0, // PC_FMADDS
FPU1, 3, 1, 1, 1, 0, // PC_FMSUB
FPU1, 3, 1, 1, 1, 0, // PC_FMSUBS
FPU1, 3, 1, 1, 1, 0, // PC_FNMADD
FPU1, 3, 1, 1, 1, 0, // PC_FNMADDS
FPU1, 3, 1, 1, 1, 0, // PC_FNMSUB
FPU1, 3, 1, 1, 1, 0, // PC_FNMSUBS
FPU1, 18, 18, 0, 0, 0, // PC_FRES
FPU1, 3, 1, 1, 1, 0, // PC_FRSQRTE
FPU1, 3, 1, 1, 1, 0, // PC_FSEL
FPU1, 3, 1, 1, 1, 0, // PC_FRSP
FPU1, 3, 1, 1, 1, 0, // PC_FCTIW
FPU1, 3, 1, 1, 1, 0, // PC_FCTIWZ
FPU1, 5, 1, 1, 1, 0, // PC_FCMPU
FPU1, 5, 1, 1, 1, 0, // PC_FCMPO
LSU1, 1, 1, 0, 0, 0, // PC_LWARX
LSU1, 1, 1, 0, 0, 0, // PC_LSWI
LSU1, 1, 1, 0, 0, 0, // PC_LSWX
LSU1, 1, 1, 0, 0, 0, // PC_STFIWX
LSU1, 1, 1, 0, 0, 0, // PC_STSWI
LSU1, 1, 1, 0, 0, 0, // PC_STSWX
LSU1, 1, 1, 0, 0, 0, // PC_STWCX
MCIU, 1, 1, 0, 0, 1, // PC_ECIWX
MCIU, 1, 1, 0, 0, 1, // PC_ECOWX
MCIU, 1, 1, 0, 0, 0, // PC_DCBI
MCIU, 1, 1, 0, 0, 0, // PC_ICBI
MCIU, 1, 1, 0, 0, 0, // PC_MCRFS
MCIU, 1, 1, 0, 0, 0, // PC_MCRXR
MCIU, 1, 1, 0, 0, 0, // PC_MFTB
MCIU, 1, 1, 0, 0, 0, // PC_MFSR
MCIU, 1, 1, 0, 0, 0, // PC_MTSR
MCIU, 1, 1, 0, 0, 0, // PC_MFSRIN
MCIU, 1, 1, 0, 0, 0, // PC_MTSRIN
MCIU, 1, 1, 0, 0, 0, // PC_MTFSB0
MCIU, 1, 1, 0, 0, 0, // PC_MTFSB1
MCIU, 1, 1, 0, 0, 0, // PC_MTFSFI
MCIU, 1, 1, 0, 0, 1, // PC_SC
FPU1, 1, 1, 0, 0, 0, // PC_FSQRT
FPU1, 1, 1, 0, 0, 0, // PC_FSQRTS
MCIU, 1, 1, 0, 0, 0, // PC_TLBIA
MCIU, 1, 1, 0, 0, 0, // PC_TLBIE
MCIU, 1, 1, 0, 0, 0, // PC_TLBLD
MCIU, 1, 1, 0, 0, 0, // PC_TLBLI
MCIU, 1, 1, 0, 0, 0, // PC_TLBSYNC
MCIU, 1, 1, 0, 0, 1, // PC_TW
MCIU, 1, 1, 0, 0, 1, // PC_TRAP
MCIU, 1, 1, 0, 0, 1, // PC_TWI
MCIU, 1, 1, 0, 0, 1, // PC_OPWORD
MCIU, 1, 1, 0, 0, 0, // PC_MFROM
MCIU, 1, 1, 0, 0, 1, // PC_DSA
MCIU, 1, 1, 0, 0, 1, // PC_ESA
MCIU, 0, 0, 0, 0, 0, // PC_DCCCI
MCIU, 0, 0, 0, 0, 0, // PC_DCREAD
MCIU, 0, 0, 0, 0, 0, // PC_ICBT
MCIU, 0, 0, 0, 0, 0, // PC_ICCCI
MCIU, 0, 0, 0, 0, 0, // PC_ICREAD
MCIU, 0, 0, 0, 0, 0, // PC_RFCI
MCIU, 0, 0, 0, 0, 0, // PC_TLBRE
MCIU, 0, 0, 0, 0, 0, // PC_TLBSX
MCIU, 0, 0, 0, 0, 0, // PC_TLBWE
MCIU, 0, 0, 0, 0, 0, // PC_WRTEE
MCIU, 0, 0, 0, 0, 0, // PC_WRTEEI
MCIU, 0, 0, 0, 0, 0, // PC_MFDCR
MCIU, 0, 0, 0, 0, 0, // PC_MTDCR
MCIU, 0, 0, 0, 0, 0, // PC_DCBA
SCIU, 0, 0, 0, 0, 0, // PC_DSS
SCIU, 0, 0, 0, 0, 0, // PC_DSSALL
SCIU, 0, 0, 0, 0, 0, // PC_DST
SCIU, 0, 0, 0, 0, 0, // PC_DSTT
SCIU, 0, 0, 0, 0, 0, // PC_DSTST
SCIU, 0, 0, 0, 0, 0, // PC_DSTSTT
SCIU, 0, 0, 0, 0, 0, // PC_LVEBX
SCIU, 0, 0, 0, 0, 0, // PC_LVEHX
SCIU, 0, 0, 0, 0, 0, // PC_LVEWX
SCIU, 0, 0, 0, 0, 0, // PC_LVSL
SCIU, 0, 0, 0, 0, 0, // PC_LVSR
SCIU, 0, 0, 0, 0, 0, // PC_LVX
SCIU, 0, 0, 0, 0, 0, // PC_LVXL
SCIU, 0, 0, 0, 0, 0, // PC_STVEBX
SCIU, 0, 0, 0, 0, 0, // PC_STVEHX
SCIU, 0, 0, 0, 0, 0, // PC_STVEWX
SCIU, 0, 0, 0, 0, 0, // PC_STVX
SCIU, 0, 0, 0, 0, 0, // PC_STVXL
SCIU, 0, 0, 0, 0, 0, // PC_MFVSCR
SCIU, 0, 0, 0, 0, 0, // PC_MTVSCR
SCIU, 0, 0, 0, 0, 0, // PC_VADDCUW
SCIU, 0, 0, 0, 0, 0, // PC_VADDFP
SCIU, 0, 0, 0, 0, 0, // PC_VADDSBS
SCIU, 0, 0, 0, 0, 0, // PC_VADDSHS
SCIU, 0, 0, 0, 0, 0, // PC_VADDSWS
SCIU, 0, 0, 0, 0, 0, // PC_VADDUBM
SCIU, 0, 0, 0, 0, 0, // PC_VADDUBS
SCIU, 0, 0, 0, 0, 0, // PC_VADDUHM
SCIU, 0, 0, 0, 0, 0, // PC_VADDUHS
SCIU, 0, 0, 0, 0, 0, // PC_VADDUWM
SCIU, 0, 0, 0, 0, 0, // PC_VADDUWS
SCIU, 0, 0, 0, 0, 0, // PC_VAND
SCIU, 0, 0, 0, 0, 0, // PC_VANDC
SCIU, 0, 0, 0, 0, 0, // PC_VAVGSB
SCIU, 0, 0, 0, 0, 0, // PC_VAVGSH
SCIU, 0, 0, 0, 0, 0, // PC_VAVGSW
SCIU, 0, 0, 0, 0, 0, // PC_VAVGUB
SCIU, 0, 0, 0, 0, 0, // PC_VAVGUH
SCIU, 0, 0, 0, 0, 0, // PC_VAVGUW
SCIU, 0, 0, 0, 0, 0, // PC_VCFSX
SCIU, 0, 0, 0, 0, 0, // PC_VCFUX
SCIU, 0, 0, 0, 0, 0, // PC_VCMPBFP
SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQFP
SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUB
SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUH
SCIU, 0, 0, 0, 0, 0, // PC_VCMPEQUW
SCIU, 0, 0, 0, 0, 0, // PC_VCMPGEFP
SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTFP
SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSB
SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSH
SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTSW
SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUB
SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUH
SCIU, 0, 0, 0, 0, 0, // PC_VCMPGTUW
SCIU, 0, 0, 0, 0, 0, // PC_VCTSXS
SCIU, 0, 0, 0, 0, 0, // PC_VCTUXS
SCIU, 0, 0, 0, 0, 0, // PC_VEXPTEFP
SCIU, 0, 0, 0, 0, 0, // PC_VLOGEFP
SCIU, 0, 0, 0, 0, 0, // PC_VMAXFP
SCIU, 0, 0, 0, 0, 0, // PC_VMAXSB
SCIU, 0, 0, 0, 0, 0, // PC_VMAXSH
SCIU, 0, 0, 0, 0, 0, // PC_VMAXSW
SCIU, 0, 0, 0, 0, 0, // PC_VMAXUB
SCIU, 0, 0, 0, 0, 0, // PC_VMAXUH
SCIU, 0, 0, 0, 0, 0, // PC_VMAXUW
SCIU, 0, 0, 0, 0, 0, // PC_VMINFP
SCIU, 0, 0, 0, 0, 0, // PC_VMINSB
SCIU, 0, 0, 0, 0, 0, // PC_VMINSH
SCIU, 0, 0, 0, 0, 0, // PC_VMINSW
SCIU, 0, 0, 0, 0, 0, // PC_VMINUB
SCIU, 0, 0, 0, 0, 0, // PC_VMINUH
SCIU, 0, 0, 0, 0, 0, // PC_VMINUW
SCIU, 0, 0, 0, 0, 0, // PC_VMRGHB
SCIU, 0, 0, 0, 0, 0, // PC_VMRGHH
SCIU, 0, 0, 0, 0, 0, // PC_VMRGHW
SCIU, 0, 0, 0, 0, 0, // PC_VMRGLB
SCIU, 0, 0, 0, 0, 0, // PC_VMRGLH
SCIU, 0, 0, 0, 0, 0, // PC_VMRGLW
SCIU, 0, 0, 0, 0, 0, // PC_VMULESB
SCIU, 0, 0, 0, 0, 0, // PC_VMULESH
SCIU, 0, 0, 0, 0, 0, // PC_VMULEUB
SCIU, 0, 0, 0, 0, 0, // PC_VMULEUH
SCIU, 0, 0, 0, 0, 0, // PC_VMULOSB
SCIU, 0, 0, 0, 0, 0, // PC_VMULOSH
SCIU, 0, 0, 0, 0, 0, // PC_VMULOUB
SCIU, 0, 0, 0, 0, 0, // PC_VMULOUH
SCIU, 0, 0, 0, 0, 0, // PC_VNOR
SCIU, 0, 0, 0, 0, 0, // PC_VOR
SCIU, 0, 0, 0, 0, 0, // PC_VPKPX
SCIU, 0, 0, 0, 0, 0, // PC_VPKSHSS
SCIU, 0, 0, 0, 0, 0, // PC_VPKSHUS
SCIU, 0, 0, 0, 0, 0, // PC_VPKSWSS
SCIU, 0, 0, 0, 0, 0, // PC_VPKSWUS
SCIU, 0, 0, 0, 0, 0, // PC_VPKUHUM
SCIU, 0, 0, 0, 0, 0, // PC_VPKUHUS
SCIU, 0, 0, 0, 0, 0, // PC_VPKUWUM
SCIU, 0, 0, 0, 0, 0, // PC_VPKUWUS
SCIU, 0, 0, 0, 0, 0, // PC_VREFP
SCIU, 0, 0, 0, 0, 0, // PC_VRFIM
SCIU, 0, 0, 0, 0, 0, // PC_VRFIN
SCIU, 0, 0, 0, 0, 0, // PC_VRFIP
SCIU, 0, 0, 0, 0, 0, // PC_VRFIZ
SCIU, 0, 0, 0, 0, 0, // PC_VRLB
SCIU, 0, 0, 0, 0, 0, // PC_VRLH
SCIU, 0, 0, 0, 0, 0, // PC_VRLW
SCIU, 0, 0, 0, 0, 0, // PC_VRSQRTEFP
SCIU, 0, 0, 0, 0, 0, // PC_VSL
SCIU, 0, 0, 0, 0, 0, // PC_VSLB
SCIU, 0, 0, 0, 0, 0, // PC_VSLH
SCIU, 0, 0, 0, 0, 0, // PC_VSLO
SCIU, 0, 0, 0, 0, 0, // PC_VSLW
SCIU, 0, 0, 0, 0, 0, // PC_VSPLTB
SCIU, 0, 0, 0, 0, 0, // PC_VSPLTH
SCIU, 0, 0, 0, 0, 0, // PC_VSPLTW
SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISB
SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISH
SCIU, 0, 0, 0, 0, 0, // PC_VSPLTISW
SCIU, 0, 0, 0, 0, 0, // PC_VSR
SCIU, 0, 0, 0, 0, 0, // PC_VSRAB
SCIU, 0, 0, 0, 0, 0, // PC_VSRAH
SCIU, 0, 0, 0, 0, 0, // PC_VSRAW
SCIU, 0, 0, 0, 0, 0, // PC_VSRB
SCIU, 0, 0, 0, 0, 0, // PC_VSRH
SCIU, 0, 0, 0, 0, 0, // PC_VSRO
SCIU, 0, 0, 0, 0, 0, // PC_VSRW
SCIU, 0, 0, 0, 0, 0, // PC_VSUBCUW
SCIU, 0, 0, 0, 0, 0, // PC_VSUBFP
SCIU, 0, 0, 0, 0, 0, // PC_VSUBSBS
SCIU, 0, 0, 0, 0, 0, // PC_VSUBSHS
SCIU, 0, 0, 0, 0, 0, // PC_VSUBSWS
SCIU, 0, 0, 0, 0, 0, // PC_VSUBUBM
SCIU, 0, 0, 0, 0, 0, // PC_VSUBUBS
SCIU, 0, 0, 0, 0, 0, // PC_VSUBUHM
SCIU, 0, 0, 0, 0, 0, // PC_VSUBUHS
SCIU, 0, 0, 0, 0, 0, // PC_VSUBUWM
SCIU, 0, 0, 0, 0, 0, // PC_VSUBUWS
SCIU, 0, 0, 0, 0, 0, // PC_VSUMSWS
SCIU, 0, 0, 0, 0, 0, // PC_VSUM2SWS
SCIU, 0, 0, 0, 0, 0, // PC_VSUM4SBS
SCIU, 0, 0, 0, 0, 0, // PC_VSUM4SHS
SCIU, 0, 0, 0, 0, 0, // PC_VSUM4UBS
SCIU, 0, 0, 0, 0, 0, // PC_VUPKHPX
SCIU, 0, 0, 0, 0, 0, // PC_VUPKHSB
SCIU, 0, 0, 0, 0, 0, // PC_VUPKHSH
SCIU, 0, 0, 0, 0, 0, // PC_VUPKLPX
SCIU, 0, 0, 0, 0, 0, // PC_VUPKLSB
SCIU, 0, 0, 0, 0, 0, // PC_VUPKLSH
SCIU, 0, 0, 0, 0, 0, // PC_VXOR
SCIU, 0, 0, 0, 0, 0, // PC_VMADDFP
SCIU, 0, 0, 0, 0, 0, // PC_VMHADDSHS
SCIU, 0, 0, 0, 0, 0, // PC_VMHRADDSHS
SCIU, 0, 0, 0, 0, 0, // PC_VMLADDUHM
SCIU, 0, 0, 0, 0, 0, // PC_VMSUMMBM
SCIU, 0, 0, 0, 0, 0, // PC_VMSUMSHM
SCIU, 0, 0, 0, 0, 0, // PC_VMSUMSHS
SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUBM
SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUHM
SCIU, 0, 0, 0, 0, 0, // PC_VMSUMUHS
SCIU, 0, 0, 0, 0, 0, // PC_VNMSUBFP
SCIU, 0, 0, 0, 0, 0, // PC_VPERM
SCIU, 0, 0, 0, 0, 0, // PC_VSEL
SCIU, 0, 0, 0, 0, 0, // PC_VSLDOI
SCIU, 0, 0, 0, 0, 0, // PC_VMR
SCIU, 0, 0, 0, 0, 0, // PC_VMRP
SCIU, 0, 0, 0, 0, 0, // PC_SLE
SCIU, 0, 0, 0, 0, 0, // PC_SLEQ
SCIU, 0, 0, 0, 0, 0, // PC_SLIQ
SCIU, 0, 0, 0, 0, 0, // PC_SLLIQ
SCIU, 0, 0, 0, 0, 0, // PC_SLLQ
SCIU, 0, 0, 0, 0, 0, // PC_SLQ
SCIU, 0, 0, 0, 0, 0, // PC_SRAIQ
SCIU, 0, 0, 0, 0, 0, // PC_SRAQ
SCIU, 0, 0, 0, 0, 0, // PC_SRE
SCIU, 0, 0, 0, 0, 0, // PC_SREA
SCIU, 0, 0, 0, 0, 0, // PC_SREQ
SCIU, 0, 0, 0, 0, 0, // PC_SRIQ
SCIU, 0, 0, 0, 0, 0, // PC_SRLIQ
SCIU, 0, 0, 0, 0, 0, // PC_SRLQ
SCIU, 0, 0, 0, 0, 0, // PC_SRQ
SCIU, 0, 0, 0, 0, 0, // PC_MASKG
SCIU, 0, 0, 0, 0, 0, // PC_MASKIR
SCIU, 0, 0, 0, 0, 0, // PC_LSCBX
SCIU, 0, 0, 0, 0, 0, // PC_DIV
SCIU, 0, 0, 0, 0, 0, // PC_DIVS
SCIU, 0, 0, 0, 0, 0, // PC_DOZ
SCIU, 0, 0, 0, 0, 0, // PC_MUL
SCIU, 0, 0, 0, 0, 0, // PC_NABS
SCIU, 0, 0, 0, 0, 0, // PC_ABS
SCIU, 0, 0, 0, 0, 0, // PC_CLCS
SCIU, 0, 0, 0, 0, 0, // PC_DOZI
SCIU, 0, 0, 0, 0, 0, // PC_RLMI
SCIU, 0, 0, 0, 0, 0, // PC_RRIB
};
static void advance(int firstStage, int oldStage, int newStage) {
PCode *instr = pipeline[oldStage].instr;
int cycles = instruction_timing[instr->op].cycles[newStage - firstStage];
pipeline[newStage].instr = instr;
pipeline[newStage].remaining = cycles;
pipeline[oldStage].instr = NULL;
}
static void assign_completion_buffer(PCode *instr) {
completionbuffers.used++;
completionbuffers.free--;
completionbuffers.entries[completionbuffers.nextFreeSlot].instr = instr;
completionbuffers.entries[completionbuffers.nextFreeSlot].completed = 0;
completionbuffers.nextFreeSlot = (completionbuffers.nextFreeSlot + 1) % MaxEntries;
}
static void complete_instruction(int stage) {
PCode *instr = pipeline[stage].instr;
int buf = 0;
while (buf < MaxEntries && completionbuffers.entries[buf].instr != instr)
buf++;
completionbuffers.entries[buf].completed = 1;
pipeline[stage].instr = NULL;
if (stage == SCIU)
sciu_completed_instruction = instr;
else if (stage == SCIU2)
sciu2_completed_instruction = instr;
}
static void retire_instruction(void) {
completionbuffers.entries[completionbuffers.nextToRetire].instr = NULL;
completionbuffers.used--;
completionbuffers.free++;
completionbuffers.nextToRetire = (completionbuffers.nextToRetire + 1) % MaxEntries;
}
static int latency(PCode *instr) {
int cycles = instruction_timing[instr->op].latency;
if (PCODE_FLAG_SET_F(instr) & fRecordBit)
cycles += 2;
if (instr->op == PC_LMW || instr->op == PC_STMW)
cycles += instr->argCount - 2;
return cycles;
}
static void initialize(void) {
int stage;
int i;
for (stage = 0; stage < NumStages; stage++)
pipeline[stage].instr = NULL;
completionbuffers.free = MaxEntries;
completionbuffers.used = 0;
completionbuffers.nextToRetire = 0;
completionbuffers.nextFreeSlot = 0;
for (i = 0; i < MaxEntries; i++)
completionbuffers.entries[i].instr = NULL;
sciu_completed_instruction = NULL;
sciu2_completed_instruction = NULL;
}
static int can_issue(PCode *instr) {
PCode *check;
int stage = instruction_timing[instr->op].stage;
if (completionbuffers.free == 0)
return 0;
if (stage == SCIU) {
int isClear1 = !pipeline[SCIU].instr;
int isClear2 = !pipeline[SCIU2].instr;
if (!isClear1 && !isClear2)
return 0;
if (isClear1 && isClear2)
return 1;
if (isClear1)
check = pipeline[SCIU2].instr;
else
check = pipeline[SCIU].instr;
if (is_dependent(instr, check, RegClass_GPR))
return 0;
if (is_dependent(instr, sciu_completed_instruction, RegClass_GPR))
return 0;
if (is_dependent(instr, sciu2_completed_instruction, RegClass_GPR))
return 0;
} else {
if (pipeline[stage].instr)
return 0;
}
return 1;
}
static void issue(PCode *instr) {
int stage = instruction_timing[instr->op].stage;
int cycles = instruction_timing[instr->op].cycles[0];
if (stage == SCIU && pipeline[SCIU].instr)
stage = SCIU2;
assign_completion_buffer(instr);
pipeline[stage].instr = instr;
pipeline[stage].remaining = cycles;
}
static void advance_clock(void) {
int stage;
int i;
sciu_completed_instruction = NULL;
sciu2_completed_instruction = NULL;
for (stage = 0; stage < NumStages; stage++) {
if (pipeline[stage].instr && pipeline[stage].remaining)
--pipeline[stage].remaining;
}
for (i = 0; i < 5; i++) {
if (completionbuffers.used == 0)
break;
if (completionbuffers.entries[completionbuffers.nextToRetire].completed == 0)
break;
retire_instruction();
}
if (pipeline[SCIU].instr && pipeline[SCIU].remaining == 0)
complete_instruction(SCIU);
if (pipeline[SCIU2].instr && pipeline[SCIU2].remaining == 0)
complete_instruction(SCIU2);
if (pipeline[MCIU].instr && pipeline[MCIU].remaining == 0)
complete_instruction(MCIU);
if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0)
complete_instruction(LSU2);
if (pipeline[FPU3].instr && pipeline[FPU3].remaining == 0)
complete_instruction(FPU3);
if (pipeline[BPU].instr && pipeline[BPU].remaining == 0)
complete_instruction(BPU);
if (
pipeline[FPU1].instr &&
pipeline[FPU1].remaining == 0 &&
(pipeline[FPU1].instr->op == PC_FDIV || pipeline[FPU1].instr->op == PC_FDIVS)
)
complete_instruction(FPU1);
if (pipeline[FPU2].instr && pipeline[FPU2].remaining == 0 && !pipeline[FPU3].instr)
advance(FPU1, FPU2, FPU3);
if (pipeline[FPU1].instr && pipeline[FPU1].remaining == 0 && !pipeline[FPU2].instr)
advance(FPU1, FPU1, FPU2);
if (pipeline[LSU1].instr && pipeline[LSU1].remaining == 0 && !pipeline[LSU2].instr)
advance(LSU1, LSU1, LSU2);
}
static int serializes(PCode *instr) {
return instruction_timing[instr->op].serializes;
}
MachineInfo machine604 = {
4,
1,
0,
&latency,
&initialize,
&can_issue,
&issue,
&advance_clock,
&serializes,
&default_uses_vpermute_unit
};
|