static DecodeStatus DecodeReturn(MCInst *MI, unsigned insn, uint64_t Address, const void *Decoder) { DecodeStatus status; unsigned rs1 = fieldFromInstruction_4(insn, 14, 5); unsigned isImm = fieldFromInstruction_4(insn, 13, 1); unsigned rs2 = 0; unsigned simm13 = 0; if (isImm) simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13); else rs2 = fieldFromInstruction_4(insn, 0, 5); // Decode RS1. status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); if (status != MCDisassembler_Success) return status; // Decode RS2 | SIMM13. if (isImm) MCInst_addOperand(MI, MCOperand_CreateImm(simm13)); else { status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); if (status != MCDisassembler_Success) return status; } return MCDisassembler_Success; }
static DecodeStatus DecodeExtSize(MCInst *Inst, unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder) { int Size = (int) Insn + 1; MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Size, 16))); return MCDisassembler_Success; }
static DecodeStatus DecodeBranchTargetMM(MCInst *Inst, unsigned Offset, uint64_t Address, MCRegisterInfo *Decoder) { unsigned BranchOffset = Offset & 0xffff; BranchOffset = SignExtend32(BranchOffset << 1, 18); MCInst_addOperand(Inst, MCOperand_CreateImm(BranchOffset)); return MCDisassembler_Success; }
static DecodeStatus DecodeSIMM13(MCInst *MI, unsigned insn, uint64_t Address, const void *Decoder) { unsigned tgt = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13); MCInst_addOperand(MI, MCOperand_CreateImm(tgt)); return MCDisassembler_Success; }
static DecodeStatus DecodeInsSize(MCInst *Inst, unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder) { // First we need to grab the pos(lsb) from MCInst. int Pos = MCOperand_getImm(MCInst_getOperand(Inst, 2)); int Size = (int) Insn - Pos + 1; MCInst_addOperand(Inst, MCOperand_CreateImm(SignExtend32(Size, 16))); return MCDisassembler_Success; }
static DecodeStatus DecodeCachePref(MCInst *Inst, unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder) { int Offset = SignExtend32(Insn & 0xffff, 16); unsigned Hint = fieldFromInstruction(Insn, 16, 5); unsigned Base = fieldFromInstruction(Insn, 21, 5); Base = getReg(Decoder, Mips_GPR32RegClassID, Base); MCOperand_CreateReg0(Inst, Base); MCOperand_CreateImm0(Inst, Offset); MCOperand_CreateImm0(Inst, Hint); return MCDisassembler_Success; }
static DecodeStatus DecodeFMem(MCInst *Inst, unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder) { int Offset = SignExtend32(Insn & 0xffff, 16); unsigned Reg = fieldFromInstruction(Insn, 16, 5); unsigned Base = fieldFromInstruction(Insn, 21, 5); Reg = getReg(Decoder, Mips_FGR64RegClassID, Reg); Base = getReg(Decoder, Mips_GPR32RegClassID, Base); MCInst_addOperand(Inst, MCOperand_CreateReg(Reg)); MCInst_addOperand(Inst, MCOperand_CreateReg(Base)); MCInst_addOperand(Inst, MCOperand_CreateImm(Offset)); return MCDisassembler_Success; }
static DecodeStatus DecodeMSA128Mem(MCInst *Inst, unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder) { int Offset = SignExtend32(fieldFromInstruction(Insn, 16, 10), 10); unsigned Reg = fieldFromInstruction(Insn, 6, 5); unsigned Base = fieldFromInstruction(Insn, 11, 5); Reg = getReg(Decoder, Mips_MSA128BRegClassID, Reg); Base = getReg(Decoder, Mips_GPR32RegClassID, Base); MCInst_addOperand(Inst, MCOperand_CreateReg(Reg)); MCInst_addOperand(Inst, MCOperand_CreateReg(Base)); // MCInst_addOperand(Inst, MCOperand_CreateImm(Offset)); // The immediate field of an LD/ST instruction is scaled which means it must // be multiplied (when decoding) by the size (in bytes) of the instructions' // data format. // .b - 1 byte // .h - 2 bytes // .w - 4 bytes // .d - 8 bytes switch(MCInst_getOpcode(Inst)) { default: //assert (0 && "Unexpected instruction"); return MCDisassembler_Fail; break; case Mips_LD_B: case Mips_ST_B: MCInst_addOperand(Inst, MCOperand_CreateImm(Offset)); break; case Mips_LD_H: case Mips_ST_H: MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 1)); break; case Mips_LD_W: case Mips_ST_W: MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 2)); break; case Mips_LD_D: case Mips_ST_D: MCInst_addOperand(Inst, MCOperand_CreateImm(Offset << 3)); break; } return MCDisassembler_Success; }
static DecodeStatus DecodeMem(MCInst *MI, unsigned insn, uint64_t Address, const void *Decoder, bool isLoad, DecodeFunc DecodeRD) { DecodeStatus status; unsigned rd = fieldFromInstruction_4(insn, 25, 5); unsigned rs1 = fieldFromInstruction_4(insn, 14, 5); bool isImm = fieldFromInstruction_4(insn, 13, 1); unsigned rs2 = 0; unsigned simm13 = 0; if (isImm) simm13 = SignExtend32(fieldFromInstruction_4(insn, 0, 13), 13); else rs2 = fieldFromInstruction_4(insn, 0, 5); if (isLoad) { status = DecodeRD(MI, rd, Address, Decoder); if (status != MCDisassembler_Success) return status; } // Decode rs1. status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder); if (status != MCDisassembler_Success) return status; // Decode imm|rs2. if (isImm) MCInst_addOperand(MI, MCOperand_CreateImm(simm13)); else { status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder); if (status != MCDisassembler_Success) return status; } if (!isLoad) { status = DecodeRD(MI, rd, Address, Decoder); if (status != MCDisassembler_Success) return status; } return MCDisassembler_Success; }
static DecodeStatus DecodeMemMMImm12(MCInst *Inst, unsigned Insn, uint64_t Address, MCRegisterInfo *Decoder) { int Offset = SignExtend32(Insn & 0x0fff, 12); unsigned Reg = fieldFromInstruction(Insn, 21, 5); unsigned Base = fieldFromInstruction(Insn, 16, 5); Reg = getReg(Decoder, Mips_GPR32RegClassID, Reg); Base = getReg(Decoder, Mips_GPR32RegClassID, Base); if (MCInst_getOpcode(Inst) == Mips_SC_MM) MCOperand_CreateReg0(Inst, Reg); MCOperand_CreateReg0(Inst, Reg); MCOperand_CreateReg0(Inst, Base); MCOperand_CreateImm0(Inst, Offset); return MCDisassembler_Success; }
static void printS5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O) { int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo)); Value = SignExtend32(Value, 5); if (Value >= 0) { if (Value > HEX_THRESHOLD) SStream_concat(O, "0x%x", Value); else SStream_concat(O, "%u", Value); } else { if (Value < -HEX_THRESHOLD) SStream_concat(O, "-0x%x", -Value); else SStream_concat(O, "-%u", -Value); } if (MI->csh->detail) { 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 = Value; MI->flat_insn->detail->ppc.op_count++; } }
static void printOperand(MCInst *MI, int opNum, SStream *O) { int Imm; unsigned reg; MCOperand *MO = MCInst_getOperand(MI, opNum); if (MCOperand_isReg(MO)) { reg = MCOperand_getReg(MO); printRegName(O, reg); reg = Sparc_map_register(reg); if (MI->csh->detail) { if (MI->csh->doing_mem) { if (MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base) MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.index = reg; else MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.base = reg; } else { MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_REG; MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].reg = reg; MI->flat_insn->detail->sparc.op_count++; } } return; } if (MCOperand_isImm(MO)) { Imm = (int)MCOperand_getImm(MO); // Conditional branches displacements needs to be signextended to be // able to jump backwards. // // Displacements are measured as the number of instructions forward or // backward, so they need to be multiplied by 4 switch (MI->Opcode) { case SP_CALL: Imm = SignExtend32(Imm, 30); Imm += (uint32_t)MI->address; break; // Branch on integer condition with prediction (BPcc) // Branch on floating point condition with prediction (FBPfcc) case SP_BPICC: case SP_BPICCA: case SP_BPICCANT: case SP_BPICCNT: case SP_BPXCC: case SP_BPXCCA: case SP_BPXCCANT: case SP_BPXCCNT: case SP_BPFCC: case SP_BPFCCA: case SP_BPFCCANT: case SP_BPFCCNT: Imm = SignExtend32(Imm, 19); Imm = (uint32_t)MI->address + Imm * 4; break; // Branch on integer condition (Bicc) // Branch on floating point condition (FBfcc) case SP_BA: case SP_BCOND: case SP_BCONDA: case SP_FBCOND: case SP_FBCONDA: Imm = SignExtend32(Imm, 22); Imm = (uint32_t)MI->address + Imm * 4; break; // Branch on integer register with prediction (BPr) case SP_BPGEZapn: case SP_BPGEZapt: case SP_BPGEZnapn: case SP_BPGEZnapt: case SP_BPGZapn: case SP_BPGZapt: case SP_BPGZnapn: case SP_BPGZnapt: case SP_BPLEZapn: case SP_BPLEZapt: case SP_BPLEZnapn: case SP_BPLEZnapt: case SP_BPLZapn: case SP_BPLZapt: case SP_BPLZnapn: case SP_BPLZnapt: case SP_BPNZapn: case SP_BPNZapt: case SP_BPNZnapn: case SP_BPNZnapt: case SP_BPZapn: case SP_BPZapt: case SP_BPZnapn: case SP_BPZnapt: Imm = SignExtend32(Imm, 16); Imm = (uint32_t)MI->address + Imm * 4; break; } if (Imm >= 0) { if (Imm > HEX_THRESHOLD) SStream_concat(O, "0x%x", Imm); else SStream_concat(O, "%u", Imm); } else { if (Imm < -HEX_THRESHOLD) SStream_concat(O, "-0x%x", -Imm); else SStream_concat(O, "-%u", -Imm); } if (MI->csh->detail) { if (MI->csh->doing_mem) { MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].mem.disp = Imm; } else { MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].type = SPARC_OP_IMM; MI->flat_insn->detail->sparc.operands[MI->flat_insn->detail->sparc.op_count].imm = Imm; MI->flat_insn->detail->sparc.op_count++; } } } return; }