xref: /aosp_15_r20/external/capstone/arch/PowerPC/PPCInstPrinter.c (revision 9a0e4156d50a75a99ec4f1653a0e9602a5d45c18)
1*9a0e4156SSadaf Ebrahimi //===-- PPCInstPrinter.cpp - Convert PPC MCInst to assembly syntax --------===//
2*9a0e4156SSadaf Ebrahimi //
3*9a0e4156SSadaf Ebrahimi //                     The LLVM Compiler Infrastructure
4*9a0e4156SSadaf Ebrahimi //
5*9a0e4156SSadaf Ebrahimi // This file is distributed under the University of Illinois Open Source
6*9a0e4156SSadaf Ebrahimi // License. See LICENSE.TXT for details.
7*9a0e4156SSadaf Ebrahimi //
8*9a0e4156SSadaf Ebrahimi //===----------------------------------------------------------------------===//
9*9a0e4156SSadaf Ebrahimi //
10*9a0e4156SSadaf Ebrahimi // This class prints an PPC MCInst to a .s file.
11*9a0e4156SSadaf Ebrahimi //
12*9a0e4156SSadaf Ebrahimi //===----------------------------------------------------------------------===//
13*9a0e4156SSadaf Ebrahimi 
14*9a0e4156SSadaf Ebrahimi /* Capstone Disassembly Engine */
15*9a0e4156SSadaf Ebrahimi /* By Nguyen Anh Quynh <[email protected]>, 2013-2015 */
16*9a0e4156SSadaf Ebrahimi 
17*9a0e4156SSadaf Ebrahimi #ifdef CAPSTONE_HAS_POWERPC
18*9a0e4156SSadaf Ebrahimi 
19*9a0e4156SSadaf Ebrahimi #include <stdio.h>
20*9a0e4156SSadaf Ebrahimi #include <stdlib.h>
21*9a0e4156SSadaf Ebrahimi #include <string.h>
22*9a0e4156SSadaf Ebrahimi 
23*9a0e4156SSadaf Ebrahimi #include "PPCInstPrinter.h"
24*9a0e4156SSadaf Ebrahimi #include "PPCPredicates.h"
25*9a0e4156SSadaf Ebrahimi #include "../../MCInst.h"
26*9a0e4156SSadaf Ebrahimi #include "../../utils.h"
27*9a0e4156SSadaf Ebrahimi #include "../../SStream.h"
28*9a0e4156SSadaf Ebrahimi #include "../../MCRegisterInfo.h"
29*9a0e4156SSadaf Ebrahimi #include "../../MathExtras.h"
30*9a0e4156SSadaf Ebrahimi #include "PPCMapping.h"
31*9a0e4156SSadaf Ebrahimi 
32*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_DIET
33*9a0e4156SSadaf Ebrahimi static const char *getRegisterName(unsigned RegNo);
34*9a0e4156SSadaf Ebrahimi #endif
35*9a0e4156SSadaf Ebrahimi 
36*9a0e4156SSadaf Ebrahimi static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
37*9a0e4156SSadaf Ebrahimi static void printInstruction(MCInst *MI, SStream *O, const MCRegisterInfo *MRI);
38*9a0e4156SSadaf Ebrahimi static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O);
39*9a0e4156SSadaf Ebrahimi static char *printAliasInstr(MCInst *MI, SStream *OS, void *info);
40*9a0e4156SSadaf Ebrahimi static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info);
41*9a0e4156SSadaf Ebrahimi static void printCustomAliasOperand(MCInst *MI, unsigned OpIdx,
42*9a0e4156SSadaf Ebrahimi 		unsigned PrintMethodIdx, SStream *OS);
43*9a0e4156SSadaf Ebrahimi 
44*9a0e4156SSadaf Ebrahimi #if 0
45*9a0e4156SSadaf Ebrahimi static void printRegName(SStream *OS, unsigned RegNo)
46*9a0e4156SSadaf Ebrahimi {
47*9a0e4156SSadaf Ebrahimi 	char *RegName = getRegisterName(RegNo);
48*9a0e4156SSadaf Ebrahimi 
49*9a0e4156SSadaf Ebrahimi 	if (RegName[0] == 'q' /* QPX */) {
50*9a0e4156SSadaf Ebrahimi 		// The system toolchain on the BG/Q does not understand QPX register names
51*9a0e4156SSadaf Ebrahimi 		// in .cfi_* directives, so print the name of the floating-point
52*9a0e4156SSadaf Ebrahimi 		// subregister instead.
53*9a0e4156SSadaf Ebrahimi 		RegName[0] = 'f';
54*9a0e4156SSadaf Ebrahimi 	}
55*9a0e4156SSadaf Ebrahimi 
56*9a0e4156SSadaf Ebrahimi 	SStream_concat0(OS, RegName);
57*9a0e4156SSadaf Ebrahimi }
58*9a0e4156SSadaf Ebrahimi #endif
59*9a0e4156SSadaf Ebrahimi 
set_mem_access(MCInst * MI,bool status)60*9a0e4156SSadaf Ebrahimi static void set_mem_access(MCInst *MI, bool status)
61*9a0e4156SSadaf Ebrahimi {
62*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail != CS_OPT_ON)
63*9a0e4156SSadaf Ebrahimi 		return;
64*9a0e4156SSadaf Ebrahimi 
65*9a0e4156SSadaf Ebrahimi 	MI->csh->doing_mem = status;
66*9a0e4156SSadaf Ebrahimi 
67*9a0e4156SSadaf Ebrahimi 	if (status) {
68*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_MEM;
69*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.base = PPC_REG_INVALID;
70*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = 0;
71*9a0e4156SSadaf Ebrahimi 	} else {
72*9a0e4156SSadaf Ebrahimi 		// done, create the next operand slot
73*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
74*9a0e4156SSadaf Ebrahimi 	}
75*9a0e4156SSadaf Ebrahimi }
76*9a0e4156SSadaf Ebrahimi 
PPC_post_printer(csh ud,cs_insn * insn,char * insn_asm,MCInst * mci)77*9a0e4156SSadaf Ebrahimi void PPC_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
78*9a0e4156SSadaf Ebrahimi {
79*9a0e4156SSadaf Ebrahimi 	if (((cs_struct *)ud)->detail != CS_OPT_ON)
80*9a0e4156SSadaf Ebrahimi 		return;
81*9a0e4156SSadaf Ebrahimi 
82*9a0e4156SSadaf Ebrahimi 	// check if this insn has branch hint
83*9a0e4156SSadaf Ebrahimi 	if (strrchr(insn_asm, '+') != NULL && !strstr(insn_asm, ".+")) {
84*9a0e4156SSadaf Ebrahimi 		insn->detail->ppc.bh = PPC_BH_PLUS;
85*9a0e4156SSadaf Ebrahimi 	} else if (strrchr(insn_asm, '-') != NULL) {
86*9a0e4156SSadaf Ebrahimi 		insn->detail->ppc.bh = PPC_BH_MINUS;
87*9a0e4156SSadaf Ebrahimi 	}
88*9a0e4156SSadaf Ebrahimi }
89*9a0e4156SSadaf Ebrahimi 
90*9a0e4156SSadaf Ebrahimi #define GET_INSTRINFO_ENUM
91*9a0e4156SSadaf Ebrahimi #include "PPCGenInstrInfo.inc"
92*9a0e4156SSadaf Ebrahimi 
isBOCTRBranch(unsigned int op)93*9a0e4156SSadaf Ebrahimi static int isBOCTRBranch(unsigned int op)
94*9a0e4156SSadaf Ebrahimi {
95*9a0e4156SSadaf Ebrahimi 	return ((op >= PPC_BDNZ) && (op <= PPC_BDZp));
96*9a0e4156SSadaf Ebrahimi }
97*9a0e4156SSadaf Ebrahimi 
PPC_printInst(MCInst * MI,SStream * O,void * Info)98*9a0e4156SSadaf Ebrahimi void PPC_printInst(MCInst *MI, SStream *O, void *Info)
99*9a0e4156SSadaf Ebrahimi {
100*9a0e4156SSadaf Ebrahimi 	char *mnem;
101*9a0e4156SSadaf Ebrahimi 
102*9a0e4156SSadaf Ebrahimi 	// Check for slwi/srwi mnemonics.
103*9a0e4156SSadaf Ebrahimi 	if (MCInst_getOpcode(MI) == PPC_RLWINM) {
104*9a0e4156SSadaf Ebrahimi 		unsigned char SH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 2));
105*9a0e4156SSadaf Ebrahimi 		unsigned char MB = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 3));
106*9a0e4156SSadaf Ebrahimi 		unsigned char ME = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 4));
107*9a0e4156SSadaf Ebrahimi 		bool useSubstituteMnemonic = false;
108*9a0e4156SSadaf Ebrahimi 
109*9a0e4156SSadaf Ebrahimi 		if (SH <= 31 && MB == 0 && ME == (31-SH)) {
110*9a0e4156SSadaf Ebrahimi 			SStream_concat0(O, "slwi\t");
111*9a0e4156SSadaf Ebrahimi 			MCInst_setOpcodePub(MI, PPC_INS_SLWI);
112*9a0e4156SSadaf Ebrahimi 			useSubstituteMnemonic = true;
113*9a0e4156SSadaf Ebrahimi 		}
114*9a0e4156SSadaf Ebrahimi 
115*9a0e4156SSadaf Ebrahimi 		if (SH <= 31 && MB == (32-SH) && ME == 31) {
116*9a0e4156SSadaf Ebrahimi 			SStream_concat0(O, "srwi\t");
117*9a0e4156SSadaf Ebrahimi 			MCInst_setOpcodePub(MI, PPC_INS_SRWI);
118*9a0e4156SSadaf Ebrahimi 			useSubstituteMnemonic = true;
119*9a0e4156SSadaf Ebrahimi 			SH = 32-SH;
120*9a0e4156SSadaf Ebrahimi 		}
121*9a0e4156SSadaf Ebrahimi 
122*9a0e4156SSadaf Ebrahimi 		if (useSubstituteMnemonic) {
123*9a0e4156SSadaf Ebrahimi 			printOperand(MI, 0, O);
124*9a0e4156SSadaf Ebrahimi 			SStream_concat0(O, ", ");
125*9a0e4156SSadaf Ebrahimi 			printOperand(MI, 1, O);
126*9a0e4156SSadaf Ebrahimi 			if (SH > HEX_THRESHOLD)
127*9a0e4156SSadaf Ebrahimi 				SStream_concat(O, ", 0x%x", (unsigned int)SH);
128*9a0e4156SSadaf Ebrahimi 			else
129*9a0e4156SSadaf Ebrahimi 				SStream_concat(O, ", %u", (unsigned int)SH);
130*9a0e4156SSadaf Ebrahimi 
131*9a0e4156SSadaf Ebrahimi 			if (MI->csh->detail) {
132*9a0e4156SSadaf Ebrahimi 				cs_ppc *ppc = &MI->flat_insn->detail->ppc;
133*9a0e4156SSadaf Ebrahimi 
134*9a0e4156SSadaf Ebrahimi 				ppc->operands[ppc->op_count].type = PPC_OP_IMM;
135*9a0e4156SSadaf Ebrahimi 				ppc->operands[ppc->op_count].imm = SH;
136*9a0e4156SSadaf Ebrahimi 				++ppc->op_count;
137*9a0e4156SSadaf Ebrahimi 			}
138*9a0e4156SSadaf Ebrahimi 
139*9a0e4156SSadaf Ebrahimi 			return;
140*9a0e4156SSadaf Ebrahimi 		}
141*9a0e4156SSadaf Ebrahimi 	}
142*9a0e4156SSadaf Ebrahimi 
143*9a0e4156SSadaf Ebrahimi 	if ((MCInst_getOpcode(MI) == PPC_OR || MCInst_getOpcode(MI) == PPC_OR8) &&
144*9a0e4156SSadaf Ebrahimi 			MCOperand_getReg(MCInst_getOperand(MI, 1)) == MCOperand_getReg(MCInst_getOperand(MI, 2))) {
145*9a0e4156SSadaf Ebrahimi 		SStream_concat0(O, "mr\t");
146*9a0e4156SSadaf Ebrahimi 		MCInst_setOpcodePub(MI, PPC_INS_MR);
147*9a0e4156SSadaf Ebrahimi 		printOperand(MI, 0, O);
148*9a0e4156SSadaf Ebrahimi 		SStream_concat0(O, ", ");
149*9a0e4156SSadaf Ebrahimi 		printOperand(MI, 1, O);
150*9a0e4156SSadaf Ebrahimi 		return;
151*9a0e4156SSadaf Ebrahimi 	}
152*9a0e4156SSadaf Ebrahimi 
153*9a0e4156SSadaf Ebrahimi 	if (MCInst_getOpcode(MI) == PPC_RLDICR) {
154*9a0e4156SSadaf Ebrahimi 		unsigned char SH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 2));
155*9a0e4156SSadaf Ebrahimi 		unsigned char ME = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 3));
156*9a0e4156SSadaf Ebrahimi 		// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
157*9a0e4156SSadaf Ebrahimi 		if (63-SH == ME) {
158*9a0e4156SSadaf Ebrahimi 			SStream_concat0(O, "sldi\t");
159*9a0e4156SSadaf Ebrahimi 			MCInst_setOpcodePub(MI, PPC_INS_SLDI);
160*9a0e4156SSadaf Ebrahimi 			printOperand(MI, 0, O);
161*9a0e4156SSadaf Ebrahimi 			SStream_concat0(O, ", ");
162*9a0e4156SSadaf Ebrahimi 			printOperand(MI, 1, O);
163*9a0e4156SSadaf Ebrahimi 			if (SH > HEX_THRESHOLD)
164*9a0e4156SSadaf Ebrahimi 				SStream_concat(O, ", 0x%x", (unsigned int)SH);
165*9a0e4156SSadaf Ebrahimi 			else
166*9a0e4156SSadaf Ebrahimi 				SStream_concat(O, ", %u", (unsigned int)SH);
167*9a0e4156SSadaf Ebrahimi 
168*9a0e4156SSadaf Ebrahimi 			return;
169*9a0e4156SSadaf Ebrahimi 		}
170*9a0e4156SSadaf Ebrahimi 	}
171*9a0e4156SSadaf Ebrahimi 
172*9a0e4156SSadaf Ebrahimi 	if ((MCInst_getOpcode(MI) == PPC_gBC)||(MCInst_getOpcode(MI) == PPC_gBCA)||
173*9a0e4156SSadaf Ebrahimi 			(MCInst_getOpcode(MI) == PPC_gBCL)||(MCInst_getOpcode(MI) == PPC_gBCLA)) {
174*9a0e4156SSadaf Ebrahimi 		int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 2));
175*9a0e4156SSadaf Ebrahimi 		bd = SignExtend64(bd, 14);
176*9a0e4156SSadaf Ebrahimi 		MCOperand_setImm(MCInst_getOperand(MI, 2),bd);
177*9a0e4156SSadaf Ebrahimi 	}
178*9a0e4156SSadaf Ebrahimi 
179*9a0e4156SSadaf Ebrahimi 	if (isBOCTRBranch(MCInst_getOpcode(MI))) {
180*9a0e4156SSadaf Ebrahimi 		if (MCOperand_isImm(MCInst_getOperand(MI,0)))
181*9a0e4156SSadaf Ebrahimi 		{
182*9a0e4156SSadaf Ebrahimi 			int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));
183*9a0e4156SSadaf Ebrahimi 			bd = SignExtend64(bd, 14);
184*9a0e4156SSadaf Ebrahimi 			MCOperand_setImm(MCInst_getOperand(MI, 0),bd);
185*9a0e4156SSadaf Ebrahimi 		}
186*9a0e4156SSadaf Ebrahimi 	}
187*9a0e4156SSadaf Ebrahimi 
188*9a0e4156SSadaf Ebrahimi 	if ((MCInst_getOpcode(MI) == PPC_B)||(MCInst_getOpcode(MI) == PPC_BA)||
189*9a0e4156SSadaf Ebrahimi 			(MCInst_getOpcode(MI) == PPC_BL)||(MCInst_getOpcode(MI) == PPC_BLA)) {
190*9a0e4156SSadaf Ebrahimi 		int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));
191*9a0e4156SSadaf Ebrahimi 		bd = SignExtend64(bd, 24);
192*9a0e4156SSadaf Ebrahimi 		MCOperand_setImm(MCInst_getOperand(MI, 0),bd);
193*9a0e4156SSadaf Ebrahimi 	}
194*9a0e4156SSadaf Ebrahimi 
195*9a0e4156SSadaf Ebrahimi 	// consider our own alias instructions first
196*9a0e4156SSadaf Ebrahimi 	mnem = printAliasInstrEx(MI, O, Info);
197*9a0e4156SSadaf Ebrahimi 	if (!mnem)
198*9a0e4156SSadaf Ebrahimi 		mnem = printAliasInstr(MI, O, Info);
199*9a0e4156SSadaf Ebrahimi 
200*9a0e4156SSadaf Ebrahimi 	if (mnem != NULL) {
201*9a0e4156SSadaf Ebrahimi 		if (strlen(mnem) > 0) {
202*9a0e4156SSadaf Ebrahimi 			struct ppc_alias alias;
203*9a0e4156SSadaf Ebrahimi 			// check to remove the last letter of ('.', '-', '+')
204*9a0e4156SSadaf Ebrahimi 			if (mnem[strlen(mnem) - 1] == '-' || mnem[strlen(mnem) - 1] == '+' || mnem[strlen(mnem) - 1] == '.')
205*9a0e4156SSadaf Ebrahimi 				mnem[strlen(mnem) - 1] = '\0';
206*9a0e4156SSadaf Ebrahimi 
207*9a0e4156SSadaf Ebrahimi 			if (PPC_alias_insn(mnem, &alias)) {
208*9a0e4156SSadaf Ebrahimi 				MCInst_setOpcodePub(MI, alias.id);
209*9a0e4156SSadaf Ebrahimi 				if (MI->csh->detail) {
210*9a0e4156SSadaf Ebrahimi 					MI->flat_insn->detail->ppc.bc = (ppc_bc)alias.cc;
211*9a0e4156SSadaf Ebrahimi 				}
212*9a0e4156SSadaf Ebrahimi 			}
213*9a0e4156SSadaf Ebrahimi 		}
214*9a0e4156SSadaf Ebrahimi 
215*9a0e4156SSadaf Ebrahimi 		cs_mem_free(mnem);
216*9a0e4156SSadaf Ebrahimi 	} else
217*9a0e4156SSadaf Ebrahimi 		printInstruction(MI, O, NULL);
218*9a0e4156SSadaf Ebrahimi }
219*9a0e4156SSadaf Ebrahimi 
220*9a0e4156SSadaf Ebrahimi enum ppc_bc_hint {
221*9a0e4156SSadaf Ebrahimi 	PPC_BC_LT_MINUS = (0 << 5) | 14,
222*9a0e4156SSadaf Ebrahimi 	PPC_BC_LE_MINUS = (1 << 5) |  6,
223*9a0e4156SSadaf Ebrahimi 	PPC_BC_EQ_MINUS = (2 << 5) | 14,
224*9a0e4156SSadaf Ebrahimi 	PPC_BC_GE_MINUS = (0 << 5) |  6,
225*9a0e4156SSadaf Ebrahimi 	PPC_BC_GT_MINUS = (1 << 5) | 14,
226*9a0e4156SSadaf Ebrahimi 	PPC_BC_NE_MINUS = (2 << 5) |  6,
227*9a0e4156SSadaf Ebrahimi 	PPC_BC_UN_MINUS = (3 << 5) | 14,
228*9a0e4156SSadaf Ebrahimi 	PPC_BC_NU_MINUS = (3 << 5) |  6,
229*9a0e4156SSadaf Ebrahimi 	PPC_BC_LT_PLUS  = (0 << 5) | 15,
230*9a0e4156SSadaf Ebrahimi 	PPC_BC_LE_PLUS  = (1 << 5) |  7,
231*9a0e4156SSadaf Ebrahimi 	PPC_BC_EQ_PLUS  = (2 << 5) | 15,
232*9a0e4156SSadaf Ebrahimi 	PPC_BC_GE_PLUS  = (0 << 5) |  7,
233*9a0e4156SSadaf Ebrahimi 	PPC_BC_GT_PLUS  = (1 << 5) | 15,
234*9a0e4156SSadaf Ebrahimi 	PPC_BC_NE_PLUS  = (2 << 5) |  7,
235*9a0e4156SSadaf Ebrahimi 	PPC_BC_UN_PLUS  = (3 << 5) | 15,
236*9a0e4156SSadaf Ebrahimi 	PPC_BC_NU_PLUS  = (3 << 5) |  7,
237*9a0e4156SSadaf Ebrahimi };
238*9a0e4156SSadaf Ebrahimi 
239*9a0e4156SSadaf Ebrahimi // normalize CC to remove _MINUS & _PLUS
cc_normalize(int cc)240*9a0e4156SSadaf Ebrahimi static int cc_normalize(int cc)
241*9a0e4156SSadaf Ebrahimi {
242*9a0e4156SSadaf Ebrahimi 	switch(cc) {
243*9a0e4156SSadaf Ebrahimi 		default: return cc;
244*9a0e4156SSadaf Ebrahimi 		case PPC_BC_LT_MINUS: return PPC_BC_LT;
245*9a0e4156SSadaf Ebrahimi 		case PPC_BC_LE_MINUS: return PPC_BC_LE;
246*9a0e4156SSadaf Ebrahimi 		case PPC_BC_EQ_MINUS: return PPC_BC_EQ;
247*9a0e4156SSadaf Ebrahimi 		case PPC_BC_GE_MINUS: return PPC_BC_GE;
248*9a0e4156SSadaf Ebrahimi 		case PPC_BC_GT_MINUS: return PPC_BC_GT;
249*9a0e4156SSadaf Ebrahimi 		case PPC_BC_NE_MINUS: return PPC_BC_NE;
250*9a0e4156SSadaf Ebrahimi 		case PPC_BC_UN_MINUS: return PPC_BC_UN;
251*9a0e4156SSadaf Ebrahimi 		case PPC_BC_NU_MINUS: return PPC_BC_NU;
252*9a0e4156SSadaf Ebrahimi 		case PPC_BC_LT_PLUS : return PPC_BC_LT;
253*9a0e4156SSadaf Ebrahimi 		case PPC_BC_LE_PLUS : return PPC_BC_LE;
254*9a0e4156SSadaf Ebrahimi 		case PPC_BC_EQ_PLUS : return PPC_BC_EQ;
255*9a0e4156SSadaf Ebrahimi 		case PPC_BC_GE_PLUS : return PPC_BC_GE;
256*9a0e4156SSadaf Ebrahimi 		case PPC_BC_GT_PLUS : return PPC_BC_GT;
257*9a0e4156SSadaf Ebrahimi 		case PPC_BC_NE_PLUS : return PPC_BC_NE;
258*9a0e4156SSadaf Ebrahimi 		case PPC_BC_UN_PLUS : return PPC_BC_UN;
259*9a0e4156SSadaf Ebrahimi 		case PPC_BC_NU_PLUS : return PPC_BC_NU;
260*9a0e4156SSadaf Ebrahimi 	}
261*9a0e4156SSadaf Ebrahimi }
262*9a0e4156SSadaf Ebrahimi 
printPredicateOperand(MCInst * MI,unsigned OpNo,SStream * O,const char * Modifier)263*9a0e4156SSadaf Ebrahimi static void printPredicateOperand(MCInst *MI, unsigned OpNo,
264*9a0e4156SSadaf Ebrahimi 		SStream *O, const char *Modifier)
265*9a0e4156SSadaf Ebrahimi {
266*9a0e4156SSadaf Ebrahimi 	unsigned Code = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
267*9a0e4156SSadaf Ebrahimi 
268*9a0e4156SSadaf Ebrahimi 	MI->flat_insn->detail->ppc.bc = (ppc_bc)cc_normalize(Code);
269*9a0e4156SSadaf Ebrahimi 
270*9a0e4156SSadaf Ebrahimi 	if (!strcmp(Modifier, "cc")) {
271*9a0e4156SSadaf Ebrahimi 		switch ((ppc_predicate)Code) {
272*9a0e4156SSadaf Ebrahimi 			default:	// unreachable
273*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LT_MINUS:
274*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LT_PLUS:
275*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LT:
276*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "lt");
277*9a0e4156SSadaf Ebrahimi 				return;
278*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LE_MINUS:
279*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LE_PLUS:
280*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LE:
281*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "le");
282*9a0e4156SSadaf Ebrahimi 				return;
283*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_EQ_MINUS:
284*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_EQ_PLUS:
285*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_EQ:
286*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "eq");
287*9a0e4156SSadaf Ebrahimi 				return;
288*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GE_MINUS:
289*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GE_PLUS:
290*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GE:
291*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "ge");
292*9a0e4156SSadaf Ebrahimi 				return;
293*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GT_MINUS:
294*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GT_PLUS:
295*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GT:
296*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "gt");
297*9a0e4156SSadaf Ebrahimi 				return;
298*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NE_MINUS:
299*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NE_PLUS:
300*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NE:
301*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "ne");
302*9a0e4156SSadaf Ebrahimi 				return;
303*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_UN_MINUS:
304*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_UN_PLUS:
305*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_UN:
306*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "un");
307*9a0e4156SSadaf Ebrahimi 				return;
308*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NU_MINUS:
309*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NU_PLUS:
310*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NU:
311*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "nu");
312*9a0e4156SSadaf Ebrahimi 				return;
313*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_BIT_SET:
314*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_BIT_UNSET:
315*9a0e4156SSadaf Ebrahimi 				// llvm_unreachable("Invalid use of bit predicate code");
316*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "invalid-predicate");
317*9a0e4156SSadaf Ebrahimi 				return;
318*9a0e4156SSadaf Ebrahimi 		}
319*9a0e4156SSadaf Ebrahimi 	}
320*9a0e4156SSadaf Ebrahimi 
321*9a0e4156SSadaf Ebrahimi 	if (!strcmp(Modifier, "pm")) {
322*9a0e4156SSadaf Ebrahimi 		switch ((ppc_predicate)Code) {
323*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LT:
324*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LE:
325*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_EQ:
326*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GE:
327*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GT:
328*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NE:
329*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_UN:
330*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NU:
331*9a0e4156SSadaf Ebrahimi 				return;
332*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LT_MINUS:
333*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LE_MINUS:
334*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_EQ_MINUS:
335*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GE_MINUS:
336*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GT_MINUS:
337*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NE_MINUS:
338*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_UN_MINUS:
339*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NU_MINUS:
340*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "-");
341*9a0e4156SSadaf Ebrahimi 				return;
342*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LT_PLUS:
343*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_LE_PLUS:
344*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_EQ_PLUS:
345*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GE_PLUS:
346*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_GT_PLUS:
347*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NE_PLUS:
348*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_UN_PLUS:
349*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_NU_PLUS:
350*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "+");
351*9a0e4156SSadaf Ebrahimi 				return;
352*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_BIT_SET:
353*9a0e4156SSadaf Ebrahimi 			case PPC_PRED_BIT_UNSET:
354*9a0e4156SSadaf Ebrahimi 				// llvm_unreachable("Invalid use of bit predicate code");
355*9a0e4156SSadaf Ebrahimi 				SStream_concat0(O, "invalid-predicate");
356*9a0e4156SSadaf Ebrahimi 				return;
357*9a0e4156SSadaf Ebrahimi 			default:	// unreachable
358*9a0e4156SSadaf Ebrahimi 				return;
359*9a0e4156SSadaf Ebrahimi 		}
360*9a0e4156SSadaf Ebrahimi 		// llvm_unreachable("Invalid predicate code");
361*9a0e4156SSadaf Ebrahimi 	}
362*9a0e4156SSadaf Ebrahimi 
363*9a0e4156SSadaf Ebrahimi 	//assert(StringRef(Modifier) == "reg" &&
364*9a0e4156SSadaf Ebrahimi 	//		"Need to specify 'cc', 'pm' or 'reg' as predicate op modifier!");
365*9a0e4156SSadaf Ebrahimi 	printOperand(MI, OpNo + 1, O);
366*9a0e4156SSadaf Ebrahimi }
367*9a0e4156SSadaf Ebrahimi 
printU2ImmOperand(MCInst * MI,unsigned OpNo,SStream * O)368*9a0e4156SSadaf Ebrahimi static void printU2ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
369*9a0e4156SSadaf Ebrahimi {
370*9a0e4156SSadaf Ebrahimi 	unsigned int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
371*9a0e4156SSadaf Ebrahimi 	//assert(Value <= 3 && "Invalid u2imm argument!");
372*9a0e4156SSadaf Ebrahimi 
373*9a0e4156SSadaf Ebrahimi 	if (Value > HEX_THRESHOLD)
374*9a0e4156SSadaf Ebrahimi 		SStream_concat(O, "0x%x", Value);
375*9a0e4156SSadaf Ebrahimi 	else
376*9a0e4156SSadaf Ebrahimi 		SStream_concat(O, "%u", Value);
377*9a0e4156SSadaf Ebrahimi 
378*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
379*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
380*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
381*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
382*9a0e4156SSadaf Ebrahimi 	}
383*9a0e4156SSadaf Ebrahimi }
384*9a0e4156SSadaf Ebrahimi 
printU4ImmOperand(MCInst * MI,unsigned OpNo,SStream * O)385*9a0e4156SSadaf Ebrahimi static void printU4ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
386*9a0e4156SSadaf Ebrahimi {
387*9a0e4156SSadaf Ebrahimi 	unsigned int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
388*9a0e4156SSadaf Ebrahimi 	//assert(Value <= 15 && "Invalid u4imm argument!");
389*9a0e4156SSadaf Ebrahimi 
390*9a0e4156SSadaf Ebrahimi 	if (Value > HEX_THRESHOLD)
391*9a0e4156SSadaf Ebrahimi 		SStream_concat(O, "0x%x", Value);
392*9a0e4156SSadaf Ebrahimi 	else
393*9a0e4156SSadaf Ebrahimi 		SStream_concat(O, "%u", Value);
394*9a0e4156SSadaf Ebrahimi 
395*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
396*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
397*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
398*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
399*9a0e4156SSadaf Ebrahimi 	}
400*9a0e4156SSadaf Ebrahimi }
401*9a0e4156SSadaf Ebrahimi 
printS5ImmOperand(MCInst * MI,unsigned OpNo,SStream * O)402*9a0e4156SSadaf Ebrahimi static void printS5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
403*9a0e4156SSadaf Ebrahimi {
404*9a0e4156SSadaf Ebrahimi 	int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
405*9a0e4156SSadaf Ebrahimi 	Value = SignExtend32(Value, 5);
406*9a0e4156SSadaf Ebrahimi 
407*9a0e4156SSadaf Ebrahimi 	printInt32(O, Value);
408*9a0e4156SSadaf Ebrahimi 
409*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
410*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
411*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
412*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
413*9a0e4156SSadaf Ebrahimi 	}
414*9a0e4156SSadaf Ebrahimi }
415*9a0e4156SSadaf Ebrahimi 
printU5ImmOperand(MCInst * MI,unsigned OpNo,SStream * O)416*9a0e4156SSadaf Ebrahimi static void printU5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
417*9a0e4156SSadaf Ebrahimi {
418*9a0e4156SSadaf Ebrahimi 	unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
419*9a0e4156SSadaf Ebrahimi 	//assert(Value <= 31 && "Invalid u5imm argument!");
420*9a0e4156SSadaf Ebrahimi 	printUInt32(O, Value);
421*9a0e4156SSadaf Ebrahimi 
422*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
423*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
424*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
425*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
426*9a0e4156SSadaf Ebrahimi 	}
427*9a0e4156SSadaf Ebrahimi }
428*9a0e4156SSadaf Ebrahimi 
printU6ImmOperand(MCInst * MI,unsigned OpNo,SStream * O)429*9a0e4156SSadaf Ebrahimi static void printU6ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
430*9a0e4156SSadaf Ebrahimi {
431*9a0e4156SSadaf Ebrahimi 	unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
432*9a0e4156SSadaf Ebrahimi 	//assert(Value <= 63 && "Invalid u6imm argument!");
433*9a0e4156SSadaf Ebrahimi 	printUInt32(O, Value);
434*9a0e4156SSadaf Ebrahimi 
435*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
436*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
437*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
438*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
439*9a0e4156SSadaf Ebrahimi 	}
440*9a0e4156SSadaf Ebrahimi }
441*9a0e4156SSadaf Ebrahimi 
printU12ImmOperand(MCInst * MI,unsigned OpNo,SStream * O)442*9a0e4156SSadaf Ebrahimi static void printU12ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
443*9a0e4156SSadaf Ebrahimi {
444*9a0e4156SSadaf Ebrahimi 	unsigned short Value = (unsigned short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
445*9a0e4156SSadaf Ebrahimi 
446*9a0e4156SSadaf Ebrahimi 	// assert(Value <= 4095 && "Invalid u12imm argument!");
447*9a0e4156SSadaf Ebrahimi 
448*9a0e4156SSadaf Ebrahimi 	if (Value > HEX_THRESHOLD)
449*9a0e4156SSadaf Ebrahimi 		SStream_concat(O, "0x%x", Value);
450*9a0e4156SSadaf Ebrahimi 	else
451*9a0e4156SSadaf Ebrahimi 		SStream_concat(O, "%u", Value);
452*9a0e4156SSadaf Ebrahimi 
453*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
454*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
455*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
456*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
457*9a0e4156SSadaf Ebrahimi 	}
458*9a0e4156SSadaf Ebrahimi }
459*9a0e4156SSadaf Ebrahimi 
printS16ImmOperand(MCInst * MI,unsigned OpNo,SStream * O)460*9a0e4156SSadaf Ebrahimi static void printS16ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
461*9a0e4156SSadaf Ebrahimi {
462*9a0e4156SSadaf Ebrahimi 	if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
463*9a0e4156SSadaf Ebrahimi 		unsigned short Imm = (unsigned short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
464*9a0e4156SSadaf Ebrahimi         if (Imm > HEX_THRESHOLD)
465*9a0e4156SSadaf Ebrahimi             SStream_concat(O, "0x%x", Imm);
466*9a0e4156SSadaf Ebrahimi         else
467*9a0e4156SSadaf Ebrahimi             SStream_concat(O, "%u", Imm);
468*9a0e4156SSadaf Ebrahimi 
469*9a0e4156SSadaf Ebrahimi 		if (MI->csh->detail) {
470*9a0e4156SSadaf Ebrahimi 			MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
471*9a0e4156SSadaf Ebrahimi 			MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;
472*9a0e4156SSadaf Ebrahimi 			MI->flat_insn->detail->ppc.op_count++;
473*9a0e4156SSadaf Ebrahimi 		}
474*9a0e4156SSadaf Ebrahimi 	} else
475*9a0e4156SSadaf Ebrahimi 		printOperand(MI, OpNo, O);
476*9a0e4156SSadaf Ebrahimi }
477*9a0e4156SSadaf Ebrahimi 
printS16ImmOperand_Mem(MCInst * MI,unsigned OpNo,SStream * O)478*9a0e4156SSadaf Ebrahimi static void printS16ImmOperand_Mem(MCInst *MI, unsigned OpNo, SStream *O)
479*9a0e4156SSadaf Ebrahimi {
480*9a0e4156SSadaf Ebrahimi 	if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
481*9a0e4156SSadaf Ebrahimi 		short Imm = (short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
482*9a0e4156SSadaf Ebrahimi 
483*9a0e4156SSadaf Ebrahimi 		if (Imm >= 0) {
484*9a0e4156SSadaf Ebrahimi 			if (Imm > HEX_THRESHOLD)
485*9a0e4156SSadaf Ebrahimi 				SStream_concat(O, "0x%x", Imm);
486*9a0e4156SSadaf Ebrahimi 			else
487*9a0e4156SSadaf Ebrahimi 				SStream_concat(O, "%u", Imm);
488*9a0e4156SSadaf Ebrahimi 		} else {
489*9a0e4156SSadaf Ebrahimi 			if (Imm < -HEX_THRESHOLD)
490*9a0e4156SSadaf Ebrahimi 				SStream_concat(O, "-0x%x", -Imm);
491*9a0e4156SSadaf Ebrahimi 			else
492*9a0e4156SSadaf Ebrahimi 				SStream_concat(O, "-%u", -Imm);
493*9a0e4156SSadaf Ebrahimi 		}
494*9a0e4156SSadaf Ebrahimi 
495*9a0e4156SSadaf Ebrahimi 		if (MI->csh->detail) {
496*9a0e4156SSadaf Ebrahimi 			if (MI->csh->doing_mem) {
497*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = Imm;
498*9a0e4156SSadaf Ebrahimi 			} else {
499*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
500*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;
501*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.op_count++;
502*9a0e4156SSadaf Ebrahimi 			}
503*9a0e4156SSadaf Ebrahimi 		}
504*9a0e4156SSadaf Ebrahimi 	} else
505*9a0e4156SSadaf Ebrahimi 		printOperand(MI, OpNo, O);
506*9a0e4156SSadaf Ebrahimi }
507*9a0e4156SSadaf Ebrahimi 
printU16ImmOperand(MCInst * MI,unsigned OpNo,SStream * O)508*9a0e4156SSadaf Ebrahimi static void printU16ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
509*9a0e4156SSadaf Ebrahimi {
510*9a0e4156SSadaf Ebrahimi 	if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
511*9a0e4156SSadaf Ebrahimi 		unsigned short Imm = (unsigned short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
512*9a0e4156SSadaf Ebrahimi 		if (Imm > HEX_THRESHOLD)
513*9a0e4156SSadaf Ebrahimi 			SStream_concat(O, "0x%x", Imm);
514*9a0e4156SSadaf Ebrahimi 		else
515*9a0e4156SSadaf Ebrahimi 			SStream_concat(O, "%u", Imm);
516*9a0e4156SSadaf Ebrahimi 
517*9a0e4156SSadaf Ebrahimi 		if (MI->csh->detail) {
518*9a0e4156SSadaf Ebrahimi 			MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
519*9a0e4156SSadaf Ebrahimi 			MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;
520*9a0e4156SSadaf Ebrahimi 			MI->flat_insn->detail->ppc.op_count++;
521*9a0e4156SSadaf Ebrahimi 		}
522*9a0e4156SSadaf Ebrahimi 	} else
523*9a0e4156SSadaf Ebrahimi 		printOperand(MI, OpNo, O);
524*9a0e4156SSadaf Ebrahimi }
525*9a0e4156SSadaf Ebrahimi 
printBranchOperand(MCInst * MI,unsigned OpNo,SStream * O)526*9a0e4156SSadaf Ebrahimi static void printBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
527*9a0e4156SSadaf Ebrahimi {
528*9a0e4156SSadaf Ebrahimi 	if (!MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
529*9a0e4156SSadaf Ebrahimi 		printOperand(MI, OpNo, O);
530*9a0e4156SSadaf Ebrahimi 		return;
531*9a0e4156SSadaf Ebrahimi 	}
532*9a0e4156SSadaf Ebrahimi 
533*9a0e4156SSadaf Ebrahimi 	// Branches can take an immediate operand.  This is used by the branch
534*9a0e4156SSadaf Ebrahimi 	// selection pass to print .+8, an eight byte displacement from the PC.
535*9a0e4156SSadaf Ebrahimi 	printAbsBranchOperand(MI, OpNo, O);
536*9a0e4156SSadaf Ebrahimi }
537*9a0e4156SSadaf Ebrahimi 
printAbsBranchOperand(MCInst * MI,unsigned OpNo,SStream * O)538*9a0e4156SSadaf Ebrahimi static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
539*9a0e4156SSadaf Ebrahimi {
540*9a0e4156SSadaf Ebrahimi 	int64_t imm;
541*9a0e4156SSadaf Ebrahimi 
542*9a0e4156SSadaf Ebrahimi 	if (!MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
543*9a0e4156SSadaf Ebrahimi 		printOperand(MI, OpNo, O);
544*9a0e4156SSadaf Ebrahimi 		return;
545*9a0e4156SSadaf Ebrahimi 	}
546*9a0e4156SSadaf Ebrahimi 
547*9a0e4156SSadaf Ebrahimi 	imm = MCOperand_getImm(MCInst_getOperand(MI, OpNo)) * 4;
548*9a0e4156SSadaf Ebrahimi 
549*9a0e4156SSadaf Ebrahimi 	if (!PPC_abs_branch(MI->csh, MCInst_getOpcode(MI))) {
550*9a0e4156SSadaf Ebrahimi 		imm = MI->address + imm;
551*9a0e4156SSadaf Ebrahimi 	}
552*9a0e4156SSadaf Ebrahimi 
553*9a0e4156SSadaf Ebrahimi 	SStream_concat(O, "0x%"PRIx64, imm);
554*9a0e4156SSadaf Ebrahimi 
555*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
556*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
557*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = imm;
558*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
559*9a0e4156SSadaf Ebrahimi 	}
560*9a0e4156SSadaf Ebrahimi }
561*9a0e4156SSadaf Ebrahimi 
562*9a0e4156SSadaf Ebrahimi 
563*9a0e4156SSadaf Ebrahimi #define GET_REGINFO_ENUM
564*9a0e4156SSadaf Ebrahimi #include "PPCGenRegisterInfo.inc"
565*9a0e4156SSadaf Ebrahimi 
printcrbitm(MCInst * MI,unsigned OpNo,SStream * O)566*9a0e4156SSadaf Ebrahimi static void printcrbitm(MCInst *MI, unsigned OpNo, SStream *O)
567*9a0e4156SSadaf Ebrahimi {
568*9a0e4156SSadaf Ebrahimi 	unsigned RegNo, tmp;
569*9a0e4156SSadaf Ebrahimi 	unsigned CCReg = MCOperand_getReg(MCInst_getOperand(MI, OpNo));
570*9a0e4156SSadaf Ebrahimi 
571*9a0e4156SSadaf Ebrahimi 	switch (CCReg) {
572*9a0e4156SSadaf Ebrahimi 		default: // llvm_unreachable("Unknown CR register");
573*9a0e4156SSadaf Ebrahimi 		case PPC_CR0: RegNo = 0; break;
574*9a0e4156SSadaf Ebrahimi 		case PPC_CR1: RegNo = 1; break;
575*9a0e4156SSadaf Ebrahimi 		case PPC_CR2: RegNo = 2; break;
576*9a0e4156SSadaf Ebrahimi 		case PPC_CR3: RegNo = 3; break;
577*9a0e4156SSadaf Ebrahimi 		case PPC_CR4: RegNo = 4; break;
578*9a0e4156SSadaf Ebrahimi 		case PPC_CR5: RegNo = 5; break;
579*9a0e4156SSadaf Ebrahimi 		case PPC_CR6: RegNo = 6; break;
580*9a0e4156SSadaf Ebrahimi 		case PPC_CR7: RegNo = 7; break;
581*9a0e4156SSadaf Ebrahimi 	}
582*9a0e4156SSadaf Ebrahimi 
583*9a0e4156SSadaf Ebrahimi 	tmp = 0x80 >> RegNo;
584*9a0e4156SSadaf Ebrahimi 	if (tmp > HEX_THRESHOLD)
585*9a0e4156SSadaf Ebrahimi 		SStream_concat(O, "0x%x", tmp);
586*9a0e4156SSadaf Ebrahimi 	else
587*9a0e4156SSadaf Ebrahimi 		SStream_concat(O, "%u", tmp);
588*9a0e4156SSadaf Ebrahimi }
589*9a0e4156SSadaf Ebrahimi 
printMemRegImm(MCInst * MI,unsigned OpNo,SStream * O)590*9a0e4156SSadaf Ebrahimi static void printMemRegImm(MCInst *MI, unsigned OpNo, SStream *O)
591*9a0e4156SSadaf Ebrahimi {
592*9a0e4156SSadaf Ebrahimi 	set_mem_access(MI, true);
593*9a0e4156SSadaf Ebrahimi 
594*9a0e4156SSadaf Ebrahimi 	printS16ImmOperand_Mem(MI, OpNo, O);
595*9a0e4156SSadaf Ebrahimi 
596*9a0e4156SSadaf Ebrahimi 	SStream_concat0(O, "(");
597*9a0e4156SSadaf Ebrahimi 
598*9a0e4156SSadaf Ebrahimi 	if (MCOperand_getReg(MCInst_getOperand(MI, OpNo + 1)) == PPC_R0)
599*9a0e4156SSadaf Ebrahimi 		SStream_concat0(O, "0");
600*9a0e4156SSadaf Ebrahimi 	else
601*9a0e4156SSadaf Ebrahimi 		printOperand(MI, OpNo + 1, O);
602*9a0e4156SSadaf Ebrahimi 
603*9a0e4156SSadaf Ebrahimi 	SStream_concat0(O, ")");
604*9a0e4156SSadaf Ebrahimi 	set_mem_access(MI, false);
605*9a0e4156SSadaf Ebrahimi }
606*9a0e4156SSadaf Ebrahimi 
printMemRegReg(MCInst * MI,unsigned OpNo,SStream * O)607*9a0e4156SSadaf Ebrahimi static void printMemRegReg(MCInst *MI, unsigned OpNo, SStream *O)
608*9a0e4156SSadaf Ebrahimi {
609*9a0e4156SSadaf Ebrahimi 	// When used as the base register, r0 reads constant zero rather than
610*9a0e4156SSadaf Ebrahimi 	// the value contained in the register.  For this reason, the darwin
611*9a0e4156SSadaf Ebrahimi 	// assembler requires that we print r0 as 0 (no r) when used as the base.
612*9a0e4156SSadaf Ebrahimi 	if (MCOperand_getReg(MCInst_getOperand(MI, OpNo)) == PPC_R0)
613*9a0e4156SSadaf Ebrahimi 		SStream_concat0(O, "0");
614*9a0e4156SSadaf Ebrahimi 	else
615*9a0e4156SSadaf Ebrahimi 		printOperand(MI, OpNo, O);
616*9a0e4156SSadaf Ebrahimi 	SStream_concat0(O, ", ");
617*9a0e4156SSadaf Ebrahimi 
618*9a0e4156SSadaf Ebrahimi 	printOperand(MI, OpNo + 1, O);
619*9a0e4156SSadaf Ebrahimi }
620*9a0e4156SSadaf Ebrahimi 
printTLSCall(MCInst * MI,unsigned OpNo,SStream * O)621*9a0e4156SSadaf Ebrahimi static void printTLSCall(MCInst *MI, unsigned OpNo, SStream *O)
622*9a0e4156SSadaf Ebrahimi {
623*9a0e4156SSadaf Ebrahimi 	set_mem_access(MI, true);
624*9a0e4156SSadaf Ebrahimi 	//printBranchOperand(MI, OpNo, O);
625*9a0e4156SSadaf Ebrahimi 
626*9a0e4156SSadaf Ebrahimi 	// On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must
627*9a0e4156SSadaf Ebrahimi 	// come at the _end_ of the expression.
628*9a0e4156SSadaf Ebrahimi 
629*9a0e4156SSadaf Ebrahimi 	SStream_concat0(O, "(");
630*9a0e4156SSadaf Ebrahimi 	printOperand(MI, OpNo + 1, O);
631*9a0e4156SSadaf Ebrahimi 	SStream_concat0(O, ")");
632*9a0e4156SSadaf Ebrahimi 	set_mem_access(MI, false);
633*9a0e4156SSadaf Ebrahimi }
634*9a0e4156SSadaf Ebrahimi 
635*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_DIET
636*9a0e4156SSadaf Ebrahimi /// stripRegisterPrefix - This method strips the character prefix from a
637*9a0e4156SSadaf Ebrahimi /// register name so that only the number is left.  Used by for linux asm.
stripRegisterPrefix(const char * RegName)638*9a0e4156SSadaf Ebrahimi static const char *stripRegisterPrefix(const char *RegName)
639*9a0e4156SSadaf Ebrahimi {
640*9a0e4156SSadaf Ebrahimi 	switch (RegName[0]) {
641*9a0e4156SSadaf Ebrahimi 		case 'r':
642*9a0e4156SSadaf Ebrahimi 		case 'f':
643*9a0e4156SSadaf Ebrahimi 		case 'q': // for QPX
644*9a0e4156SSadaf Ebrahimi 		case 'v':
645*9a0e4156SSadaf Ebrahimi 			if (RegName[1] == 's')
646*9a0e4156SSadaf Ebrahimi 				return RegName + 2;
647*9a0e4156SSadaf Ebrahimi 			return RegName + 1;
648*9a0e4156SSadaf Ebrahimi 		case 'c':
649*9a0e4156SSadaf Ebrahimi 			if (RegName[1] == 'r')
650*9a0e4156SSadaf Ebrahimi 				return RegName + 2;
651*9a0e4156SSadaf Ebrahimi 	}
652*9a0e4156SSadaf Ebrahimi 
653*9a0e4156SSadaf Ebrahimi 	return RegName;
654*9a0e4156SSadaf Ebrahimi }
655*9a0e4156SSadaf Ebrahimi #endif
656*9a0e4156SSadaf Ebrahimi 
printOperand(MCInst * MI,unsigned OpNo,SStream * O)657*9a0e4156SSadaf Ebrahimi static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
658*9a0e4156SSadaf Ebrahimi {
659*9a0e4156SSadaf Ebrahimi 	MCOperand *Op = MCInst_getOperand(MI, OpNo);
660*9a0e4156SSadaf Ebrahimi 	if (MCOperand_isReg(Op)) {
661*9a0e4156SSadaf Ebrahimi 		unsigned reg = MCOperand_getReg(Op);
662*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_DIET
663*9a0e4156SSadaf Ebrahimi 		const char *RegName = getRegisterName(reg);
664*9a0e4156SSadaf Ebrahimi #endif
665*9a0e4156SSadaf Ebrahimi 		// map to public register
666*9a0e4156SSadaf Ebrahimi 		reg = PPC_map_register(reg);
667*9a0e4156SSadaf Ebrahimi #ifndef CAPSTONE_DIET
668*9a0e4156SSadaf Ebrahimi 		// The linux and AIX assembler does not take register prefixes.
669*9a0e4156SSadaf Ebrahimi 		if (MI->csh->syntax == CS_OPT_SYNTAX_NOREGNAME)
670*9a0e4156SSadaf Ebrahimi 			RegName = stripRegisterPrefix(RegName);
671*9a0e4156SSadaf Ebrahimi 
672*9a0e4156SSadaf Ebrahimi 		SStream_concat0(O, RegName);
673*9a0e4156SSadaf Ebrahimi #endif
674*9a0e4156SSadaf Ebrahimi 
675*9a0e4156SSadaf Ebrahimi 		if (MI->csh->detail) {
676*9a0e4156SSadaf Ebrahimi 			if (MI->csh->doing_mem) {
677*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.base = reg;
678*9a0e4156SSadaf Ebrahimi 			} else {
679*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_REG;
680*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].reg = reg;
681*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.op_count++;
682*9a0e4156SSadaf Ebrahimi 			}
683*9a0e4156SSadaf Ebrahimi 		}
684*9a0e4156SSadaf Ebrahimi 
685*9a0e4156SSadaf Ebrahimi 		return;
686*9a0e4156SSadaf Ebrahimi 	}
687*9a0e4156SSadaf Ebrahimi 
688*9a0e4156SSadaf Ebrahimi 	if (MCOperand_isImm(Op)) {
689*9a0e4156SSadaf Ebrahimi 		int32_t imm = (int32_t)MCOperand_getImm(Op);
690*9a0e4156SSadaf Ebrahimi 		printInt32(O, imm);
691*9a0e4156SSadaf Ebrahimi 
692*9a0e4156SSadaf Ebrahimi 		if (MI->csh->detail) {
693*9a0e4156SSadaf Ebrahimi 			if (MI->csh->doing_mem) {
694*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = (int32_t)imm;
695*9a0e4156SSadaf Ebrahimi 			} else {
696*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
697*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = imm;
698*9a0e4156SSadaf Ebrahimi 				MI->flat_insn->detail->ppc.op_count++;
699*9a0e4156SSadaf Ebrahimi 			}
700*9a0e4156SSadaf Ebrahimi 		}
701*9a0e4156SSadaf Ebrahimi 	}
702*9a0e4156SSadaf Ebrahimi }
703*9a0e4156SSadaf Ebrahimi 
op_addImm(MCInst * MI,int v)704*9a0e4156SSadaf Ebrahimi static void op_addImm(MCInst *MI, int v)
705*9a0e4156SSadaf Ebrahimi {
706*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
707*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
708*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = v;
709*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
710*9a0e4156SSadaf Ebrahimi 	}
711*9a0e4156SSadaf Ebrahimi }
712*9a0e4156SSadaf Ebrahimi 
op_addReg(MCInst * MI,unsigned int reg)713*9a0e4156SSadaf Ebrahimi static void op_addReg(MCInst *MI, unsigned int reg)
714*9a0e4156SSadaf Ebrahimi {
715*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
716*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_REG;
717*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].reg = reg;
718*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.op_count++;
719*9a0e4156SSadaf Ebrahimi 	}
720*9a0e4156SSadaf Ebrahimi }
721*9a0e4156SSadaf Ebrahimi 
op_addBC(MCInst * MI,unsigned int bc)722*9a0e4156SSadaf Ebrahimi static void op_addBC(MCInst *MI, unsigned int bc)
723*9a0e4156SSadaf Ebrahimi {
724*9a0e4156SSadaf Ebrahimi 	if (MI->csh->detail) {
725*9a0e4156SSadaf Ebrahimi 		MI->flat_insn->detail->ppc.bc = (ppc_bc)bc;
726*9a0e4156SSadaf Ebrahimi 	}
727*9a0e4156SSadaf Ebrahimi }
728*9a0e4156SSadaf Ebrahimi 
729*9a0e4156SSadaf Ebrahimi #define CREQ (0)
730*9a0e4156SSadaf Ebrahimi #define CRGT (1)
731*9a0e4156SSadaf Ebrahimi #define CRLT (2)
732*9a0e4156SSadaf Ebrahimi #define CRUN (3)
733*9a0e4156SSadaf Ebrahimi 
getBICRCond(int bi)734*9a0e4156SSadaf Ebrahimi static int getBICRCond(int bi)
735*9a0e4156SSadaf Ebrahimi {
736*9a0e4156SSadaf Ebrahimi 	return (bi-PPC_CR0EQ) >> 3;
737*9a0e4156SSadaf Ebrahimi }
738*9a0e4156SSadaf Ebrahimi 
getBICR(int bi)739*9a0e4156SSadaf Ebrahimi static int getBICR(int bi)
740*9a0e4156SSadaf Ebrahimi {
741*9a0e4156SSadaf Ebrahimi 	return ((bi - PPC_CR0EQ) & 7) + PPC_CR0;
742*9a0e4156SSadaf Ebrahimi }
743*9a0e4156SSadaf Ebrahimi 
printAliasInstrEx(MCInst * MI,SStream * OS,void * info)744*9a0e4156SSadaf Ebrahimi static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
745*9a0e4156SSadaf Ebrahimi {
746*9a0e4156SSadaf Ebrahimi #define GETREGCLASS_CONTAIN(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), MCOperand_getReg(MCInst_getOperand(MI, _reg)))
747*9a0e4156SSadaf Ebrahimi 	SStream ss;
748*9a0e4156SSadaf Ebrahimi 	const char *opCode;
749*9a0e4156SSadaf Ebrahimi 	char *tmp, *AsmMnem, *AsmOps, *c;
750*9a0e4156SSadaf Ebrahimi 	int OpIdx, PrintMethodIdx;
751*9a0e4156SSadaf Ebrahimi 	int decCtr = false, needComma = false;
752*9a0e4156SSadaf Ebrahimi 	MCRegisterInfo *MRI = (MCRegisterInfo *)info;
753*9a0e4156SSadaf Ebrahimi 
754*9a0e4156SSadaf Ebrahimi 	SStream_Init(&ss);
755*9a0e4156SSadaf Ebrahimi 	switch (MCInst_getOpcode(MI)) {
756*9a0e4156SSadaf Ebrahimi 		default: return NULL;
757*9a0e4156SSadaf Ebrahimi 		case PPC_gBC:
758*9a0e4156SSadaf Ebrahimi 				 opCode = "b%s";
759*9a0e4156SSadaf Ebrahimi 				 break;
760*9a0e4156SSadaf Ebrahimi 		case PPC_gBCA:
761*9a0e4156SSadaf Ebrahimi 				 opCode = "b%sa";
762*9a0e4156SSadaf Ebrahimi 				 break;
763*9a0e4156SSadaf Ebrahimi 		case PPC_gBCCTR:
764*9a0e4156SSadaf Ebrahimi 				 opCode = "b%sctr";
765*9a0e4156SSadaf Ebrahimi 				 break;
766*9a0e4156SSadaf Ebrahimi 		case PPC_gBCCTRL:
767*9a0e4156SSadaf Ebrahimi 				 opCode = "b%sctrl";
768*9a0e4156SSadaf Ebrahimi 				 break;
769*9a0e4156SSadaf Ebrahimi 		case PPC_gBCL:
770*9a0e4156SSadaf Ebrahimi 				 opCode = "b%sl";
771*9a0e4156SSadaf Ebrahimi 				 break;
772*9a0e4156SSadaf Ebrahimi 		case PPC_gBCLA:
773*9a0e4156SSadaf Ebrahimi 				 opCode = "b%sla";
774*9a0e4156SSadaf Ebrahimi 				 break;
775*9a0e4156SSadaf Ebrahimi 		case PPC_gBCLR:
776*9a0e4156SSadaf Ebrahimi 				 opCode = "b%slr";
777*9a0e4156SSadaf Ebrahimi 				 break;
778*9a0e4156SSadaf Ebrahimi 		case PPC_gBCLRL:
779*9a0e4156SSadaf Ebrahimi 				 opCode = "b%slrl";
780*9a0e4156SSadaf Ebrahimi 				 break;
781*9a0e4156SSadaf Ebrahimi 	}
782*9a0e4156SSadaf Ebrahimi 
783*9a0e4156SSadaf Ebrahimi 	if (MCInst_getNumOperands(MI) == 3 &&
784*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
785*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 0) &&
786*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 1)) {
787*9a0e4156SSadaf Ebrahimi 		SStream_concat(&ss, opCode, "dnzf");
788*9a0e4156SSadaf Ebrahimi 		decCtr = true;
789*9a0e4156SSadaf Ebrahimi 	}
790*9a0e4156SSadaf Ebrahimi 
791*9a0e4156SSadaf Ebrahimi 	if (MCInst_getNumOperands(MI) == 3 &&
792*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
793*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 2) &&
794*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 3)) {
795*9a0e4156SSadaf Ebrahimi 		SStream_concat(&ss, opCode, "dzf");
796*9a0e4156SSadaf Ebrahimi 		decCtr = true;
797*9a0e4156SSadaf Ebrahimi 	}
798*9a0e4156SSadaf Ebrahimi 
799*9a0e4156SSadaf Ebrahimi 	if (MCInst_getNumOperands(MI) == 3 &&
800*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
801*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 4) &&
802*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 7) &&
803*9a0e4156SSadaf Ebrahimi 			MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
804*9a0e4156SSadaf Ebrahimi 			GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
805*9a0e4156SSadaf Ebrahimi 		int cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
806*9a0e4156SSadaf Ebrahimi 		switch(cr) {
807*9a0e4156SSadaf Ebrahimi 			case CREQ:
808*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, opCode, "ne");
809*9a0e4156SSadaf Ebrahimi 				break;
810*9a0e4156SSadaf Ebrahimi 			case CRGT:
811*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, opCode, "le");
812*9a0e4156SSadaf Ebrahimi 				break;
813*9a0e4156SSadaf Ebrahimi 			case CRLT:
814*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, opCode, "ge");
815*9a0e4156SSadaf Ebrahimi 				break;
816*9a0e4156SSadaf Ebrahimi 			case CRUN:
817*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, opCode, "ns");
818*9a0e4156SSadaf Ebrahimi 				break;
819*9a0e4156SSadaf Ebrahimi 		}
820*9a0e4156SSadaf Ebrahimi 
821*9a0e4156SSadaf Ebrahimi 		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 6)
822*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, "-");
823*9a0e4156SSadaf Ebrahimi 
824*9a0e4156SSadaf Ebrahimi 		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 7)
825*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, "+");
826*9a0e4156SSadaf Ebrahimi 
827*9a0e4156SSadaf Ebrahimi 		decCtr = false;
828*9a0e4156SSadaf Ebrahimi 	}
829*9a0e4156SSadaf Ebrahimi 
830*9a0e4156SSadaf Ebrahimi 	if (MCInst_getNumOperands(MI) == 3 &&
831*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
832*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 8) &&
833*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 9)) {
834*9a0e4156SSadaf Ebrahimi 		SStream_concat(&ss, opCode, "dnzt");
835*9a0e4156SSadaf Ebrahimi 		decCtr = true;
836*9a0e4156SSadaf Ebrahimi 	}
837*9a0e4156SSadaf Ebrahimi 
838*9a0e4156SSadaf Ebrahimi 	if (MCInst_getNumOperands(MI) == 3 &&
839*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
840*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 10) &&
841*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 11)) {
842*9a0e4156SSadaf Ebrahimi 		SStream_concat(&ss, opCode, "dzt");
843*9a0e4156SSadaf Ebrahimi 		decCtr = true;
844*9a0e4156SSadaf Ebrahimi 	}
845*9a0e4156SSadaf Ebrahimi 
846*9a0e4156SSadaf Ebrahimi 	if (MCInst_getNumOperands(MI) == 3 &&
847*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
848*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 12) &&
849*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 15) &&
850*9a0e4156SSadaf Ebrahimi 			MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
851*9a0e4156SSadaf Ebrahimi 			GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
852*9a0e4156SSadaf Ebrahimi 		int cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
853*9a0e4156SSadaf Ebrahimi 		switch(cr) {
854*9a0e4156SSadaf Ebrahimi 			case CREQ:
855*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, opCode, "eq");
856*9a0e4156SSadaf Ebrahimi 				break;
857*9a0e4156SSadaf Ebrahimi 			case CRGT:
858*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, opCode, "gt");
859*9a0e4156SSadaf Ebrahimi 				break;
860*9a0e4156SSadaf Ebrahimi 			case CRLT:
861*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, opCode, "lt");
862*9a0e4156SSadaf Ebrahimi 				break;
863*9a0e4156SSadaf Ebrahimi 			case CRUN:
864*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, opCode, "so");
865*9a0e4156SSadaf Ebrahimi 				break;
866*9a0e4156SSadaf Ebrahimi 		}
867*9a0e4156SSadaf Ebrahimi 
868*9a0e4156SSadaf Ebrahimi 		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 14)
869*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, "-");
870*9a0e4156SSadaf Ebrahimi 
871*9a0e4156SSadaf Ebrahimi 		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 15)
872*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, "+");
873*9a0e4156SSadaf Ebrahimi 
874*9a0e4156SSadaf Ebrahimi 		decCtr = false;
875*9a0e4156SSadaf Ebrahimi 	}
876*9a0e4156SSadaf Ebrahimi 
877*9a0e4156SSadaf Ebrahimi 	if (MCInst_getNumOperands(MI) == 3 &&
878*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
879*9a0e4156SSadaf Ebrahimi 			((MCOperand_getImm(MCInst_getOperand(MI, 0)) & 0x12)== 16)) {
880*9a0e4156SSadaf Ebrahimi 		SStream_concat(&ss, opCode, "dnz");
881*9a0e4156SSadaf Ebrahimi 
882*9a0e4156SSadaf Ebrahimi 		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 24)
883*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, "-");
884*9a0e4156SSadaf Ebrahimi 
885*9a0e4156SSadaf Ebrahimi 		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 25)
886*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, "+");
887*9a0e4156SSadaf Ebrahimi 
888*9a0e4156SSadaf Ebrahimi 		needComma = false;
889*9a0e4156SSadaf Ebrahimi 	}
890*9a0e4156SSadaf Ebrahimi 
891*9a0e4156SSadaf Ebrahimi 	if (MCInst_getNumOperands(MI) == 3 &&
892*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
893*9a0e4156SSadaf Ebrahimi 			((MCOperand_getImm(MCInst_getOperand(MI, 0)) & 0x12)== 18)) {
894*9a0e4156SSadaf Ebrahimi 		SStream_concat(&ss, opCode, "dz");
895*9a0e4156SSadaf Ebrahimi 
896*9a0e4156SSadaf Ebrahimi 		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 26)
897*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, "-");
898*9a0e4156SSadaf Ebrahimi 
899*9a0e4156SSadaf Ebrahimi 		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 27)
900*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, "+");
901*9a0e4156SSadaf Ebrahimi 
902*9a0e4156SSadaf Ebrahimi 		needComma = false;
903*9a0e4156SSadaf Ebrahimi 	}
904*9a0e4156SSadaf Ebrahimi 
905*9a0e4156SSadaf Ebrahimi 	if (MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
906*9a0e4156SSadaf Ebrahimi 			GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1) &&
907*9a0e4156SSadaf Ebrahimi 			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
908*9a0e4156SSadaf Ebrahimi 			(MCOperand_getImm(MCInst_getOperand(MI, 0)) < 16)) {
909*9a0e4156SSadaf Ebrahimi 		int cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));
910*9a0e4156SSadaf Ebrahimi 
911*9a0e4156SSadaf Ebrahimi 		if (decCtr) {
912*9a0e4156SSadaf Ebrahimi 			needComma = true;
913*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, " ");
914*9a0e4156SSadaf Ebrahimi 
915*9a0e4156SSadaf Ebrahimi 			if (cr > PPC_CR0) {
916*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, "4*cr%d+", cr - PPC_CR0);
917*9a0e4156SSadaf Ebrahimi 			}
918*9a0e4156SSadaf Ebrahimi 
919*9a0e4156SSadaf Ebrahimi 			cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
920*9a0e4156SSadaf Ebrahimi 			switch(cr) {
921*9a0e4156SSadaf Ebrahimi 				case CREQ:
922*9a0e4156SSadaf Ebrahimi 					SStream_concat0(&ss, "eq");
923*9a0e4156SSadaf Ebrahimi 					op_addBC(MI, PPC_BC_EQ);
924*9a0e4156SSadaf Ebrahimi 					break;
925*9a0e4156SSadaf Ebrahimi 				case CRGT:
926*9a0e4156SSadaf Ebrahimi 					SStream_concat0(&ss, "gt");
927*9a0e4156SSadaf Ebrahimi 					op_addBC(MI, PPC_BC_GT);
928*9a0e4156SSadaf Ebrahimi 					break;
929*9a0e4156SSadaf Ebrahimi 				case CRLT:
930*9a0e4156SSadaf Ebrahimi 					SStream_concat0(&ss, "lt");
931*9a0e4156SSadaf Ebrahimi 					op_addBC(MI, PPC_BC_LT);
932*9a0e4156SSadaf Ebrahimi 					break;
933*9a0e4156SSadaf Ebrahimi 				case CRUN:
934*9a0e4156SSadaf Ebrahimi 					SStream_concat0(&ss, "so");
935*9a0e4156SSadaf Ebrahimi 					op_addBC(MI, PPC_BC_SO);
936*9a0e4156SSadaf Ebrahimi 					break;
937*9a0e4156SSadaf Ebrahimi 			}
938*9a0e4156SSadaf Ebrahimi 
939*9a0e4156SSadaf Ebrahimi 			cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));
940*9a0e4156SSadaf Ebrahimi 			if (cr > PPC_CR0) {
941*9a0e4156SSadaf Ebrahimi 				if (MI->csh->detail) {
942*9a0e4156SSadaf Ebrahimi 					MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_CRX;
943*9a0e4156SSadaf Ebrahimi 					MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.scale = 4;
944*9a0e4156SSadaf Ebrahimi 					MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.reg = PPC_REG_CR0 + cr - PPC_CR0;
945*9a0e4156SSadaf Ebrahimi 					MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.cond = MI->flat_insn->detail->ppc.bc;
946*9a0e4156SSadaf Ebrahimi 					MI->flat_insn->detail->ppc.op_count++;
947*9a0e4156SSadaf Ebrahimi 				}
948*9a0e4156SSadaf Ebrahimi 			}
949*9a0e4156SSadaf Ebrahimi 		} else {
950*9a0e4156SSadaf Ebrahimi 			if (cr > PPC_CR0) {
951*9a0e4156SSadaf Ebrahimi 				needComma = true;
952*9a0e4156SSadaf Ebrahimi 				SStream_concat(&ss, " cr%d", cr - PPC_CR0);
953*9a0e4156SSadaf Ebrahimi 				op_addReg(MI, PPC_REG_CR0 + cr - PPC_CR0);
954*9a0e4156SSadaf Ebrahimi 			}
955*9a0e4156SSadaf Ebrahimi 		}
956*9a0e4156SSadaf Ebrahimi 	}
957*9a0e4156SSadaf Ebrahimi 
958*9a0e4156SSadaf Ebrahimi 	if (MCOperand_isImm(MCInst_getOperand(MI, 2)) &&
959*9a0e4156SSadaf Ebrahimi 			MCOperand_getImm(MCInst_getOperand(MI, 2)) != 0) {
960*9a0e4156SSadaf Ebrahimi 		if (needComma)
961*9a0e4156SSadaf Ebrahimi 			SStream_concat0(&ss, ",");
962*9a0e4156SSadaf Ebrahimi 
963*9a0e4156SSadaf Ebrahimi 		SStream_concat0(&ss, " $\xFF\x03\x01");
964*9a0e4156SSadaf Ebrahimi 	}
965*9a0e4156SSadaf Ebrahimi 
966*9a0e4156SSadaf Ebrahimi 	tmp = cs_strdup(ss.buffer);
967*9a0e4156SSadaf Ebrahimi 	AsmMnem = tmp;
968*9a0e4156SSadaf Ebrahimi 	for(AsmOps = tmp; *AsmOps; AsmOps++) {
969*9a0e4156SSadaf Ebrahimi 		if (*AsmOps == ' ' || *AsmOps == '\t') {
970*9a0e4156SSadaf Ebrahimi 			*AsmOps = '\0';
971*9a0e4156SSadaf Ebrahimi 			AsmOps++;
972*9a0e4156SSadaf Ebrahimi 			break;
973*9a0e4156SSadaf Ebrahimi 		}
974*9a0e4156SSadaf Ebrahimi 	}
975*9a0e4156SSadaf Ebrahimi 
976*9a0e4156SSadaf Ebrahimi 	SStream_concat0(OS, AsmMnem);
977*9a0e4156SSadaf Ebrahimi 	if (*AsmOps) {
978*9a0e4156SSadaf Ebrahimi 		SStream_concat0(OS, "\t");
979*9a0e4156SSadaf Ebrahimi 		for (c = AsmOps; *c; c++) {
980*9a0e4156SSadaf Ebrahimi 			if (*c == '$') {
981*9a0e4156SSadaf Ebrahimi 				c += 1;
982*9a0e4156SSadaf Ebrahimi 				if (*c == (char)0xff) {
983*9a0e4156SSadaf Ebrahimi 					c += 1;
984*9a0e4156SSadaf Ebrahimi 					OpIdx = *c - 1;
985*9a0e4156SSadaf Ebrahimi 					c += 1;
986*9a0e4156SSadaf Ebrahimi 					PrintMethodIdx = *c - 1;
987*9a0e4156SSadaf Ebrahimi 					printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);
988*9a0e4156SSadaf Ebrahimi 				} else
989*9a0e4156SSadaf Ebrahimi 					printOperand(MI, *c - 1, OS);
990*9a0e4156SSadaf Ebrahimi 			} else {
991*9a0e4156SSadaf Ebrahimi 				SStream_concat(OS, "%c", *c);
992*9a0e4156SSadaf Ebrahimi 			}
993*9a0e4156SSadaf Ebrahimi 		}
994*9a0e4156SSadaf Ebrahimi 	}
995*9a0e4156SSadaf Ebrahimi 
996*9a0e4156SSadaf Ebrahimi 	return tmp;
997*9a0e4156SSadaf Ebrahimi }
998*9a0e4156SSadaf Ebrahimi 
999*9a0e4156SSadaf Ebrahimi #define PRINT_ALIAS_INSTR
1000*9a0e4156SSadaf Ebrahimi #include "PPCGenAsmWriter.inc"
1001*9a0e4156SSadaf Ebrahimi 
1002*9a0e4156SSadaf Ebrahimi #endif
1003