2016-06-05 12:14:20 +02:00
# pragma once
2025-10-05 18:28:03 +02:00
# include <functional>
2017-04-16 03:31:58 +02:00
# include <string>
2016-07-07 20:42:39 +02:00
# include <map>
2023-06-25 14:53:42 +02:00
# include <deque>
2025-01-10 16:34:24 +01:00
# include <span>
2025-10-05 18:28:03 +02:00
# include "rx/align.hpp"
# include "rx/types.hpp"
2023-06-25 14:53:42 +02:00
# include "util/to_endian.hpp"
2016-07-07 20:42:39 +02:00
2025-10-04 21:19:57 +02:00
# include "rx/EnumBitSet.hpp"
2017-10-13 04:13:43 +02:00
# include "PPUOpcodes.h"
2016-07-07 20:42:39 +02:00
// PPU Function Attributes
2025-01-15 18:49:56 +01:00
enum class ppu_attr : u8
2016-07-07 20:42:39 +02:00
{
known_size ,
no_return ,
no_size ,
2021-06-25 09:50:42 +02:00
has_mfvscr ,
2016-08-07 21:01:27 +02:00
2025-10-04 23:54:46 +02:00
bitset_last = has_mfvscr ,
2016-07-07 20:42:39 +02:00
} ;
// PPU Function Information
struct ppu_function
{
2016-07-24 19:54:15 +02:00
u32 addr = 0 ;
u32 toc = 0 ;
u32 size = 0 ;
2021-04-03 18:38:02 +02:00
std : : map < u32 , u32 > blocks { } ; // Basic blocks: addr -> size
2025-01-10 16:34:24 +01:00
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 } ;
}
2016-07-07 20:42:39 +02:00
} ;
2017-06-26 15:55:35 +02:00
// PPU Relocation Information
struct ppu_reloc
{
2017-07-01 01:08:51 +02:00
u32 addr ;
2017-06-26 15:55:35 +02:00
u32 type ;
2017-07-01 01:08:51 +02:00
u64 data ;
2018-03-17 18:41:35 +01:00
// Operator for sorting
2025-04-05 21:50:45 +02:00
bool operator < ( const ppu_reloc & rhs ) const
2018-03-17 18:41:35 +01:00
{
return addr < rhs . addr ;
}
2025-04-05 21:50:45 +02:00
bool operator < ( u32 rhs ) const
2018-03-17 18:41:35 +01:00
{
return addr < rhs ;
}
2017-06-26 15:55:35 +02:00
} ;
// PPU Segment Information
struct ppu_segment
{
u32 addr ;
u32 size ;
u32 type ;
u32 flags ;
2017-08-22 23:42:12 +02:00
u32 filesz ;
2023-06-25 14:53:42 +02:00
void * ptr { } ;
2017-06-26 15:55:35 +02:00
} ;
2025-02-23 18:04:14 +01:00
struct ppua_reg_mask_t
{
u64 mask ;
} ;
2017-02-26 16:56:31 +01:00
// PPU Module Information
2024-12-22 19:59:48 +01:00
template < typename Type >
struct ppu_module : public Type
2017-02-26 16:56:31 +01:00
{
2024-12-22 19:59:48 +01:00
using Type : : Type ;
2023-04-08 17:03:05 +02:00
ppu_module ( ) noexcept = default ;
2021-03-02 17:22:39 +01:00
ppu_module ( const ppu_module & ) = delete ;
2023-04-08 17:03:05 +02:00
ppu_module ( ppu_module & & ) noexcept = default ;
2021-03-02 17:22:39 +01:00
ppu_module & operator = ( const ppu_module & ) = delete ;
2023-04-08 17:03:05 +02:00
ppu_module & operator = ( ppu_module & & ) noexcept = default ;
2021-03-02 17:22:39 +01:00
2025-04-05 21:50:45 +02:00
uchar sha1 [ 20 ] { } ; // Hash
std : : string name { } ; // Filename
std : : string path { } ; // Filepath
s64 offset = 0 ; // Offset of file
2025-10-04 21:56:43 +02:00
mutable rx : : EnumBitSet < ppu_attr > attr { } ; // Shared module attributes
2025-04-05 21:50:45 +02:00
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!)
2025-02-23 18:04:14 +01:00
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
2025-04-05 21:50:45 +02:00
bool is_relocatable = false ; // Is code relocatable(?)
2025-01-10 16:34:24 +01:00
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 ;
2025-04-05 21:50:45 +02:00
constexpr auto compare = [ ] ( const type & a , u32 addr )
{
return a . addr < addr ;
} ;
2025-01-10 16:34:24 +01:00
const auto end = arg . data ( ) + arg . size ( ) ;
const auto start = std : : lower_bound ( arg . data ( ) , end , min_addr , compare ) ;
2025-04-05 21:50:45 +02:00
return std : : span < type > { start , std : : lower_bound ( start , end , max_addr , compare ) } ;
2025-01-10 16:34:24 +01:00
}
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 ) ;
}
2017-07-01 01:08:51 +02:00
2017-10-10 15:40:46 +02:00
// Copy info without functions
void copy_part ( const ppu_module & info )
{
2018-03-20 16:53:15 +01:00
std : : memcpy ( sha1 , info . sha1 , sizeof ( sha1 ) ) ;
2017-10-10 15:40:46 +02:00
name = info . name ;
path = info . path ;
segs = info . segs ;
2023-06-25 14:53:42 +02:00
allocations = info . allocations ;
addr_to_seg_index = info . addr_to_seg_index ;
2025-01-10 16:34:24 +01:00
parent = const_cast < ppu_module * > ( & info ) ;
attr = info . attr ;
2025-01-31 16:15:51 +01:00
is_relocatable = info . is_relocatable ;
2025-01-10 16:34:24 +01:00
local_bounds = { u32 { umax } , 0 } ; // Initially empty range
2017-10-10 15:40:46 +02:00
}
2024-11-11 20:54:44 +01:00
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 = { } ) ;
2017-07-01 01:08:51 +02:00
void validate ( u32 reloc ) ;
2023-06-25 14:53:42 +02:00
template < typename T >
2023-07-12 19:43:33 +02:00
to_be_t < T > * get_ptr ( u32 addr , u32 size_bytes ) const
2023-06-25 14:53:42 +02:00
{
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 ;
2025-10-05 18:28:03 +02:00
if ( seg_size > = std : : max < usz > ( size_bytes , 1 ) & & addr < = rx : : alignUp < u32 > ( seg_addr + seg_size , 0x10000 ) - size_bytes )
2023-06-25 14:53:42 +02:00
{
return reinterpret_cast < to_be_t < T > * > ( static_cast < u8 * > ( seg . ptr ) + ( addr - seg_addr ) ) ;
}
return nullptr ;
}
2023-07-12 19:43:33 +02:00
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 } ) ;
}
2025-04-05 21:50:45 +02:00
template < typename T , typename U >
requires requires ( const U & obj ) { obj . get_ptr ( ) ; }
2023-06-25 14:53:42 +02:00
to_be_t < T > * get_ptr ( U & & addr ) const
{
2023-07-12 19:43:33 +02:00
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 } ) ;
2023-06-25 14:53:42 +02:00
}
2023-07-22 11:03:45 +02:00
template < typename T >
2024-05-21 09:34:51 +02:00
to_be_t < T > & get_ref ( u32 addr , std : : source_location src_loc = std : : source_location : : current ( ) ) const
2023-07-22 11:03:45 +02:00
{
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 ;
}
2024-05-21 09:34:51 +02:00
fmt : : throw_exception ( " get_ref(): Failure! (addr=0x%x)%s " , addr , src_loc ) ;
2023-07-22 11:03:45 +02:00
return * std : : add_pointer_t < to_be_t < T > > { } ;
}
2025-04-05 21:50:45 +02:00
template < typename T , typename U >
requires requires ( const U & obj ) { obj . get_ptr ( ) ; }
2024-05-21 09:34:51 +02:00
to_be_t < T > & get_ref ( U & & addr , u32 index = 0 , std : : source_location src_loc = std : : source_location : : current ( ) ) const
2023-07-22 11:03:45 +02:00
{
constexpr usz size_element = std : : is_void_v < T > ? 0 : sizeof ( std : : conditional_t < std : : is_void_v < T > , char , T > ) ;
2023-08-06 18:47:23 +02:00
if ( auto ptr = get_ptr < T > ( ( addr + index ) . addr ( ) , u32 { size_element } ) )
2023-07-22 11:03:45 +02:00
{
return * ptr ;
}
2024-05-21 09:34:51 +02:00
fmt : : throw_exception ( " get_ref(): Failure! (addr=0x%x)%s " , ( addr + index ) . addr ( ) , src_loc ) ;
2023-07-22 11:03:45 +02:00
return * std : : add_pointer_t < to_be_t < T > > { } ;
}
2017-02-26 16:56:31 +01:00
} ;
2024-12-22 19:59:48 +01:00
template < typename T >
struct main_ppu_module : public ppu_module < T >
2023-04-08 17:03:05 +02:00
{
2023-06-15 20:59:19 +02:00
u32 elf_entry { } ;
u32 seg0_code_end { } ;
2024-12-25 09:56:39 +01:00
// Disable inherited savestate ordering
void save ( utils : : serial & ) = delete ;
static constexpr double savestate_init_pos = double { } ;
2023-04-08 17:03:05 +02:00
} ;
2016-07-09 00:36:42 +02:00
// Aux
struct ppu_pattern
{
be_t < u32 > opcode ;
be_t < u32 > mask ;
ppu_pattern ( ) = default ;
ppu_pattern ( u32 op )
2025-04-05 21:50:45 +02:00
: opcode ( op ) , mask ( 0xffffffff )
2016-07-09 00:36:42 +02:00
{
}
ppu_pattern ( u32 op , u32 ign )
2025-04-05 21:50:45 +02:00
: opcode ( op & ~ ign ) , mask ( ~ ign )
2016-07-09 00:36:42 +02:00
{
}
} ;
2017-01-23 22:56:27 +01:00
struct ppu_pattern_array
{
const ppu_pattern * ptr ;
2020-12-18 08:39:54 +01:00
usz count ;
2017-01-23 22:56:27 +01:00
2020-12-18 08:39:54 +01:00
template < usz N >
2025-04-05 21:50:45 +02:00
constexpr ppu_pattern_array ( const ppu_pattern ( & array ) [ N ] )
: ptr ( array ) , count ( N )
2017-01-23 22:56:27 +01:00
{
}
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 ;
2020-12-18 08:39:54 +01:00
usz count ;
2017-01-23 22:56:27 +01:00
2020-12-18 08:39:54 +01:00
template < usz N >
2025-04-05 21:50:45 +02:00
constexpr ppu_pattern_matrix ( const ppu_pattern_array ( & array ) [ N ] )
: ptr ( array ) , count ( N )
2017-01-23 22:56:27 +01:00
{
}
constexpr const ppu_pattern_array * begin ( ) const
{
return ptr ;
}
constexpr const ppu_pattern_array * end ( ) const
{
return ptr + count ;
}
} ;
2016-06-05 12:14:20 +02:00
// PPU Instruction Type
struct ppu_itype
{
2025-04-05 21:50:45 +02:00
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
2023-08-20 03:24:42 +02:00
2023-09-06 05:53:10 +02:00
enum class type
2016-06-05 12:14:20 +02:00
{
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 ,
2021-12-30 17:39:18 +01:00
VCMPBFP_ ,
2016-06-05 12:14:20 +02:00
VCMPEQFP ,
2021-12-30 17:39:18 +01:00
VCMPEQFP_ ,
2016-06-05 12:14:20 +02:00
VCMPEQUB ,
2021-12-30 17:39:18 +01:00
VCMPEQUB_ ,
2016-06-05 12:14:20 +02:00
VCMPEQUH ,
2021-12-30 17:39:18 +01:00
VCMPEQUH_ ,
2016-06-05 12:14:20 +02:00
VCMPEQUW ,
2021-12-30 17:39:18 +01:00
VCMPEQUW_ ,
2016-06-05 12:14:20 +02:00
VCMPGEFP ,
2021-12-30 17:39:18 +01:00
VCMPGEFP_ ,
2016-06-05 12:14:20 +02:00
VCMPGTFP ,
2021-12-30 17:39:18 +01:00
VCMPGTFP_ ,
2016-06-05 12:14:20 +02:00
VCMPGTSB ,
2021-12-30 17:39:18 +01:00
VCMPGTSB_ ,
2016-06-05 12:14:20 +02:00
VCMPGTSH ,
2021-12-30 17:39:18 +01:00
VCMPGTSH_ ,
2016-06-05 12:14:20 +02:00
VCMPGTSW ,
2021-12-30 17:39:18 +01:00
VCMPGTSW_ ,
2016-06-05 12:14:20 +02:00
VCMPGTUB ,
2021-12-30 17:39:18 +01:00
VCMPGTUB_ ,
2016-06-05 12:14:20 +02:00
VCMPGTUH ,
2021-12-30 17:39:18 +01:00
VCMPGTUH_ ,
2016-06-05 12:14:20 +02:00
VCMPGTUW ,
2021-12-30 17:39:18 +01:00
VCMPGTUW_ ,
2016-06-05 12:14:20 +02:00
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 ,
2021-12-30 17:39:18 +01:00
SUBFCO ,
2016-06-05 12:14:20 +02:00
ADDC ,
2021-12-30 17:39:18 +01:00
ADDCO ,
2016-06-05 12:14:20 +02:00
MULHDU ,
MULHWU ,
MFOCRF ,
LWARX ,
LDX ,
LWZX ,
SLW ,
CNTLZW ,
SLD ,
AND ,
LVSR ,
LVEHX ,
SUBF ,
2021-12-30 17:39:18 +01:00
SUBFO ,
2016-06-05 12:14:20 +02:00
LDUX ,
LWZUX ,
CNTLZD ,
ANDC ,
LVEWX ,
MULHD ,
MULHW ,
LDARX ,
DCBF ,
LBZX ,
LVX ,
NEG ,
2021-12-30 17:39:18 +01:00
NEGO ,
2016-06-05 12:14:20 +02:00
LBZUX ,
NOR ,
SUBFE ,
2021-12-30 17:39:18 +01:00
SUBFEO ,
2016-06-05 12:14:20 +02:00
ADDE ,
2021-12-30 17:39:18 +01:00
ADDEO ,
2016-06-05 12:14:20 +02:00
MTOCRF ,
SUBFZE ,
2021-12-30 17:39:18 +01:00
SUBFZEO ,
2016-06-05 12:14:20 +02:00
ADDZE ,
2021-12-30 17:39:18 +01:00
ADDZEO ,
2016-06-05 12:14:20 +02:00
SUBFME ,
2021-12-30 17:39:18 +01:00
SUBFMEO ,
2016-06-05 12:14:20 +02:00
MULLD ,
2021-12-30 17:39:18 +01:00
MULLDO ,
2016-06-05 12:14:20 +02:00
ADDME ,
2021-12-30 17:39:18 +01:00
ADDMEO ,
2016-06-05 12:14:20 +02:00
MULLW ,
2021-12-30 17:39:18 +01:00
MULLWO ,
2016-06-05 12:14:20 +02:00
ADD ,
2021-12-30 17:39:18 +01:00
ADDO ,
2016-06-05 12:14:20 +02:00
LHZX ,
EQV ,
ECIWX ,
LHZUX ,
XOR ,
MFSPR ,
LWAX ,
LHAX ,
LVXL ,
MFTB ,
LWAUX ,
LHAUX ,
ORC ,
ECOWX ,
OR ,
DIVDU ,
2021-12-30 17:39:18 +01:00
DIVDUO ,
2016-06-05 12:14:20 +02:00
DIVWU ,
2021-12-30 17:39:18 +01:00
DIVWUO ,
2016-06-05 12:14:20 +02:00
MTSPR ,
NAND ,
DIVD ,
2021-12-30 17:39:18 +01:00
DIVDO ,
2016-06-05 12:14:20 +02:00
DIVW ,
2021-12-30 17:39:18 +01:00
DIVWO ,
2016-06-05 12:14:20 +02:00
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 ,
2021-12-30 17:39:18 +01:00
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_ ,
2023-08-20 03:24:42 +02:00
2025-01-31 16:15:51 +01:00
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
2023-08-20 03:24:42 +02:00
B , // branch_tag first
BC ,
BCLR ,
BCCTR , // branch_tag last
2023-08-24 22:03:51 +02:00
TD , // trap_tag first
TW ,
TDI ,
TWI , // trap_tag last
2016-06-05 12:14:20 +02:00
} ;
2023-09-06 05:53:10 +02:00
using enum type ;
2016-06-05 12:14:20 +02:00
// Enable address-of operator for ppu_decoder<>
2025-04-05 21:50:45 +02:00
friend constexpr type operator & ( type value )
2016-06-05 12:14:20 +02:00
{
return value ;
}
2023-08-20 03:24:42 +02:00
2025-04-05 21:50:45 +02:00
friend constexpr bool operator & ( type value , branch_tag )
2023-08-20 03:24:42 +02:00
{
return value > = B & & value < = BCCTR ;
}
2023-08-24 22:03:51 +02:00
2025-04-05 21:50:45 +02:00
friend constexpr bool operator & ( type value , trap_tag )
2023-08-24 22:03:51 +02:00
{
return value > = TD & & value < = TWI ;
}
2025-01-31 16:15:51 +01:00
2025-04-05 21:50:45 +02:00
friend constexpr bool operator & ( type value , store_tag )
2025-01-31 16:15:51 +01:00
{
return value > = STMW & & value < = DSTST ;
}
2016-06-05 12:14:20 +02:00
} ;
2016-06-07 22:24:20 +02:00
struct ppu_iname
{
2020-03-26 13:26:49 +01:00
# define NAME(x) static constexpr const char& x = *#x;
2021-12-30 17:39:18 +01:00
# define NAME_(x) static constexpr const char& x##_ = *#x ".";
2016-06-07 22:24:20 +02:00
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 )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPBFP )
2016-06-07 22:24:20 +02:00
NAME ( VCMPEQFP )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPEQFP )
2016-06-07 22:24:20 +02:00
NAME ( VCMPEQUB )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPEQUB )
2016-06-07 22:24:20 +02:00
NAME ( VCMPEQUH )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPEQUH )
2016-06-07 22:24:20 +02:00
NAME ( VCMPEQUW )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPEQUW )
2016-06-07 22:24:20 +02:00
NAME ( VCMPGEFP )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPGEFP )
2016-06-07 22:24:20 +02:00
NAME ( VCMPGTFP )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPGTFP )
2016-06-07 22:24:20 +02:00
NAME ( VCMPGTSB )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPGTSB )
2016-06-07 22:24:20 +02:00
NAME ( VCMPGTSH )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPGTSH )
2016-06-07 22:24:20 +02:00
NAME ( VCMPGTSW )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPGTSW )
2016-06-07 22:24:20 +02:00
NAME ( VCMPGTUB )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPGTUB )
2016-06-07 22:24:20 +02:00
NAME ( VCMPGTUH )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPGTUH )
2016-06-07 22:24:20 +02:00
NAME ( VCMPGTUW )
2021-12-30 17:39:18 +01:00
NAME_ ( VCMPGTUW )
2016-06-07 22:24:20 +02:00
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 )
2021-12-30 17:39:18 +01:00
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 )
2016-06-07 22:24:20 +02:00
# undef NAME
2021-12-30 17:39:18 +01:00
# undef NAME_
2016-06-07 22:24:20 +02:00
} ;