Пример #1
0
unsigned SparcMCCodeEmitter::
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                  SmallVectorImpl<MCFixup> &Fixups,
                  const MCSubtargetInfo &STI) const {

  if (MO.isReg())
    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());

  if (MO.isImm())
    return MO.getImm();

  assert(MO.isExpr());
  const MCExpr *Expr = MO.getExpr();
  if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
    MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
    Fixups.push_back(MCFixup::create(0, Expr, Kind));
    return 0;
  }

  int64_t Res;
  if (Expr->evaluateAsAbsolute(Res))
    return Res;

  llvm_unreachable("Unhandled expression!");
  return 0;
}
Пример #2
0
uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
                                              const MCOperand &MO,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const {
  if (MO.isReg()) {
    if (HAS_NATIVE_OPERANDS(MCII.get(MI.getOpcode()).TSFlags))
      return MRI.getEncodingValue(MO.getReg());
    return getHWReg(MO.getReg());
  }

  if (MO.isExpr()) {
    const MCSymbolRefExpr *Expr = cast<MCSymbolRefExpr>(MO.getExpr());
    // We put rodata at the end of code section, then map the entire
    // code secetion as vtx buf. Thus the section relative address is the
    // correct one.
    // Each R600 literal instruction has two operands
    // We can't easily get the order of the current one, so compare against
    // the first one and adjust offset.
    const unsigned offset = (&MO == &MI.getOperand(0)) ? 0 : 4;
    Fixups.push_back(MCFixup::create(offset, Expr, FK_SecRel_4, MI.getLoc()));
    return 0;
  }

  assert(MO.isImm());
  return MO.getImm();
}
Пример #3
0
// Expand PseudoCALL and PseudoTAIL to AUIPC and JALR with relocation types.
// We expand PseudoCALL and PseudoTAIL while encoding, meaning AUIPC and JALR
// won't go through RISCV MC to MC compressed instruction transformation. This
// is acceptable because AUIPC has no 16-bit form and C_JALR have no immediate
// operand field.  We let linker relaxation deal with it. When linker
// relaxation enabled, AUIPC and JALR have chance relax to JAL. If C extension
// is enabled, JAL has chance relax to C_JAL.
void RISCVMCCodeEmitter::expandFunctionCall(const MCInst &MI, raw_ostream &OS,
                                            SmallVectorImpl<MCFixup> &Fixups,
                                            const MCSubtargetInfo &STI) const {
  MCInst TmpInst;
  MCOperand Func = MI.getOperand(0);
  unsigned Ra = (MI.getOpcode() == RISCV::PseudoTAIL) ? RISCV::X6 : RISCV::X1;
  uint32_t Binary;

  assert(Func.isExpr() && "Expected expression");

  const MCExpr *CallExpr = Func.getExpr();

  // Emit AUIPC Ra, Func with R_RISCV_CALL relocation type.
  TmpInst = MCInstBuilder(RISCV::AUIPC)
                .addReg(Ra)
                .addOperand(MCOperand::createExpr(CallExpr));
  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
  support::endian::write(OS, Binary, support::little);

  if (MI.getOpcode() == RISCV::PseudoTAIL)
    // Emit JALR X0, X6, 0
    TmpInst = MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(Ra).addImm(0);
  else
    // Emit JALR X1, X1, 0
    TmpInst = MCInstBuilder(RISCV::JALR).addReg(Ra).addReg(Ra).addImm(0);
  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
  support::endian::write(OS, Binary, support::little);
}
Пример #4
0
void SystemZInstPrinter::printOperand(const MCOperand &MO, raw_ostream &O) {
    if (MO.isReg())
        O << '%' << getRegisterName(MO.getReg());
    else if (MO.isImm())
        O << MO.getImm();
    else if (MO.isExpr())
        O << *MO.getExpr();
    else
        llvm_unreachable("Invalid operand");
}
Пример #5
0
void ARM64InstPrinter::printAMIndexed(const MCInst *MI, unsigned OpNum,
                                      unsigned Scale, raw_ostream &O) {
  const MCOperand MO1 = MI->getOperand(OpNum + 1);
  O << '[' << getRegisterName(MI->getOperand(OpNum).getReg());
  if (MO1.isImm()) {
    if (MO1.getImm() != 0)
      O << ", #" << (MO1.getImm() * Scale);
  } else {
    assert (MO1.isExpr() && "Unexpected operand type!");
    O << ", " << *MO1.getExpr();
  }
  O << ']';
}
Пример #6
0
MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,
                                          MCInst const &Inst,
                                          MCOperand const &MO) {
  assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) ||
         HexagonMCInstrInfo::isExtended(MCII, Inst));

  MCInst XMI;
  XMI.setOpcode(Hexagon::A4_ext);
  if (MO.isImm())
    XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
  else if (MO.isExpr())
    XMI.addOperand(MCOperand::createExpr(MO.getExpr()));
  else
    llvm_unreachable("invalid extendable operand");
  return XMI;
}
Пример #7
0
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned Cpu0MCCodeEmitter::
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                  SmallVectorImpl<MCFixup> &Fixups,
                  const MCSubtargetInfo &STI) const {
  if (MO.isReg()) {
    unsigned Reg = MO.getReg();
    unsigned RegNo = Ctx.getRegisterInfo()->getEncodingValue(Reg);
    return RegNo;
  } else if (MO.isImm()) {
    return static_cast<unsigned>(MO.getImm());
  } else if (MO.isFPImm()) {
    return static_cast<unsigned>(APFloat(MO.getFPImm())
        .bitcastToAPInt().getHiBits(32).getLimitedValue());
  }
  // MO must be an Expr.
  assert(MO.isExpr());
  return getExprOpValue(MO.getExpr(),Fixups, STI);
}
Пример #8
0
void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
                               SmallVectorImpl<MCInst> &Instructions) {
  MCOperand MCRegOp = Inst.getOperand(0);
  MCOperand MCValOp = Inst.getOperand(1);
  assert(MCRegOp.isReg());
  assert(MCValOp.isImm() || MCValOp.isExpr());

  // the imm operand can be either an expression or an immediate.
  bool IsImm = Inst.getOperand(1).isImm();
  uint64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
  const MCExpr *ValExpr;
  if (IsImm)
    ValExpr = MCConstantExpr::Create(ImmValue, getContext());
  else
    ValExpr = MCValOp.getExpr();

  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);

  if (!IsImm || (ImmValue & ~0x1fff)) {
    MCInst TmpInst;
    const MCExpr *Expr =
        SparcMCExpr::Create(SparcMCExpr::VK_Sparc_HI, ValExpr, getContext());
    TmpInst.setLoc(IDLoc);
    TmpInst.setOpcode(SP::SETHIi);
    TmpInst.addOperand(MCRegOp);
    TmpInst.addOperand(MCOperand::createExpr(Expr));
    Instructions.push_back(TmpInst);
    PrevReg = MCRegOp;
  }

  if (!IsImm || ((ImmValue & 0x1fff) != 0 || ImmValue == 0)) {
    MCInst TmpInst;
    const MCExpr *Expr =
        SparcMCExpr::Create(SparcMCExpr::VK_Sparc_LO, ValExpr, getContext());
    TmpInst.setLoc(IDLoc);
    TmpInst.setOpcode(SP::ORri);
    TmpInst.addOperand(MCRegOp);
    TmpInst.addOperand(PrevReg);
    TmpInst.addOperand(MCOperand::createExpr(Expr));
    Instructions.push_back(TmpInst);
  }
}
Пример #9
0
// Expand PseudoAddTPRel to a simple ADD with the correct relocation.
void RISCVMCCodeEmitter::expandAddTPRel(const MCInst &MI, raw_ostream &OS,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const {
  MCOperand DestReg = MI.getOperand(0);
  MCOperand SrcReg = MI.getOperand(1);
  MCOperand TPReg = MI.getOperand(2);
  assert(TPReg.isReg() && TPReg.getReg() == RISCV::X4 &&
         "Expected thread pointer as second input to TP-relative add");

  MCOperand SrcSymbol = MI.getOperand(3);
  assert(SrcSymbol.isExpr() &&
         "Expected expression as third input to TP-relative add");

  const RISCVMCExpr *Expr = dyn_cast<RISCVMCExpr>(SrcSymbol.getExpr());
  assert(Expr && Expr->getKind() == RISCVMCExpr::VK_RISCV_TPREL_ADD &&
         "Expected tprel_add relocation on TP-relative symbol");

  // Emit the correct tprel_add relocation for the symbol.
  Fixups.push_back(MCFixup::create(
      0, Expr, MCFixupKind(RISCV::fixup_riscv_tprel_add), MI.getLoc()));

  // Emit fixup_riscv_relax for tprel_add where the relax feature is enabled.
  if (STI.getFeatureBits()[RISCV::FeatureRelax]) {
    const MCConstantExpr *Dummy = MCConstantExpr::create(0, Ctx);
    Fixups.push_back(MCFixup::create(
        0, Dummy, MCFixupKind(RISCV::fixup_riscv_relax), MI.getLoc()));
  }

  // Emit a normal ADD instruction with the given operands.
  MCInst TmpInst = MCInstBuilder(RISCV::ADD)
                       .addOperand(DestReg)
                       .addOperand(SrcReg)
                       .addOperand(TPReg);
  uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
  support::endian::write(OS, Binary, support::little);
}
Пример #10
0
bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
                               SmallVectorImpl<MCInst> &Instructions) {
  MCOperand MCRegOp = Inst.getOperand(0);
  MCOperand MCValOp = Inst.getOperand(1);
  assert(MCRegOp.isReg());
  assert(MCValOp.isImm() || MCValOp.isExpr());

  // the imm operand can be either an expression or an immediate.
  bool IsImm = Inst.getOperand(1).isImm();
  int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;

  // Allow either a signed or unsigned 32-bit immediate.
  if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
    return Error(IDLoc,
                 "set: argument must be between -2147483648 and 4294967295");
  }

  // If the value was expressed as a large unsigned number, that's ok.
  // We want to see if it "looks like" a small signed number.
  int32_t ImmValue = RawImmValue;
  // For 'set' you can't use 'or' with a negative operand on V9 because
  // that would splat the sign bit across the upper half of the destination
  // register, whereas 'set' is defined to zero the high 32 bits.
  bool IsEffectivelyImm13 =
      IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
  const MCExpr *ValExpr;
  if (IsImm)
    ValExpr = MCConstantExpr::create(ImmValue, getContext());
  else
    ValExpr = MCValOp.getExpr();

  MCOperand PrevReg = MCOperand::createReg(Sparc::G0);

  // If not just a signed imm13 value, then either we use a 'sethi' with a
  // following 'or', or a 'sethi' by itself if there are no more 1 bits.
  // In either case, start with the 'sethi'.
  if (!IsEffectivelyImm13) {
    MCInst TmpInst;
    const MCExpr *Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_HI, ValExpr);
    TmpInst.setLoc(IDLoc);
    TmpInst.setOpcode(SP::SETHIi);
    TmpInst.addOperand(MCRegOp);
    TmpInst.addOperand(MCOperand::createExpr(Expr));
    Instructions.push_back(TmpInst);
    PrevReg = MCRegOp;
  }

  // The low bits require touching in 3 cases:
  // * A non-immediate value will always require both instructions.
  // * An effectively imm13 value needs only an 'or' instruction.
  // * Otherwise, an immediate that is not effectively imm13 requires the
  //   'or' only if bits remain after clearing the 22 bits that 'sethi' set.
  // If the low bits are known zeros, there's nothing to do.
  // In the second case, and only in that case, must we NOT clear
  // bits of the immediate value via the %lo() assembler function.
  // Note also, the 'or' instruction doesn't mind a large value in the case
  // where the operand to 'set' was 0xFFFFFzzz - it does exactly what you mean.
  if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
    MCInst TmpInst;
    const MCExpr *Expr;
    if (IsEffectivelyImm13)
      Expr = ValExpr;
    else
      Expr = adjustPICRelocation(SparcMCExpr::VK_Sparc_LO, ValExpr);
    TmpInst.setLoc(IDLoc);
    TmpInst.setOpcode(SP::ORri);
    TmpInst.addOperand(MCRegOp);
    TmpInst.addOperand(PrevReg);
    TmpInst.addOperand(MCOperand::createExpr(Expr));
    Instructions.push_back(TmpInst);
  }
  return false;
}
Пример #11
0
unsigned Disassembler::decodeInstruction(unsigned Address,
  MachineBasicBlock *Block) {
  // Disassemble instruction
  const MCDisassembler *DA = MC->getMCDisassembler();
  uint64_t InstSize;
  MCInst *Inst = new MCInst();
  StringRef Bytes;

  if (!(DA->getInstruction(*Inst, InstSize, *CurSectionMemory, Address,
        nulls(), nulls()))) {
    printError("Unknown instruction encountered, instruction decode failed!");
    return 1;
    // Instructions[Address] = NULL;
    // Block->push_back(NULL);	
    // TODO: Replace with default size for each target.
    // return 1;
    // outs() << format("%8" PRIx64 ":\t", SectAddr + Index);
    // Dism->rawBytesToString(StringRef(Bytes.data() + Index, Size));
    // outs() << "   unkn\n";
  }
  Instructions[Address] = Inst;

  // Recover Instruction information
  const MCInstrInfo *MII = MC->getMCInstrInfo();
  MCInstrDesc *MCID = new MCInstrDesc(MII->get(Inst->getOpcode()));
  MCID->Size = InstSize;

  // Check if the instruction can load to program counter and mark it as a Ret
  // FIXME: Better analysis would be to see if the PC value references memory
  // sent as a parameter or set locally in the function, but that would need to
  // happen after decompilation. In either case, this is definitely a BB
  // terminator or branch!
  if (MCID->mayLoad()
    && MCID->mayAffectControlFlow(*Inst, *MC->getMCRegisterInfo())) {
    MCID->Flags |= (1 << MCID::Return);
    MCID->Flags |= (1 << MCID::Terminator);
  }


  // Recover MachineInstr representation
  DebugLoc *Location = setDebugLoc(Address);
  MachineInstrBuilder MIB = BuildMI(Block, *Location, *MCID);
  unsigned int numDefs = MCID->getNumDefs();
  for (unsigned int i = 0; i < Inst->getNumOperands(); i++) {
    MCOperand MCO = Inst->getOperand(i);
    // FIXME: This hack is a workaround for the assert in MachineInstr.cpp:653,
    // where OpNo >= MCID->getNumOperands()...
    if (i >= MCID->getNumOperands() && !(MCID->isVariadic()))
      break;

    if (MCO.isReg()) {
      unsigned flags = 0;
      // Defs always start at the beginning of the operands list,
      // unfortunately BuildMI doesn't set default define flags so we have
      // to do it manually here.
      // NOTE: This should always be true, but might not be if operands list
      //       is not populated correctly by the MC Backend for the target.
      if (i < numDefs) {
        flags |= RegState::Define;
      }

      // NOTE: No need to worry about imp defs and uses, as these are already
      //       specificed in the MCID attached to the MachineInst object.
      MIB.addReg(MCO.getReg(), flags);
      continue;
    }
    if (MCO.isImm()) {
      MIB.addImm(MCO.getImm());
        continue;
    }
    //else if (MCO.isFPImm()) MIB.addFPImm(MCO.getFPImm());
    if (MCO.isExpr()) {
      MCOperandInfo MCOpInfo = MCID->OpInfo[i];
      switch (MCOpInfo.OperandType) {
        case MCOI::OPERAND_MEMORY:
        case MCOI::OPERAND_PCREL:
        case MCOI::OPERAND_UNKNOWN:
        default:
          printError("Unknown how to handle this Expression at this time.");
      }
    }
    printError("Unknown how to handle Operand!");
  }

  // NOTE: I tried MCOpInfo here, and it appearst o be NULL
  // ... at least for ARM.
  unsigned flags = 0;
  if (MCID->mayLoad())
  	flags |= MachineMemOperand::MOLoad;
  if (MCID->mayStore())
  	flags |= MachineMemOperand::MOStore;
  if (flags != 0) {
  	// Constant* cInt = ConstantInt::get(Type::getInt64Ty(ctx), MCO.getImm());
  	// Value *Val = ConstantExpr::getIntToPtr(cInt,
  	// PointerType::getUnqual(Type::getInt32Ty(ctx)));
  	// FIXME: note size of 4 is known to be bad for
  	// some targets

  	//Copy & paste set getImm to zero
  	MachineMemOperand* MMO = new MachineMemOperand(
  			MachinePointerInfo(), flags, 4, 0);	//MCO.getImm()
		 	 MIB.addMemOperand(MMO);
		 	 //outs() << "Name: " << MII->getName(Inst->getOpcode()) << " Flags: " << flags << "\n";
	 }

  // Note: I don't know why they decided instruction size needed to be 64 bits,
  // but the following conversion shouldn't be an issue.
  return ((unsigned)InstSize);
}