mirror of
				https://github.com/dolphin-emu/dolphin.git
				synced 2025-10-27 10:29:07 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1493 lines
		
	
	
	
		
			87 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			1493 lines
		
	
	
	
		
			87 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright 2023 Dolphin Emulator Project
 | |
| // SPDX-License-Identifier: GPL-2.0-or-later
 | |
| 
 | |
| #include "Common/Assembler/AssemblerTables.h"
 | |
| 
 | |
| #include "Common/Assembler/AssemblerShared.h"
 | |
| #include "Common/Assembler/CaseInsensitiveDict.h"
 | |
| #include "Common/CommonTypes.h"
 | |
| 
 | |
| namespace Common::GekkoAssembler::detail
 | |
| {
 | |
| namespace
 | |
| {
 | |
| constexpr size_t PLAIN_MNEMONIC = 0x0;
 | |
| constexpr size_t RECORD_BIT = 0x1;
 | |
| constexpr size_t OVERFLOW_EXCEPTION = 0x2;
 | |
| // Since RC/OE are mutually exclusive from LK/AA, they can occupy the same slot
 | |
| constexpr size_t LINK_BIT = 0x1;
 | |
| constexpr size_t ABSOLUTE_ADDRESS_BIT = 0x2;
 | |
| 
 | |
| // Compile-time helpers for mnemonic generation
 | |
| // Generate inclusive mask [left, right] -- MSB=0 LSB=31
 | |
| constexpr u32 Mask(u32 left, u32 right)
 | |
| {
 | |
|   return static_cast<u32>(((u64{1} << (32 - left)) - 1) & ~((u64{1} << (31 - right)) - 1));
 | |
| }
 | |
| constexpr u32 InsertVal(u32 val, u32 left, u32 right)
 | |
| {
 | |
|   return val << (31 - right) & Mask(left, right);
 | |
| }
 | |
| constexpr u32 InsertOpcode(u32 opcode)
 | |
| {
 | |
|   return InsertVal(opcode, 0, 5);
 | |
| }
 | |
| constexpr u32 SprBitswap(u32 spr)
 | |
| {
 | |
|   return ((spr & 0b0000011111) << 5) | ((spr & 0b1111100000) >> 5);
 | |
| }
 | |
| 
 | |
| constexpr MnemonicDesc INVALID_MNEMONIC = {0, 0, {}};
 | |
| constexpr ExtendedMnemonicDesc INVALID_EXT_MNEMONIC = {0, nullptr};
 | |
| 
 | |
| // All operands as referenced by the Gekko/Broadway user manual
 | |
| // See section 12.1.2 under Chapter 12
 | |
| constexpr OperandDesc OpDesc_A = OperandDesc{Mask(11, 15), {16, false}};
 | |
| constexpr OperandDesc OpDesc_B = OperandDesc{Mask(16, 20), {11, false}};
 | |
| constexpr OperandDesc OpDesc_BD = OperandDesc{Mask(16, 29), {0, true}};
 | |
| constexpr OperandDesc OpDesc_BI = OperandDesc{Mask(11, 15), {16, false}};
 | |
| constexpr OperandDesc OpDesc_BO = OperandDesc{Mask(6, 10), {21, false}};
 | |
| constexpr OperandDesc OpDesc_C = OperandDesc{Mask(21, 25), {6, false}};
 | |
| constexpr OperandDesc OpDesc_Crba = OperandDesc{Mask(11, 15), {16, false}};
 | |
| constexpr OperandDesc OpDesc_Crbb = OperandDesc{Mask(16, 20), {11, false}};
 | |
| constexpr OperandDesc OpDesc_Crbd = OperandDesc{Mask(6, 10), {21, false}};
 | |
| constexpr OperandDesc OpDesc_Crfd = OperandDesc{Mask(6, 8), {23, false}};
 | |
| constexpr OperandDesc OpDesc_Crfs = OperandDesc{Mask(11, 13), {18, false}};
 | |
| constexpr OperandDesc OpDesc_CRM = OperandDesc{Mask(12, 19), {12, false}};
 | |
| constexpr OperandDesc OpDesc_D = OperandDesc{Mask(6, 10), {21, false}};
 | |
| constexpr OperandDesc OpDesc_FM = OperandDesc{Mask(7, 14), {17, false}};
 | |
| constexpr OperandDesc OpDesc_W1 = OperandDesc{Mask(16, 16), {15, false}};
 | |
| constexpr OperandDesc OpDesc_W2 = OperandDesc{Mask(21, 21), {10, false}};
 | |
| constexpr OperandDesc OpDesc_IMM = OperandDesc{Mask(16, 19), {12, false}};
 | |
| constexpr OperandDesc OpDesc_L = OperandDesc{Mask(10, 10), {21, false}};
 | |
| constexpr OperandDesc OpDesc_LI = OperandDesc{Mask(6, 29), {0, true}};
 | |
| constexpr OperandDesc OpDesc_MB = OperandDesc{Mask(21, 25), {6, false}};
 | |
| constexpr OperandDesc OpDesc_ME = OperandDesc{Mask(26, 30), {1, false}};
 | |
| constexpr OperandDesc OpDesc_NB = OperandDesc{Mask(16, 20), {11, false}};
 | |
| constexpr OperandDesc OpDesc_Offd = OperandDesc{Mask(16, 31), {0, true}};
 | |
| constexpr OperandDesc OpDesc_OffdPs = OperandDesc{Mask(20, 31), {0, true}};
 | |
| constexpr OperandDesc OpDesc_S = OperandDesc{Mask(6, 10), {21, false}};
 | |
| constexpr OperandDesc OpDesc_SH = OperandDesc{Mask(16, 20), {11, false}};
 | |
| constexpr OperandDesc OpDesc_SIMM = OperandDesc{Mask(16, 31), {0, true}};
 | |
| constexpr OperandDesc OpDesc_SPR = OperandDesc{Mask(11, 20), {11, false}};
 | |
| constexpr OperandDesc OpDesc_SR = OperandDesc{Mask(12, 15), {16, false}};
 | |
| constexpr OperandDesc OpDesc_TO = OperandDesc{Mask(6, 10), {21, false}};
 | |
| constexpr OperandDesc OpDesc_TPR = OperandDesc{Mask(11, 20), {11, false}};
 | |
| constexpr OperandDesc OpDesc_UIMM = OperandDesc{Mask(16, 31), {0, false}};
 | |
| constexpr OperandDesc OpDesc_I1 = OperandDesc{Mask(17, 19), {12, false}};
 | |
| constexpr OperandDesc OpDesc_I2 = OperandDesc{Mask(22, 24), {7, false}};
 | |
| }  // namespace
 | |
| 
 | |
| void OperandList::Insert(size_t before, u32 val)
 | |
| {
 | |
|   overfill = count == MAX_OPERANDS;
 | |
|   for (size_t i = before + 1; i <= count && i < MAX_OPERANDS; i++)
 | |
|   {
 | |
|     std::swap(list[i], list[before]);
 | |
|   }
 | |
| 
 | |
|   list[before] = Tagged<Interval, u32>({0, 0}, val);
 | |
|   if (!overfill)
 | |
|   {
 | |
|     count++;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // OperandDesc holds the shift position for an operand, as well as the mask
 | |
| // Whether the user provided a valid input for an operand can be determined by the mask
 | |
| u32 OperandDesc::MaxVal() const
 | |
| {
 | |
|   const u32 mask_sh = mask >> shift;
 | |
|   if (is_signed)
 | |
|   {
 | |
|     const u32 mask_hibit = (mask_sh & (mask_sh ^ (mask_sh >> 1)));
 | |
|     return mask_hibit - 1;
 | |
|   }
 | |
|   return mask_sh;
 | |
| }
 | |
| 
 | |
| u32 OperandDesc::MinVal() const
 | |
| {
 | |
|   if (is_signed)
 | |
|   {
 | |
|     return ~MaxVal();
 | |
|   }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| u32 OperandDesc::TruncBits() const
 | |
| {
 | |
|   const u32 mask_sh = mask >> shift;
 | |
|   const u32 mask_lobit = mask_sh & (mask_sh ^ (mask_sh << 1));
 | |
|   return mask_lobit - 1;
 | |
| }
 | |
| 
 | |
| bool OperandDesc::Fits(u32 val) const
 | |
| {
 | |
|   const u32 mask_sh = mask >> shift;
 | |
|   if (is_signed)
 | |
|   {
 | |
|     // Get high bit and low bit from a range mask
 | |
|     const u32 mask_hibit = mask_sh & (mask_sh ^ (mask_sh >> 1));
 | |
|     const u32 mask_lobit = mask_sh & (mask_sh ^ (mask_sh << 1));
 | |
|     // Positive max is (signbit - 1)
 | |
|     // Negative min is ~(Positive Max)
 | |
|     const u32 positive_max = mask_hibit - 1;
 | |
|     const u32 negative_max = ~positive_max;
 | |
|     // Truncated bits are any bits right of the mask that are 0 after shifting
 | |
|     const u32 truncate_bits = mask_lobit - 1;
 | |
|     return (val <= positive_max || val >= negative_max) && !(val & truncate_bits);
 | |
|   }
 | |
|   return (mask_sh & val) == val;
 | |
| }
 | |
| 
 | |
| u32 OperandDesc::Fit(u32 val) const
 | |
| {
 | |
|   return (val << shift) & mask;
 | |
| }
 | |
| 
 | |
| ///////////////////
 | |
| // PARSER TABLES //
 | |
| ///////////////////
 | |
| 
 | |
| extern const CaseInsensitiveDict<u32, '_'> sprg_map = {
 | |
|     {"xer", 1},      {"lr", 8},       {"ctr", 9},      {"dsisr", 18},   {"dar", 19},
 | |
|     {"dec", 22},     {"sdr1", 25},    {"srr0", 26},    {"srr1", 27},    {"sprg0", 272},
 | |
|     {"sprg1", 273},  {"sprg2", 274},  {"sprg3", 275},  {"ear", 282},    {"tbl", 284},
 | |
|     {"tbu", 285},    {"ibat0u", 528}, {"ibat0l", 529}, {"ibat1u", 530}, {"ibat1l", 531},
 | |
|     {"ibat2u", 532}, {"ibat2l", 533}, {"ibat3u", 534}, {"ibat3l", 535}, {"dbat0u", 536},
 | |
|     {"dbat0l", 537}, {"dbat1u", 538}, {"dbat1l", 539}, {"dbat2u", 540}, {"dbat2l", 541},
 | |
|     {"dbat3u", 542}, {"dbat3l", 543}, {"gqr0", 912},   {"gqr1", 913},   {"gqr2", 914},
 | |
|     {"gqr3", 915},   {"gqr4", 916},   {"gqr5", 917},   {"gqr6", 918},   {"gqr7", 919},
 | |
|     {"hid2", 920},   {"wpar", 921},   {"dma_u", 922},  {"dma_l", 923},  {"ummcr0", 936},
 | |
|     {"upmc1", 937},  {"upmc2", 938},  {"usia", 939},   {"ummcr1", 940}, {"upmc3", 941},
 | |
|     {"upmc4", 942},  {"usda", 943},   {"mmcr0", 952},  {"pmc1", 953},   {"pmc2", 954},
 | |
|     {"sia", 955},    {"mmcr1", 956},  {"pmc3", 957},   {"pmc4", 958},   {"sda", 959},
 | |
|     {"hid0", 1008},  {"hid1", 1009},  {"iabr", 1010},  {"dabr", 1013},  {"l2cr", 1017},
 | |
|     {"ictc", 1019},  {"thrm1", 1020}, {"thrm2", 1021}, {"thrm3", 1022}};
 | |
| 
 | |
| extern const CaseInsensitiveDict<GekkoDirective> directives_map = {
 | |
|     {"byte", GekkoDirective::Byte},     {"2byte", GekkoDirective::_2byte},
 | |
|     {"4byte", GekkoDirective::_4byte},  {"8byte", GekkoDirective::_8byte},
 | |
|     {"float", GekkoDirective::Float},   {"double", GekkoDirective::Double},
 | |
|     {"locate", GekkoDirective::Locate}, {"padalign", GekkoDirective::PadAlign},
 | |
|     {"align", GekkoDirective::Align},   {"zeros", GekkoDirective::Zeros},
 | |
|     {"skip", GekkoDirective::Skip},     {"defvar", GekkoDirective::DefVar},
 | |
|     {"ascii", GekkoDirective::Ascii},   {"asciz", GekkoDirective::Asciz},
 | |
| };
 | |
| 
 | |
| #define MNEMONIC(mnemonic_str, mnemonic_enum, variant_bits, alg)                                   \
 | |
|   {                                                                                                \
 | |
|     mnemonic_str,                                                                                  \
 | |
|     {                                                                                              \
 | |
|       static_cast<size_t>(mnemonic_enum) * VARIANT_PERMUTATIONS + (variant_bits), alg              \
 | |
|     }                                                                                              \
 | |
|   }
 | |
| #define PLAIN_MNEMONIC(mnemonic_str, mnemonic_enum, alg)                                           \
 | |
|   MNEMONIC(mnemonic_str, mnemonic_enum, PLAIN_MNEMONIC, alg)
 | |
| #define RC_MNEMONIC(mnemonic_str, mnemonic_enum, alg)                                              \
 | |
|   MNEMONIC(mnemonic_str, mnemonic_enum, PLAIN_MNEMONIC, alg),                                      \
 | |
|       MNEMONIC(mnemonic_str ".", mnemonic_enum, RECORD_BIT, alg)
 | |
| #define OERC_MNEMONIC(mnemonic_str, mnemonic_enum, alg)                                            \
 | |
|   MNEMONIC(mnemonic_str, mnemonic_enum, PLAIN_MNEMONIC, alg),                                      \
 | |
|       MNEMONIC(mnemonic_str ".", mnemonic_enum, RECORD_BIT, alg),                                  \
 | |
|       MNEMONIC(mnemonic_str "o", mnemonic_enum, OVERFLOW_EXCEPTION, alg),                          \
 | |
|       MNEMONIC(mnemonic_str "o.", mnemonic_enum, (RECORD_BIT | OVERFLOW_EXCEPTION), alg)
 | |
| #define LK_MNEMONIC(mnemonic_str, mnemonic_enum, alg)                                              \
 | |
|   MNEMONIC(mnemonic_str, mnemonic_enum, PLAIN_MNEMONIC, alg),                                      \
 | |
|       MNEMONIC(mnemonic_str "l", mnemonic_enum, LINK_BIT, alg)
 | |
| #define AALK_MNEMONIC(mnemonic_str, mnemonic_enum, alg)                                            \
 | |
|   MNEMONIC(mnemonic_str, mnemonic_enum, PLAIN_MNEMONIC, alg),                                      \
 | |
|       MNEMONIC(mnemonic_str "l", mnemonic_enum, LINK_BIT, alg),                                    \
 | |
|       MNEMONIC(mnemonic_str "a", mnemonic_enum, ABSOLUTE_ADDRESS_BIT, alg),                        \
 | |
|       MNEMONIC(mnemonic_str "la", mnemonic_enum, (LINK_BIT | ABSOLUTE_ADDRESS_BIT), alg)
 | |
| 
 | |
| extern const CaseInsensitiveDict<ParseInfo, '.', '_'> mnemonic_tokens = {
 | |
|     OERC_MNEMONIC("add", GekkoMnemonic::Add, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("addc", GekkoMnemonic::Addc, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("adde", GekkoMnemonic::Adde, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("addi", GekkoMnemonic::Addi, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("addic", GekkoMnemonic::Addic, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("addic.", GekkoMnemonic::AddicDot, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("addis", GekkoMnemonic::Addis, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("addme", GekkoMnemonic::Addme, ParseAlg::Op2),
 | |
|     OERC_MNEMONIC("addze", GekkoMnemonic::Addze, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("and", GekkoMnemonic::And, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("andc", GekkoMnemonic::Andc, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("andi.", GekkoMnemonic::AndiDot, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("andis.", GekkoMnemonic::AndisDot, ParseAlg::Op3),
 | |
|     AALK_MNEMONIC("b", GekkoMnemonic::B, ParseAlg::Op1),
 | |
|     AALK_MNEMONIC("bc", GekkoMnemonic::Bc, ParseAlg::Op3),
 | |
|     LK_MNEMONIC("bcctr", GekkoMnemonic::Bcctr, ParseAlg::Op2),
 | |
|     LK_MNEMONIC("bclr", GekkoMnemonic::Bclr, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("cmp", GekkoMnemonic::Cmp, ParseAlg::Op4),
 | |
|     PLAIN_MNEMONIC("cmpi", GekkoMnemonic::Cmpi, ParseAlg::Op4),
 | |
|     PLAIN_MNEMONIC("cmpl", GekkoMnemonic::Cmpl, ParseAlg::Op4),
 | |
|     PLAIN_MNEMONIC("cmpli", GekkoMnemonic::Cmpli, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("cntlzw", GekkoMnemonic::Cntlzw, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("crand", GekkoMnemonic::Crand, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("crandc", GekkoMnemonic::Crandc, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("creqv", GekkoMnemonic::Creqv, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("crnand", GekkoMnemonic::Crnand, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("crnor", GekkoMnemonic::Crnor, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("cror", GekkoMnemonic::Cror, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("crorc", GekkoMnemonic::Crorc, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("crxor", GekkoMnemonic::Crxor, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("dcbf", GekkoMnemonic::Dcbf, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("dcbi", GekkoMnemonic::Dcbi, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("dcbst", GekkoMnemonic::Dcbst, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("dcbt", GekkoMnemonic::Dcbt, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("dcbtst", GekkoMnemonic::Dcbtst, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("dcbz", GekkoMnemonic::Dcbz, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("dcbz_l", GekkoMnemonic::Dcbz_l, ParseAlg::Op2),
 | |
|     OERC_MNEMONIC("divw", GekkoMnemonic::Divw, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("divwu", GekkoMnemonic::Divwu, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("eciwx", GekkoMnemonic::Eciwx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("ecowx", GekkoMnemonic::Ecowx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("eieio", GekkoMnemonic::Eieio, ParseAlg::None),
 | |
|     RC_MNEMONIC("eqv", GekkoMnemonic::Eqv, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("extsb", GekkoMnemonic::Extsb, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("extsh", GekkoMnemonic::Extsh, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("fabs", GekkoMnemonic::Fabs, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("fadd", GekkoMnemonic::Fadd, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("fadds", GekkoMnemonic::Fadds, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("fcmpo", GekkoMnemonic::Fcmpo, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("fcmpu", GekkoMnemonic::Fcmpu, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("fctiw", GekkoMnemonic::Fctiw, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("fctiwz", GekkoMnemonic::Fctiwz, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("fdiv", GekkoMnemonic::Fdiv, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("fdivs", GekkoMnemonic::Fdivs, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("fmadd", GekkoMnemonic::Fmadd, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fmadds", GekkoMnemonic::Fmadds, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fmr", GekkoMnemonic::Fmr, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("fmsub", GekkoMnemonic::Fmsub, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fmsubs", GekkoMnemonic::Fmsubs, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fmul", GekkoMnemonic::Fmul, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("fmuls", GekkoMnemonic::Fmuls, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("fnabs", GekkoMnemonic::Fnabs, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("fneg", GekkoMnemonic::Fneg, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("fnmadd", GekkoMnemonic::Fnmadd, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fnmadds", GekkoMnemonic::Fnmadds, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fnmsub", GekkoMnemonic::Fnmsub, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fnmsubs", GekkoMnemonic::Fnmsubs, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fres", GekkoMnemonic::Fres, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("frsp", GekkoMnemonic::Frsp, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("frsqrte", GekkoMnemonic::Frsqrte, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("fsel", GekkoMnemonic::Fsel, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("fsub", GekkoMnemonic::Fsub, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("fsubs", GekkoMnemonic::Fsubs, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("icbi", GekkoMnemonic::Icbi, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("isync", GekkoMnemonic::Isync, ParseAlg::None),
 | |
|     PLAIN_MNEMONIC("lbz", GekkoMnemonic::Lbz, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lbzu", GekkoMnemonic::Lbzu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lbzux", GekkoMnemonic::Lbzux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lbzx", GekkoMnemonic::Lbzx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lfd", GekkoMnemonic::Lfd, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lfdu", GekkoMnemonic::Lfdu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lfdux", GekkoMnemonic::Lfdux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lfdx", GekkoMnemonic::Lfdx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lfs", GekkoMnemonic::Lfs, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lfsu", GekkoMnemonic::Lfsu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lfsux", GekkoMnemonic::Lfsux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lfsx", GekkoMnemonic::Lfsx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lha", GekkoMnemonic::Lha, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lhau", GekkoMnemonic::Lhau, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lhaux", GekkoMnemonic::Lhaux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lhax", GekkoMnemonic::Lhax, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lhbrx", GekkoMnemonic::Lhbrx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lhz", GekkoMnemonic::Lhz, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lhzu", GekkoMnemonic::Lhzu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lhzux", GekkoMnemonic::Lhzux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lhzx", GekkoMnemonic::Lhzx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lmw", GekkoMnemonic::Lmw, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lswi", GekkoMnemonic::Lswi, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lswx", GekkoMnemonic::Lswx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lwarx", GekkoMnemonic::Lwarx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lwbrx", GekkoMnemonic::Lwbrx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lwz", GekkoMnemonic::Lwz, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lwzu", GekkoMnemonic::Lwzu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("lwzux", GekkoMnemonic::Lwzux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("lwzx", GekkoMnemonic::Lwzx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("mcrf", GekkoMnemonic::Mcrf, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mcrfs", GekkoMnemonic::Mcrfs, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mcrxr", GekkoMnemonic::Mcrxr, ParseAlg::Op1),
 | |
|     PLAIN_MNEMONIC("mfcr", GekkoMnemonic::Mfcr, ParseAlg::Op1),
 | |
|     RC_MNEMONIC("mffs", GekkoMnemonic::Mffs, ParseAlg::Op1),
 | |
|     PLAIN_MNEMONIC("mfmsr", GekkoMnemonic::Mfmsr, ParseAlg::Op1),
 | |
|     PLAIN_MNEMONIC("mfspr_nobitswap", GekkoMnemonic::Mfspr_nobitswap, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mfsr", GekkoMnemonic::Mfsr, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mfsrin", GekkoMnemonic::Mfsrin, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mftb_nobitswap", GekkoMnemonic::Mftb_nobitswap, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mtcrf", GekkoMnemonic::Mtcrf, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("mtfsb0", GekkoMnemonic::Mtfsb0, ParseAlg::Op1),
 | |
|     RC_MNEMONIC("mtfsb1", GekkoMnemonic::Mtfsb1, ParseAlg::Op1),
 | |
|     RC_MNEMONIC("mtfsf", GekkoMnemonic::Mtfsf, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("mtfsfi", GekkoMnemonic::Mtfsfi, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mtmsr", GekkoMnemonic::Mtmsr, ParseAlg::Op1),
 | |
|     PLAIN_MNEMONIC("mtspr_nobitswap", GekkoMnemonic::Mtspr_nobitswap, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mtsr", GekkoMnemonic::Mtsr, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("mtsrin", GekkoMnemonic::Mtsrin, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("mulhw", GekkoMnemonic::Mulhw, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("mulhwu", GekkoMnemonic::Mulhwu, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("mulli", GekkoMnemonic::Mulli, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("mullw", GekkoMnemonic::Mullw, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("nand", GekkoMnemonic::Nand, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("neg", GekkoMnemonic::Neg, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("nor", GekkoMnemonic::Nor, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("or", GekkoMnemonic::Or, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("orc", GekkoMnemonic::Orc, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("ori", GekkoMnemonic::Ori, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("oris", GekkoMnemonic::Oris, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("psq_l", GekkoMnemonic::Psq_l, ParseAlg::Op1Off1Op2),
 | |
|     PLAIN_MNEMONIC("psq_lu", GekkoMnemonic::Psq_lu, ParseAlg::Op1Off1Op2),
 | |
|     PLAIN_MNEMONIC("psq_lux", GekkoMnemonic::Psq_lux, ParseAlg::Op5),
 | |
|     PLAIN_MNEMONIC("psq_lx", GekkoMnemonic::Psq_lx, ParseAlg::Op5),
 | |
|     PLAIN_MNEMONIC("psq_st", GekkoMnemonic::Psq_st, ParseAlg::Op1Off1Op2),
 | |
|     PLAIN_MNEMONIC("psq_stu", GekkoMnemonic::Psq_stu, ParseAlg::Op1Off1Op2),
 | |
|     PLAIN_MNEMONIC("psq_stux", GekkoMnemonic::Psq_stux, ParseAlg::Op5),
 | |
|     PLAIN_MNEMONIC("psq_stx", GekkoMnemonic::Psq_stx, ParseAlg::Op5),
 | |
|     RC_MNEMONIC("ps_abs", GekkoMnemonic::Ps_abs, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("ps_add", GekkoMnemonic::Ps_add, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("ps_cmpo0", GekkoMnemonic::Ps_cmpo0, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("ps_cmpo1", GekkoMnemonic::Ps_cmpo1, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("ps_cmpu0", GekkoMnemonic::Ps_cmpu0, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("ps_cmpu1", GekkoMnemonic::Ps_cmpu1, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_div", GekkoMnemonic::Ps_div, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_madd", GekkoMnemonic::Ps_madd, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("ps_madds0", GekkoMnemonic::Ps_madds0, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("ps_madds1", GekkoMnemonic::Ps_madds1, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("ps_merge00", GekkoMnemonic::Ps_merge00, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_merge01", GekkoMnemonic::Ps_merge01, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_merge10", GekkoMnemonic::Ps_merge10, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_merge11", GekkoMnemonic::Ps_merge11, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_mr", GekkoMnemonic::Ps_mr, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("ps_msub", GekkoMnemonic::Ps_msub, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("ps_mul", GekkoMnemonic::Ps_mul, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_muls0", GekkoMnemonic::Ps_muls0, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_muls1", GekkoMnemonic::Ps_muls1, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_nabs", GekkoMnemonic::Ps_nabs, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("ps_neg", GekkoMnemonic::Ps_neg, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("ps_nmadd", GekkoMnemonic::Ps_nmadd, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("ps_nmsub", GekkoMnemonic::Ps_nmsub, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("ps_res", GekkoMnemonic::Ps_res, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("ps_rsqrte", GekkoMnemonic::Ps_rsqrte, ParseAlg::Op2),
 | |
|     RC_MNEMONIC("ps_sel", GekkoMnemonic::Ps_sel, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("ps_sub", GekkoMnemonic::Ps_sub, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("ps_sum0", GekkoMnemonic::Ps_sum0, ParseAlg::Op4),
 | |
|     RC_MNEMONIC("ps_sum1", GekkoMnemonic::Ps_sum1, ParseAlg::Op4),
 | |
|     PLAIN_MNEMONIC("rfi", GekkoMnemonic::Rfi, ParseAlg::None),
 | |
|     RC_MNEMONIC("rlwimi", GekkoMnemonic::Rlwimi, ParseAlg::Op5),
 | |
|     RC_MNEMONIC("rlwinm", GekkoMnemonic::Rlwinm, ParseAlg::Op5),
 | |
|     RC_MNEMONIC("rlwnm", GekkoMnemonic::Rlwnm, ParseAlg::Op5),
 | |
|     PLAIN_MNEMONIC("sc", GekkoMnemonic::Sc, ParseAlg::None),
 | |
|     RC_MNEMONIC("slw", GekkoMnemonic::Slw, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("sraw", GekkoMnemonic::Sraw, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("srawi", GekkoMnemonic::Srawi, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("srw", GekkoMnemonic::Srw, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stb", GekkoMnemonic::Stb, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stbu", GekkoMnemonic::Stbu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stbux", GekkoMnemonic::Stbux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stbx", GekkoMnemonic::Stbx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stfd", GekkoMnemonic::Stfd, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stfdu", GekkoMnemonic::Stfdu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stfdux", GekkoMnemonic::Stfdux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stfdx", GekkoMnemonic::Stfdx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stfiwx", GekkoMnemonic::Stfiwx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stfs", GekkoMnemonic::Stfs, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stfsu", GekkoMnemonic::Stfsu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stfsux", GekkoMnemonic::Stfsux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stfsx", GekkoMnemonic::Stfsx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("sth", GekkoMnemonic::Sth, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("sthbrx", GekkoMnemonic::Sthbrx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("sthu", GekkoMnemonic::Sthu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("sthux", GekkoMnemonic::Sthux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("sthx", GekkoMnemonic::Sthx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stmw", GekkoMnemonic::Stmw, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stswi", GekkoMnemonic::Stswi, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stswx", GekkoMnemonic::Stswx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stw", GekkoMnemonic::Stw, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stwbrx", GekkoMnemonic::Stwbrx, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stwcx.", GekkoMnemonic::StwcxDot, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stwu", GekkoMnemonic::Stwu, ParseAlg::Op1Off1),
 | |
|     PLAIN_MNEMONIC("stwux", GekkoMnemonic::Stwux, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("stwx", GekkoMnemonic::Stwx, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("subf", GekkoMnemonic::Subf, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("subfc", GekkoMnemonic::Subfc, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("subfe", GekkoMnemonic::Subfe, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("subfic", GekkoMnemonic::Subfic, ParseAlg::Op3),
 | |
|     OERC_MNEMONIC("subfme", GekkoMnemonic::Subfme, ParseAlg::Op2),
 | |
|     OERC_MNEMONIC("subfze", GekkoMnemonic::Subfze, ParseAlg::Op2),
 | |
|     PLAIN_MNEMONIC("sync", GekkoMnemonic::Sync, ParseAlg::None),
 | |
|     PLAIN_MNEMONIC("tlbie", GekkoMnemonic::Tlbie, ParseAlg::Op1),
 | |
|     PLAIN_MNEMONIC("tlbsync", GekkoMnemonic::Tlbsync, ParseAlg::None),
 | |
|     PLAIN_MNEMONIC("tw", GekkoMnemonic::Tw, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("twi", GekkoMnemonic::Twi, ParseAlg::Op3),
 | |
|     RC_MNEMONIC("xor", GekkoMnemonic::Xor, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("xori", GekkoMnemonic::Xori, ParseAlg::Op3),
 | |
|     PLAIN_MNEMONIC("xoris", GekkoMnemonic::Xoris, ParseAlg::Op3),
 | |
| };
 | |
| 
 | |
| #define PSEUDO(mnemonic, base, variant_bits, alg)                                                  \
 | |
|   {                                                                                                \
 | |
|     mnemonic,                                                                                      \
 | |
|     {                                                                                              \
 | |
|       static_cast<size_t>(base) * VARIANT_PERMUTATIONS + (variant_bits), alg                       \
 | |
|     }                                                                                              \
 | |
|   }
 | |
| #define PLAIN_PSEUDO(mnemonic, base, alg) PSEUDO(mnemonic, base, PLAIN_MNEMONIC, alg)
 | |
| #define RC_PSEUDO(mnemonic, base, alg)                                                             \
 | |
|   PSEUDO(mnemonic, base, PLAIN_MNEMONIC, alg), PSEUDO(mnemonic ".", base, RECORD_BIT, alg)
 | |
| #define OERC_PSEUDO(mnemonic, base, alg)                                                           \
 | |
|   PSEUDO(mnemonic, base, PLAIN_MNEMONIC, alg), PSEUDO(mnemonic ".", base, RECORD_BIT, alg),        \
 | |
|       PSEUDO(mnemonic "o", base, OVERFLOW_EXCEPTION, alg),                                         \
 | |
|       PSEUDO(mnemonic "o.", base, (RECORD_BIT | OVERFLOW_EXCEPTION), alg)
 | |
| #define LK_PSEUDO(mnemonic, base, alg)                                                             \
 | |
|   PSEUDO(mnemonic, base, PLAIN_MNEMONIC, alg), PSEUDO(mnemonic "l", base, LINK_BIT, alg)
 | |
| #define LKAA_PSEUDO(mnemonic, base, alg)                                                           \
 | |
|   PSEUDO(mnemonic, base, PLAIN_MNEMONIC, alg), PSEUDO(mnemonic "l", base, LINK_BIT, alg),          \
 | |
|       PSEUDO(mnemonic "a", base, ABSOLUTE_ADDRESS_BIT, alg),                                       \
 | |
|       PSEUDO(mnemonic "la", base, (LINK_BIT | ABSOLUTE_ADDRESS_BIT), alg)
 | |
| #define LKPRED_PSEUDO(mnemonic, base, alg)                                                         \
 | |
|   PSEUDO(mnemonic, base, PLAIN_MNEMONIC, alg), PSEUDO(mnemonic "l", base, LINK_BIT, alg),          \
 | |
|       PSEUDO(mnemonic "-", base, PLAIN_MNEMONIC, alg), PSEUDO(mnemonic "l-", base, LINK_BIT, alg), \
 | |
|       PSEUDO(mnemonic "+", base##Predict, PLAIN_MNEMONIC, alg),                                    \
 | |
|       PSEUDO(mnemonic "l+", base##Predict, LINK_BIT, alg)
 | |
| #define LKAAPRED_PSEUDO(mnemonic, base, alg)                                                       \
 | |
|   PSEUDO(mnemonic, base, PLAIN_MNEMONIC, alg), PSEUDO(mnemonic "l", base, LINK_BIT, alg),          \
 | |
|       PSEUDO(mnemonic "a", base, ABSOLUTE_ADDRESS_BIT, alg),                                       \
 | |
|       PSEUDO(mnemonic "la", base, (LINK_BIT | ABSOLUTE_ADDRESS_BIT), alg),                         \
 | |
|       PSEUDO(mnemonic "-", base, PLAIN_MNEMONIC, alg), PSEUDO(mnemonic "l-", base, LINK_BIT, alg), \
 | |
|       PSEUDO(mnemonic "a-", base, ABSOLUTE_ADDRESS_BIT, alg),                                      \
 | |
|       PSEUDO(mnemonic "la-", base, (LINK_BIT | ABSOLUTE_ADDRESS_BIT), alg),                        \
 | |
|       PSEUDO(mnemonic "+", base##Predict, PLAIN_MNEMONIC, alg),                                    \
 | |
|       PSEUDO(mnemonic "l+", base##Predict, LINK_BIT, alg),                                         \
 | |
|       PSEUDO(mnemonic "a+", base##Predict, ABSOLUTE_ADDRESS_BIT, alg),                             \
 | |
|       PSEUDO(mnemonic "la+", base##Predict, (LINK_BIT | ABSOLUTE_ADDRESS_BIT), alg)
 | |
| 
 | |
| extern const CaseInsensitiveDict<ParseInfo, '.', '_', '+', '-'> extended_mnemonic_tokens = {
 | |
|     PLAIN_PSEUDO("subi", ExtendedGekkoMnemonic::Subi, ParseAlg::Op3),
 | |
|     PLAIN_PSEUDO("subis", ExtendedGekkoMnemonic::Subis, ParseAlg::Op3),
 | |
|     PLAIN_PSEUDO("subic", ExtendedGekkoMnemonic::Subic, ParseAlg::Op3),
 | |
|     PLAIN_PSEUDO("subic.", ExtendedGekkoMnemonic::SubicDot, ParseAlg::Op3),
 | |
|     OERC_PSEUDO("sub", ExtendedGekkoMnemonic::Sub, ParseAlg::Op3),
 | |
|     OERC_PSEUDO("subc", ExtendedGekkoMnemonic::Subc, ParseAlg::Op3),
 | |
|     PLAIN_PSEUDO("cmpwi", ExtendedGekkoMnemonic::Cmpwi, ParseAlg::Op2Or3),
 | |
|     PLAIN_PSEUDO("cmpw", ExtendedGekkoMnemonic::Cmpw, ParseAlg::Op2Or3),
 | |
|     PLAIN_PSEUDO("cmplwi", ExtendedGekkoMnemonic::Cmplwi, ParseAlg::Op2Or3),
 | |
|     PLAIN_PSEUDO("cmplw", ExtendedGekkoMnemonic::Cmplw, ParseAlg::Op2Or3),
 | |
|     RC_PSEUDO("extlwi", ExtendedGekkoMnemonic::Extlwi, ParseAlg::Op4),
 | |
|     RC_PSEUDO("extrwi", ExtendedGekkoMnemonic::Extrwi, ParseAlg::Op4),
 | |
|     RC_PSEUDO("inslwi", ExtendedGekkoMnemonic::Inslwi, ParseAlg::Op4),
 | |
|     RC_PSEUDO("insrwi", ExtendedGekkoMnemonic::Insrwi, ParseAlg::Op4),
 | |
|     RC_PSEUDO("rotlwi", ExtendedGekkoMnemonic::Rotlwi, ParseAlg::Op3),
 | |
|     RC_PSEUDO("rotrwi", ExtendedGekkoMnemonic::Rotrwi, ParseAlg::Op3),
 | |
|     RC_PSEUDO("rotlw", ExtendedGekkoMnemonic::Rotlw, ParseAlg::Op3),
 | |
|     RC_PSEUDO("slwi", ExtendedGekkoMnemonic::Slwi, ParseAlg::Op3),
 | |
|     RC_PSEUDO("srwi", ExtendedGekkoMnemonic::Srwi, ParseAlg::Op3),
 | |
|     RC_PSEUDO("clrlwi", ExtendedGekkoMnemonic::Clrlwi, ParseAlg::Op3),
 | |
|     RC_PSEUDO("clrrwi", ExtendedGekkoMnemonic::Clrrwi, ParseAlg::Op3),
 | |
|     RC_PSEUDO("clrlslwi", ExtendedGekkoMnemonic::Clrlslwi, ParseAlg::Op4),
 | |
|     LKAAPRED_PSEUDO("bt", ExtendedGekkoMnemonic::Bt, ParseAlg::Op2),
 | |
|     LKAAPRED_PSEUDO("bf", ExtendedGekkoMnemonic::Bf, ParseAlg::Op2),
 | |
|     LKAAPRED_PSEUDO("bdnz", ExtendedGekkoMnemonic::Bdnz, ParseAlg::Op1),
 | |
|     LKAAPRED_PSEUDO("bdnzt", ExtendedGekkoMnemonic::Bdnzt, ParseAlg::Op2),
 | |
|     LKAAPRED_PSEUDO("bdnzf", ExtendedGekkoMnemonic::Bdnzf, ParseAlg::Op2),
 | |
|     LKAAPRED_PSEUDO("bdz", ExtendedGekkoMnemonic::Bdz, ParseAlg::Op1),
 | |
|     LKAAPRED_PSEUDO("bdzt", ExtendedGekkoMnemonic::Bdzt, ParseAlg::Op2),
 | |
|     LKAAPRED_PSEUDO("bdzf", ExtendedGekkoMnemonic::Bdzf, ParseAlg::Op2),
 | |
|     LK_PSEUDO("blr", ExtendedGekkoMnemonic::Blr, ParseAlg::None),
 | |
|     LK_PSEUDO("bctr", ExtendedGekkoMnemonic::Bctr, ParseAlg::None),
 | |
|     LKPRED_PSEUDO("btlr", ExtendedGekkoMnemonic::Btlr, ParseAlg::Op1),
 | |
|     LKPRED_PSEUDO("btctr", ExtendedGekkoMnemonic::Btctr, ParseAlg::Op1),
 | |
|     LKPRED_PSEUDO("bflr", ExtendedGekkoMnemonic::Bflr, ParseAlg::Op1),
 | |
|     LKPRED_PSEUDO("bfctr", ExtendedGekkoMnemonic::Bfctr, ParseAlg::Op1),
 | |
|     LKPRED_PSEUDO("bdnzlr", ExtendedGekkoMnemonic::Bdnzlr, ParseAlg::None),
 | |
|     LKPRED_PSEUDO("bdnztlr", ExtendedGekkoMnemonic::Bdnztlr, ParseAlg::Op1),
 | |
|     LKPRED_PSEUDO("bdnzflr", ExtendedGekkoMnemonic::Bdnzflr, ParseAlg::Op1),
 | |
|     LKPRED_PSEUDO("bdzlr", ExtendedGekkoMnemonic::Bdzlr, ParseAlg::None),
 | |
|     LKPRED_PSEUDO("bdztlr", ExtendedGekkoMnemonic::Bdztlr, ParseAlg::Op1),
 | |
|     LKPRED_PSEUDO("bdzflr", ExtendedGekkoMnemonic::Bdzflr, ParseAlg::Op1),
 | |
|     LKAAPRED_PSEUDO("blt", ExtendedGekkoMnemonic::Blt, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("ble", ExtendedGekkoMnemonic::Ble, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("beq", ExtendedGekkoMnemonic::Beq, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bge", ExtendedGekkoMnemonic::Bge, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bgt", ExtendedGekkoMnemonic::Bgt, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bnl", ExtendedGekkoMnemonic::Bnl, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bne", ExtendedGekkoMnemonic::Bne, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bng", ExtendedGekkoMnemonic::Bng, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bso", ExtendedGekkoMnemonic::Bso, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bns", ExtendedGekkoMnemonic::Bns, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bun", ExtendedGekkoMnemonic::Bun, ParseAlg::Op1Or2),
 | |
|     LKAAPRED_PSEUDO("bnu", ExtendedGekkoMnemonic::Bnu, ParseAlg::Op1Or2),
 | |
|     LKPRED_PSEUDO("bltlr", ExtendedGekkoMnemonic::Bltlr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bltctr", ExtendedGekkoMnemonic::Bltctr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("blelr", ExtendedGekkoMnemonic::Blelr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("blectr", ExtendedGekkoMnemonic::Blectr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("beqlr", ExtendedGekkoMnemonic::Beqlr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("beqctr", ExtendedGekkoMnemonic::Beqctr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bgelr", ExtendedGekkoMnemonic::Bgelr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bgectr", ExtendedGekkoMnemonic::Bgectr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bgtlr", ExtendedGekkoMnemonic::Bgtlr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bgtctr", ExtendedGekkoMnemonic::Bgtctr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnllr", ExtendedGekkoMnemonic::Bnllr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnlctr", ExtendedGekkoMnemonic::Bnlctr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnelr", ExtendedGekkoMnemonic::Bnelr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnectr", ExtendedGekkoMnemonic::Bnectr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnglr", ExtendedGekkoMnemonic::Bnglr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bngctr", ExtendedGekkoMnemonic::Bngctr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bsolr", ExtendedGekkoMnemonic::Bsolr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bsoctr", ExtendedGekkoMnemonic::Bsoctr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnslr", ExtendedGekkoMnemonic::Bnslr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnsctr", ExtendedGekkoMnemonic::Bnsctr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bunlr", ExtendedGekkoMnemonic::Bunlr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bunctr", ExtendedGekkoMnemonic::Bunctr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnulr", ExtendedGekkoMnemonic::Bnulr, ParseAlg::NoneOrOp1),
 | |
|     LKPRED_PSEUDO("bnuctr", ExtendedGekkoMnemonic::Bnuctr, ParseAlg::NoneOrOp1),
 | |
|     PLAIN_PSEUDO("crset", ExtendedGekkoMnemonic::Crset, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("crclr", ExtendedGekkoMnemonic::Crclr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("crmove", ExtendedGekkoMnemonic::Crmove, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("crnot", ExtendedGekkoMnemonic::Crnot, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlt", ExtendedGekkoMnemonic::Twlt, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlti", ExtendedGekkoMnemonic::Twlti, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twle", ExtendedGekkoMnemonic::Twle, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlei", ExtendedGekkoMnemonic::Twlei, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("tweq", ExtendedGekkoMnemonic::Tweq, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("tweqi", ExtendedGekkoMnemonic::Tweqi, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twge", ExtendedGekkoMnemonic::Twge, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twgei", ExtendedGekkoMnemonic::Twgei, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twgt", ExtendedGekkoMnemonic::Twgt, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twgti", ExtendedGekkoMnemonic::Twgti, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twnl", ExtendedGekkoMnemonic::Twnl, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twnli", ExtendedGekkoMnemonic::Twnli, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twne", ExtendedGekkoMnemonic::Twne, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twnei", ExtendedGekkoMnemonic::Twnei, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twng", ExtendedGekkoMnemonic::Twng, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twngi", ExtendedGekkoMnemonic::Twngi, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twllt", ExtendedGekkoMnemonic::Twllt, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twllti", ExtendedGekkoMnemonic::Twllti, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlle", ExtendedGekkoMnemonic::Twlle, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twllei", ExtendedGekkoMnemonic::Twllei, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlge", ExtendedGekkoMnemonic::Twlge, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlgei", ExtendedGekkoMnemonic::Twlgei, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlgt", ExtendedGekkoMnemonic::Twlgt, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlgti", ExtendedGekkoMnemonic::Twlgti, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlnl", ExtendedGekkoMnemonic::Twlnl, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlnli", ExtendedGekkoMnemonic::Twlnli, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlng", ExtendedGekkoMnemonic::Twlng, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("twlngi", ExtendedGekkoMnemonic::Twlngi, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("trap", ExtendedGekkoMnemonic::Trap, ParseAlg::None),
 | |
|     PLAIN_PSEUDO("mtxer", ExtendedGekkoMnemonic::Mtxer, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfxer", ExtendedGekkoMnemonic::Mfxer, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtlr", ExtendedGekkoMnemonic::Mtlr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mflr", ExtendedGekkoMnemonic::Mflr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtctr", ExtendedGekkoMnemonic::Mtctr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfctr", ExtendedGekkoMnemonic::Mfctr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtdsisr", ExtendedGekkoMnemonic::Mtdsisr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfdsisr", ExtendedGekkoMnemonic::Mfdsisr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtdar", ExtendedGekkoMnemonic::Mtdar, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfdar", ExtendedGekkoMnemonic::Mfdar, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtdec", ExtendedGekkoMnemonic::Mtdec, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfdec", ExtendedGekkoMnemonic::Mfdec, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtsdr1", ExtendedGekkoMnemonic::Mtsdr1, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfsdr1", ExtendedGekkoMnemonic::Mfsdr1, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtsrr0", ExtendedGekkoMnemonic::Mtsrr0, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfsrr0", ExtendedGekkoMnemonic::Mfsrr0, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtsrr1", ExtendedGekkoMnemonic::Mtsrr1, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfsrr1", ExtendedGekkoMnemonic::Mfsrr1, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtasr", ExtendedGekkoMnemonic::Mtasr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfasr", ExtendedGekkoMnemonic::Mfasr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtear", ExtendedGekkoMnemonic::Mtear, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfear", ExtendedGekkoMnemonic::Mfear, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mttbl", ExtendedGekkoMnemonic::Mttbl, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mftbl", ExtendedGekkoMnemonic::Mftbl, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mttbu", ExtendedGekkoMnemonic::Mttbu, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mftbu", ExtendedGekkoMnemonic::Mftbu, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mtsprg", ExtendedGekkoMnemonic::Mtsprg, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mfsprg", ExtendedGekkoMnemonic::Mfsprg, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mtibatu", ExtendedGekkoMnemonic::Mtibatu, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mfibatu", ExtendedGekkoMnemonic::Mfibatu, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mtibatl", ExtendedGekkoMnemonic::Mtibatl, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mfibatl", ExtendedGekkoMnemonic::Mfibatl, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mtdbatu", ExtendedGekkoMnemonic::Mtdbatu, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mfdbatu", ExtendedGekkoMnemonic::Mfdbatu, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mtdbatl", ExtendedGekkoMnemonic::Mtdbatl, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mfdbatl", ExtendedGekkoMnemonic::Mfdbatl, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("nop", ExtendedGekkoMnemonic::Nop, ParseAlg::None),
 | |
|     PLAIN_PSEUDO("li", ExtendedGekkoMnemonic::Li, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("lis", ExtendedGekkoMnemonic::Lis, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("la", ExtendedGekkoMnemonic::La, ParseAlg::Op1Off1),
 | |
|     RC_PSEUDO("mr", ExtendedGekkoMnemonic::Mr, ParseAlg::Op2),
 | |
|     RC_PSEUDO("not", ExtendedGekkoMnemonic::Not, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mtcr", ExtendedGekkoMnemonic::Mtcr, ParseAlg::Op1),
 | |
|     PLAIN_PSEUDO("mfspr", ExtendedGekkoMnemonic::Mfspr, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mftb", ExtendedGekkoMnemonic::Mftb, ParseAlg::Op2),
 | |
|     PLAIN_PSEUDO("mtspr", ExtendedGekkoMnemonic::Mtspr, ParseAlg::Op2),
 | |
| };
 | |
| 
 | |
| #undef MNEMONIC
 | |
| #undef PLAIN_MNEMONIC
 | |
| #undef RC_MNEMONIC
 | |
| #undef OERC_MNEMONIC
 | |
| #undef LK_MNEMONIC
 | |
| #undef AALK_MNEMONIC
 | |
| #undef PSEUDO
 | |
| #undef PLAIN_PSEUDO
 | |
| #undef RC_PSEUDO
 | |
| #undef OERC_PSEUDO
 | |
| #undef LK_PSEUDO
 | |
| #undef LKAA_PSEUDO
 | |
| #undef LKPRED_PSEUDO
 | |
| #undef LKAAPRED_PSEUDO
 | |
| 
 | |
| //////////////////////
 | |
| // ASSEMBLER TABLES //
 | |
| //////////////////////
 | |
| #define EMIT_MNEMONIC_ENTRY(opcode_val, extra_bits, ...)                                           \
 | |
|   MnemonicDesc                                                                                     \
 | |
|   {                                                                                                \
 | |
|     InsertOpcode(opcode_val) | (extra_bits),                                                       \
 | |
|         static_cast<u32>(std::initializer_list<OperandDesc>{__VA_ARGS__}.size()),                  \
 | |
|     {                                                                                              \
 | |
|       __VA_ARGS__                                                                                  \
 | |
|     }                                                                                              \
 | |
|   }
 | |
| #define MNEMONIC(opcode_val, extra_bits, ...)                                                      \
 | |
|   EMIT_MNEMONIC_ENTRY(opcode_val, extra_bits, __VA_ARGS__), INVALID_MNEMONIC, INVALID_MNEMONIC,    \
 | |
|       INVALID_MNEMONIC
 | |
| #define BASIC_MNEMONIC(opcode_val, ...) MNEMONIC(opcode_val, 0, __VA_ARGS__)
 | |
| #define RC_MNEMONIC(opcode_val, extra_bits, ...)                                                   \
 | |
|   EMIT_MNEMONIC_ENTRY(opcode_val, extra_bits, __VA_ARGS__),                                        \
 | |
|       EMIT_MNEMONIC_ENTRY(opcode_val, ((extra_bits) | InsertVal(1, 31, 31)), __VA_ARGS__),         \
 | |
|       INVALID_MNEMONIC, INVALID_MNEMONIC
 | |
| #define OERC_MNEMONIC(opcode_val, extra_bits, ...)                                                 \
 | |
|   EMIT_MNEMONIC_ENTRY(opcode_val, extra_bits, __VA_ARGS__),                                        \
 | |
|       EMIT_MNEMONIC_ENTRY(opcode_val, ((extra_bits) | InsertVal(1, 31, 31)), __VA_ARGS__),         \
 | |
|       EMIT_MNEMONIC_ENTRY(opcode_val, ((extra_bits) | InsertVal(1, 21, 21)), __VA_ARGS__),         \
 | |
|       EMIT_MNEMONIC_ENTRY(                                                                         \
 | |
|           opcode_val, ((extra_bits) | InsertVal(1, 31, 31) | InsertVal(1, 21, 21)), __VA_ARGS__)
 | |
| #define LK_MNEMONIC(opcode_val, extra_bits, ...)                                                   \
 | |
|   EMIT_MNEMONIC_ENTRY(opcode_val, extra_bits, __VA_ARGS__),                                        \
 | |
|       EMIT_MNEMONIC_ENTRY(opcode_val, ((extra_bits) | InsertVal(1, 31, 31)), __VA_ARGS__),         \
 | |
|       INVALID_MNEMONIC, INVALID_MNEMONIC
 | |
| #define AALK_MNEMONIC(opcode_val, extra_bits, ...)                                                 \
 | |
|   EMIT_MNEMONIC_ENTRY(opcode_val, extra_bits, __VA_ARGS__),                                        \
 | |
|       EMIT_MNEMONIC_ENTRY(opcode_val, ((extra_bits) | InsertVal(0b01, 30, 31)), __VA_ARGS__),      \
 | |
|       EMIT_MNEMONIC_ENTRY(opcode_val, ((extra_bits) | InsertVal(0b10, 30, 31)), __VA_ARGS__),      \
 | |
|       EMIT_MNEMONIC_ENTRY(opcode_val, ((extra_bits) | InsertVal(0b11, 30, 31)), __VA_ARGS__)
 | |
| 
 | |
| // Defines all basic mnemonics that Broadway/Gekko supports
 | |
| extern const std::array<MnemonicDesc, NUM_MNEMONICS * VARIANT_PERMUTATIONS> mnemonics = {
 | |
|     // A-2
 | |
|     OERC_MNEMONIC(31, InsertVal(266, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // add
 | |
|     OERC_MNEMONIC(31, InsertVal(10, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),   // addc
 | |
|     OERC_MNEMONIC(31, InsertVal(138, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // adde
 | |
|     BASIC_MNEMONIC(14, OpDesc_D, OpDesc_A, OpDesc_SIMM),                      // addi
 | |
|     BASIC_MNEMONIC(12, OpDesc_D, OpDesc_A, OpDesc_SIMM),                      // addic
 | |
|     BASIC_MNEMONIC(13, OpDesc_D, OpDesc_A, OpDesc_SIMM),                      // addic.
 | |
|     BASIC_MNEMONIC(15, OpDesc_D, OpDesc_A, OpDesc_SIMM),                      // addis
 | |
|     OERC_MNEMONIC(31, InsertVal(234, 22, 30), OpDesc_D, OpDesc_A),            // addme
 | |
|     OERC_MNEMONIC(31, InsertVal(202, 22, 30), OpDesc_D, OpDesc_A),            // addze
 | |
|     OERC_MNEMONIC(31, InsertVal(491, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // divw
 | |
|     OERC_MNEMONIC(31, InsertVal(459, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // divwu
 | |
|     RC_MNEMONIC(31, InsertVal(75, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),     // mulhw
 | |
|     RC_MNEMONIC(31, InsertVal(11, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),     // mulhwu
 | |
|     BASIC_MNEMONIC(7, OpDesc_D, OpDesc_A, OpDesc_SIMM),                       // mulli
 | |
|     OERC_MNEMONIC(31, InsertVal(235, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // mullw
 | |
|     OERC_MNEMONIC(31, InsertVal(104, 22, 30), OpDesc_D, OpDesc_A),            // neg
 | |
|     OERC_MNEMONIC(31, InsertVal(40, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),   // subf
 | |
|     OERC_MNEMONIC(31, InsertVal(8, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),    // subfc
 | |
|     OERC_MNEMONIC(31, InsertVal(136, 22, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // subfe
 | |
|     BASIC_MNEMONIC(8, OpDesc_D, OpDesc_A, OpDesc_SIMM),                       // subfic
 | |
|     OERC_MNEMONIC(31, InsertVal(232, 22, 30), OpDesc_D, OpDesc_A),            // subfme
 | |
|     OERC_MNEMONIC(31, InsertVal(200, 22, 30), OpDesc_D, OpDesc_A),            // subfze
 | |
| 
 | |
|     // A-3
 | |
|     MNEMONIC(31, InsertVal(0, 21, 30), OpDesc_Crfd, OpDesc_L, OpDesc_A, OpDesc_B),   // cmp
 | |
|     BASIC_MNEMONIC(11, OpDesc_Crfd, OpDesc_L, OpDesc_A, OpDesc_SIMM),                // cmpi
 | |
|     MNEMONIC(31, InsertVal(32, 21, 30), OpDesc_Crfd, OpDesc_L, OpDesc_A, OpDesc_B),  // cmpl
 | |
|     BASIC_MNEMONIC(10, OpDesc_Crfd, OpDesc_L, OpDesc_A, OpDesc_UIMM),                // cmpli
 | |
| 
 | |
|     // A-4
 | |
|     RC_MNEMONIC(31, InsertVal(28, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),   // and
 | |
|     RC_MNEMONIC(31, InsertVal(60, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),   // andc
 | |
|     BASIC_MNEMONIC(28, OpDesc_A, OpDesc_S, OpDesc_UIMM),                    // andi.
 | |
|     BASIC_MNEMONIC(29, OpDesc_A, OpDesc_S, OpDesc_UIMM),                    // andis.
 | |
|     RC_MNEMONIC(31, InsertVal(26, 21, 30), OpDesc_A, OpDesc_S),             // cntlzw
 | |
|     RC_MNEMONIC(31, InsertVal(284, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),  // eqv
 | |
|     RC_MNEMONIC(31, InsertVal(954, 21, 30), OpDesc_A, OpDesc_S),            // extsb
 | |
|     RC_MNEMONIC(31, InsertVal(922, 21, 30), OpDesc_A, OpDesc_S),            // extsh
 | |
|     RC_MNEMONIC(31, InsertVal(476, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),  // nand
 | |
|     RC_MNEMONIC(31, InsertVal(124, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),  // nor
 | |
|     RC_MNEMONIC(31, InsertVal(444, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),  // or
 | |
|     RC_MNEMONIC(31, InsertVal(412, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),  // orc
 | |
|     BASIC_MNEMONIC(24, OpDesc_A, OpDesc_S, OpDesc_UIMM),                    // ori
 | |
|     BASIC_MNEMONIC(25, OpDesc_A, OpDesc_S, OpDesc_UIMM),                    // oris
 | |
|     RC_MNEMONIC(31, InsertVal(316, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),  // xor
 | |
|     BASIC_MNEMONIC(26, OpDesc_A, OpDesc_S, OpDesc_UIMM),                    // xori
 | |
|     BASIC_MNEMONIC(27, OpDesc_A, OpDesc_S, OpDesc_UIMM),                    // xoris
 | |
| 
 | |
|     // A-5
 | |
|     RC_MNEMONIC(20, 0, OpDesc_A, OpDesc_S, OpDesc_SH, OpDesc_MB, OpDesc_ME),  // rlwimi
 | |
|     RC_MNEMONIC(21, 0, OpDesc_A, OpDesc_S, OpDesc_SH, OpDesc_MB, OpDesc_ME),  // rlwinm
 | |
|     RC_MNEMONIC(23, 0, OpDesc_A, OpDesc_S, OpDesc_B, OpDesc_MB, OpDesc_ME),   // rlwnm
 | |
| 
 | |
|     // A-6
 | |
|     RC_MNEMONIC(31, InsertVal(24, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),    // slw
 | |
|     RC_MNEMONIC(31, InsertVal(792, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),   // sraw
 | |
|     RC_MNEMONIC(31, InsertVal(824, 21, 30), OpDesc_A, OpDesc_S, OpDesc_SH),  // srawi
 | |
|     RC_MNEMONIC(31, InsertVal(536, 21, 30), OpDesc_A, OpDesc_S, OpDesc_B),   // srw
 | |
| 
 | |
|     // A-7
 | |
|     RC_MNEMONIC(63, InsertVal(21, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // fadd
 | |
|     RC_MNEMONIC(59, InsertVal(21, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // fadds
 | |
|     RC_MNEMONIC(63, InsertVal(18, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // fdiv
 | |
|     RC_MNEMONIC(59, InsertVal(18, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // fdivs
 | |
|     RC_MNEMONIC(63, InsertVal(25, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C),            // fmul
 | |
|     RC_MNEMONIC(59, InsertVal(25, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C),            // fmuls
 | |
|     RC_MNEMONIC(59, InsertVal(24, 26, 30), OpDesc_D, OpDesc_B),                      // fres
 | |
|     RC_MNEMONIC(63, InsertVal(26, 26, 30), OpDesc_D, OpDesc_B),                      // frsqrte
 | |
|     RC_MNEMONIC(63, InsertVal(20, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // fsub
 | |
|     RC_MNEMONIC(59, InsertVal(20, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // fsubs
 | |
|     RC_MNEMONIC(63, InsertVal(23, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fsel
 | |
| 
 | |
|     // A-8
 | |
|     RC_MNEMONIC(63, InsertVal(29, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fmadd
 | |
|     RC_MNEMONIC(59, InsertVal(29, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fmadds
 | |
|     RC_MNEMONIC(63, InsertVal(28, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fmsub
 | |
|     RC_MNEMONIC(59, InsertVal(28, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fmsubs
 | |
|     RC_MNEMONIC(63, InsertVal(31, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fnmadd
 | |
|     RC_MNEMONIC(59, InsertVal(31, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fnmadds
 | |
|     RC_MNEMONIC(63, InsertVal(30, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fnmsub
 | |
|     RC_MNEMONIC(59, InsertVal(30, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // fnmsubs
 | |
| 
 | |
|     // A-9
 | |
|     RC_MNEMONIC(63, InsertVal(14, 21, 30), OpDesc_D, OpDesc_B),  // fctiw
 | |
|     RC_MNEMONIC(63, InsertVal(15, 21, 30), OpDesc_D, OpDesc_B),  // fctiwz
 | |
|     RC_MNEMONIC(63, InsertVal(12, 21, 30), OpDesc_D, OpDesc_B),  // frsp
 | |
| 
 | |
|     // A-10
 | |
|     MNEMONIC(63, InsertVal(32, 21, 30), OpDesc_Crfd, OpDesc_A, OpDesc_B),  // fcmpo
 | |
|     MNEMONIC(63, InsertVal(0, 21, 30), OpDesc_Crfd, OpDesc_A, OpDesc_B),   // fcmpu
 | |
| 
 | |
|     // A-11
 | |
|     MNEMONIC(63, InsertVal(64, 21, 30), OpDesc_Crfd, OpDesc_Crfs),     // mcrfs
 | |
|     RC_MNEMONIC(63, InsertVal(583, 21, 30), OpDesc_D),                 // mffs
 | |
|     RC_MNEMONIC(63, InsertVal(70, 21, 30), OpDesc_Crbd),               // mtfsb0
 | |
|     RC_MNEMONIC(63, InsertVal(38, 21, 30), OpDesc_Crbd),               // mtfsb1
 | |
|     RC_MNEMONIC(63, InsertVal(711, 21, 30), OpDesc_FM, OpDesc_B),      // mtfsf
 | |
|     RC_MNEMONIC(63, InsertVal(134, 21, 30), OpDesc_Crfd, OpDesc_IMM),  // mtfsfi
 | |
| 
 | |
|     // A-12
 | |
|     BASIC_MNEMONIC(34, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lbz
 | |
|     BASIC_MNEMONIC(35, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lbzu
 | |
|     MNEMONIC(31, InsertVal(119, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lbzux
 | |
|     MNEMONIC(31, InsertVal(87, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),   // lbzx
 | |
|     BASIC_MNEMONIC(42, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lha
 | |
|     BASIC_MNEMONIC(43, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lhau
 | |
|     MNEMONIC(31, InsertVal(375, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lhaux
 | |
|     MNEMONIC(31, InsertVal(343, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lhax
 | |
|     BASIC_MNEMONIC(40, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lhz
 | |
|     BASIC_MNEMONIC(41, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lhzu
 | |
|     MNEMONIC(31, InsertVal(311, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lhzux
 | |
|     MNEMONIC(31, InsertVal(279, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lhzx
 | |
|     BASIC_MNEMONIC(32, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lwz
 | |
|     BASIC_MNEMONIC(33, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lwzu
 | |
|     MNEMONIC(31, InsertVal(55, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),   // lwzux
 | |
|     MNEMONIC(31, InsertVal(23, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),   // lwzx
 | |
| 
 | |
|     // A-13
 | |
|     BASIC_MNEMONIC(38, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // stb
 | |
|     BASIC_MNEMONIC(39, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // stbu
 | |
|     MNEMONIC(31, InsertVal(247, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stbux
 | |
|     MNEMONIC(31, InsertVal(215, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stbx
 | |
|     BASIC_MNEMONIC(44, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // sth
 | |
|     BASIC_MNEMONIC(45, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // sthu
 | |
|     MNEMONIC(31, InsertVal(439, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // sthux
 | |
|     MNEMONIC(31, InsertVal(407, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // sthx
 | |
|     BASIC_MNEMONIC(36, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // stw
 | |
|     BASIC_MNEMONIC(37, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // stwu
 | |
|     MNEMONIC(31, InsertVal(183, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stwux
 | |
|     MNEMONIC(31, InsertVal(151, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stwx
 | |
| 
 | |
|     // A-14
 | |
|     MNEMONIC(31, InsertVal(790, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lhbrx
 | |
|     MNEMONIC(31, InsertVal(534, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lwbrx
 | |
|     MNEMONIC(31, InsertVal(918, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // sthbrx
 | |
|     MNEMONIC(31, InsertVal(662, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stwbrx
 | |
| 
 | |
|     // A-15
 | |
|     BASIC_MNEMONIC(46, OpDesc_D, OpDesc_Offd, OpDesc_A),  // lmw
 | |
|     BASIC_MNEMONIC(47, OpDesc_S, OpDesc_Offd, OpDesc_A),  // stmw
 | |
| 
 | |
|     // A-16
 | |
|     MNEMONIC(31, InsertVal(597, 21, 30), OpDesc_D, OpDesc_A, OpDesc_NB),  // lswi
 | |
|     MNEMONIC(31, InsertVal(533, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),   // lswx
 | |
|     MNEMONIC(31, InsertVal(725, 21, 30), OpDesc_S, OpDesc_A, OpDesc_NB),  // stswi
 | |
|     MNEMONIC(31, InsertVal(661, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),   // stswx
 | |
| 
 | |
|     // A-17
 | |
|     MNEMONIC(31, InsertVal(854, 21, 30)),                               // eieio
 | |
|     MNEMONIC(19, InsertVal(150, 21, 30)),                               // isync
 | |
|     MNEMONIC(31, InsertVal(20, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lwarx
 | |
|     MNEMONIC(31, InsertVal(150, 21, 30) | InsertVal(1, 31, 31), OpDesc_S, OpDesc_A,
 | |
|              OpDesc_B),                    // stwcx.
 | |
|     MNEMONIC(31, InsertVal(598, 21, 30)),  // sync
 | |
| 
 | |
|     // A-18
 | |
|     BASIC_MNEMONIC(50, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lfd
 | |
|     BASIC_MNEMONIC(51, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lfdu
 | |
|     MNEMONIC(31, InsertVal(631, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lfdux
 | |
|     MNEMONIC(31, InsertVal(599, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lfdx
 | |
|     BASIC_MNEMONIC(48, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lfs
 | |
|     BASIC_MNEMONIC(49, OpDesc_D, OpDesc_Offd, OpDesc_A),                 // lfsu
 | |
|     MNEMONIC(31, InsertVal(567, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lfsux
 | |
|     MNEMONIC(31, InsertVal(535, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // lfsx
 | |
| 
 | |
|     // A-19
 | |
|     BASIC_MNEMONIC(54, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // stfd
 | |
|     BASIC_MNEMONIC(55, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // stfdu
 | |
|     MNEMONIC(31, InsertVal(759, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stfdux
 | |
|     MNEMONIC(31, InsertVal(727, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stfdx
 | |
|     MNEMONIC(31, InsertVal(983, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stfiwx
 | |
|     BASIC_MNEMONIC(52, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // stfs
 | |
|     BASIC_MNEMONIC(53, OpDesc_S, OpDesc_Offd, OpDesc_A),                 // stfsu
 | |
|     MNEMONIC(31, InsertVal(695, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stfsux
 | |
|     MNEMONIC(31, InsertVal(663, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // stfsx
 | |
| 
 | |
|     // A-20
 | |
|     RC_MNEMONIC(63, InsertVal(264, 21, 30), OpDesc_D, OpDesc_B),  // fabs
 | |
|     RC_MNEMONIC(63, InsertVal(72, 21, 30), OpDesc_D, OpDesc_B),   // fmr
 | |
|     RC_MNEMONIC(63, InsertVal(136, 21, 30), OpDesc_D, OpDesc_B),  // fnabs
 | |
|     RC_MNEMONIC(63, InsertVal(40, 21, 30), OpDesc_D, OpDesc_B),   // fneg
 | |
| 
 | |
|     // A-21
 | |
|     AALK_MNEMONIC(18, 0, OpDesc_LI),                                // b
 | |
|     AALK_MNEMONIC(16, 0, OpDesc_BO, OpDesc_BI, OpDesc_BD),          // bc
 | |
|     LK_MNEMONIC(19, InsertVal(528, 21, 30), OpDesc_BO, OpDesc_BI),  // bcctr
 | |
|     LK_MNEMONIC(19, InsertVal(16, 21, 30), OpDesc_BO, OpDesc_BI),   // bclr
 | |
| 
 | |
|     // A-22
 | |
|     MNEMONIC(19, InsertVal(257, 21, 30), OpDesc_Crbd, OpDesc_Crba, OpDesc_Crbb),  // crand
 | |
|     MNEMONIC(19, InsertVal(129, 21, 30), OpDesc_Crbd, OpDesc_Crba, OpDesc_Crbb),  // crandc
 | |
|     MNEMONIC(19, InsertVal(289, 21, 30), OpDesc_Crbd, OpDesc_Crba, OpDesc_Crbb),  // creqv
 | |
|     MNEMONIC(19, InsertVal(225, 21, 30), OpDesc_Crbd, OpDesc_Crba, OpDesc_Crbb),  // crnand
 | |
|     MNEMONIC(19, InsertVal(33, 21, 30), OpDesc_Crbd, OpDesc_Crba, OpDesc_Crbb),   // crnor
 | |
|     MNEMONIC(19, InsertVal(449, 21, 30), OpDesc_Crbd, OpDesc_Crba, OpDesc_Crbb),  // cror
 | |
|     MNEMONIC(19, InsertVal(417, 21, 30), OpDesc_Crbd, OpDesc_Crba, OpDesc_Crbb),  // crorc
 | |
|     MNEMONIC(19, InsertVal(193, 21, 30), OpDesc_Crbd, OpDesc_Crba, OpDesc_Crbb),  // crxor
 | |
|     MNEMONIC(19, InsertVal(0, 21, 30), OpDesc_Crfd, OpDesc_Crfs),                 // mcrf
 | |
| 
 | |
|     // A-23
 | |
|     MNEMONIC(19, InsertVal(50, 21, 30)),  // rfi
 | |
|     MNEMONIC(17, InsertVal(1, 30, 30)),   // sc
 | |
| 
 | |
|     // A-24
 | |
|     MNEMONIC(31, InsertVal(4, 21, 30), OpDesc_TO, OpDesc_A, OpDesc_B),  // tw
 | |
|     BASIC_MNEMONIC(3, OpDesc_TO, OpDesc_A, OpDesc_SIMM),                // twi
 | |
| 
 | |
|     // A-25
 | |
|     MNEMONIC(31, InsertVal(512, 21, 30), OpDesc_Crfd),           // mcrxr
 | |
|     MNEMONIC(31, InsertVal(19, 21, 30), OpDesc_D),               // mfcr
 | |
|     MNEMONIC(31, InsertVal(83, 21, 30), OpDesc_D),               // mfmsr
 | |
|     MNEMONIC(31, InsertVal(339, 21, 30), OpDesc_D, OpDesc_SPR),  // mfspr
 | |
|     MNEMONIC(31, InsertVal(371, 21, 30), OpDesc_D, OpDesc_TPR),  // mftb
 | |
|     MNEMONIC(31, InsertVal(144, 21, 30), OpDesc_CRM, OpDesc_S),  // mtcrf
 | |
|     MNEMONIC(31, InsertVal(146, 21, 30), OpDesc_S),              // mtmsr
 | |
|     MNEMONIC(31, InsertVal(467, 21, 30), OpDesc_SPR, OpDesc_D),  // mtspr
 | |
| 
 | |
|     // A-26
 | |
|     MNEMONIC(31, InsertVal(86, 21, 30), OpDesc_A, OpDesc_B),    // dcbf
 | |
|     MNEMONIC(31, InsertVal(470, 21, 30), OpDesc_A, OpDesc_B),   // dcbi
 | |
|     MNEMONIC(31, InsertVal(54, 21, 30), OpDesc_A, OpDesc_B),    // dcbst
 | |
|     MNEMONIC(31, InsertVal(278, 21, 30), OpDesc_A, OpDesc_B),   // dcbt
 | |
|     MNEMONIC(31, InsertVal(246, 21, 30), OpDesc_A, OpDesc_B),   // dcbtst
 | |
|     MNEMONIC(31, InsertVal(1014, 21, 30), OpDesc_A, OpDesc_B),  // dcbz
 | |
|     MNEMONIC(31, InsertVal(982, 21, 30), OpDesc_A, OpDesc_B),   // icbi
 | |
| 
 | |
|     // A-27
 | |
|     MNEMONIC(31, InsertVal(595, 21, 30), OpDesc_D, OpDesc_SR),  // mfsr
 | |
|     MNEMONIC(31, InsertVal(659, 21, 30), OpDesc_D, OpDesc_B),   // mfsrin
 | |
|     MNEMONIC(31, InsertVal(210, 21, 30), OpDesc_SR, OpDesc_S),  // mtsr
 | |
|     MNEMONIC(31, InsertVal(242, 21, 30), OpDesc_S, OpDesc_B),   // mtsrin
 | |
| 
 | |
|     // A-28
 | |
|     MNEMONIC(31, InsertVal(306, 21, 30), OpDesc_B),  // tlbie
 | |
|     MNEMONIC(31, InsertVal(566, 21, 30)),            // tlbsync
 | |
| 
 | |
|     // A-29
 | |
|     MNEMONIC(31, InsertVal(310, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),  // eciwx
 | |
|     MNEMONIC(31, InsertVal(438, 21, 30), OpDesc_S, OpDesc_A, OpDesc_B),  // ecowx
 | |
| 
 | |
|     // A-30
 | |
|     MNEMONIC(4, InsertVal(6, 25, 30), OpDesc_D, OpDesc_A, OpDesc_B, OpDesc_W2,
 | |
|              OpDesc_I2),  // psq_lx
 | |
|     MNEMONIC(4, InsertVal(7, 25, 30), OpDesc_S, OpDesc_A, OpDesc_B, OpDesc_W2,
 | |
|              OpDesc_I2),  // psq_stx
 | |
|     MNEMONIC(4, InsertVal(38, 25, 30), OpDesc_D, OpDesc_A, OpDesc_B, OpDesc_W2,
 | |
|              OpDesc_I2),  // psq_lux
 | |
|     MNEMONIC(4, InsertVal(39, 25, 30), OpDesc_S, OpDesc_A, OpDesc_B, OpDesc_W2,
 | |
|              OpDesc_I2),                                                          // psq_stux
 | |
|     BASIC_MNEMONIC(56, OpDesc_D, OpDesc_OffdPs, OpDesc_A, OpDesc_W1, OpDesc_I1),  // psq_l
 | |
|     BASIC_MNEMONIC(57, OpDesc_D, OpDesc_OffdPs, OpDesc_A, OpDesc_W1, OpDesc_I1),  // psq_lu
 | |
|     BASIC_MNEMONIC(60, OpDesc_S, OpDesc_OffdPs, OpDesc_A, OpDesc_W1, OpDesc_I1),  // psq_st
 | |
|     BASIC_MNEMONIC(61, OpDesc_S, OpDesc_OffdPs, OpDesc_A, OpDesc_W1, OpDesc_I1),  // psq_stu
 | |
| 
 | |
|     // A-31
 | |
|     RC_MNEMONIC(4, InsertVal(18, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // ps_div
 | |
|     RC_MNEMONIC(4, InsertVal(20, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // ps_sub
 | |
|     RC_MNEMONIC(4, InsertVal(21, 26, 30), OpDesc_D, OpDesc_A, OpDesc_B),            // ps_add
 | |
|     RC_MNEMONIC(4, InsertVal(23, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_sel
 | |
|     RC_MNEMONIC(4, InsertVal(24, 26, 30), OpDesc_D, OpDesc_B),                      // ps_res
 | |
|     RC_MNEMONIC(4, InsertVal(25, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C),            // ps_mul
 | |
|     RC_MNEMONIC(4, InsertVal(26, 26, 30), OpDesc_D, OpDesc_B),                      // ps_rsqrte
 | |
|     RC_MNEMONIC(4, InsertVal(28, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_msub
 | |
|     RC_MNEMONIC(4, InsertVal(29, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_madd
 | |
|     RC_MNEMONIC(4, InsertVal(30, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_nmsub
 | |
|     RC_MNEMONIC(4, InsertVal(31, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_nmadd
 | |
|     RC_MNEMONIC(4, InsertVal(40, 21, 30), OpDesc_D, OpDesc_B),                      // ps_neg
 | |
|     RC_MNEMONIC(4, InsertVal(72, 21, 30), OpDesc_D, OpDesc_B),                      // ps_mr
 | |
|     RC_MNEMONIC(4, InsertVal(136, 21, 30), OpDesc_D, OpDesc_B),                     // ps_nabs
 | |
|     RC_MNEMONIC(4, InsertVal(264, 21, 30), OpDesc_D, OpDesc_B),                     // ps_abs
 | |
| 
 | |
|     // A-32
 | |
|     RC_MNEMONIC(4, InsertVal(10, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_sum0
 | |
|     RC_MNEMONIC(4, InsertVal(11, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_sum1
 | |
|     RC_MNEMONIC(4, InsertVal(12, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C),            // ps_muls0
 | |
|     RC_MNEMONIC(4, InsertVal(13, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C),            // ps_muls1
 | |
|     RC_MNEMONIC(4, InsertVal(14, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_madds0
 | |
|     RC_MNEMONIC(4, InsertVal(15, 26, 30), OpDesc_D, OpDesc_A, OpDesc_C, OpDesc_B),  // ps_madds1
 | |
|     MNEMONIC(4, InsertVal(0, 21, 30), OpDesc_Crfd, OpDesc_A, OpDesc_B),             // ps_cmpu0
 | |
|     MNEMONIC(4, InsertVal(32, 21, 30), OpDesc_Crfd, OpDesc_A, OpDesc_B),            // ps_cmpo0
 | |
|     MNEMONIC(4, InsertVal(64, 21, 30), OpDesc_Crfd, OpDesc_A, OpDesc_B),            // ps_cmpu1
 | |
|     MNEMONIC(4, InsertVal(96, 21, 30), OpDesc_Crfd, OpDesc_A, OpDesc_B),            // ps_cmpo1
 | |
|     RC_MNEMONIC(4, InsertVal(528, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),           // ps_merge00
 | |
|     RC_MNEMONIC(4, InsertVal(560, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),           // ps_merge01
 | |
|     RC_MNEMONIC(4, InsertVal(592, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),           // ps_merge10
 | |
|     RC_MNEMONIC(4, InsertVal(624, 21, 30), OpDesc_D, OpDesc_A, OpDesc_B),           // ps_merge11
 | |
|     MNEMONIC(4, InsertVal(1014, 21, 30), OpDesc_A, OpDesc_B),                       // dcbz_l
 | |
| };
 | |
| 
 | |
| namespace
 | |
| {
 | |
| // Reused operand translators for extended mnemonics
 | |
| void NegateSIMM(OperandList& operands)
 | |
| {
 | |
|   operands[2] = static_cast<u32>(-static_cast<s32>(operands[2]));
 | |
| }
 | |
| 
 | |
| void SwapOps1And2(OperandList& operands)
 | |
| {
 | |
|   std::swap(operands[1], operands[2]);
 | |
| }
 | |
| 
 | |
| void SetCompareWordMode(OperandList& operands)
 | |
| {
 | |
|   if (operands.count == 2)
 | |
|   {
 | |
|     operands.Insert(0, 0);
 | |
|   }
 | |
|   operands.Insert(1, 0);
 | |
| }
 | |
| 
 | |
| template <u32 BO, u32 BI>
 | |
| void FillBOBI(OperandList& operands)
 | |
| {
 | |
|   operands.Insert(0, BO);
 | |
|   operands.Insert(1, BI);
 | |
| }
 | |
| 
 | |
| template <size_t Idx>
 | |
| void BitswapIdx(OperandList& operands)
 | |
| {
 | |
|   operands[Idx] = SprBitswap(operands[Idx]);
 | |
| }
 | |
| 
 | |
| template <u32 BO, u32 Cond, u32 ParamCount>
 | |
| void FillBOBICond(OperandList& operands)
 | |
| {
 | |
|   if (operands.count < ParamCount)
 | |
|   {
 | |
|     operands.Insert(0, 0);
 | |
|   }
 | |
|   operands[0] = (operands[0] << 2) | Cond;
 | |
|   operands.Insert(0, BO);
 | |
| }
 | |
| 
 | |
| template <u32 BO>
 | |
| void FillBO(OperandList& operands)
 | |
| {
 | |
|   operands.Insert(0, BO);
 | |
| }
 | |
| 
 | |
| template <u32 TO>
 | |
| void TrapSetTO(OperandList& operands)
 | |
| {
 | |
|   operands.Insert(0, TO);
 | |
| }
 | |
| 
 | |
| template <u32 SPRG>
 | |
| void FillMtspr(OperandList& operands)
 | |
| {
 | |
|   operands.Insert(0, SPRG);
 | |
| }
 | |
| 
 | |
| template <u32 SPRG>
 | |
| void FillMfspr(OperandList& operands)
 | |
| {
 | |
|   operands.Insert(1, SPRG);
 | |
| }
 | |
| 
 | |
| template <u32 SPRG>
 | |
| void FillMtsprBatAndBitswap(OperandList& operands)
 | |
| {
 | |
|   operands[0] = SprBitswap(2 * operands[0] + SPRG);
 | |
| }
 | |
| 
 | |
| template <u32 SPRG>
 | |
| void FillMfsprBatAndBitswap(OperandList& operands)
 | |
| {
 | |
|   operands[1] = SprBitswap(2 * operands[1] + SPRG);
 | |
| }
 | |
| }  // namespace
 | |
| 
 | |
| #define PSEUDO(base, variant_bits, cb)                                                             \
 | |
|   ExtendedMnemonicDesc                                                                             \
 | |
|   {                                                                                                \
 | |
|     static_cast<size_t>(base) * VARIANT_PERMUTATIONS + variant_bits, cb                            \
 | |
|   }
 | |
| #define PLAIN_PSEUDO(base, cb)                                                                     \
 | |
|   PSEUDO(base, PLAIN_MNEMONIC, cb), INVALID_EXT_MNEMONIC, INVALID_EXT_MNEMONIC, INVALID_EXT_MNEMONIC
 | |
| #define RC_PSEUDO(base, cb)                                                                        \
 | |
|   PSEUDO(base, PLAIN_MNEMONIC, cb), PSEUDO(base, RECORD_BIT, cb), INVALID_EXT_MNEMONIC,            \
 | |
|       INVALID_EXT_MNEMONIC
 | |
| #define OERC_PSEUDO(base, cb)                                                                      \
 | |
|   PSEUDO(base, PLAIN_MNEMONIC, cb), PSEUDO(base, RECORD_BIT, cb),                                  \
 | |
|       PSEUDO(base, OVERFLOW_EXCEPTION, cb), PSEUDO(base, (RECORD_BIT | OVERFLOW_EXCEPTION), cb)
 | |
| #define LK_PSEUDO(base, cb)                                                                        \
 | |
|   PSEUDO(base, PLAIN_MNEMONIC, cb), PSEUDO(base, LINK_BIT, cb), INVALID_EXT_MNEMONIC,              \
 | |
|       INVALID_EXT_MNEMONIC
 | |
| #define LKAA_PSEUDO(base, cb)                                                                      \
 | |
|   PSEUDO(base, PLAIN_MNEMONIC, cb), PSEUDO(base, LINK_BIT, cb),                                    \
 | |
|       PSEUDO(base, ABSOLUTE_ADDRESS_BIT, cb), PSEUDO(base, (LINK_BIT | ABSOLUTE_ADDRESS_BIT), cb)
 | |
| 
 | |
| extern const std::array<ExtendedMnemonicDesc, NUM_EXT_MNEMONICS * VARIANT_PERMUTATIONS>
 | |
|     extended_mnemonics = {
 | |
|         // E.2.1
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Addi, NegateSIMM),      // subi
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Addis, NegateSIMM),     // subis
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Addic, NegateSIMM),     // subic
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::AddicDot, NegateSIMM),  // subic.
 | |
| 
 | |
|         // E.2.2
 | |
|         OERC_PSEUDO(GekkoMnemonic::Subf, SwapOps1And2),   // sub
 | |
|         OERC_PSEUDO(GekkoMnemonic::Subfc, SwapOps1And2),  // subc
 | |
| 
 | |
|         // E.3.2
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Cmpi, SetCompareWordMode),   // cmpwi
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Cmp, SetCompareWordMode),    // cmpw
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Cmpli, SetCompareWordMode),  // cmplwi
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Cmpl, SetCompareWordMode),   // cmplw
 | |
| 
 | |
|         // E.4.2
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2], b = operands[3];
 | |
|                     operands[2] = b;
 | |
|                     operands[3] = 0;
 | |
|                     operands.Insert(4, n - 1);
 | |
|                   })),  // extlwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2], b = operands[3];
 | |
|                     operands[2] = b + n;
 | |
|                     operands[3] = 32 - n;
 | |
|                     operands.Insert(4, 31);
 | |
|                   })),  // extrwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwimi, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2], b = operands[3];
 | |
|                     operands[2] = 32 - b;
 | |
|                     operands[3] = b;
 | |
|                     operands.Insert(4, b + n - 1);
 | |
|                   })),  // inslwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwimi, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2], b = operands[3];
 | |
|                     operands[2] = 32 - (b + n);
 | |
|                     operands[3] = b;
 | |
|                     operands.Insert(4, b + n - 1);
 | |
|                   })),  // insrwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     operands.Insert(3, 0);
 | |
|                     operands.Insert(4, 31);
 | |
|                   })),  // rotlwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2];
 | |
|                     operands[2] = 32 - n;
 | |
|                     operands.Insert(3, 0);
 | |
|                     operands.Insert(4, 31);
 | |
|                   })),  // rotrwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwnm, ([](OperandList& operands) {
 | |
|                     operands.Insert(3, 0);
 | |
|                     operands.Insert(4, 31);
 | |
|                   })),  // rotlw
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2];
 | |
|                     operands.Insert(3, 0);
 | |
|                     operands.Insert(4, 31 - n);
 | |
|                   })),  // slwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2];
 | |
|                     operands[2] = 32 - n;
 | |
|                     operands.Insert(3, n);
 | |
|                     operands.Insert(4, 31);
 | |
|                   })),  // srwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2];
 | |
|                     operands[2] = 0;
 | |
|                     operands.Insert(3, n);
 | |
|                     operands.Insert(4, 31);
 | |
|                   })),  // clrlwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     const u32 n = operands[2];
 | |
|                     operands[2] = 0;
 | |
|                     operands.Insert(3, 0);
 | |
|                     operands.Insert(4, 31 - n);
 | |
|                   })),  // clrrwi
 | |
|         RC_PSEUDO(GekkoMnemonic::Rlwinm, ([](OperandList& operands) {
 | |
|                     const u32 b = operands[2], n = operands[3];
 | |
|                     operands[2] = n;
 | |
|                     operands[3] = b - n;
 | |
|                     operands.Insert(4, 31 - n);
 | |
|                   })),  // clrlslwi
 | |
| 
 | |
|         // E.5.2
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<12>)),       // bt
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<4>)),        // bf
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBI<16, 0>)),  // bdnz
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<8>)),        // bdnzt
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<0>)),        // bdnzf
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBI<18, 0>)),  // bdz
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<10>)),       // bdzt
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<2>)),        // bdzf
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<13>)),       // bt+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<5>)),        // bf+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBI<17, 0>)),  // bdnz+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<9>)),        // bdnzt+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<1>)),        // bdnzf+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBI<19, 0>)),  // bdz+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<11>)),       // bdzt+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBO<3>)),        // bdzf+
 | |
| 
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBI<20, 0>)),  // blr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<12>)),       // btlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<4>)),        // bflr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBI<16, 0>)),  // bdnzlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<8>)),        // bdnztlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<0>)),        // bdnzflr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBI<18, 0>)),  // bdzlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<10>)),       // bdztlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<2>)),        // bdzflr
 | |
| 
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<13>)),       // btlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<5>)),        // bflr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBI<17, 0>)),  // bdnzlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<9>)),        // bdnztlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<1>)),        // bdnzflr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBI<19, 0>)),  // bdzlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<11>)),       // bdztlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBO<3>)),        // bdzflr+
 | |
| 
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBI<20, 0>)),  // bctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBO<12>)),       // btctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBO<4>)),        // bfctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBO<13>)),       // btctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBO<5>)),        // bfctr+
 | |
| 
 | |
|         // E.5.3
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<12, 0, 2>)),  // blt
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<4, 1, 2>)),   // ble
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<12, 2, 2>)),  // beq
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<4, 0, 2>)),   // bge
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<12, 1, 2>)),  // bgt
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<4, 0, 2>)),   // bnl
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<4, 2, 2>)),   // bne
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<4, 1, 2>)),   // bng
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<12, 3, 2>)),  // bso
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<4, 3, 2>)),   // bns
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<12, 3, 2>)),  // bun
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<4, 3, 2>)),   // bnu
 | |
| 
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<13, 0, 2>)),  // blt+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<5, 1, 2>)),   // ble+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<13, 2, 2>)),  // beq+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<5, 0, 2>)),   // bge+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<13, 1, 2>)),  // bgt+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<5, 0, 2>)),   // bnl+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<5, 2, 2>)),   // bne+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<5, 1, 2>)),   // bng+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<13, 3, 2>)),  // bso+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<5, 3, 2>)),   // bns+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<13, 3, 2>)),  // bun+
 | |
|         LKAA_PSEUDO(GekkoMnemonic::Bc, (FillBOBICond<5, 3, 2>)),   // bnu+
 | |
| 
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<12, 0, 1>)),  // bltlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<4, 1, 1>)),   // blelr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<12, 2, 1>)),  // beqlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<4, 0, 1>)),   // bgelr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<12, 1, 1>)),  // bgtlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<4, 0, 1>)),   // bnllr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<4, 2, 1>)),   // bnelr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<4, 1, 1>)),   // bnglr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<12, 3, 1>)),  // bsolr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<4, 3, 1>)),   // bnslr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<12, 3, 1>)),  // bunlr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<4, 3, 1>)),   // bnulr
 | |
| 
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<13, 0, 1>)),  // bltlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<5, 1, 1>)),   // blelr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<13, 2, 1>)),  // beqlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<5, 0, 1>)),   // bgelr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<13, 1, 1>)),  // bgtlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<5, 0, 1>)),   // bnllr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<5, 2, 1>)),   // bnelr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<5, 1, 1>)),   // bnglr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<13, 3, 1>)),  // bsolr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<5, 3, 1>)),   // bnslr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<13, 3, 1>)),  // bunlr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bclr, (FillBOBICond<5, 3, 1>)),   // bnulr+
 | |
| 
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<12, 0, 1>)),  // bltctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<4, 1, 1>)),   // blectr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<12, 2, 1>)),  // beqctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<4, 0, 1>)),   // bgectr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<12, 1, 1>)),  // bgtctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<4, 0, 1>)),   // bnlctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<4, 2, 1>)),   // bnectr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<4, 1, 1>)),   // bngctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<12, 3, 1>)),  // bsoctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<4, 3, 1>)),   // bnsctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<12, 3, 1>)),  // bunctr
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<4, 3, 1>)),   // bnuctr
 | |
| 
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<13, 0, 1>)),  // bltctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<5, 1, 1>)),   // blectr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<13, 2, 1>)),  // beqctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<5, 0, 1>)),   // bgectr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<13, 1, 1>)),  // bgtctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<5, 0, 1>)),   // bnlctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<5, 2, 1>)),   // bnectr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<5, 1, 1>)),   // bngctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<13, 3, 1>)),  // bsoctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<5, 3, 1>)),   // bnsctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<13, 3, 1>)),  // bunctr+
 | |
|         LK_PSEUDO(GekkoMnemonic::Bcctr, (FillBOBICond<5, 3, 1>)),   // bnuctr+
 | |
| 
 | |
|         // E.6
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Creqv,
 | |
|                      [](OperandList& operands) {
 | |
|                        operands.Insert(1, operands[0]);
 | |
|                        operands.Insert(2, operands[0]);
 | |
|                      }),  // crset
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Crxor,
 | |
|                      [](OperandList& operands) {
 | |
|                        operands.Insert(1, operands[0]);
 | |
|                        operands.Insert(2, operands[0]);
 | |
|                      }),  // crclr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Cror,
 | |
|                      [](OperandList& operands) { operands.Insert(2, operands[1]); }),  // crmove
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Crnor,
 | |
|                      [](OperandList& operands) { operands.Insert(2, operands[1]); }),  // crnot
 | |
| 
 | |
|         // E.7
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<16>),   // twlt
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<16>),  // twlti
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<20>),   // twle
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<20>),  // twlei
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<4>),    // tweq
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<4>),   // tweqi
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<12>),   // twge
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<12>),  // twgei
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<8>),    // twgt
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<8>),   // twgti
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<12>),   // twnl
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<12>),  // twnli
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<24>),   // twne
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<24>),  // twnei
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<20>),   // twng
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<20>),  // twngi
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<2>),    // twllt
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<2>),   // twllti
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<6>),    // twlle
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<6>),   // twllei
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<5>),    // twlge
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<5>),   // twlgei
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<1>),    // twlgt
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<1>),   // twlgti
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<5>),    // twlnl
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<5>),   // twlnli
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw, TrapSetTO<6>),    // twlng
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Twi, TrapSetTO<6>),   // twlngi
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Tw,
 | |
|                      [](OperandList& operands) {
 | |
|                        operands.Insert(0, 31);
 | |
|                        operands.Insert(1, 0);
 | |
|                        operands.Insert(2, 0);
 | |
|                      }),  // trap
 | |
| 
 | |
|         // E.8
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(1)>),    // mtxer
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(1)>),    // mfxer
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(8)>),    // mtlr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(8)>),    // mflr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(9)>),    // mtctr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(9)>),    // mfctr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(18)>),   // mtdsisr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(18)>),   // mfdsisr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(19)>),   // mtdar
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(19)>),   // mfdar
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(22)>),   // mtdec
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(22)>),   // mfdec
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(25)>),   // mtsdr1
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(25)>),   // mfsdr1
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(26)>),   // mtsrr0
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(26)>),   // mfsrr0
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(27)>),   // mtsrr1
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(27)>),   // mfsrr1
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(280)>),  // mtasr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(280)>),  // mfasr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(282)>),  // mtear
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfspr<SprBitswap(282)>),  // mfear
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(284)>),  // mttbl
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mftb_nobitswap, FillMfspr<SprBitswap(268)>),   // mftbl
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtspr<SprBitswap(285)>),  // mttbu
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mftb_nobitswap, FillMfspr<SprBitswap(269)>),   // mftbu
 | |
|         PLAIN_PSEUDO(
 | |
|             GekkoMnemonic::Mtspr_nobitswap,
 | |
|             [](OperandList& operands) { operands[0] = SprBitswap(operands[0] + 272); }),  // mtsprg
 | |
|         PLAIN_PSEUDO(
 | |
|             GekkoMnemonic::Mfspr_nobitswap,
 | |
|             [](OperandList& operands) { operands[1] = SprBitswap(operands[1] + 272); }),  // mfsprg
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtsprBatAndBitswap<528>),        // mtibatu
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfsprBatAndBitswap<528>),        // mfibatu
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtsprBatAndBitswap<529>),        // mtibatl
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfsprBatAndBitswap<529>),        // mfibatl
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtsprBatAndBitswap<536>),        // mtdbatu
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfsprBatAndBitswap<536>),        // mfdbatu
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, FillMtsprBatAndBitswap<537>),        // mtdbatl
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, FillMfsprBatAndBitswap<537>),        // mfdbatl
 | |
| 
 | |
|         // E.9
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Ori,
 | |
|                      [](OperandList& operands) {
 | |
|                        operands.Insert(0, 0);
 | |
|                        operands.Insert(1, 0);
 | |
|                        operands.Insert(2, 0);
 | |
|                      }),  // nop
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Addi,
 | |
|                      [](OperandList& operands) { operands.Insert(1, 0); }),  // li
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Addis,
 | |
|                      [](OperandList& operands) { operands.Insert(1, 0); }),  // lis
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Addi, SwapOps1And2),                     // la
 | |
|         RC_PSEUDO(GekkoMnemonic::Or,
 | |
|                   ([](OperandList& operands) { operands.Insert(2, operands[1]); })),  // mr
 | |
|         RC_PSEUDO(GekkoMnemonic::Nor,
 | |
|                   ([](OperandList& operands) { operands.Insert(2, operands[1]); })),  // not
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtcrf,
 | |
|                      [](OperandList& operands) { operands.Insert(0, 0xff); }),  // mtcr
 | |
| 
 | |
|         // Additional mnemonics
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mfspr_nobitswap, BitswapIdx<1>),  // mfspr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mftb_nobitswap, BitswapIdx<1>),   // mfspr
 | |
|         PLAIN_PSEUDO(GekkoMnemonic::Mtspr_nobitswap, BitswapIdx<0>),  // mtspr
 | |
| };
 | |
| 
 | |
| #undef EMIT_MNEMONIC_ENTRY
 | |
| #undef MNEMONIC
 | |
| #undef BASIC_MNEMONIC
 | |
| #undef RC_MNEMONIC
 | |
| #undef OERC_MNEMONIC
 | |
| #undef LK_MNEMONIC
 | |
| #undef AALK_MNEMONIC
 | |
| #undef PSEUDO
 | |
| #undef PLAIN_PSEUDO
 | |
| #undef RC_PSEUDO
 | |
| #undef OERC_PSEUDO
 | |
| #undef LK_PSEUDO
 | |
| #undef LKAA_PSEUDO
 | |
| 
 | |
| //////////////////
 | |
| // LEXER TABLES //
 | |
| //////////////////
 | |
| 
 | |
| namespace
 | |
| {
 | |
| constexpr TransitionF HasPlusOrMinus = [](char c) { return c == '+' || c == '-'; };
 | |
| constexpr TransitionF HasDigit = [](char c) -> bool { return std::isdigit(c); };
 | |
| constexpr TransitionF HasE = [](char c) { return c == 'e'; };
 | |
| constexpr TransitionF HasDot = [](char c) { return c == '.'; };
 | |
| 
 | |
| // Normal string characters
 | |
| constexpr TransitionF HasNormal = [](char c) { return c != '\n' && c != '"' && c != '\\'; };
 | |
| // Invalid characters in string
 | |
| constexpr TransitionF HasInvalid = [](char c) { return c == '\n'; };
 | |
| // Octal digits
 | |
| constexpr TransitionF HasOctal = [](char c) { return c >= '0' && c <= '7'; };
 | |
| // Hex digits
 | |
| constexpr TransitionF HasHex = [](char c) -> bool { return std::isxdigit(c); };
 | |
| // Normal - octal
 | |
| constexpr TransitionF HasNormalMinusOctal = [](char c) { return HasNormal(c) && !HasOctal(c); };
 | |
| // Normal - hex
 | |
| constexpr TransitionF HasNormalMinusHex = [](char c) { return HasNormal(c) && !HasHex(c); };
 | |
| // Escape start
 | |
| constexpr TransitionF HasEscape = [](char c) { return c == '\\'; };
 | |
| // All single-character escapes
 | |
| constexpr TransitionF HasSCE = [](char c) { return !HasOctal(c) && c != 'x' && c != '\n'; };
 | |
| // Hex escape
 | |
| constexpr TransitionF HasHexStart = [](char c) { return c == 'x'; };
 | |
| constexpr TransitionF HasQuote = [](char c) { return c == '"'; };
 | |
| }  // namespace
 | |
| 
 | |
| extern const std::vector<DfaNode> float_dfa = {
 | |
|     {{DfaEdge(HasPlusOrMinus, 1), DfaEdge(HasDigit, 2), DfaEdge(HasDot, 5)},
 | |
|      "Invalid float: No numeric value"},
 | |
| 
 | |
|     {{DfaEdge(HasDigit, 2), DfaEdge(HasDot, 5)}, "Invalid float: No numeric value"},
 | |
| 
 | |
|     {{DfaEdge(HasDigit, 2), DfaEdge(HasDot, 3), DfaEdge(HasE, 7)}, std::nullopt},
 | |
|     {{DfaEdge(HasDigit, 4)}, "Invalid float: No numeric value after decimal point"},
 | |
|     {{DfaEdge(HasDigit, 4), DfaEdge(HasE, 7)}, std::nullopt},
 | |
| 
 | |
|     {{DfaEdge(HasDigit, 6)}, "Invalid float: No numeric value after decimal point"},
 | |
|     {{DfaEdge(HasDigit, 6), DfaEdge(HasE, 7)}, std::nullopt},
 | |
| 
 | |
|     {{DfaEdge(HasDigit, 9), DfaEdge(HasPlusOrMinus, 8)},
 | |
|      "Invalid float: No numeric value following exponent signifier"},
 | |
|     {{DfaEdge(HasDigit, 9)}, "Invalid float: No numeric value following exponent signifier"},
 | |
|     {{DfaEdge(HasDigit, 9)}, std::nullopt},
 | |
| };
 | |
| 
 | |
| extern const std::vector<DfaNode> string_dfa = {
 | |
|     // Base character check
 | |
|     {{DfaEdge(HasNormal, 0), DfaEdge(HasInvalid, 1), DfaEdge(HasQuote, 2), DfaEdge(HasEscape, 3)},
 | |
|      "Invalid string: No terminating \""},
 | |
| 
 | |
|     // Invalid (unescaped newline)
 | |
|     {{}, "Invalid string: No terminating \""},
 | |
|     // String end
 | |
|     {{}, std::nullopt},
 | |
| 
 | |
|     // Escape character breakout
 | |
|     {{DfaEdge(HasSCE, 0), DfaEdge(HasInvalid, 1), DfaEdge(HasOctal, 4), DfaEdge(HasHexStart, 6)},
 | |
|      "Invalid string: No terminating \""},
 | |
| 
 | |
|     // Octal characters, at most 3
 | |
|     {{DfaEdge(HasNormalMinusOctal, 0), DfaEdge(HasInvalid, 1), DfaEdge(HasQuote, 2),
 | |
|       DfaEdge(HasEscape, 3), DfaEdge(HasOctal, 5)},
 | |
|      "Invalid string: No terminating \""},
 | |
|     {{DfaEdge(HasNormal, 0), DfaEdge(HasInvalid, 1), DfaEdge(HasQuote, 2), DfaEdge(HasEscape, 3)},
 | |
|      "Invalid string: No terminating \""},
 | |
| 
 | |
|     // Hex characters, 1 or more
 | |
|     {{DfaEdge(HasHex, 7)}, "Invalid string: bad hex escape"},
 | |
|     {{DfaEdge(HasNormalMinusHex, 0), DfaEdge(HasInvalid, 1), DfaEdge(HasQuote, 2),
 | |
|       DfaEdge(HasEscape, 3), DfaEdge(HasHex, 7)},
 | |
|      "Invalid string: No terminating \""},
 | |
| };
 | |
| }  // namespace Common::GekkoAssembler::detail
 |