1a18f08318afddc7352609c1765c39734c3e3c779Wesley Peck//===-- MBlazeMCInstLower.cpp - Convert MBlaze MachineInstr to an MCInst---===//
24e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck//
34e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck//                     The LLVM Compiler Infrastructure
44e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck//
54e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck// This file is distributed under the University of Illinois Open Source
64e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck// License. See LICENSE.TXT for details.
74e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck//
84e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck//===----------------------------------------------------------------------===//
94e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck//
104e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck// This file contains code to lower MBlaze MachineInstrs to their corresponding
114e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck// MCInst records.
124e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck//
134e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck//===----------------------------------------------------------------------===//
144e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
154e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "MBlazeMCInstLower.h"
164e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "MBlazeInstrInfo.h"
174e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/Constants.h"
184e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/CodeGen/AsmPrinter.h"
194e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/CodeGen/MachineBasicBlock.h"
204e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/CodeGen/MachineInstr.h"
214e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/MC/MCAsmInfo.h"
224e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/MC/MCContext.h"
234e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/MC/MCExpr.h"
244e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/MC/MCInst.h"
254e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/Target/Mangler.h"
264e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/Support/Debug.h"
274e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/Support/raw_ostream.h"
284e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/Support/ErrorHandling.h"
294e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck#include "llvm/ADT/SmallString.h"
304e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peckusing namespace llvm;
314e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
324e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckMCSymbol *MBlazeMCInstLower::
334e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckGetGlobalAddressSymbol(const MachineOperand &MO) const {
344e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  switch (MO.getTargetFlags()) {
3582dc040d0690059beb060ba6640907fb2a295958Wesley Peck  default: llvm_unreachable("Unknown target flag on GV operand");
3682dc040d0690059beb060ba6640907fb2a295958Wesley Peck  case 0:  break;
374e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  }
384e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
394e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  return Printer.Mang->getSymbol(MO.getGlobal());
404e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck}
414e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
424e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckMCSymbol *MBlazeMCInstLower::
434e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckGetExternalSymbolSymbol(const MachineOperand &MO) const {
444e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  switch (MO.getTargetFlags()) {
4582dc040d0690059beb060ba6640907fb2a295958Wesley Peck  default: llvm_unreachable("Unknown target flag on GV operand");
4682dc040d0690059beb060ba6640907fb2a295958Wesley Peck  case 0:  break;
474e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  }
484e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
494e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
504e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck}
514e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
524e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckMCSymbol *MBlazeMCInstLower::
534e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckGetJumpTableSymbol(const MachineOperand &MO) const {
544e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  SmallString<256> Name;
554e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI"
564e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck                            << Printer.getFunctionNumber() << '_'
574e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck                            << MO.getIndex();
584e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  switch (MO.getTargetFlags()) {
5982dc040d0690059beb060ba6640907fb2a295958Wesley Peck  default: llvm_unreachable("Unknown target flag on GV operand");
6082dc040d0690059beb060ba6640907fb2a295958Wesley Peck  case 0:  break;
614e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  }
624e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
634e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  // Create a symbol for the name.
644e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  return Ctx.GetOrCreateSymbol(Name.str());
654e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck}
664e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
674e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckMCSymbol *MBlazeMCInstLower::
684e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckGetConstantPoolIndexSymbol(const MachineOperand &MO) const {
694e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  SmallString<256> Name;
704e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI"
714e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck                            << Printer.getFunctionNumber() << '_'
724e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck                            << MO.getIndex();
734e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
744e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  switch (MO.getTargetFlags()) {
754e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  default:
764e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      llvm_unreachable("Unknown target flag on GV operand");
774e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
784e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  case 0: break;
794e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  }
804e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
814e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  // Create a symbol for the name.
824e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  return Ctx.GetOrCreateSymbol(Name.str());
834e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck}
844e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
854e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckMCSymbol *MBlazeMCInstLower::
864e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckGetBlockAddressSymbol(const MachineOperand &MO) const {
874e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  switch (MO.getTargetFlags()) {
88bc2198133a1836598b54b943420748e75d5dea94Craig Topper  default: llvm_unreachable("Unknown target flag on GV operand");
894e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  case 0: break;
904e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  }
914e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
924e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  return Printer.GetBlockAddressSymbol(MO.getBlockAddress());
934e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck}
944e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
954e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckMCOperand MBlazeMCInstLower::
964e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley PeckLowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const {
974e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  // FIXME: We would like an efficient form for this, so we don't have to do a
984e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  // lot of extra uniquing.
994e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx);
1004e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
1014e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  switch (MO.getTargetFlags()) {
1024e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  default:
1034e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      llvm_unreachable("Unknown target flag on GV operand");
1044e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
1054e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  case 0: break;
1064e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  }
1074e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
1084e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  if (!MO.isJTI() && MO.getOffset())
1094e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    Expr = MCBinaryExpr::CreateAdd(Expr,
1104e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck                                   MCConstantExpr::Create(MO.getOffset(), Ctx),
1114e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck                                   Ctx);
1124e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  return MCOperand::CreateExpr(Expr);
1134e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck}
1144e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
1154e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peckvoid MBlazeMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
1164e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  OutMI.setOpcode(MI->getOpcode());
1174e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
1184e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
1194e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    const MachineOperand &MO = MI->getOperand(i);
1204e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
1214e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    MCOperand MCOp;
1224e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    switch (MO.getType()) {
12382dc040d0690059beb060ba6640907fb2a295958Wesley Peck    default: llvm_unreachable("unknown operand type");
1244e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    case MachineOperand::MO_Register:
1254e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      // Ignore all implicit register operands.
1264e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      if (MO.isImplicit()) continue;
1274e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = MCOperand::CreateReg(MO.getReg());
1284e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
1294e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    case MachineOperand::MO_Immediate:
1304e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = MCOperand::CreateImm(MO.getImm());
1314e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
1324e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    case MachineOperand::MO_MachineBasicBlock:
1334e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create(
1344e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck                         MO.getMBB()->getSymbol(), Ctx));
1354e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
1364e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    case MachineOperand::MO_GlobalAddress:
1374e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
1384e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
1394e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    case MachineOperand::MO_ExternalSymbol:
1404e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
1414e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
1424e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    case MachineOperand::MO_JumpTableIndex:
1434e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO));
1444e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
1454e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    case MachineOperand::MO_ConstantPoolIndex:
1464e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
1474e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
1484e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    case MachineOperand::MO_BlockAddress:
1494e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
1504e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
15171f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen    case MachineOperand::MO_FPImmediate: {
1524e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      bool ignored;
1534e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      APFloat FVal = MO.getFPImm()->getValueAPF();
1544e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      FVal.convert(APFloat::IEEEsingle, APFloat::rmTowardZero, &ignored);
1554e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
1564e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      APInt IVal = FVal.bitcastToAPInt();
1574e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      uint64_t Val = *IVal.getRawData();
1584e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      MCOp = MCOperand::CreateImm(Val);
1594e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck      break;
1604e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    }
16171f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen    case MachineOperand::MO_RegisterMask:
16271f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen      continue;
16371f0fc1ca88965b69b4b2c8794a7144bc93d4bbaJakob Stoklund Olesen    }
1644e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck
1654e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck    OutMI.addOperand(MCOp);
1664e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck  }
1674e9141fd4c0040cd7d4d830211f7d27fd98e9338Wesley Peck}
168