fix: decode j call loop

This commit is contained in:
billow 2023-03-29 12:31:35 +08:00
parent d9e715bc17
commit 878e09db04
9 changed files with 2512 additions and 2470 deletions

View File

@ -253,7 +253,7 @@ DecodeRegisterClass(MCInst *Inst, unsigned RegNo, const MCOperandInfo *MCOI, voi
static DecodeStatus DecodeSBInstruction(MCInst *Inst, unsigned Insn,
uint64_t Address, void *Decoder) {
unsigned disp8 = fieldFromInstruction_4(Insn, 8, 8);
unsigned disp8 = fieldFromInstruction_2(Insn, 8, 8);
unsigned is32Bit = fieldFromInstruction_4(Insn, 0, 1);
if (is32Bit) // This instruction is 16-bit
@ -268,8 +268,8 @@ static DecodeStatus DecodeSBInstruction(MCInst *Inst, unsigned Insn,
static DecodeStatus DecodeSBRInstruction(MCInst *Inst, unsigned Insn,
uint64_t Address, void *Decoder) {
DecodeStatus status;
unsigned s2 = fieldFromInstruction_4(Insn, 12, 4);
unsigned disp4 = fieldFromInstruction_4(Insn, 8, 4);
unsigned s2 = fieldFromInstruction_2(Insn, 12, 4);
unsigned disp4 = fieldFromInstruction_2(Insn, 8, 4);
unsigned is32Bit = fieldFromInstruction_4(Insn, 0, 1);
if (is32Bit) // This instruction is 16-bit
@ -288,7 +288,7 @@ static DecodeStatus DecodeSBRInstruction(MCInst *Inst, unsigned Insn,
static DecodeStatus DecodeSCInstruction(MCInst *Inst, unsigned Insn,
uint64_t Address, void *Decoder) {
unsigned const8 = fieldFromInstruction_4(Insn, 8, 8);
unsigned const8 = fieldFromInstruction_2(Insn, 8, 8);
unsigned is32Bit = fieldFromInstruction_4(Insn, 0, 1);
if (is32Bit) // This instruction is 16-bit
@ -303,7 +303,7 @@ static DecodeStatus DecodeSCInstruction(MCInst *Inst, unsigned Insn,
static DecodeStatus DecodeSRInstruction(MCInst *Inst, unsigned Insn,
uint64_t Address, void *Decoder) {
DecodeStatus status;
unsigned s1_d = fieldFromInstruction_4(Insn, 8, 4);
unsigned s1_d = fieldFromInstruction_2(Insn, 8, 4);
unsigned is32Bit = fieldFromInstruction_4(Insn, 0, 1);
if (is32Bit) // This instruction is 16-bit
@ -323,8 +323,8 @@ static DecodeStatus DecodeSRInstruction(MCInst *Inst, unsigned Insn,
static DecodeStatus DecodeSRCInstruction(MCInst *Inst, unsigned Insn,
uint64_t Address, void *Decoder) {
DecodeStatus status;
unsigned const4 = fieldFromInstruction_4(Insn, 12, 4);
unsigned s1_d = fieldFromInstruction_4(Insn, 8, 4);
unsigned const4 = fieldFromInstruction_2(Insn, 12, 4);
unsigned s1_d = fieldFromInstruction_2(Insn, 8, 4);
unsigned is32Bit = fieldFromInstruction_4(Insn, 0, 1);
if (is32Bit) // This instruction is 16-bit
@ -346,8 +346,8 @@ static DecodeStatus DecodeSRCInstruction(MCInst *Inst, unsigned Insn,
static DecodeStatus DecodeSRRInstruction(MCInst *Inst, unsigned Insn,
uint64_t Address, void *Decoder) {
DecodeStatus status;
unsigned s2 = fieldFromInstruction_4(Insn, 12, 4);
unsigned s1_d = fieldFromInstruction_4(Insn, 8, 4);
unsigned s2 = fieldFromInstruction_2(Insn, 12, 4);
unsigned s1_d = fieldFromInstruction_2(Insn, 8, 4);
unsigned is32Bit = fieldFromInstruction_4(Insn, 0, 1);
if (is32Bit) // This instruction is 16-bit
@ -492,7 +492,8 @@ static DecodeStatus DecodeBOLInstruction(MCInst *Inst, unsigned Insn,
case TriCore_LD_BU_bol:
case TriCore_LD_H_bol:
case TriCore_LD_HU_bol:
case TriCore_LD_W_bol: {
case TriCore_LD_W_bol:
case TriCore_LEA_bol: {
// Decode s1_d.
status = DecodeRegisterClass(Inst, s1_d, &desc->OpInfo[0], Decoder);
if (status != MCDisassembler_Success)
@ -519,7 +520,8 @@ static DecodeStatus DecodeBOLInstruction(MCInst *Inst, unsigned Insn,
return status;
break;
}
default: return MCDisassembler_Fail;
default:
return MCDisassembler_Fail;
}
// Decode off16.
@ -850,6 +852,11 @@ static DecodeStatus DecodeSBCInstruction(MCInst *Inst, unsigned Insn, uint64_t A
if (is32Bit) // This instruction is 16-bit
return MCDisassembler_Fail;
const MCInstrDesc *desc = &TriCoreInsts[MCInst_getOpcode(Inst)];
if (desc->NumOperands != 2) {
return MCDisassembler_Fail;
}
// Decode disp4.
MCOperand_CreateImm0(Inst, disp4);
@ -867,11 +874,10 @@ static DecodeStatus DecodeSBRNInstruction(MCInst *Inst, unsigned Insn, uint64_t
if (is32Bit) // This instruction is 16-bit
return MCDisassembler_Fail;
// Decode disp4.
MCOperand_CreateImm0(Inst, disp4);
// Decode n.
MCOperand_CreateImm0(Inst, n);
// Decode disp4.
MCOperand_CreateImm0(Inst, disp4);
return MCDisassembler_Success;
}
@ -1224,14 +1230,26 @@ static DecodeStatus DecodeBRRInstruction(MCInst *Inst, unsigned Insn, uint64_t A
return MCDisassembler_Fail;
const MCInstrDesc *desc = &TriCoreInsts[MCInst_getOpcode(Inst)];
status = DecodeRegisterClass(Inst, s1, &desc->OpInfo[0], Decoder);
if (status != MCDisassembler_Success)
return status;
if (MCInst_getOpcode(Inst) == TriCore_LOOP_brr) {
status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[0], Decoder);
if (status != MCDisassembler_Success)
return status;
// Decode s2.
status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], Decoder);
if (status != MCDisassembler_Success)
return status;
MCOperand_CreateImm0(Inst, disp15);
return MCDisassembler_Success;
}
if (desc->NumOperands >= 2) {
status = DecodeRegisterClass(Inst, s1, &desc->OpInfo[0], Decoder);
if (status != MCDisassembler_Success)
return status;
if (desc->NumOperands >= 3) {
status = DecodeRegisterClass(Inst, s2, &desc->OpInfo[1], Decoder);
if (status != MCDisassembler_Success)
return status;
}
}
// Decode disp15.
MCOperand_CreateImm0(Inst, disp15);

File diff suppressed because it is too large Load Diff

View File

@ -321,7 +321,7 @@ static const uint8_t DecoderTable16[] = {
/* 1336 */ MCD_OPC_FilterValue, 3, 4, 0, 0, // Skip to: 1345
/* 1341 */ MCD_OPC_Decode, 231, 3, 6, // Opcode: JNE_sbr2
/* 1345 */ MCD_OPC_Fail,
0
0
};
static const uint8_t DecoderTable32[] = {
@ -2662,11 +2662,11 @@ static const uint8_t DecoderTable32[] = {
/* 11256 */ MCD_OPC_FilterValue, 1, 4, 0, 0, // Skip to: 11265
/* 11261 */ MCD_OPC_Decode, 205, 3, 32, // Opcode: JGE_U_brc
/* 11265 */ MCD_OPC_Fail,
0
0
};
static bool checkDecoderPredicate(MCInst *Inst, unsigned Idx) {
/* llvm_unreachable("Invalid index!"); */
/* llvm_unreachable("Invalid index!"); */
}
#define DecodeToMCInst(fname, fieldname, InsnType) \
@ -2704,19 +2704,19 @@ static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *M
if (DecodeSCInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
return S; \
case 9: \
if (DecodeSBCInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
if (DecodeSBInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
return S; \
case 10: \
if (DecodeSBRNInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
if (DecodeSBCInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
return S; \
case 11: \
if (DecodeSSRInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
if (DecodeSBRNInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
return S; \
case 12: \
if (DecodeSSROInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
if (DecodeSSRInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
return S; \
case 13: \
if (DecodeSBInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
if (DecodeSSROInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \
return S; \
case 14: \
if (DecodeSYSInstruction(MI, insn, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \

View File

@ -1674,7 +1674,7 @@ static const MCInstrDesc TriCoreInsts[] = {
{ 3, OperandInfo46 },
{ 2, OperandInfo53 },
{ 2, OperandInfo52 },
{ 1, OperandInfo64 },
{ 1, OperandInfo57 },
{ 1, OperandInfo2 },
{ 2, OperandInfo53 },
{ 2, OperandInfo52 },

View File

@ -131,48 +131,51 @@ static void printPairAddrRegsOperand(MCInst *MI, unsigned OpNum, SStream *O,
SStream_concat0(O, "]");
}
static inline void fill_tricore_imm(MCInst *MI, int64_t imm) {
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
static inline void fill_tricore_imm(MCInst *MI, int32_t imm) {
if (MI->csh->detail == CS_OPT_ON) {
cs_tricore *tricore = &MI->flat_insn->detail->tricore;
tricore->operands[tricore->op_count]
.type = TRICORE_OP_IMM;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.imm = (int) imm;
MI->flat_insn->detail->tricore.op_count++;
tricore->operands[tricore->op_count]
.imm = imm;
tricore->op_count++;
}
}
static inline int64_t sign_ext(int64_t imm, unsigned n) {
int64_t sign = imm >> (n - 1) & 0x1;
for (unsigned i = n; i < 64; ++i) {
imm = (imm & ~(1LL << i)) | (sign << i);
static inline int32_t sign_ext(int32_t imm, unsigned n) {
int32_t sign = imm >> (n - 1) & 0x1;
for (unsigned i = n; i < 32; ++i) {
imm = (imm & ~(1 << i)) | (sign << i);
}
return imm;
}
static inline void SS_print_sign_hex(SStream *O, int32_t imm) {
if (imm >= 0) {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%x", imm);
else
SStream_concat(O, "%u", imm);
} else {
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%x", -imm);
else
SStream_concat(O, "-%u", -imm);
}
}
static void print_sign_ext(MCInst *MI, int OpNum, SStream *O, unsigned n) {
MCOperand *MO = MCInst_getOperand(MI, OpNum);
if (MCOperand_isImm(MO)) {
int64_t imm = MCOperand_getImm(MO);
int32_t imm = (int32_t) MCOperand_getImm(MO);
imm = sign_ext(imm, n);
if (imm >= 0) {
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%x", imm);
else
SStream_concat(O, "%u", imm);
} else {
if (imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%x", -imm);
else
SStream_concat(O, "-%u", -imm);
}
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
} else
printOperand(MI, OpNum, O);
}
static void off4_fixup(MCInst *MI, int64_t *off4) {
static void off4_fixup(MCInst *MI, uint64_t *off4) {
switch (MCInst_getOpcode(MI)) {
case TriCore_LD_A_slro:
case TriCore_LD_A_sro:
@ -198,9 +201,9 @@ static void off4_fixup(MCInst *MI, int64_t *off4) {
static void print_zero_ext(MCInst *MI, int OpNum, SStream *O, unsigned n) {
MCOperand *MO = MCInst_getOperand(MI, OpNum);
if (MCOperand_isImm(MO)) {
int64_t imm = MCOperand_getImm(MO);
for (unsigned i = n + 1; i < 64; ++i) {
imm &= ~(1LL << i);
uint64_t imm = MCOperand_getImm(MO);
for (unsigned i = n + 1; i < 32; ++i) {
imm &= ~(1 << i);
}
if (n == 4) {
off4_fixup(MI, &imm);
@ -236,11 +239,11 @@ static void printOff18Imm(MCInst *MI, int OpNum, SStream *O) {
static void printDisp24Imm(MCInst *MI, int OpNum, SStream *O) {
MCOperand *MO = MCInst_getOperand(MI, OpNum);
if (MCOperand_isImm(MO)) {
uint32_t imm = (uint32_t) MCOperand_getImm(MO);
int32_t imm = (int32_t) MCOperand_getImm(MO);
switch (MCInst_getOpcode(MI)) {
case TriCore_CALL_b:
case TriCore_FCALL_b:
imm = MI->address + sign_ext(imm * 2, 24);
imm = (int32_t) MI->address + sign_ext(imm * 2, 24);
break;
case TriCore_CALLA_b:
case TriCore_FCALLA_b:
@ -251,14 +254,14 @@ static void printDisp24Imm(MCInst *MI, int OpNum, SStream *O) {
break;
case TriCore_J_b:
case TriCore_JL_b:
imm = MI->address + sign_ext(imm, 24) * 2;
imm = (int32_t) MI->address + sign_ext(imm, 24) * 2;
break;
default:
// handle other cases, if any
break;
}
SStream_concat(O, "0x%x", imm);
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
} else
printOperand(MI, OpNum, O);
@ -267,7 +270,7 @@ static void printDisp24Imm(MCInst *MI, int OpNum, SStream *O) {
static void printDisp15Imm(MCInst *MI, int OpNum, SStream *O) {
MCOperand *MO = MCInst_getOperand(MI, OpNum);
if (MCOperand_isImm(MO)) {
uint32_t imm = (uint32_t) MCOperand_getImm(MO);
int32_t imm = (int32_t) MCOperand_getImm(MO);
switch (MCInst_getOpcode(MI)) {
case TriCore_JEQ_brc:
case TriCore_JEQ_brr:
@ -291,18 +294,18 @@ static void printDisp15Imm(MCInst *MI, int OpNum, SStream *O) {
case TriCore_JNZ_T_brn:
case TriCore_JZ_A_brr:
case TriCore_JZ_T_brn:
imm = MI->address + sign_ext(imm, 15) * 2;
imm = (int32_t) MI->address + sign_ext(imm, 15) * 2;
break;
case TriCore_LOOP_brr:
case TriCore_LOOPU_brr:
imm = MI->address + sign_ext(imm * 2, 15);
imm = (int32_t) MI->address + sign_ext(imm * 2, 15);
break;
default:
// handle other cases, if any
break;
}
SStream_concat(O, "0x%x", imm);
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
} else
printOperand(MI, OpNum, O);
@ -311,20 +314,22 @@ static void printDisp15Imm(MCInst *MI, int OpNum, SStream *O) {
static void printDisp8Imm(MCInst *MI, int OpNum, SStream *O) {
MCOperand *MO = MCInst_getOperand(MI, OpNum);
if (MCOperand_isImm(MO)) {
uint32_t imm = (uint32_t) MCOperand_getImm(MO);
int32_t imm = (int32_t) MCOperand_getImm(MO);
switch (MCInst_getOpcode(MI)) {
case TriCore_CALL_sb:
imm = MI->address + sign_ext(2 * imm, 8);
imm = (int32_t) MI->address + sign_ext(2 * imm, 8);
break;
case TriCore_J_sb:
case TriCore_JNZ_sb:
case TriCore_JZ_sb:
imm = MI->address + sign_ext(imm, 8) * 2;
imm = (int32_t) MI->address + sign_ext(imm, 8) * 2;
break;
default:
// handle other cases, if any
break;
}
SStream_concat(O, "0x%x", imm);
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
} else
printOperand(MI, OpNum, O);
@ -333,7 +338,7 @@ static void printDisp8Imm(MCInst *MI, int OpNum, SStream *O) {
static void printDisp4Imm(MCInst *MI, int OpNum, SStream *O) {
MCOperand *MO = MCInst_getOperand(MI, OpNum);
if (MCOperand_isImm(MO)) {
uint32_t imm = (uint32_t) MCOperand_getImm(MO);
int32_t imm = (int32_t) MCOperand_getImm(MO);
switch (MCInst_getOpcode(MI)) {
case TriCore_JEQ_sbc1:
case TriCore_JEQ_sbr1:
@ -349,24 +354,24 @@ static void printDisp4Imm(MCInst *MI, int OpNum, SStream *O) {
case TriCore_JZ_sbr:
case TriCore_JZ_A_sbr:
case TriCore_JZ_T_sbrn:
imm = MI->address + imm * 2;
imm = (int32_t) MI->address + imm * 2;
break;
case TriCore_JEQ_sbc2:
case TriCore_JEQ_sbr2:
case TriCore_JNE_sbc2:
case TriCore_JNE_sbr2:
imm = MI->address + (imm + 16) * 2;
imm = (int32_t) MI->address + (imm + 16) * 2;
break;
case TriCore_LOOP_sbr:
// {27b111111111111111111111111111, disp4, 0};
imm = MI->address + ((0b111111111111111111111111111 << 5) & (imm << 1));
imm = (int32_t) MI->address + ((0b111111111111111111111111111 << 5) | (imm << 1));
break;
default:
// handle other cases, if any
break;
}
SStream_concat(O, "0x%x", imm);
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
} else
printOperand(MI, OpNum, O);

View File

@ -739,6 +739,9 @@ def call_target : Operand<i32> {
class ISB<bits<8> op1, string asmstr>
: SB<op1, (outs), (ins disp8imm:$disp8), asmstr # " $disp8", []>;
class ISB_D15D<bits<8> op1, string asmstr>
: SB<op1, (outs), (ins disp8imm:$disp8), asmstr # " %d15, $disp8", []>;
let isCall = 1,
Defs = [A11],
Uses = [A10] in {
@ -1031,11 +1034,11 @@ class IBRR<bits<8> op1, bits<1> op2, string asmstr>
class IBRC<bits<8> op1, bits<1> op2, string asmstr>
: BRC<op1, op2, (outs), (ins DataRegs:$s1, s4imm:$const4, disp15imm:$disp15),
: BRC<op1, op2, (outs), (ins DataRegs:$s1, u4imm:$const4, disp15imm:$disp15),
!strconcat(asmstr, " $s1, $const4, $disp15"), []>;
class ISBC<bits<8> op1, string asmstr>
: SBC<op1, (outs), (ins s4imm:$const4, disp4imm:$disp4),
: SBC<op1, (outs), (ins disp4imm:$disp4, s4imm:$const4),
!strconcat(asmstr, " %d15, $const4, $disp4"), []>;
// D[15], D[b], disp4 (SBR)
@ -1078,7 +1081,8 @@ def JGEZ_sbr : ISBR_b<0xCE, "jgez">;
def JGTZ_sbr : ISBR_b<0x4E, "jgtz">;
def JI_rr : IRR_Aa<0x2D, 0x03, "ji">;
def JI_sr : ISR_1<0xDC, 0x00, "ji">;
def JI_sr : SR<0xDC, 0x00, (outs), (ins AddrRegs:$s1),
"ji $s1", []>;
def JL_b : IB<0x5D, "jl">;
def JLA_b : IB<0xDD, "jla">;
@ -1110,7 +1114,7 @@ multiclass mISB_SBR_T_BRN_SBRN<bits<8> sb, bits<8> sbr,
bits<8> a1, bits<1> a2, bits<8> a3,
bits<7> brn1, bits<1> brn2, bits<8> sbrn,
string asmstr>{
def _sb : ISB<sb, asmstr>;
def _sb : ISB_D15D<sb, asmstr>;
def _sbr : ISBR_b<sbr, asmstr>;
defm _A : mIBRR_SBR<a1, a2, a3, asmstr # ".a">;
def _T_brn : BRN<brn1, brn2, (outs), (ins DataRegs:$s1, i32imm:$n, disp15imm:$disp15),

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -23,18 +23,30 @@ def gen(filename):
mnemonic: str = caps[5]
operands = caps[6]
def try_dedisp(x):
try:
disp = int(x, 16)
if disp > 0x10000000:
return hex(disp - addr)
return x
except ValueError:
pass
return x
hexstr = ','.join(f'0x{x}' for x in hexstr if x)
operands = re.sub(r'\s*<.+>\s*', ' ', operands)
operands = re.sub(r'\s*<.+>\s*', '', operands)
operands = operands.replace(',', ', ')
# print(hex(addr), hexstr, mnemonic, operands)
if any([mnemonic.startswith(pre) for pre in ['j', 'call', 'st', 'ld', 'loop']]):
if any([mnemonic.startswith(pre) for pre in ['st', 'ld']]):
print(f"# {hexstr.ljust(19)} = {mnemonic}\t{operands}")
elif any([mnemonic.startswith(pre) for pre in ['j', 'call', 'loop']]):
# de relative addressing
try:
# disp = int(operands, 16) - addr
# operands = hex(disp)
print(f"# {hexstr.ljust(19)} = {mnemonic}\t{operands}")
except ValueError:
continue
if ',' in operands:
operands = map(try_dedisp, operands.split(', '))
operands = ', '.join(operands)
else:
operands = try_dedisp(operands)
print(f"# {hexstr.ljust(19)} = {mnemonic}\t{operands}")
else:
print(f"{hexstr.ljust(19)} = {mnemonic}\t{operands}")