static void printDstIdx(MCInst *MI, unsigned Op, SStream *O) { if (MI->csh->detail) { MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0; } // DI accesses are always ES-based on non-64bit mode if (MI->csh->mode != CS_MODE_64) { SStream_concat0(O, "%es:("); if (MI->csh->detail) { MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_ES; } } else SStream_concat0(O, "("); set_mem_access(MI, true); printOperand(MI, Op, O); SStream_concat0(O, ")"); set_mem_access(MI, false); }
static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O) { MCOperand *SegReg; int reg; if (MI->csh->detail) { MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0; } SegReg = MCInst_getOperand(MI, Op+1); reg = MCOperand_getReg(SegReg); // If this has a segment register, print it. if (reg) { _printOperand(MI, Op+1, O); if (MI->csh->detail) { MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg; } SStream_concat0(O, ":"); } SStream_concat0(O, "["); set_mem_access(MI, true); printOperand(MI, Op, O); SStream_concat0(O, "]"); set_mem_access(MI, false); }
static void printMemOperand(MCInst *MI, int opNum, SStream *O, const char *Modifier) { MCOperand *MO; set_mem_access(MI, true); printOperand(MI, opNum, O); // If this is an ADD operand, emit it like normal operands. if (Modifier && !strcmp(Modifier, "arith")) { SStream_concat0(O, ", "); printOperand(MI, opNum + 1, O); set_mem_access(MI, false); return; } MO = MCInst_getOperand(MI, opNum + 1); if (MCOperand_isReg(MO) && (MCOperand_getReg(MO) == SP_G0)) { set_mem_access(MI, false); return; // don't print "+%g0" } if (MCOperand_isImm(MO) && (MCOperand_getImm(MO) == 0)) { set_mem_access(MI, false); return; // don't print "+0" } SStream_concat0(O, "+"); // qq printOperand(MI, opNum + 1, O); set_mem_access(MI, false); }
static void printf32mem(MCInst *MI, unsigned OpNo, SStream *O) { switch(MCInst_getOpcode(MI)) { default: SStream_concat0(O, "dword ptr "); MI->x86opsize = 4; break; case X86_FBSTPm: case X86_FBLDm: // TODO: fix this in tablegen instead SStream_concat0(O, "tbyte ptr "); MI->x86opsize = 10; break; case X86_FSTENVm: case X86_FLDENVm: // TODO: fix this in tablegen instead switch(MI->csh->mode) { default: // never reach break; case CS_MODE_16: MI->x86opsize = 14; break; case CS_MODE_32: case CS_MODE_64: MI->x86opsize = 28; break; } break; } printMemReference(MI, OpNo, O); }
static void printMemOffset(MCInst *MI, unsigned Op, SStream *O) { MCOperand *DispSpec = MCInst_getOperand(MI, Op); MCOperand *SegReg = MCInst_getOperand(MI, Op + 1); int reg; if (MI->csh->detail) { #ifndef CAPSTONE_DIET uint8_t access[6]; #endif MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0; #ifndef CAPSTONE_DIET get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags); MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count]; #endif } // If this has a segment register, print it. reg = MCOperand_getReg(SegReg); if (reg) { _printOperand(MI, Op + 1, O); SStream_concat0(O, ":"); if (MI->csh->detail) { MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg; } } SStream_concat0(O, "["); if (MCOperand_isImm(DispSpec)) { int64_t imm = MCOperand_getImm(DispSpec); if (MI->csh->detail) MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm; if (imm < 0) { SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & imm); } else { if (imm > HEX_THRESHOLD) SStream_concat(O, "0x%"PRIx64, imm); else SStream_concat(O, "%"PRIu64, imm); } } SStream_concat0(O, "]"); if (MI->csh->detail) MI->flat_insn->detail->x86.op_count++; if (MI->op1_size == 0) MI->op1_size = MI->x86opsize; }
static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O) { SStream_concat0(O, "["); printInt32(O, (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum))); SStream_concat0(O, "]"); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count - 1].vector_index = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); } }
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O) { int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3; switch (Imm) { case 0: SStream_concat0(O, "{rn-sae}"); break; case 1: SStream_concat0(O, "{rd-sae}"); break; case 2: SStream_concat0(O, "{ru-sae}"); break; case 3: SStream_concat0(O, "{rz-sae}"); break; default: break; // nev0er reach } }
void printRoundingControl(MCInst *MI, unsigned Op, SStream *O) { int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3; switch (Imm) { case 0: SStream_concat0(O, "{rn-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RN); break; case 1: SStream_concat0(O, "{rd-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RD); break; case 2: SStream_concat0(O, "{ru-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RU); break; case 3: SStream_concat0(O, "{rz-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RZ); break; default: break; // never reach } }
static void printTLSCall(MCInst *MI, unsigned OpNo, SStream *O) { set_mem_access(MI, true); //printBranchOperand(MI, OpNo, O); // On PPC64, VariantKind is VK_None, but on PPC32, it's VK_PLT, and it must // come at the _end_ of the expression. SStream_concat0(O, "("); printOperand(MI, OpNo + 1, O); SStream_concat0(O, ")"); set_mem_access(MI, false); }
static void printMemRegReg(MCInst *MI, unsigned OpNo, SStream *O) { // When used as the base register, r0 reads constant zero rather than // the value contained in the register. For this reason, the darwin // assembler requires that we print r0 as 0 (no r) when used as the base. if (MCOperand_getReg(MCInst_getOperand(MI, OpNo)) == PPC_R0) SStream_concat0(O, "0"); else printOperand(MI, OpNo, O); SStream_concat0(O, ", "); printOperand(MI, OpNo + 1, O); }
static void printVectorList(MCInst *MI, unsigned OpNum, SStream *O, char *LayoutSuffix, MCRegisterInfo *MRI, arm64_vas vas, arm64_vess vess) { #define GETREGCLASS_CONTAIN0(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), _reg) unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)); unsigned NumRegs = 1, FirstReg, i; SStream_concat0(O, "{"); // Work out how many registers there are in the list (if there is an actual // list). if (GETREGCLASS_CONTAIN0(AArch64_DDRegClassID , Reg) || GETREGCLASS_CONTAIN0(AArch64_QQRegClassID, Reg)) NumRegs = 2; else if (GETREGCLASS_CONTAIN0(AArch64_DDDRegClassID, Reg) || GETREGCLASS_CONTAIN0(AArch64_QQQRegClassID, Reg)) NumRegs = 3; else if (GETREGCLASS_CONTAIN0(AArch64_DDDDRegClassID, Reg) || GETREGCLASS_CONTAIN0(AArch64_QQQQRegClassID, Reg)) NumRegs = 4; // Now forget about the list and find out what the first register is. if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_dsub0))) Reg = FirstReg; else if ((FirstReg = MCRegisterInfo_getSubReg(MRI, Reg, AArch64_qsub0))) Reg = FirstReg; // If it's a D-reg, we need to promote it to the equivalent Q-reg before // printing (otherwise getRegisterName fails). if (GETREGCLASS_CONTAIN0(AArch64_FPR64RegClassID, Reg)) { MCRegisterClass *FPR128RC = MCRegisterInfo_getRegClass(MRI, AArch64_FPR128RegClassID); Reg = MCRegisterInfo_getMatchingSuperReg(MRI, Reg, AArch64_dsub, FPR128RC); } for (i = 0; i < NumRegs; ++i, Reg = getNextVectorRegister(Reg, 1)) { SStream_concat(O, "%s%s", getRegisterName(Reg, AArch64_vreg), LayoutSuffix); if (i + 1 != NumRegs) SStream_concat0(O, ", "); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = AArch64_map_vregister(Reg); MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].vas = vas; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].vess = vess; MI->flat_insn->detail->arm64.op_count++; } } SStream_concat0(O, "}"); }
static void printMemRegImm(MCInst *MI, unsigned OpNo, SStream *O) { set_mem_access(MI, true); printS16ImmOperand_Mem(MI, OpNo, O); SStream_concat0(O, "("); if (MCOperand_getReg(MCInst_getOperand(MI, OpNo + 1)) == PPC_R0) SStream_concat0(O, "0"); else printOperand(MI, OpNo + 1, O); SStream_concat0(O, ")"); set_mem_access(MI, false); }
static void printPostIncOperand(MCInst *MI, unsigned OpNo, unsigned Imm, SStream *O) { MCOperand *Op = MCInst_getOperand(MI, OpNo); if (MCOperand_isReg(Op)) { unsigned Reg = MCOperand_getReg(Op); if (Reg == AArch64_XZR) { printInt32Bang(O, Imm); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Imm; MI->flat_insn->detail->arm64.op_count++; } } else { SStream_concat0(O, getRegisterName(Reg, AArch64_NoRegAltName)); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Reg; MI->flat_insn->detail->arm64.op_count++; } } } //llvm_unreachable("unknown operand kind in printPostIncOperand64"); }
static void printDstIdx(MCInst *MI, unsigned Op, SStream *O) { if (MI->csh->detail) { #ifndef CAPSTONE_DIET uint8_t access[6]; #endif MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0; #ifndef CAPSTONE_DIET get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags); MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count]; #endif } // DI accesses are always ES-based on non-64bit mode if (MI->csh->mode != CS_MODE_64) { SStream_concat(O, "es:["); if (MI->csh->detail) { MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_ES; } } else SStream_concat(O, "["); set_mem_access(MI, true); printOperand(MI, Op, O); SStream_concat0(O, "]"); set_mem_access(MI, false); }
static void printCCOperand(MCInst *MI, int opNum, SStream *O) { int CC = (int)MCOperand_getImm(MCInst_getOperand(MI, opNum)) + 256; switch (MCInst_getOpcode(MI)) { default: break; case SP_FBCOND: case SP_FBCONDA: case SP_BPFCC: case SP_BPFCCA: case SP_BPFCCNT: case SP_BPFCCANT: case SP_MOVFCCrr: case SP_V9MOVFCCrr: case SP_MOVFCCri: case SP_V9MOVFCCri: case SP_FMOVS_FCC: case SP_V9FMOVS_FCC: case SP_FMOVD_FCC: case SP_V9FMOVD_FCC: case SP_FMOVQ_FCC: case SP_V9FMOVQ_FCC: // Make sure CC is a fp conditional flag. CC = (CC < 16+256) ? (CC + 16) : CC; break; } SStream_concat0(O, SPARCCondCodeToString((sparc_cc)CC)); if (MI->csh->detail) MI->flat_insn->detail->sparc.cc = (sparc_cc)CC; }
static void printAddress(MCInst *MI, unsigned Base, int64_t Disp, unsigned Index, SStream *O) { if (Disp >= 0) { if (Disp > HEX_THRESHOLD) SStream_concat(O, "0x%"PRIx64, Disp); else SStream_concat(O, "%"PRIu64, Disp); } else { if (Disp < -HEX_THRESHOLD) SStream_concat(O, "-0x%"PRIx64, -Disp); else SStream_concat(O, "-%"PRIu64, -Disp); } if (Base) { SStream_concat0(O, "("); if (Index) SStream_concat(O, "%%%s, ", getRegisterName(Index)); SStream_concat(O, "%%%s)", getRegisterName(Base)); if (MI->csh->detail) { MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM; MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base); MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.index = (uint8_t)SystemZ_map_register(Index); MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = Disp; MI->flat_insn->detail->sysz.op_count++; } } else if (!Index) { if (MI->csh->detail) { MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_IMM; MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].imm = Disp; MI->flat_insn->detail->sysz.op_count++; } } }
static void printBDLAddrOperand(MCInst *MI, int OpNum, SStream *O) { unsigned Base = MCOperand_getReg(MCInst_getOperand(MI, OpNum)); uint64_t Disp = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)); uint64_t Length = (uint64_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 2)); if (Disp > HEX_THRESHOLD) SStream_concat(O, "0x%"PRIx64, Disp); else SStream_concat(O, "%"PRIu64, Disp); if (Length > HEX_THRESHOLD) SStream_concat(O, "(0x%"PRIx64, Length); else SStream_concat(O, "(%"PRIu64, Length); if (Base) SStream_concat(O, ", %%%s", getRegisterName(Base)); SStream_concat0(O, ")"); if (MI->csh->detail) { MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].type = SYSZ_OP_MEM; MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.base = (uint8_t)SystemZ_map_register(Base); MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.length = Length; MI->flat_insn->detail->sysz.operands[MI->flat_insn->detail->sysz.op_count].mem.disp = (int64_t)Disp; MI->flat_insn->detail->sysz.op_count++; } }
static void printBarrierOption(MCInst *MI, unsigned OpNo, SStream *O) { unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNo)); unsigned Opcode = MCInst_getOpcode(MI); bool Valid; char *Name; if (Opcode == AArch64_ISB) Name = A64NamedImmMapper_toString(&A64ISB_ISBMapper, Val, &Valid); else Name = A64NamedImmMapper_toString(&A64DB_DBarrierMapper, Val, &Valid); if (Valid) { SStream_concat0(O, Name); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_BARRIER; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].barrier = Val; MI->flat_insn->detail->arm64.op_count++; } } else { printUInt32Bang(O, Val); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_IMM; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].imm = Val; MI->flat_insn->detail->arm64.op_count++; } } }
static void printCondCode(MCInst *MI, unsigned OpNum, SStream *O) { A64CC_CondCode CC = (A64CC_CondCode)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); SStream_concat0(O, getCondCodeName(CC)); if (MI->csh->detail) MI->flat_insn->detail->arm64.cc = (arm64_cc)(CC + 1); }
static void printMemExtend(MCInst *MI, unsigned OpNum, SStream *O, char SrcRegKind, unsigned Width) { unsigned SignExtend = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum)); unsigned DoShift = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNum + 1)); // sxtw, sxtx, uxtw or lsl (== uxtx) bool IsLSL = !SignExtend && SrcRegKind == 'x'; if (IsLSL) { SStream_concat0(O, "lsl"); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.type = ARM64_SFT_LSL; } } else { SStream_concat(O, "%cxt%c", (SignExtend ? 's' : 'u'), SrcRegKind); if (MI->csh->detail) { if (!SignExtend) { switch(SrcRegKind) { default: break; case 'b': MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTB; break; case 'h': MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTH; break; case 'w': MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_UXTW; break; } } else { switch(SrcRegKind) { default: break; case 'b': MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTB; break; case 'h': MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTH; break; case 'w': MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTW; break; case 'x': MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].ext = ARM64_EXT_SXTX; break; } } } } if (DoShift || IsLSL) { SStream_concat(O, " #%u", Log2_32(Width / 8)); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.type = ARM64_SFT_LSL; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].shift.value = Log2_32(Width / 8); } } }
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O) { MCOperand *Op = MCInst_getOperand(MI, OpNo); if (MCOperand_isReg(Op)) { unsigned reg = MCOperand_getReg(Op); #ifndef CAPSTONE_DIET char *RegName = getRegisterName(reg); #endif // map to public register reg = PPC_map_register(reg); #ifndef CAPSTONE_DIET // The linux and AIX assembler does not take register prefixes. if (MI->csh->syntax == CS_OPT_SYNTAX_NOREGNAME) RegName = stripRegisterPrefix(RegName); SStream_concat0(O, RegName); #endif if (MI->csh->detail) { if (MI->csh->doing_mem) { MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.base = reg; } else { MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_REG; MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].reg = reg; MI->flat_insn->detail->ppc.op_count++; } } return; } if (MCOperand_isImm(Op)) { int64_t imm = MCOperand_getImm(Op); if (imm >= 0) { if (imm > HEX_THRESHOLD) SStream_concat(O, "0x%" PRIx64, imm); else SStream_concat(O, "%" PRIu64 , imm); } else { if (imm < -HEX_THRESHOLD) SStream_concat(O, "-0x%" PRIx64 , -imm); else SStream_concat(O, "-%" PRIu64 , -imm); } if (MI->csh->detail) { if (MI->csh->doing_mem) { MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = imm; } else { MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM; MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = imm; MI->flat_insn->detail->ppc.op_count++; } } } }
static void printShiftedRegister(MCInst *MI, unsigned OpNum, SStream *O) { SStream_concat0(O, getRegisterName(MCOperand_getReg(MCInst_getOperand(MI, OpNum)), AArch64_NoRegAltName)); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)); MI->flat_insn->detail->arm64.op_count++; } printShifter(MI, OpNum + 1, O); }
static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O) { MCOperand *SegReg; SegReg = MCInst_getOperand(MI, Op+1); SStream_concat0(O, markup("<mem:")); // If this has a segment register, print it. if (MCOperand_getReg(SegReg)) { printOperand(MI, Op+1, O); SStream_concat0(O, ":"); } SStream_concat0(O, "("); printOperand(MI, Op, O); SStream_concat(O, ")%s", markup(">")); }
static void printVRegOperand(MCInst *MI, unsigned OpNo, SStream *O) { MCOperand *Op = MCInst_getOperand(MI, OpNo); //assert(Op.isReg() && "Non-register vreg operand!"); unsigned Reg = MCOperand_getReg(Op); SStream_concat0(O, getRegisterName(Reg, AArch64_vreg)); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = AArch64_map_vregister(Reg); MI->flat_insn->detail->arm64.op_count++; } }
static void printMemOffset(MCInst *MI, unsigned Op, SStream *O) { MCOperand *DispSpec = MCInst_getOperand(MI, Op); MCOperand *SegReg = MCInst_getOperand(MI, Op+1); SStream_concat0(O, markup("<mem:")); // If this has a segment register, print it. if (MCOperand_getReg(SegReg)) { printOperand(MI, Op+1, O); SStream_concat0(O, ":"); } if (MI->csh->detail) { MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1; MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0; } if (MCOperand_isImm(DispSpec)) { int64_t imm = MCOperand_getImm(DispSpec); if (MI->csh->detail) MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm; if (imm < 0) { SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & imm); } else { if (imm > HEX_THRESHOLD) SStream_concat(O, "0x%"PRIx64, imm); else SStream_concat(O, "%"PRIu64, imm); } } SStream_concat0(O, markup(">")); if (MI->csh->detail) MI->flat_insn->detail->x86.op_count++; }
static void printRegName(SStream *OS, unsigned RegNo) { char *RegName = getRegisterName(RegNo); if (RegName[0] == 'q' /* QPX */) { // The system toolchain on the BG/Q does not understand QPX register names // in .cfi_* directives, so print the name of the floating-point // subregister instead. RegName[0] = 'f'; } SStream_concat0(OS, RegName); }
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS) { int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 7; switch (Imm) { default: break; // never reach case 0: SStream_concat0(OS, "eq"); op_addSseCC(MI, X86_SSE_CC_EQ); break; case 1: SStream_concat0(OS, "lt"); op_addSseCC(MI, X86_SSE_CC_LT); break; case 2: SStream_concat0(OS, "le"); op_addSseCC(MI, X86_SSE_CC_LE); break; case 3: SStream_concat0(OS, "unord"); op_addSseCC(MI, X86_SSE_CC_UNORD); break; case 4: SStream_concat0(OS, "neq"); op_addSseCC(MI, X86_SSE_CC_NEQ); break; case 5: SStream_concat0(OS, "nlt"); op_addSseCC(MI, X86_SSE_CC_NLT); break; case 6: SStream_concat0(OS, "nle"); op_addSseCC(MI, X86_SSE_CC_NLE); break; case 7: SStream_concat0(OS, "ord"); op_addSseCC(MI, X86_SSE_CC_ORD); break; } }
void printXOPCC(MCInst *MI, unsigned Op, SStream *O) { int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)); switch (Imm) { default: // llvm_unreachable("Invalid xopcc argument!"); case 0: SStream_concat0(O, "lt"); op_addXopCC(MI, X86_XOP_CC_LT); break; case 1: SStream_concat0(O, "le"); op_addXopCC(MI, X86_XOP_CC_LE); break; case 2: SStream_concat0(O, "gt"); op_addXopCC(MI, X86_XOP_CC_GT); break; case 3: SStream_concat0(O, "ge"); op_addXopCC(MI, X86_XOP_CC_GE); break; case 4: SStream_concat0(O, "eq"); op_addXopCC(MI, X86_XOP_CC_EQ); break; case 5: SStream_concat0(O, "neq"); op_addXopCC(MI, X86_XOP_CC_NEQ); break; case 6: SStream_concat0(O, "false"); op_addXopCC(MI, X86_XOP_CC_FALSE); break; case 7: SStream_concat0(O, "true"); op_addXopCC(MI, X86_XOP_CC_TRUE); break; } }
static void printCond4Operand(MCInst *MI, int OpNum, SStream *O) { static char *const CondNames[] = { "o", "h", "nle", "l", "nhe", "lh", "ne", "e", "nlh", "he", "nl", "le", "nh", "no" }; uint64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, OpNum)); // assert(Imm > 0 && Imm < 15 && "Invalid condition"); SStream_concat0(O, CondNames[Imm - 1]); if (MI->csh->detail) MI->flat_insn->detail->sysz.cc = (sysz_cc)Imm; }
static void printMSRSystemRegister(MCInst *MI, unsigned OpNo, SStream *O) { unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNo)); char Name[128]; A64SysRegMapper_toString(&AArch64_MSRMapper, Val, Name); SStream_concat0(O, Name); if (MI->csh->detail) { MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].type = ARM64_OP_REG_MSR; MI->flat_insn->detail->arm64.operands[MI->flat_insn->detail->arm64.op_count].reg = Val; MI->flat_insn->detail->arm64.op_count++; } }