// @LOCALMOD-BEGIN
// Unlike LowerARMMachineInstrToMCInst, the opcode has already been set.
// Otherwise, this is like LowerARMMachineInstrToMCInst, but with special
// handling where the "immediate" is PC Relative
// (used for MOVi16PIC / MOVTi16PIC, etc. -- see .td file)
void llvm::LowerARMMachineInstrToMCInstPCRel(const MachineInstr *MI,
                                             MCInst &OutMI,
                                             ARMAsmPrinter &AP,
                                             unsigned ImmIndex,
                                             unsigned PCIndex,
                                             MCSymbol *PCLabel,
                                             unsigned PCAdjustment) {

  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
    if (i == ImmIndex) {
      MCContext &Ctx = AP.OutContext;
      const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, Ctx);
      if (PCAdjustment) {
        const MCExpr *AdjExpr = MCConstantExpr::Create(PCAdjustment, Ctx);
        PCRelExpr = MCBinaryExpr::CreateAdd(PCRelExpr, AdjExpr, Ctx);
      }

      // Get the usual symbol operand, then subtract the PCRelExpr.
      const MachineOperand &MOImm = MI->getOperand(ImmIndex);
      MCOperand SymOp;
      bool DidLower = AP.lowerOperand(MOImm, SymOp);
      assert (DidLower && "Immediate-like operand should have been lowered");

      const MCExpr *Expr = SymOp.getExpr();
      ARMMCExpr::VariantKind TargetKind = ARMMCExpr::VK_ARM_None;
      /* Unwrap and rewrap the ARMMCExpr */
      if (Expr->getKind() == MCExpr::Target) {
        const ARMMCExpr *TargetExpr = cast<ARMMCExpr>(Expr);
        TargetKind = TargetExpr->getKind();
        Expr = TargetExpr->getSubExpr();
      }
      Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, Ctx);
      if (TargetKind != ARMMCExpr::VK_ARM_None) {
        Expr = ARMMCExpr::Create(TargetKind, Expr, Ctx);
      }
      MCOperand MCOp = MCOperand::CreateExpr(Expr);
      OutMI.addOperand(MCOp);
    } else if (i == PCIndex) {  // dummy index already handled as PCLabel
      continue;
    } else {
      MCOperand MCOp;
      if (AP.lowerOperand(MI->getOperand(i), MCOp)) {
        OutMI.addOperand(MCOp);
      }
    }
  }
}
예제 #2
0
void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
                                        ARMAsmPrinter &AP) {
  OutMI.setOpcode(MI->getOpcode());

  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
    const MachineOperand &MO = MI->getOperand(i);

    MCOperand MCOp;
    if (AP.lowerOperand(MO, MCOp))
      OutMI.addOperand(MCOp);
  }
}
void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI,
                                        ARMAsmPrinter &AP) {
  OutMI.setOpcode(MI->getOpcode());

  // In the MC layer, we keep modified immediates in their encoded form
  bool EncodeImms = false;
  switch (MI->getOpcode()) {
  default: break;
  case ARM::MOVi:
  case ARM::MVNi:
  case ARM::CMPri:
  case ARM::CMNri:
  case ARM::TSTri:
  case ARM::TEQri:
  case ARM::MSRi:
  case ARM::ADCri:
  case ARM::ADDri:
  case ARM::ADDSri:
  case ARM::SBCri:
  case ARM::SUBri:
  case ARM::SUBSri:
  case ARM::ANDri:
  case ARM::ORRri:
  case ARM::EORri:
  case ARM::BICri:
  case ARM::RSBri:
  case ARM::RSBSri:
  case ARM::RSCri:
    EncodeImms = true;
    break;
  }

  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
    const MachineOperand &MO = MI->getOperand(i);

    MCOperand MCOp;
    if (AP.lowerOperand(MO, MCOp)) {
      if (MCOp.isImm() && EncodeImms) {
        int32_t Enc = ARM_AM::getSOImmVal(MCOp.getImm());
        if (Enc != -1)
          MCOp.setImm(Enc);
      }
      OutMI.addOperand(MCOp);
    }
  }
}