From 9099567d909f80bc4aeaecf6201c0d61fb8b9ff1 Mon Sep 17 00:00:00 2001 From: Bastian Koppelmann Date: Wed, 26 Jul 2023 06:47:05 +0000 Subject: [PATCH] Fixing TriCore disasm instructions (#2088) --- arch/TriCore/TriCoreDisassembler.c | 121 +++++++++++++++++++++++------ arch/TriCore/TriCoreInstPrinter.c | 16 ++++ suite/MC/TriCore/csfr.s.cs | 3 + suite/MC/TriCore/extr_u.s.cs | 3 + suite/MC/TriCore/ldst_br_circ.s.cs | 47 +++++++++++ suite/MC/TriCore/rr_insn.s.cs | 6 ++ 6 files changed, 174 insertions(+), 22 deletions(-) create mode 100644 suite/MC/TriCore/csfr.s.cs create mode 100644 suite/MC/TriCore/extr_u.s.cs create mode 100644 suite/MC/TriCore/ldst_br_circ.s.cs create mode 100644 suite/MC/TriCore/rr_insn.s.cs diff --git a/arch/TriCore/TriCoreDisassembler.c b/arch/TriCore/TriCoreDisassembler.c index 408f516c59..40aad5e684 100644 --- a/arch/TriCore/TriCoreDisassembler.c +++ b/arch/TriCore/TriCoreDisassembler.c @@ -425,6 +425,7 @@ static DecodeStatus DecodeBOInstruction(MCInst *Inst, unsigned Insn, unsigned off10_0 = fieldFromInstruction_4(Insn, 16, 6); unsigned off10_1 = fieldFromInstruction_4(Insn, 28, 4); unsigned off10 = (off10_0 << 0) | (off10_1 << 6); + bool is_store = false; unsigned s2 = fieldFromInstruction_4(Insn, 12, 4); unsigned s1_d = fieldFromInstruction_4(Insn, 8, 4); @@ -440,32 +441,83 @@ static DecodeStatus DecodeBOInstruction(MCInst *Inst, unsigned Insn, return DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], Decoder); } - if (desc->NumOperands == 2) { - status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], - Decoder); - if (status != MCDisassembler_Success) - return status; + switch (MCInst_getOpcode(Inst)) { + case TRICORE_ST_A_bo_r: + case TRICORE_ST_A_bo_c: + case TRICORE_ST_B_bo_r: + case TRICORE_ST_B_bo_c: + case TRICORE_ST_D_bo_r: + case TRICORE_ST_D_bo_c: + case TRICORE_ST_DA_bo_r: + case TRICORE_ST_DA_bo_c: + case TRICORE_ST_H_bo_r: + case TRICORE_ST_H_bo_c: + case TRICORE_ST_Q_bo_r: + case TRICORE_ST_Q_bo_c: + case TRICORE_ST_W_bo_r: + case TRICORE_ST_W_bo_c: + case TRICORE_SWAP_W_bo_r: + case TRICORE_SWAP_W_bo_c: + case TRICORE_SWAPMSK_W_bo_c: + case TRICORE_SWAPMSK_W_bo_r: { + is_store = true; + break; + } + } + if (desc->NumOperands == 2) { if (desc->OpInfo[1].OperandType == MCOI_OPERAND_REGISTER) { - return DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[1], - Decoder); + // we have [reg+r] instruction + if (is_store) { + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; + return DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[1], + Decoder); + } else { + status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; + return DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], + Decoder); + } } else { + // we have one of the CACHE instructions without destination reg + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; + MCOperand_CreateImm0(Inst, off10); } return MCDisassembler_Success; } if (desc->NumOperands > 2) { - status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[0], - Decoder); - if (status != MCDisassembler_Success) - return status; + if (is_store) { + // we have [reg+c] instruction + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; - status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], - Decoder); - if (status != MCDisassembler_Success) - return status; + status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[1], + Decoder); + if (status != MCDisassembler_Success) + return status; + } else { + status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[0], + Decoder); + if (status != MCDisassembler_Success) + return status; + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], + Decoder); + if (status != MCDisassembler_Success) + return status; + } MCOperand_CreateImm0(Inst, off10); } @@ -649,8 +701,13 @@ static DecodeStatus DecodeRLCInstruction(MCInst *Inst, unsigned Insn, MCOperand_CreateImm0(Inst, const16); } else { MCOperand_CreateImm0(Inst, const16); - status = - DecodeRegisterClass(Inst, d, &desc->OpInfo[1], Decoder); + if (MCInst_getOpcode(Inst) == TRICORE_MTCR_rlc) { + status = + DecodeRegisterClass(Inst, s1, &desc->OpInfo[1], Decoder); + } else { + status = + DecodeRegisterClass(Inst, d, &desc->OpInfo[1], Decoder); + } if (status != MCDisassembler_Success) return status; } @@ -699,10 +756,24 @@ static DecodeStatus DecodeRRInstruction(MCInst *Inst, unsigned Insn, } if (desc->NumOperands > 1) { - status = DecodeRegisterClass(Inst, s1, &desc->OpInfo[1], - Decoder); - if (status != MCDisassembler_Success) - return status; + if (desc->OpInfo[0].OperandType == MCOI_OPERAND_REGISTER) { + switch (MCInst_getOpcode(Inst)) { + case TRICORE_ABSS_rr: + case TRICORE_ABSS_H_rr: + case TRICORE_ABS_H_rr: + case TRICORE_ABS_B_rr: + case TRICORE_ABS_rr: { + status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], + Decoder); + break; + default: + status = DecodeRegisterClass(Inst, s1, &desc->OpInfo[1], + Decoder); + } + if (status != MCDisassembler_Success) + return status; + } + } } if (desc->NumOperands > 2) { @@ -1259,7 +1330,13 @@ static DecodeStatus DecodeRRRRInstruction(MCInst *Inst, unsigned Insn, return status; if (desc->NumOperands == 3) { - return DecodeRegisterClass(Inst, s2, &desc->OpInfo[2], Decoder); + switch (MCInst_getOpcode(Inst)) { + case TRICORE_EXTR_rrrr: + case TRICORE_EXTR_U_rrrr: + return DecodeRegisterClass(Inst, s3, &desc->OpInfo[2], Decoder); + default: + return DecodeRegisterClass(Inst, s2, &desc->OpInfo[2], Decoder); + } } // Decode s2. diff --git a/arch/TriCore/TriCoreInstPrinter.c b/arch/TriCore/TriCoreInstPrinter.c index a15b962df6..679ca709c1 100644 --- a/arch/TriCore/TriCoreInstPrinter.c +++ b/arch/TriCore/TriCoreInstPrinter.c @@ -225,6 +225,19 @@ static void off4_fixup(MCInst *MI, uint64_t *off4) } } +static void const8_fixup(MCInst *MI, uint64_t *const8) +{ + switch (MCInst_getOpcode(MI)) { + case TRICORE_LD_A_sc: + case TRICORE_ST_A_sc: + case TRICORE_ST_W_sc: + case TRICORE_LD_W_sc: { + *const8 *= 4; + break; + } + } +} + static void print_zero_ext(MCInst *MI, int OpNum, SStream *O, unsigned n) { MCOperand *MO = MCInst_getOperand(MI, OpNum); @@ -236,6 +249,9 @@ static void print_zero_ext(MCInst *MI, int OpNum, SStream *O, unsigned n) if (n == 4) { off4_fixup(MI, &imm); } + if (n == 8) { + const8_fixup(MI, &imm); + } printInt64Bang(O, imm); fill_imm(MI, imm); diff --git a/suite/MC/TriCore/csfr.s.cs b/suite/MC/TriCore/csfr.s.cs new file mode 100644 index 0000000000..fc0db30274 --- /dev/null +++ b/suite/MC/TriCore/csfr.s.cs @@ -0,0 +1,3 @@ +# CS_ARCH_TRICORE, CS_MODE_TRICORE_131, None +0xcd, 0x41, 0xe0, 0x0f = mtcr #-0x1fc, d1 +0x4d, 0x40, 0xe0, 0x2f = mfcr d2, #0xfe04 diff --git a/suite/MC/TriCore/extr_u.s.cs b/suite/MC/TriCore/extr_u.s.cs new file mode 100644 index 0000000000..907a5e4ed1 --- /dev/null +++ b/suite/MC/TriCore/extr_u.s.cs @@ -0,0 +1,3 @@ +# CS_ARCH_TRICORE, CS_MODE_TRICORE_131, None +0x17, 0x01, 0x40, 0x02 = extr d0, d1, e2 +0x17, 0x01, 0x60, 0x02 = extr.u d0, d1, e2 diff --git a/suite/MC/TriCore/ldst_br_circ.s.cs b/suite/MC/TriCore/ldst_br_circ.s.cs new file mode 100644 index 0000000000..0bc85fb8fa --- /dev/null +++ b/suite/MC/TriCore/ldst_br_circ.s.cs @@ -0,0 +1,47 @@ +# CS_ARCH_TRICORE, CS_MODE_TRICORE_162, None +0xa9, 0x00, 0x80, 0x03 = cachea.i [p0+r] +0xa9, 0x00, 0x8a, 0x07 = cachea.i [p0+c]#0xa +0xa9, 0x00, 0x00, 0x03 = cachea.w [p0+r] +0xa9, 0x00, 0x0a, 0x07 = cachea.w [p0+c]#0xa +0xa9, 0x00, 0x40, 0x03 = cachea.wi [p0+r] +0xa9, 0x00, 0x4a, 0x07 = cachea.wi [p0+c]#0xa +0x69, 0x02, 0xc0, 0x00 = cmpswap.w [p0+r], e2 +0x69, 0x02, 0xca, 0x04 = cmpswap.w [p0+c]#0xa, e2 +0x29, 0x02, 0x80, 0x01 = ld.a a2, [p0+r] +0x29, 0x02, 0x8a, 0x05 = ld.a a2, [p0+c]#0xa +0x29, 0x02, 0x00, 0x00 = ld.b d2, [p0+r] +0x29, 0x02, 0x0a, 0x04 = ld.b d2, [p0+c]#0xa +0x29, 0x02, 0x40, 0x00 = ld.bu d2, [p0+r] +0x29, 0x02, 0x4a, 0x04 = ld.bu d2, [p0+c]#0xa +0x29, 0x02, 0x40, 0x01 = ld.d e2, [p0+r] +0x29, 0x02, 0x4a, 0x05 = ld.d e2, [p0+c]#0xa +0x29, 0x02, 0xc0, 0x01 = ld.da p2, [p0+r] +0x29, 0x02, 0xca, 0x05 = ld.da p2, [p0+c]#0xa +0x29, 0x02, 0x80, 0x00 = ld.h d2, [p0+r] +0x29, 0x02, 0x8a, 0x04 = ld.h d2, [p0+c]#0xa +0x29, 0x02, 0xc0, 0x00 = ld.hu d2, [p0+r] +0x29, 0x02, 0xca, 0x04 = ld.hu d2, [p0+c]#0xa +0x29, 0x02, 0x00, 0x02 = ld.q d2, [p0+r] +0x29, 0x02, 0x0a, 0x06 = ld.q d2, [p0+c]#0xa +0x29, 0x02, 0x00, 0x01 = ld.w d2, [p0+r] +0x29, 0x02, 0x0a, 0x05 = ld.w d2, [p0+c]#0xa +0x69, 0x02, 0x40, 0x00 = ldmst [p0+r], e2 +0x69, 0x02, 0x4a, 0x04 = ldmst [p0+c]#0xa, e2 +0xa9, 0x02, 0x80, 0x01 = st.a [p0+r], a2 +0xa9, 0x02, 0x8a, 0x05 = st.a [p0+c]#0xa, a2 +0xa9, 0x02, 0x00, 0x00 = st.b [p0+r], d2 +0xa9, 0x02, 0x0a, 0x04 = st.b [p0+c]#0xa, d2 +0xa9, 0x02, 0x40, 0x01 = st.d [p0+r], e2 +0xa9, 0x02, 0x4a, 0x05 = st.d [p0+c]#0xa, e2 +0xa9, 0x02, 0xc0, 0x01 = st.da [p0+r], p2 +0xa9, 0x02, 0xca, 0x05 = st.da [p0+c]#0xa, p2 +0xa9, 0x02, 0x80, 0x00 = st.h [p0+r], d2 +0xa9, 0x02, 0x8a, 0x04 = st.h [p0+c]#0xa, d2 +0xa9, 0x02, 0x00, 0x02 = st.q [p0+r], d2 +0xa9, 0x02, 0x0a, 0x06 = st.q [p0+c]#0xa, d2 +0xa9, 0x02, 0x00, 0x01 = st.w [p0+r], d2 +0xa9, 0x02, 0x0a, 0x05 = st.w [p0+c]#0xa, d2 +0x69, 0x02, 0x00, 0x00 = swap.w [p0+r], d2 +0x69, 0x02, 0x0a, 0x04 = swap.w [p0+c]#0xa, d2 +0x69, 0x02, 0x80, 0x00 = swapmsk.w [p0+r], e2 +0x69, 0x02, 0x8a, 0x04 = swapmsk.w [p0+c]#0xa, e2 diff --git a/suite/MC/TriCore/rr_insn.s.cs b/suite/MC/TriCore/rr_insn.s.cs new file mode 100644 index 0000000000..734b42ba07 --- /dev/null +++ b/suite/MC/TriCore/rr_insn.s.cs @@ -0,0 +1,6 @@ +# CS_ARCH_TRICORE, CS_MODE_TRICORE_131, None +0x0b, 0x20, 0xc0, 0x01 = abs d0, d2 +0x0b, 0x60, 0xc0, 0x05 = abs.b d0, d6 +0x0b, 0x40, 0xc0, 0x27 = abs.h d2, d4 +0x0b, 0x10, 0xd0, 0x01 = abss d0, d1 +0x0b, 0x10, 0xd0, 0x07 = abss.h d0, d1