/* Capstone Disassembly Engine */ /* By Dmitry Sibirtsev , 2023 */ #ifdef CAPSTONE_HAS_HPPA #include #include #include "HPPAMapping.h" #include "HPPAConstants.h" #include "../../Mapping.h" #include "../../utils.h" #ifndef CAPSTONE_DIET static const name_map group_name_maps[] = { { HPPA_GRP_INVALID, NULL }, { HPPA_GRP_COMPUTATION, "computation" }, { HPPA_GRP_MULTIMEDIA, "multimedia" }, { HPPA_GRP_MEM_REF, "memory_reference" }, { HPPA_GRP_LONG_IMM, "long_imm" }, { HPPA_GRP_BRANCH, "branch" }, { HPPA_GRP_SYSCTRL, "system_control" }, { HPPA_GRP_ASSIST, "assist" }, { HPPA_GRP_FLOAT, "float" }, }; #endif const char *HPPA_group_name(csh handle, unsigned int id) { #ifndef CAPSTONE_DIET return id2name(group_name_maps, ARR_SIZE(group_name_maps), id); #else return NULL; #endif } #ifndef CAPSTONE_DIET static const name_map insn_name_maps[HPPA_INS_ENDING] = { { HPPA_INS_INVALID, NULL }, { HPPA_INS_ADD, "add" }, { HPPA_INS_ADDI, "addi" }, { HPPA_INS_ADDIO, "addio" }, { HPPA_INS_ADDIT, "addit" }, { HPPA_INS_ADDITO, "addito" }, { HPPA_INS_ADDB, "addb" }, { HPPA_INS_ADDBT, "addbt" }, { HPPA_INS_ADDBF, "addbf" }, { HPPA_INS_ADDIB, "addib" }, { HPPA_INS_ADDIBT, "addibt" }, { HPPA_INS_ADDIBF, "addibf" }, { HPPA_INS_ADDIL, "addil" }, { HPPA_INS_ADDC, "addc" }, { HPPA_INS_ADDCO, "addco" }, { HPPA_INS_ADDL, "addl" }, { HPPA_INS_ADDO, "addo" }, { HPPA_INS_AND, "and" }, { HPPA_INS_ANDCM, "andcm" }, { HPPA_INS_B, "b" }, { HPPA_INS_BB, "bb" }, { HPPA_INS_BE, "be" }, { HPPA_INS_BL, "bl" }, { HPPA_INS_BLE, "ble" }, { HPPA_INS_BLR, "blr" }, { HPPA_INS_BREAK, "break" }, { HPPA_INS_BV, "bv" }, { HPPA_INS_BVB, "bvb" }, { HPPA_INS_BVE, "bve" }, { HPPA_INS_CALL, "call" }, { HPPA_INS_CLDD, "cldd" }, { HPPA_INS_CLDDS, "cldds" }, { HPPA_INS_CLDDX, "clddx" }, { HPPA_INS_CLDW, "cldw" }, { HPPA_INS_CLDWS, "cldws" }, { HPPA_INS_CLDWX, "cldwx" }, { HPPA_INS_CLRBTS, "clrbts" }, { HPPA_INS_CMPB, "cmpb" }, { HPPA_INS_CMPCLR, "cmpclr" }, { HPPA_INS_CMPIB, "cmpib" }, { HPPA_INS_CMPICLR, "cmpiclr" }, { HPPA_INS_COMB, "comb" }, { HPPA_INS_COMBT, "combt" }, { HPPA_INS_COMBF, "combf" }, { HPPA_INS_COMCLR, "comclr" }, { HPPA_INS_COMIB, "comib" }, { HPPA_INS_COMIBT, "comibt" }, { HPPA_INS_COMIBF, "comibf" }, { HPPA_INS_COMICLR, "comiclr" }, { HPPA_INS_COPR, "copr" }, { HPPA_INS_COPY, "copy" }, { HPPA_INS_CSTD, "cstd" }, { HPPA_INS_CSTDS, "cstds" }, { HPPA_INS_CSTDX, "cstdx" }, { HPPA_INS_CSTW, "cstw" }, { HPPA_INS_CSTWS, "cstws" }, { HPPA_INS_CSTWX, "cstwx" }, { HPPA_INS_DCOR, "dcor" }, { HPPA_INS_DEP, "dep" }, { HPPA_INS_DEPI, "depi" }, { HPPA_INS_DEPD, "depd" }, { HPPA_INS_DEPDI, "depdi" }, { HPPA_INS_DEPW, "depw" }, { HPPA_INS_DEPWI, "depwi" }, { HPPA_INS_DIAG, "diag" }, { HPPA_INS_DS, "ds" }, { HPPA_INS_EXTRD, "extrd" }, { HPPA_INS_EXTRS, "extrs" }, { HPPA_INS_EXTRU, "extru" }, { HPPA_INS_EXTRW, "extrw" }, { HPPA_INS_FABS, "fabs" }, { HPPA_INS_FADD, "fadd" }, { HPPA_INS_FCMP, "fcmp" }, { HPPA_INS_FCNV, "fcnv" }, { HPPA_INS_FCNVFF, "fcnvff" }, { HPPA_INS_FCNVFX, "fcnvfx" }, { HPPA_INS_FCNVFXT, "fcnvfxt" }, { HPPA_INS_FCNVXF, "fcnvxf" }, { HPPA_INS_FCPY, "fcpy" }, { HPPA_INS_FDC, "fdc" }, { HPPA_INS_FDCE, "fdce" }, { HPPA_INS_FDIV, "fdiv" }, { HPPA_INS_FIC, "fic" }, { HPPA_INS_FICE, "fice" }, { HPPA_INS_FID, "fid" }, { HPPA_INS_FLDD, "fldd" }, { HPPA_INS_FLDDS, "fldds" }, { HPPA_INS_FLDDX, "flddx" }, { HPPA_INS_FLDW, "fldw" }, { HPPA_INS_FLDWS, "fldws" }, { HPPA_INS_FLDWX, "fldwx" }, { HPPA_INS_FMPY, "fmpy" }, { HPPA_INS_FMPYADD, "fmpyadd" }, { HPPA_INS_FMPYFADD, "fmpyfadd" }, { HPPA_INS_FMPYNFADD, "fmpynfadd" }, { HPPA_INS_FMPYSUB, "fmpysub" }, { HPPA_INS_FNEG, "fneg" }, { HPPA_INS_FNEGABS, "fnegabs" }, { HPPA_INS_FREM, "frem" }, { HPPA_INS_FRND, "frnd" }, { HPPA_INS_FSQRT, "fsqrt" }, { HPPA_INS_FSTD, "fstd" }, { HPPA_INS_FSTDS, "fstds" }, { HPPA_INS_FSTDX, "fstdx" }, { HPPA_INS_FSTW, "fstw" }, { HPPA_INS_FSTWS, "fstws" }, { HPPA_INS_FSTWX, "fstwx" }, { HPPA_INS_FSTQS, "fstqs" }, { HPPA_INS_FSTQX, "fstqx" }, { HPPA_INS_FSUB, "fsub" }, { HPPA_INS_FTEST, "ftest" }, { HPPA_INS_GATE, "gate" }, { HPPA_INS_GFR, "gfr" }, { HPPA_INS_GFW, "gfw" }, { HPPA_INS_GRSHDW, "grshdw" }, { HPPA_INS_HADD, "hadd" }, { HPPA_INS_HAVG, "havg" }, { HPPA_INS_HSHL, "hshl" }, { HPPA_INS_HSHLADD, "hshladd" }, { HPPA_INS_HSHR, "hshr" }, { HPPA_INS_HSHRADD, "hshradd" }, { HPPA_INS_HSUB, "hsub" }, { HPPA_INS_IDTLBA, "idtlba" }, { HPPA_INS_IDTLBP, "idtlbp" }, { HPPA_INS_IDTLBT, "idtlbt" }, { HPPA_INS_IDCOR, "idcor" }, { HPPA_INS_IITLBA, "iitlba" }, { HPPA_INS_IITLBP, "iitlbp" }, { HPPA_INS_IITLBT, "iitlbt" }, { HPPA_INS_LCI, "lci" }, { HPPA_INS_LDB, "ldb" }, { HPPA_INS_LDBS, "ldbs" }, { HPPA_INS_LDBX, "ldbx" }, { HPPA_INS_LDCD, "ldcd" }, { HPPA_INS_LDCW, "ldcw" }, { HPPA_INS_LDCWS, "ldcws" }, { HPPA_INS_LDCWX, "ldcwx" }, { HPPA_INS_LDD, "ldd" }, { HPPA_INS_LDDA, "ldda" }, { HPPA_INS_LDH, "ldh" }, { HPPA_INS_LDHS, "ldhs" }, { HPPA_INS_LDHX, "ldhx" }, { HPPA_INS_LDI, "ldi" }, { HPPA_INS_LDIL, "ldil" }, { HPPA_INS_LDO, "ldo" }, { HPPA_INS_LDSID, "ldsid" }, { HPPA_INS_LDW, "ldw" }, { HPPA_INS_LDWA, "ldwa" }, { HPPA_INS_LDWAS, "ldwas" }, { HPPA_INS_LDWAX, "ldwax" }, { HPPA_INS_LDWM, "ldwm" }, { HPPA_INS_LDWS, "ldws" }, { HPPA_INS_LDWX, "ldwx" }, { HPPA_INS_LPA, "lpa" }, { HPPA_INS_MFCPU, "mfcpu" }, { HPPA_INS_MFCTL, "mfctl" }, { HPPA_INS_MFIA, "mfia" }, { HPPA_INS_MFSP, "mfsp" }, { HPPA_INS_MIXH, "mixh" }, { HPPA_INS_MIXW, "mixw" }, { HPPA_INS_MOVB, "movb" }, { HPPA_INS_MOVIB, "movib" }, { HPPA_INS_MTCPU, "mtcpu" }, { HPPA_INS_MTCTL, "mtctl" }, { HPPA_INS_MTSAR, "mtsar" }, { HPPA_INS_MTSARCM, "mtsarcm" }, { HPPA_INS_MTSM, "mtsm" }, { HPPA_INS_MTSP, "mtsp" }, { HPPA_INS_NOP, "nop" }, { HPPA_INS_OR, "or" }, { HPPA_INS_PDC, "pdc" }, { HPPA_INS_PDTLB, "pdtlb" }, { HPPA_INS_PDTLBE, "pdtlbe" }, { HPPA_INS_PERMH, "permh" }, { HPPA_INS_PITLB, "pitlb" }, { HPPA_INS_PITLBE, "pitlbe" }, { HPPA_INS_PMDIS, "pmdis" }, { HPPA_INS_PMENB, "pmenb" }, { HPPA_INS_POPBTS, "popbts" }, { HPPA_INS_PROBE, "probe" }, { HPPA_INS_PROBEI, "probei" }, { HPPA_INS_PROBER, "prober" }, { HPPA_INS_PROBERI, "proberi" }, { HPPA_INS_PROBEW, "probew" }, { HPPA_INS_PROBEWI, "probewi" }, { HPPA_INS_PUSHBTS, "pushbts" }, { HPPA_INS_PUSHNOM, "pushnom" }, { HPPA_INS_RET, "ret" }, { HPPA_INS_RFI, "rfi" }, { HPPA_INS_RFIR, "rfir" }, { HPPA_INS_RSM, "rsm" }, { HPPA_INS_SHDWGR, "shdwgr" }, { HPPA_INS_SHLADD, "shladd" }, { HPPA_INS_SH1ADD, "sh1add" }, { HPPA_INS_SH1ADDL, "sh1addl" }, { HPPA_INS_SH1ADDO, "sh1addo" }, { HPPA_INS_SH2ADD, "sh2add" }, { HPPA_INS_SH2ADDL, "sh2addl" }, { HPPA_INS_SH2ADDO, "sh2addo" }, { HPPA_INS_SH3ADD, "sh3add" }, { HPPA_INS_SH3ADDL, "sh3addl" }, { HPPA_INS_SH3ADDO, "sh3addo" }, { HPPA_INS_SHD, "shd" }, { HPPA_INS_SHRPD, "shrpd" }, { HPPA_INS_SHRPW, "shrpw" }, { HPPA_INS_SPOP0, "spop0" }, { HPPA_INS_SPOP1, "spop1" }, { HPPA_INS_SPOP2, "spop2" }, { HPPA_INS_SPOP3, "spop3" }, { HPPA_INS_SSM, "ssm" }, { HPPA_INS_STB, "stb" }, { HPPA_INS_STBS, "stbs" }, { HPPA_INS_STBY, "stby" }, { HPPA_INS_STBYS, "stbys" }, { HPPA_INS_STD, "std" }, { HPPA_INS_STDA, "stda" }, { HPPA_INS_STDBY, "stdby" }, { HPPA_INS_STH, "sth" }, { HPPA_INS_STHS, "sths" }, { HPPA_INS_STW, "stw" }, { HPPA_INS_STWA, "stwa" }, { HPPA_INS_STWAS, "stwas" }, { HPPA_INS_STWS, "stws" }, { HPPA_INS_STWM, "stwm" }, { HPPA_INS_SUB, "sub" }, { HPPA_INS_SUBB, "subb" }, { HPPA_INS_SUBBO, "subbo" }, { HPPA_INS_SUBI, "subi" }, { HPPA_INS_SUBIO, "subio" }, { HPPA_INS_SUBO, "subo" }, { HPPA_INS_SUBT, "subt" }, { HPPA_INS_SUBTO, "subto" }, { HPPA_INS_SYNC, "sync" }, { HPPA_INS_SYNCDMA, "syncdma" }, { HPPA_INS_TOCDIS, "tocdis" }, { HPPA_INS_TOCEN, "tocen" }, { HPPA_INS_UADDCM, "uaddcm" }, { HPPA_INS_UADDCMT, "uaddcmt" }, { HPPA_INS_UXOR, "uxor" }, { HPPA_INS_VDEP, "vdep" }, { HPPA_INS_VDEPI, "vdepi" }, { HPPA_INS_VEXTRS, "vextrs" }, { HPPA_INS_VEXTRU, "vextru" }, { HPPA_INS_VSHD, "vshd" }, { HPPA_INS_XMPYU, "xmpyu" }, { HPPA_INS_XOR, "xor" }, { HPPA_INS_ZDEP, "zdep" }, { HPPA_INS_ZDEPI, "zdepi" }, { HPPA_INS_ZVDEP, "zvdep" }, { HPPA_INS_ZVDEPI, "zvdepi" }, }; #endif const char *HPPA_insn_name(csh handle, unsigned int id) { #ifndef CAPSTONE_DIET return id2name(insn_name_maps, ARR_SIZE(insn_name_maps), id); #else return NULL; #endif } #ifndef CAPSTONE_DIET /* Integer register names, indexed by the numbers which appear in the opcodes. */ static const char *const reg_names[] = { "flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1", "sp", "r31" }; /* Floating point register names, indexed by the numbers which appear in the opcodes. */ static const char *const fp_reg_names[] = { "fpsr", "fpe2", "fpe4", "fpe6", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31" }; static const char *const control_reg[] = { "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4", "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr", "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7" }; static const char *const space_reg[] = { "sr0", "sr1", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7" }; static const char *const fpe_reg[] = { "fpe1", "fpe3", "fpe5", "fpe7", "fr4R", "fr5R", "fr6R", "fr7R", "fr8R", "fr9R", "fr10R", "fr11R", "fr12R", "fr13R", "fr14R", "fr15R", "fr16R", "fr17R", "fr18R", "fr19R", "fr20R", "fr21R", "fr22R", "fr23R", "fr24R", "fr25R", "fr26R", "fr27R", "fr28R", "fr29R", "fr30R", "fr31R" }; static const char *const sp_fp_reg[] = { "fr16L", "fr17L", "fr18L", "fr19L", "fr20L", "fr21L", "fr22L", "fr23L", "fr24L", "fr25L", "fr26L", "fr27L", "fr28L", "fr29L", "fr30L", "fr31L", "fr16R", "fr17R", "fr18R", "fr19R", "fr20R", "fr21R", "fr22R", "fr23R", "fr24R", "fr25R", "fr26R", "fr27R", "fr28R", "fr29R", "fr30R", "fr31R" }; #endif const char *HPPA_reg_name(csh handle, unsigned int reg) { #ifndef CAPSTONE_DIET if (reg >= HPPA_REG_GR0 && reg <= HPPA_REG_GR31) return reg_names[reg - HPPA_REG_GR0]; else if (reg >= HPPA_REG_FPR0 && reg <= HPPA_REG_FPR31) return fp_reg_names[reg - HPPA_REG_FPR0]; else if (reg >= HPPA_REG_SR0 && reg <= HPPA_REG_SR7) return space_reg[reg - HPPA_REG_SR0]; else if (reg >= HPPA_REG_CR0 && reg <= HPPA_REG_CR31) return control_reg[reg - HPPA_REG_CR0]; else if (reg >= HPPA_REG_FPE0 && reg <= HPPA_REG_FPE31) return fpe_reg[reg - HPPA_REG_FPE0]; else if (reg >= HPPA_REG_SP_FPR0 && reg <= HPPA_REG_SP_FPR31) return sp_fp_reg[reg - HPPA_REG_SP_FPR0]; return NULL; #else return NULL; #endif } void HPPA_get_insn_id(cs_struct *h, cs_insn *insn, unsigned int opcode) { insn->id = opcode; } static void sort_and_uniq(cs_regs arr, uint8_t n, uint8_t *new_n) { /* arr is always a tiny (usually n < 3) array, * a simple O(n^2) sort is efficient enough. */ int i; int j; int iMin; int tmp; /* a modified selection sort for sorting and making unique */ for (j = 0; j < n; j++) { /* arr[iMin] will be min(arr[j .. n-1]) */ iMin = j; for (i = j + 1; i < n; i++) { if (arr[i] < arr[iMin]) iMin = i; } if (j != 0 && arr[iMin] == arr[j - 1]) { // duplicate ele found arr[iMin] = arr[n - 1]; --n; } else { tmp = arr[iMin]; arr[iMin] = arr[j]; arr[j] = tmp; } } *new_n = n; } void HPPA_reg_access(const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count) { uint8_t read_count = 0; uint8_t write_count = 0; const cs_hppa *hppa = &(insn->detail->hppa); for (unsigned i = 0; i < hppa->op_count; ++i) { const cs_hppa_op *op = &(hppa->operands[i]); switch (op->type) { case HPPA_OP_REG: case HPPA_OP_IDX_REG: if (op->access & CS_AC_READ) { regs_read[read_count++] = op->reg; } if (op->access & CS_AC_WRITE) { regs_write[write_count++] = op->reg; } break; case HPPA_OP_MEM: if (op->mem.space != HPPA_REG_INVALID) regs_read[read_count++] = op->mem.space; if (op->mem.base_access & CS_AC_READ) { regs_read[read_count++] = op->mem.base; } if (op->mem.base_access & CS_AC_WRITE) { regs_write[write_count++] = op->mem.base; } break; default: break; } } sort_and_uniq(regs_read, read_count, regs_read_count); sort_and_uniq(regs_write, write_count, regs_write_count); } #endif