static DecodeStatus DecodeDaddiGroupBranch_4(MCInst *MI, uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder) { // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled // (otherwise we would have matched the ADDI instruction from the earlier // ISA's instead). // // We have: // 0b011000 sssss ttttt iiiiiiiiiiiiiiii // BNVC if rs >= rt // BNEZALC if rs == 0 && rt != 0 // BNEC if rs < rt && rs != 0 uint32_t Rs = fieldFromInstruction(insn, 21, 5); uint32_t Rt = fieldFromInstruction(insn, 16, 5); uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; bool HasRs = false; if (Rs >= Rt) { MCInst_setOpcode(MI, Mips_BNVC); HasRs = true; } else if (Rs != 0 && Rs < Rt) { MCInst_setOpcode(MI, Mips_BNEC); HasRs = true; } else MCInst_setOpcode(MI, Mips_BNEZALC); if (HasRs) MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs)); MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt)); MCOperand_CreateImm0(MI, Imm); return MCDisassembler_Success; }
void Mips_printInst(MCInst *MI, SStream *O, void *info) { switch (MCInst_getOpcode(MI)) { default: break; case Mips_RDHWR: case Mips_RDHWR64: SStream_concat(O, ".set\tpush\n"); SStream_concat(O, ".set\tmips32r2\n"); break; case Mips_Save16: SStream_concat(O, "\tsave\t"); printSaveRestore(MI, O); SStream_concat(O, " # 16 bit inst\n"); return; case Mips_SaveX16: SStream_concat(O, "\tsave\t"); printSaveRestore(MI, O); SStream_concat(O, "\n"); return; case Mips_Restore16: SStream_concat(O, "\trestore\t"); printSaveRestore(MI, O); SStream_concat(O, " # 16 bit inst\n"); return; case Mips_RestoreX16: SStream_concat(O, "\trestore\t"); printSaveRestore(MI, O); SStream_concat(O, "\n"); return; } // Try to print any aliases first. if (!printAliasInstr(MI, O, info) && !printAlias(MI, O)) printInstruction(MI, O, NULL); else { // fixup instruction id due to the change in alias instruction char *mnem = cs_strdup(O->buffer); char *tab = strchr(mnem, '\t'); if (tab) *tab = '\0'; // reflect the new insn name (alias) in the opcode unsigned id = Mips_map_insn(mnem); MCInst_setOpcode(MI, Mips_get_insn_id2(id)); MCInst_setOpcodePub(MI, id); cs_mem_free(mnem); } switch (MCInst_getOpcode(MI)) { default: break; case Mips_RDHWR: case Mips_RDHWR64: SStream_concat(O, "\n.set\tpop"); break; } }
static DecodeStatus DecodeBgtzlGroupBranch_4(MCInst *MI, uint32_t insn, uint64_t Address, MCRegisterInfo *Decoder) { // If we are called then we can assume that MIPS32r6/MIPS64r6 is enabled // (otherwise we would have matched the BGTZL instruction from the earlier // ISA's instead). // // We have: // 0b010111 sssss ttttt iiiiiiiiiiiiiiii // Invalid if rs == 0 // BGTZC if rs == 0 && rt != 0 // BLTZC if rs == rt && rt != 0 // BLTC if rs != rt && rs != 0 && rt != 0 bool HasRs = false; uint32_t Rs = fieldFromInstruction(insn, 21, 5); uint32_t Rt = fieldFromInstruction(insn, 16, 5); uint32_t Imm = (uint32_t)SignExtend64(fieldFromInstruction(insn, 0, 16), 16) * 4; if (Rt == 0) return MCDisassembler_Fail; else if (Rs == 0) MCInst_setOpcode(MI, Mips_BGTZC); else if (Rs == Rt) MCInst_setOpcode(MI, Mips_BLTZC); else { MCInst_setOpcode(MI, Mips_BLTC); HasRs = true; } if (HasRs) MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rs)); MCOperand_CreateReg0(MI, getReg(Decoder, Mips_GPR32RegClassID, Rt)); MCOperand_CreateImm0(MI, Imm); return MCDisassembler_Success; }
static DecodeStatus DecodeL5RInstructionFail(MCInst *Inst, unsigned Insn, uint64_t Address, void *Decoder) { unsigned Opcode; // Try and decode as a L6R instruction. MCInst_clear(Inst); Opcode = fieldFromInstruction_4(Insn, 27, 5); switch (Opcode) { default: break; case 0x00: MCInst_setOpcode(Inst, XCore_LMUL_l6r); return DecodeL6RInstruction(Inst, Insn, Address, Decoder); } return MCDisassembler_Fail; }
void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info) { //if (TSFlags & X86II::LOCK) // O << "\tlock\n"; if (printAliasInstr(MI, O)) { char *mnem = cs_strdup(O->buffer); char *tab = strchr(mnem, '\t'); if (tab) *tab = '\0'; // reflect the new insn name (alias) in the opcode MCInst_setOpcode(MI, X86_get_insn_id2(X86_map_insn(mnem))); cs_mem_free(mnem); } else printInstruction(MI, O, NULL); if (MI->csh->detail) { char tmp[64]; if (get_first_op(O->buffer, tmp)) { int post; char *acc_regs[] = { "al", "ax", "eax", "rax", NULL }; unsigned int acc_regs_id[] = { X86_REG_AL, X86_REG_AX, X86_REG_EAX, X86_REG_RAX }; if (tmp[0] != 0 && ((post = str_in_list(acc_regs, tmp)) != -1)) { // first op is register, so set operand size following register size MI->flat_insn.x86.op_size = 1 << post; // tmp is a register if ((MI->flat_insn.x86.operands[0].type != X86_OP_INVALID) && ((MI->flat_insn.x86.operands[0].type != X86_OP_REG) || (MI->flat_insn.x86.operands[0].reg != acc_regs_id[post]))) { // first op is register, so insert its detail to position 0 int i; for (i = MI->flat_insn.x86.op_count; i > 0; i--) { memcpy(&(MI->flat_insn.x86.operands[i]), &(MI->flat_insn.x86.operands[i - 1]), sizeof(MI->flat_insn.x86.operands[0])); } MI->flat_insn.x86.operands[0].type = X86_OP_REG; MI->flat_insn.x86.operands[0].reg = x86_map_regname(tmp); MI->flat_insn.x86.op_count++; } } } } }
/// translateImmediate - Appends an immediate operand to an MCInst. /// /// @param mcInst - The MCInst to append to. /// @param immediate - The immediate value to append. /// @param operand - The operand, as stored in the descriptor table. /// @param insn - The internal instruction. static void translateImmediate(MCInst *mcInst, uint64_t immediate, const OperandSpecifier *operand, InternalInstruction *insn) { OperandType type; type = (OperandType)operand->type; if (type == TYPE_RELv) { //isBranch = true; //pcrel = insn->startLocation + insn->immediateOffset + insn->immediateSize; switch (insn->displacementSize) { case 1: if (immediate & 0x80) immediate |= ~(0xffull); break; case 2: if (immediate & 0x8000) immediate |= ~(0xffffull); break; case 4: if (immediate & 0x80000000) immediate |= ~(0xffffffffull); break; case 8: break; default: break; } } // By default sign-extend all X86 immediates based on their encoding. else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 || type == TYPE_IMM64 || type == TYPE_IMMv) { uint32_t Opcode = MCInst_getOpcode(mcInst); switch (operand->encoding) { default: break; case ENCODING_IB: // Special case those X86 instructions that use the imm8 as a set of // bits, bit count, etc. and are not sign-extend. if ( #ifndef CAPSTONE_X86_REDUCE Opcode != X86_BLENDPSrri && Opcode != X86_BLENDPDrri && Opcode != X86_PBLENDWrri && Opcode != X86_MPSADBWrri && Opcode != X86_DPPSrri && Opcode != X86_DPPDrri && Opcode != X86_INSERTPSrr && Opcode != X86_VBLENDPSYrri && Opcode != X86_VBLENDPSYrmi && Opcode != X86_VBLENDPDYrri && Opcode != X86_VBLENDPDYrmi && Opcode != X86_VPBLENDWrri && Opcode != X86_VMPSADBWrri && Opcode != X86_VDPPSYrri && Opcode != X86_VDPPSYrmi && Opcode != X86_VDPPDrri && Opcode != X86_VINSERTPSrr && #endif Opcode != X86_INT) if(immediate & 0x80) immediate |= ~(0xffull); break; case ENCODING_IW: if(immediate & 0x8000) immediate |= ~(0xffffull); break; case ENCODING_ID: if(immediate & 0x80000000) immediate |= ~(0xffffffffull); break; case ENCODING_IO: break; } } else if (type == TYPE_IMM3) { #ifndef CAPSTONE_X86_REDUCE // Check for immediates that printSSECC can't handle. if (immediate >= 8) { unsigned NewOpc = 0; switch (MCInst_getOpcode(mcInst)) { default: break; // never reach case X86_CMPPDrmi: NewOpc = X86_CMPPDrmi_alt; break; case X86_CMPPDrri: NewOpc = X86_CMPPDrri_alt; break; case X86_CMPPSrmi: NewOpc = X86_CMPPSrmi_alt; break; case X86_CMPPSrri: NewOpc = X86_CMPPSrri_alt; break; case X86_CMPSDrm: NewOpc = X86_CMPSDrm_alt; break; case X86_CMPSDrr: NewOpc = X86_CMPSDrr_alt; break; case X86_CMPSSrm: NewOpc = X86_CMPSSrm_alt; break; case X86_CMPSSrr: NewOpc = X86_CMPSSrr_alt; break; } // Switch opcode to the one that doesn't get special printing. MCInst_setOpcode(mcInst, NewOpc); } #endif } else if (type == TYPE_IMM5) { #ifndef CAPSTONE_X86_REDUCE // Check for immediates that printAVXCC can't handle. if (immediate >= 32) { unsigned NewOpc = 0; switch (MCInst_getOpcode(mcInst)) { default: break; // unexpected opcode case X86_VCMPPDrmi: NewOpc = X86_VCMPPDrmi_alt; break; case X86_VCMPPDrri: NewOpc = X86_VCMPPDrri_alt; break; case X86_VCMPPSrmi: NewOpc = X86_VCMPPSrmi_alt; break; case X86_VCMPPSrri: NewOpc = X86_VCMPPSrri_alt; break; case X86_VCMPSDrm: NewOpc = X86_VCMPSDrm_alt; break; case X86_VCMPSDrr: NewOpc = X86_VCMPSDrr_alt; break; case X86_VCMPSSrm: NewOpc = X86_VCMPSSrm_alt; break; case X86_VCMPSSrr: NewOpc = X86_VCMPSSrr_alt; break; case X86_VCMPPDYrmi: NewOpc = X86_VCMPPDYrmi_alt; break; case X86_VCMPPDYrri: NewOpc = X86_VCMPPDYrri_alt; break; case X86_VCMPPSYrmi: NewOpc = X86_VCMPPSYrmi_alt; break; case X86_VCMPPSYrri: NewOpc = X86_VCMPPSYrri_alt; break; case X86_VCMPPDZrmi: NewOpc = X86_VCMPPDZrmi_alt; break; case X86_VCMPPDZrri: NewOpc = X86_VCMPPDZrri_alt; break; case X86_VCMPPSZrmi: NewOpc = X86_VCMPPSZrmi_alt; break; case X86_VCMPPSZrri: NewOpc = X86_VCMPPSZrri_alt; break; case X86_VCMPSDZrm: NewOpc = X86_VCMPSDZrmi_alt; break; case X86_VCMPSDZrr: NewOpc = X86_VCMPSDZrri_alt; break; case X86_VCMPSSZrm: NewOpc = X86_VCMPSSZrmi_alt; break; case X86_VCMPSSZrr: NewOpc = X86_VCMPSSZrri_alt; break; } // Switch opcode to the one that doesn't get special printing. MCInst_setOpcode(mcInst, NewOpc); } #endif } switch (type) { case TYPE_XMM32: case TYPE_XMM64: case TYPE_XMM128: MCOperand_CreateReg0(mcInst, X86_XMM0 + ((uint32_t)immediate >> 4)); return; case TYPE_XMM256: MCOperand_CreateReg0(mcInst, X86_YMM0 + ((uint32_t)immediate >> 4)); return; case TYPE_XMM512: MCOperand_CreateReg0(mcInst, X86_ZMM0 + ((uint32_t)immediate >> 4)); return; case TYPE_REL8: if(immediate & 0x80) immediate |= ~(0xffull); break; case TYPE_REL32: case TYPE_REL64: if(immediate & 0x80000000) immediate |= ~(0xffffffffull); break; default: // operand is 64 bits wide. Do nothing. break; } MCOperand_CreateImm0(mcInst, immediate); if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 || type == TYPE_MOFFS32 || type == TYPE_MOFFS64) { MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]); } }
static DecodeStatus DecodeL2OpInstructionFail(MCInst *Inst, unsigned Insn, uint64_t Address, void *Decoder) { // Try and decode as a L3R / L2RUS instruction. unsigned Opcode = fieldFromInstruction_4(Insn, 16, 4) | fieldFromInstruction_4(Insn, 27, 5) << 4; switch (Opcode) { case 0x0c: MCInst_setOpcode(Inst, XCore_STW_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x1c: MCInst_setOpcode(Inst, XCore_XOR_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x2c: MCInst_setOpcode(Inst, XCore_ASHR_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x3c: MCInst_setOpcode(Inst, XCore_LDAWF_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x4c: MCInst_setOpcode(Inst, XCore_LDAWB_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x5c: MCInst_setOpcode(Inst, XCore_LDA16F_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x6c: MCInst_setOpcode(Inst, XCore_LDA16B_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x7c: MCInst_setOpcode(Inst, XCore_MUL_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x8c: MCInst_setOpcode(Inst, XCore_DIVS_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x9c: MCInst_setOpcode(Inst, XCore_DIVU_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x10c: MCInst_setOpcode(Inst, XCore_ST16_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x11c: MCInst_setOpcode(Inst, XCore_ST8_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x12c: MCInst_setOpcode(Inst, XCore_ASHR_l2rus); return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder); case 0x12d: MCInst_setOpcode(Inst, XCore_OUTPW_l2rus); return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder); case 0x12e: MCInst_setOpcode(Inst, XCore_INPW_l2rus); return DecodeL2RUSBitpInstruction(Inst, Insn, Address, Decoder); case 0x13c: MCInst_setOpcode(Inst, XCore_LDAWF_l2rus); return DecodeL2RUSInstruction(Inst, Insn, Address, Decoder); case 0x14c: MCInst_setOpcode(Inst, XCore_LDAWB_l2rus); return DecodeL2RUSInstruction(Inst, Insn, Address, Decoder); case 0x15c: MCInst_setOpcode(Inst, XCore_CRC_l3r); return DecodeL3RSrcDstInstruction(Inst, Insn, Address, Decoder); case 0x18c: MCInst_setOpcode(Inst, XCore_REMS_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); case 0x19c: MCInst_setOpcode(Inst, XCore_REMU_l3r); return DecodeL3RInstruction(Inst, Insn, Address, Decoder); } return MCDisassembler_Fail; }
static DecodeStatus Decode2OpInstructionFail(MCInst *Inst, unsigned Insn, uint64_t Address, void *Decoder) { // Try and decode as a 3R instruction. unsigned Opcode = fieldFromInstruction_4(Insn, 11, 5); switch (Opcode) { case 0x0: MCInst_setOpcode(Inst, XCore_STW_2rus); return Decode2RUSInstruction(Inst, Insn, Address, Decoder); case 0x1: MCInst_setOpcode(Inst, XCore_LDW_2rus); return Decode2RUSInstruction(Inst, Insn, Address, Decoder); case 0x2: MCInst_setOpcode(Inst, XCore_ADD_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x3: MCInst_setOpcode(Inst, XCore_SUB_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x4: MCInst_setOpcode(Inst, XCore_SHL_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x5: MCInst_setOpcode(Inst, XCore_SHR_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x6: MCInst_setOpcode(Inst, XCore_EQ_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x7: MCInst_setOpcode(Inst, XCore_AND_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x8: MCInst_setOpcode(Inst, XCore_OR_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x9: MCInst_setOpcode(Inst, XCore_LDW_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x10: MCInst_setOpcode(Inst, XCore_LD16S_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x11: MCInst_setOpcode(Inst, XCore_LD8U_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x12: MCInst_setOpcode(Inst, XCore_ADD_2rus); return Decode2RUSInstruction(Inst, Insn, Address, Decoder); case 0x13: MCInst_setOpcode(Inst, XCore_SUB_2rus); return Decode2RUSInstruction(Inst, Insn, Address, Decoder); case 0x14: MCInst_setOpcode(Inst, XCore_SHL_2rus); return Decode2RUSBitpInstruction(Inst, Insn, Address, Decoder); case 0x15: MCInst_setOpcode(Inst, XCore_SHR_2rus); return Decode2RUSBitpInstruction(Inst, Insn, Address, Decoder); case 0x16: MCInst_setOpcode(Inst, XCore_EQ_2rus); return Decode2RUSInstruction(Inst, Insn, Address, Decoder); case 0x17: MCInst_setOpcode(Inst, XCore_TSETR_3r); return Decode3RImmInstruction(Inst, Insn, Address, Decoder); case 0x18: MCInst_setOpcode(Inst, XCore_LSS_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); case 0x19: MCInst_setOpcode(Inst, XCore_LSU_3r); return Decode3RInstruction(Inst, Insn, Address, Decoder); } return MCDisassembler_Fail; }