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