1*5f613dfdSUlrich Weigand //===-- SystemZMCInstLower.cpp - Lower MachineInstr to MCInst -------------===// 2*5f613dfdSUlrich Weigand // 3*5f613dfdSUlrich Weigand // The LLVM Compiler Infrastructure 4*5f613dfdSUlrich Weigand // 5*5f613dfdSUlrich Weigand // This file is distributed under the University of Illinois Open Source 6*5f613dfdSUlrich Weigand // License. See LICENSE.TXT for details. 7*5f613dfdSUlrich Weigand // 8*5f613dfdSUlrich Weigand //===----------------------------------------------------------------------===// 9*5f613dfdSUlrich Weigand 10*5f613dfdSUlrich Weigand #include "SystemZMCInstLower.h" 11*5f613dfdSUlrich Weigand #include "SystemZAsmPrinter.h" 12*5f613dfdSUlrich Weigand #include "llvm/MC/MCExpr.h" 13*5f613dfdSUlrich Weigand #include "llvm/MC/MCStreamer.h" 14*5f613dfdSUlrich Weigand #include "llvm/Target/Mangler.h" 15*5f613dfdSUlrich Weigand 16*5f613dfdSUlrich Weigand using namespace llvm; 17*5f613dfdSUlrich Weigand 18*5f613dfdSUlrich Weigand // Where relaxable pairs of reloc-generating instructions exist, 19*5f613dfdSUlrich Weigand // we tend to use the longest form by default, since that produces 20*5f613dfdSUlrich Weigand // correct assembly in cases where no relaxation is performed. 21*5f613dfdSUlrich Weigand // If Opcode is one such instruction, return the opcode for the 22*5f613dfdSUlrich Weigand // shortest possible form instead, otherwise return Opcode itself. 23*5f613dfdSUlrich Weigand static unsigned getShortenedInstr(unsigned Opcode) { 24*5f613dfdSUlrich Weigand switch (Opcode) { 25*5f613dfdSUlrich Weigand case SystemZ::BRCL: return SystemZ::BRC; 26*5f613dfdSUlrich Weigand case SystemZ::JG: return SystemZ::J; 27*5f613dfdSUlrich Weigand case SystemZ::BRASL: return SystemZ::BRAS; 28*5f613dfdSUlrich Weigand } 29*5f613dfdSUlrich Weigand return Opcode; 30*5f613dfdSUlrich Weigand } 31*5f613dfdSUlrich Weigand 32*5f613dfdSUlrich Weigand // Return the VK_* enumeration for MachineOperand target flags Flags. 33*5f613dfdSUlrich Weigand static MCSymbolRefExpr::VariantKind getVariantKind(unsigned Flags) { 34*5f613dfdSUlrich Weigand switch (Flags & SystemZII::MO_SYMBOL_MODIFIER) { 35*5f613dfdSUlrich Weigand case 0: 36*5f613dfdSUlrich Weigand return MCSymbolRefExpr::VK_None; 37*5f613dfdSUlrich Weigand case SystemZII::MO_GOT: 38*5f613dfdSUlrich Weigand return MCSymbolRefExpr::VK_GOT; 39*5f613dfdSUlrich Weigand } 40*5f613dfdSUlrich Weigand llvm_unreachable("Unrecognised MO_ACCESS_MODEL"); 41*5f613dfdSUlrich Weigand } 42*5f613dfdSUlrich Weigand 43*5f613dfdSUlrich Weigand SystemZMCInstLower::SystemZMCInstLower(Mangler *mang, MCContext &ctx, 44*5f613dfdSUlrich Weigand SystemZAsmPrinter &asmprinter) 45*5f613dfdSUlrich Weigand : Mang(mang), Ctx(ctx), AsmPrinter(asmprinter) {} 46*5f613dfdSUlrich Weigand 47*5f613dfdSUlrich Weigand MCOperand SystemZMCInstLower::lowerSymbolOperand(const MachineOperand &MO, 48*5f613dfdSUlrich Weigand const MCSymbol *Symbol, 49*5f613dfdSUlrich Weigand int64_t Offset) const { 50*5f613dfdSUlrich Weigand MCSymbolRefExpr::VariantKind Kind = getVariantKind(MO.getTargetFlags()); 51*5f613dfdSUlrich Weigand const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, Kind, Ctx); 52*5f613dfdSUlrich Weigand if (Offset) { 53*5f613dfdSUlrich Weigand const MCExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx); 54*5f613dfdSUlrich Weigand Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx); 55*5f613dfdSUlrich Weigand } 56*5f613dfdSUlrich Weigand return MCOperand::CreateExpr(Expr); 57*5f613dfdSUlrich Weigand } 58*5f613dfdSUlrich Weigand 59*5f613dfdSUlrich Weigand MCOperand SystemZMCInstLower::lowerOperand(const MachineOperand &MO) const { 60*5f613dfdSUlrich Weigand switch (MO.getType()) { 61*5f613dfdSUlrich Weigand default: 62*5f613dfdSUlrich Weigand llvm_unreachable("unknown operand type"); 63*5f613dfdSUlrich Weigand 64*5f613dfdSUlrich Weigand case MachineOperand::MO_Register: 65*5f613dfdSUlrich Weigand // Ignore all implicit register operands. 66*5f613dfdSUlrich Weigand if (MO.isImplicit()) 67*5f613dfdSUlrich Weigand return MCOperand(); 68*5f613dfdSUlrich Weigand return MCOperand::CreateReg(MO.getReg()); 69*5f613dfdSUlrich Weigand 70*5f613dfdSUlrich Weigand case MachineOperand::MO_Immediate: 71*5f613dfdSUlrich Weigand return MCOperand::CreateImm(MO.getImm()); 72*5f613dfdSUlrich Weigand 73*5f613dfdSUlrich Weigand case MachineOperand::MO_MachineBasicBlock: 74*5f613dfdSUlrich Weigand return lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), 75*5f613dfdSUlrich Weigand /* MO has no offset field */0); 76*5f613dfdSUlrich Weigand 77*5f613dfdSUlrich Weigand case MachineOperand::MO_GlobalAddress: 78*5f613dfdSUlrich Weigand return lowerSymbolOperand(MO, Mang->getSymbol(MO.getGlobal()), 79*5f613dfdSUlrich Weigand MO.getOffset()); 80*5f613dfdSUlrich Weigand 81*5f613dfdSUlrich Weigand case MachineOperand::MO_ExternalSymbol: { 82*5f613dfdSUlrich Weigand StringRef Name = MO.getSymbolName(); 83*5f613dfdSUlrich Weigand return lowerSymbolOperand(MO, AsmPrinter.GetExternalSymbolSymbol(Name), 84*5f613dfdSUlrich Weigand MO.getOffset()); 85*5f613dfdSUlrich Weigand } 86*5f613dfdSUlrich Weigand 87*5f613dfdSUlrich Weigand case MachineOperand::MO_JumpTableIndex: 88*5f613dfdSUlrich Weigand return lowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()), 89*5f613dfdSUlrich Weigand /* MO has no offset field */0); 90*5f613dfdSUlrich Weigand 91*5f613dfdSUlrich Weigand case MachineOperand::MO_ConstantPoolIndex: 92*5f613dfdSUlrich Weigand return lowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()), 93*5f613dfdSUlrich Weigand MO.getOffset()); 94*5f613dfdSUlrich Weigand 95*5f613dfdSUlrich Weigand case MachineOperand::MO_BlockAddress: { 96*5f613dfdSUlrich Weigand const BlockAddress *BA = MO.getBlockAddress(); 97*5f613dfdSUlrich Weigand return lowerSymbolOperand(MO, AsmPrinter.GetBlockAddressSymbol(BA), 98*5f613dfdSUlrich Weigand MO.getOffset()); 99*5f613dfdSUlrich Weigand } 100*5f613dfdSUlrich Weigand } 101*5f613dfdSUlrich Weigand } 102*5f613dfdSUlrich Weigand 103*5f613dfdSUlrich Weigand void SystemZMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const { 104*5f613dfdSUlrich Weigand unsigned Opcode = MI->getOpcode(); 105*5f613dfdSUlrich Weigand // When emitting binary code, start with the shortest form of an instruction 106*5f613dfdSUlrich Weigand // and then relax it where necessary. 107*5f613dfdSUlrich Weigand if (!AsmPrinter.OutStreamer.hasRawTextSupport()) 108*5f613dfdSUlrich Weigand Opcode = getShortenedInstr(Opcode); 109*5f613dfdSUlrich Weigand OutMI.setOpcode(Opcode); 110*5f613dfdSUlrich Weigand for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 111*5f613dfdSUlrich Weigand const MachineOperand &MO = MI->getOperand(I); 112*5f613dfdSUlrich Weigand MCOperand MCOp = lowerOperand(MO); 113*5f613dfdSUlrich Weigand if (MCOp.isValid()) 114*5f613dfdSUlrich Weigand OutMI.addOperand(MCOp); 115*5f613dfdSUlrich Weigand } 116*5f613dfdSUlrich Weigand } 117