/
PPUTranslator.h
712 lines (619 loc) · 20.7 KB
/
PPUTranslator.h
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
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
#pragma once
#ifdef LLVM_AVAILABLE
#include "../rpcs3/Emu/CPU/CPUTranslator.h"
#include "../rpcs3/Emu/Cell/PPUOpcodes.h"
#include "../rpcs3/Emu/Cell/PPUAnalyser.h"
class PPUTranslator final : public cpu_translator
{
// PPU Module
const ppu_module& m_info;
// Relevant relocations
std::map<u64, const ppu_reloc*> m_relocs;
// Attributes for function calls which are "pure" and may be optimized away if their results are unused
const llvm::AttributeList m_pure_attr;
// LLVM function
llvm::Function* m_function;
llvm::MDNode* m_md_unlikely;
llvm::MDNode* m_md_likely;
// Current position-independent address
u64 m_addr = 0;
// Relocation info
const ppu_segment* m_reloc = nullptr;
// Set by instruction code after processing the relocation
const ppu_reloc* m_rel = nullptr;
/* Variables */
// Segments
std::vector<llvm::GlobalVariable*> m_segs;
// Memory base
llvm::GlobalVariable* m_base;
llvm::Value* m_base_loaded;
// Thread context
llvm::Value* m_thread;
// Callable functions
llvm::GlobalVariable* m_call;
// Thread context struct
llvm::StructType* m_thread_type;
llvm::Value* m_mtocr_table{};
llvm::Value* m_globals[173];
llvm::Value** const m_g_cr = m_globals + 99;
llvm::Value* m_locals[173];
llvm::Value** const m_gpr = m_locals + 3;
llvm::Value** const m_fpr = m_locals + 35;
llvm::Value** const m_vr = m_locals + 67;
llvm::Value** const m_cr = m_locals + 99;
llvm::Value** const m_fc = m_locals + 131; // FPSCR bits (used partially)
#define DEF_VALUE(loc, glb, pos)\
llvm::Value*& loc = m_locals[pos];\
llvm::Value*& glb = m_globals[pos];
DEF_VALUE(m_lr, m_g_lr, 163); // LR, Link Register
DEF_VALUE(m_ctr, m_g_ctr, 164); // CTR, Counter Register
DEF_VALUE(m_vrsave, m_g_vrsave, 165);
DEF_VALUE(m_cia, m_g_cia, 166);
DEF_VALUE(m_so, m_g_so, 167); // XER.SO bit, summary overflow
DEF_VALUE(m_ov, m_g_ov, 168); // XER.OV bit, overflow flag
DEF_VALUE(m_ca, m_g_ca, 169); // XER.CA bit, carry flag
DEF_VALUE(m_cnt, m_g_cnt, 170); // XER.CNT
DEF_VALUE(m_sat, m_g_sat, 171); // VSCR.SAT bit, sticky saturation flag
DEF_VALUE(m_nj, m_g_nj, 172); // VSCR.NJ bit, non-Java mode
#undef DEF_VALUE
public:
template <typename T>
value_t<T> get_vr(u32 vr)
{
value_t<T> result;
result.value = m_ir->CreateBitCast(GetVr(vr, VrType::vi32), value_t<T>::get_type(m_context));
return result;
}
template <typename T, typename... Args>
std::tuple<std::conditional_t<false, Args, value_t<T>>...> get_vrs(const Args&... args)
{
return {get_vr<T>(args)...};
}
template <typename T>
void set_vr(u32 vr, T&& expr)
{
return SetVr(vr, expr.eval(m_ir));
}
// Get current instruction address
llvm::Value* GetAddr(u64 _add = 0);
// Change integer size for integer or integer vector type (by 2^degree)
llvm::Type* ScaleType(llvm::Type*, s32 pow2 = 0);
// Extend arg to double width with its copy
llvm::Value* DuplicateExt(llvm::Value* arg);
// Rotate arg left by n (n must be < bitwidth)
llvm::Value* RotateLeft(llvm::Value* arg, u64 n);
// Rotate arg left by n (n will be masked)
llvm::Value* RotateLeft(llvm::Value* arg, llvm::Value* n);
// Emit function call
void CallFunction(u64 target, llvm::Value* indirect = nullptr);
// Initialize global for writing
llvm::Value* RegInit(llvm::Value*& local);
// Load last register value
llvm::Value* RegLoad(llvm::Value*& local);
// Store register value locally
void RegStore(llvm::Value* value, llvm::Value*& local);
// Write global registers
void FlushRegisters();
// Load gpr
llvm::Value* GetGpr(u32 r, u32 num_bits = 64);
// Set gpr
void SetGpr(u32 r, llvm::Value* value);
// Get fpr
llvm::Value* GetFpr(u32 r, u32 bits = 64, bool as_int = false);
// Set fpr
void SetFpr(u32 r, llvm::Value* val);
// Vector register type
enum class VrType
{
vi8, // i8 vector
vi16, // i16 vector
vi32, // i32 vector
vf, // f32 vector
i128, // Solid 128-bit integer
};
// Load vr
llvm::Value* GetVr(u32 vr, VrType);
// Load VRs
template<typename... Vrs>
std::array<llvm::Value*, sizeof...(Vrs)> GetVrs(VrType type, Vrs... regs)
{
static_assert(sizeof...(Vrs), "Empty VR list");
return{ GetVr(regs, type)... };
}
// Set vr to the specified value
void SetVr(u32 vr, llvm::Value*);
// Bitcast to scalar integer value
llvm::Value* Solid(llvm::Value*);
// Compare value with zero constant of appropriate size
llvm::Value* IsZero(llvm::Value*); llvm::Value* IsNotZero(llvm::Value*);
// Compare value with all-ones constant of appropriate size
llvm::Value* IsOnes(llvm::Value*); llvm::Value* IsNotOnes(llvm::Value*);
// Broadcast specified value
llvm::Value* Broadcast(llvm::Value* value, u32 count);
// Saturate scalar or vector given the comparison operand and the extreme value to compare with (second result is the comparison result)
std::pair<llvm::Value*, llvm::Value*> Saturate(llvm::Value* value, llvm::CmpInst::Predicate inst, llvm::Value* extreme);
// Saturate signed value (second result is the disjunction of comparison results)
std::pair<llvm::Value*, llvm::Value*> SaturateSigned(llvm::Value* value, u64 min, u64 max);
// Multiply FP value or vector by the pow(2, scale)
llvm::Value* Scale(llvm::Value* value, s32 scale);
// Create shuffle instruction with constant args
llvm::Value* Shuffle(llvm::Value* left, llvm::Value* right, std::initializer_list<u32> indices);
// Create sign extension (with double size if type is nullptr)
llvm::Value* SExt(llvm::Value* value, llvm::Type* = nullptr);
template<std::size_t N>
std::array<llvm::Value*, N> SExt(std::array<llvm::Value*, N> values, llvm::Type* type = nullptr)
{
for (std::size_t i = 0; i < N; i++) values[i] = SExt(values[i], type);
return values;
}
// Create zero extension (with double size if type is nullptr)
llvm::Value* ZExt(llvm::Value*, llvm::Type* = nullptr);
template<std::size_t N>
std::array<llvm::Value*, N> ZExt(std::array<llvm::Value*, N> values, llvm::Type* type = nullptr)
{
for (std::size_t i = 0; i < N; i++) values[i] = ZExt(values[i], type);
return values;
}
// Add multiple elements
llvm::Value* Add(std::initializer_list<llvm::Value*>);
// Create tuncation (with half size if type is nullptr)
llvm::Value* Trunc(llvm::Value*, llvm::Type* = nullptr);
// Get specified CR bit
llvm::Value* GetCrb(u32 crb);
// Set specified CR bit
void SetCrb(u32 crb, llvm::Value* value);
// Set CR field, if `so` value (5th arg) is nullptr, loaded from XER.SO
void SetCrField(u32 group, llvm::Value* lt, llvm::Value* gt, llvm::Value* eq, llvm::Value* so = nullptr);
// Set CR field based on signed comparison
void SetCrFieldSignedCmp(u32 n, llvm::Value* a, llvm::Value* b);
// Set CR field based on unsigned comparison
void SetCrFieldUnsignedCmp(u32 n, llvm::Value* a, llvm::Value* b);
// Set CR field from FPSCR CC fieds
void SetCrFieldFPCC(u32 n);
// Set FPSCR CC fields provided, optionally updating CR1
void SetFPCC(llvm::Value* lt, llvm::Value* gt, llvm::Value* eq, llvm::Value* un, bool set_cr = false);
// Update FPRF fields for the value, optionally updating CR1
void SetFPRF(llvm::Value* value, bool set_cr);
// Update FR bit
void SetFPSCR_FR(llvm::Value* value);
// Update FI bit (and set XX exception)
void SetFPSCR_FI(llvm::Value* value);
// Update sticky FPSCR exception bit, update FPSCR.FX
void SetFPSCRException(llvm::Value* ptr, llvm::Value* value);
// Get FPSCR bit (exception bits are cleared)
llvm::Value* GetFPSCRBit(u32 n);
// Set FPSCR bit
void SetFPSCRBit(u32 n, llvm::Value*, bool update_fx);
// Get XER.CA bit
llvm::Value* GetCarry();
// Set XER.CA bit
void SetCarry(llvm::Value*);
// Set XER.OV bit, and update XER.SO bit (|=)
void SetOverflow(llvm::Value*);
// Update sticky VSCR.SAT bit (|=)
void SetSat(llvm::Value*);
// Check condition for trap instructions
llvm::Value* CheckTrapCondition(u32 to, llvm::Value* left, llvm::Value* right);
// Emit trap for current address
void Trap();
// Get condition for branch instructions
llvm::Value* CheckBranchCondition(u32 bo, u32 bi);
// Get hint for branch instructions
llvm::MDNode* CheckBranchProbability(u32 bo);
// Branch to next instruction if condition failed, never branch on nullptr
void UseCondition(llvm::MDNode* hint, llvm::Value* = nullptr);
// Get memory pointer
llvm::Value* GetMemory(llvm::Value* addr, llvm::Type* type);
// Read from memory
llvm::Value* ReadMemory(llvm::Value* addr, llvm::Type* type, bool is_be = true, u32 align = 1);
// Write to memory
void WriteMemory(llvm::Value* addr, llvm::Value* value, bool is_be = true, u32 align = 1);
// Get an undefined value with specified type
template<typename T>
llvm::Value* GetUndef()
{
return llvm::UndefValue::get(GetType<T>());
}
// Call a function with attribute list
template<typename... Args>
llvm::CallInst* Call(llvm::Type* ret, llvm::AttributeList attr, llvm::StringRef name, Args... args)
{
// Call the function
return m_ir->CreateCall(m_module->getOrInsertFunction(name, attr, ret, args->getType()...).getCallee(), {args...});
}
// Call a function
template<typename... Args>
llvm::CallInst* Call(llvm::Type* ret, llvm::StringRef name, Args... args)
{
return Call(ret, llvm::AttributeList{}, name, args...);
}
// Handle compilation errors
void CompilationError(const std::string& error);
PPUTranslator(llvm::LLVMContext& context, llvm::Module* module, const ppu_module& info, llvm::ExecutionEngine& engine);
~PPUTranslator();
// Get thread context struct type
llvm::Type* GetContextType();
// Parses PPU opcodes and translate them into LLVM IR
llvm::Function* Translate(const ppu_function& info);
void MFVSCR(ppu_opcode_t op);
void MTVSCR(ppu_opcode_t op);
void VADDCUW(ppu_opcode_t op);
void VADDFP(ppu_opcode_t op);
void VADDSBS(ppu_opcode_t op);
void VADDSHS(ppu_opcode_t op);
void VADDSWS(ppu_opcode_t op);
void VADDUBM(ppu_opcode_t op);
void VADDUBS(ppu_opcode_t op);
void VADDUHM(ppu_opcode_t op);
void VADDUHS(ppu_opcode_t op);
void VADDUWM(ppu_opcode_t op);
void VADDUWS(ppu_opcode_t op);
void VAND(ppu_opcode_t op);
void VANDC(ppu_opcode_t op);
void VAVGSB(ppu_opcode_t op);
void VAVGSH(ppu_opcode_t op);
void VAVGSW(ppu_opcode_t op);
void VAVGUB(ppu_opcode_t op);
void VAVGUH(ppu_opcode_t op);
void VAVGUW(ppu_opcode_t op);
void VCFSX(ppu_opcode_t op);
void VCFUX(ppu_opcode_t op);
void VCMPBFP(ppu_opcode_t op);
void VCMPEQFP(ppu_opcode_t op);
void VCMPEQUB(ppu_opcode_t op);
void VCMPEQUH(ppu_opcode_t op);
void VCMPEQUW(ppu_opcode_t op);
void VCMPGEFP(ppu_opcode_t op);
void VCMPGTFP(ppu_opcode_t op);
void VCMPGTSB(ppu_opcode_t op);
void VCMPGTSH(ppu_opcode_t op);
void VCMPGTSW(ppu_opcode_t op);
void VCMPGTUB(ppu_opcode_t op);
void VCMPGTUH(ppu_opcode_t op);
void VCMPGTUW(ppu_opcode_t op);
void VCTSXS(ppu_opcode_t op);
void VCTUXS(ppu_opcode_t op);
void VEXPTEFP(ppu_opcode_t op);
void VLOGEFP(ppu_opcode_t op);
void VMADDFP(ppu_opcode_t op);
void VMAXFP(ppu_opcode_t op);
void VMAXSB(ppu_opcode_t op);
void VMAXSH(ppu_opcode_t op);
void VMAXSW(ppu_opcode_t op);
void VMAXUB(ppu_opcode_t op);
void VMAXUH(ppu_opcode_t op);
void VMAXUW(ppu_opcode_t op);
void VMHADDSHS(ppu_opcode_t op);
void VMHRADDSHS(ppu_opcode_t op);
void VMINFP(ppu_opcode_t op);
void VMINSB(ppu_opcode_t op);
void VMINSH(ppu_opcode_t op);
void VMINSW(ppu_opcode_t op);
void VMINUB(ppu_opcode_t op);
void VMINUH(ppu_opcode_t op);
void VMINUW(ppu_opcode_t op);
void VMLADDUHM(ppu_opcode_t op);
void VMRGHB(ppu_opcode_t op);
void VMRGHH(ppu_opcode_t op);
void VMRGHW(ppu_opcode_t op);
void VMRGLB(ppu_opcode_t op);
void VMRGLH(ppu_opcode_t op);
void VMRGLW(ppu_opcode_t op);
void VMSUMMBM(ppu_opcode_t op);
void VMSUMSHM(ppu_opcode_t op);
void VMSUMSHS(ppu_opcode_t op);
void VMSUMUBM(ppu_opcode_t op);
void VMSUMUHM(ppu_opcode_t op);
void VMSUMUHS(ppu_opcode_t op);
void VMULESB(ppu_opcode_t op);
void VMULESH(ppu_opcode_t op);
void VMULEUB(ppu_opcode_t op);
void VMULEUH(ppu_opcode_t op);
void VMULOSB(ppu_opcode_t op);
void VMULOSH(ppu_opcode_t op);
void VMULOUB(ppu_opcode_t op);
void VMULOUH(ppu_opcode_t op);
void VNMSUBFP(ppu_opcode_t op);
void VNOR(ppu_opcode_t op);
void VOR(ppu_opcode_t op);
void VPERM(ppu_opcode_t op);
void VPKPX(ppu_opcode_t op);
void VPKSHSS(ppu_opcode_t op);
void VPKSHUS(ppu_opcode_t op);
void VPKSWSS(ppu_opcode_t op);
void VPKSWUS(ppu_opcode_t op);
void VPKUHUM(ppu_opcode_t op);
void VPKUHUS(ppu_opcode_t op);
void VPKUWUM(ppu_opcode_t op);
void VPKUWUS(ppu_opcode_t op);
void VREFP(ppu_opcode_t op);
void VRFIM(ppu_opcode_t op);
void VRFIN(ppu_opcode_t op);
void VRFIP(ppu_opcode_t op);
void VRFIZ(ppu_opcode_t op);
void VRLB(ppu_opcode_t op);
void VRLH(ppu_opcode_t op);
void VRLW(ppu_opcode_t op);
void VRSQRTEFP(ppu_opcode_t op);
void VSEL(ppu_opcode_t op);
void VSL(ppu_opcode_t op);
void VSLB(ppu_opcode_t op);
void VSLDOI(ppu_opcode_t op);
void VSLH(ppu_opcode_t op);
void VSLO(ppu_opcode_t op);
void VSLW(ppu_opcode_t op);
void VSPLTB(ppu_opcode_t op);
void VSPLTH(ppu_opcode_t op);
void VSPLTISB(ppu_opcode_t op);
void VSPLTISH(ppu_opcode_t op);
void VSPLTISW(ppu_opcode_t op);
void VSPLTW(ppu_opcode_t op);
void VSR(ppu_opcode_t op);
void VSRAB(ppu_opcode_t op);
void VSRAH(ppu_opcode_t op);
void VSRAW(ppu_opcode_t op);
void VSRB(ppu_opcode_t op);
void VSRH(ppu_opcode_t op);
void VSRO(ppu_opcode_t op);
void VSRW(ppu_opcode_t op);
void VSUBCUW(ppu_opcode_t op);
void VSUBFP(ppu_opcode_t op);
void VSUBSBS(ppu_opcode_t op);
void VSUBSHS(ppu_opcode_t op);
void VSUBSWS(ppu_opcode_t op);
void VSUBUBM(ppu_opcode_t op);
void VSUBUBS(ppu_opcode_t op);
void VSUBUHM(ppu_opcode_t op);
void VSUBUHS(ppu_opcode_t op);
void VSUBUWM(ppu_opcode_t op);
void VSUBUWS(ppu_opcode_t op);
void VSUMSWS(ppu_opcode_t op);
void VSUM2SWS(ppu_opcode_t op);
void VSUM4SBS(ppu_opcode_t op);
void VSUM4SHS(ppu_opcode_t op);
void VSUM4UBS(ppu_opcode_t op);
void VUPKHPX(ppu_opcode_t op);
void VUPKHSB(ppu_opcode_t op);
void VUPKHSH(ppu_opcode_t op);
void VUPKLPX(ppu_opcode_t op);
void VUPKLSB(ppu_opcode_t op);
void VUPKLSH(ppu_opcode_t op);
void VXOR(ppu_opcode_t op);
void TDI(ppu_opcode_t op);
void TWI(ppu_opcode_t op);
void MULLI(ppu_opcode_t op);
void SUBFIC(ppu_opcode_t op);
void CMPLI(ppu_opcode_t op);
void CMPI(ppu_opcode_t op);
void ADDIC(ppu_opcode_t op);
void ADDI(ppu_opcode_t op);
void ADDIS(ppu_opcode_t op);
void BC(ppu_opcode_t op);
void SC(ppu_opcode_t op);
void B(ppu_opcode_t op);
void MCRF(ppu_opcode_t op);
void BCLR(ppu_opcode_t op);
void CRNOR(ppu_opcode_t op);
void CRANDC(ppu_opcode_t op);
void ISYNC(ppu_opcode_t op);
void CRXOR(ppu_opcode_t op);
void CRNAND(ppu_opcode_t op);
void CRAND(ppu_opcode_t op);
void CREQV(ppu_opcode_t op);
void CRORC(ppu_opcode_t op);
void CROR(ppu_opcode_t op);
void BCCTR(ppu_opcode_t op);
void RLWIMI(ppu_opcode_t op);
void RLWINM(ppu_opcode_t op);
void RLWNM(ppu_opcode_t op);
void ORI(ppu_opcode_t op);
void ORIS(ppu_opcode_t op);
void XORI(ppu_opcode_t op);
void XORIS(ppu_opcode_t op);
void ANDI(ppu_opcode_t op);
void ANDIS(ppu_opcode_t op);
void RLDICL(ppu_opcode_t op);
void RLDICR(ppu_opcode_t op);
void RLDIC(ppu_opcode_t op);
void RLDIMI(ppu_opcode_t op);
void RLDCL(ppu_opcode_t op);
void RLDCR(ppu_opcode_t op);
void CMP(ppu_opcode_t op);
void TW(ppu_opcode_t op);
void LVSL(ppu_opcode_t op);
void LVEBX(ppu_opcode_t op);
void SUBFC(ppu_opcode_t op);
void MULHDU(ppu_opcode_t op);
void ADDC(ppu_opcode_t op);
void MULHWU(ppu_opcode_t op);
void MFOCRF(ppu_opcode_t op);
void LWARX(ppu_opcode_t op);
void LDX(ppu_opcode_t op);
void LWZX(ppu_opcode_t op);
void SLW(ppu_opcode_t op);
void CNTLZW(ppu_opcode_t op);
void SLD(ppu_opcode_t op);
void AND(ppu_opcode_t op);
void CMPL(ppu_opcode_t op);
void LVSR(ppu_opcode_t op);
void LVEHX(ppu_opcode_t op);
void SUBF(ppu_opcode_t op);
void LDUX(ppu_opcode_t op);
void DCBST(ppu_opcode_t op);
void LWZUX(ppu_opcode_t op);
void CNTLZD(ppu_opcode_t op);
void ANDC(ppu_opcode_t op);
void TD(ppu_opcode_t op);
void LVEWX(ppu_opcode_t op);
void MULHD(ppu_opcode_t op);
void MULHW(ppu_opcode_t op);
void LDARX(ppu_opcode_t op);
void DCBF(ppu_opcode_t op);
void LBZX(ppu_opcode_t op);
void LVX(ppu_opcode_t op);
void NEG(ppu_opcode_t op);
void LBZUX(ppu_opcode_t op);
void NOR(ppu_opcode_t op);
void STVEBX(ppu_opcode_t op);
void SUBFE(ppu_opcode_t op);
void ADDE(ppu_opcode_t op);
void MTOCRF(ppu_opcode_t op);
void STDX(ppu_opcode_t op);
void STWCX(ppu_opcode_t op);
void STWX(ppu_opcode_t op);
void STVEHX(ppu_opcode_t op);
void STDUX(ppu_opcode_t op);
void STWUX(ppu_opcode_t op);
void STVEWX(ppu_opcode_t op);
void SUBFZE(ppu_opcode_t op);
void ADDZE(ppu_opcode_t op);
void STDCX(ppu_opcode_t op);
void STBX(ppu_opcode_t op);
void STVX(ppu_opcode_t op);
void MULLD(ppu_opcode_t op);
void SUBFME(ppu_opcode_t op);
void ADDME(ppu_opcode_t op);
void MULLW(ppu_opcode_t op);
void DCBTST(ppu_opcode_t op);
void STBUX(ppu_opcode_t op);
void ADD(ppu_opcode_t op);
void DCBT(ppu_opcode_t op);
void LHZX(ppu_opcode_t op);
void EQV(ppu_opcode_t op);
void ECIWX(ppu_opcode_t op);
void LHZUX(ppu_opcode_t op);
void XOR(ppu_opcode_t op);
void MFSPR(ppu_opcode_t op);
void LWAX(ppu_opcode_t op);
void DST(ppu_opcode_t op);
void LHAX(ppu_opcode_t op);
void LVXL(ppu_opcode_t op);
void MFTB(ppu_opcode_t op);
void LWAUX(ppu_opcode_t op);
void DSTST(ppu_opcode_t op);
void LHAUX(ppu_opcode_t op);
void STHX(ppu_opcode_t op);
void ORC(ppu_opcode_t op);
void ECOWX(ppu_opcode_t op);
void STHUX(ppu_opcode_t op);
void OR(ppu_opcode_t op);
void DIVDU(ppu_opcode_t op);
void DIVWU(ppu_opcode_t op);
void MTSPR(ppu_opcode_t op);
void DCBI(ppu_opcode_t op);
void NAND(ppu_opcode_t op);
void STVXL(ppu_opcode_t op);
void DIVD(ppu_opcode_t op);
void DIVW(ppu_opcode_t op);
void LVLX(ppu_opcode_t op);
void LDBRX(ppu_opcode_t op);
void LSWX(ppu_opcode_t op);
void LWBRX(ppu_opcode_t op);
void LFSX(ppu_opcode_t op);
void SRW(ppu_opcode_t op);
void SRD(ppu_opcode_t op);
void LVRX(ppu_opcode_t op);
void LSWI(ppu_opcode_t op);
void LFSUX(ppu_opcode_t op);
void SYNC(ppu_opcode_t op);
void LFDX(ppu_opcode_t op);
void LFDUX(ppu_opcode_t op);
void STVLX(ppu_opcode_t op);
void STDBRX(ppu_opcode_t op);
void STSWX(ppu_opcode_t op);
void STWBRX(ppu_opcode_t op);
void STFSX(ppu_opcode_t op);
void STVRX(ppu_opcode_t op);
void STFSUX(ppu_opcode_t op);
void STSWI(ppu_opcode_t op);
void STFDX(ppu_opcode_t op);
void STFDUX(ppu_opcode_t op);
void LVLXL(ppu_opcode_t op);
void LHBRX(ppu_opcode_t op);
void SRAW(ppu_opcode_t op);
void SRAD(ppu_opcode_t op);
void LVRXL(ppu_opcode_t op);
void DSS(ppu_opcode_t op);
void SRAWI(ppu_opcode_t op);
void SRADI(ppu_opcode_t op);
void EIEIO(ppu_opcode_t op);
void STVLXL(ppu_opcode_t op);
void STHBRX(ppu_opcode_t op);
void EXTSH(ppu_opcode_t op);
void STVRXL(ppu_opcode_t op);
void EXTSB(ppu_opcode_t op);
void STFIWX(ppu_opcode_t op);
void EXTSW(ppu_opcode_t op);
void ICBI(ppu_opcode_t op);
void DCBZ(ppu_opcode_t op);
void LWZ(ppu_opcode_t op);
void LWZU(ppu_opcode_t op);
void LBZ(ppu_opcode_t op);
void LBZU(ppu_opcode_t op);
void STW(ppu_opcode_t op);
void STWU(ppu_opcode_t op);
void STB(ppu_opcode_t op);
void STBU(ppu_opcode_t op);
void LHZ(ppu_opcode_t op);
void LHZU(ppu_opcode_t op);
void LHA(ppu_opcode_t op);
void LHAU(ppu_opcode_t op);
void STH(ppu_opcode_t op);
void STHU(ppu_opcode_t op);
void LMW(ppu_opcode_t op);
void STMW(ppu_opcode_t op);
void LFS(ppu_opcode_t op);
void LFSU(ppu_opcode_t op);
void LFD(ppu_opcode_t op);
void LFDU(ppu_opcode_t op);
void STFS(ppu_opcode_t op);
void STFSU(ppu_opcode_t op);
void STFD(ppu_opcode_t op);
void STFDU(ppu_opcode_t op);
void LD(ppu_opcode_t op);
void LDU(ppu_opcode_t op);
void LWA(ppu_opcode_t op);
void STD(ppu_opcode_t op);
void STDU(ppu_opcode_t op);
void FDIVS(ppu_opcode_t op);
void FSUBS(ppu_opcode_t op);
void FADDS(ppu_opcode_t op);
void FSQRTS(ppu_opcode_t op);
void FRES(ppu_opcode_t op);
void FMULS(ppu_opcode_t op);
void FMADDS(ppu_opcode_t op);
void FMSUBS(ppu_opcode_t op);
void FNMSUBS(ppu_opcode_t op);
void FNMADDS(ppu_opcode_t op);
void MTFSB1(ppu_opcode_t op);
void MCRFS(ppu_opcode_t op);
void MTFSB0(ppu_opcode_t op);
void MTFSFI(ppu_opcode_t op);
void MFFS(ppu_opcode_t op);
void MTFSF(ppu_opcode_t op);
void FCMPU(ppu_opcode_t op);
void FRSP(ppu_opcode_t op);
void FCTIW(ppu_opcode_t op);
void FCTIWZ(ppu_opcode_t op);
void FDIV(ppu_opcode_t op);
void FSUB(ppu_opcode_t op);
void FADD(ppu_opcode_t op);
void FSQRT(ppu_opcode_t op);
void FSEL(ppu_opcode_t op);
void FMUL(ppu_opcode_t op);
void FRSQRTE(ppu_opcode_t op);
void FMSUB(ppu_opcode_t op);
void FMADD(ppu_opcode_t op);
void FNMSUB(ppu_opcode_t op);
void FNMADD(ppu_opcode_t op);
void FCMPO(ppu_opcode_t op);
void FNEG(ppu_opcode_t op);
void FMR(ppu_opcode_t op);
void FNABS(ppu_opcode_t op);
void FABS(ppu_opcode_t op);
void FCTID(ppu_opcode_t op);
void FCTIDZ(ppu_opcode_t op);
void FCFID(ppu_opcode_t op);
void UNK(ppu_opcode_t op);
};
#endif