Skip to content

Commit

Permalink
Fixing TriCore disasm instructions (#2088)
Browse files Browse the repository at this point in the history
  • Loading branch information
bkoppelmann authored Jul 26, 2023
1 parent 10a4d8d commit 9099567
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 22 deletions.
121 changes: 99 additions & 22 deletions arch/TriCore/TriCoreDisassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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.
Expand Down
16 changes: 16 additions & 0 deletions arch/TriCore/TriCoreInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions suite/MC/TriCore/csfr.s.cs
Original file line number Diff line number Diff line change
@@ -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
3 changes: 3 additions & 0 deletions suite/MC/TriCore/extr_u.s.cs
Original file line number Diff line number Diff line change
@@ -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
47 changes: 47 additions & 0 deletions suite/MC/TriCore/ldst_br_circ.s.cs
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions suite/MC/TriCore/rr_insn.s.cs
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 9099567

Please sign in to comment.