예제 #1
0
MCOperand EpiphanyMCInstLower::
LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {

  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);

  switch (MO.getTargetFlags()) {
  case EpiphanyII::MO_LO16:
    Expr = EpiphanyMCExpr::createLo16(Expr, Ctx);
    break;
  case EpiphanyII::MO_HI16:
    Expr = EpiphanyMCExpr::createHi16(Expr, Ctx);
    break;
  case EpiphanyII::MO_NO_FLAG:
    // Expr is already correct
    break;
  default:
    llvm_unreachable("Unexpected MachineOperand flag - lowersymboloperand");
  }

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(Expr,
                                   MCConstantExpr::create(MO.getOffset(), Ctx),
                                   Ctx);

  return MCOperand::createExpr(Expr);
}
예제 #2
0
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned ARMCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                           const MachineOperand &MO) {
  if (MO.isReg())
    return ARMRegisterInfo::getRegisterNumbering(MO.getReg());
  else if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());
  else if (MO.isGlobal())
    emitGlobalAddress(MO.getGlobal(), ARM::reloc_arm_branch, true, false);
  else if (MO.isSymbol())
    emitExternalSymbolAddress(MO.getSymbolName(), ARM::reloc_arm_branch);
  else if (MO.isCPI()) {
    const TargetInstrDesc &TID = MI.getDesc();
    // For VFP load, the immediate offset is multiplied by 4.
    unsigned Reloc =  ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPLdStFrm)
      ? ARM::reloc_arm_vfp_cp_entry : ARM::reloc_arm_cp_entry;
    emitConstPoolAddress(MO.getIndex(), Reloc);
  } else if (MO.isJTI())
    emitJumpTableAddress(MO.getIndex(), ARM::reloc_arm_relative);
  else if (MO.isMBB())
    emitMachineBasicBlock(MO.getMBB(), ARM::reloc_arm_branch);
  else {
#ifndef NDEBUG
    errs() << MO;
#endif
    llvm_unreachable(0);
  }
  return 0;
}
예제 #3
0
MCOperand LanaiMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
                                               MCSymbol *Sym) const {
  LanaiMCExpr::VariantKind Kind;

  switch (MO.getTargetFlags()) {
  case LanaiII::MO_NO_FLAG:
    Kind = LanaiMCExpr::VK_Lanai_None;
    break;
  case LanaiII::MO_ABS_HI:
    Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
    break;
  case LanaiII::MO_ABS_LO:
    Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
    break;
  default:
    llvm_unreachable("Unknown target flag on GV operand");
  }

  const MCExpr *Expr =
      MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
  Expr = LanaiMCExpr::create(Kind, Expr, Ctx);
  return MCOperand::createExpr(Expr);
}
예제 #4
0
MachineRelocation PPCCodeEmitter::GetRelocation(const MachineOperand &MO, 
                                                unsigned RelocID) const {
  // If in PIC mode, we need to encode the negated address of the
  // 'movepctolr' into the unrelocated field.  After relocation, we'll have
  // &gv-&movepctolr-4 in the imm field.  Once &movepctolr is added to the imm
  // field, we get &gv.  This doesn't happen for branch relocations, which are
  // always implicitly pc relative.
  intptr_t Cst = 0;
  if (TM.getRelocationModel() == Reloc::PIC_) {
    assert(MovePCtoLROffset && "MovePCtoLR not seen yet?");
    Cst = -(intptr_t)MovePCtoLROffset - 4;
  }
  
  if (MO.isGlobal())
    return MachineRelocation::getGV(MCE.getCurrentPCOffset(), RelocID,
                                    const_cast<GlobalValue *>(MO.getGlobal()),
                                    Cst, isa<Function>(MO.getGlobal()));
  if (MO.isSymbol())
    return MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
                                        RelocID, MO.getSymbolName(), Cst);
  if (MO.isCPI())
    return MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
                                           RelocID, MO.getIndex(), Cst);

  if (MO.isMBB())
    return MachineRelocation::getBB(MCE.getCurrentPCOffset(),
                                    RelocID, MO.getMBB());
  
  assert(MO.isJTI());
  return MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
                                         RelocID, MO.getIndex(), Cst);
}
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
                              AsmPrinter &Printer, bool isDarwin) {
  MCContext &Ctx = Printer.OutContext;
  MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;

  if (MO.getTargetFlags() & PPCII::MO_LO16)
    RefKind = isDarwin ? MCSymbolRefExpr::VK_PPC_DARWIN_LO16 : MCSymbolRefExpr::VK_PPC_GAS_LO16;
  else if (MO.getTargetFlags() & PPCII::MO_HA16)
    RefKind = isDarwin ? MCSymbolRefExpr::VK_PPC_DARWIN_HA16 : MCSymbolRefExpr::VK_PPC_GAS_HA16;

  // FIXME: This isn't right, but we don't have a good way to express this in
  // the MC Level, see below.
  if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG)
    RefKind = MCSymbolRefExpr::VK_None;
  
  const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx);

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::CreateAdd(Expr,
                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
                                   Ctx);

  // Subtract off the PIC base if required.
  if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) {
    const MachineFunction *MF = MO.getParent()->getParent()->getParent();
    
    const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx);
    Expr = MCBinaryExpr::CreateSub(Expr, PB, Ctx);
    // FIXME: We have no way to make the result be VK_PPC_LO16/VK_PPC_HA16,
    // since it is not a symbol!
  }
  
  return MCOperand::CreateExpr(Expr);
}
예제 #6
0
MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
                                      const MCSymbol *Symbol) {
  MCSymbolRefExpr::VariantKind SymbolVariant = MCSymbolRefExpr::VK_None;
  if (MO.getTargetFlags() & ARMII::MO_SBREL)
    SymbolVariant = MCSymbolRefExpr::VK_ARM_SBREL;

  const MCExpr *Expr =
      MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext);
  switch (MO.getTargetFlags() & ARMII::MO_OPTION_MASK) {
  default:
    llvm_unreachable("Unknown target flag on symbol operand");
  case ARMII::MO_NO_FLAG:
    break;
  case ARMII::MO_LO16:
    Expr =
        MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext);
    Expr = ARMMCExpr::createLower16(Expr, OutContext);
    break;
  case ARMII::MO_HI16:
    Expr =
        MCSymbolRefExpr::create(Symbol, SymbolVariant, OutContext);
    Expr = ARMMCExpr::createUpper16(Expr, OutContext);
    break;
  }

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(Expr,
                                   MCConstantExpr::create(MO.getOffset(),
                                                          OutContext),
                                   OutContext);
  return MCOperand::createExpr(Expr);

}
예제 #7
0
static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
                                    const AsmPrinter &AP) {
  MCContext &Ctx = AP.OutContext;
  RISCVMCExpr::VariantKind Kind;

  switch (MO.getTargetFlags()) {
  default:
    llvm_unreachable("Unknown target flag on GV operand");
  case RISCVII::MO_None:
    Kind = RISCVMCExpr::VK_RISCV_None;
    break;
  case RISCVII::MO_LO:
    Kind = RISCVMCExpr::VK_RISCV_LO;
    break;
  case RISCVII::MO_HI:
    Kind = RISCVMCExpr::VK_RISCV_HI;
    break;
  }

  const MCExpr *ME =
      MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);

  if (!MO.isJTI() && MO.getOffset())
    ME = MCBinaryExpr::createAdd(
        ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);

  ME = RISCVMCExpr::create(ME, Kind, Ctx);
  return MCOperand::createExpr(ME);
}
예제 #8
0
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                            const MachineOperand &MO) const {
  if (MO.isReg())
    return MipsRegisterInfo::getRegisterNumbering(MO.getReg());
  else if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());
  else if (MO.isGlobal()) {
    if (MI.getOpcode() == Mips::ULW || MI.getOpcode() == Mips::USW ||
          MI.getOpcode() == Mips::ULH || MI.getOpcode() == Mips::ULHu)
      emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 4);
    else if (MI.getOpcode() == Mips::USH)
      emitGlobalAddressUnaligned(MO.getGlobal(), getRelocation(MI, MO), 8);
    else
      emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
  } else if (MO.isSymbol())
    emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
  else if (MO.isCPI())
    emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
  else if (MO.isJTI())
    emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
  else if (MO.isMBB())
    emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
  else
    llvm_unreachable("Unable to encode MachineOperand!");
  return 0;
}
예제 #9
0
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
                              ARMAsmPrinter &Printer) {
  MCContext &Ctx = Printer.OutContext;
  const MCExpr *Expr;
  switch (MO.getTargetFlags()) {
  default: assert(0 && "Unknown target flag on symbol operand");
  case 0:
    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, Ctx);
    break;
  case ARMII::MO_LO16:
    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_LO16, Ctx);
    break;
  case ARMII::MO_HI16:
    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_HI16, Ctx);
    break;
  case ARMII::MO_PLT:
    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT, Ctx);
    break;
  }

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::CreateAdd(Expr,
                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
                                   Ctx);
  return MCOperand::CreateExpr(Expr);

}
예제 #10
0
MCOperand AArch64MCInstLower::lowerSymbolOperandDarwin(const MachineOperand &MO,
                                                       MCSymbol *Sym) const {
  // FIXME: We would like an efficient form for this, so we don't have to do a
  // lot of extra uniquing.
  MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
  if ((MO.getTargetFlags() & AArch64II::MO_GOT) != 0) {
    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      RefKind = MCSymbolRefExpr::VK_GOTPAGE;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_PAGEOFF)
      RefKind = MCSymbolRefExpr::VK_GOTPAGEOFF;
    else
      llvm_unreachable("Unexpected target flags with MO_GOT on GV operand");
  } else if ((MO.getTargetFlags() & AArch64II::MO_TLS) != 0) {
    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      RefKind = MCSymbolRefExpr::VK_TLVPPAGE;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_PAGEOFF)
      RefKind = MCSymbolRefExpr::VK_TLVPPAGEOFF;
    else
      llvm_unreachable("Unexpected target flags with MO_TLS on GV operand");
  } else {
    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
      RefKind = MCSymbolRefExpr::VK_PAGE;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_PAGEOFF)
      RefKind = MCSymbolRefExpr::VK_PAGEOFF;
  }
  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
  return MCOperand::createExpr(Expr);
}
예제 #11
0
static bool isSimilarDispOp(const MachineOperand &MO1,
                            const MachineOperand &MO2) {
  assert(isValidDispOp(MO1) && isValidDispOp(MO2) &&
         "Address displacement operand is not valid");
  return (MO1.isImm() && MO2.isImm()) ||
         (MO1.isCPI() && MO2.isCPI() && MO1.getIndex() == MO2.getIndex()) ||
         (MO1.isJTI() && MO2.isJTI() && MO1.getIndex() == MO2.getIndex()) ||
         (MO1.isSymbol() && MO2.isSymbol() &&
          MO1.getSymbolName() == MO2.getSymbolName()) ||
         (MO1.isGlobal() && MO2.isGlobal() &&
          MO1.getGlobal() == MO2.getGlobal()) ||
         (MO1.isBlockAddress() && MO2.isBlockAddress() &&
          MO1.getBlockAddress() == MO2.getBlockAddress()) ||
         (MO1.isMCSymbol() && MO2.isMCSymbol() &&
          MO1.getMCSymbol() == MO2.getMCSymbol()) ||
         (MO1.isMBB() && MO2.isMBB() && MO1.getMBB() == MO2.getMBB());
}
예제 #12
0
static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
                              AsmPrinter &Printer, bool isDarwin) {
  MCContext &Ctx = Printer.OutContext;
  MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;

  unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK;

  switch (access) {
    case PPCII::MO_TPREL_LO:
      RefKind = MCSymbolRefExpr::VK_PPC_TPREL_LO;
      break;
    case PPCII::MO_TPREL_HA:
      RefKind = MCSymbolRefExpr::VK_PPC_TPREL_HA;
      break;
    case PPCII::MO_DTPREL_LO:
      RefKind = MCSymbolRefExpr::VK_PPC_DTPREL_LO;
      break;
    case PPCII::MO_TLSLD_LO:
      RefKind = MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO;
      break;
    case PPCII::MO_TOC_LO:
      RefKind = MCSymbolRefExpr::VK_PPC_TOC_LO;
      break;
    case PPCII::MO_TLS:
      RefKind = MCSymbolRefExpr::VK_PPC_TLS;
      break;
  }

  if (MO.getTargetFlags() == PPCII::MO_PLT_OR_STUB && !isDarwin)
    RefKind = MCSymbolRefExpr::VK_PLT;

  const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, RefKind, Ctx);

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(Expr,
                                   MCConstantExpr::create(MO.getOffset(), Ctx),
                                   Ctx);

  // Subtract off the PIC base if required.
  if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) {
    const MachineFunction *MF = MO.getParent()->getParent()->getParent();
    
    const MCExpr *PB = MCSymbolRefExpr::create(MF->getPICBaseSymbol(), Ctx);
    Expr = MCBinaryExpr::createSub(Expr, PB, Ctx);
  }

  // Add ha16() / lo16() markers if required.
  switch (access) {
    case PPCII::MO_LO:
      Expr = PPCMCExpr::createLo(Expr, isDarwin, Ctx);
      break;
    case PPCII::MO_HA:
      Expr = PPCMCExpr::createHa(Expr, isDarwin, Ctx);
      break;
  }

  return MCOperand::createExpr(Expr);
}
예제 #13
0
MCOperand ARMMCInstLower::
LowerSymbolRefOperand(const MachineOperand &MO,
                      const MCSymbolRefExpr *Sym) const {
  const MCExpr *Expr = Sym;
  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::CreateAdd(Expr,
                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
                                   Ctx);
  return MCOperand::CreateExpr(Expr);
}
예제 #14
0
MCOperand WebAssemblyMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
        MCSymbol *Sym) const {

    const MCExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);

    if (!MO.isJTI() && MO.getOffset())
        llvm_unreachable("unknown symbol op");

    return MCOperand::createExpr(Expr);
}
예제 #15
0
static MCOperand GetSymbolRef(const MachineOperand& MO, const MCSymbol* Symbol,
                              HexagonAsmPrinter& Printer) {
  MCContext &MC = Printer.OutContext;
  const MCExpr *ME;

  ME = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, MC);

  if (!MO.isJTI() && MO.getOffset())
    ME = MCBinaryExpr::CreateAdd(ME, MCConstantExpr::Create(MO.getOffset(), MC),
                                 MC);

  return (MCOperand::createExpr(ME));
}
예제 #16
0
MCOperand AArch64MCInstLower::lowerSymbolOperandCOFF(const MachineOperand &MO,
                                                     MCSymbol *Sym) const {
  uint32_t RefFlags = 0;

  if (MO.getTargetFlags() & AArch64II::MO_TLS) {
    if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGEOFF)
      RefFlags |= AArch64MCExpr::VK_SECREL_LO12;
    else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
             AArch64II::MO_HI12)
      RefFlags |= AArch64MCExpr::VK_SECREL_HI12;

  } else if (MO.getTargetFlags() & AArch64II::MO_S) {
    RefFlags |= AArch64MCExpr::VK_SABS;
  } else {
    RefFlags |= AArch64MCExpr::VK_ABS;
  }

  if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
    RefFlags |= AArch64MCExpr::VK_G3;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2)
    RefFlags |= AArch64MCExpr::VK_G2;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1)
    RefFlags |= AArch64MCExpr::VK_G1;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
    RefFlags |= AArch64MCExpr::VK_G0;

  // FIXME: Currently we only set VK_NC for MO_G3/MO_G2/MO_G1/MO_G0. This is
  // because setting VK_NC for others would mean setting their respective
  // RefFlags correctly.  We should do this in a separate patch.
  if (MO.getTargetFlags() & AArch64II::MO_NC) {
    auto MOFrag = (MO.getTargetFlags() & AArch64II::MO_FRAGMENT);
    if (MOFrag == AArch64II::MO_G3 || MOFrag == AArch64II::MO_G2 ||
        MOFrag == AArch64II::MO_G1 || MOFrag == AArch64II::MO_G0)
      RefFlags |= AArch64MCExpr::VK_NC;
  }

  const MCExpr *Expr =
      MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);

  auto RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
  assert(RefKind != AArch64MCExpr::VK_INVALID &&
         "Invalid relocation requested");
  Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);

  return MCOperand::createExpr(Expr);
}
예제 #17
0
void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt,
                                         unsigned DoubleDestReg,
                                         MachineOperand &HiOperand,
                                         MachineOperand &LoOperand) {
  unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill());
  unsigned HiReg = HiOperand.getReg();

  DebugLoc DL = InsertPt->getDebugLoc();
  MachineBasicBlock *BB = InsertPt->getParent();

  // Handle global.
  if (LoOperand.isGlobal()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
      .addReg(HiReg, HiRegKillFlag)
      .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
                        LoOperand.getTargetFlags());
    return;
  }
  // Handle block addresses.
  if (LoOperand.isBlockAddress()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
      .addReg(HiReg, HiRegKillFlag)
      .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
                       LoOperand.getTargetFlags());
    return;
  }
  // Handle jump tables.
  if (LoOperand.isJTI()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
      .addReg(HiOperand.getReg(), HiRegKillFlag)
      .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
    return;
  }
  // Handle constant pools.
  if (LoOperand.isCPI()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
      .addReg(HiOperand.getReg(), HiRegKillFlag)
      .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
                            LoOperand.getTargetFlags());
    return;
  }

  // Insert new combine instruction.
  //  DoubleRegDest = combine HiReg, #LoImm
  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg)
    .addReg(HiReg, HiRegKillFlag)
    .addImm(LoOperand.getImm());
}
예제 #18
0
MCOperand MSP430MCInstLower::
LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
  // FIXME: We would like an efficient form for this, so we don't have to do a
  // lot of extra uniquing.
  const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);

  switch (MO.getTargetFlags()) {
  default: llvm_unreachable("Unknown target flag on GV operand");
  case 0: break;
  }

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::CreateAdd(Expr,
                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
                                   Ctx);
  return MCOperand::CreateExpr(Expr);
}
예제 #19
0
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned MipsCodeEmitter::getMachineOpValue(const MachineInstr &MI,
                                            const MachineOperand &MO) const {
  if (MO.isReg())
    return TM.getRegisterInfo()->getEncodingValue(MO.getReg());
  else if (MO.isImm())
    return static_cast<unsigned>(MO.getImm());
  else if (MO.isGlobal())
    emitGlobalAddress(MO.getGlobal(), getRelocation(MI, MO), true);
  else if (MO.isSymbol())
    emitExternalSymbolAddress(MO.getSymbolName(), getRelocation(MI, MO));
  else if (MO.isCPI())
    emitConstPoolAddress(MO.getIndex(), getRelocation(MI, MO));
  else if (MO.isJTI())
    emitJumpTableAddress(MO.getIndex(), getRelocation(MI, MO));
  else if (MO.isMBB())
    emitMachineBasicBlock(MO.getMBB(), getRelocation(MI, MO));
  else
    llvm_unreachable("Unable to encode MachineOperand!");
  return 0;
}
예제 #20
0
MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
                                      const MCSymbol *Symbol) {
  const MCExpr *Expr;
  switch (MO.getTargetFlags()) {
  default: {
    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
                                   OutContext);
    switch (MO.getTargetFlags()) {
    default:
      assert(0 && "Unknown target flag on symbol operand");
    case 0:
      break;
    case ARMII::MO_LO16:
      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
                                     OutContext);
      Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
      break;
    case ARMII::MO_HI16:
      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
                                     OutContext);
      Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
      break;
    }
    break;
  }

  case ARMII::MO_PLT:
    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_ARM_PLT,
                                   OutContext);
    break;
  }

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::CreateAdd(Expr,
                                   MCConstantExpr::Create(MO.getOffset(),
                                                          OutContext),
                                   OutContext);
  return MCOperand::CreateExpr(Expr);

}
MCOperand ARMAsmPrinter::GetSymbolRef(const MachineOperand &MO,
                                      const MCSymbol *Symbol) {
  const MCExpr *Expr;
  unsigned Option = MO.getTargetFlags() & ARMII::MO_OPTION_MASK;
  switch (Option) {
  default: {
    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
                                   OutContext);
    switch (Option) {
    default: llvm_unreachable("Unknown target flag on symbol operand");
    case ARMII::MO_NO_FLAG:
      break;
    case ARMII::MO_LO16:
      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
                                     OutContext);
      Expr = ARMMCExpr::CreateLower16(Expr, OutContext);
      break;
    case ARMII::MO_HI16:
      Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
                                     OutContext);
      Expr = ARMMCExpr::CreateUpper16(Expr, OutContext);
      break;
    }
    break;
  }

  case ARMII::MO_PLT:
    Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_PLT,
                                   OutContext);
    break;
  }

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::CreateAdd(Expr,
                                   MCConstantExpr::Create(MO.getOffset(),
                                                          OutContext),
                                   OutContext);
  return MCOperand::CreateExpr(Expr);

}
예제 #22
0
static bool isValidDispOp(const MachineOperand &MO) {
  return MO.isImm() || MO.isCPI() || MO.isJTI() || MO.isSymbol() ||
         MO.isGlobal() || MO.isBlockAddress() || MO.isMCSymbol() || MO.isMBB();
}
MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
                                             MCSymbol *Sym) const {
  // FIXME: We would like an efficient form for this, so we don't have to do a
  // lot of extra uniquing.
  const MCExpr *Expr = 0;
  MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;

  switch (MO.getTargetFlags()) {
  default: llvm_unreachable("Unknown target flag on GV operand");
  case X86II::MO_NO_FLAG:    // No flag.
  // These affect the name of the symbol, not any suffix.
  case X86II::MO_DARWIN_NONLAZY:
  case X86II::MO_DLLIMPORT:
  case X86II::MO_DARWIN_STUB:
    break;

  case X86II::MO_TLVP:      RefKind = MCSymbolRefExpr::VK_TLVP; break;
  case X86II::MO_TLVP_PIC_BASE:
    Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
    // Subtract the pic base.
    Expr = MCBinaryExpr::CreateSub(Expr,
                                  MCSymbolRefExpr::Create(MF.getPICBaseSymbol(),
                                                           Ctx),
                                   Ctx);
    break;
  case X86II::MO_SECREL:    RefKind = MCSymbolRefExpr::VK_SECREL; break;
  case X86II::MO_TLSGD:     RefKind = MCSymbolRefExpr::VK_TLSGD; break;
  case X86II::MO_TLSLD:     RefKind = MCSymbolRefExpr::VK_TLSLD; break;
  case X86II::MO_TLSLDM:    RefKind = MCSymbolRefExpr::VK_TLSLDM; break;
  case X86II::MO_GOTTPOFF:  RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break;
  case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break;
  case X86II::MO_TPOFF:     RefKind = MCSymbolRefExpr::VK_TPOFF; break;
  case X86II::MO_DTPOFF:    RefKind = MCSymbolRefExpr::VK_DTPOFF; break;
  case X86II::MO_NTPOFF:    RefKind = MCSymbolRefExpr::VK_NTPOFF; break;
  case X86II::MO_GOTNTPOFF: RefKind = MCSymbolRefExpr::VK_GOTNTPOFF; break;
  case X86II::MO_GOTPCREL:  RefKind = MCSymbolRefExpr::VK_GOTPCREL; break;
  case X86II::MO_GOT:       RefKind = MCSymbolRefExpr::VK_GOT; break;
  case X86II::MO_GOTOFF:    RefKind = MCSymbolRefExpr::VK_GOTOFF; break;
  case X86II::MO_PLT:       RefKind = MCSymbolRefExpr::VK_PLT; break;
  case X86II::MO_PIC_BASE_OFFSET:
  case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
  case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
    Expr = MCSymbolRefExpr::Create(Sym, Ctx);
    // Subtract the pic base.
    Expr = MCBinaryExpr::CreateSub(Expr,
                            MCSymbolRefExpr::Create(MF.getPICBaseSymbol(), Ctx),
                                   Ctx);
    if (MO.isJTI() && MAI.hasSetDirective()) {
      // If .set directive is supported, use it to reduce the number of
      // relocations the assembler will generate for differences between
      // local labels. This is only safe when the symbols are in the same
      // section so we are restricting it to jumptable references.
      MCSymbol *Label = Ctx.CreateTempSymbol();
      AsmPrinter.OutStreamer.EmitAssignment(Label, Expr);
      Expr = MCSymbolRefExpr::Create(Label, Ctx);
    }
    break;
  }

  if (Expr == 0)
    Expr = MCSymbolRefExpr::Create(Sym, RefKind, Ctx);

  if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
    Expr = MCBinaryExpr::CreateAdd(Expr,
                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
                                   Ctx);
  return MCOperand::CreateExpr(Expr);
}
예제 #24
0
void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt,
                                         unsigned DoubleDestReg,
                                         MachineOperand &HiOperand,
                                         MachineOperand &LoOperand) {
  DebugLoc DL = InsertPt->getDebugLoc();
  MachineBasicBlock *BB = InsertPt->getParent();

  // Handle globals.
  if (HiOperand.isGlobal()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
      .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(),
                        HiOperand.getTargetFlags())
      .addImm(LoOperand.getImm());
    return;
  }
  if (LoOperand.isGlobal()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
      .addImm(HiOperand.getImm())
      .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(),
                        LoOperand.getTargetFlags());
    return;
  }

  // Handle block addresses.
  if (HiOperand.isBlockAddress()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
      .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(),
                       HiOperand.getTargetFlags())
      .addImm(LoOperand.getImm());
    return;
  }
  if (LoOperand.isBlockAddress()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
      .addImm(HiOperand.getImm())
      .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(),
                       LoOperand.getTargetFlags());
    return;
  }

  // Handle jump tables.
  if (HiOperand.isJTI()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
      .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags())
      .addImm(LoOperand.getImm());
    return;
  }
  if (LoOperand.isJTI()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
      .addImm(HiOperand.getImm())
      .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags());
    return;
  }

  // Handle constant pools.
  if (HiOperand.isCPI()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
      .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(),
                            HiOperand.getTargetFlags())
      .addImm(LoOperand.getImm());
    return;
  }
  if (LoOperand.isCPI()) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
      .addImm(HiOperand.getImm())
      .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(),
                            LoOperand.getTargetFlags());
    return;
  }

  // First preference should be given to Hexagon::A2_combineii instruction
  // as it can include U6 (in Hexagon::A4_combineii) as well.
  // In this instruction, HiOperand is const extended, if required.
  if (isInt<8>(LoOperand.getImm())) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
      .addImm(HiOperand.getImm())
      .addImm(LoOperand.getImm());
      return;
  }

  // In this instruction, LoOperand is const extended, if required.
  if (isInt<8>(HiOperand.getImm())) {
    BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg)
      .addImm(HiOperand.getImm())
      .addImm(LoOperand.getImm());
    return;
  }

  // Insert new combine instruction.
  //  DoubleRegDest = combine #HiImm, #LoImm
  BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg)
    .addImm(HiOperand.getImm())
    .addImm(LoOperand.getImm());
}
예제 #25
0
MCOperand AArch64MCInstLower::lowerSymbolOperandELF(const MachineOperand &MO,
                                                    MCSymbol *Sym) const {
  uint32_t RefFlags = 0;

  if (MO.getTargetFlags() & AArch64II::MO_GOT)
    RefFlags |= AArch64MCExpr::VK_GOT;
  else if (MO.getTargetFlags() & AArch64II::MO_TLS) {
    TLSModel::Model Model;
    if (MO.isGlobal()) {
      const GlobalValue *GV = MO.getGlobal();
      Model = Printer.TM.getTLSModel(GV);
      if (!EnableAArch64ELFLocalDynamicTLSGeneration &&
          Model == TLSModel::LocalDynamic)
        Model = TLSModel::GeneralDynamic;

    } else {
      assert(MO.isSymbol() &&
             StringRef(MO.getSymbolName()) == "_TLS_MODULE_BASE_" &&
             "unexpected external TLS symbol");
      // The general dynamic access sequence is used to get the
      // address of _TLS_MODULE_BASE_.
      Model = TLSModel::GeneralDynamic;
    }
    switch (Model) {
    case TLSModel::InitialExec:
      RefFlags |= AArch64MCExpr::VK_GOTTPREL;
      break;
    case TLSModel::LocalExec:
      RefFlags |= AArch64MCExpr::VK_TPREL;
      break;
    case TLSModel::LocalDynamic:
      RefFlags |= AArch64MCExpr::VK_DTPREL;
      break;
    case TLSModel::GeneralDynamic:
      RefFlags |= AArch64MCExpr::VK_TLSDESC;
      break;
    }
  } else {
    // No modifier means this is a generic reference, classified as absolute for
    // the cases where it matters (:abs_g0: etc).
    RefFlags |= AArch64MCExpr::VK_ABS;
  }

  if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_PAGE)
    RefFlags |= AArch64MCExpr::VK_PAGE;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) ==
           AArch64II::MO_PAGEOFF)
    RefFlags |= AArch64MCExpr::VK_PAGEOFF;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G3)
    RefFlags |= AArch64MCExpr::VK_G3;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G2)
    RefFlags |= AArch64MCExpr::VK_G2;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G1)
    RefFlags |= AArch64MCExpr::VK_G1;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_G0)
    RefFlags |= AArch64MCExpr::VK_G0;
  else if ((MO.getTargetFlags() & AArch64II::MO_FRAGMENT) == AArch64II::MO_HI12)
    RefFlags |= AArch64MCExpr::VK_HI12;

  if (MO.getTargetFlags() & AArch64II::MO_NC)
    RefFlags |= AArch64MCExpr::VK_NC;

  const MCExpr *Expr =
      MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::createAdd(
        Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);

  AArch64MCExpr::VariantKind RefKind;
  RefKind = static_cast<AArch64MCExpr::VariantKind>(RefFlags);
  Expr = AArch64MCExpr::create(Expr, RefKind, Ctx);

  return MCOperand::createExpr(Expr);
}
예제 #26
0
MCOperand
AArch64AsmPrinter::lowerSymbolOperand(const MachineOperand &MO,
                                      const MCSymbol *Sym) const {
  const MCExpr *Expr = 0;

  Expr = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, OutContext);

  switch (MO.getTargetFlags()) {
  case AArch64II::MO_GOT:
    Expr = AArch64MCExpr::CreateGOT(Expr, OutContext);
    break;
  case AArch64II::MO_GOT_LO12:
    Expr = AArch64MCExpr::CreateGOTLo12(Expr, OutContext);
    break;
  case AArch64II::MO_LO12:
    Expr = AArch64MCExpr::CreateLo12(Expr, OutContext);
    break;
  case AArch64II::MO_DTPREL_G1:
    Expr = AArch64MCExpr::CreateDTPREL_G1(Expr, OutContext);
    break;
  case AArch64II::MO_DTPREL_G0_NC:
    Expr = AArch64MCExpr::CreateDTPREL_G0_NC(Expr, OutContext);
    break;
  case AArch64II::MO_GOTTPREL:
    Expr = AArch64MCExpr::CreateGOTTPREL(Expr, OutContext);
    break;
  case AArch64II::MO_GOTTPREL_LO12:
    Expr = AArch64MCExpr::CreateGOTTPRELLo12(Expr, OutContext);
    break;
  case AArch64II::MO_TLSDESC:
    Expr = AArch64MCExpr::CreateTLSDesc(Expr, OutContext);
    break;
  case AArch64II::MO_TLSDESC_LO12:
    Expr = AArch64MCExpr::CreateTLSDescLo12(Expr, OutContext);
    break;
  case AArch64II::MO_TPREL_G1:
    Expr = AArch64MCExpr::CreateTPREL_G1(Expr, OutContext);
    break;
  case AArch64II::MO_TPREL_G0_NC:
    Expr = AArch64MCExpr::CreateTPREL_G0_NC(Expr, OutContext);
    break;
  case AArch64II::MO_ABS_G3:
    Expr = AArch64MCExpr::CreateABS_G3(Expr, OutContext);
    break;
  case AArch64II::MO_ABS_G2_NC:
    Expr = AArch64MCExpr::CreateABS_G2_NC(Expr, OutContext);
    break;
  case AArch64II::MO_ABS_G1_NC:
    Expr = AArch64MCExpr::CreateABS_G1_NC(Expr, OutContext);
    break;
  case AArch64II::MO_ABS_G0_NC:
    Expr = AArch64MCExpr::CreateABS_G0_NC(Expr, OutContext);
    break;
  case AArch64II::MO_NO_FLAG:
    // Expr is already correct
    break;
  default:
    llvm_unreachable("Unexpected MachineOperand flag");
  }

  if (!MO.isJTI() && MO.getOffset())
    Expr = MCBinaryExpr::CreateAdd(Expr,
                                   MCConstantExpr::Create(MO.getOffset(),
                                                          OutContext),
                                   OutContext);

  return MCOperand::CreateExpr(Expr);
}