mirror of
				https://github.com/yuzu-emu/yuzu.git
				synced 2025-11-04 08:53:43 +00:00 
			
		
		
		
	arm_disasm: ARMv6 mul/div and abs media instructions
SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD, SMMLA, SMMUL, SMMLS USAD8, USADA8
This commit is contained in:
		
							parent
							
								
									4a1db13072
								
							
						
					
					
						commit
						38c87733d9
					
				@ -92,8 +92,17 @@ static const char *opcode_names[] = {
 | 
			
		||||
    "shsax",
 | 
			
		||||
    "shsub16",
 | 
			
		||||
    "shsub8",
 | 
			
		||||
    "smlad",
 | 
			
		||||
    "smlal",
 | 
			
		||||
    "smlald",
 | 
			
		||||
    "smlsd",
 | 
			
		||||
    "smlsld",
 | 
			
		||||
    "smmla",
 | 
			
		||||
    "smmls",
 | 
			
		||||
    "smmul",
 | 
			
		||||
    "smuad",
 | 
			
		||||
    "smull",
 | 
			
		||||
    "smusd",
 | 
			
		||||
    "ssat",
 | 
			
		||||
    "ssat16",
 | 
			
		||||
    "ssax",
 | 
			
		||||
@ -139,6 +148,8 @@ static const char *opcode_names[] = {
 | 
			
		||||
    "uqsax",
 | 
			
		||||
    "uqsub16",
 | 
			
		||||
    "uqsub8",
 | 
			
		||||
    "usad8",
 | 
			
		||||
    "usada8",
 | 
			
		||||
    "usat",
 | 
			
		||||
    "usat16",
 | 
			
		||||
    "usax",
 | 
			
		||||
@ -341,6 +352,18 @@ std::string ARM_Disasm::Disassemble(uint32_t addr, uint32_t insn)
 | 
			
		||||
            return DisassembleREV(opcode, insn);
 | 
			
		||||
        case OP_SEL:
 | 
			
		||||
            return DisassembleSEL(insn);
 | 
			
		||||
        case OP_SMLAD:
 | 
			
		||||
        case OP_SMLALD:
 | 
			
		||||
        case OP_SMLSD:
 | 
			
		||||
        case OP_SMLSLD:
 | 
			
		||||
        case OP_SMMLA:
 | 
			
		||||
        case OP_SMMLS:
 | 
			
		||||
        case OP_SMMUL:
 | 
			
		||||
        case OP_SMUAD:
 | 
			
		||||
        case OP_SMUSD:
 | 
			
		||||
        case OP_USAD8:
 | 
			
		||||
        case OP_USADA8:
 | 
			
		||||
            return DisassembleMediaMulDiv(opcode, insn);
 | 
			
		||||
        case OP_SSAT:
 | 
			
		||||
        case OP_SSAT16:
 | 
			
		||||
        case OP_USAT:
 | 
			
		||||
@ -503,6 +526,38 @@ std::string ARM_Disasm::DisassembleCLZ(uint32_t insn)
 | 
			
		||||
    return Common::StringFromFormat("clz%s\tr%d, r%d", cond_to_str(cond), rd, rm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ARM_Disasm::DisassembleMediaMulDiv(Opcode opcode, uint32_t insn) {
 | 
			
		||||
    uint32_t cond = BITS(insn, 28, 31);
 | 
			
		||||
    uint32_t rd = BITS(insn, 16, 19);
 | 
			
		||||
    uint32_t ra = BITS(insn, 12, 15);
 | 
			
		||||
    uint32_t rm = BITS(insn, 8, 11);
 | 
			
		||||
    uint32_t m = BIT(insn, 5);
 | 
			
		||||
    uint32_t rn = BITS(insn, 0, 3);
 | 
			
		||||
 | 
			
		||||
    std::string cross = "";
 | 
			
		||||
    if (m) {
 | 
			
		||||
        if (opcode == OP_SMMLA || opcode == OP_SMMUL || opcode == OP_SMMLS)
 | 
			
		||||
            cross = "r";
 | 
			
		||||
        else
 | 
			
		||||
            cross = "x";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string ext_reg = "";
 | 
			
		||||
    std::unordered_set<Opcode, std::hash<int>> with_ext_reg = {
 | 
			
		||||
            OP_SMLAD, OP_SMLSD, OP_SMMLA, OP_SMMLS, OP_USADA8
 | 
			
		||||
    };
 | 
			
		||||
    if (with_ext_reg.find(opcode) != with_ext_reg.end())
 | 
			
		||||
        ext_reg = Common::StringFromFormat(", r%u", ra);
 | 
			
		||||
 | 
			
		||||
    std::string rd_low = "";
 | 
			
		||||
    if (opcode == OP_SMLALD || opcode == OP_SMLSLD)
 | 
			
		||||
        rd_low = Common::StringFromFormat("r%u, ", ra);
 | 
			
		||||
 | 
			
		||||
    return Common::StringFromFormat("%s%s%s\t%sr%u, r%u, r%u%s", opcode_names[opcode],
 | 
			
		||||
                                    cross.c_str(), cond_to_str(cond), rd_low.c_str(), rd, rn, rm,
 | 
			
		||||
                                    ext_reg.c_str());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ARM_Disasm::DisassembleMemblock(Opcode opcode, uint32_t insn)
 | 
			
		||||
{
 | 
			
		||||
    std::string tmp_list;
 | 
			
		||||
@ -1339,11 +1394,52 @@ Opcode ARM_Disasm::DecodeMSRImmAndHints(uint32_t insn) {
 | 
			
		||||
    return OP_MSR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Opcode ARM_Disasm::DecodeMediaMulDiv(uint32_t insn) {
 | 
			
		||||
    uint32_t op1 = BITS(insn, 20, 22);
 | 
			
		||||
    uint32_t op2_h = BITS(insn, 6, 7);
 | 
			
		||||
    uint32_t a = BITS(insn, 12, 15);
 | 
			
		||||
 | 
			
		||||
    switch (op1) {
 | 
			
		||||
        case 0x0:
 | 
			
		||||
            if (op2_h == 0x0) {
 | 
			
		||||
                if (a != 0xf)
 | 
			
		||||
                    return OP_SMLAD;
 | 
			
		||||
                else
 | 
			
		||||
                    return OP_SMUAD;
 | 
			
		||||
            } else if (op2_h == 0x1) {
 | 
			
		||||
                if (a != 0xf)
 | 
			
		||||
                    return OP_SMLSD;
 | 
			
		||||
                else
 | 
			
		||||
                    return OP_SMUSD;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case 0x4:
 | 
			
		||||
            if (op2_h == 0x0)
 | 
			
		||||
                return OP_SMLALD;
 | 
			
		||||
            else if (op2_h == 0x1)
 | 
			
		||||
                return OP_SMLSLD;
 | 
			
		||||
            break;
 | 
			
		||||
        case 0x5:
 | 
			
		||||
            if (op2_h == 0x0) {
 | 
			
		||||
                if (a != 0xf)
 | 
			
		||||
                    return OP_SMMLA;
 | 
			
		||||
                else
 | 
			
		||||
                    return OP_SMMUL;
 | 
			
		||||
            } else if (op2_h == 0x3) {
 | 
			
		||||
                return OP_SMMLS;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return OP_UNDEFINED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Opcode ARM_Disasm::DecodeMedia(uint32_t insn) {
 | 
			
		||||
    uint32_t op1 = BITS(insn, 20, 24);
 | 
			
		||||
    uint32_t rd = BITS(insn, 12, 15);
 | 
			
		||||
    uint32_t op2 = BITS(insn, 5, 7);
 | 
			
		||||
    uint32_t rn = BITS(insn, 0, 3);
 | 
			
		||||
 | 
			
		||||
    switch (BITS(op1, 3, 4)) {
 | 
			
		||||
        case 0x0:
 | 
			
		||||
@ -1352,6 +1448,15 @@ Opcode ARM_Disasm::DecodeMedia(uint32_t insn) {
 | 
			
		||||
        case 0x1:
 | 
			
		||||
            // Packing, unpacking, saturation, and reversal
 | 
			
		||||
            return DecodePackingSaturationReversal(insn);
 | 
			
		||||
        case 0x2:
 | 
			
		||||
            // Signed multiply, signed and unsigned divide
 | 
			
		||||
            return DecodeMediaMulDiv(insn);
 | 
			
		||||
        case 0x3:
 | 
			
		||||
            if (op2 == 0 && rd == 0xf)
 | 
			
		||||
                return OP_USAD8;
 | 
			
		||||
            if (op2 == 0 && rd != 0xf)
 | 
			
		||||
                return OP_USADA8;
 | 
			
		||||
            break;
 | 
			
		||||
        default:
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -73,8 +73,17 @@ enum Opcode {
 | 
			
		||||
    OP_SHSAX,
 | 
			
		||||
    OP_SHSUB16,
 | 
			
		||||
    OP_SHSUB8,
 | 
			
		||||
    OP_SMLAD,
 | 
			
		||||
    OP_SMLAL,
 | 
			
		||||
    OP_SMLALD,
 | 
			
		||||
    OP_SMLSD,
 | 
			
		||||
    OP_SMLSLD,
 | 
			
		||||
    OP_SMMLA,
 | 
			
		||||
    OP_SMMLS,
 | 
			
		||||
    OP_SMMUL,
 | 
			
		||||
    OP_SMUAD,
 | 
			
		||||
    OP_SMULL,
 | 
			
		||||
    OP_SMUSD,
 | 
			
		||||
    OP_SSAT,
 | 
			
		||||
    OP_SSAT16,
 | 
			
		||||
    OP_SSAX,
 | 
			
		||||
@ -120,6 +129,8 @@ enum Opcode {
 | 
			
		||||
    OP_UQSAX,
 | 
			
		||||
    OP_UQSUB16,
 | 
			
		||||
    OP_UQSUB8,
 | 
			
		||||
    OP_USAD8,
 | 
			
		||||
    OP_USADA8,
 | 
			
		||||
    OP_USAT,
 | 
			
		||||
    OP_USAT16,
 | 
			
		||||
    OP_USAX,
 | 
			
		||||
@ -193,6 +204,7 @@ class ARM_Disasm {
 | 
			
		||||
  static Opcode DecodePackingSaturationReversal(uint32_t insn);
 | 
			
		||||
  static Opcode DecodeMUL(uint32_t insn);
 | 
			
		||||
  static Opcode DecodeMSRImmAndHints(uint32_t insn);
 | 
			
		||||
  static Opcode DecodeMediaMulDiv(uint32_t insn);
 | 
			
		||||
  static Opcode DecodeMedia(uint32_t insn);
 | 
			
		||||
  static Opcode DecodeLDRH(uint32_t insn);
 | 
			
		||||
  static Opcode DecodeALU(uint32_t insn);
 | 
			
		||||
@ -202,6 +214,7 @@ class ARM_Disasm {
 | 
			
		||||
  static std::string DisassembleBX(uint32_t insn);
 | 
			
		||||
  static std::string DisassembleBKPT(uint32_t insn);
 | 
			
		||||
  static std::string DisassembleCLZ(uint32_t insn);
 | 
			
		||||
  static std::string DisassembleMediaMulDiv(Opcode opcode, uint32_t insn);
 | 
			
		||||
  static std::string DisassembleMemblock(Opcode opcode, uint32_t insn);
 | 
			
		||||
  static std::string DisassembleMem(uint32_t insn);
 | 
			
		||||
  static std::string DisassembleMemHalf(uint32_t insn);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user