11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZMCInstLower.cpp - Lower MachineInstr to MCInst -------------===//
21d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//
31d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//                     The LLVM Compiler Infrastructure
41d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//
51d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file is distributed under the University of Illinois Open Source
61d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// License. See LICENSE.TXT for details.
71d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//
81d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===//
91d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZMCInstLower.h"
111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZAsmPrinter.h"
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Mangler.h"
131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCExpr.h"
141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCStreamer.h"
151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm;
171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// Return the VK_* enumeration for MachineOperand target flags Flags.
191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandstatic MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags) {
201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  switch (Flags & SystemZII::MO_SYMBOL_MODIFIER) {
211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    case 0:
221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand      return MCSymbolRefExpr::VK_None;
231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    case SystemZII::MO_GOT:
241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand      return MCSymbolRefExpr::VK_GOT;
25ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case SystemZII::MO_INDNTPOFF:
26ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return MCSymbolRefExpr::VK_INDNTPOFF;
271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  llvm_unreachable("Unrecognised MO_ACCESS_MODEL");
291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
318eff5d998e88ba8763d72f4e94d7a32f2dbb9005Rafael EspindolaSystemZMCInstLower::SystemZMCInstLower(MCContext &ctx,
321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                                       SystemZAsmPrinter &asmprinter)
338eff5d998e88ba8763d72f4e94d7a32f2dbb9005Rafael Espindola  : Ctx(ctx), AsmPrinter(asmprinter) {}
341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
3576f8ae87b4705f5c08c3995948223531715a2d58Richard Sandifordconst MCExpr *
3676f8ae87b4705f5c08c3995948223531715a2d58Richard SandifordSystemZMCInstLower::getExpr(const MachineOperand &MO,
3776f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford                            MCSymbolRefExpr::VariantKind Kind) const {
3876f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  const MCSymbol *Symbol;
3976f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  bool HasOffset = true;
4076f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  switch (MO.getType()) {
4176f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  case MachineOperand::MO_MachineBasicBlock:
4276f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    Symbol = MO.getMBB()->getSymbol();
4376f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    HasOffset = false;
4476f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    break;
4576f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford
4676f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  case MachineOperand::MO_GlobalAddress:
47ffc7dca885151ed42642c2d6733e8db75d276621Rafael Espindola    Symbol = AsmPrinter.getSymbol(MO.getGlobal());
4876f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    break;
4976f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford
5076f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  case MachineOperand::MO_ExternalSymbol:
5176f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    Symbol = AsmPrinter.GetExternalSymbolSymbol(MO.getSymbolName());
5276f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    break;
5376f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford
5476f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  case MachineOperand::MO_JumpTableIndex:
5576f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    Symbol = AsmPrinter.GetJTISymbol(MO.getIndex());
5676f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    HasOffset = false;
5776f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    break;
5876f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford
5976f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  case MachineOperand::MO_ConstantPoolIndex:
6076f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    Symbol = AsmPrinter.GetCPISymbol(MO.getIndex());
6176f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    break;
6276f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford
6376f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  case MachineOperand::MO_BlockAddress:
6476f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    Symbol = AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress());
6576f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    break;
6676f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford
6776f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  default:
6876f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    llvm_unreachable("unknown operand type");
691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
7076f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, Kind, Ctx);
7176f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  if (HasOffset)
7276f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    if (int64_t Offset = MO.getOffset()) {
7376f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford      const MCExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx);
7476f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford      Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx);
7576f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    }
7676f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  return Expr;
771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const {
801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  switch (MO.getType()) {
811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  case MachineOperand::MO_Register:
821d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    return MCOperand::CreateReg(MO.getReg());
831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  case MachineOperand::MO_Immediate:
851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    return MCOperand::CreateImm(MO.getImm());
861d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
8776f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  default: {
8876f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags());
8976f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford    return MCOperand::CreateExpr(getExpr(MO, Kind));
901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
9576f8ae87b4705f5c08c3995948223531715a2d58Richard Sandiford  OutMI.setOpcode(MI->getOpcode());
961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    const MachineOperand &MO = MI->getOperand(I);
985e009541973b7935386055066689902aa7134e2dRichard Sandiford    // Ignore all implicit register operands.
995e009541973b7935386055066689902aa7134e2dRichard Sandiford    if (!MO.isReg() || !MO.isImplicit())
1005e009541973b7935386055066689902aa7134e2dRichard Sandiford      OutMI.addOperand(lowerOperand(MO));
1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
103