fix: disp print and fill

This commit is contained in:
billow 2023-03-31 18:26:31 +08:00
parent c9d8d6c9bf
commit d759996f15

View File

@ -50,6 +50,38 @@ void TriCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci) {
#include "TriCoreGenRegisterInfo.inc"
static inline void fill_tricore_register(MCInst *MI, uint32_t reg) {
if (MI->csh->detail != CS_OPT_ON) return;
cs_tricore *tricore = &MI->flat_insn->detail->tricore;
tricore->operands[tricore->op_count]
.type = TRICORE_OP_REG;
tricore->operands[tricore->op_count]
.reg = TriCore_map_register(reg);
tricore->op_count++;
}
static inline void fill_tricore_imm(MCInst *MI, int32_t imm) {
if (MI->csh->detail != CS_OPT_ON) return;
cs_tricore *tricore = &MI->flat_insn->detail->tricore;
tricore->operands[tricore->op_count]
.type = TRICORE_OP_IMM;
tricore->operands[tricore->op_count]
.imm = imm;
tricore->op_count++;
}
static inline void fill_tricore_mem(MCInst *MI, uint8_t base, int32_t disp) {
if (MI->csh->detail != CS_OPT_ON) return;
cs_tricore *tricore = &MI->flat_insn->detail->tricore;
tricore->operands[tricore->op_count]
.type = TRICORE_OP_MEM;
tricore->operands[tricore->op_count]
.mem.base = base;
tricore->operands[tricore->op_count]
.mem.disp = disp;
tricore->op_count++;
}
static void printOperand(MCInst *MI, int OpNum, SStream *O) {
MCOperand *Op;
if (OpNum >= MI->size)
@ -60,16 +92,7 @@ static void printOperand(MCInst *MI, int OpNum, SStream *O) {
if (MCOperand_isReg(Op)) {
unsigned reg = MCOperand_getReg(Op);
SStream_concat(O, "%%%s", getRegisterName(reg));
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_REG;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.reg = (uint8_t) TriCore_map_register(reg);
MI->flat_insn->detail->tricore.op_count++;
}
fill_tricore_register(MI, reg);
} else if (MCOperand_isImm(Op)) {
int64_t Imm = MCOperand_getImm(Op);
@ -85,15 +108,7 @@ static void printOperand(MCInst *MI, int OpNum, SStream *O) {
SStream_concat(O, "-%" PRIu64, -Imm);
}
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_IMM;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.imm = Imm;
MI->flat_insn->detail->tricore.op_count++;
}
fill_tricore_imm(MI, (int32_t) Imm);
}
}
@ -131,17 +146,6 @@ static void printPairAddrRegsOperand(MCInst *MI, unsigned OpNum, SStream *O,
SStream_concat0(O, "]");
}
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;
tricore->operands[tricore->op_count]
.imm = imm;
tricore->op_count++;
}
}
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) {
@ -231,38 +235,51 @@ static void printOff18Imm(MCInst *MI, int OpNum, SStream *O) {
uint32_t imm = (uint32_t) MCOperand_getImm(MO);
imm = ((imm & 0x3C000) << 14) | (imm & 0x3fff);
SStream_concat(O, "0x%x", imm);
fill_tricore_imm(MI, imm);
fill_tricore_imm(MI, (int32_t) imm);
} else
printOperand(MI, OpNum, O);
}
static inline void fixup_tricore_disp(MCInst *MI, int OpNum, int32_t disp) {
if (MI->csh->detail != CS_OPT_ON) return;
if (OpNum <= 0) return;
cs_tricore *tricore = &MI->flat_insn->detail->tricore;
if (tricore->operands[tricore->op_count - 1].type != TRICORE_OP_REG) return;
MCOperand *baseOp = MCInst_getOperand(MI, OpNum - 1);
tricore->operands[tricore->op_count - 1]
.type = TRICORE_OP_MEM;
tricore->operands[tricore->op_count - 1]
.mem.base = tricore->operands[tricore->op_count - 1].reg;
tricore->operands[tricore->op_count - 1]
.mem.disp = disp;
}
static void printDisp24Imm(MCInst *MI, int OpNum, SStream *O) {
MCOperand *MO = MCInst_getOperand(MI, OpNum);
if (MCOperand_isImm(MO)) {
int32_t imm = (int32_t) MCOperand_getImm(MO);
int32_t disp = (int32_t) MCOperand_getImm(MO);
switch (MCInst_getOpcode(MI)) {
case TriCore_CALL_b:
case TriCore_FCALL_b:
imm = (int32_t) MI->address + sign_ext(imm * 2, 24);
disp = (int32_t) MI->address + sign_ext(disp * 2, 24);
break;
case TriCore_CALLA_b:
case TriCore_FCALLA_b:
case TriCore_JA_b:
case TriCore_JLA_b:
// = {disp24[23:20], 7b0000000, disp24[19:0], 1b0};
imm = ((imm & 0xf00000) < 8) | ((imm & 0xfffff) << 1);
disp = ((disp & 0xf00000) < 8) | ((disp & 0xfffff) << 1);
break;
case TriCore_J_b:
case TriCore_JL_b:
imm = (int32_t) MI->address + sign_ext(imm, 24) * 2;
break;
default:
// handle other cases, if any
disp = (int32_t) MI->address + sign_ext(disp, 24) * 2;
break;
}
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
SS_print_sign_hex(O, disp);
fixup_tricore_disp(MI, OpNum, disp);
} else
printOperand(MI, OpNum, O);
}
@ -270,7 +287,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)) {
int32_t imm = (int32_t) MCOperand_getImm(MO);
int32_t disp = (int32_t) MCOperand_getImm(MO);
switch (MCInst_getOpcode(MI)) {
case TriCore_JEQ_brc:
case TriCore_JEQ_brr:
@ -294,19 +311,19 @@ 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 = (int32_t) MI->address + sign_ext(imm, 15) * 2;
disp = (int32_t) MI->address + sign_ext(disp, 15) * 2;
break;
case TriCore_LOOP_brr:
case TriCore_LOOPU_brr:
imm = (int32_t) MI->address + sign_ext(imm * 2, 15);
disp = (int32_t) MI->address + sign_ext(disp * 2, 15);
break;
default:
// handle other cases, if any
break;
}
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
SS_print_sign_hex(O, disp);
fixup_tricore_disp(MI, OpNum, disp);
} else
printOperand(MI, OpNum, O);
}
@ -314,23 +331,23 @@ 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)) {
int32_t imm = (int32_t) MCOperand_getImm(MO);
int32_t disp = (int32_t) MCOperand_getImm(MO);
switch (MCInst_getOpcode(MI)) {
case TriCore_CALL_sb:
imm = (int32_t) MI->address + sign_ext(2 * imm, 8);
disp = (int32_t) MI->address + sign_ext(2 * disp, 8);
break;
case TriCore_J_sb:
case TriCore_JNZ_sb:
case TriCore_JZ_sb:
imm = (int32_t) MI->address + sign_ext(imm, 8) * 2;
disp = (int32_t) MI->address + sign_ext(disp, 8) * 2;
break;
default:
// handle other cases, if any
break;
}
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
SS_print_sign_hex(O, disp);
fixup_tricore_disp(MI, OpNum, disp);
} else
printOperand(MI, OpNum, O);
}
@ -338,7 +355,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)) {
int32_t imm = (int32_t) MCOperand_getImm(MO);
int32_t disp = (int32_t) MCOperand_getImm(MO);
switch (MCInst_getOpcode(MI)) {
case TriCore_JEQ_sbc1:
case TriCore_JEQ_sbr1:
@ -354,25 +371,25 @@ static void printDisp4Imm(MCInst *MI, int OpNum, SStream *O) {
case TriCore_JZ_sbr:
case TriCore_JZ_A_sbr:
case TriCore_JZ_T_sbrn:
imm = (int32_t) MI->address + imm * 2;
disp = (int32_t) MI->address + disp * 2;
break;
case TriCore_JEQ_sbc2:
case TriCore_JEQ_sbr2:
case TriCore_JNE_sbc2:
case TriCore_JNE_sbr2:
imm = (int32_t) MI->address + (imm + 16) * 2;
disp = (int32_t) MI->address + (disp + 16) * 2;
break;
case TriCore_LOOP_sbr:
// {27b111111111111111111111111111, disp4, 0};
imm = (int32_t) MI->address + ((0b111111111111111111111111111 << 5) | (imm << 1));
disp = (int32_t) MI->address + ((0b111111111111111111111111111 << 5) | (disp << 1));
break;
default:
// handle other cases, if any
break;
}
SS_print_sign_hex(O, imm);
fill_tricore_imm(MI, imm);
SS_print_sign_hex(O, disp);
fixup_tricore_disp(MI, OpNum, disp);
} else
printOperand(MI, OpNum, O);
}
@ -411,202 +428,6 @@ printZExtImm_(2)
printZExtImm_(1)
static void printPCRelImmOperand(MCInst *MI, int OpNum, SStream *O) {
MCOperand *Op = MCInst_getOperand(MI, OpNum);
if (MCOperand_isImm(Op)) {
unsigned imm = (unsigned) MCOperand_getImm(Op);
if (imm > HEX_THRESHOLD)
SStream_concat(O, "0x%x", imm);
else
SStream_concat(O, "%u", imm);
} else
printOperand(MI, OpNum, O);
}
// Print a 'bo' operand which is an addressing mode
// Base+Offset
static void printAddrBO(MCInst *MI, int OpNum, SStream *O) {
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
uint64_t Disp = (uint64_t) MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
SStream_concat(O, "[");
SStream_concat(O, "%%%s", getRegisterName(Base));
SStream_concat(O, "] ");
if (Disp > HEX_THRESHOLD)
SStream_concat(O, "0x%" PRIx64, Disp);
else
SStream_concat(O, "%" PRIu64, Disp);
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_MEM;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.mem.base = (uint8_t) TriCore_map_register(Base);
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.mem.disp = Disp;
MI->flat_insn->detail->tricore.op_count++;
}
}
// Print a 'preincbo' operand which is an addressing mode
// Pre-increment Base+Offset
static void printAddrPreIncBO(MCInst *MI, int OpNum, SStream *O) {
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
uint64_t Disp = (uint64_t) MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
SStream_concat(O, "[+");
SStream_concat(O, "%%%s", getRegisterName(Base));
SStream_concat(O, "] ");
if (Disp > HEX_THRESHOLD)
SStream_concat(O, "0x%" PRIx64, Disp);
else
SStream_concat(O, "%" PRIu64, Disp);
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_MEM;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.mem.base = (uint8_t) TriCore_map_register(Base);
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.mem.disp = Disp;
MI->flat_insn->detail->tricore.op_count++;
}
}
// Print a 'postincbo' operand which is an addressing mode
// Post-increment Base+Offset
static void printAddrPostIncBO(MCInst *MI, int OpNum, SStream *O) {
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
uint64_t Disp = (uint64_t) MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
SStream_concat(O, "[");
SStream_concat(O, "%%%s", getRegisterName(Base));
SStream_concat(O, "+] ");
if (Disp > HEX_THRESHOLD)
SStream_concat(O, "0x%" PRIx64, Disp);
else
SStream_concat(O, "%" PRIu64, Disp);
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_MEM;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.mem.base = (uint8_t) TriCore_map_register(Base);
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.mem.disp = Disp;
MI->flat_insn->detail->tricore.op_count++;
}
}
// Print a 'circbo' operand which is an addressing mode
// Circular Base+Offset
static void printAddrCircBO(MCInst *MI, unsigned OpNum, SStream *O,
MCRegisterInfo *MRI) {
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
uint64_t Disp = (uint64_t) MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1));
SStream_concat0(O, "[");
SStream_concat(O, "%%%s",
getRegisterName(
MCRegisterInfo_getSubReg(MRI, Base, TriCore_subreg_even)));
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_REG;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.reg = (uint8_t) TriCore_map_register(
MCRegisterInfo_getSubReg(MRI, Base, TriCore_subreg_even));
MI->flat_insn->detail->tricore.op_count++;
}
SStream_concat0(O, "/");
SStream_concat(
O, "%%%s",
getRegisterName(MCRegisterInfo_getSubReg(MRI, Base, TriCore_subreg_odd)));
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_REG;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.reg = (uint8_t) TriCore_map_register(
MCRegisterInfo_getSubReg(MRI, Base, TriCore_subreg_odd));
MI->flat_insn->detail->tricore.op_count++;
}
SStream_concat0(O, "+c] ");
if (Disp > HEX_THRESHOLD)
SStream_concat(O, "0x%" PRIx64, Disp);
else
SStream_concat(O, "%" PRIu64, Disp);
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_MEM;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.mem.base = (uint8_t) TriCore_map_register(Base);
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.mem.disp = Disp;
MI->flat_insn->detail->tricore.op_count++;
}
}
// Print a 'bitrevbo' operand which is an addressing mode
// Bit-Reverse Base+Offset
static void printAddrBitRevBO(MCInst *MI, unsigned OpNum, SStream *O,
MCRegisterInfo *MRI) {
unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
SStream_concat0(O, "[");
SStream_concat(O, "%%%s",
getRegisterName(
MCRegisterInfo_getSubReg(MRI, Base, TriCore_subreg_even)));
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_REG;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.reg = (uint8_t) TriCore_map_register(
MCRegisterInfo_getSubReg(MRI, Base, TriCore_subreg_even));
MI->flat_insn->detail->tricore.op_count++;
}
SStream_concat0(O, "/");
SStream_concat(
O, "%%%s",
getRegisterName(MCRegisterInfo_getSubReg(MRI, Base, TriCore_subreg_odd)));
if (MI->csh->detail) {
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.type = TRICORE_OP_REG;
MI->flat_insn->detail->tricore
.operands[MI->flat_insn->detail->tricore.op_count]
.reg = (uint8_t) TriCore_map_register(
MCRegisterInfo_getSubReg(MRI, Base, TriCore_subreg_odd));
MI->flat_insn->detail->tricore.op_count++;
}
SStream_concat0(O, "+r]");
}
/// Returned by getMnemonic() of the AsmPrinters.
typedef struct {
const char *first; // Menmonic