예제 #1
0
static bool printSparcAliasInstr(MCInst *MI, SStream *O)
{
	switch (MCInst_getOpcode(MI)) {
		default: return false;
		case SP_JMPLrr:
		case SP_JMPLri:
				 if (MCInst_getNumOperands(MI) != 3)
					 return false;
				 if (!MCOperand_isReg(MCInst_getOperand(MI, 0)))
					 return false;

				 switch (MCOperand_getReg(MCInst_getOperand(MI, 0))) {
					 default: return false;
					 case SP_G0: // jmp $addr | ret | retl
							  if (MCOperand_isImm(MCInst_getOperand(MI, 2)) &&
									MCOperand_getImm(MCInst_getOperand(MI, 2)) == 8) {
								  switch(MCOperand_getReg(MCInst_getOperand(MI, 1))) {
									  default: break;
									  case SP_I7: SStream_concat0(O, "ret"); MCInst_setOpcodePub(MI, SPARC_INS_RET); return true;
									  case SP_O7: SStream_concat0(O, "retl"); MCInst_setOpcodePub(MI, SPARC_INS_RETL); return true;
								  }
							  }

							  SStream_concat0(O, "jmp\t");
							  MCInst_setOpcodePub(MI, SPARC_INS_JMP);
							  printMemOperand(MI, 1, O, NULL);
							  return true;
					 case SP_O7: // call $addr
							  SStream_concat0(O, "call ");
							  MCInst_setOpcodePub(MI, SPARC_INS_CALL);
							  printMemOperand(MI, 1, O, NULL);
							  return true;
				 }
		case SP_V9FCMPS:
		case SP_V9FCMPD:
		case SP_V9FCMPQ:
		case SP_V9FCMPES:
		case SP_V9FCMPED:
		case SP_V9FCMPEQ:
				 if (MI->csh->mode & CS_MODE_V9 || (MCInst_getNumOperands(MI) != 3) ||
						 (!MCOperand_isReg(MCInst_getOperand(MI, 0))) ||
						 (MCOperand_getReg(MCInst_getOperand(MI, 0)) != SP_FCC0))
						 return false;
				 // if V8, skip printing %fcc0.
				 switch(MCInst_getOpcode(MI)) {
					 default:
					 case SP_V9FCMPS:  SStream_concat0(O, "fcmps\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPS); break;
					 case SP_V9FCMPD:  SStream_concat0(O, "fcmpd\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPD); break;
					 case SP_V9FCMPQ:  SStream_concat0(O, "fcmpq\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPQ); break;
					 case SP_V9FCMPES: SStream_concat0(O, "fcmpes\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPES); break;
					 case SP_V9FCMPED: SStream_concat0(O, "fcmped\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPED); break;
					 case SP_V9FCMPEQ: SStream_concat0(O, "fcmpeq\t"); MCInst_setOpcodePub(MI, SPARC_INS_FCMPEQ); break;
				 }
				 printOperand(MI, 1, O);
				 SStream_concat0(O, ", ");
				 printOperand(MI, 2, O);
				 return true;
	}
}
예제 #2
0
static void printSaveRestore(MCInst *MI, SStream *O)
{
	unsigned i, e;
	for (i = 0, e = MCInst_getNumOperands(MI); i != e; ++i) {
		if (i != 0)
			SStream_concat(O, ", ");
		if (MCOperand_isReg(MCInst_getOperand(MI, i)))
			printRegName(O, MCOperand_getReg(MCInst_getOperand(MI, i)));
		else
			printUnsignedImm(MI, i, O);
	}
}
예제 #3
0
static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
{
#define GETREGCLASS_CONTAIN(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), MCOperand_getReg(MCInst_getOperand(MI, _reg)))
	SStream ss;
	const char *opCode;
	char *tmp, *AsmMnem, *AsmOps, *c;
	int OpIdx, PrintMethodIdx;
	int decCtr = false, needComma = false;
	MCRegisterInfo *MRI = (MCRegisterInfo *)info;

	SStream_Init(&ss);
	switch (MCInst_getOpcode(MI)) {
		default: return NULL;
		case PPC_gBC:
				 opCode = "b%s";
				 break;
		case PPC_gBCA:
				 opCode = "b%sa";
				 break;
		case PPC_gBCCTR:
				 opCode = "b%sctr";
				 break;
		case PPC_gBCCTRL:
				 opCode = "b%sctrl";
				 break;
		case PPC_gBCL:
				 opCode = "b%sl";
				 break;
		case PPC_gBCLA:
				 opCode = "b%sla";
				 break;
		case PPC_gBCLR:
				 opCode = "b%slr";
				 break;
		case PPC_gBCLRL:
				 opCode = "b%slrl";
				 break;
	}

	if (MCInst_getNumOperands(MI) == 3 &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 0) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 1)) {
		SStream_concat(&ss, opCode, "dnzf");
		decCtr = true;
	}

	if (MCInst_getNumOperands(MI) == 3 &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 2) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 3)) {
		SStream_concat(&ss, opCode, "dzf");
		decCtr = true;
	}

	if (MCInst_getNumOperands(MI) == 3 &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 4) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 7) &&
			MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
			GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
		int cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
		switch(cr) {
			case CREQ:
				SStream_concat(&ss, opCode, "ne");
				break;
			case CRGT:
				SStream_concat(&ss, opCode, "le");
				break;
			case CRLT:
				SStream_concat(&ss, opCode, "ge");
				break;
			case CRUN:
				SStream_concat(&ss, opCode, "ns");
				break;
		}

		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 6)
			SStream_concat0(&ss, "-");

		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 7)
			SStream_concat0(&ss, "+");

		decCtr = false;
	}

	if (MCInst_getNumOperands(MI) == 3 &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 8) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 9)) {
		SStream_concat(&ss, opCode, "dnzt");
		decCtr = true;
	}

	if (MCInst_getNumOperands(MI) == 3 &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 10) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 11)) {
		SStream_concat(&ss, opCode, "dzt");
		decCtr = true;
	}

	if (MCInst_getNumOperands(MI) == 3 &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 12) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 15) &&
			MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
			GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
		int cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
		switch(cr) {
			case CREQ:
				SStream_concat(&ss, opCode, "eq");
				break;
			case CRGT:
				SStream_concat(&ss, opCode, "gt");
				break;
			case CRLT:
				SStream_concat(&ss, opCode, "lt");
				break;
			case CRUN:
				SStream_concat(&ss, opCode, "so");
				break;
		}

		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 14)
			SStream_concat0(&ss, "-");

		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 15)
			SStream_concat0(&ss, "+");

		decCtr = false;
	}

	if (MCInst_getNumOperands(MI) == 3 &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			((MCOperand_getImm(MCInst_getOperand(MI, 0)) & 0x12)== 16)) {
		SStream_concat(&ss, opCode, "dnz");

		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 24)
			SStream_concat0(&ss, "-");

		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 25)
			SStream_concat0(&ss, "+");

		needComma = false;
	}

	if (MCInst_getNumOperands(MI) == 3 &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			((MCOperand_getImm(MCInst_getOperand(MI, 0)) & 0x12)== 18)) {
		SStream_concat(&ss, opCode, "dz");

		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 26)
			SStream_concat0(&ss, "-");

		if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 27)
			SStream_concat0(&ss, "+");

		needComma = false;
	}

	if (MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
			GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1) &&
			MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
			(MCOperand_getImm(MCInst_getOperand(MI, 0)) < 16)) {
		int cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));

		if (decCtr) {
			needComma = true;
			SStream_concat0(&ss, " ");

			if (cr > PPC_CR0) {
				SStream_concat(&ss, "4*cr%d+", cr - PPC_CR0);
			}

			cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
			switch(cr) {
				case CREQ:
					SStream_concat0(&ss, "eq");
					op_addBC(MI, PPC_BC_EQ);
					break;
				case CRGT:
					SStream_concat0(&ss, "gt");
					op_addBC(MI, PPC_BC_GT);
					break;
				case CRLT:
					SStream_concat0(&ss, "lt");
					op_addBC(MI, PPC_BC_LT);
					break;
				case CRUN:
					SStream_concat0(&ss, "so");
					op_addBC(MI, PPC_BC_SO);
					break;
			}

			cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));
			if (cr > PPC_CR0) {
				if (MI->csh->detail) {
					MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_CRX;
					MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.scale = 4;
					MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.reg = PPC_REG_CR0 + cr - PPC_CR0;
					MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.cond = MI->flat_insn->detail->ppc.bc;
					MI->flat_insn->detail->ppc.op_count++;
				}
			}
		} else {
			if (cr > PPC_CR0) {
				needComma = true;
				SStream_concat(&ss, " cr%d", cr - PPC_CR0);
				op_addReg(MI, PPC_REG_CR0 + cr - PPC_CR0);
			}
		}
	}

	if (MCOperand_isImm(MCInst_getOperand(MI, 2)) &&
			MCOperand_getImm(MCInst_getOperand(MI, 2)) != 0) {
		if (needComma)
			SStream_concat0(&ss, ",");

		SStream_concat0(&ss, " $\xFF\x03\x01");
	}

	tmp = cs_strdup(ss.buffer);
	AsmMnem = tmp;
	for(AsmOps = tmp; *AsmOps; AsmOps++) {
		if (*AsmOps == ' ' || *AsmOps == '\t') {
			*AsmOps = '\0';
			AsmOps++;
			break;
		}
	}

	SStream_concat0(OS, AsmMnem);
	if (*AsmOps) {
		SStream_concat0(OS, "\t");
		for (c = AsmOps; *c; c++) {
			if (*c == '$') {
				c += 1;
				if (*c == (char)0xff) {
					c += 1;
					OpIdx = *c - 1;
					c += 1;
					PrintMethodIdx = *c - 1;
					printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);
				} else
					printOperand(MI, *c - 1, OS);
			} else {
				SStream_concat(OS, "%c", *c);
			}
		}
	}

	return tmp;
}