From 7c02e727590339018efcdcc45f2d2ef0794ca387 Mon Sep 17 00:00:00 2001 From: noone Date: Sat, 10 May 2025 07:52:24 -0700 Subject: [PATCH] Add support for paired-single instructions --- arch/powerpc/decode/decode.c | 211 +++++++++++++++++++++++++++++++++ arch/powerpc/decode/decode.h | 48 ++++++-- arch/powerpc/decode/mnemonic.c | 73 ++++++++++-- arch/powerpc/decode/operands.c | 142 +++++++++++++++++++++- arch/powerpc/il.cpp | 4 +- 5 files changed, 457 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/decode/decode.c b/arch/powerpc/decode/decode.c index 535062118..64a5f3529 100644 --- a/arch/powerpc/decode/decode.c +++ b/arch/powerpc/decode/decode.c @@ -2063,6 +2063,203 @@ static InstructionId DecodeSpe0x04(uint32_t word32, uint32_t decodeFlags) } } +static InstructionId DecodePairedSingle0x04(uint32_t word32, uint32_t decodeFlags) +{ + uint32_t a = GetA(word32); + uint32_t b = GetB(word32); + uint32_t c = GetC(word32); + uint32_t d = GetD(word32); + + // see IBM Broadway RISC Microprocessor User's Manual, + // Tables A-30, A-31, and A-32 + uint32_t subop = (word32 >> 1) & 0x1f; + switch (subop) + { + case 10: + return PPC_ID_PAIREDSINGLE_PS_SUM0x; + + case 11: + return PPC_ID_PAIREDSINGLE_PS_SUM1x; + + case 12: + if (b != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_MULS0x; + + case 13: + if (b != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_MULS1x; + + case 14: + return PPC_ID_PAIREDSINGLE_PS_MADDS0x; + + case 15: + return PPC_ID_PAIREDSINGLE_PS_MADDS1x; + + case 18: + if (c != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_DIVx; + + case 20: + if (c != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_SUBx; + + case 21: + if (c != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_ADDx; + + case 23: + return PPC_ID_PAIREDSINGLE_PS_SELx; + + case 24: + if ((a != 0) || (c != 0)) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_RESx; + + case 25: + if (b != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_MULx; + + case 26: + if ((a != 0) || (c != 0)) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_RSQRTEx; + + case 28: + return PPC_ID_PAIREDSINGLE_PS_MSUBx; + + case 29: + return PPC_ID_PAIREDSINGLE_PS_MADDx; + + case 30: + return PPC_ID_PAIREDSINGLE_PS_NMSUBx; + + case 31: + return PPC_ID_PAIREDSINGLE_PS_NMADDx; + + default: + ; + } + + subop = (word32 >> 1) & 0x3f; + switch (subop) + { + case 6: + if ((word32 & 0x1) != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PSQ_LX; + + case 7: + if ((word32 & 0x1) != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PSQ_STX; + + case 38: + if ((word32 & 0x1) != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PSQ_LUX; + + case 39: + if ((word32 & 0x1) != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PSQ_STUX; + + default: + ; + } + + subop = (word32 >> 1) & 0x3ff; + switch (subop) + { + case 0: + if ((word32 & 0x00600001) != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_CMPU0; + + case 32: + if ((word32 & 0x00600001) != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_CMPO0; + + case 40: + if (a != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_NEGx; + + case 64: + if ((word32 & 0x00600001) != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_CMPU1; + + case 72: + if (a != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_MRx; + + case 96: + if ((word32 & 0x00600001) != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_CMPO1; + + case 136: + if (a != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_NABSx; + + case 264: + if (a != 0) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_PS_ABSx; + + case 528: + return PPC_ID_PAIREDSINGLE_PS_MERGE00x; + + case 560: + return PPC_ID_PAIREDSINGLE_PS_MERGE01x; + + case 592: + return PPC_ID_PAIREDSINGLE_PS_MERGE10x; + + case 624: + return PPC_ID_PAIREDSINGLE_PS_MERGE11x; + + case 1014: + if ((d != 0) || ((word32 & 0x1) != 0)) + return PPC_ID_INVALID; + + return PPC_ID_PAIREDSINGLE_DCBZ_L; + + default: + return PPC_ID_INVALID; + } + +} + static InstructionId Decode0x13(uint32_t word32, uint32_t decodeFlags) { uint32_t a = GetA(word32); @@ -5537,6 +5734,8 @@ static InstructionId Decode32(uint32_t word32, uint32_t decodeFlags) return DecodeAltivec0x04(word32, decodeFlags); else if ((decodeFlags & DECODE_FLAGS_SPE)) return DecodeSpe0x04(word32, decodeFlags); + else if ((decodeFlags & DECODE_FLAGS_PS)) + return DecodePairedSingle0x04(word32, decodeFlags); else return PPC_ID_INVALID; } @@ -5757,9 +5956,17 @@ static InstructionId Decode32(uint32_t word32, uint32_t decodeFlags) case 0x37: return PPC_ID_STFDU; + case 0x38: + if ((decodeFlags & DECODE_FLAGS_PS) != 0) + return PPC_ID_PAIREDSINGLE_PSQ_L; + else + return PPC_ID_INVALID; + case 0x39: if ((decodeFlags & DECODE_FLAGS_VSX) != 0) return DecodeVsx0x39(word32, decodeFlags); + else if ((decodeFlags & DECODE_FLAGS_PS) != 0) + return PPC_ID_PAIREDSINGLE_PSQ_LU; else return PPC_ID_INVALID; @@ -5781,12 +5988,16 @@ static InstructionId Decode32(uint32_t word32, uint32_t decodeFlags) case 0x3c: if ((decodeFlags & DECODE_FLAGS_VSX) != 0) return DecodeVsx0x3C(word32, decodeFlags); + else if ((decodeFlags & DECODE_FLAGS_PS) != 0) + return PPC_ID_PAIREDSINGLE_PSQ_ST; else return PPC_ID_INVALID; case 0x3d: if ((decodeFlags & DECODE_FLAGS_VSX) != 0) return DecodeVsx0x3D(word32, decodeFlags); + else if ((decodeFlags & DECODE_FLAGS_PS) != 0) + return PPC_ID_PAIREDSINGLE_PSQ_STU; else return PPC_ID_INVALID; diff --git a/arch/powerpc/decode/decode.h b/arch/powerpc/decode/decode.h index f5cd82746..a0645773d 100644 --- a/arch/powerpc/decode/decode.h +++ b/arch/powerpc/decode/decode.h @@ -1359,15 +1359,45 @@ extern "C" { PPC_ID_VSX_XXSPLTW, PPC_ID_VSX_XXSWAPD, - // Pair-stored - PPC_ID_PSQ_L, - PPC_ID_PSQ_LU, - PPC_ID_PSQ_LUX, - PPC_ID_PSQ_LX, - PPC_ID_PSQ_ST, - PPC_ID_PSQ_STU, - PPC_ID_PSQ_STUX, - PPC_ID_PSQ_STX, + // Paired-single + PPC_ID_PAIREDSINGLE_DCBZ_L, + PPC_ID_PAIREDSINGLE_PS_ABSx, + PPC_ID_PAIREDSINGLE_PS_ADDx, + PPC_ID_PAIREDSINGLE_PS_CMPO0, + PPC_ID_PAIREDSINGLE_PS_CMPO1, + PPC_ID_PAIREDSINGLE_PS_CMPU0, + PPC_ID_PAIREDSINGLE_PS_CMPU1, + PPC_ID_PAIREDSINGLE_PS_DIVx, + PPC_ID_PAIREDSINGLE_PS_MADDx, + PPC_ID_PAIREDSINGLE_PS_MADDS0x, + PPC_ID_PAIREDSINGLE_PS_MADDS1x, + PPC_ID_PAIREDSINGLE_PS_MERGE00x, + PPC_ID_PAIREDSINGLE_PS_MERGE01x, + PPC_ID_PAIREDSINGLE_PS_MERGE10x, + PPC_ID_PAIREDSINGLE_PS_MERGE11x, + PPC_ID_PAIREDSINGLE_PS_MRx, + PPC_ID_PAIREDSINGLE_PS_MSUBx, + PPC_ID_PAIREDSINGLE_PS_MULx, + PPC_ID_PAIREDSINGLE_PS_MULS0x, + PPC_ID_PAIREDSINGLE_PS_MULS1x, + PPC_ID_PAIREDSINGLE_PS_NABSx, + PPC_ID_PAIREDSINGLE_PS_NEGx, + PPC_ID_PAIREDSINGLE_PS_NMADDx, + PPC_ID_PAIREDSINGLE_PS_NMSUBx, + PPC_ID_PAIREDSINGLE_PS_RESx, + PPC_ID_PAIREDSINGLE_PS_RSQRTEx, + PPC_ID_PAIREDSINGLE_PS_SELx, + PPC_ID_PAIREDSINGLE_PS_SUBx, + PPC_ID_PAIREDSINGLE_PS_SUM0x, + PPC_ID_PAIREDSINGLE_PS_SUM1x, + PPC_ID_PAIREDSINGLE_PSQ_L, + PPC_ID_PAIREDSINGLE_PSQ_LU, + PPC_ID_PAIREDSINGLE_PSQ_LUX, + PPC_ID_PAIREDSINGLE_PSQ_LX, + PPC_ID_PAIREDSINGLE_PSQ_ST, + PPC_ID_PAIREDSINGLE_PSQ_STU, + PPC_ID_PAIREDSINGLE_PSQ_STUX, + PPC_ID_PAIREDSINGLE_PSQ_STX, // SPE (Signal Processing Engine) instructions PPC_ID_SPE_BRINC, diff --git a/arch/powerpc/decode/mnemonic.c b/arch/powerpc/decode/mnemonic.c index 45bbea921..0c6a16774 100644 --- a/arch/powerpc/decode/mnemonic.c +++ b/arch/powerpc/decode/mnemonic.c @@ -301,6 +301,33 @@ DEFINE_SUBMNEM_ROUND2ODD(SubMnemXSSQRTQPx, "xssqrtqp"); DEFINE_SUBMNEM_ROUND2ODD(SubMnemXSSUBQPx, "xssubqp"); DEFINE_SUBMNEM_INEXACT(SubMnemXSRQPIx, "xsrqpi"); +// PAIREDSINGLE MNEMONICS +DEFINE_SUBMNEM_RC(SubMnemPS_ABSx, "ps_abs"); +DEFINE_SUBMNEM_RC(SubMnemPS_ADDx, "ps_add"); +DEFINE_SUBMNEM_RC(SubMnemPS_DIVx, "ps_div"); +DEFINE_SUBMNEM_RC(SubMnemPS_MADDx, "ps_madd"); +DEFINE_SUBMNEM_RC(SubMnemPS_MADDS0x, "ps_madds0"); +DEFINE_SUBMNEM_RC(SubMnemPS_MADDS1x, "ps_madds1"); +DEFINE_SUBMNEM_RC(SubMnemPS_MERGE00x, "ps_merge00"); +DEFINE_SUBMNEM_RC(SubMnemPS_MERGE01x, "ps_merge01"); +DEFINE_SUBMNEM_RC(SubMnemPS_MERGE10x, "ps_merge10"); +DEFINE_SUBMNEM_RC(SubMnemPS_MERGE11x, "ps_merge11"); +DEFINE_SUBMNEM_RC(SubMnemPS_MRx, "ps_mr"); +DEFINE_SUBMNEM_RC(SubMnemPS_MSUBx, "ps_msub"); +DEFINE_SUBMNEM_RC(SubMnemPS_MULx, "ps_mul"); +DEFINE_SUBMNEM_RC(SubMnemPS_MULS0x, "ps_muls0"); +DEFINE_SUBMNEM_RC(SubMnemPS_MULS1x, "ps_muls1"); +DEFINE_SUBMNEM_RC(SubMnemPS_NABSx, "ps_nabs"); +DEFINE_SUBMNEM_RC(SubMnemPS_NEGx, "ps_neg"); +DEFINE_SUBMNEM_RC(SubMnemPS_NMADDx, "ps_nmadd"); +DEFINE_SUBMNEM_RC(SubMnemPS_NMSUBx, "ps_nmsub"); +DEFINE_SUBMNEM_RC(SubMnemPS_RESx, "ps_res"); +DEFINE_SUBMNEM_RC(SubMnemPS_RSQRTEx, "ps_rsqrte"); +DEFINE_SUBMNEM_RC(SubMnemPS_SELx, "ps_sel"); +DEFINE_SUBMNEM_RC(SubMnemPS_SUBx, "ps_sub"); +DEFINE_SUBMNEM_RC(SubMnemPS_SUM0x, "ps_sum0"); +DEFINE_SUBMNEM_RC(SubMnemPS_SUM1x, "ps_sum1"); + static const char* RcMnemonic(const Instruction* instruction, const char* names[2]) { return names[instruction->flags.rc]; @@ -1589,14 +1616,44 @@ const char* GetMnemonic(const Instruction* instruction) case PPC_ID_VSX_XXSPLTW: return "xxspltw"; case PPC_ID_VSX_XXSWAPD: return "xxswapd"; - case PPC_ID_PSQ_L: return "psq_l"; - case PPC_ID_PSQ_LU: return "psq_lu"; - case PPC_ID_PSQ_LUX: return "psq_lux"; - case PPC_ID_PSQ_LX: return "psq_lx"; - case PPC_ID_PSQ_ST: return "psq_st"; - case PPC_ID_PSQ_STU: return "psq_stu"; - case PPC_ID_PSQ_STUX: return "psq_stux"; - case PPC_ID_PSQ_STX: return "psq_stx"; + case PPC_ID_PAIREDSINGLE_DCBZ_L: return "dcbz_l"; + case PPC_ID_PAIREDSINGLE_PS_ABSx: return RcMnemonic(instruction, SubMnemPS_ABSx); + case PPC_ID_PAIREDSINGLE_PS_ADDx: return RcMnemonic(instruction, SubMnemPS_ADDx); + case PPC_ID_PAIREDSINGLE_PS_CMPO0: return "ps_cmpo0"; + case PPC_ID_PAIREDSINGLE_PS_CMPO1: return "ps_cmpo1"; + case PPC_ID_PAIREDSINGLE_PS_CMPU0: return "ps_cmpu0"; + case PPC_ID_PAIREDSINGLE_PS_CMPU1: return "ps_cmpu1"; + case PPC_ID_PAIREDSINGLE_PS_DIVx: return RcMnemonic(instruction, SubMnemPS_DIVx); + case PPC_ID_PAIREDSINGLE_PS_MADDx: return RcMnemonic(instruction, SubMnemPS_MADDx); + case PPC_ID_PAIREDSINGLE_PS_MADDS0x: return RcMnemonic(instruction, SubMnemPS_MADDS0x); + case PPC_ID_PAIREDSINGLE_PS_MADDS1x: return RcMnemonic(instruction, SubMnemPS_MADDS1x); + case PPC_ID_PAIREDSINGLE_PS_MERGE00x: return RcMnemonic(instruction, SubMnemPS_MERGE00x); + case PPC_ID_PAIREDSINGLE_PS_MERGE01x: return RcMnemonic(instruction, SubMnemPS_MERGE01x); + case PPC_ID_PAIREDSINGLE_PS_MERGE10x: return RcMnemonic(instruction, SubMnemPS_MERGE10x); + case PPC_ID_PAIREDSINGLE_PS_MERGE11x: return RcMnemonic(instruction, SubMnemPS_MERGE11x); + case PPC_ID_PAIREDSINGLE_PS_MRx: return RcMnemonic(instruction, SubMnemPS_MRx); + case PPC_ID_PAIREDSINGLE_PS_MSUBx: return RcMnemonic(instruction, SubMnemPS_MSUBx); + case PPC_ID_PAIREDSINGLE_PS_MULx: return RcMnemonic(instruction, SubMnemPS_MULx); + case PPC_ID_PAIREDSINGLE_PS_MULS0x: return RcMnemonic(instruction, SubMnemPS_MULS0x); + case PPC_ID_PAIREDSINGLE_PS_MULS1x: return RcMnemonic(instruction, SubMnemPS_MULS1x); + case PPC_ID_PAIREDSINGLE_PS_NABSx: return RcMnemonic(instruction, SubMnemPS_NABSx); + case PPC_ID_PAIREDSINGLE_PS_NEGx: return RcMnemonic(instruction, SubMnemPS_NEGx); + case PPC_ID_PAIREDSINGLE_PS_NMADDx: return RcMnemonic(instruction, SubMnemPS_NMADDx); + case PPC_ID_PAIREDSINGLE_PS_NMSUBx: return RcMnemonic(instruction, SubMnemPS_NMSUBx); + case PPC_ID_PAIREDSINGLE_PS_RESx: return RcMnemonic(instruction, SubMnemPS_RESx); + case PPC_ID_PAIREDSINGLE_PS_RSQRTEx: return RcMnemonic(instruction, SubMnemPS_RSQRTEx); + case PPC_ID_PAIREDSINGLE_PS_SELx: return RcMnemonic(instruction, SubMnemPS_SELx); + case PPC_ID_PAIREDSINGLE_PS_SUBx: return RcMnemonic(instruction, SubMnemPS_SUBx); + case PPC_ID_PAIREDSINGLE_PS_SUM0x: return RcMnemonic(instruction, SubMnemPS_SUM0x); + case PPC_ID_PAIREDSINGLE_PS_SUM1x: return RcMnemonic(instruction, SubMnemPS_SUM1x); + case PPC_ID_PAIREDSINGLE_PSQ_L: return "psq_l"; + case PPC_ID_PAIREDSINGLE_PSQ_LU: return "psq_lu"; + case PPC_ID_PAIREDSINGLE_PSQ_LUX: return "psq_lux"; + case PPC_ID_PAIREDSINGLE_PSQ_LX: return "psq_lx"; + case PPC_ID_PAIREDSINGLE_PSQ_ST: return "psq_st"; + case PPC_ID_PAIREDSINGLE_PSQ_STU: return "psq_stu"; + case PPC_ID_PAIREDSINGLE_PSQ_STUX: return "psq_stux"; + case PPC_ID_PAIREDSINGLE_PSQ_STX: return "psq_stx"; case PPC_ID_SPE_BRINC: return "brinc"; case PPC_ID_SPE_EFDABS: return "efdabs"; diff --git a/arch/powerpc/decode/operands.c b/arch/powerpc/decode/operands.c index bc3528778..dc6d22949 100644 --- a/arch/powerpc/decode/operands.c +++ b/arch/powerpc/decode/operands.c @@ -222,12 +222,17 @@ static void FillBranchLikelyHint(Instruction* instruction, uint32_t word32) } } -static void PushMemRA(Instruction* instruction, uint32_t word32) +static void PushMemRAOffset(Instruction* instruction, uint32_t word32, int32_t offset) { - int32_t offset = (int32_t)((int16_t)(word32 & 0xffff)); PushMem(instruction, PPC_OP_MEM_RA, Gpr(GetA(word32)), offset); } +// Default of d=lower 16 bits +static void PushMemRA(Instruction* instruction, uint32_t word32) +{ + PushMemRAOffset(instruction, word32, (int32_t)((int16_t)(word32 & 0xffff))); +} + static void PushVsxA(Instruction* instruction, uint32_t word32, VsxWidth width) { PushRegister(instruction, @@ -2939,6 +2944,139 @@ void FillOperands32(Instruction* instruction, uint32_t word32, uint64_t address) break; } + // PAIRED-SINGLE INSTRUCTIONS + + // op[.] frD, frA, frB + case PPC_ID_PAIREDSINGLE_PS_ADDx: + case PPC_ID_PAIREDSINGLE_PS_DIVx: + case PPC_ID_PAIREDSINGLE_PS_MERGE00x: + case PPC_ID_PAIREDSINGLE_PS_MERGE01x: + case PPC_ID_PAIREDSINGLE_PS_MERGE10x: + case PPC_ID_PAIREDSINGLE_PS_MERGE11x: + case PPC_ID_PAIREDSINGLE_PS_SUBx: + PushFRD(instruction, word32); + PushFRA(instruction, word32); + PushFRB(instruction, word32); + + instruction->flags.rc = word32 & 0x1; + break; + + // op[.] frD, frA, frC + case PPC_ID_PAIREDSINGLE_PS_MULx: + case PPC_ID_PAIREDSINGLE_PS_MULS0x: + case PPC_ID_PAIREDSINGLE_PS_MULS1x: + PushFRD(instruction, word32); + PushFRA(instruction, word32); + PushFRC(instruction, word32); + + instruction->flags.rc = word32 & 0x1; + break; + + // op[.] frD, frB + case PPC_ID_PAIREDSINGLE_PS_ABSx: + case PPC_ID_PAIREDSINGLE_PS_MRx: + case PPC_ID_PAIREDSINGLE_PS_NABSx: + case PPC_ID_PAIREDSINGLE_PS_NEGx: + case PPC_ID_PAIREDSINGLE_PS_RESx: + case PPC_ID_PAIREDSINGLE_PS_RSQRTEx: + PushFRD(instruction, word32); + PushFRB(instruction, word32); + + instruction->flags.rc = word32 & 0x1; + break; + + // op[.] frD, frA, frC, frB + // (take care not to use frD, frA, frB, frC) + case PPC_ID_PAIREDSINGLE_PS_MADDx: + case PPC_ID_PAIREDSINGLE_PS_MADDS0x: + case PPC_ID_PAIREDSINGLE_PS_MADDS1x: + case PPC_ID_PAIREDSINGLE_PS_MSUBx: + case PPC_ID_PAIREDSINGLE_PS_NMADDx: + case PPC_ID_PAIREDSINGLE_PS_NMSUBx: + case PPC_ID_PAIREDSINGLE_PS_SELx: + case PPC_ID_PAIREDSINGLE_PS_SUM0x: + case PPC_ID_PAIREDSINGLE_PS_SUM1x: + PushFRD(instruction, word32); + PushFRA(instruction, word32); + PushFRC(instruction, word32); + PushFRB(instruction, word32); + + instruction->flags.rc = word32 & 0x1; + break; + + // op crfD, frA, frB + case PPC_ID_PAIREDSINGLE_PS_CMPO0: + case PPC_ID_PAIREDSINGLE_PS_CMPO1: + case PPC_ID_PAIREDSINGLE_PS_CMPU0: + case PPC_ID_PAIREDSINGLE_PS_CMPU1: + PushCRFDImplyCR0(instruction, word32); + PushFRA(instruction, word32); + PushFRB(instruction, word32); + break; + + // load-stores + case PPC_ID_PAIREDSINGLE_PSQ_L: + case PPC_ID_PAIREDSINGLE_PSQ_LU: + { + uint32_t w = (word32 >> 15) & 0x1; + uint32_t i = (word32 >> 12) & 0x7; + uint32_t d = word32 & 0xfff; + + PushFRD(instruction, word32); + PushMemRAOffset(instruction, word32, sign_extend(d, 12)); + PushUIMMValue(instruction, w); + PushUIMMValue(instruction, i); + break; + } + + case PPC_ID_PAIREDSINGLE_PSQ_LUX: + case PPC_ID_PAIREDSINGLE_PSQ_LX: + { + uint32_t w = (word32 >> 10) & 0x1; + uint32_t i = (word32 >> 7) & 0x7; + + PushFRD(instruction, word32); + PushRA(instruction, word32); + PushRB(instruction, word32); + PushUIMMValue(instruction, w); + PushUIMMValue(instruction, i); + break; + } + + case PPC_ID_PAIREDSINGLE_PSQ_ST: + case PPC_ID_PAIREDSINGLE_PSQ_STU: + { + uint32_t w = (word32 >> 15) & 0x1; + uint32_t i = (word32 >> 12) & 0x7; + uint32_t d = word32 & 0xfff; + + PushFRS(instruction, word32); + PushMemRAOffset(instruction, word32, sign_extend(d, 12)); + PushUIMMValue(instruction, w); + PushUIMMValue(instruction, i); + break; + } + + case PPC_ID_PAIREDSINGLE_PSQ_STX: + case PPC_ID_PAIREDSINGLE_PSQ_STUX: + { + uint32_t w = (word32 >> 10) & 0x1; + uint32_t i = (word32 >> 7) & 0x7; + + PushFRS(instruction, word32); + PushRA(instruction, word32); + PushRB(instruction, word32); + PushUIMMValue(instruction, w); + PushUIMMValue(instruction, i); + break; + } + + // dcbz_l rA, rB + case PPC_ID_PAIREDSINGLE_DCBZ_L: + PushRAor0(instruction, word32); + PushRB(instruction, word32); + break; + default: break; } diff --git a/arch/powerpc/il.cpp b/arch/powerpc/il.cpp index 316a65f15..7bf741cf6 100644 --- a/arch/powerpc/il.cpp +++ b/arch/powerpc/il.cpp @@ -1974,7 +1974,7 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il, il.AddInstruction(ei0); break; - case PPC_ID_PSQ_ST: + case PPC_ID_PAIREDSINGLE_PSQ_ST: REQUIRE4OPS MYLOG("0x%08x psq_st args f%d r%d[%d] w:%lldd gcqr:%lld\n", (uint32_t)addr, oper0->reg - PPC_REG_F0, oper1->mem.base - PPC_REG_R0, oper1->mem.disp, oper2->imm, @@ -2012,7 +2012,7 @@ bool GetLowLevelILForPPCInstruction(Architecture *arch, LowLevelILFunction &il, // } break; - case PPC_ID_PSQ_L: + case PPC_ID_PAIREDSINGLE_PSQ_L: REQUIRE4OPS // w_l = oper2->imm;