| 
									
										
										
										
											2015-05-24 06:32:32 +02:00
										 |  |  | // Copyright 2014 Dolphin Emulator Project
 | 
					
						
							|  |  |  | // Licensed under GPLv2+
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | /* $VER: ppc_disasm.c V1.5 (27.05.2009)
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Disassembler module for the PowerPC microprocessor family | 
					
						
							|  |  |  |  * Copyright (c) 1998-2001,2009,2011 Frank Wille | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Redistribution and use in source and binary forms, with or without | 
					
						
							|  |  |  |  * modification, are permitted provided that the following conditions are met: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 1. Redistributions of source code must retain the above copyright notice, | 
					
						
							|  |  |  |  * this list of conditions and the following disclaimer. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 2. Redistributions in binary form must reproduce the above copyright notice, | 
					
						
							|  |  |  |  * this list of conditions and the following disclaimer in the documentation | 
					
						
							|  |  |  |  * and/or other materials provided with the distribution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
					
						
							|  |  |  |  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
					
						
							|  |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
					
						
							|  |  |  |  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | 
					
						
							|  |  |  |  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 
					
						
							|  |  |  |  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 
					
						
							|  |  |  |  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 
					
						
							|  |  |  |  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 
					
						
							|  |  |  |  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 
					
						
							|  |  |  |  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 
					
						
							|  |  |  |  * POSSIBILITY OF SUCH DAMAGE. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Modified for use with Dolphin
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <string>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Common/CommonTypes.h"
 | 
					
						
							|  |  |  | #include "Common/GekkoDisassembler.h"
 | 
					
						
							|  |  |  | #include "Common/StringUtil.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // version/revision
 | 
					
						
							|  |  |  | #define PPCDISASM_VER 1
 | 
					
						
							|  |  |  | #define PPCDISASM_REV 6
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // general defines
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | #define PPCIDXMASK 0xfc000000
 | 
					
						
							|  |  |  | #define PPCIDX2MASK 0x000007fe
 | 
					
						
							|  |  |  | #define PPCDMASK 0x03e00000
 | 
					
						
							|  |  |  | #define PPCAMASK 0x001f0000
 | 
					
						
							|  |  |  | #define PPCBMASK 0x0000f800
 | 
					
						
							|  |  |  | #define PPCCMASK 0x000007c0
 | 
					
						
							|  |  |  | #define PPCMMASK 0x0000003e
 | 
					
						
							|  |  |  | #define PPCCRDMASK 0x03800000
 | 
					
						
							|  |  |  | #define PPCCRAMASK 0x001c0000
 | 
					
						
							|  |  |  | #define PPCLMASK 0x00600000
 | 
					
						
							|  |  |  | #define PPCOE 0x00000400
 | 
					
						
							|  |  |  | #define PPCVRC 0x00000400
 | 
					
						
							|  |  |  | #define PPCDST 0x02000000
 | 
					
						
							|  |  |  | #define PPCSTRM 0x00600000
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PPCIDXSH 26
 | 
					
						
							|  |  |  | #define PPCDSH 21
 | 
					
						
							|  |  |  | #define PPCASH 16
 | 
					
						
							|  |  |  | #define PPCBSH 11
 | 
					
						
							|  |  |  | #define PPCCSH 6
 | 
					
						
							|  |  |  | #define PPCMSH 1
 | 
					
						
							|  |  |  | #define PPCCRDSH 23
 | 
					
						
							|  |  |  | #define PPCCRASH 18
 | 
					
						
							|  |  |  | #define PPCLSH 21
 | 
					
						
							|  |  |  | #define PPCIDX2SH 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define PPCGETIDX(x) (((x)&PPCIDXMASK) >> PPCIDXSH)
 | 
					
						
							|  |  |  | #define PPCGETD(x) (((x)&PPCDMASK) >> PPCDSH)
 | 
					
						
							|  |  |  | #define PPCGETA(x) (((x)&PPCAMASK) >> PPCASH)
 | 
					
						
							|  |  |  | #define PPCGETB(x) (((x)&PPCBMASK) >> PPCBSH)
 | 
					
						
							|  |  |  | #define PPCGETC(x) (((x)&PPCCMASK) >> PPCCSH)
 | 
					
						
							|  |  |  | #define PPCGETM(x) (((x)&PPCMMASK) >> PPCMSH)
 | 
					
						
							|  |  |  | #define PPCGETCRD(x) (((x)&PPCCRDMASK) >> PPCCRDSH)
 | 
					
						
							|  |  |  | #define PPCGETCRA(x) (((x)&PPCCRAMASK) >> PPCCRASH)
 | 
					
						
							|  |  |  | #define PPCGETL(x) (((x)&PPCLMASK) >> PPCLSH)
 | 
					
						
							|  |  |  | #define PPCGETIDX2(x) (((x)&PPCIDX2MASK) >> PPCIDX2SH)
 | 
					
						
							|  |  |  | #define PPCGETSTRM(x) (((x)&PPCSTRM) >> PPCDSH)
 | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | static const char* trap_condition[32] = { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     nullptr, "lgt",   "llt",   nullptr, "eq",    "lge",   "lle",   nullptr, | 
					
						
							|  |  |  |     "gt",    nullptr, nullptr, nullptr, "ge",    nullptr, nullptr, nullptr, | 
					
						
							|  |  |  |     "lt",    nullptr, nullptr, nullptr, "le",    nullptr, nullptr, nullptr, | 
					
						
							|  |  |  |     "ne",    nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* cmpname[4] = {"cmpw", "cmpd", "cmplw", "cmpld"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* ps_cmpname[4] = {"ps_cmpu0", "ps_cmpo0", "ps_cmpu1", "ps_cmpo1"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* b_ext[4] = {"", "l", "a", "la"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* b_condition[8] = {"ge", "le", "ne", "ns", "lt", "gt", "eq", "so"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* b_decr[16] = {"nzf", "zf", nullptr, nullptr, "nzt", "zt", nullptr, nullptr, | 
					
						
							|  |  |  |                                  "nz",  "z",  nullptr, nullptr, "nz",  "z",  nullptr, nullptr}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* regsel[2] = {"", "r"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* oesel[2] = {"", "o"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* rcsel[2] = {"", "."}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* ldstnames[24] = {"lwz", "lwzu", "lbz", "lbzu", "stw",  "stwu",  "stb",  "stbu", | 
					
						
							|  |  |  |                                     "lhz", "lhzu", "lha", "lhau", "sth",  "sthu",  "lmw",  "stmw", | 
					
						
							|  |  |  |                                     "lfs", "lfsu", "lfd", "lfdu", "stfs", "stfsu", "stfd", "stfdu"}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char* regnames[32] = {"r0",  "sp",  "rtoc", "r3",  "r4",  "r5",  "r6",  "r7", | 
					
						
							|  |  |  |                                    "r8",  "r9",  "r10",  "r11", "r12", "r13", "r14", "r15", | 
					
						
							|  |  |  |                                    "r16", "r17", "r18",  "r19", "r20", "r21", "r22", "r23", | 
					
						
							|  |  |  |                                    "r24", "r25", "r26",  "r27", "r28", "r29", "r30", "r31"}; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Initialize static class variables.
 | 
					
						
							|  |  |  | u32* GekkoDisassembler::m_instr = nullptr; | 
					
						
							|  |  |  | u32* GekkoDisassembler::m_iaddr = nullptr; | 
					
						
							|  |  |  | std::string GekkoDisassembler::m_opcode = ""; | 
					
						
							|  |  |  | std::string GekkoDisassembler::m_operands = ""; | 
					
						
							|  |  |  | unsigned char GekkoDisassembler::m_type = 0; | 
					
						
							|  |  |  | unsigned char GekkoDisassembler::m_flags = PPCF_ILLEGAL; | 
					
						
							|  |  |  | unsigned short GekkoDisassembler::m_sreg = 0; | 
					
						
							|  |  |  | u32 GekkoDisassembler::m_displacement = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static std::string spr_name(int i) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   switch (i) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   case 1: | 
					
						
							|  |  |  |     return "XER"; | 
					
						
							|  |  |  |   case 8: | 
					
						
							|  |  |  |     return "LR"; | 
					
						
							|  |  |  |   case 9: | 
					
						
							|  |  |  |     return "CTR"; | 
					
						
							|  |  |  |   case 18: | 
					
						
							|  |  |  |     return "DSIR"; | 
					
						
							|  |  |  |   case 19: | 
					
						
							|  |  |  |     return "DAR"; | 
					
						
							|  |  |  |   case 22: | 
					
						
							|  |  |  |     return "DEC"; | 
					
						
							|  |  |  |   case 25: | 
					
						
							|  |  |  |     return "SDR1"; | 
					
						
							|  |  |  |   case 26: | 
					
						
							|  |  |  |     return "SRR0"; | 
					
						
							|  |  |  |   case 27: | 
					
						
							|  |  |  |     return "SRR1"; | 
					
						
							|  |  |  |   case 272: | 
					
						
							|  |  |  |     return "SPRG0"; | 
					
						
							|  |  |  |   case 273: | 
					
						
							|  |  |  |     return "SPRG1"; | 
					
						
							|  |  |  |   case 274: | 
					
						
							|  |  |  |     return "SPRG2"; | 
					
						
							|  |  |  |   case 275: | 
					
						
							|  |  |  |     return "SPRG3"; | 
					
						
							|  |  |  |   case 282: | 
					
						
							|  |  |  |     return "EAR"; | 
					
						
							|  |  |  |   case 287: | 
					
						
							|  |  |  |     return "PVR"; | 
					
						
							|  |  |  |   case 528: | 
					
						
							|  |  |  |     return "IBAT0U"; | 
					
						
							|  |  |  |   case 529: | 
					
						
							|  |  |  |     return "IBAT0L"; | 
					
						
							|  |  |  |   case 530: | 
					
						
							|  |  |  |     return "IBAT1U"; | 
					
						
							|  |  |  |   case 531: | 
					
						
							|  |  |  |     return "IBAT1L"; | 
					
						
							|  |  |  |   case 532: | 
					
						
							|  |  |  |     return "IBAT2U"; | 
					
						
							|  |  |  |   case 533: | 
					
						
							|  |  |  |     return "IBAT2L"; | 
					
						
							|  |  |  |   case 534: | 
					
						
							|  |  |  |     return "IBAT3U"; | 
					
						
							|  |  |  |   case 535: | 
					
						
							|  |  |  |     return "IBAT3L"; | 
					
						
							|  |  |  |   case 536: | 
					
						
							|  |  |  |     return "DBAT0U"; | 
					
						
							|  |  |  |   case 537: | 
					
						
							|  |  |  |     return "DBAT0L"; | 
					
						
							|  |  |  |   case 538: | 
					
						
							|  |  |  |     return "DBAT1U"; | 
					
						
							|  |  |  |   case 539: | 
					
						
							|  |  |  |     return "DBAT1L"; | 
					
						
							|  |  |  |   case 540: | 
					
						
							|  |  |  |     return "DBAT2U"; | 
					
						
							|  |  |  |   case 541: | 
					
						
							|  |  |  |     return "DBAT2L"; | 
					
						
							|  |  |  |   case 542: | 
					
						
							|  |  |  |     return "DBAT3U"; | 
					
						
							|  |  |  |   case 543: | 
					
						
							|  |  |  |     return "DBAT3L"; | 
					
						
							|  |  |  |   case 912: | 
					
						
							|  |  |  |     return "GQR0"; | 
					
						
							|  |  |  |   case 913: | 
					
						
							|  |  |  |     return "GQR1"; | 
					
						
							|  |  |  |   case 914: | 
					
						
							|  |  |  |     return "GQR2"; | 
					
						
							|  |  |  |   case 915: | 
					
						
							|  |  |  |     return "GQR3"; | 
					
						
							|  |  |  |   case 916: | 
					
						
							|  |  |  |     return "GQR4"; | 
					
						
							|  |  |  |   case 917: | 
					
						
							|  |  |  |     return "GQR5"; | 
					
						
							|  |  |  |   case 918: | 
					
						
							|  |  |  |     return "GQR6"; | 
					
						
							|  |  |  |   case 919: | 
					
						
							|  |  |  |     return "GQR7"; | 
					
						
							|  |  |  |   case 920: | 
					
						
							|  |  |  |     return "HID2"; | 
					
						
							|  |  |  |   case 921: | 
					
						
							|  |  |  |     return "WPAR"; | 
					
						
							|  |  |  |   case 922: | 
					
						
							|  |  |  |     return "DMA_U"; | 
					
						
							|  |  |  |   case 923: | 
					
						
							|  |  |  |     return "DMA_L"; | 
					
						
							|  |  |  |   case 924: | 
					
						
							|  |  |  |     return "ECID_U"; | 
					
						
							|  |  |  |   case 925: | 
					
						
							|  |  |  |     return "ECID_M"; | 
					
						
							|  |  |  |   case 926: | 
					
						
							|  |  |  |     return "ECID_L"; | 
					
						
							|  |  |  |   case 936: | 
					
						
							|  |  |  |     return "UMMCR0"; | 
					
						
							|  |  |  |   case 937: | 
					
						
							|  |  |  |     return "UPMC1"; | 
					
						
							|  |  |  |   case 938: | 
					
						
							|  |  |  |     return "UPMC2"; | 
					
						
							|  |  |  |   case 939: | 
					
						
							|  |  |  |     return "USIA"; | 
					
						
							|  |  |  |   case 940: | 
					
						
							|  |  |  |     return "UMMCR1"; | 
					
						
							|  |  |  |   case 941: | 
					
						
							|  |  |  |     return "UPMC3"; | 
					
						
							|  |  |  |   case 942: | 
					
						
							|  |  |  |     return "UPMC4"; | 
					
						
							|  |  |  |   case 943: | 
					
						
							|  |  |  |     return "USDA"; | 
					
						
							|  |  |  |   case 952: | 
					
						
							|  |  |  |     return "MMCR0"; | 
					
						
							|  |  |  |   case 953: | 
					
						
							|  |  |  |     return "PMC1"; | 
					
						
							|  |  |  |   case 954: | 
					
						
							|  |  |  |     return "PMC2"; | 
					
						
							|  |  |  |   case 955: | 
					
						
							|  |  |  |     return "SIA"; | 
					
						
							|  |  |  |   case 956: | 
					
						
							|  |  |  |     return "MMCR1"; | 
					
						
							|  |  |  |   case 957: | 
					
						
							|  |  |  |     return "PMC3"; | 
					
						
							|  |  |  |   case 958: | 
					
						
							|  |  |  |     return "PMC4"; | 
					
						
							|  |  |  |   case 959: | 
					
						
							|  |  |  |     return "SDA"; | 
					
						
							|  |  |  |   case 1008: | 
					
						
							|  |  |  |     return "HID0"; | 
					
						
							|  |  |  |   case 1009: | 
					
						
							|  |  |  |     return "HID1"; | 
					
						
							|  |  |  |   case 1010: | 
					
						
							|  |  |  |     return "IABR"; | 
					
						
							|  |  |  |   case 1011: | 
					
						
							|  |  |  |     return "HID4"; | 
					
						
							|  |  |  |   case 1013: | 
					
						
							|  |  |  |     return "DABR"; | 
					
						
							|  |  |  |   case 1017: | 
					
						
							|  |  |  |     return "L2CR"; | 
					
						
							|  |  |  |   case 1019: | 
					
						
							|  |  |  |     return "ICTC"; | 
					
						
							|  |  |  |   case 1020: | 
					
						
							|  |  |  |     return "THRM1"; | 
					
						
							|  |  |  |   case 1021: | 
					
						
							|  |  |  |     return "THRM2"; | 
					
						
							|  |  |  |   case 1022: | 
					
						
							|  |  |  |     return "THRM3"; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return StringFromFormat("%d", i); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static u32 swapda(u32 w) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return ((w & 0xfc00ffff) | ((w & PPCAMASK) << 5) | ((w & PPCDMASK) >> 5)); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static u32 swapab(u32 w) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return ((w & 0xffe007ff) | ((w & PPCBMASK) << 5) | ((w & PPCAMASK) >> 5)); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::ill(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (in == 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = ""; | 
					
						
							|  |  |  |     m_operands = "---"; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = "(ill)"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("%08x", in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_flags |= PPCF_ILLEGAL; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Generate immediate instruction operand.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Type 0: D-mode, D,A,imm
 | 
					
						
							|  |  |  | // Type 1: S-mode, A,S,imm
 | 
					
						
							|  |  |  | // Type 2: S/D register is ignored (trap,cmpi)
 | 
					
						
							|  |  |  | // Type 3: A register is ignored (li)
 | 
					
						
							|  |  |  | std::string GekkoDisassembler::imm(u32 in, int uimm, int type, bool hex) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int i = (int)(in & 0xffff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_type = PPCINSTR_IMM; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (uimm == 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (i > 0x7fff) | 
					
						
							|  |  |  |       i -= 0x10000; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_flags |= PPCF_UNSIGNED; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   m_displacement = i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (type) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   case 0: | 
					
						
							|  |  |  |     return StringFromFormat("%s, %s, %d", regnames[(int)PPCGETD(in)], regnames[(int)PPCGETA(in)], | 
					
						
							|  |  |  |                             i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 1: | 
					
						
							|  |  |  |     if (hex) | 
					
						
							|  |  |  |       return StringFromFormat("%s, %s, 0x%.4X", regnames[(int)PPCGETA(in)], | 
					
						
							|  |  |  |                               regnames[(int)PPCGETD(in)], i); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       return StringFromFormat("%s, %s, %d", regnames[(int)PPCGETA(in)], regnames[(int)PPCGETD(in)], | 
					
						
							|  |  |  |                               i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 2: | 
					
						
							|  |  |  |     return StringFromFormat("%s, %d", regnames[(int)PPCGETA(in)], i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 3: | 
					
						
							|  |  |  |     if (hex) | 
					
						
							|  |  |  |       return StringFromFormat("%s, 0x%.4X", regnames[(int)PPCGETD(in)], i); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       return StringFromFormat("%s, %d", regnames[(int)PPCGETD(in)], i); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |     return StringFromFormat("%s", "imm(): Wrong type"); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string GekkoDisassembler::ra_rb(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return StringFromFormat("%s, %s", regnames[(int)PPCGETA(in)], regnames[(int)PPCGETB(in)]); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string GekkoDisassembler::rd_ra_rb(u32 in, int mask) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   std::string result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mask) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (mask & 4) | 
					
						
							|  |  |  |       result += StringFromFormat("%s, ", regnames[(int)PPCGETD(in)]); | 
					
						
							|  |  |  |     if (mask & 2) | 
					
						
							|  |  |  |       result += StringFromFormat("%s, ", regnames[(int)PPCGETA(in)]); | 
					
						
							|  |  |  |     if (mask & 1) | 
					
						
							|  |  |  |       result += StringFromFormat("%s, ", regnames[(int)PPCGETB(in)]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     size_t pos = result.rfind(", "); | 
					
						
							|  |  |  |     if (pos != std::string::npos) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       result.erase(pos, result.length() - pos); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return result; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string GekkoDisassembler::fd_ra_rb(u32 in, int mask) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   std::string result; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (mask) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (mask & 4) | 
					
						
							|  |  |  |       result += StringFromFormat("f%d,", (int)PPCGETD(in)); | 
					
						
							|  |  |  |     if (mask & 2) | 
					
						
							|  |  |  |       result += StringFromFormat("%s,", regnames[(int)PPCGETA(in)]); | 
					
						
							|  |  |  |     if (mask & 1) | 
					
						
							|  |  |  |       result += StringFromFormat("%s,", regnames[(int)PPCGETB(in)]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Drop the trailing comma
 | 
					
						
							|  |  |  |     result.pop_back(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return result; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::trapi(u32 in, unsigned char dmode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   const char* cnd = trap_condition[PPCGETD(in)]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_flags |= dmode; | 
					
						
							|  |  |  |   if (cnd != nullptr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("t%c%s", dmode ? 'd' : 'w', cnd); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("t%ci", dmode ? 'd' : 'w'); | 
					
						
							|  |  |  |     m_operands = StringFromFormat("%d, ", PPCGETD(in)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   m_operands += imm(in, 0, 2, false); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::cmpi(u32 in, int uimm) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int i = (int)PPCGETL(in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (i < 2) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (i != 0) | 
					
						
							|  |  |  |       m_flags |= PPCF_64; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("%si", cmpname[uimm * 2 + i]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     i = (int)PPCGETCRD(in); | 
					
						
							|  |  |  |     if (i != 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       m_operands += StringFromFormat("cr%c, ", '0' + i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_operands += imm(in, uimm, 2, false); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::addi(u32 in, const std::string& ext) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if ((in & 0x08000000) && !PPCGETA(in)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("l%s", ext.c_str());  // li, lis
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ext == "i") | 
					
						
							|  |  |  |       m_operands = imm(in, 0, 3, false); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       m_operands = imm(in, 1, 3, true); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("%s%s", (in & 0x8000) ? "sub" : "add", ext.c_str()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (in & 0x8000) | 
					
						
							|  |  |  |       in = (in ^ 0xffff) + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_operands = imm(in, 1, 0, false); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Build a branch instr. and return number of chars written to operand.
 | 
					
						
							|  |  |  | size_t GekkoDisassembler::branch(u32 in, const char* bname, int aform, int bdisp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int bo = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int bi = (int)PPCGETA(in); | 
					
						
							|  |  |  |   char y = (char)(bo & 1); | 
					
						
							|  |  |  |   const char* ext = b_ext[aform * 2 + (int)(in & 1)]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (bdisp < 0) | 
					
						
							|  |  |  |     y ^= 1; | 
					
						
							|  |  |  |   y = (y != 0) ? '+' : '-'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (bo & 4) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // standard case - no decrement
 | 
					
						
							|  |  |  |     if (bo & 16) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       // branch always
 | 
					
						
							|  |  |  |       if (PPCGETIDX(in) != 16) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         m_opcode = StringFromFormat("b%s%s", bname, ext); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         m_opcode = StringFromFormat("bc%s", ext); | 
					
						
							|  |  |  |         m_operands = StringFromFormat("%d, %d", bo, bi); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else  // Branch conditional
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       m_opcode = | 
					
						
							|  |  |  |           StringFromFormat("b%s%s%s%c", b_condition[((bo & 8) >> 1) + (bi & 3)], bname, ext, y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (bi >= 4) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         m_operands = StringFromFormat("cr%d", bi >> 2); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     // CTR is decremented and checked
 | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("bd%s%s%s%c", b_decr[bo >> 1], bname, ext, y); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((bo & 16) == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       m_operands = StringFromFormat("%d", bi); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return m_operands.length(); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::bc(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   unsigned int d = (int)(in & 0xfffc); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (d & 0x8000) | 
					
						
							|  |  |  |     d |= 0xffff0000; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   branch(in, "", (in & 2) ? 1 : 0, d); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (in & 2)  // AA ?
 | 
					
						
							|  |  |  |     m_operands = StringFromFormat("%s ->0x%.8X", m_operands.c_str(), d); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     m_operands = StringFromFormat("%s ->0x%.8X", m_operands.c_str(), *m_iaddr + d); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_type = PPCINSTR_BRANCH; | 
					
						
							|  |  |  |   m_displacement = d; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::bli(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   unsigned int d = (unsigned int)(in & 0x3fffffc); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (d & 0x02000000) | 
					
						
							|  |  |  |     d |= 0xfc000000; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_opcode = StringFromFormat("b%s", b_ext[in & 3]); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (in & 2)  // AA ?
 | 
					
						
							|  |  |  |     m_operands = StringFromFormat("->0x%.8X", d); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     m_operands = StringFromFormat("->0x%.8X", *m_iaddr + d); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_type = PPCINSTR_BRANCH; | 
					
						
							|  |  |  |   m_displacement = d; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::mcrf(u32 in, char c) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if ((in & 0x0063f801) == 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("mcrf%c", c); | 
					
						
							|  |  |  |     m_operands = StringFromFormat("cr%d, cr%d", (int)PPCGETCRD(in), (int)PPCGETCRA(in)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::crop(u32 in, const char* n1, const char* n2) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int crd = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int cra = (int)PPCGETA(in); | 
					
						
							|  |  |  |   int crb = (int)PPCGETB(in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if ((in & 1) == 0) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("cr%s", (cra == crb && n2) ? n2 : n1); | 
					
						
							|  |  |  |     if (cra == crb && n2) | 
					
						
							|  |  |  |       m_operands = StringFromFormat("%d, %d", crd, cra); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       m_operands = StringFromFormat("%d, %d, %d", crd, cra, crb); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::nooper(u32 in, const char* name, unsigned char dmode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (in & (PPCDMASK | PPCAMASK | PPCBMASK | 1)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_flags |= dmode; | 
					
						
							|  |  |  |     m_opcode = name; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::rlw(u32 in, const char* name, int i) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int s = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int a = (int)PPCGETA(in); | 
					
						
							|  |  |  |   int bsh = (int)PPCGETB(in); | 
					
						
							|  |  |  |   int mb = (int)PPCGETC(in); | 
					
						
							|  |  |  |   int me = (int)PPCGETM(in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_opcode = StringFromFormat("rlw%s%c", name, in & 1 ? '.' : '\0'); | 
					
						
							|  |  |  |   m_operands = StringFromFormat("%s, %s, %s%d, %d, %d (%08x)", regnames[a], regnames[s], regsel[i], | 
					
						
							|  |  |  |                                 bsh, mb, me, HelperRotateMask(bsh, mb, me)); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::ori(u32 in, const char* name) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_opcode = name; | 
					
						
							|  |  |  |   m_operands = imm(in, 1, 1, true); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::rld(u32 in, const char* name, int i) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int s = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int a = (int)PPCGETA(in); | 
					
						
							|  |  |  |   int bsh = i ? (int)PPCGETB(in) : (int)(((in & 2) << 4) + PPCGETB(in)); | 
					
						
							|  |  |  |   int m = (int)(in & 0x7e0) >> 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_flags |= PPCF_64; | 
					
						
							|  |  |  |   m_opcode = StringFromFormat("rld%s%c", name, in & 1 ? '.' : '\0'); | 
					
						
							|  |  |  |   m_operands = StringFromFormat("%s, %s, %s%d, %d", regnames[a], regnames[s], regsel[i], bsh, m); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::cmp(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int i = (int)PPCGETL(in); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (i < 2) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (i != 0) | 
					
						
							|  |  |  |       m_flags |= PPCF_64; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     m_opcode = cmpname[((in & PPCIDX2MASK) ? 2 : 0) + i]; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     i = (int)PPCGETCRD(in); | 
					
						
							|  |  |  |     if (i != 0) | 
					
						
							|  |  |  |       m_operands += StringFromFormat("cr%c,", '0' + i); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |     m_operands += ra_rb(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::trap(u32 in, unsigned char dmode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int to = (int)PPCGETD(in); | 
					
						
							|  |  |  |   const char* cnd = trap_condition[to]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (cnd != nullptr) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_flags |= dmode; | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("t%c%s", dmode ? 'd' : 'w', cnd); | 
					
						
							|  |  |  |     m_operands = ra_rb(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (to == 31) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (dmode) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         m_flags |= dmode; | 
					
						
							|  |  |  |         m_opcode = "td"; | 
					
						
							|  |  |  |         m_operands = "31,0,0"; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         m_opcode = "trap"; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       ill(in); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Standard instruction: xxxx rD,rA,rB
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | void GekkoDisassembler::dab(u32 in, const char* name, int mask, int smode, int chkoe, int chkrc, | 
					
						
							|  |  |  |                             unsigned char dmode) | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (chkrc >= 0 && ((in & 1) != (unsigned int)chkrc)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_flags |= dmode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // rA,rS,rB
 | 
					
						
							|  |  |  |     if (smode) | 
					
						
							|  |  |  |       in = swapda(in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("%s%s%s", name, oesel[chkoe && (in & PPCOE)], | 
					
						
							|  |  |  |                                 rcsel[(chkrc < 0) && (in & 1)]); | 
					
						
							|  |  |  |     m_operands = rd_ra_rb(in, mask); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Last operand is no register: xxxx rD,rA,NB
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | void GekkoDisassembler::rrn(u32 in, const char* name, int smode, int chkoe, int chkrc, | 
					
						
							|  |  |  |                             unsigned char dmode) | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (chkrc >= 0 && ((in & 1) != (unsigned int)chkrc)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_flags |= dmode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // rA,rS,NB
 | 
					
						
							|  |  |  |     if (smode) | 
					
						
							|  |  |  |       in = swapda(in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("%s%s%s", name, oesel[chkoe && (in & PPCOE)], | 
					
						
							|  |  |  |                                 rcsel[(chkrc < 0) && (in & 1)]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_operands = rd_ra_rb(in, 6); | 
					
						
							|  |  |  |     m_operands += StringFromFormat(",%d", (int)PPCGETB(in)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::mtcr(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int s = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int crm = (int)(in & 0x000ff000) >> 12; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (in & 0x00100801) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("mtcr%c", crm == 0xff ? '\0' : 'f'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (crm != 0xff) | 
					
						
							|  |  |  |       m_operands += StringFromFormat("0x%02x,", crm); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_operands += regnames[s]; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::msr(u32 in, int smode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int s = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int sr = (int)(in & 0x000f0000) >> 16; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (in & 0x0010f801) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_flags |= PPCF_SUPER; | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("m%csr", smode ? 't' : 'f'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (smode) | 
					
						
							|  |  |  |       m_operands = StringFromFormat("%d, %s", sr, regnames[s]); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       m_operands = StringFromFormat("%s, %d", regnames[s], sr); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::mspr(u32 in, int smode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int d = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int spr = (int)((PPCGETB(in) << 5) + PPCGETA(in)); | 
					
						
							|  |  |  |   int fmt = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (in & 1) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     if (spr != 1 && spr != 8 && spr != 9) | 
					
						
							|  |  |  |       m_flags |= PPCF_SUPER; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const char* x; | 
					
						
							|  |  |  |     switch (spr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case 1: | 
					
						
							|  |  |  |       x = "xer"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 8: | 
					
						
							|  |  |  |       x = "lr"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 9: | 
					
						
							|  |  |  |       x = "ctr"; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       x = "spr"; | 
					
						
							|  |  |  |       fmt = 1; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("m%c%s", smode ? 't' : 'f', x); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (fmt) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (smode) | 
					
						
							|  |  |  |         m_operands = StringFromFormat("%s, %s", spr_name(spr).c_str(), regnames[d]); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         m_operands = StringFromFormat("%s, %s", regnames[d], spr_name(spr).c_str()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       m_operands = regnames[d]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::mtb(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int d = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int tbr = (int)((PPCGETB(in) << 5) + PPCGETA(in)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (in & 1) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_operands += regnames[d]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     char x; | 
					
						
							|  |  |  |     switch (tbr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case 268: | 
					
						
							|  |  |  |       x = 'l'; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 269: | 
					
						
							|  |  |  |       x = 'u'; | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       x = '\0'; | 
					
						
							|  |  |  |       m_flags |= PPCF_SUPER; | 
					
						
							|  |  |  |       m_operands += StringFromFormat(",%d", tbr); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("mftb%c", x); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::sradi(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int s = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int a = (int)PPCGETA(in); | 
					
						
							|  |  |  |   int bsh = (int)(((in & 2) << 4) + PPCGETB(in)); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_flags |= PPCF_64; | 
					
						
							|  |  |  |   m_opcode = StringFromFormat("sradi%c", in & 1 ? '.' : '\0'); | 
					
						
							|  |  |  |   m_operands = StringFromFormat("%s, %s, %d", regnames[a], regnames[s], bsh); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::ldst(u32 in, const char* name, char reg, unsigned char dmode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int s = (int)PPCGETD(in); | 
					
						
							|  |  |  |   int a = (int)PPCGETA(in); | 
					
						
							|  |  |  |   int d = (u32)(in & 0xffff); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_type = PPCINSTR_LDST; | 
					
						
							|  |  |  |   m_flags |= dmode; | 
					
						
							|  |  |  |   m_sreg = (short)a; | 
					
						
							|  |  |  |   //  if (d >= 0x8000)
 | 
					
						
							|  |  |  |   //    d -= 0x10000;
 | 
					
						
							|  |  |  |   m_displacement = (u32)d; | 
					
						
							|  |  |  |   m_opcode = name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (reg == 'r') | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_operands = StringFromFormat("%s, %s (%s)", regnames[s], ldst_offs(d).c_str(), regnames[a]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_operands = StringFromFormat("%c%d, %s (%s)", reg, s, ldst_offs(d).c_str(), regnames[a]); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Standard floating point instruction: xxxx fD,fA,fC,fB
 | 
					
						
							|  |  |  | void GekkoDisassembler::fdabc(u32 in, const char* name, int mask, unsigned char dmode) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   int err = 0; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_flags |= dmode; | 
					
						
							|  |  |  |   m_opcode = StringFromFormat("f%s%s", name, rcsel[in & 1]); | 
					
						
							|  |  |  |   m_operands += StringFromFormat("f%d,", (int)PPCGETD(in)); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (mask & 4) | 
					
						
							|  |  |  |     m_operands += StringFromFormat("f%d,", (int)PPCGETA(in)); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     err |= (int)PPCGETA(in); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (mask & 2) | 
					
						
							|  |  |  |     m_operands += StringFromFormat("f%d,", (int)PPCGETC(in)); | 
					
						
							|  |  |  |   else if (PPCGETC(in)) | 
					
						
							|  |  |  |     err |= (int)PPCGETC(in); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (mask & 1) | 
					
						
							|  |  |  |     m_operands += StringFromFormat("f%d,", (int)PPCGETB(in)); | 
					
						
							|  |  |  |   else if (!(mask & 8)) | 
					
						
							|  |  |  |     err |= (int)PPCGETB(in); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   // Drop the trailing comma
 | 
					
						
							|  |  |  |   m_operands.pop_back(); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (err) | 
					
						
							|  |  |  |     ill(in); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::fmr(u32 in) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_opcode = StringFromFormat("fmr%s", rcsel[in & 1]); | 
					
						
							|  |  |  |   m_operands = StringFromFormat("f%d, f%d", (int)PPCGETD(in), (int)PPCGETB(in)); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Indexed float instruction: xxxx fD,rA,rB
 | 
					
						
							|  |  |  | void GekkoDisassembler::fdab(u32 in, const char* name, int mask) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_opcode = name; | 
					
						
							|  |  |  |   m_operands = fd_ra_rb(in, mask); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::fcmp(u32 in, char c) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (in & 0x00600001) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("fcmp%c", c); | 
					
						
							|  |  |  |     m_operands = | 
					
						
							|  |  |  |         StringFromFormat("cr%d,f%d,f%d", (int)PPCGETCRD(in), (int)PPCGETA(in), (int)PPCGETB(in)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::mtfsb(u32 in, int n) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (in & (PPCAMASK | PPCBMASK)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = StringFromFormat("mtfsb%d%s", n, rcsel[in & 1]); | 
					
						
							|  |  |  |     m_operands = StringFromFormat("%d", (int)PPCGETD(in)); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Paired instructions
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define RA ((inst >> 16) & 0x1f)
 | 
					
						
							|  |  |  | #define RB ((inst >> 11) & 0x1f)
 | 
					
						
							|  |  |  | #define RC ((inst >> 6) & 0x1f)
 | 
					
						
							|  |  |  | #define RD ((inst >> 21) & 0x1f)
 | 
					
						
							|  |  |  | #define RS ((inst >> 21) & 0x1f)
 | 
					
						
							|  |  |  | #define FA ((inst >> 16) & 0x1f)
 | 
					
						
							|  |  |  | #define FB ((inst >> 11) & 0x1f)
 | 
					
						
							|  |  |  | #define FC ((inst >> 6) & 0x1f)
 | 
					
						
							|  |  |  | #define FD ((inst >> 21) & 0x1f)
 | 
					
						
							|  |  |  | #define FS ((inst >> 21) & 0x1f)
 | 
					
						
							|  |  |  | #define IMM (inst & 0xffff)
 | 
					
						
							|  |  |  | #define UIMM (inst & 0xffff)
 | 
					
						
							|  |  |  | #define OFS (inst & 0xffff)
 | 
					
						
							|  |  |  | #define OPCD ((inst >> 26) & 0x3f)
 | 
					
						
							|  |  |  | #define XO_10 ((inst >> 1) & 0x3ff)
 | 
					
						
							|  |  |  | #define XO_9 ((inst >> 1) & 0x1ff)
 | 
					
						
							|  |  |  | #define XO_5 ((inst >> 1) & 0x1f)
 | 
					
						
							|  |  |  | #define Rc (inst & 1)
 | 
					
						
							|  |  |  | #define SH ((inst >> 11) & 0x1f)
 | 
					
						
							|  |  |  | #define MB ((inst >> 6) & 0x1f)
 | 
					
						
							|  |  |  | #define ME ((inst >> 1) & 0x1f)
 | 
					
						
							|  |  |  | #define OE ((inst >> 10) & 1)
 | 
					
						
							|  |  |  | #define TO ((inst >> 21) & 0x1f)
 | 
					
						
							|  |  |  | #define CRFD ((inst >> 23) & 0x7)
 | 
					
						
							|  |  |  | #define CRFS ((inst >> 18) & 0x7)
 | 
					
						
							|  |  |  | #define CRBD ((inst >> 21) & 0x1f)
 | 
					
						
							|  |  |  | #define CRBA ((inst >> 16) & 0x1f)
 | 
					
						
							|  |  |  | #define CRBB ((inst >> 11) & 0x1f)
 | 
					
						
							|  |  |  | #define L ((inst >> 21) & 1)
 | 
					
						
							|  |  |  | #define NB ((inst >> 11) & 0x1f)
 | 
					
						
							|  |  |  | #define AA ((inst >> 1) & 1)
 | 
					
						
							|  |  |  | #define LK (inst & 1)
 | 
					
						
							|  |  |  | #define LI ((inst >> 2) & 0xffffff)
 | 
					
						
							|  |  |  | #define BO ((inst >> 21) & 0x1f)
 | 
					
						
							|  |  |  | #define BI ((inst >> 16) & 0x1f)
 | 
					
						
							|  |  |  | #define BD ((inst >> 2) & 0x3fff)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define MTFSFI_IMM ((inst >> 12) & 0xf)
 | 
					
						
							|  |  |  | #define FM ((inst >> 17) & 0xff)
 | 
					
						
							|  |  |  | #define SR ((inst >> 16) & 0xf)
 | 
					
						
							|  |  |  | #define SPR ((inst >> 11) & 0x3ff)
 | 
					
						
							|  |  |  | #define TBR ((inst >> 11) & 0x3ff)
 | 
					
						
							|  |  |  | #define CRM ((inst >> 12) & 0xff)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-28 17:01:35 -07:00
										 |  |  | #define I ((inst >> 12) & 0x7)
 | 
					
						
							|  |  |  | #define W ((inst >> 15) & 0x1)
 | 
					
						
							|  |  |  | #define IX ((inst >> 7) & 0x7)
 | 
					
						
							|  |  |  | #define WX ((inst >> 10) & 0x1)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | void GekkoDisassembler::ps(u32 inst) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   switch ((inst >> 1) & 0x1F) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   case 6: | 
					
						
							|  |  |  |     m_opcode = inst & 0x40 ? "psq_lux" : "psq_lx"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, (r%u + r%u), %d, qr%d", FD, RA, RB, WX, IX); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 7: | 
					
						
							|  |  |  |     m_opcode = inst & 0x40 ? "psq_stux" : "psq_stx"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, r%u, r%u, %d, qr%d", FS, RA, RB, WX, IX); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 18: | 
					
						
							|  |  |  |     m_opcode = "ps_div"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u/p%u", FD, FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 20: | 
					
						
							|  |  |  |     m_opcode = "ps_sub"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u-p%u", FD, FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 21: | 
					
						
							|  |  |  |     m_opcode = "ps_add"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u+p%u", FD, FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 23: | 
					
						
							|  |  |  |     m_opcode = "ps_sel"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u>=0?p%u:p%u", FD, FA, FC); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 24: | 
					
						
							|  |  |  |     m_opcode = "ps_res"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, (1/p%u)", FD, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 25: | 
					
						
							|  |  |  |     m_opcode = "ps_mul"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u*p%u", FD, FA, FC); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 26:  // rsqrte
 | 
					
						
							|  |  |  |     m_opcode = "ps_rsqrte"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u", FD, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 28:  // msub
 | 
					
						
							|  |  |  |     m_opcode = "ps_msub"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u*p%u-p%u", FD, FA, FC, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 29:  // madd
 | 
					
						
							|  |  |  |     m_opcode = "ps_madd"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u*p%u+p%u", FD, FA, FC, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 30:  // nmsub
 | 
					
						
							|  |  |  |     m_opcode = "ps_nmsub"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, -(p%u*p%u-p%u)", FD, FA, FC, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 31:  // nmadd
 | 
					
						
							|  |  |  |     m_opcode = "ps_nmadd"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, -(p%u*p%u+p%u)", FD, FA, FC, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 10: | 
					
						
							|  |  |  |     m_opcode = "ps_sum0"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, 0=p%u+p%u, 1=p%u", FD, FA, FB, FC); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 11: | 
					
						
							|  |  |  |     m_opcode = "ps_sum1"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, 0=p%u, 1=p%u+p%u", FD, FC, FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 12: | 
					
						
							|  |  |  |     m_opcode = "ps_muls0"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u*p%u[0]", FD, FA, FC); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 13: | 
					
						
							|  |  |  |     m_opcode = "ps_muls1"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u*p%u[1]", FD, FA, FC); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 14: | 
					
						
							|  |  |  |     m_opcode = "ps_madds0"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u*p%u[0]+p%u", FD, FA, FC, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 15: | 
					
						
							|  |  |  |     m_opcode = "ps_madds1"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u*p%u[1]+p%u", FD, FA, FC, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch ((inst >> 1) & 0x3FF) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   // 10-bit suckers  (?)
 | 
					
						
							|  |  |  |   case 40:  // nmadd
 | 
					
						
							|  |  |  |     m_opcode = "ps_neg"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, -p%u", FD, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 72:  // nmadd
 | 
					
						
							|  |  |  |     m_opcode = "ps_mr"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u", FD, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 136: | 
					
						
							|  |  |  |     m_opcode = "ps_nabs"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, -|p%u|", FD, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 264: | 
					
						
							|  |  |  |     m_opcode = "ps_abs"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, |p%u|", FD, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 0: | 
					
						
							|  |  |  |   case 32: | 
					
						
							|  |  |  |   case 64: | 
					
						
							|  |  |  |   case 96: | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     m_opcode = ps_cmpname[(inst >> 6) & 0x3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int i = (int)PPCGETCRD(inst); | 
					
						
							|  |  |  |     if (i != 0) | 
					
						
							|  |  |  |       m_operands += StringFromFormat("cr%c, ", '0' + i); | 
					
						
							|  |  |  |     m_operands += StringFromFormat("p%u, p%u", FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   case 528: | 
					
						
							|  |  |  |     m_opcode = "ps_merge00"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u[0],p%u[0]", FD, FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 560: | 
					
						
							|  |  |  |     m_opcode = "ps_merge01"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u[0],p%u[1]", FD, FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 592: | 
					
						
							|  |  |  |     m_opcode = "ps_merge10"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u[1],p%u[0]", FD, FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 624: | 
					
						
							|  |  |  |     m_opcode = "ps_merge11"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, p%u[1],p%u[1]", FD, FA, FB); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 1014: | 
					
						
							|  |  |  |     if (inst & PPCDMASK) | 
					
						
							|  |  |  |       ill(inst); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       dab(inst, "dcbz_l", 3, 0, 0, 0, 0); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //	default:
 | 
					
						
							|  |  |  |   m_opcode = StringFromFormat("ps_%i", ((inst >> 1) & 0x1f)); | 
					
						
							|  |  |  |   m_operands = "---"; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GekkoDisassembler::ps_mem(u32 inst) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   switch (PPCGETIDX(inst)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   case 56: | 
					
						
							|  |  |  |     m_opcode = "psq_l"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, %i(r%u), %d, qr%d", RS, SEX12(inst & 0xFFF), RA, W, I); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 57: | 
					
						
							|  |  |  |     m_opcode = "psq_lu"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, %i(r%u), %d, qr%d", RS, SEX12(inst & 0xFFF), RA, W, I); | 
					
						
							|  |  |  |     ; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 60: | 
					
						
							|  |  |  |     m_opcode = "psq_st"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, %i(r%u), %d, qr%d", RS, SEX12(inst & 0xFFF), RA, W, I); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 61: | 
					
						
							|  |  |  |     m_opcode = "psq_stu"; | 
					
						
							|  |  |  |     m_operands = StringFromFormat("p%u, %i(r%u), %d, qr%d", RS, SEX12(inst & 0xFFF), RA, W, I); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Disassemble PPC instruction and return a pointer to the next
 | 
					
						
							| 
									
										
										
										
											2016-02-19 01:48:10 +00:00
										 |  |  | // instruction, or nullptr if an error occurred.
 | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | u32* GekkoDisassembler::DoDisassembly(bool big_endian) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 in = *m_instr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!big_endian) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     in = (in & 0xff) << 24 | (in & 0xff00) << 8 | (in & 0xff0000) >> 8 | (in & 0xff000000) >> 24; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_opcode.clear(); | 
					
						
							|  |  |  |   m_operands.clear(); | 
					
						
							|  |  |  |   m_type = PPCINSTR_OTHER; | 
					
						
							|  |  |  |   m_flags = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   switch (PPCGETIDX(in)) | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |   case 2: | 
					
						
							|  |  |  |     trapi(in, PPCF_64);  // tdi
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 3: | 
					
						
							|  |  |  |     trapi(in, 0);  // twi
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 4: | 
					
						
							|  |  |  |     ps(in); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 56: | 
					
						
							|  |  |  |   case 57: | 
					
						
							|  |  |  |   case 60: | 
					
						
							|  |  |  |   case 61: | 
					
						
							|  |  |  |     ps_mem(in); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 7: | 
					
						
							|  |  |  |     m_opcode = "mulli"; | 
					
						
							|  |  |  |     m_operands = imm(in, 0, 0, false); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 8: | 
					
						
							|  |  |  |     m_opcode = "subfic"; | 
					
						
							|  |  |  |     m_operands = imm(in, 0, 0, false); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 10: | 
					
						
							|  |  |  |     cmpi(in, 1);  // cmpli
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 11: | 
					
						
							|  |  |  |     cmpi(in, 0);  // cmpi
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 12: | 
					
						
							|  |  |  |     addi(in, "ic");  // addic
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 13: | 
					
						
							|  |  |  |     addi(in, "ic.");  // addic.
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 14: | 
					
						
							|  |  |  |     addi(in, "i");  // addi
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 15: | 
					
						
							|  |  |  |     addi(in, "is");  // addis
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 16: | 
					
						
							|  |  |  |     bc(in); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 17: | 
					
						
							|  |  |  |     if ((in & ~PPCIDXMASK) == 2) | 
					
						
							|  |  |  |       m_opcode = "sc"; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       ill(in); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 18: | 
					
						
							|  |  |  |     bli(in); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 19: | 
					
						
							|  |  |  |     switch (PPCGETIDX2(in)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |       mcrf(in, '\0');  // mcrf
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 16: | 
					
						
							|  |  |  |       branch(in, "lr", 0, 0);  // bclr
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 33: | 
					
						
							|  |  |  |       crop(in, "nor", "not");  // crnor
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 50: | 
					
						
							|  |  |  |       nooper(in, "rfi", PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 129: | 
					
						
							|  |  |  |       crop(in, "andc", nullptr);  // crandc
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 150: | 
					
						
							|  |  |  |       nooper(in, "isync", 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 193: | 
					
						
							|  |  |  |       crop(in, "xor", "clr");  // crxor
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 225: | 
					
						
							|  |  |  |       crop(in, "nand", nullptr);  // crnand
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 257: | 
					
						
							|  |  |  |       crop(in, "and", nullptr);  // crand
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 289: | 
					
						
							|  |  |  |       crop(in, "eqv", "set");  // creqv
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 417: | 
					
						
							|  |  |  |       crop(in, "orc", nullptr);  // crorc
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 449: | 
					
						
							|  |  |  |       crop(in, "or", "move");  // cror
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 528: | 
					
						
							|  |  |  |       branch(in, "ctr", 0, 0);  // bcctr
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       ill(in); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 20: | 
					
						
							|  |  |  |     rlw(in, "imi", 0);  // rlwimi
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 21: | 
					
						
							|  |  |  |     rlw(in, "inm", 0);  // rlwinm
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 23: | 
					
						
							|  |  |  |     rlw(in, "nm", 1);  // rlwnm
 | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 24: | 
					
						
							|  |  |  |     if (in & ~PPCIDXMASK) | 
					
						
							|  |  |  |       ori(in, "ori"); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       m_opcode = "nop"; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 25: | 
					
						
							|  |  |  |     ori(in, "oris"); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 26: | 
					
						
							|  |  |  |     ori(in, "xori"); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 27: | 
					
						
							|  |  |  |     ori(in, "xoris"); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 28: | 
					
						
							|  |  |  |     ori(in, "andi."); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 29: | 
					
						
							|  |  |  |     ori(in, "andis."); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 30: | 
					
						
							|  |  |  |     switch (in & 0x1c) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |       rld(in, "icl", 0);  // rldicl
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 1: | 
					
						
							|  |  |  |       rld(in, "icr", 0);  // rldicr
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 2: | 
					
						
							|  |  |  |       rld(in, "ic", 0);  // rldic
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 3: | 
					
						
							|  |  |  |       rld(in, "imi", 0);  // rldimi
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 4: | 
					
						
							|  |  |  |       rld(in, in & 2 ? "cl" : "cr", 1);  // rldcl, rldcr
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       ill(in); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 31: | 
					
						
							|  |  |  |     switch (PPCGETIDX2(in)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |     case 32: | 
					
						
							|  |  |  |       if (in & 1) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         cmp(in);  // cmp, cmpl
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 4: | 
					
						
							|  |  |  |       if (in & 1) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         trap(in, 0);  // tw
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 8: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 8: | 
					
						
							|  |  |  |       dab(swapab(in), "subc", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 9: | 
					
						
							|  |  |  |       dab(in, "mulhdu", 7, 0, 0, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 10: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 10: | 
					
						
							|  |  |  |       dab(in, "addc", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 11: | 
					
						
							|  |  |  |       dab(in, "mulhwu", 7, 0, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 19: | 
					
						
							|  |  |  |       if (in & (PPCAMASK | PPCBMASK)) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "mfcr", 4, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 20: | 
					
						
							|  |  |  |       dab(in, "lwarx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 21: | 
					
						
							|  |  |  |       dab(in, "ldx", 7, 0, 0, 0, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 23: | 
					
						
							|  |  |  |       dab(in, "lwzx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 24: | 
					
						
							|  |  |  |       dab(in, "slw", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 26: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "cntlzw", 6, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 27: | 
					
						
							|  |  |  |       dab(in, "sld", 7, 1, 0, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 28: | 
					
						
							|  |  |  |       dab(in, "and", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 40: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 40: | 
					
						
							|  |  |  |       dab(swapab(in), "sub", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 53: | 
					
						
							|  |  |  |       dab(in, "ldux", 7, 0, 0, 0, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 54: | 
					
						
							|  |  |  |       if (in & PPCDMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "dcbst", 3, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 55: | 
					
						
							|  |  |  |       dab(in, "lwzux", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 58: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "cntlzd", 6, 1, 0, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 60: | 
					
						
							|  |  |  |       dab(in, "andc", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 68: | 
					
						
							|  |  |  |       trap(in, PPCF_64);  // td
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 73: | 
					
						
							|  |  |  |       dab(in, "mulhd", 7, 0, 0, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 75: | 
					
						
							|  |  |  |       dab(in, "mulhw", 7, 0, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 83: | 
					
						
							|  |  |  |       if (in & (PPCAMASK | PPCBMASK)) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "mfmsr", 4, 0, 0, 0, PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 84: | 
					
						
							|  |  |  |       dab(in, "ldarx", 7, 0, 0, 0, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 86: | 
					
						
							|  |  |  |       if (in & PPCDMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "dcbf", 3, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 87: | 
					
						
							|  |  |  |       dab(in, "lbzx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 104: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 104: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "neg", 6, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 119: | 
					
						
							|  |  |  |       dab(in, "lbzux", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 124: | 
					
						
							|  |  |  |       if (PPCGETD(in) == PPCGETB(in)) | 
					
						
							|  |  |  |         dab(in, "not", 6, 1, 0, -1, 0); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "nor", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 136: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 136: | 
					
						
							|  |  |  |       dab(in, "subfe", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 138: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 138: | 
					
						
							|  |  |  |       dab(in, "adde", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 144: | 
					
						
							|  |  |  |       mtcr(in); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 146: | 
					
						
							|  |  |  |       if (in & (PPCAMASK | PPCBMASK)) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "mtmsr", 4, 0, 0, 0, PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 149: | 
					
						
							|  |  |  |       dab(in, "stdx", 7, 0, 0, 0, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 150: | 
					
						
							|  |  |  |       dab(in, "stwcx.", 7, 0, 0, 1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 151: | 
					
						
							|  |  |  |       dab(in, "stwx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 181: | 
					
						
							|  |  |  |       dab(in, "stdux", 7, 0, 0, 0, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 183: | 
					
						
							|  |  |  |       dab(in, "stwux", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 200: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 200: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "subfze", 6, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 202: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 202: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "addze", 6, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 210: | 
					
						
							|  |  |  |       msr(in, 1);  // mfsr
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 214: | 
					
						
							|  |  |  |       dab(in, "stdcx.", 7, 0, 0, 1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 215: | 
					
						
							|  |  |  |       dab(in, "stbx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 232: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 232: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "subfme", 6, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 233: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 233: | 
					
						
							|  |  |  |       dab(in, "mulld", 7, 0, 1, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 234: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 234: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "addme", 6, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 235: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 235: | 
					
						
							|  |  |  |       dab(in, "mullw", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 242: | 
					
						
							|  |  |  |       if (in & PPCAMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "mtsrin", 5, 0, 0, 0, PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 246: | 
					
						
							|  |  |  |       if (in & PPCDMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "dcbtst", 3, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 247: | 
					
						
							|  |  |  |       dab(in, "stbux", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 266: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 266: | 
					
						
							|  |  |  |       dab(in, "add", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 278: | 
					
						
							|  |  |  |       if (in & PPCDMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "dcbt", 3, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 279: | 
					
						
							|  |  |  |       dab(in, "lhzx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 284: | 
					
						
							|  |  |  |       dab(in, "eqv", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 306: | 
					
						
							|  |  |  |       if (in & (PPCDMASK | PPCAMASK)) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "tlbie", 1, 0, 0, 0, PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 310: | 
					
						
							|  |  |  |       dab(in, "eciwx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 311: | 
					
						
							|  |  |  |       dab(in, "lhzux", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 316: | 
					
						
							|  |  |  |       dab(in, "xor", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 339: | 
					
						
							|  |  |  |       mspr(in, 0);  // mfspr
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 341: | 
					
						
							|  |  |  |       dab(in, "lwax", 7, 0, 0, 0, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 343: | 
					
						
							|  |  |  |       dab(in, "lhax", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 370: | 
					
						
							|  |  |  |       nooper(in, "tlbia", PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 371: | 
					
						
							|  |  |  |       mtb(in);  // mftb
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 373: | 
					
						
							|  |  |  |       dab(in, "lwaux", 7, 0, 0, 0, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 375: | 
					
						
							|  |  |  |       dab(in, "lhaux", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 407: | 
					
						
							|  |  |  |       dab(in, "sthx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 412: | 
					
						
							|  |  |  |       dab(in, "orc", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 413: | 
					
						
							|  |  |  |       sradi(in);  // sradi
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 434: | 
					
						
							|  |  |  |       if (in & (PPCDMASK | PPCAMASK)) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "slbie", 1, 0, 0, 0, PPCF_SUPER | PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 438: | 
					
						
							|  |  |  |       dab(in, "ecowx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 439: | 
					
						
							|  |  |  |       dab(in, "sthux", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 444: | 
					
						
							|  |  |  |       if (PPCGETD(in) == PPCGETB(in)) | 
					
						
							|  |  |  |         dab(in, "mr", 6, 1, 0, -1, 0); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "or", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 457: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 457: | 
					
						
							|  |  |  |       dab(in, "divdu", 7, 0, 1, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 459: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 459: | 
					
						
							|  |  |  |       dab(in, "divwu", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 467: | 
					
						
							|  |  |  |       mspr(in, 1);  // mtspr
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 470: | 
					
						
							|  |  |  |       if (in & PPCDMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "dcbi", 3, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 476: | 
					
						
							|  |  |  |       dab(in, "nand", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 489: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 489: | 
					
						
							|  |  |  |       dab(in, "divd", 7, 0, 1, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 491: | 
					
						
							|  |  |  |     case (PPCOE >> 1) + 491: | 
					
						
							|  |  |  |       dab(in, "divw", 7, 0, 1, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 498: | 
					
						
							|  |  |  |       nooper(in, "slbia", PPCF_SUPER | PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 512: | 
					
						
							|  |  |  |       if (in & 0x007ff801) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         m_opcode = "mcrxr"; | 
					
						
							|  |  |  |         m_operands = StringFromFormat("cr%d", (int)PPCGETCRD(in)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 533: | 
					
						
							|  |  |  |       dab(in, "lswx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 534: | 
					
						
							|  |  |  |       dab(in, "lwbrx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 535: | 
					
						
							|  |  |  |       fdab(in, "lfsx", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 536: | 
					
						
							|  |  |  |       dab(in, "srw", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 539: | 
					
						
							|  |  |  |       dab(in, "srd", 7, 1, 0, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 566: | 
					
						
							|  |  |  |       nooper(in, "tlbsync", PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 567: | 
					
						
							|  |  |  |       fdab(in, "lfsux", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 595: | 
					
						
							|  |  |  |       msr(in, 0);  // mfsr
 | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 597: | 
					
						
							|  |  |  |       rrn(in, "lswi", 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 598: | 
					
						
							|  |  |  |       nooper(in, "sync", PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 599: | 
					
						
							|  |  |  |       fdab(in, "lfdx", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 631: | 
					
						
							|  |  |  |       fdab(in, "lfdux", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 659: | 
					
						
							|  |  |  |       if (in & PPCAMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "mfsrin", 5, 0, 0, 0, PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 661: | 
					
						
							|  |  |  |       dab(in, "stswx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 662: | 
					
						
							|  |  |  |       dab(in, "stwbrx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 663: | 
					
						
							|  |  |  |       fdab(in, "stfsx", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 695: | 
					
						
							|  |  |  |       fdab(in, "stfsux", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 725: | 
					
						
							|  |  |  |       rrn(in, "stswi", 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 727: | 
					
						
							|  |  |  |       fdab(in, "stfdx", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 759: | 
					
						
							|  |  |  |       fdab(in, "stfdux", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 790: | 
					
						
							|  |  |  |       dab(in, "lhbrx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 792: | 
					
						
							|  |  |  |       dab(in, "sraw", 7, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 794: | 
					
						
							|  |  |  |       dab(in, "srad", 7, 1, 0, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 824: | 
					
						
							|  |  |  |       rrn(in, "srawi", 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 854: | 
					
						
							|  |  |  |       nooper(in, "eieio", PPCF_SUPER); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 918: | 
					
						
							|  |  |  |       dab(in, "sthbrx", 7, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 922: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "extsh", 6, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 954: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "extsb", 6, 1, 0, -1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 982: | 
					
						
							|  |  |  |       if (in & PPCDMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "icbi", 3, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 983: | 
					
						
							|  |  |  |       fdab(in, "stfiwx", 7); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 986: | 
					
						
							|  |  |  |       if (in & PPCBMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "extsw", 6, 1, 0, -1, PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 1014: | 
					
						
							|  |  |  |       if (in & PPCDMASK) | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         dab(in, "dcbz", 3, 0, 0, 0, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       ill(in); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 32: | 
					
						
							|  |  |  |   case 33: | 
					
						
							|  |  |  |   case 34: | 
					
						
							|  |  |  |   case 35: | 
					
						
							|  |  |  |   case 36: | 
					
						
							|  |  |  |   case 37: | 
					
						
							|  |  |  |   case 38: | 
					
						
							|  |  |  |   case 39: | 
					
						
							|  |  |  |   case 40: | 
					
						
							|  |  |  |   case 41: | 
					
						
							|  |  |  |   case 42: | 
					
						
							|  |  |  |   case 43: | 
					
						
							|  |  |  |   case 44: | 
					
						
							|  |  |  |   case 45: | 
					
						
							|  |  |  |   case 46: | 
					
						
							|  |  |  |   case 47: | 
					
						
							|  |  |  |     ldst(in, ldstnames[PPCGETIDX(in) - 32], 'r', 0); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 48: | 
					
						
							|  |  |  |   case 49: | 
					
						
							|  |  |  |   case 50: | 
					
						
							|  |  |  |   case 51: | 
					
						
							|  |  |  |   case 52: | 
					
						
							|  |  |  |   case 53: | 
					
						
							|  |  |  |   case 54: | 
					
						
							|  |  |  |   case 55: | 
					
						
							|  |  |  |     ldst(in, ldstnames[PPCGETIDX(in) - 32], 'f', 0); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 58: | 
					
						
							|  |  |  |     switch (in & 3) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |       ldst(in & ~3, "ld", 'r', PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 1: | 
					
						
							|  |  |  |       ldst(in & ~3, "ldu", 'r', PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 2: | 
					
						
							|  |  |  |       ldst(in & ~3, "lwa", 'r', PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       ill(in); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 59: | 
					
						
							|  |  |  |     switch (in & 0x3e) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case 36: | 
					
						
							|  |  |  |       fdabc(in, "divs", 5, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 40: | 
					
						
							|  |  |  |       fdabc(in, "subs", 5, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 42: | 
					
						
							|  |  |  |       fdabc(in, "adds", 5, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 44: | 
					
						
							|  |  |  |       fdabc(in, "sqrts", 1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 48: | 
					
						
							|  |  |  |       fdabc(in, "res", 1, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 50: | 
					
						
							|  |  |  |       fdabc(in, "muls", 6, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 56: | 
					
						
							|  |  |  |       fdabc(in, "msubs", 7, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 58: | 
					
						
							|  |  |  |       fdabc(in, "madds", 7, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 60: | 
					
						
							|  |  |  |       fdabc(in, "nmsubs", 7, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 62: | 
					
						
							|  |  |  |       fdabc(in, "nmadds", 7, 0); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       ill(in); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 62: | 
					
						
							|  |  |  |     switch (in & 3) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |       ldst(in & ~3, "std", 'r', PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     case 1: | 
					
						
							|  |  |  |       ldst(in & ~3, "stdu", 'r', PPCF_64); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       ill(in); | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   case 63: | 
					
						
							|  |  |  |     if (in & 32) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       switch (in & 0x1e) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |       case 4: | 
					
						
							|  |  |  |         fdabc(in, "div", 5, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 8: | 
					
						
							|  |  |  |         fdabc(in, "sub", 5, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 10: | 
					
						
							|  |  |  |         fdabc(in, "add", 5, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 12: | 
					
						
							|  |  |  |         fdabc(in, "sqrt", 1, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 14: | 
					
						
							|  |  |  |         fdabc(in, "sel", 7, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 18: | 
					
						
							|  |  |  |         fdabc(in, "mul", 6, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 20: | 
					
						
							|  |  |  |         fdabc(in, "rsqrte", 1, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 24: | 
					
						
							|  |  |  |         fdabc(in, "msub", 7, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 26: | 
					
						
							|  |  |  |         fdabc(in, "madd", 7, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 28: | 
					
						
							|  |  |  |         fdabc(in, "nmsub", 7, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 30: | 
					
						
							|  |  |  |         fdabc(in, "nmadd", 7, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       switch (PPCGETIDX2(in)) | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |       case 0: | 
					
						
							|  |  |  |         fcmp(in, 'u'); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 12: | 
					
						
							|  |  |  |         fdabc(in, "rsp", 1, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 14: | 
					
						
							|  |  |  |         fdabc(in, "ctiw", 1, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 15: | 
					
						
							|  |  |  |         fdabc(in, "ctiwz", 1, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 32: | 
					
						
							|  |  |  |         fcmp(in, 'o'); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 38: | 
					
						
							|  |  |  |         mtfsb(in, 1); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 40: | 
					
						
							|  |  |  |         fdabc(in, "neg", 10, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 64: | 
					
						
							|  |  |  |         mcrf(in, 's');  // mcrfs
 | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 70: | 
					
						
							|  |  |  |         mtfsb(in, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 72: | 
					
						
							|  |  |  |         fmr(in); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 134: | 
					
						
							|  |  |  |         if ((in & 0x006f0800) == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           m_opcode = StringFromFormat("mtfsfi%s", rcsel[in & 1]); | 
					
						
							|  |  |  |           m_operands = StringFromFormat("cr%d,%d", (int)PPCGETCRD(in), (int)(in & 0xf000) >> 12); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           ill(in); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 136: | 
					
						
							|  |  |  |         fdabc(in, "nabs", 10, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 264: | 
					
						
							|  |  |  |         fdabc(in, "abs", 10, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 583: | 
					
						
							|  |  |  |         if (in & (PPCAMASK | PPCBMASK)) | 
					
						
							|  |  |  |           ill(in); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           dab(in, "mffs", 4, 0, 0, -1, 0); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 711: | 
					
						
							|  |  |  |         if ((in & 0x02010000) == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           m_opcode = StringFromFormat("mtfsf%s", rcsel[in & 1]); | 
					
						
							|  |  |  |           m_operands = StringFromFormat("0x%x,%u", (unsigned int)(in >> 17) & 0x01fe, | 
					
						
							|  |  |  |                                         (unsigned int)PPCGETB(in)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           ill(in); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 814: | 
					
						
							|  |  |  |         fdabc(in, "fctid", 10, PPCF_64); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 815: | 
					
						
							|  |  |  |         fdabc(in, "fctidz", 10, PPCF_64); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       case 846: | 
					
						
							|  |  |  |         fdabc(in, "fcfid", 10, PPCF_64); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       default: | 
					
						
							|  |  |  |         ill(in); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |     ill(in); | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return (m_instr + 1); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // simplified interface
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | std::string GekkoDisassembler::Disassemble(u32 opcode, u32 current_instruction_address, | 
					
						
							|  |  |  |                                            bool big_endian) | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   u32 opc = opcode; | 
					
						
							|  |  |  |   u32 addr = current_instruction_address; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   m_instr = (u32*)&opc; | 
					
						
							|  |  |  |   m_iaddr = (u32*)&addr; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   DoDisassembly(big_endian); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return m_opcode.append("\t").append(m_operands); | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 16:45:49 -04:00
										 |  |  | static const char* gprnames[] = { | 
					
						
							|  |  |  |     " r0", " r1 (sp)", " r2 (rtoc)", " r3", " r4", " r5", " r6", " r7", " r8", " r9", "r10", | 
					
						
							|  |  |  |     "r11", "r12",      "r13",        "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", | 
					
						
							|  |  |  |     "r22", "r23",      "r24",        "r25", "r26", "r27", "r28", "r29", "r30", "r31"}; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | const char* GekkoDisassembler::GetGPRName(u32 index) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (index < 32) | 
					
						
							|  |  |  |     return gprnames[index]; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return nullptr; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  | static const char* fprnames[] = {" f0", " f1", " f2", " f3", " f4", " f5", " f6", " f7", | 
					
						
							|  |  |  |                                  " f8", " f9", "f10", "f11", "f12", "f13", "f14", "f15", | 
					
						
							|  |  |  |                                  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", | 
					
						
							|  |  |  |                                  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"}; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | const char* GekkoDisassembler::GetFPRName(u32 index) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   if (index < 32) | 
					
						
							|  |  |  |     return fprnames[index]; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-24 10:43:46 +02:00
										 |  |  |   return nullptr; | 
					
						
							| 
									
										
										
										
											2014-07-17 21:33:51 -04:00
										 |  |  | } |