From 104ad28a7e4d342303568fb0f2fb0898230be137 Mon Sep 17 00:00:00 2001 From: Sidney Pontes Filho Date: Fri, 10 Jun 2016 13:08:46 +0200 Subject: [PATCH] Improve TriCore InstPrinter and Mapping --- arch/TriCore/TriCoreInstPrinter.c | 141 +++++++++++++++++++++++++++++- arch/TriCore/TriCoreMapping.c | 19 ++++ 2 files changed, 156 insertions(+), 4 deletions(-) diff --git a/arch/TriCore/TriCoreInstPrinter.c b/arch/TriCore/TriCoreInstPrinter.c index 80a71eeff..645703721 100644 --- a/arch/TriCore/TriCoreInstPrinter.c +++ b/arch/TriCore/TriCoreInstPrinter.c @@ -29,8 +29,6 @@ #include "../../MathExtras.h" #include "TriCoreMapping.h" -// TODO: Implement all functions - static char *getRegisterName(unsigned RegNo); static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI); static void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier); @@ -72,7 +70,7 @@ void TriCore_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci) static void printRegName(SStream *OS, unsigned RegNo) { - SStream_concat0(OS, "%"); + SStream_concat0(OS, "$"); SStream_concat0(OS, getRegisterName(RegNo)); } @@ -90,8 +88,143 @@ void TriCore_printInst(MCInst *MI, SStream *O, void *Info) static void printOperand(MCInst *MI, int OpNum, SStream *O) { - if (OpNum >= MI->size) + MCOperand *Op; + + if (OpNo >= MI->size) return; + + Op = MCInst_getOperand(MI, OpNo); + if (MCOperand_isReg(Op)) { + unsigned int reg = MCOperand_getReg(Op); + printRegName(O, reg); + reg = TriCore_map_register(reg); + if (MI->csh->detail) { + if (MI->csh->doing_mem) { + MI->flat_insn->detail->tricore.operands[MI->flat_insn->detail->tricore.op_count].mem.base = reg; + } else { + 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 = reg; + MI->flat_insn->detail->tricore.op_count++; + } + } + } else if (MCOperand_isImm(Op)) { + int64_t imm = MCOperand_getImm(Op); + if (MI->csh->doing_mem) { + if (imm) { // only print Imm offset if it is not 0 + if (imm >= 0) { + if (imm > HEX_THRESHOLD) + SStream_concat(O, "0x%"PRIx64, imm); + else + SStream_concat(O, "%"PRIu64, imm); + } else { + if (imm < -HEX_THRESHOLD) + SStream_concat(O, "-0x%"PRIx64, -imm); + else + SStream_concat(O, "-%"PRIu64, -imm); + } + } + if (MI->csh->detail) + MI->flat_insn->detail->tricore.operands[MI->flat_insn->detail->tricore.op_count].mem.disp = imm; + } else { + if (imm >= 0) { + if (imm > HEX_THRESHOLD) + SStream_concat(O, "0x%"PRIx64, imm); + else + SStream_concat(O, "%"PRIu64, imm); + } else { + if (imm < -HEX_THRESHOLD) + SStream_concat(O, "-0x%"PRIx64, -imm); + else + 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++; + } + } + } +} + +static void printSExtImm(MCInst *MI, int opNum, SStream *O) +{ + MCOperand *MO = MCInst_getOperand(MI, opNum); + if (MCOperand_isImm(MO)) { + int64_t imm = MCOperand_getImm(MO); + if (imm >= 0) { + if (imm > HEX_THRESHOLD) + SStream_concat(O, "0x%x", (unsigned short int)imm); + else + SStream_concat(O, "%u", (unsigned short int)imm); + } else { + if (imm < -HEX_THRESHOLD) + SStream_concat(O, "-0x%x", (short int)-imm); + else + SStream_concat(O, "-%u", (short int)-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 = (unsigned short int)imm; + MI->flat_insn->detail->tricore.op_count++; + } + } else + printOperand(MI, opNum, O); +} + +static void printZExtImm(MCInst *MI, int opNum, SStream *O) +{ + MCOperand *MO = MCInst_getOperand(MI, opNum); + if (MCOperand_isImm(MO)) { + unsigned imm = (unsigned)MCOperand_getImm(MO); + if (imm > HEX_THRESHOLD) + SStream_concat(O, "0x%x", imm); + else + SStream_concat(O, "%u", 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++; + } + } else + printOperand(MI, opNum, O); +} + +// Print a 'memsrc' operand which is a (Register, Offset) pair. +// TODO: verify this function +void printAddrModeMemSrc(const MCInst *MI, unsigned OpNum, raw_ostream &O) { + + MCOperand *Base = MCInst_getOperand(MI, opNum); + + // Print register base field + if (MCOperand_isReg(Base)) { + SStream_concat(O, "[%"); + printRegName(O, MCOperand_getReg(Base)); + SStream_concat(O, "]"); + } + + SStream_concat(O, " "); + printOperand(MI, opNum+1, O); // Disp +} + +static void printCCOperand(MCInst *MI, int opNum, SStream *O) +{ + MCOperand *MO = MCInst_getOperand(MI, opNum); + unsigned CC = MCOperand_getImm(MO); + switch (CC) { + default: // unreachable + case 0: + SStream_concat0(O, "eq"); + break; + case 1: + SStream_concat0(O, "ne"); + break; + case 3: + SStream_concat0(O, "lt"); + break; + case 2: + SStream_concat0(O, "ge"); + break; } #define PRINT_ALIAS_INSTR diff --git a/arch/TriCore/TriCoreMapping.c b/arch/TriCore/TriCoreMapping.c index 262caca9e..6c5b44a6a 100644 --- a/arch/TriCore/TriCoreMapping.c +++ b/arch/TriCore/TriCoreMapping.c @@ -876,6 +876,25 @@ const char *TriCore_insn_name(csh handle, unsigned int id) #endif } +#ifndef CAPSTONE_DIET +static name_map group_name_maps[] = { + { TRICORE_GRP_INVALID, NULL }, + { TRICORE_GRP_JUMP, "jump" }, +}; +#endif + +const char *TriCore_group_name(csh handle, unsigned int id) +{ +#ifndef CAPSTONE_DIET + if (id >= TRICORE_GRP_ENDING) + return NULL; + + return group_name_maps[id].name; +#else + return NULL; +#endif +} + // map internal raw register to 'public' register tricore_reg TriCore_map_register(unsigned int r) {