17 #ifdef CAPSTONE_HAS_POWERPC
25 #include "../../MCInst.h"
26 #include "../../utils.h"
27 #include "../../SStream.h"
28 #include "../../MCRegisterInfo.h"
29 #include "../../MathExtras.h"
33 static const char *getRegisterName(
unsigned RegNo);
38 static void printAbsBranchOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O);
41 static void printCustomAliasOperand(
MCInst *MI,
unsigned OpIdx,
45 static void printRegName(
SStream *
OS,
unsigned RegNo)
47 char *RegName = getRegisterName(RegNo);
49 if (RegName[0] ==
'q' ) {
83 if (strrchr(insn_asm,
'+') !=
NULL && !strstr(insn_asm,
".+")) {
85 }
else if (strrchr(insn_asm,
'-') !=
NULL) {
90 #define GET_INSTRINFO_ENUM
93 static int isBOCTRBranch(
unsigned int op)
95 return ((
op >= PPC_BDNZ) && (
op <= PPC_BDZp));
107 bool useSubstituteMnemonic =
false;
109 if (
SH <= 31 &&
MB == 0 && ME == (31-
SH)) {
112 useSubstituteMnemonic =
true;
115 if (
SH <= 31 &&
MB == (32-
SH) && ME == 31) {
118 useSubstituteMnemonic =
true;
122 if (useSubstituteMnemonic) {
123 printOperand(MI, 0,
O);
125 printOperand(MI, 1,
O);
135 ppc->operands[
ppc->op_count].imm =
SH;
147 printOperand(MI, 0,
O);
149 printOperand(MI, 1,
O);
160 printOperand(MI, 0,
O);
162 printOperand(MI, 1,
O);
195 mnem = printAliasInstrEx(MI,
O, Info);
197 mnem = printAliasInstr(MI,
O, Info);
200 if (strlen(
mnem) > 0) {
218 printInstruction(MI,
O,
NULL);
222 PPC_BC_LT_MINUS = (0 << 5) | 14,
223 PPC_BC_LE_MINUS = (1 << 5) | 6,
224 PPC_BC_EQ_MINUS = (2 << 5) | 14,
225 PPC_BC_GE_MINUS = (0 << 5) | 6,
226 PPC_BC_GT_MINUS = (1 << 5) | 14,
227 PPC_BC_NE_MINUS = (2 << 5) | 6,
228 PPC_BC_UN_MINUS = (3 << 5) | 14,
229 PPC_BC_NU_MINUS = (3 << 5) | 6,
230 PPC_BC_LT_PLUS = (0 << 5) | 15,
231 PPC_BC_LE_PLUS = (1 << 5) | 7,
232 PPC_BC_EQ_PLUS = (2 << 5) | 15,
233 PPC_BC_GE_PLUS = (0 << 5) | 7,
234 PPC_BC_GT_PLUS = (1 << 5) | 15,
235 PPC_BC_NE_PLUS = (2 << 5) | 7,
236 PPC_BC_UN_PLUS = (3 << 5) | 15,
237 PPC_BC_NU_PLUS = (3 << 5) | 7,
241 static int cc_normalize(
int cc)
264 static void printPredicateOperand(
MCInst *MI,
unsigned OpNo,
271 if (!strcmp(Modifier,
"cc")) {
322 if (!strcmp(Modifier,
"pm")) {
366 printOperand(MI, OpNo + 1,
O);
369 static void printU2ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
386 static void printU4ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
403 static void printS5ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
417 static void printU5ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
430 static void printU6ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
443 static void printU12ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
461 static void printS16ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
476 printOperand(MI, OpNo,
O);
479 static void printS16ImmOperand_Mem(
MCInst *MI,
unsigned OpNo,
SStream *
O)
498 MI->
flat_insn->detail->ppc.operands[MI->
flat_insn->detail->ppc.op_count].mem.disp = Imm;
506 printOperand(MI, OpNo,
O);
509 static void printU16ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
524 printOperand(MI, OpNo,
O);
527 static void printBranchOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
530 printOperand(MI, OpNo,
O);
536 printAbsBranchOperand(MI, OpNo,
O);
539 static void printAbsBranchOperand(
MCInst *MI,
unsigned OpNo,
SStream *
O)
544 printOperand(MI, OpNo,
O);
564 #define GET_REGINFO_ENUM
574 case PPC_CR0: RegNo = 0;
break;
575 case PPC_CR1: RegNo = 1;
break;
576 case PPC_CR2: RegNo = 2;
break;
577 case PPC_CR3: RegNo = 3;
break;
578 case PPC_CR4: RegNo = 4;
break;
579 case PPC_CR5: RegNo = 5;
break;
580 case PPC_CR6: RegNo = 6;
break;
581 case PPC_CR7: RegNo = 7;
break;
593 set_mem_access(MI,
true);
595 printS16ImmOperand_Mem(MI, OpNo,
O);
602 printOperand(MI, OpNo + 1,
O);
605 set_mem_access(MI,
false);
616 printOperand(MI, OpNo,
O);
619 printOperand(MI, OpNo + 1,
O);
624 set_mem_access(MI,
true);
631 printOperand(MI, OpNo + 1,
O);
633 set_mem_access(MI,
false);
636 #ifndef CAPSTONE_DIET
639 static const char *stripRegisterPrefix(
const char *RegName)
641 switch (RegName[0]) {
646 if (RegName[1] ==
's')
650 if (RegName[1] ==
'r')
663 #ifndef CAPSTONE_DIET
664 const char *RegName = getRegisterName(
reg);
668 #ifndef CAPSTONE_DIET
671 RegName = stripRegisterPrefix(RegName);
723 static void op_addBC(
MCInst *MI,
unsigned int bc)
735 static int getBICRCond(
int bi)
737 return (bi-PPC_CR0EQ) >> 3;
740 static int getBICR(
int bi)
742 return ((bi - PPC_CR0EQ) & 7) + PPC_CR0;
747 #define GETREGCLASS_CONTAIN(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), MCOperand_getReg(MCInst_getOperand(MI, _reg)))
750 char *
tmp, *AsmMnem, *AsmOps, *
c;
751 int OpIdx, PrintMethodIdx;
752 int decCtr =
false, needComma =
false;
757 default:
return NULL;
805 GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
852 GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
907 GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1) &&
944 MI->
flat_insn->detail->ppc.operands[MI->
flat_insn->detail->ppc.op_count].crx.scale = 4;
969 for(AsmOps =
tmp; *AsmOps; AsmOps++) {
970 if (*AsmOps ==
' ' || *AsmOps ==
'\t') {
980 for (
c = AsmOps; *
c;
c++) {
983 if (*
c == (
char)0xff) {
987 PrintMethodIdx = *
c - 1;
988 printCustomAliasOperand(MI, OpIdx, PrintMethodIdx,
OS);
990 printOperand(MI, *
c - 1,
OS);
1000 #define PRINT_ALIAS_INSTR
unsigned MCInst_getOpcode(const MCInst *inst)
unsigned MCInst_getNumOperands(const MCInst *inst)
MCOperand * MCInst_getOperand(MCInst *inst, unsigned i)
void MCOperand_setImm(MCOperand *op, int64_t Val)
bool MCOperand_isReg(const MCOperand *op)
void MCInst_setOpcodePub(MCInst *inst, unsigned Op)
int64_t MCOperand_getImm(MCOperand *op)
unsigned MCOperand_getReg(const MCOperand *op)
getReg - Returns the register number.
bool MCOperand_isImm(const MCOperand *op)
void PPC_printInst(MCInst *MI, SStream *O, void *Info)
void PPC_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
ppc_reg PPC_map_register(unsigned int r)
bool PPC_alias_insn(const char *name, struct ppc_alias *alias)
bool PPC_abs_branch(cs_struct *h, unsigned int id)
ppc_insn PPC_map_insn(const char *name)
void SStream_Init(SStream *ss)
void SStream_concat(SStream *ss, const char *fmt,...)
void SStream_concat0(SStream *ss, const char *s)
void printUInt32(SStream *O, uint32_t val)
void printInt32(SStream *O, int32_t val)
void op_addImm(MCInst *MI, int v)
void op_addReg(MCInst *MI, int reg)
RzBinInfo * info(RzBinFile *bf)
@ CS_OPT_SYNTAX_NOREGNAME
Prints register name with only number (CS_OPT_SYNTAX)
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
static const char struct stat static buf struct stat static buf static vhangup int status
@ PPC_BH_MINUS
MINUS hint.
@ PPC_OP_REG
= CS_OP_REG (Register operand).
@ PPC_OP_IMM
= CS_OP_IMM (Immediate operand).
@ PPC_OP_MEM
= CS_OP_MEM (Memory operand).
@ PPC_OP_CRX
Condition Register field.
ppc_bc
PPC branch codes for some branch instructions.
@ PPC_BC_SO
summary overflow
char * cs_strdup(const char *str)