@@ -358,7 +358,7 @@ class PowerpcArchitecture: public Architecture
358358 return false ;
359359 }
360360
361- if (DoesQualifyForLocalDisassembly (data)) {
361+ if (DoesQualifyForLocalDisassembly (data, endian == BigEndian )) {
362362 result.length = 4 ;
363363 return true ;
364364 }
@@ -457,149 +457,56 @@ class PowerpcArchitecture: public Architecture
457457 return true ;
458458 }
459459
460- bool DoesQualifyForLocalDisassembly (const uint8_t *data)
461- {
462- uint32_t insword = *(uint32_t *)data;
463- if (endian == BigEndian)
464- insword = bswap32 (insword);
465-
466- // 111111xxx00xxxxxxxxxx00001000000 <- fcmpo
467- uint32_t tmp = insword & 0xFC6007FF ;
468- if (tmp==0xFC000040 )
469- return true ;
470- // 111100xxxxxxxxxxxxxxx00111010xxx <- xxpermr
471- if ((insword & 0xFC0007F8 ) == 0xF00001D0 )
472- return true ;
473- // 000100xxxxxxxxxxxxxxxxxxx000110x <- psq_lx
474- // 000100xxxxxxxxxxxxxxxxxxx000111x <- psq_stx
475- // 000100xxxxxxxxxxxxxxxxxxx100110x <- psq_lux
476- // 000100xxxxxxxxxxxxxxxxxxx100111x <- psq_stux
477- tmp = insword & 0xFC00007E ;
478- if (tmp==0x1000000C || tmp==0x1000000E || tmp==0x1000004C || tmp==0x1000004E )
479- return true ;
480- // 000100xxxxxxxxxx00000xxxxx011000 <- ps_muls0
481- // 000100xxxxxxxxxx00000xxxxx011001 <- ps_muls0.
482- // 000100xxxxxxxxxx00000xxxxx011010 <- ps_muls1
483- // 000100xxxxxxxxxx00000xxxxx011011 <- ps_muls1.
484- tmp = insword & 0xFC00F83F ;
485- if (tmp==0x10000018 || tmp==0x10000019 || tmp==0x1000001A || tmp==0x1000001B )
486- return true ;
487-
488- return false ;
489- }
490-
491- bool PerformLocalDisassembly (const uint8_t *data, uint64_t addr, size_t &len, vector<InstructionTextToken> &result)
460+ bool PrintLocalDisassembly (const uint8_t *data, uint64_t addr, size_t &len, vector<InstructionTextToken> &result, decomp_result* res)
492461 {
493462 (void )addr;
463+ char buf[16 ];
464+ uint32_t local_op = PPC_INS_INVALID;
494465
495- if (len < 4 ) return false ;
496- uint32_t insword = *(uint32_t *)data;
497- if (endian == BigEndian)
498- insword = bswap32 (insword);
466+ struct cs_detail *detail = 0 ;
467+ struct cs_ppc *ppc = 0 ;
468+ struct cs_insn *insn = &(res->insn );
469+
470+ detail = &(res->detail );
471+ ppc = &(detail->ppc );
499472
473+ if (len < 4 )
474+ return false ;
500475 len = 4 ;
501476
502- char buf[16 ];
477+ local_op = DoesQualifyForLocalDisassembly (data, endian == BigEndian);
478+ PerformLocalDisassembly (data, addr, len, res, endian == BigEndian);
503479
504- // 111111AAA00BBBBBCCCCC00001000000 "fcmpo crA,fB,fC"
505- uint32_t tmp = insword & 0xFC6007FF ;
506- if (tmp== 0xFC000040 ) {
507- result.emplace_back (InstructionToken, " fcmpo " );
480+ switch (local_op)
481+ {
482+ case PPC_INS_BN_FCMPO:
483+ result.emplace_back (InstructionToken, insn-> mnemonic );
508484 result.emplace_back (TextToken, " " );
509- snprintf (buf, sizeof (buf), " cr%d" , (insword >> 23 ) & 7 );
485+ snprintf (buf, sizeof (buf), " cr%d" , ppc-> operands [ 0 ]. reg );
510486 result.emplace_back (RegisterToken, buf);
511487 result.emplace_back (OperandSeparatorToken, " , " );
512- snprintf (buf, sizeof (buf), " f%d" , (insword >> 16 ) & 31 );
488+ snprintf (buf, sizeof (buf), " f%d" , ppc-> operands [ 1 ]. reg );
513489 result.emplace_back (RegisterToken, buf);
514490 result.emplace_back (OperandSeparatorToken, " , " );
515- snprintf (buf, sizeof (buf), " f%d" , (insword >> 11 ) & 31 );
516- result.emplace_back (RegisterToken, buf);
517- return true ;
518- }
519-
520- // 111100AAAAABBBBBCCCCC00011010BCA "xxpermr vsA,vsB,vsC"
521- if ((insword & 0xFC0007F8 )==0xF00001D0 ) {
522- int a = ((insword & 0x3E00000 )>>21 )|((insword & 0x1 )<<5 );
523- int b = ((insword & 0x1F0000 )>>16 )|((insword & 0x4 )<<3 );
524- int c = ((insword & 0xF800 )>>11 )|((insword & 0x2 )<<4 );
525- result.emplace_back (InstructionToken, " xxpermr" );
526- result.emplace_back (TextToken, " " );
527- snprintf (buf, sizeof (buf), " vs%d" , a);
491+ snprintf (buf, sizeof (buf), " f%d" , ppc->operands [2 ].reg );
528492 result.emplace_back (RegisterToken, buf);
529- result.emplace_back (OperandSeparatorToken, " , " );
530- snprintf (buf, sizeof (buf), " vs%d" , b);
531- result.emplace_back (RegisterToken, buf);
532- result.emplace_back (OperandSeparatorToken, " , " );
533- snprintf (buf, sizeof (buf), " vs%d" , c);
534- result.emplace_back (RegisterToken, buf);
535- return true ;
536- }
537-
538- // 000100AAAAABBBBBCCCCCDEEE000110x psq_lx FREG,GPR,GPR,NUM,NUM
539- // 000100AAAAABBBBBCCCCCDEEE000111x psq_stx FREG,GPR,GPR,NUM,NUM
540- // 000100AAAAABBBBBCCCCCDEEE100110x psq_lux FREG,GPR,GPR,NUM,NUM
541- // 000100AAAAABBBBBCCCCCDEEE100111x psq_stux FREG,GPR,GPR,NUM,NUM
542- tmp = insword & 0xFC00007E ;
543- if (tmp==0x1000000C || tmp==0x1000000E || tmp==0x1000004C || tmp==0x1000004E ) {
544- switch (tmp) {
545- case 0x1000000C :
546- result.emplace_back (InstructionToken, " psq_lx" );
547- result.emplace_back (TextToken, " " );
548- break ;
549- case 0x1000000E : result.emplace_back (InstructionToken, " psq_stx" );
550- result.emplace_back (TextToken, " " );
551- break ;
552- case 0x1000004C : result.emplace_back (InstructionToken, " psq_lux" );
553- result.emplace_back (TextToken, " " );
554- break ;
555- case 0x1000004E : result.emplace_back (InstructionToken, " psq_stux" );
556- result.emplace_back (TextToken, " " );
557- break ;
558- }
559- snprintf (buf, sizeof (buf), " f%d" , (insword & 0x3E00000 ) >> 21 );
560- result.emplace_back (RegisterToken, buf);
561- result.emplace_back (OperandSeparatorToken, " , " );
562- snprintf (buf, sizeof (buf), " r%d" , (insword & 0x1F0000 ) >> 16 );
563- result.emplace_back (RegisterToken, buf);
564- result.emplace_back (OperandSeparatorToken, " , " );
565- snprintf (buf, sizeof (buf), " r%d" , (insword & 0xF800 ) >> 11 );
566- result.emplace_back (RegisterToken, buf);
567- result.emplace_back (OperandSeparatorToken, " , " );
568- tmp = (insword & 0x400 )>>10 ;
569- snprintf (buf, sizeof (buf), " %d" , tmp);
570- result.emplace_back (IntegerToken, buf, tmp, 1 );
571- result.emplace_back (OperandSeparatorToken, " , " );
572- tmp = (insword & 0x380 )>>7 ;
573- snprintf (buf, sizeof (buf), " %d" , tmp);
574- result.emplace_back (IntegerToken, buf, tmp, 1 );
575- return true ;
576- }
577-
578- // 000100AAAAABBBBB00000CCCCC011000 ps_muls0 FREG,FREG,FREG
579- // 000100AAAAABBBBB00000CCCCC011001 ps_muls0. FREG,FREG,FREG
580- // 000100AAAAABBBBB00000CCCCC011010 ps_muls1 FREG,FREG,FREG
581- // 000100AAAAABBBBB00000CCCCC011011 ps_muls1. FREG,FREG,FREG
582- tmp = insword & 0xFC00F83F ;
583- if (tmp==0x10000018 || tmp==0x10000019 || tmp==0x1000001A || tmp==0x1000001B ) {
584- switch (tmp) {
585- case 0x10000018 : result.emplace_back (InstructionToken, " ps_muls0" ); break ;
586- case 0x10000019 : result.emplace_back (InstructionToken, " ps_muls0." ); break ;
587- case 0x1000001A : result.emplace_back (InstructionToken, " ps_muls1" ); break ;
588- case 0x1000001B : result.emplace_back (InstructionToken, " ps_muls1." ); break ;
589- }
493+ break ;
494+ case PPC_INS_BN_XXPERMR:
495+ result.emplace_back (InstructionToken, insn->mnemonic );
590496 result.emplace_back (TextToken, " " );
591- snprintf (buf, sizeof (buf), " f %d" , (insword & 0x3E00000 ) >> 21 );
497+ snprintf (buf, sizeof (buf), " vs %d" , ppc-> operands [ 0 ]. reg );
592498 result.emplace_back (RegisterToken, buf);
593499 result.emplace_back (OperandSeparatorToken, " , " );
594- snprintf (buf, sizeof (buf), " f %d" , (insword & 0x1F0000 ) >> 16 );
500+ snprintf (buf, sizeof (buf), " vs %d" , ppc-> operands [ 1 ]. reg );
595501 result.emplace_back (RegisterToken, buf);
596502 result.emplace_back (OperandSeparatorToken, " , " );
597- snprintf (buf, sizeof (buf), " f %d" , (insword & 0x7C0 ) >> 6 );
503+ snprintf (buf, sizeof (buf), " vs %d" , ppc-> operands [ 2 ]. reg );
598504 result.emplace_back (RegisterToken, buf);
599- return true ;
505+ break ;
506+ default :
507+ return false ;
600508 }
601-
602- return false ;
509+ return true ;
603510 }
604511
605512 /* populate the vector result with InstructionTextToken
@@ -623,9 +530,9 @@ class PowerpcArchitecture: public Architecture
623530 goto cleanup;
624531 }
625532
626- if (DoesQualifyForLocalDisassembly (data))
627- return PerformLocalDisassembly (data, addr, len, result );
628-
533+ if (DoesQualifyForLocalDisassembly (data, endian == BigEndian ))
534+ // PerformLocalDisassembly(data, addr, len, &res, endian == BigEndian );
535+ return PrintLocalDisassembly (data, addr, len, result, &res);
629536 if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 , cs_mode_local)) {
630537 MYLOG (" ERROR: powerpc_decompose()\n " );
631538 goto cleanup;
@@ -733,6 +640,7 @@ class PowerpcArchitecture: public Architecture
733640 virtual bool GetInstructionLowLevelIL (const uint8_t * data, uint64_t addr, size_t & len, LowLevelILFunction& il) override
734641 {
735642 bool rc = false ;
643+ struct decomp_result res = {0 };
736644
737645 if (len < 4 ) {
738646 MYLOG (" ERROR: need at least 4 bytes\n " );
@@ -743,21 +651,16 @@ class PowerpcArchitecture: public Architecture
743651 // MYLOG("%s(data, 0x%llX, 0x%zX, il)\n", __func__, addr, len);
744652 // }
745653
746- struct decomp_result res;
747-
748- if (DoesQualifyForLocalDisassembly (data)) {
749- il.AddInstruction (il.Unimplemented ());
750- rc = true ;
751- len = 4 ;
752- goto cleanup;
654+ if (DoesQualifyForLocalDisassembly (data, endian == BigEndian)) {
655+ PerformLocalDisassembly (data, addr, len, &res, endian == BigEndian);
753656 }
754-
755- if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 , cs_mode_local)) {
657+ else if (powerpc_decompose (data, 4 , (uint32_t )addr, endian == LittleEndian, &res, GetAddressSize () == 8 , cs_mode_local)) {
756658 MYLOG (" ERROR: powerpc_decompose()\n " );
757659 il.AddInstruction (il.Undefined ());
758660 goto cleanup;
759661 }
760662
663+ getil:
761664 rc = GetLowLevelILForPPCInstruction (this , il, data, addr, &res, endian == LittleEndian);
762665 len = 4 ;
763666
0 commit comments