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;
    switch (MO.getType()) {
    default:
      MI->dump();
      assert(0 && "unknown operand type");
    case MachineOperand::MO_Register:
      // Ignore all non-CPSR implicit register operands.
      if (MO.isImplicit() && MO.getReg() != ARM::CPSR) continue;
      assert(!MO.getSubReg() && "Subregs should be eliminated!");
      MCOp = MCOperand::CreateReg(MO.getReg());
      break;
    case MachineOperand::MO_Immediate:
      MCOp = MCOperand::CreateImm(MO.getImm());
      break;
    case MachineOperand::MO_MachineBasicBlock:
      MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
                       MO.getMBB()->getSymbol(), AP.OutContext));
      break;
    case MachineOperand::MO_GlobalAddress:
      MCOp = GetSymbolRef(MO, AP.Mang->getSymbol(MO.getGlobal()), AP);
      break;
    case MachineOperand::MO_ExternalSymbol:
      MCOp = GetSymbolRef(MO,
                          AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
      break;
    case MachineOperand::MO_JumpTableIndex:
      MCOp = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP);
      break;
    case MachineOperand::MO_ConstantPoolIndex:
      MCOp = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP);
      break;
    case MachineOperand::MO_BlockAddress:
      MCOp = GetSymbolRef(MO,AP.GetBlockAddressSymbol(MO.getBlockAddress()),AP);
      break;
    case MachineOperand::MO_FPImmediate:
      APFloat Val = MO.getFPImm()->getValueAPF();
      bool ignored;
      Val.convert(APFloat::IEEEdouble, APFloat::rmTowardZero, &ignored);
      MCOp = MCOperand::CreateFPImm(Val.convertToDouble());
      break;
    }

    OutMI.addOperand(MCOp);
  }
}
// @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);
      }
    }
  }
}
Beispiel #3
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);
    }
  }
}