1488 lines
87 KiB
C++
1488 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
|