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
|
#include "compiler/Scheduler.h"
#include "compiler/PCode.h"
#include "compiler/PCodeInfo.h"
// https://www.nxp.com/docs/en/user-guide/MPC821UM.pdf
typedef enum Stage {
BranchUnit,
Stage1,
Stage2,
LSU1,
LSU2,
CRUnit,
NumStages,
Stage7
} 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 = 6
};
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 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] = {
BranchUnit, 0, 0, 0, 0, 0, // PC_B
BranchUnit, 0, 0, 0, 0, 0, // PC_BL
BranchUnit, 0, 0, 0, 0, 0, // PC_BC
BranchUnit, 0, 0, 0, 0, 0, // PC_BCLR
BranchUnit, 0, 0, 0, 0, 0, // PC_BCCTR
BranchUnit, 0, 0, 0, 0, 0, // PC_BT
BranchUnit, 0, 0, 0, 0, 0, // PC_BTLR
BranchUnit, 0, 0, 0, 0, 0, // PC_BTCTR
BranchUnit, 0, 0, 0, 0, 0, // PC_BF
BranchUnit, 0, 0, 0, 0, 0, // PC_BFLR
BranchUnit, 0, 0, 0, 0, 0, // PC_BFCTR
BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZ
BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZT
BranchUnit, 0, 0, 0, 0, 0, // PC_BDNZF
BranchUnit, 0, 0, 0, 0, 0, // PC_BDZ
BranchUnit, 0, 0, 0, 0, 0, // PC_BDZT
BranchUnit, 0, 0, 0, 0, 0, // PC_BDZF
BranchUnit, 0, 0, 0, 0, 0, // PC_BLR
BranchUnit, 0, 0, 0, 0, 0, // PC_BCTR
BranchUnit, 0, 0, 0, 0, 0, // PC_BCTRL
BranchUnit, 0, 0, 0, 0, 0, // PC_BLRL
BranchUnit, 0, 0, 0, 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, 2, 1, 1, 0, 0, // PC_STB
LSU1, 2, 1, 1, 0, 0, // PC_STBU
LSU1, 2, 1, 1, 0, 0, // PC_STBX
LSU1, 2, 1, 1, 0, 0, // PC_STBUX
LSU1, 2, 1, 1, 0, 0, // PC_STH
LSU1, 2, 1, 1, 0, 0, // PC_STHU
LSU1, 2, 1, 1, 0, 0, // PC_STHX
LSU1, 2, 1, 1, 0, 0, // PC_STHUX
LSU1, 2, 1, 1, 0, 0, // PC_STHBRX
LSU1, 2, 1, 1, 0, 0, // PC_STW
LSU1, 2, 1, 1, 0, 0, // PC_STWU
LSU1, 2, 1, 1, 0, 0, // PC_STWX
LSU1, 2, 1, 1, 0, 0, // PC_STWUX
LSU1, 2, 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
LSU1, 2, 1, 1, 0, 0, // PC_ADD
Stage1, 1, 1, 0, 0, 0, // PC_ADDC
Stage1, 1, 1, 0, 0, 0, // PC_ADDE
Stage1, 1, 1, 0, 0, 0, // PC_ADDI
Stage1, 1, 1, 0, 0, 0, // PC_ADDIC
Stage1, 1, 1, 0, 0, 0, // PC_ADDICR
Stage1, 1, 1, 0, 0, 0, // PC_ADDIS
Stage1, 1, 1, 0, 0, 0, // PC_ADDME
Stage1, 1, 1, 0, 0, 0, // PC_ADDZE
Stage1, 1, 1, 0, 0, 0, // PC_DIVW
Stage1, 37, 37, 0, 0, 0, // PC_DIVWU
Stage1, 37, 37, 0, 0, 0, // PC_MULHW
Stage1, 5, 5, 0, 0, 0, // PC_MULHWU
Stage1, 5, 5, 0, 0, 0, // PC_MULLI
Stage1, 3, 3, 0, 0, 0, // PC_MULLW
Stage1, 5, 5, 0, 0, 0, // PC_NEG
Stage1, 1, 1, 0, 0, 0, // PC_SUBF
Stage1, 1, 1, 0, 0, 0, // PC_SUBFC
Stage1, 1, 1, 0, 0, 0, // PC_SUBFE
Stage1, 1, 1, 0, 0, 0, // PC_SUBFIC
Stage1, 1, 1, 0, 0, 0, // PC_SUBFME
Stage1, 1, 1, 0, 0, 0, // PC_SUBFZE
Stage1, 1, 1, 0, 0, 0, // PC_CMPI
Stage1, 3, 1, 0, 0, 0, // PC_CMP
Stage1, 3, 1, 0, 0, 0, // PC_CMPLI
Stage1, 3, 1, 0, 0, 0, // PC_CMPL
Stage1, 3, 1, 0, 0, 0, // PC_ANDI
Stage1, 1, 1, 0, 0, 0, // PC_ANDIS
Stage1, 1, 1, 0, 0, 0, // PC_ORI
Stage1, 1, 1, 0, 0, 0, // PC_ORIS
Stage1, 1, 1, 0, 0, 0, // PC_XORI
Stage1, 1, 1, 0, 0, 0, // PC_XORIS
Stage1, 1, 1, 0, 0, 0, // PC_AND
Stage1, 1, 1, 0, 0, 0, // PC_OR
Stage1, 1, 1, 0, 0, 0, // PC_XOR
Stage1, 1, 1, 0, 0, 0, // PC_NAND
Stage1, 1, 1, 0, 0, 0, // PC_NOR
Stage1, 1, 1, 0, 0, 0, // PC_EQV
Stage1, 1, 1, 0, 0, 0, // PC_ANDC
Stage1, 1, 1, 0, 0, 0, // PC_ORC
Stage1, 1, 1, 0, 0, 0, // PC_EXTSB
Stage1, 1, 1, 0, 0, 0, // PC_EXTSH
Stage1, 1, 1, 0, 0, 0, // PC_CNTLZW
Stage1, 1, 1, 0, 0, 0, // PC_RLWINM
Stage1, 1, 1, 0, 0, 0, // PC_RLWNM
Stage1, 1, 1, 0, 0, 0, // PC_RLWIMI
Stage1, 1, 1, 0, 0, 0, // PC_SLW
Stage1, 1, 1, 0, 0, 0, // PC_SRW
Stage1, 1, 1, 0, 0, 0, // PC_SRAWI
Stage1, 1, 1, 0, 0, 0, // PC_SRAW
Stage1, 1, 1, 0, 0, 0, // PC_CRAND
CRUnit, 1, 1, 0, 0, 0, // PC_CRANDC
CRUnit, 1, 1, 0, 0, 0, // PC_CREQV
CRUnit, 1, 1, 0, 0, 0, // PC_CRNAND
CRUnit, 1, 1, 0, 0, 0, // PC_CRNOR
CRUnit, 1, 1, 0, 0, 0, // PC_CROR
CRUnit, 1, 1, 0, 0, 0, // PC_CRORC
CRUnit, 1, 1, 0, 0, 0, // PC_CRXOR
CRUnit, 1, 1, 0, 0, 0, // PC_MCRF
CRUnit, 1, 1, 0, 0, 0, // PC_MTXER
Stage1, 1, 1, 0, 0, 0, // PC_MTCTR
BranchUnit, 2, 2, 0, 0, 0, // PC_MTLR
BranchUnit, 2, 2, 0, 0, 0, // PC_MTCRF
Stage1, 1, 1, 0, 0, 0, // PC_MTMSR
Stage1, 1, 1, 0, 0, 0, // PC_MTSPR
Stage1, 1, 1, 0, 0, 0, // PC_MFMSR
Stage1, 1, 1, 0, 0, 0, // PC_MFSPR
Stage1, 1, 1, 0, 0, 0, // PC_MFXER
Stage7, 3, 1, 1, 1, 0, // PC_MFCTR
Stage7, 3, 1, 1, 1, 0, // PC_MFLR
Stage1, 1, 1, 0, 0, 0, // PC_MFCR
Stage1, 1, 1, 0, 0, 0, // PC_MFFS
Stage1, 1, 1, 0, 0, 0, // PC_MTFSF
Stage1, 1, 1, 0, 0, 0, // PC_EIEIO
Stage1, 1, 1, 0, 0, 0, // PC_ISYNC
Stage1, 1, 1, 0, 0, 0, // PC_SYNC
Stage1, 1, 1, 0, 0, 0, // PC_RFI
Stage1, 1, 1, 0, 0, 0, // PC_LI
LSU1, 2, 1, 1, 0, 0, // PC_LIS
LSU1, 2, 1, 1, 0, 0, // PC_MR
LSU1, 2, 1, 1, 0, 0, // PC_NOP
LSU1, 2, 1, 1, 0, 0, // PC_NOT
LSU1, 2, 1, 1, 0, 0, // PC_LFS
LSU1, 2, 1, 1, 0, 0, // PC_LFSU
LSU1, 2, 1, 1, 0, 0, // PC_LFSX
LSU1, 2, 1, 1, 0, 0, // PC_LFSUX
LSU1, 2, 1, 1, 0, 0, // PC_LFD
LSU1, 2, 1, 1, 0, 0, // PC_LFDU
LSU1, 2, 1, 1, 0, 0, // PC_LFDX
LSU1, 2, 1, 1, 0, 0, // PC_LFDUX
LSU1, 2, 1, 1, 0, 0, // PC_STFS
LSU1, 2, 1, 1, 0, 0, // PC_STFSU
LSU1, 2, 1, 1, 0, 0, // PC_STFSX
LSU1, 2, 1, 1, 0, 0, // PC_STFSUX
Stage7, 3, 1, 1, 1, 0, // PC_STFD
Stage7, 3, 1, 1, 1, 0, // PC_STFDU
Stage7, 3, 1, 1, 1, 0, // PC_STFDX
Stage7, 3, 1, 1, 1, 0, // PC_STFDUX
Stage7, 3, 1, 1, 1, 0, // PC_FMR
Stage7, 3, 1, 1, 1, 0, // PC_FABS
Stage7, 3, 1, 1, 1, 0, // PC_FNEG
Stage7, 3, 1, 1, 1, 0, // PC_FNABS
Stage7, 4, 2, 1, 1, 0, // PC_FADD
Stage7, 3, 1, 1, 1, 0, // PC_FADDS
Stage7, 33, 33, 0, 0, 0, // PC_FSUB
Stage7, 18, 18, 0, 0, 0, // PC_FSUBS
Stage7, 4, 2, 1, 1, 0, // PC_FMUL
Stage7, 3, 1, 1, 1, 0, // PC_FMULS
Stage7, 4, 2, 1, 1, 0, // PC_FDIV
Stage7, 3, 1, 1, 1, 0, // PC_FDIVS
Stage7, 4, 2, 1, 1, 0, // PC_FMADD
Stage7, 3, 1, 1, 1, 0, // PC_FMADDS
Stage7, 4, 2, 1, 1, 0, // PC_FMSUB
Stage7, 3, 1, 1, 1, 0, // PC_FMSUBS
Stage7, 18, 18, 0, 0, 0, // PC_FNMADD
Stage7, 3, 1, 1, 1, 0, // PC_FNMADDS
Stage7, 3, 1, 1, 1, 0, // PC_FNMSUB
Stage7, 3, 1, 1, 1, 0, // PC_FNMSUBS
Stage7, 3, 1, 1, 1, 0, // PC_FRES
Stage7, 3, 1, 1, 1, 0, // PC_FRSQRTE
Stage7, 5, 1, 1, 1, 0, // PC_FSEL
Stage7, 5, 1, 1, 1, 0, // PC_FRSP
LSU1, 1, 0, 0, 0, 0, // PC_FCTIW
LSU1, 1, 0, 0, 0, 0, // PC_FCTIWZ
LSU1, 1, 0, 0, 0, 0, // PC_FCMPU
LSU1, 1, 0, 0, 0, 0, // PC_FCMPO
LSU1, 1, 0, 0, 0, 0, // PC_LWARX
LSU1, 1, 0, 0, 0, 0, // PC_LSWI
LSU1, 1, 0, 0, 0, 0, // PC_LSWX
Stage1, 1, 0, 0, 0, 0, // PC_STFIWX
Stage1, 1, 0, 0, 0, 0, // PC_STSWI
Stage1, 1, 0, 0, 0, 0, // PC_STSWX
Stage1, 1, 0, 0, 0, 0, // PC_STWCX
Stage1, 1, 0, 0, 0, 0, // PC_ECIWX
Stage1, 1, 0, 0, 0, 0, // PC_ECOWX
Stage1, 1, 0, 0, 0, 0, // PC_DCBI
Stage1, 1, 0, 0, 0, 0, // PC_ICBI
Stage1, 1, 0, 0, 0, 0, // PC_MCRFS
Stage1, 1, 0, 0, 0, 0, // PC_MCRXR
Stage1, 1, 0, 0, 0, 0, // PC_MFTB
Stage1, 1, 0, 0, 0, 0, // PC_MFSR
Stage1, 1, 0, 0, 0, 0, // PC_MTSR
Stage1, 1, 0, 0, 0, 0, // PC_MFSRIN
Stage1, 1, 0, 0, 0, 0, // PC_MTSRIN
Stage1, 1, 0, 0, 0, 0, // PC_MTFSB0
Stage1, 1, 0, 0, 0, 0, // PC_MTFSB1
Stage1, 1, 0, 0, 0, 0, // PC_MTFSFI
Stage1, 1, 0, 0, 0, 1, // PC_SC
Stage1, 1, 0, 0, 0, 1, // PC_FSQRT
Stage1, 1, 0, 0, 0, 0, // PC_FSQRTS
Stage1, 1, 0, 0, 0, 0, // PC_TLBIA
Stage1, 1, 0, 0, 0, 0, // PC_TLBIE
Stage1, 1, 0, 0, 0, 0, // PC_TLBLD
Stage1, 1, 0, 0, 0, 0, // PC_TLBLI
Stage1, 1, 0, 0, 0, 0, // PC_TLBSYNC
Stage1, 1, 0, 0, 0, 0, // PC_TW
Stage1, 1, 0, 0, 0, 1, // PC_TRAP
Stage1, 1, 0, 0, 0, 1, // PC_TWI
Stage1, 1, 0, 0, 0, 1, // PC_OPWORD
Stage1, 1, 0, 0, 0, 1, // PC_MFROM
Stage1, 1, 0, 0, 0, 0, // PC_DSA
Stage1, 1, 0, 0, 0, 0, // PC_ESA
Stage1, 1, 0, 0, 0, 0, // PC_DCCCI
Stage1, 0, 0, 0, 0, 0, // PC_DCREAD
Stage1, 0, 0, 0, 0, 0, // PC_ICBT
Stage1, 0, 0, 0, 0, 0, // PC_ICCCI
Stage1, 0, 0, 0, 0, 0, // PC_ICREAD
Stage1, 0, 0, 0, 0, 0, // PC_RFCI
Stage1, 0, 0, 0, 0, 0, // PC_TLBRE
Stage1, 0, 0, 0, 0, 0, // PC_TLBSX
Stage1, 0, 0, 0, 0, 0, // PC_TLBWE
Stage1, 0, 0, 0, 0, 0, // PC_WRTEE
Stage1, 0, 0, 0, 0, 0, // PC_WRTEEI
Stage1, 0, 0, 0, 0, 0, // PC_MFDCR
Stage1, 0, 0, 0, 0, 0, // PC_MTDCR
Stage1, 0, 0, 0, 0, 0, // PC_DCBA
Stage1, 0, 0, 0, 0, 0, // PC_DSS
BranchUnit, 0, 0, 0, 0, 0, // PC_DSSALL
BranchUnit, 0, 0, 0, 0, 0, // PC_DST
BranchUnit, 0, 0, 0, 0, 0, // PC_DSTT
BranchUnit, 0, 0, 0, 0, 0, // PC_DSTST
BranchUnit, 0, 0, 0, 0, 0, // PC_DSTSTT
BranchUnit, 0, 0, 0, 0, 0, // PC_LVEBX
BranchUnit, 0, 0, 0, 0, 0, // PC_LVEHX
BranchUnit, 0, 0, 0, 0, 0, // PC_LVEWX
BranchUnit, 0, 0, 0, 0, 0, // PC_LVSL
BranchUnit, 0, 0, 0, 0, 0, // PC_LVSR
BranchUnit, 0, 0, 0, 0, 0, // PC_LVX
BranchUnit, 0, 0, 0, 0, 0, // PC_LVXL
BranchUnit, 0, 0, 0, 0, 0, // PC_STVEBX
BranchUnit, 0, 0, 0, 0, 0, // PC_STVEHX
BranchUnit, 0, 0, 0, 0, 0, // PC_STVEWX
BranchUnit, 0, 0, 0, 0, 0, // PC_STVX
BranchUnit, 0, 0, 0, 0, 0, // PC_STVXL
BranchUnit, 0, 0, 0, 0, 0, // PC_MFVSCR
BranchUnit, 0, 0, 0, 0, 0, // PC_MTVSCR
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDCUW
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSBS
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDSWS
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUBM
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUBS
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUHM
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUWM
BranchUnit, 0, 0, 0, 0, 0, // PC_VADDUWS
BranchUnit, 0, 0, 0, 0, 0, // PC_VAND
BranchUnit, 0, 0, 0, 0, 0, // PC_VANDC
BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSB
BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSH
BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGSW
BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUB
BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUH
BranchUnit, 0, 0, 0, 0, 0, // PC_VAVGUW
BranchUnit, 0, 0, 0, 0, 0, // PC_VCFSX
BranchUnit, 0, 0, 0, 0, 0, // PC_VCFUX
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPBFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUB
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUH
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPEQUW
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGEFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSB
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSH
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTSW
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUB
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUH
BranchUnit, 0, 0, 0, 0, 0, // PC_VCMPGTUW
BranchUnit, 0, 0, 0, 0, 0, // PC_VCTSXS
BranchUnit, 0, 0, 0, 0, 0, // PC_VCTUXS
BranchUnit, 0, 0, 0, 0, 0, // PC_VEXPTEFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VLOGEFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXSW
BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMAXUW
BranchUnit, 0, 0, 0, 0, 0, // PC_VMINFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMINSW
BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMINUW
BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGHW
BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMRGLW
BranchUnit, 0, 0, 0, 0, 0, // PC_VMULESB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMULESH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMULEUB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMULEUH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOSB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOSH
BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOUB
BranchUnit, 0, 0, 0, 0, 0, // PC_VMULOUH
BranchUnit, 0, 0, 0, 0, 0, // PC_VNOR
BranchUnit, 0, 0, 0, 0, 0, // PC_VOR
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKPX
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSHSS
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSHUS
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSWSS
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKSWUS
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUHUM
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUHUS
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUWUM
BranchUnit, 0, 0, 0, 0, 0, // PC_VPKUWUS
BranchUnit, 0, 0, 0, 0, 0, // PC_VREFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIM
BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIN
BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIP
BranchUnit, 0, 0, 0, 0, 0, // PC_VRFIZ
BranchUnit, 0, 0, 0, 0, 0, // PC_VRLB
BranchUnit, 0, 0, 0, 0, 0, // PC_VRLH
BranchUnit, 0, 0, 0, 0, 0, // PC_VRLW
BranchUnit, 0, 0, 0, 0, 0, // PC_VRSQRTEFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VSL
BranchUnit, 0, 0, 0, 0, 0, // PC_VSLB
BranchUnit, 0, 0, 0, 0, 0, // PC_VSLH
BranchUnit, 0, 0, 0, 0, 0, // PC_VSLO
BranchUnit, 0, 0, 0, 0, 0, // PC_VSLW
BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTB
BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTH
BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTW
BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISB
BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISH
BranchUnit, 0, 0, 0, 0, 0, // PC_VSPLTISW
BranchUnit, 0, 0, 0, 0, 0, // PC_VSR
BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAB
BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAH
BranchUnit, 0, 0, 0, 0, 0, // PC_VSRAW
BranchUnit, 0, 0, 0, 0, 0, // PC_VSRB
BranchUnit, 0, 0, 0, 0, 0, // PC_VSRH
BranchUnit, 0, 0, 0, 0, 0, // PC_VSRO
BranchUnit, 0, 0, 0, 0, 0, // PC_VSRW
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBCUW
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSBS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBSWS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUBM
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUBS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUHM
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUWM
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUBUWS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUMSWS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM2SWS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4SBS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4SHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VSUM4UBS
BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHPX
BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHSB
BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKHSH
BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLPX
BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLSB
BranchUnit, 0, 0, 0, 0, 0, // PC_VUPKLSH
BranchUnit, 0, 0, 0, 0, 0, // PC_VXOR
BranchUnit, 0, 0, 0, 0, 0, // PC_VMADDFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VMHADDSHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VMHRADDSHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VMLADDUHM
BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMMBM
BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMSHM
BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMSHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUBM
BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUHM
BranchUnit, 0, 0, 0, 0, 0, // PC_VMSUMUHS
BranchUnit, 0, 0, 0, 0, 0, // PC_VNMSUBFP
BranchUnit, 0, 0, 0, 0, 0, // PC_VPERM
BranchUnit, 0, 0, 0, 0, 0, // PC_VSEL
BranchUnit, 0, 0, 0, 0, 0, // PC_VSLDOI
BranchUnit, 0, 0, 0, 0, 0, // PC_VMR
BranchUnit, 0, 0, 0, 0, 0, // PC_VMRP
BranchUnit, 0, 0, 0, 0, 0, // PC_SLE
BranchUnit, 0, 0, 0, 0, 0, // PC_SLEQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SLIQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SLLIQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SLLQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SLQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SRAIQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SRAQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SRE
BranchUnit, 0, 0, 0, 0, 0, // PC_SREA
BranchUnit, 0, 0, 0, 0, 0, // PC_SREQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SRIQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SRLIQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SRLQ
BranchUnit, 0, 0, 0, 0, 0, // PC_SRQ
BranchUnit, 0, 0, 0, 0, 0, // PC_MASKG
BranchUnit, 0, 0, 0, 0, 0, // PC_MASKIR
BranchUnit, 0, 0, 0, 0, 0, // PC_LSCBX
BranchUnit, 0, 0, 0, 0, 0, // PC_DIV
BranchUnit, 0, 0, 0, 0, 0, // PC_DIVS
BranchUnit, 0, 0, 0, 0, 0, // PC_DOZ
BranchUnit, 0, 0, 0, 0, 0, // PC_MUL
BranchUnit, 0, 0, 0, 0, 0, // PC_NABS
BranchUnit, 0, 0, 0, 0, 0, // PC_ABS
BranchUnit, 0, 0, 0, 0, 0, // PC_CLCS
BranchUnit, 0, 0, 0, 0, 0, // PC_DOZI
BranchUnit, 0, 0, 0, 0, 0, // PC_RLMI
BranchUnit, 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;
}
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;
}
static int can_issue(PCode *instr) {
int stage;
if (completionbuffers.free == 0)
return 0;
stage = instruction_timing[instr->op].stage;
if (pipeline[stage].instr)
return 0;
if ((instr->flags & fIsWrite) && pipeline[LSU2].instr && (pipeline[LSU2].instr->flags & fIsWrite))
return 0;
return 1;
}
static void issue(PCode *instr) {
int stage = instruction_timing[instr->op].stage;
int cycles = instruction_timing[instr->op].cycles[0];
assign_completion_buffer(instr);
pipeline[stage].instr = instr;
pipeline[stage].remaining = cycles;
}
static void advance_clock(void) {
int stage;
for (stage = 0; stage < NumStages; stage++) {
if (pipeline[stage].instr && pipeline[stage].remaining)
--pipeline[stage].remaining;
}
if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
retire_instruction();
if (completionbuffers.used && completionbuffers.entries[completionbuffers.nextToRetire].completed) {
retire_instruction();
}
}
if (pipeline[Stage1].instr && pipeline[Stage1].remaining == 0)
complete_instruction(Stage1);
if (pipeline[LSU2].instr && pipeline[LSU2].remaining == 0)
complete_instruction(LSU2);
if (pipeline[BranchUnit].instr && pipeline[BranchUnit].remaining == 0)
complete_instruction(BranchUnit);
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 machine821 = {
1,
0,
0,
&latency,
&initialize,
&can_issue,
&issue,
&advance_clock,
&serializes,
&default_uses_vpermute_unit
};
|