void AMDGPUMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {

  int MCOpcode = ST.getInstrInfo()->pseudoToMCOpcode(MI->getOpcode());

  if (MCOpcode == -1) {
    LLVMContext &C = MI->getParent()->getParent()->getFunction()->getContext();
    C.emitError("AMDGPUMCInstLower::lower - Pseudo instruction doesn't have "
                "a target-specific version: " + Twine(MI->getOpcode()));
  }

  OutMI.setOpcode(MCOpcode);

  for (const MachineOperand &MO : MI->explicit_operands()) {
    MCOperand MCOp;
    switch (MO.getType()) {
    default:
      llvm_unreachable("unknown operand type");
    case MachineOperand::MO_Immediate:
      MCOp = MCOperand::createImm(MO.getImm());
      break;
    case MachineOperand::MO_Register:
      MCOp = MCOperand::createReg(AMDGPU::getMCReg(MO.getReg(), ST));
      break;
    case MachineOperand::MO_MachineBasicBlock:
      MCOp = MCOperand::createExpr(MCSymbolRefExpr::create(
                                   MO.getMBB()->getSymbol(), Ctx));
      break;
    case MachineOperand::MO_GlobalAddress: {
      const GlobalValue *GV = MO.getGlobal();
      MCSymbol *Sym = Ctx.getOrCreateSymbol(StringRef(GV->getName()));
      const MCExpr *SymExpr = MCSymbolRefExpr::create(Sym, Ctx);
      const MCExpr *Expr = MCBinaryExpr::createAdd(SymExpr,
          MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
      MCOp = MCOperand::createExpr(Expr);
      break;
    }
    case MachineOperand::MO_ExternalSymbol: {
      MCSymbol *Sym = Ctx.getOrCreateSymbol(StringRef(MO.getSymbolName()));
      Sym->setExternal(true);
      const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
      MCOp = MCOperand::createExpr(Expr);
      break;
    }
    }
    OutMI.addOperand(MCOp);
  }
}
bool AMDGPUMCInstLower::lowerOperand(const MachineOperand &MO,
                                     MCOperand &MCOp) const {
  switch (MO.getType()) {
  default:
    llvm_unreachable("unknown operand type");
  case MachineOperand::MO_Immediate:
    MCOp = MCOperand::createImm(MO.getImm());
    return true;
  case MachineOperand::MO_Register:
    MCOp = MCOperand::createReg(AMDGPU::getMCReg(MO.getReg(), ST));
    return true;
  case MachineOperand::MO_MachineBasicBlock: {
    if (MO.getTargetFlags() != 0) {
      MCOp = MCOperand::createExpr(
        getLongBranchBlockExpr(*MO.getParent()->getParent(), MO));
    } else {
      MCOp = MCOperand::createExpr(
        MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
    }

    return true;
  }
  case MachineOperand::MO_GlobalAddress: {
    const GlobalValue *GV = MO.getGlobal();
    SmallString<128> SymbolName;
    AP.getNameWithPrefix(SymbolName, GV);
    MCSymbol *Sym = Ctx.getOrCreateSymbol(SymbolName);
    const MCExpr *SymExpr =
      MCSymbolRefExpr::create(Sym, getVariantKind(MO.getTargetFlags()),Ctx);
    const MCExpr *Expr = MCBinaryExpr::createAdd(SymExpr,
      MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
    MCOp = MCOperand::createExpr(Expr);
    return true;
  }
  case MachineOperand::MO_ExternalSymbol: {
    MCSymbol *Sym = Ctx.getOrCreateSymbol(StringRef(MO.getSymbolName()));
    Sym->setExternal(true);
    const MCSymbolRefExpr *Expr = MCSymbolRefExpr::create(Sym, Ctx);
    MCOp = MCOperand::createExpr(Expr);
    return true;
  }
  case MachineOperand::MO_RegisterMask:
    // Regmasks are like implicit defs.
    return false;
  }
}
  void EmitMappingSymbol(StringRef Name) {
    MCSymbol *Start = getContext().createTempSymbol();
    EmitLabel(Start);

    MCSymbol *Symbol =
      getContext().getOrCreateSymbol(Name + "." +
                                     Twine(MappingSymbolCounter++));

    getAssembler().registerSymbol(*Symbol);
    MCELF::SetType(*Symbol, ELF::STT_NOTYPE);
    MCELF::SetBinding(*Symbol, ELF::STB_LOCAL);
    Symbol->setExternal(false);
    AssignSection(Symbol, getCurrentSection().first);

    const MCExpr *Value = MCSymbolRefExpr::create(Start, getContext());
    Symbol->setVariableValue(Value);
  }