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);
36 static void printOperand(
MCInst *MI,
unsigned OpNo,
SStream *O);
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
91 #include "PPCGenInstrInfo.inc"
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);
196 mnem = printAliasInstrEx(MI, O, Info);
198 mnem = printAliasInstr(MI, O, Info);
201 if (strlen(mnem) > 0) {
217 printInstruction(MI, O, NULL);
221 PPC_BC_LT_MINUS = (0 << 5) | 14,
222 PPC_BC_LE_MINUS = (1 << 5) | 6,
223 PPC_BC_EQ_MINUS = (2 << 5) | 14,
224 PPC_BC_GE_MINUS = (0 << 5) | 6,
225 PPC_BC_GT_MINUS = (1 << 5) | 14,
226 PPC_BC_NE_MINUS = (2 << 5) | 6,
227 PPC_BC_UN_MINUS = (3 << 5) | 14,
228 PPC_BC_NU_MINUS = (3 << 5) | 6,
229 PPC_BC_LT_PLUS = (0 << 5) | 15,
230 PPC_BC_LE_PLUS = (1 << 5) | 7,
231 PPC_BC_EQ_PLUS = (2 << 5) | 15,
232 PPC_BC_GE_PLUS = (0 << 5) | 7,
233 PPC_BC_GT_PLUS = (1 << 5) | 15,
234 PPC_BC_NE_PLUS = (2 << 5) | 7,
235 PPC_BC_UN_PLUS = (3 << 5) | 15,
236 PPC_BC_NU_PLUS = (3 << 5) | 7,
240 static int cc_normalize(
int cc)
263 static void printPredicateOperand(
MCInst *MI,
unsigned OpNo,
264 SStream *O,
const char *Modifier)
270 if (!strcmp(Modifier,
"cc")) {
321 if (!strcmp(Modifier,
"pm")) {
365 printOperand(MI, OpNo + 1, O);
368 static void printU2ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
385 static void printU4ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
402 static void printS5ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
416 static void printU5ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
429 static void printU6ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
442 static void printU12ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
460 static void printS16ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
475 printOperand(MI, OpNo, O);
478 static void printS16ImmOperand_Mem(
MCInst *MI,
unsigned OpNo,
SStream *O)
497 MI->
flat_insn->detail->ppc.operands[MI->
flat_insn->detail->ppc.op_count].mem.disp = Imm;
505 printOperand(MI, OpNo, O);
508 static void printU16ImmOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
523 printOperand(MI, OpNo, O);
526 static void printBranchOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
529 printOperand(MI, OpNo, O);
535 printAbsBranchOperand(MI, OpNo, O);
538 static void printAbsBranchOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
543 printOperand(MI, OpNo, O);
563 #define GET_REGINFO_ENUM
564 #include "PPCGenRegisterInfo.inc"
566 static void printcrbitm(
MCInst *MI,
unsigned OpNo,
SStream *O)
573 case PPC_CR0: RegNo = 0;
break;
574 case PPC_CR1: RegNo = 1;
break;
575 case PPC_CR2: RegNo = 2;
break;
576 case PPC_CR3: RegNo = 3;
break;
577 case PPC_CR4: RegNo = 4;
break;
578 case PPC_CR5: RegNo = 5;
break;
579 case PPC_CR6: RegNo = 6;
break;
580 case PPC_CR7: RegNo = 7;
break;
590 static void printMemRegImm(
MCInst *MI,
unsigned OpNo,
SStream *O)
592 set_mem_access(MI,
true);
594 printS16ImmOperand_Mem(MI, OpNo, O);
601 printOperand(MI, OpNo + 1, O);
604 set_mem_access(MI,
false);
607 static void printMemRegReg(
MCInst *MI,
unsigned OpNo,
SStream *O)
615 printOperand(MI, OpNo, O);
618 printOperand(MI, OpNo + 1, O);
621 static void printTLSCall(
MCInst *MI,
unsigned OpNo,
SStream *O)
623 set_mem_access(MI,
true);
630 printOperand(MI, OpNo + 1, O);
632 set_mem_access(MI,
false);
635 #ifndef CAPSTONE_DIET
636 static const char *stripRegisterPrefix(
const char *RegName)
640 switch (RegName[0]) {
645 if (RegName[1] ==
's')
649 if (RegName[1] ==
'r')
657 static void printOperand(
MCInst *MI,
unsigned OpNo,
SStream *O)
662 #ifndef CAPSTONE_DIET
663 const char *RegName = getRegisterName(reg);
667 #ifndef CAPSTONE_DIET
670 RegName = stripRegisterPrefix(RegName);
677 MI->
flat_insn->detail->ppc.operands[MI->
flat_insn->detail->ppc.op_count].mem.base = reg;
722 static void op_addBC(
MCInst *MI,
unsigned int bc)
734 static int getBICRCond(
int bi)
736 return (
bi-PPC_CR0EQ) >> 3;
739 static int getBICR(
int bi)
741 return ((
bi - PPC_CR0EQ) & 7) + PPC_CR0;
746 #define GETREGCLASS_CONTAIN(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), MCOperand_getReg(MCInst_getOperand(MI, _reg)))
749 char *
tmp, *AsmMnem, *AsmOps, *
c;
750 int OpIdx, PrintMethodIdx;
751 int decCtr =
false, needComma =
false;
756 default:
return NULL;
804 GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
851 GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
906 GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1) &&
943 MI->
flat_insn->detail->ppc.operands[MI->
flat_insn->detail->ppc.op_count].crx.scale = 4;
968 for(AsmOps =
tmp; *AsmOps; AsmOps++) {
969 if (*AsmOps ==
' ' || *AsmOps ==
'\t') {
979 for (
c = AsmOps; *
c;
c++) {
982 if (*
c == (
char)0xff) {
986 PrintMethodIdx = *
c - 1;
987 printCustomAliasOperand(MI, OpIdx, PrintMethodIdx,
OS);
989 printOperand(MI, *
c - 1,
OS);
999 #define PRINT_ALIAS_INSTR
1000 #include "PPCGenAsmWriter.inc"