19578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne//===-- XCoreMCInstLower.cpp - Convert XCore MachineInstr to MCInst -------===//
29578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne//
39578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne//                     The LLVM Compiler Infrastructure
49578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne//
59578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne// This file is distributed under the University of Illinois Open Source
69578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne// License. See LICENSE.TXT for details.
79578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne//
89578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne//===----------------------------------------------------------------------===//
9b4d40a04f0639fdec8329a8708565411fa53b5bcRichard Osborne///
10b4d40a04f0639fdec8329a8708565411fa53b5bcRichard Osborne/// \file
11b4d40a04f0639fdec8329a8708565411fa53b5bcRichard Osborne/// \brief This file contains code to lower XCore MachineInstrs to their
12b4d40a04f0639fdec8329a8708565411fa53b5bcRichard Osborne/// corresponding MCInst records.
13b4d40a04f0639fdec8329a8708565411fa53b5bcRichard Osborne///
149578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne//===----------------------------------------------------------------------===//
159578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "XCoreMCInstLower.h"
169578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "llvm/CodeGen/AsmPrinter.h"
179578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "llvm/CodeGen/MachineFunction.h"
189578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "llvm/CodeGen/MachineInstr.h"
199578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "llvm/CodeGen/MachineOperand.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Mangler.h"
219578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "llvm/MC/MCContext.h"
229578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "llvm/MC/MCExpr.h"
239578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne#include "llvm/MC/MCInst.h"
249578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
259578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborneusing namespace llvm;
269578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
279578d793c9450b315721d5cb15001c2e69bff3d0Richard OsborneXCoreMCInstLower::XCoreMCInstLower(class AsmPrinter &asmprinter)
289578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne: Printer(asmprinter) {}
299578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
309578d793c9450b315721d5cb15001c2e69bff3d0Richard Osbornevoid XCoreMCInstLower::Initialize(Mangler *M, MCContext *C) {
319578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  Mang = M;
329578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  Ctx = C;
339578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne}
349578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
359578d793c9450b315721d5cb15001c2e69bff3d0Richard OsborneMCOperand XCoreMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
369578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne                                               MachineOperandType MOTy,
379578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne                                               unsigned Offset) const {
389578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
399578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  const MCSymbol *Symbol;
409578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
419578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  switch (MOTy) {
429578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_MachineBasicBlock:
439578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Symbol = MO.getMBB()->getSymbol();
449578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      break;
459578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_GlobalAddress:
46ffc7dca885151ed42642c2d6733e8db75d276621Rafael Espindola      Symbol = Printer.getSymbol(MO.getGlobal());
479578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Offset += MO.getOffset();
489578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      break;
499578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_BlockAddress:
509578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Symbol = Printer.GetBlockAddressSymbol(MO.getBlockAddress());
519578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Offset += MO.getOffset();
529578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      break;
539578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_ExternalSymbol:
549578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Symbol = Printer.GetExternalSymbolSymbol(MO.getSymbolName());
559578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Offset += MO.getOffset();
569578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      break;
579578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_JumpTableIndex:
589578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Symbol = Printer.GetJTISymbol(MO.getIndex());
599578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      break;
609578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_ConstantPoolIndex:
619578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Symbol = Printer.GetCPISymbol(MO.getIndex());
629578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      Offset += MO.getOffset();
639578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      break;
649578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    default:
659578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      llvm_unreachable("<unknown operand type>");
669578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  }
679578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::create(Symbol, Kind, *Ctx);
699578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
709578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  if (!Offset)
716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return MCOperand::createExpr(MCSym);
729578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
739578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  // Assume offset is never negative.
749578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  assert(Offset > 0);
759578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCConstantExpr *OffsetExpr =  MCConstantExpr::create(Offset, *Ctx);
776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCBinaryExpr *Add = MCBinaryExpr::createAdd(MCSym, OffsetExpr, *Ctx);
786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return MCOperand::createExpr(Add);
799578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne}
809578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
819578d793c9450b315721d5cb15001c2e69bff3d0Richard OsborneMCOperand XCoreMCInstLower::LowerOperand(const MachineOperand &MO,
829578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne                                         unsigned offset) const {
839578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  MachineOperandType MOTy = MO.getType();
849578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
859578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  switch (MOTy) {
869578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    default: llvm_unreachable("unknown operand type");
879578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_Register:
889578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      // Ignore all implicit register operands.
899578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      if (MO.isImplicit()) break;
906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return MCOperand::createReg(MO.getReg());
919578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_Immediate:
926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return MCOperand::createImm(MO.getImm() + offset);
939578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_MachineBasicBlock:
949578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_GlobalAddress:
959578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_ExternalSymbol:
969578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_JumpTableIndex:
979578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_ConstantPoolIndex:
989578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_BlockAddress:
999578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      return LowerSymbolOperand(MO, MOTy, offset);
1009578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    case MachineOperand::MO_RegisterMask:
1019578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      break;
1029578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  }
1039578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
1049578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  return MCOperand();
1059578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne}
1069578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
1079578d793c9450b315721d5cb15001c2e69bff3d0Richard Osbornevoid XCoreMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
1089578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  OutMI.setOpcode(MI->getOpcode());
1099578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
1109578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1119578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    const MachineOperand &MO = MI->getOperand(i);
1129578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    MCOperand MCOp = LowerOperand(MO);
1139578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne
1149578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne    if (MCOp.isValid())
1159578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne      OutMI.addOperand(MCOp);
1169578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne  }
1179578d793c9450b315721d5cb15001c2e69bff3d0Richard Osborne}
118