rpcsx/rpcs3/Emu/Cell/PPUAnalyser.h
2025-10-05 19:28:03 +03:00

1439 lines
22 KiB
C++

#pragma once
#include <functional>
#include <string>
#include <map>
#include <deque>
#include <span>
#include "rx/align.hpp"
#include "rx/types.hpp"
#include "util/to_endian.hpp"
#include "rx/EnumBitSet.hpp"
#include "PPUOpcodes.h"
// PPU Function Attributes
enum class ppu_attr : u8
{
known_size,
no_return,
no_size,
has_mfvscr,
bitset_last = has_mfvscr,
};
// PPU Function Information
struct ppu_function
{
u32 addr = 0;
u32 toc = 0;
u32 size = 0;
std::map<u32, u32> blocks{}; // Basic blocks: addr -> size
struct iterator
{
const ppu_function* _this;
typename std::map<u32, u32>::const_iterator it;
usz index = 0;
std::pair<const u32, u32> operator*() const
{
return _this->blocks.empty() ? std::pair<const u32, u32>(_this->addr, _this->size) : *it;
}
iterator& operator++()
{
index++;
if (it != _this->blocks.end())
{
it++;
}
return *this;
}
bool operator==(const iterator& rhs) const noexcept
{
return it == rhs.it || (rhs.index == index && _this->blocks.empty());
}
bool operator!=(const iterator& rhs) const noexcept
{
return !operator==(rhs);
}
};
iterator begin() const
{
return iterator{this, blocks.begin()};
}
iterator end() const
{
return iterator{this, blocks.end(), 1};
}
};
// PPU Relocation Information
struct ppu_reloc
{
u32 addr;
u32 type;
u64 data;
// Operator for sorting
bool operator<(const ppu_reloc& rhs) const
{
return addr < rhs.addr;
}
bool operator<(u32 rhs) const
{
return addr < rhs;
}
};
// PPU Segment Information
struct ppu_segment
{
u32 addr;
u32 size;
u32 type;
u32 flags;
u32 filesz;
void* ptr{};
};
struct ppua_reg_mask_t
{
u64 mask;
};
// PPU Module Information
template <typename Type>
struct ppu_module : public Type
{
using Type::Type;
ppu_module() noexcept = default;
ppu_module(const ppu_module&) = delete;
ppu_module(ppu_module&&) noexcept = default;
ppu_module& operator=(const ppu_module&) = delete;
ppu_module& operator=(ppu_module&&) noexcept = default;
uchar sha1[20]{}; // Hash
std::string name{}; // Filename
std::string path{}; // Filepath
s64 offset = 0; // Offset of file
mutable rx::EnumBitSet<ppu_attr> attr{}; // Shared module attributes
std::string cache{}; // Cache file path
std::vector<ppu_reloc> relocs{}; // Relocations
std::vector<ppu_segment> segs{}; // Segments
std::vector<ppu_segment> secs{}; // Segment sections
std::vector<ppu_function> funcs{}; // Function list
std::vector<u32> applied_patches; // Patch addresses
std::deque<std::shared_ptr<void>> allocations; // Segment memory allocations
std::map<u32, u32> addr_to_seg_index; // address->segment ordered translator map
ppu_module* parent = nullptr; // For compilation: refers to original structure (is whole, not partitioned)
std::pair<u32, u32> local_bounds{0, u32{umax}}; // Module addresses range
std::shared_ptr<std::pair<u32, u32>> jit_bounds; // JIT instance modules addresses range
std::unordered_map<u32, void*> imports; // Imports information for release upon unload (TODO: OVL implementation!)
std::map<u32, std::vector<std::pair<ppua_reg_mask_t, u64>>> stub_addr_to_constant_state_of_registers; // Tells possible constant states of registers of functions
bool is_relocatable = false; // Is code relocatable(?)
template <typename T>
auto as_span(T&& arg, bool bound_local, bool bound_jit) const
{
using unref = std::remove_reference_t<T>;
using type = std::conditional_t<std::is_const_v<unref>, std::add_const_t<typename unref::value_type>, typename unref::value_type>;
if (bound_local || bound_jit)
{
// Return span bound to specified bounds
const auto [min_addr, max_addr] = bound_jit ? *jit_bounds : local_bounds;
constexpr auto compare = [](const type& a, u32 addr)
{
return a.addr < addr;
};
const auto end = arg.data() + arg.size();
const auto start = std::lower_bound(arg.data(), end, min_addr, compare);
return std::span<type>{start, std::lower_bound(start, end, max_addr, compare)};
}
return std::span<type>(arg.data(), arg.size());
}
auto get_funcs(bool bound_local = true, bool bound_jit = false)
{
return as_span(parent ? parent->funcs : funcs, bound_local, bound_jit);
}
auto get_funcs(bool bound_local = true, bool bound_jit = false) const
{
return as_span(parent ? parent->funcs : funcs, bound_local, bound_jit);
}
auto get_relocs(bool bound_local = false) const
{
return as_span(parent ? parent->relocs : relocs, bound_local, false);
}
// Copy info without functions
void copy_part(const ppu_module& info)
{
std::memcpy(sha1, info.sha1, sizeof(sha1));
name = info.name;
path = info.path;
segs = info.segs;
allocations = info.allocations;
addr_to_seg_index = info.addr_to_seg_index;
parent = const_cast<ppu_module*>(&info);
attr = info.attr;
is_relocatable = info.is_relocatable;
local_bounds = {u32{umax}, 0}; // Initially empty range
}
bool analyse(u32 lib_toc, u32 entry, u32 end, const std::vector<u32>& applied, const std::vector<u32>& exported_funcs = std::vector<u32>{}, std::function<bool()> check_aborted = {});
void validate(u32 reloc);
template <typename T>
to_be_t<T>* get_ptr(u32 addr, u32 size_bytes) const
{
auto it = addr_to_seg_index.upper_bound(addr);
if (it == addr_to_seg_index.begin())
{
return nullptr;
}
it--;
const auto& seg = segs[it->second];
const u32 seg_size = seg.size;
const u32 seg_addr = seg.addr;
if (seg_size >= std::max<usz>(size_bytes, 1) && addr <= rx::alignUp<u32>(seg_addr + seg_size, 0x10000) - size_bytes)
{
return reinterpret_cast<to_be_t<T>*>(static_cast<u8*>(seg.ptr) + (addr - seg_addr));
}
return nullptr;
}
template <typename T>
to_be_t<T>* get_ptr(u32 addr) const
{
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
return get_ptr<T>(addr, u32{size_element});
}
template <typename T, typename U>
requires requires(const U& obj) { obj.get_ptr(); }
to_be_t<T>* get_ptr(U&& addr) const
{
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
return get_ptr<T>(addr.addr(), u32{size_element});
}
template <typename T>
to_be_t<T>& get_ref(u32 addr, std::source_location src_loc = std::source_location::current()) const
{
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
if (auto ptr = get_ptr<T>(addr, u32{size_element}))
{
return *ptr;
}
fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr, src_loc);
return *std::add_pointer_t<to_be_t<T>>{};
}
template <typename T, typename U>
requires requires(const U& obj) { obj.get_ptr(); }
to_be_t<T>& get_ref(U&& addr, u32 index = 0, std::source_location src_loc = std::source_location::current()) const
{
constexpr usz size_element = std::is_void_v<T> ? 0 : sizeof(std::conditional_t<std::is_void_v<T>, char, T>);
if (auto ptr = get_ptr<T>((addr + index).addr(), u32{size_element}))
{
return *ptr;
}
fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", (addr + index).addr(), src_loc);
return *std::add_pointer_t<to_be_t<T>>{};
}
};
template <typename T>
struct main_ppu_module : public ppu_module<T>
{
u32 elf_entry{};
u32 seg0_code_end{};
// Disable inherited savestate ordering
void save(utils::serial&) = delete;
static constexpr double savestate_init_pos = double{};
};
// Aux
struct ppu_pattern
{
be_t<u32> opcode;
be_t<u32> mask;
ppu_pattern() = default;
ppu_pattern(u32 op)
: opcode(op), mask(0xffffffff)
{
}
ppu_pattern(u32 op, u32 ign)
: opcode(op & ~ign), mask(~ign)
{
}
};
struct ppu_pattern_array
{
const ppu_pattern* ptr;
usz count;
template <usz N>
constexpr ppu_pattern_array(const ppu_pattern (&array)[N])
: ptr(array), count(N)
{
}
constexpr const ppu_pattern* begin() const
{
return ptr;
}
constexpr const ppu_pattern* end() const
{
return ptr + count;
}
};
struct ppu_pattern_matrix
{
const ppu_pattern_array* ptr;
usz count;
template <usz N>
constexpr ppu_pattern_matrix(const ppu_pattern_array (&array)[N])
: ptr(array), count(N)
{
}
constexpr const ppu_pattern_array* begin() const
{
return ptr;
}
constexpr const ppu_pattern_array* end() const
{
return ptr + count;
}
};
// PPU Instruction Type
struct ppu_itype
{
static constexpr struct branch_tag
{
} branch{}; // Branch Instructions
static constexpr struct trap_tag
{
} trap{}; // Trap Instructions
static constexpr struct store_tag
{
} store{}; // Memory store Instructions
static constexpr struct load_tag
{
} load{}; // Memory load Instructions (TODO: Fill it)
static constexpr struct memory_tag
{
} memory{}; // Memory Instructions
enum class type
{
UNK = 0,
MFVSCR,
MTVSCR,
VADDCUW,
VADDFP,
VADDSBS,
VADDSHS,
VADDSWS,
VADDUBM,
VADDUBS,
VADDUHM,
VADDUHS,
VADDUWM,
VADDUWS,
VAND,
VANDC,
VAVGSB,
VAVGSH,
VAVGSW,
VAVGUB,
VAVGUH,
VAVGUW,
VCFSX,
VCFUX,
VCMPBFP,
VCMPBFP_,
VCMPEQFP,
VCMPEQFP_,
VCMPEQUB,
VCMPEQUB_,
VCMPEQUH,
VCMPEQUH_,
VCMPEQUW,
VCMPEQUW_,
VCMPGEFP,
VCMPGEFP_,
VCMPGTFP,
VCMPGTFP_,
VCMPGTSB,
VCMPGTSB_,
VCMPGTSH,
VCMPGTSH_,
VCMPGTSW,
VCMPGTSW_,
VCMPGTUB,
VCMPGTUB_,
VCMPGTUH,
VCMPGTUH_,
VCMPGTUW,
VCMPGTUW_,
VCTSXS,
VCTUXS,
VEXPTEFP,
VLOGEFP,
VMADDFP,
VMAXFP,
VMAXSB,
VMAXSH,
VMAXSW,
VMAXUB,
VMAXUH,
VMAXUW,
VMHADDSHS,
VMHRADDSHS,
VMINFP,
VMINSB,
VMINSH,
VMINSW,
VMINUB,
VMINUH,
VMINUW,
VMLADDUHM,
VMRGHB,
VMRGHH,
VMRGHW,
VMRGLB,
VMRGLH,
VMRGLW,
VMSUMMBM,
VMSUMSHM,
VMSUMSHS,
VMSUMUBM,
VMSUMUHM,
VMSUMUHS,
VMULESB,
VMULESH,
VMULEUB,
VMULEUH,
VMULOSB,
VMULOSH,
VMULOUB,
VMULOUH,
VNMSUBFP,
VNOR,
VOR,
VPERM,
VPKPX,
VPKSHSS,
VPKSHUS,
VPKSWSS,
VPKSWUS,
VPKUHUM,
VPKUHUS,
VPKUWUM,
VPKUWUS,
VREFP,
VRFIM,
VRFIN,
VRFIP,
VRFIZ,
VRLB,
VRLH,
VRLW,
VRSQRTEFP,
VSEL,
VSL,
VSLB,
VSLDOI,
VSLH,
VSLO,
VSLW,
VSPLTB,
VSPLTH,
VSPLTISB,
VSPLTISH,
VSPLTISW,
VSPLTW,
VSR,
VSRAB,
VSRAH,
VSRAW,
VSRB,
VSRH,
VSRO,
VSRW,
VSUBCUW,
VSUBFP,
VSUBSBS,
VSUBSHS,
VSUBSWS,
VSUBUBM,
VSUBUBS,
VSUBUHM,
VSUBUHS,
VSUBUWM,
VSUBUWS,
VSUMSWS,
VSUM2SWS,
VSUM4SBS,
VSUM4SHS,
VSUM4UBS,
VUPKHPX,
VUPKHSB,
VUPKHSH,
VUPKLPX,
VUPKLSB,
VUPKLSH,
VXOR,
MULLI,
SUBFIC,
ADDIC,
ADDI,
ADDIS,
SC,
MCRF,
CRNOR,
CRANDC,
ISYNC,
CRXOR,
CRNAND,
CRAND,
CREQV,
CRORC,
CROR,
RLWIMI,
RLWINM,
RLWNM,
ORI,
ORIS,
XORI,
XORIS,
ANDI,
ANDIS,
RLDICL,
RLDICR,
RLDIC,
RLDIMI,
RLDCL,
RLDCR,
LVSL,
LVEBX,
SUBFC,
SUBFCO,
ADDC,
ADDCO,
MULHDU,
MULHWU,
MFOCRF,
LWARX,
LDX,
LWZX,
SLW,
CNTLZW,
SLD,
AND,
LVSR,
LVEHX,
SUBF,
SUBFO,
LDUX,
LWZUX,
CNTLZD,
ANDC,
LVEWX,
MULHD,
MULHW,
LDARX,
DCBF,
LBZX,
LVX,
NEG,
NEGO,
LBZUX,
NOR,
SUBFE,
SUBFEO,
ADDE,
ADDEO,
MTOCRF,
SUBFZE,
SUBFZEO,
ADDZE,
ADDZEO,
SUBFME,
SUBFMEO,
MULLD,
MULLDO,
ADDME,
ADDMEO,
MULLW,
MULLWO,
ADD,
ADDO,
LHZX,
EQV,
ECIWX,
LHZUX,
XOR,
MFSPR,
LWAX,
LHAX,
LVXL,
MFTB,
LWAUX,
LHAUX,
ORC,
ECOWX,
OR,
DIVDU,
DIVDUO,
DIVWU,
DIVWUO,
MTSPR,
NAND,
DIVD,
DIVDO,
DIVW,
DIVWO,
LVLX,
LDBRX,
LSWX,
LWBRX,
LFSX,
SRW,
SRD,
LVRX,
LSWI,
LFSUX,
LFDX,
LFDUX,
LVLXL,
LHBRX,
SRAW,
SRAD,
LVRXL,
SRAWI,
SRADI,
EXTSH,
EXTSB,
EXTSW,
LWZ,
LWZU,
LBZ,
LBZU,
LHZ,
LHZU,
LHA,
LHAU,
LMW,
LFS,
LFSU,
LFD,
LFDU,
LD,
LDU,
LWA,
FDIVS,
FSUBS,
FADDS,
FSQRTS,
FRES,
FMULS,
FMADDS,
FMSUBS,
FNMSUBS,
FNMADDS,
MTFSB1,
MCRFS,
MTFSB0,
MTFSFI,
MFFS,
MTFSF,
FCMPU,
FRSP,
FCTIW,
FCTIWZ,
FDIV,
FSUB,
FADD,
FSQRT,
FSEL,
FMUL,
FRSQRTE,
FMSUB,
FMADD,
FNMSUB,
FNMADD,
FCMPO,
FNEG,
FMR,
FNABS,
FABS,
FCTID,
FCTIDZ,
FCFID,
SUBFCO_,
ADDCO_,
SUBFO_,
NEGO_,
SUBFEO_,
ADDEO_,
SUBFZEO_,
ADDZEO_,
SUBFMEO_,
MULLDO_,
ADDMEO_,
MULLWO_,
ADDO_,
DIVDUO_,
DIVWUO_,
DIVDO_,
DIVWO_,
RLWIMI_,
RLWINM_,
RLWNM_,
RLDICL_,
RLDICR_,
RLDIC_,
RLDIMI_,
RLDCL_,
RLDCR_,
SUBFC_,
MULHDU_,
ADDC_,
MULHWU_,
SLW_,
CNTLZW_,
SLD_,
AND_,
SUBF_,
CNTLZD_,
ANDC_,
MULHD_,
MULHW_,
NEG_,
NOR_,
SUBFE_,
ADDE_,
SUBFZE_,
ADDZE_,
MULLD_,
SUBFME_,
ADDME_,
MULLW_,
ADD_,
EQV_,
XOR_,
ORC_,
OR_,
DIVDU_,
DIVWU_,
NAND_,
DIVD_,
DIVW_,
SRW_,
SRD_,
SRAW_,
SRAD_,
SRAWI_,
SRADI_,
EXTSH_,
EXTSB_,
EXTSW_,
FDIVS_,
FSUBS_,
FADDS_,
FSQRTS_,
FRES_,
FMULS_,
FMADDS_,
FMSUBS_,
FNMSUBS_,
FNMADDS_,
MTFSB1_,
MTFSB0_,
MTFSFI_,
MFFS_,
MTFSF_,
FRSP_,
FCTIW_,
FCTIWZ_,
FDIV_,
FSUB_,
FADD_,
FSQRT_,
FSEL_,
FMUL_,
FRSQRTE_,
FMSUB_,
FMADD_,
FNMSUB_,
FNMADD_,
FNEG_,
FMR_,
FNABS_,
FABS_,
FCTID_,
FCTIDZ_,
FCFID_,
CMPLI,
CMPI,
CMP,
CMPL,
STMW, // store_tag first
STSWX,
STSWI,
STVXL,
STVLX,
STVRX,
STVEBX,
STVEHX,
STVEWX,
STVX,
STVLXL,
STVRXL,
STDX,
STDUX,
STDCX,
STDBRX,
STD,
STDU,
STFDUX,
STFDX,
STFDU,
STFD,
STFS,
STFSU,
STFSX,
STFSUX,
STFIWX,
STWCX,
STWX,
STWUX,
STWBRX,
STWU,
STW,
STHBRX,
STHX,
STHUX,
STH,
STBX,
STBU,
STB,
STHU,
STBUX,
DCBZ,
DCBI, // Perceive memory barrier or flag instructions as stores
DCBTST,
DCBT,
DCBST,
DST,
DSS,
ICBI,
SYNC,
EIEIO,
DSTST, // store_tag last
B, // branch_tag first
BC,
BCLR,
BCCTR, // branch_tag last
TD, // trap_tag first
TW,
TDI,
TWI, // trap_tag last
};
using enum type;
// Enable address-of operator for ppu_decoder<>
friend constexpr type operator&(type value)
{
return value;
}
friend constexpr bool operator&(type value, branch_tag)
{
return value >= B && value <= BCCTR;
}
friend constexpr bool operator&(type value, trap_tag)
{
return value >= TD && value <= TWI;
}
friend constexpr bool operator&(type value, store_tag)
{
return value >= STMW && value <= DSTST;
}
};
struct ppu_iname
{
#define NAME(x) static constexpr const char& x = *#x;
#define NAME_(x) static constexpr const char& x##_ = *#x ".";
NAME(UNK)
NAME(MFVSCR)
NAME(MTVSCR)
NAME(VADDCUW)
NAME(VADDFP)
NAME(VADDSBS)
NAME(VADDSHS)
NAME(VADDSWS)
NAME(VADDUBM)
NAME(VADDUBS)
NAME(VADDUHM)
NAME(VADDUHS)
NAME(VADDUWM)
NAME(VADDUWS)
NAME(VAND)
NAME(VANDC)
NAME(VAVGSB)
NAME(VAVGSH)
NAME(VAVGSW)
NAME(VAVGUB)
NAME(VAVGUH)
NAME(VAVGUW)
NAME(VCFSX)
NAME(VCFUX)
NAME(VCMPBFP)
NAME_(VCMPBFP)
NAME(VCMPEQFP)
NAME_(VCMPEQFP)
NAME(VCMPEQUB)
NAME_(VCMPEQUB)
NAME(VCMPEQUH)
NAME_(VCMPEQUH)
NAME(VCMPEQUW)
NAME_(VCMPEQUW)
NAME(VCMPGEFP)
NAME_(VCMPGEFP)
NAME(VCMPGTFP)
NAME_(VCMPGTFP)
NAME(VCMPGTSB)
NAME_(VCMPGTSB)
NAME(VCMPGTSH)
NAME_(VCMPGTSH)
NAME(VCMPGTSW)
NAME_(VCMPGTSW)
NAME(VCMPGTUB)
NAME_(VCMPGTUB)
NAME(VCMPGTUH)
NAME_(VCMPGTUH)
NAME(VCMPGTUW)
NAME_(VCMPGTUW)
NAME(VCTSXS)
NAME(VCTUXS)
NAME(VEXPTEFP)
NAME(VLOGEFP)
NAME(VMADDFP)
NAME(VMAXFP)
NAME(VMAXSB)
NAME(VMAXSH)
NAME(VMAXSW)
NAME(VMAXUB)
NAME(VMAXUH)
NAME(VMAXUW)
NAME(VMHADDSHS)
NAME(VMHRADDSHS)
NAME(VMINFP)
NAME(VMINSB)
NAME(VMINSH)
NAME(VMINSW)
NAME(VMINUB)
NAME(VMINUH)
NAME(VMINUW)
NAME(VMLADDUHM)
NAME(VMRGHB)
NAME(VMRGHH)
NAME(VMRGHW)
NAME(VMRGLB)
NAME(VMRGLH)
NAME(VMRGLW)
NAME(VMSUMMBM)
NAME(VMSUMSHM)
NAME(VMSUMSHS)
NAME(VMSUMUBM)
NAME(VMSUMUHM)
NAME(VMSUMUHS)
NAME(VMULESB)
NAME(VMULESH)
NAME(VMULEUB)
NAME(VMULEUH)
NAME(VMULOSB)
NAME(VMULOSH)
NAME(VMULOUB)
NAME(VMULOUH)
NAME(VNMSUBFP)
NAME(VNOR)
NAME(VOR)
NAME(VPERM)
NAME(VPKPX)
NAME(VPKSHSS)
NAME(VPKSHUS)
NAME(VPKSWSS)
NAME(VPKSWUS)
NAME(VPKUHUM)
NAME(VPKUHUS)
NAME(VPKUWUM)
NAME(VPKUWUS)
NAME(VREFP)
NAME(VRFIM)
NAME(VRFIN)
NAME(VRFIP)
NAME(VRFIZ)
NAME(VRLB)
NAME(VRLH)
NAME(VRLW)
NAME(VRSQRTEFP)
NAME(VSEL)
NAME(VSL)
NAME(VSLB)
NAME(VSLDOI)
NAME(VSLH)
NAME(VSLO)
NAME(VSLW)
NAME(VSPLTB)
NAME(VSPLTH)
NAME(VSPLTISB)
NAME(VSPLTISH)
NAME(VSPLTISW)
NAME(VSPLTW)
NAME(VSR)
NAME(VSRAB)
NAME(VSRAH)
NAME(VSRAW)
NAME(VSRB)
NAME(VSRH)
NAME(VSRO)
NAME(VSRW)
NAME(VSUBCUW)
NAME(VSUBFP)
NAME(VSUBSBS)
NAME(VSUBSHS)
NAME(VSUBSWS)
NAME(VSUBUBM)
NAME(VSUBUBS)
NAME(VSUBUHM)
NAME(VSUBUHS)
NAME(VSUBUWM)
NAME(VSUBUWS)
NAME(VSUMSWS)
NAME(VSUM2SWS)
NAME(VSUM4SBS)
NAME(VSUM4SHS)
NAME(VSUM4UBS)
NAME(VUPKHPX)
NAME(VUPKHSB)
NAME(VUPKHSH)
NAME(VUPKLPX)
NAME(VUPKLSB)
NAME(VUPKLSH)
NAME(VXOR)
NAME(TDI)
NAME(TWI)
NAME(MULLI)
NAME(SUBFIC)
NAME(CMPLI)
NAME(CMPI)
NAME(ADDIC)
NAME(ADDI)
NAME(ADDIS)
NAME(BC)
NAME(SC)
NAME(B)
NAME(MCRF)
NAME(BCLR)
NAME(CRNOR)
NAME(CRANDC)
NAME(ISYNC)
NAME(CRXOR)
NAME(CRNAND)
NAME(CRAND)
NAME(CREQV)
NAME(CRORC)
NAME(CROR)
NAME(BCCTR)
NAME(RLWIMI)
NAME(RLWINM)
NAME(RLWNM)
NAME(ORI)
NAME(ORIS)
NAME(XORI)
NAME(XORIS)
NAME(ANDI)
NAME(ANDIS)
NAME(RLDICL)
NAME(RLDICR)
NAME(RLDIC)
NAME(RLDIMI)
NAME(RLDCL)
NAME(RLDCR)
NAME(CMP)
NAME(TW)
NAME(LVSL)
NAME(LVEBX)
NAME(SUBFC)
NAME(ADDC)
NAME(MULHDU)
NAME(MULHWU)
NAME(MFOCRF)
NAME(LWARX)
NAME(LDX)
NAME(LWZX)
NAME(SLW)
NAME(CNTLZW)
NAME(SLD)
NAME(AND)
NAME(CMPL)
NAME(LVSR)
NAME(LVEHX)
NAME(SUBF)
NAME(LDUX)
NAME(DCBST)
NAME(LWZUX)
NAME(CNTLZD)
NAME(ANDC)
NAME(TD)
NAME(LVEWX)
NAME(MULHD)
NAME(MULHW)
NAME(LDARX)
NAME(DCBF)
NAME(LBZX)
NAME(LVX)
NAME(NEG)
NAME(LBZUX)
NAME(NOR)
NAME(STVEBX)
NAME(SUBFE)
NAME(ADDE)
NAME(MTOCRF)
NAME(STDX)
NAME(STWCX)
NAME(STWX)
NAME(STVEHX)
NAME(STDUX)
NAME(STWUX)
NAME(STVEWX)
NAME(SUBFZE)
NAME(ADDZE)
NAME(STDCX)
NAME(STBX)
NAME(STVX)
NAME(SUBFME)
NAME(MULLD)
NAME(ADDME)
NAME(MULLW)
NAME(DCBTST)
NAME(STBUX)
NAME(ADD)
NAME(DCBT)
NAME(LHZX)
NAME(EQV)
NAME(ECIWX)
NAME(LHZUX)
NAME(XOR)
NAME(MFSPR)
NAME(LWAX)
NAME(DST)
NAME(LHAX)
NAME(LVXL)
NAME(MFTB)
NAME(LWAUX)
NAME(DSTST)
NAME(LHAUX)
NAME(STHX)
NAME(ORC)
NAME(ECOWX)
NAME(STHUX)
NAME(OR)
NAME(DIVDU)
NAME(DIVWU)
NAME(MTSPR)
NAME(DCBI)
NAME(NAND)
NAME(STVXL)
NAME(DIVD)
NAME(DIVW)
NAME(LVLX)
NAME(LDBRX)
NAME(LSWX)
NAME(LWBRX)
NAME(LFSX)
NAME(SRW)
NAME(SRD)
NAME(LVRX)
NAME(LSWI)
NAME(LFSUX)
NAME(SYNC)
NAME(LFDX)
NAME(LFDUX)
NAME(STVLX)
NAME(STDBRX)
NAME(STSWX)
NAME(STWBRX)
NAME(STFSX)
NAME(STVRX)
NAME(STFSUX)
NAME(STSWI)
NAME(STFDX)
NAME(STFDUX)
NAME(LVLXL)
NAME(LHBRX)
NAME(SRAW)
NAME(SRAD)
NAME(LVRXL)
NAME(DSS)
NAME(SRAWI)
NAME(SRADI)
NAME(EIEIO)
NAME(STVLXL)
NAME(STHBRX)
NAME(EXTSH)
NAME(STVRXL)
NAME(EXTSB)
NAME(STFIWX)
NAME(EXTSW)
NAME(ICBI)
NAME(DCBZ)
NAME(LWZ)
NAME(LWZU)
NAME(LBZ)
NAME(LBZU)
NAME(STW)
NAME(STWU)
NAME(STB)
NAME(STBU)
NAME(LHZ)
NAME(LHZU)
NAME(LHA)
NAME(LHAU)
NAME(STH)
NAME(STHU)
NAME(LMW)
NAME(STMW)
NAME(LFS)
NAME(LFSU)
NAME(LFD)
NAME(LFDU)
NAME(STFS)
NAME(STFSU)
NAME(STFD)
NAME(STFDU)
NAME(LD)
NAME(LDU)
NAME(LWA)
NAME(STD)
NAME(STDU)
NAME(FDIVS)
NAME(FSUBS)
NAME(FADDS)
NAME(FSQRTS)
NAME(FRES)
NAME(FMULS)
NAME(FMADDS)
NAME(FMSUBS)
NAME(FNMSUBS)
NAME(FNMADDS)
NAME(MTFSB1)
NAME(MCRFS)
NAME(MTFSB0)
NAME(MTFSFI)
NAME(MFFS)
NAME(MTFSF)
NAME(FCMPU)
NAME(FRSP)
NAME(FCTIW)
NAME(FCTIWZ)
NAME(FDIV)
NAME(FSUB)
NAME(FADD)
NAME(FSQRT)
NAME(FSEL)
NAME(FMUL)
NAME(FRSQRTE)
NAME(FMSUB)
NAME(FMADD)
NAME(FNMSUB)
NAME(FNMADD)
NAME(FCMPO)
NAME(FNEG)
NAME(FMR)
NAME(FNABS)
NAME(FABS)
NAME(FCTID)
NAME(FCTIDZ)
NAME(FCFID)
NAME(SUBFCO)
NAME(ADDCO)
NAME(SUBFO)
NAME(NEGO)
NAME(SUBFEO)
NAME(ADDEO)
NAME(SUBFZEO)
NAME(ADDZEO)
NAME(SUBFMEO)
NAME(MULLDO)
NAME(ADDMEO)
NAME(MULLWO)
NAME(ADDO)
NAME(DIVDUO)
NAME(DIVWUO)
NAME(DIVDO)
NAME(DIVWO)
NAME_(SUBFCO)
NAME_(ADDCO)
NAME_(SUBFO)
NAME_(NEGO)
NAME_(SUBFEO)
NAME_(ADDEO)
NAME_(SUBFZEO)
NAME_(ADDZEO)
NAME_(SUBFMEO)
NAME_(MULLDO)
NAME_(ADDMEO)
NAME_(MULLWO)
NAME_(ADDO)
NAME_(DIVDUO)
NAME_(DIVWUO)
NAME_(DIVDO)
NAME_(DIVWO)
NAME_(RLWIMI)
NAME_(RLWINM)
NAME_(RLWNM)
NAME_(RLDICL)
NAME_(RLDICR)
NAME_(RLDIC)
NAME_(RLDIMI)
NAME_(RLDCL)
NAME_(RLDCR)
NAME_(SUBFC)
NAME_(MULHDU)
NAME_(ADDC)
NAME_(MULHWU)
NAME_(SLW)
NAME_(CNTLZW)
NAME_(SLD)
NAME_(AND)
NAME_(SUBF)
NAME_(CNTLZD)
NAME_(ANDC)
NAME_(MULHD)
NAME_(MULHW)
NAME_(NEG)
NAME_(NOR)
NAME_(SUBFE)
NAME_(ADDE)
NAME_(SUBFZE)
NAME_(ADDZE)
NAME_(MULLD)
NAME_(SUBFME)
NAME_(ADDME)
NAME_(MULLW)
NAME_(ADD)
NAME_(EQV)
NAME_(XOR)
NAME_(ORC)
NAME_(OR)
NAME_(DIVDU)
NAME_(DIVWU)
NAME_(NAND)
NAME_(DIVD)
NAME_(DIVW)
NAME_(SRW)
NAME_(SRD)
NAME_(SRAW)
NAME_(SRAD)
NAME_(SRAWI)
NAME_(SRADI)
NAME_(EXTSH)
NAME_(EXTSB)
NAME_(EXTSW)
NAME_(FDIVS)
NAME_(FSUBS)
NAME_(FADDS)
NAME_(FSQRTS)
NAME_(FRES)
NAME_(FMULS)
NAME_(FMADDS)
NAME_(FMSUBS)
NAME_(FNMSUBS)
NAME_(FNMADDS)
NAME_(MTFSB1)
NAME_(MTFSB0)
NAME_(MTFSFI)
NAME_(MFFS)
NAME_(MTFSF)
NAME_(FRSP)
NAME_(FCTIW)
NAME_(FCTIWZ)
NAME_(FDIV)
NAME_(FSUB)
NAME_(FADD)
NAME_(FSQRT)
NAME_(FSEL)
NAME_(FMUL)
NAME_(FRSQRTE)
NAME_(FMSUB)
NAME_(FMADD)
NAME_(FNMSUB)
NAME_(FNMADD)
NAME_(FNEG)
NAME_(FMR)
NAME_(FNABS)
NAME_(FABS)
NAME_(FCTID)
NAME_(FCTIDZ)
NAME_(FCFID)
#undef NAME
#undef NAME_
};