1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsAsmPrinter.cpp - Mips LLVM Assembly Printer -------------------===// 2972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// 3972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// The LLVM Compiler Infrastructure 4972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// 84552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 9972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// 10972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// This file contains a printer that converts from our internal representation 11972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// of machine-dependent LLVM code to GAS-format MIPS assembly language. 12972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes// 134552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 14972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 15794bf17cbe0bac301ef9e52fb4a0295bfdfe0cabAkira Hatanaka#include "InstPrinter/MipsInstPrinter.h" 1647b92f3d8362518596d57269dc53d985bc13323aBruno Cardoso Lopes#include "MCTargetDesc/MipsBaseInfo.h" 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/MipsMCNaCl.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "Mips.h" 19c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter#include "MipsAsmPrinter.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MipsInstrInfo.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MipsMCInstLower.h" 22320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola#include "MipsTargetStreamer.h" 23ce1a538ab5b7ae7e0ed48d18c02571280fe105aaBruno Cardoso Lopes#include "llvm/ADT/SmallString.h" 24ce1a538ab5b7ae7e0ed48d18c02571280fe105aaBruno Cardoso Lopes#include "llvm/ADT/StringExtras.h" 25ce1a538ab5b7ae7e0ed48d18c02571280fe105aaBruno Cardoso Lopes#include "llvm/ADT/Twine.h" 26972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/MachineConstantPool.h" 27a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes#include "llvm/CodeGen/MachineFrameInfo.h" 28244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter#include "llvm/CodeGen/MachineFunctionPass.h" 29972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes#include "llvm/CodeGen/MachineInstr.h" 3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineJumpTableInfo.h" 315c21c9e78ebbb5b766fac31bf30433926dcc2a5dAkira Hatanaka#include "llvm/CodeGen/MachineMemOperand.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/BasicBlock.h" 330b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 340b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/InlineAsm.h" 350b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Mangler.h" 37af76e592c7f9deff0e55c13dbb4a34f07f1c7f64Chris Lattner#include "llvm/MC/MCAsmInfo.h" 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCContext.h" 395e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola#include "llvm/MC/MCELFStreamer.h" 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCExpr.h" 41794bf17cbe0bac301ef9e52fb4a0295bfdfe0cabAkira Hatanaka#include "llvm/MC/MCInst.h" 4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSection.h" 4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCSectionELF.h" 44325d3dcfe4d5efc91db0f59b20a72a11dea024edChris Lattner#include "llvm/MC/MCSymbol.h" 45ccb3c9c2702f548fd0a7d60a622e6f4fdf0940e7Jack Carter#include "llvm/Support/ELF.h" 46244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter#include "llvm/Support/TargetRegistry.h" 47d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/raw_ostream.h" 4881092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes#include "llvm/Target/TargetLoweringObjectFile.h" 49753a98740bfe3164fd0961a1959306c46135cf19Bruno Cardoso Lopes#include "llvm/Target/TargetOptions.h" 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <string> 51c4f24eb584f6b4dba3caba2ed766c7c4bf1bf8afAkira Hatanaka 52972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopesusing namespace llvm; 53972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mips-asm-printer" 55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 56320296a4cfe414ce59f406b8a5ce15272f563103Rafael EspindolaMipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() { 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return static_cast<MipsTargetStreamer &>(*OutStreamer.getTargetStreamer()); 58320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola} 59320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola 60f93b86306683f8e860c8824efb717995cb072a70Akira Hatanakabool MipsAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 61a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler // Initialize TargetLoweringObjectFile. 62a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler if (Subtarget->allowMixed16_32()) 63a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) 64a430cb613b6e93c05f128b04323c57acfd08686dReed Kotler .Initialize(OutContext, TM); 65f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka MipsFI = MF.getInfo<MipsFunctionInfo>(); 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->inMips16Mode()) 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (std::map< 6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *, 6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines it = MipsFI->StubsNeeded.begin(); 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines it != MipsFI->StubsNeeded.end(); ++it) { 7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *Symbol = it->first; 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second; 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (StubsNeeded.find(Symbol) == StubsNeeded.end()) 7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StubsNeeded[Symbol] = Signature; 7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 77cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler MCP = MF.getConstantPool(); 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // In NaCl, all indirect jump targets must be aligned to bundle size. 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->isTargetNaCl()) 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NaClAlignIndirectJumpTargets(MF); 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 83f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka AsmPrinter::runOnMachineFunction(MF); 84f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka return true; 85ce1a538ab5b7ae7e0ed48d18c02571280fe105aaBruno Cardoso Lopes} 86ce1a538ab5b7ae7e0ed48d18c02571280fe105aaBruno Cardoso Lopes 87cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanakabool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { 88cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka MCOp = MCInstLowering.LowerOperand(MO); 89cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka return MCOp.isValid(); 90cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka} 91cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka 92cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka#include "MipsGenMCPseudoLowering.inc" 93cc46fe591af10c193c17323547a3dd7cc00c925dAkira Hatanaka 94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM, 95cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines// JALR, or JALR64 as appropriate for the target 96cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer, 97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MachineInstr *MI) { 98cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool HasLinkReg = false; 99cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCInst TmpInst0; 100cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Subtarget->hasMips64r6()) { 102cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // MIPS64r6 should use (JALR64 ZERO_64, $rs) 103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpInst0.setOpcode(Mips::JALR64); 104cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines HasLinkReg = true; 105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (Subtarget->hasMips32r6()) { 106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // MIPS32r6 should use (JALR ZERO, $rs) 107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpInst0.setOpcode(Mips::JALR); 108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines HasLinkReg = true; 109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } else if (Subtarget->inMicroMipsMode()) 110cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // microMIPS should use (JR_MM $rs) 111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpInst0.setOpcode(Mips::JR_MM); 112cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines else { 113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // Everything else should use (JR $rs) 114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpInst0.setOpcode(Mips::JR); 115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCOperand MCOp; 118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (HasLinkReg) { 120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines unsigned ZeroReg = Subtarget->isGP64bit() ? Mips::ZERO_64 : Mips::ZERO; 121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpInst0.addOperand(MCOperand::CreateReg(ZeroReg)); 122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines lowerOperand(MI->getOperand(0), MCOp); 125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TmpInst0.addOperand(MCOp); 126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines EmitToStreamer(OutStreamer, TmpInst0); 128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 130aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanakavoid MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) { 131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MipsTargetStreamer &TS = getTargetStreamer(); 132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines TS.setCanHaveModuleDir(false); 133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 134aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka if (MI->isDebugValue()) { 135ce8524c0160787fc727c16816979302df42b914aBruno Cardoso Lopes SmallString<128> Str; 136ce8524c0160787fc727c16816979302df42b914aBruno Cardoso Lopes raw_svector_ostream OS(Str); 137ce8524c0160787fc727c16816979302df42b914aBruno Cardoso Lopes 138aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka PrintDebugValueComment(MI, OS); 139aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka return; 140aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka } 141972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 142cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // If we just ended a constant pool, mark it as such. 143cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler if (InConstantPool && MI->getOpcode() != Mips::CONSTPOOL_ENTRY) { 144cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 145cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler InConstantPool = false; 146cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler } 147cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler if (MI->getOpcode() == Mips::CONSTPOOL_ENTRY) { 148cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // CONSTPOOL_ENTRY - This instruction represents a floating 149cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler //constant pool in the function. The first operand is the ID# 150cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // for this instruction, the second is the index into the 151cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // MachineConstantPool that this is, the third is the size in 152cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // bytes of this constant pool entry. 153cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // The required alignment is specified on the basic block holding this MI. 154cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // 155cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler unsigned LabelId = (unsigned)MI->getOperand(0).getImm(); 156cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex(); 157cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler 158cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // If this is the first entry of the pool, mark it. 159cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler if (!InConstantPool) { 160cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler OutStreamer.EmitDataRegion(MCDR_DataRegion); 161cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler InConstantPool = true; 162cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler } 163cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler 164cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler OutStreamer.EmitLabel(GetCPISymbol(LabelId)); 165cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler 166cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx]; 167cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler if (MCPE.isMachineConstantPoolEntry()) 168cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); 169cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler else 170cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler EmitGlobalConstant(MCPE.Val.ConstVal); 171cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler return; 172cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler } 173cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler 174cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler 175158413930f25ecdd0902e1cc11bb8dc3683b94f8Akira Hatanaka MachineBasicBlock::const_instr_iterator I = MI; 176158413930f25ecdd0902e1cc11bb8dc3683b94f8Akira Hatanaka MachineBasicBlock::const_instr_iterator E = MI->getParent()->instr_end(); 177158413930f25ecdd0902e1cc11bb8dc3683b94f8Akira Hatanaka 178158413930f25ecdd0902e1cc11bb8dc3683b94f8Akira Hatanaka do { 1796c59c9f57c8428e477ed592ee3537323d287d96fAkira Hatanaka // Do any auto-generated pseudo lowerings. 1806c59c9f57c8428e477ed592ee3537323d287d96fAkira Hatanaka if (emitPseudoExpansionLowering(OutStreamer, &*I)) 1816c59c9f57c8428e477ed592ee3537323d287d96fAkira Hatanaka continue; 18269dba7e20476ec0e64791e47b498ae3a69619f7dJack Carter 183cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (I->getOpcode() == Mips::PseudoReturn || 184cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines I->getOpcode() == Mips::PseudoReturn64 || 185cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines I->getOpcode() == Mips::PseudoIndirectBranch || 186cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines I->getOpcode() == Mips::PseudoIndirectBranch64) { 187cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines emitPseudoIndirectBranch(OutStreamer, &*I); 188cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines continue; 189cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 190cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 19179cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler // The inMips16Mode() test is not permanent. 19279cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler // Some instructions are marked as pseudo right now which 19379cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler // would make the test fail for the wrong reason but 19479cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler // that will be fixed soon. We need this here because we are 19579cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler // removing another test for this situation downstream in the 19679cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler // callchain. 19779cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler // 198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (I->isPseudo() && !Subtarget->inMips16Mode() 199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines && !isLongBranchPseudo(I->getOpcode())) 20079cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler llvm_unreachable("Pseudo opcode found in EmitInstruction()"); 20179cd4118090a3c0bc80cafc699a51abf1d6299f3Reed Kotler 2026c59c9f57c8428e477ed592ee3537323d287d96fAkira Hatanaka MCInst TmpInst0; 2036c59c9f57c8428e477ed592ee3537323d287d96fAkira Hatanaka MCInstLowering.Lower(I, TmpInst0); 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitToStreamer(OutStreamer, TmpInst0); 2056c59c9f57c8428e477ed592ee3537323d287d96fAkira Hatanaka } while ((++I != E) && I->isInsideBundle()); // Delay slot check 206aa08ea0530a2baa7d1d74c492b1bd5af3518ad60Akira Hatanaka} 207972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 2084552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 209dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// 210dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// Mips Asm Directives 211dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// 212dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// -- Frame directive "frame Stackpointer, Stacksize, RARegister" 213dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// Describe the stack frame. 214dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// 21581092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// -- Mask directives "(f)mask bitmask, offset" 216dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// Tells the assembler which registers are saved and where. 21781092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// bitmask - contain a little endian bitset indicating which registers are 21881092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// saved on function prologue (e.g. with a 0x80000000 mask, the 219dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// assembler knows the register 31 (RA) is saved at prologue. 22081092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// offset - the position before stack pointer subtraction indicating where 221dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// the first saved register on prologue is located. (e.g. with a 222dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// 223dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// Consider the following function prologue: 224dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// 2256ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling// .frame $fp,48,$ra 2266ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling// .mask 0xc0000000,-8 2276ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling// addiu $sp, $sp, -48 2286ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling// sw $ra, 40($sp) 2296ef781f3ce0d0311004adba9d1e7dbd7950918ddBill Wendling// sw $fp, 36($sp) 230dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// 23181092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// With a 0xc0000000 mask, the assembler knows the register 31 (RA) and 23281092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// 30 (FP) are saved at prologue. As the save order on prologue is from 23381092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// left to right, RA is saved first. A -8 offset means that after the 234dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// stack pointer subtration, the first register in the mask (RA) will be 235dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// saved at address 48-8=40. 236dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes// 2374552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 238a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes 2394552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 24043d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes// Mask directives 2414552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 24243d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes 24381092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes// Create a bitmask with all callee saved registers for CPU or Floating Point 244bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes// registers. For CPU registers consider RA, GP and FP for saving if necessary. 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::printSavedRegsBitmask() { 246bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes // CPU and FPU Saved Registers Bitmasks 247f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka unsigned CPUBitmask = 0, FPUBitmask = 0; 248f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka int CPUTopSavedRegOff, FPUTopSavedRegOff; 249dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes 250bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes // Set the CPU and FPU Bitmasks 251a34103f6fa6f21025518596efc73631eb899410bChris Lattner const MachineFrameInfo *MFI = MF->getFrameInfo(); 252dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 253f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka // size of stack area to which FP callee-saved regs are saved. 2541858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka unsigned CPURegSize = Mips::GPR32RegClass.getSize(); 255420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned FGR32RegSize = Mips::FGR32RegClass.getSize(); 256420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned AFGR64RegSize = Mips::AFGR64RegClass.getSize(); 257f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka bool HasAFGR64Reg = false; 258f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka unsigned CSFPRegsSize = 0; 259f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka unsigned i, e = CSI.size(); 260f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka 261f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka // Set FPU Bitmask. 262f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka for (i = 0; i != e; ++i) { 26342d075c4fb21995265961501cec9ff6e3fb497ceRafael Espindola unsigned Reg = CSI[i].getReg(); 2641858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka if (Mips::GPR32RegClass.contains(Reg)) 265f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka break; 266f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka 267e8068692f924a1577075bd2d7b72b44820e0ffb2Akira Hatanaka unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg); 268420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper if (Mips::AFGR64RegClass.contains(Reg)) { 269f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka FPUBitmask |= (3 << RegNum); 270f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka CSFPRegsSize += AFGR64RegSize; 271f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka HasAFGR64Reg = true; 272f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka continue; 273f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka } 274f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka 275f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka FPUBitmask |= (1 << RegNum); 276f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka CSFPRegsSize += FGR32RegSize; 277f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka } 278f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka 279f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka // Set CPU Bitmask. 280f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka for (; i != e; ++i) { 281f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka unsigned Reg = CSI[i].getReg(); 282e8068692f924a1577075bd2d7b72b44820e0ffb2Akira Hatanaka unsigned RegNum = TM.getRegisterInfo()->getEncodingValue(Reg); 283f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka CPUBitmask |= (1 << RegNum); 284bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes } 285dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes 286f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka // FP Regs are saved right below where the virtual frame pointer points to. 287f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka FPUTopSavedRegOff = FPUBitmask ? 288f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka (HasAFGR64Reg ? -AFGR64RegSize : -FGR32RegSize) : 0; 289d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 290f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka // CPU Regs are saved below FP Regs. 291f8928c07e7ab43847770421393da6ad3922e5c8aAkira Hatanaka CPUTopSavedRegOff = CPUBitmask ? -CSFPRegsSize - CPURegSize : 0; 292dc0c04c0ed8a8792e6e5a838f4d5b8c8a0d1988dBruno Cardoso Lopes 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsTargetStreamer &TS = getTargetStreamer(); 294bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes // Print CPUBitmask 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitMask(CPUBitmask, CPUTopSavedRegOff); 296bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes 297bbe51362d53a532942997903a49faa7b5b50ad1fBruno Cardoso Lopes // Print FPUBitmask 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitFMask(FPUBitmask, FPUTopSavedRegOff); 299a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes} 300a4e8200366805c665bb1424d8af5550f5d3d6863Bruno Cardoso Lopes 3014552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 30243d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes// Frame and Set directives 3034552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka//===----------------------------------------------------------------------===// 30443d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes 30543d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes/// Frame Directive 3069d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattnervoid MipsAsmPrinter::emitFrameDirective() { 30743d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes const TargetRegisterInfo &RI = *TM.getRegisterInfo(); 30843d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes 309a34103f6fa6f21025518596efc73631eb899410bChris Lattner unsigned stackReg = RI.getFrameRegister(*MF); 31043d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes unsigned returnReg = RI.getRARegister(); 311a34103f6fa6f21025518596efc73631eb899410bChris Lattner unsigned stackSize = MF->getFrameInfo()->getStackSize(); 31243d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes 31336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getTargetStreamer().emitFrame(stackReg, stackSize, returnReg); 31443d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes} 31543d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes 31643d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes/// Emit Set directives. 31781092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopesconst char *MipsAsmPrinter::getCurrentABIString() const { 3189d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner switch (Subtarget->getTargetABI()) { 31981092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes case MipsSubtarget::O32: return "abi32"; 3209d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner case MipsSubtarget::N32: return "abiN32"; 3219d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner case MipsSubtarget::N64: return "abi64"; 3229d7efd3081ef13b4d1ac7e0ad4854e92e5f132adChris Lattner case MipsSubtarget::EABI: return "eabi32"; // TODO: handle eabi64 3232de0572caec55e3779857cae0bbcd962af2e495dDmitri Gribenko default: llvm_unreachable("Unknown Mips ABI"); 32443d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes } 32581092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes} 32643d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes 3275006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattnervoid MipsAsmPrinter::EmitFunctionEntryLabel() { 32836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsTargetStreamer &TS = getTargetStreamer(); 32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // NaCl sandboxing requires that indirect call instructions are masked. 33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // This means that function entry points should be bundle-aligned. 33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->isTargetNaCl()) 33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitAlignment(std::max(MF->getAlignment(), MIPS_NACL_BUNDLE_ALIGN)); 334ccb3c9c2702f548fd0a7d60a622e6f4fdf0940e7Jack Carter 335ccb3c9c2702f548fd0a7d60a622e6f4fdf0940e7Jack Carter if (Subtarget->inMicroMipsMode()) 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetMicroMips(); 337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else 338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines TS.emitDirectiveSetNoMicroMips(); 33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->inMips16Mode()) 34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetMips16(); 34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetNoMips16(); 34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveEnt(*CurrentFnSym); 3465006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattner OutStreamer.EmitLabel(CurrentFnSym); 3475006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattner} 3485006071f7a75b81ea9b4cb18d8352e612bb787ecChris Lattner 349a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// EmitFunctionBodyStart - Targets can override this to emit stuff before 350a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// the first basic block in the function. 351a34103f6fa6f21025518596efc73631eb899410bChris Lattnervoid MipsAsmPrinter::EmitFunctionBodyStart() { 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsTargetStreamer &TS = getTargetStreamer(); 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 354a300b1cc29020b7dfaf7bfe443d38af8fbec7433Rafael Espindola MCInstLowering.Initialize(&MF->getContext()); 355f93b86306683f8e860c8824efb717995cb072a70Akira Hatanaka 3562bb955a6931580c9bb0472aa29b3fbbabe263295Reed Kotler bool IsNakedFunction = 3572bb955a6931580c9bb0472aa29b3fbbabe263295Reed Kotler MF->getFunction()-> 3582bb955a6931580c9bb0472aa29b3fbbabe263295Reed Kotler getAttributes().hasAttribute(AttributeSet::FunctionIndex, 3592bb955a6931580c9bb0472aa29b3fbbabe263295Reed Kotler Attribute::Naked); 3602bb955a6931580c9bb0472aa29b3fbbabe263295Reed Kotler if (!IsNakedFunction) 3612bb955a6931580c9bb0472aa29b3fbbabe263295Reed Kotler emitFrameDirective(); 36281092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!IsNakedFunction) 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines printSavedRegsBitmask(); 36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Subtarget->inMips16Mode()) { 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetNoReorder(); 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetNoMacro(); 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetNoAt(); 3704147e4d054b62eb2ea8259db0385791ec23c460bAkira Hatanaka } 371a34103f6fa6f21025518596efc73631eb899410bChris Lattner} 372972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 373a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// EmitFunctionBodyEnd - Targets can override this to emit stuff after 374a34103f6fa6f21025518596efc73631eb899410bChris Lattner/// the last basic block in the function. 375a34103f6fa6f21025518596efc73631eb899410bChris Lattnervoid MipsAsmPrinter::EmitFunctionBodyEnd() { 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsTargetStreamer &TS = getTargetStreamer(); 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 378745ec06ad2fa533e9ef47ce572c3a03547376224Chris Lattner // There are instruction for this macros, but they must 379745ec06ad2fa533e9ef47ce572c3a03547376224Chris Lattner // always be at the function end, and we can't emit and 38081092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes // break with BB logic. 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!Subtarget->inMips16Mode()) { 38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetAt(); 38336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetMacro(); 38436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetReorder(); 385ce1a538ab5b7ae7e0ed48d18c02571280fe105aaBruno Cardoso Lopes } 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveEnd(CurrentFnSym->getName()); 387cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // Make sure to terminate any constant pools that were at the end 388cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler // of the function. 389cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler if (!InConstantPool) 390cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler return; 391cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler InConstantPool = false; 392cb2280e4c7c5a07104306cc73265ff64fa8dd973Reed Kotler OutStreamer.EmitDataRegion(MCDR_DataRegionEnd); 393972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes} 394972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 39546773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes/// isBlockOnlyReachableByFallthough - Return true if the basic block has 39646773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes/// exactly one predecessor and the control transfer mechanism between 39746773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes/// the predecessor and this block is a fall-through. 3984552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanakabool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock* 3994552c9a3b34ad9b2085635266348d0d9b95514a6Akira Hatanaka MBB) const { 40046773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes // The predecessor has to be immediately before this block. 40146773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes const MachineBasicBlock *Pred = *MBB->pred_begin(); 40246773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes 40346773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes // If the predecessor is a switch statement, assume a jump table 40446773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes // implementation, so it is not a fall through. 40546773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes if (const BasicBlock *bb = Pred->getBasicBlock()) 40646773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes if (isa<SwitchInst>(bb->getTerminator())) 40746773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes return false; 40881092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes 409a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka // If this is a landing pad, it isn't a fall through. If it has no preds, 410a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka // then nothing falls through to it. 411a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka if (MBB->isLandingPad() || MBB->pred_empty()) 412a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka return false; 413a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka 414a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka // If there isn't exactly one predecessor, it can't be a fall through. 415a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI; 416a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka ++PI2; 417bb481f882093fb738d2bb15610c79364bada5496Jia Liu 418a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka if (PI2 != MBB->pred_end()) 419bb481f882093fb738d2bb15610c79364bada5496Jia Liu return false; 420a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka 421a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka // The predecessor has to be immediately before this block. 422a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka if (!Pred->isLayoutSuccessor(MBB)) 423a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka return false; 424bb481f882093fb738d2bb15610c79364bada5496Jia Liu 425a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka // If the block is completely empty, then it definitely does fall through. 426a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka if (Pred->empty()) 427a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka return true; 428bb481f882093fb738d2bb15610c79364bada5496Jia Liu 429a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka // Otherwise, check the last instruction. 430a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka // Check if the last terminator is an unconditional branch. 431a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka MachineBasicBlock::const_iterator I = Pred->end(); 4325a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng while (I != Pred->begin() && !(--I)->isTerminator()) ; 433a4485c49641a492688276a061ddd0cb38d38e270Akira Hatanaka 4345a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng return !I->isBarrier(); 43546773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes} 43646773793cbf18fa0fa4643c91d3b6f5c5bf15dd9Bruno Cardoso Lopes 43791ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes// Print out an operand for an inline asm expression. 43805b7a50210c1ebdd88fd7799c3d32b8fe1a0ce29Eric Christopherbool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, 439c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner unsigned AsmVariant,const char *ExtraCode, 440c75c028a15a13786eee585aa634b4faf694dd00aChris Lattner raw_ostream &O) { 44191ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes // Does this asm operand have a single letter operand modifier? 44205b7a50210c1ebdd88fd7799c3d32b8fe1a0ce29Eric Christopher if (ExtraCode && ExtraCode[0]) { 44305b7a50210c1ebdd88fd7799c3d32b8fe1a0ce29Eric Christopher if (ExtraCode[1] != 0) return true; // Unknown modifier. 44405b7a50210c1ebdd88fd7799c3d32b8fe1a0ce29Eric Christopher 44505b7a50210c1ebdd88fd7799c3d32b8fe1a0ce29Eric Christopher const MachineOperand &MO = MI->getOperand(OpNum); 44605b7a50210c1ebdd88fd7799c3d32b8fe1a0ce29Eric Christopher switch (ExtraCode[0]) { 44775f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher default: 448d5e11ad51a3966c0b80ce2119946cd1aa3558aecJack Carter // See if this is a generic print operand 449d5e11ad51a3966c0b80ce2119946cd1aa3558aecJack Carter return AsmPrinter::PrintAsmOperand(MI,OpNum,AsmVariant,ExtraCode,O); 45075f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher case 'X': // hex const int 45175f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher if ((MO.getType()) != MachineOperand::MO_Immediate) 45275f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher return true; 45375f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher O << "0x" << StringRef(utohexstr(MO.getImm())).lower(); 45475f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher return false; 45575f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher case 'x': // hex const int (low 16 bits) 45675f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher if ((MO.getType()) != MachineOperand::MO_Immediate) 45775f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher return true; 45875f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher O << "0x" << StringRef(utohexstr(MO.getImm() & 0xffff)).lower(); 45975f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher return false; 46075f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher case 'd': // decimal const int 46175f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher if ((MO.getType()) != MachineOperand::MO_Immediate) 46275f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher return true; 46375f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher O << MO.getImm(); 46475f89b54b588521e9e5aac113e3c4f7088bb6106Eric Christopher return false; 4656ab75b4dcbac0a2538177ed34819704f5e5373eeEric Christopher case 'm': // decimal const int minus 1 4666ab75b4dcbac0a2538177ed34819704f5e5373eeEric Christopher if ((MO.getType()) != MachineOperand::MO_Immediate) 4676ab75b4dcbac0a2538177ed34819704f5e5373eeEric Christopher return true; 4686ab75b4dcbac0a2538177ed34819704f5e5373eeEric Christopher O << MO.getImm() - 1; 4696ab75b4dcbac0a2538177ed34819704f5e5373eeEric Christopher return false; 470f38ad8efd0f313a51307f700a2699ae57608ddd4Jack Carter case 'z': { 471f38ad8efd0f313a51307f700a2699ae57608ddd4Jack Carter // $0 if zero, regular printing otherwise 4727c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter if (MO.getType() != MachineOperand::MO_Immediate) 4737c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter return true; 4747c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter int64_t Val = MO.getImm(); 4757c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter if (Val) 4767c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter O << Val; 4777c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter else 4787c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter O << "$0"; 4797c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter return false; 4807c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter } 481bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter case 'D': // Second part of a double word register operand 482bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter case 'L': // Low order register of a double word register operand 483a0f14afee16ca976fef79c64df9a678e7f26cf43Jack Carter case 'M': // High order register of a double word register operand 484bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter { 485244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter if (OpNum == 0) 486244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter return true; 487244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1); 488244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter if (!FlagsOP.isImm()) 489244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter return true; 490244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter unsigned Flags = FlagsOP.getImm(); 491244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter unsigned NumVals = InlineAsm::getNumOperandRegisters(Flags); 492020f07f571fd1ae060becb2ecf8da2b220a9d47dJack Carter // Number of registers represented by this operand. We are looking 493020f07f571fd1ae060becb2ecf8da2b220a9d47dJack Carter // for 2 for 32 bit mode and 1 for 64 bit mode. 494244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter if (NumVals != 2) { 495020f07f571fd1ae060becb2ecf8da2b220a9d47dJack Carter if (Subtarget->isGP64bit() && NumVals == 1 && MO.isReg()) { 496244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter unsigned Reg = MO.getReg(); 497244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter O << '$' << MipsInstPrinter::getRegisterName(Reg); 498244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter return false; 499244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter } 500244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter return true; 501244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter } 5029a1199459d54b7b3cbe444480ae75d286e362d01Jack Carter 5039a1199459d54b7b3cbe444480ae75d286e362d01Jack Carter unsigned RegOp = OpNum; 5049a1199459d54b7b3cbe444480ae75d286e362d01Jack Carter if (!Subtarget->isGP64bit()){ 505bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter // Endianess reverses which register holds the high or low value 506a0f14afee16ca976fef79c64df9a678e7f26cf43Jack Carter // between M and L. 507bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter switch(ExtraCode[0]) { 508a0f14afee16ca976fef79c64df9a678e7f26cf43Jack Carter case 'M': 509a0f14afee16ca976fef79c64df9a678e7f26cf43Jack Carter RegOp = (Subtarget->isLittle()) ? OpNum + 1 : OpNum; 510bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter break; 511bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter case 'L': 512a0f14afee16ca976fef79c64df9a678e7f26cf43Jack Carter RegOp = (Subtarget->isLittle()) ? OpNum : OpNum + 1; 513a0f14afee16ca976fef79c64df9a678e7f26cf43Jack Carter break; 514a0f14afee16ca976fef79c64df9a678e7f26cf43Jack Carter case 'D': // Always the second part 515a0f14afee16ca976fef79c64df9a678e7f26cf43Jack Carter RegOp = OpNum + 1; 516bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter } 517bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter if (RegOp >= MI->getNumOperands()) 518bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter return true; 519bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter const MachineOperand &MO = MI->getOperand(RegOp); 520bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter if (!MO.isReg()) 521bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter return true; 522bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter unsigned Reg = MO.getReg(); 523bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter O << '$' << MipsInstPrinter::getRegisterName(Reg); 524bb78930489aceab797eecffe6771c6e52ff0c80cJack Carter return false; 525244a84ee57cc73509a0e85cc92585cb567d0b72cJack Carter } 52605b7a50210c1ebdd88fd7799c3d32b8fe1a0ce29Eric Christopher } 5279e2838e29b0820afc35f6ef2d465d4aca9ed402aDaniel Sanders case 'w': 5289e2838e29b0820afc35f6ef2d465d4aca9ed402aDaniel Sanders // Print MSA registers for the 'f' constraint 5299e2838e29b0820afc35f6ef2d465d4aca9ed402aDaniel Sanders // In LLVM, the 'w' modifier doesn't need to do anything. 5309e2838e29b0820afc35f6ef2d465d4aca9ed402aDaniel Sanders // We can just call printOperand as normal. 5319e2838e29b0820afc35f6ef2d465d4aca9ed402aDaniel Sanders break; 532020f07f571fd1ae060becb2ecf8da2b220a9d47dJack Carter } 533020f07f571fd1ae060becb2ecf8da2b220a9d47dJack Carter } 53491ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes 53505b7a50210c1ebdd88fd7799c3d32b8fe1a0ce29Eric Christopher printOperand(MI, OpNum, O); 53691ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes return false; 53791ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes} 53891ef849e6cb01a019dc50ed4e95c058e01616062Bruno Cardoso Lopes 53921afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanakabool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, 54021afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanaka unsigned OpNum, unsigned AsmVariant, 54121afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanaka const char *ExtraCode, 54221afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanaka raw_ostream &O) { 543a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter int Offset = 0; 544a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter // Currently we are expecting either no ExtraCode or 'D' 545a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter if (ExtraCode) { 546a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter if (ExtraCode[0] == 'D') 547a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter Offset = 4; 548a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter else 549a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter return true; // Unknown modifier. 550a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter } 551bb481f882093fb738d2bb15610c79364bada5496Jia Liu 55221afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanaka const MachineOperand &MO = MI->getOperand(OpNum); 55321afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanaka assert(MO.isReg() && "unexpected inline asm memory operand"); 554a9a5c537ad0bf5ab68ed79c163500a4fcb3fc3ffJack Carter O << Offset << "($" << MipsInstPrinter::getRegisterName(MO.getReg()) << ")"; 5557c3cd4d24edf125bafc9aa258fc8e8ae1b00a4dfJack Carter 55621afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanaka return false; 55721afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanaka} 55821afc63ea7b8227ccb1b735255be55bf422136d6Akira Hatanaka 55935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid MipsAsmPrinter::printOperand(const MachineInstr *MI, int opNum, 56035c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O) { 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const DataLayout *DL = TM.getDataLayout(); 562972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes const MachineOperand &MO = MI->getOperand(opNum); 563c7db5618f9e5e708b87d9ae6595b3fd510a2a0c0Bruno Cardoso Lopes bool closeP = false; 564c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes 565c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes if (MO.getTargetFlags()) 5660c80be59c7ccbd844b5dee71b038090052cac07bBruno Cardoso Lopes closeP = true; 567c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes 568c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes switch(MO.getTargetFlags()) { 569c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes case MipsII::MO_GPREL: O << "%gp_rel("; break; 570c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes case MipsII::MO_GOT_CALL: O << "%call16("; break; 571e2e436a6bc44deb2f989a39514f482b4932b93bcAkira Hatanaka case MipsII::MO_GOT: O << "%got("; break; 572e2e436a6bc44deb2f989a39514f482b4932b93bcAkira Hatanaka case MipsII::MO_ABS_HI: O << "%hi("; break; 573e2e436a6bc44deb2f989a39514f482b4932b93bcAkira Hatanaka case MipsII::MO_ABS_LO: O << "%lo("; break; 574d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes case MipsII::MO_TLSGD: O << "%tlsgd("; break; 575d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes case MipsII::MO_GOTTPREL: O << "%gottprel("; break; 576d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes case MipsII::MO_TPREL_HI: O << "%tprel_hi("; break; 577d979686bb47f2dcdca60f0a088f59d1964346453Bruno Cardoso Lopes case MipsII::MO_TPREL_LO: O << "%tprel_lo("; break; 578e33ca9ce1f978b8129972922f1ac0c16eec9e5f1Akira Hatanaka case MipsII::MO_GPOFF_HI: O << "%hi(%neg(%gp_rel("; break; 579e33ca9ce1f978b8129972922f1ac0c16eec9e5f1Akira Hatanaka case MipsII::MO_GPOFF_LO: O << "%lo(%neg(%gp_rel("; break; 580e33ca9ce1f978b8129972922f1ac0c16eec9e5f1Akira Hatanaka case MipsII::MO_GOT_DISP: O << "%got_disp("; break; 581e33ca9ce1f978b8129972922f1ac0c16eec9e5f1Akira Hatanaka case MipsII::MO_GOT_PAGE: O << "%got_page("; break; 582e33ca9ce1f978b8129972922f1ac0c16eec9e5f1Akira Hatanaka case MipsII::MO_GOT_OFST: O << "%got_ofst("; break; 583972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes } 584c517cb006553320875544f39655c3299124be3eaBruno Cardoso Lopes 585762ccea600158bb317dcccdff3303e942426cb71Chris Lattner switch (MO.getType()) { 586972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes case MachineOperand::MO_Register: 587794bf17cbe0bac301ef9e52fb4a0295bfdfe0cabAkira Hatanaka O << '$' 588590853667345d6fb191764b9d0bd2ff13589e3a3Benjamin Kramer << StringRef(MipsInstPrinter::getRegisterName(MO.getReg())).lower(); 589972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes break; 590972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 591972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes case MachineOperand::MO_Immediate: 592ce98deb9f512070fe82518594550dd030b26dd96Akira Hatanaka O << MO.getImm(); 593972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes break; 594972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 595972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes case MachineOperand::MO_MachineBasicBlock: 5961b2eb0e8a6aaf034675b17be6d853cb1c666200fChris Lattner O << *MO.getMBB()->getSymbol(); 597972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes return; 598972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 599972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes case MachineOperand::MO_GlobalAddress: 600ffc7dca885151ed42642c2d6733e8db75d276621Rafael Espindola O << *getSymbol(MO.getGlobal()); 601972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes break; 602972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 603ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes case MachineOperand::MO_BlockAddress: { 604864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress()); 605ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes O << BA->getName(); 606ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes break; 607ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes } 608ca8a2aa921ec8966b1f0708d77e4dc0a6f1a32f8Bruno Cardoso Lopes 609972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes case MachineOperand::MO_ConstantPoolIndex: 61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines O << DL->getPrivateGlobalPrefix() << "CPI" 6118aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner << getFunctionNumber() << "_" << MO.getIndex(); 6122045c47affc0d1462a815175e420f9d6bd3f35c6Bruno Cardoso Lopes if (MO.getOffset()) 6132045c47affc0d1462a815175e420f9d6bd3f35c6Bruno Cardoso Lopes O << "+" << MO.getOffset(); 614972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes break; 61581092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes 616972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes default: 617c23197a26f34f559ea9797de51e187087c039c42Torok Edwin llvm_unreachable("<unknown operand type>"); 618972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes } 619972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 620972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes if (closeP) O << ")"; 621972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes} 622972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 62335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattnervoid MipsAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, 62435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner raw_ostream &O) { 625739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes const MachineOperand &MO = MI->getOperand(opNum); 626a00adba6a7e9b0f6600cb6c8c627bb0c705d2f59Devang Patel if (MO.isImm()) 627739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes O << (unsigned short int)MO.getImm(); 62881092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes else 62935c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, opNum, O); 630739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes} 631739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopes 632bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sandersvoid MipsAsmPrinter::printUnsignedImm8(const MachineInstr *MI, int opNum, 633bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders raw_ostream &O) { 634bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders const MachineOperand &MO = MI->getOperand(opNum); 635bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders if (MO.isImm()) 636bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders O << (unsigned short int)(unsigned char)MO.getImm(); 637bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders else 638bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders printOperand(MI, opNum, O); 639bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders} 640bb47fd04c9b1616c0371eb2c488c5f0f665c25f8Daniel Sanders 641739e441311410796d66e6d72426ef0344e0be98fBruno Cardoso Lopesvoid MipsAsmPrinter:: 64203236be44af1d98eb8daa57e8eb8b7bdd7884523Akira HatanakaprintMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O) { 64381092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes // Load/Store memory operands -- imm($reg) 64481092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes // If PIC target the target is loaded as the 645c7db5618f9e5e708b87d9ae6595b3fd510a2a0c0Bruno Cardoso Lopes // pattern lw $25,%call16($28) 64635c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner printOperand(MI, opNum+1, O); 647d3ac47f80551d95c64cb41c3f94e888d7e13275bAkira Hatanaka O << "("; 648d3ac47f80551d95c64cb41c3f94e888d7e13275bAkira Hatanaka printOperand(MI, opNum, O); 649972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes O << ")"; 650972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes} 651972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 652225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopesvoid MipsAsmPrinter:: 65303236be44af1d98eb8daa57e8eb8b7bdd7884523Akira HatanakaprintMemOperandEA(const MachineInstr *MI, int opNum, raw_ostream &O) { 65403236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka // when using stack locations for not load/store instructions 65503236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka // print the same way as all normal 3 operand instructions. 65603236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka printOperand(MI, opNum, O); 65703236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka O << ", "; 65803236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka printOperand(MI, opNum+1, O); 65903236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka return; 66003236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka} 66103236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanaka 66203236be44af1d98eb8daa57e8eb8b7bdd7884523Akira Hatanakavoid MipsAsmPrinter:: 66335c33bd772b3cfb34fdc6b5c9171f955454d0043Chris LattnerprintFCCOperand(const MachineInstr *MI, int opNum, raw_ostream &O, 66435c33bd772b3cfb34fdc6b5c9171f955454d0043Chris Lattner const char *Modifier) { 665864f66085cd9543070ef01b9f7371c110ecd7898Akira Hatanaka const MachineOperand &MO = MI->getOperand(opNum); 66681092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopes O << Mips::MipsFCCToString((Mips::CondCode)MO.getImm()); 667225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes} 668225ca9cdd70de3d12641b0aba7daf6cb568a7ebdBruno Cardoso Lopes 669812209a58c5520c604bc9279aa069e5ae066e860Bob Wilsonvoid MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { 670571dd98ea4d6bf911c3b46a20ca3b5e3b341b21fJack Carter // TODO: Need to add -mabicalls and -mno-abicalls flags. 671571dd98ea4d6bf911c3b46a20ca3b5e3b341b21fJack Carter // Currently we assume that -mabicalls is the default. 672dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool IsABICalls = true; 673dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IsABICalls) { 674dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveAbiCalls(); 675dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Reloc::Model RM = Subtarget->getRelocationModel(); 676dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // FIXME: This condition should be a lot more complicated that it is here. 677dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Ideally it should test for properties of the ABI and not the ABI 678dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // itself. 679dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // For the moment, I'm only correcting enough to make MIPS-IV work. 680dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RM == Reloc::Static && !Subtarget->isABI_N64()) 681dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines getTargetStreamer().emitDirectiveOptionPic0(); 682dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 683571dd98ea4d6bf911c3b46a20ca3b5e3b341b21fJack Carter 68443d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes // Tell the assembler which ABI we are using 68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string SectionName = std::string(".mdebug.") + getCurrentABIString(); 68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.SwitchSection(OutContext.getELFSection( 68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionName, ELF::SHT_PROGBITS, 0, SectionKind::getDataRel())); 68843d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes 689dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // NaN: At the moment we only support: 690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // 1. .nan legacy (default) 691dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // 2. .nan 2008 692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Subtarget->isNaN2008() ? getTargetStreamer().emitDirectiveNaN2008() 693dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines : getTargetStreamer().emitDirectiveNaNLegacy(); 694dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 69543d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes // TODO: handle O64 ABI 69643d526d162c69f29a1cc6734014576eade49529bBruno Cardoso Lopes 69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->isABI_EABI()) { 69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->isGP32bit()) 69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.SwitchSection( 70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutContext.getELFSection(".gcc_compiled_long32", ELF::SHT_PROGBITS, 0, 70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionKind::getDataRel())); 70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.SwitchSection( 70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutContext.getELFSection(".gcc_compiled_long64", ELF::SHT_PROGBITS, 0, 70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionKind::getDataRel())); 70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 707cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 708cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().updateABIInfo(*Subtarget); 709cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().emitDirectiveModuleFP(); 710cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 711cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Subtarget->isABI_O32()) 712cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getTargetStreamer().emitDirectiveModuleOddSPReg(Subtarget->useOddSPReg(), 713cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Subtarget->isABI_O32()); 71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 715c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter 71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::EmitJal(MCSymbol *Symbol) { 71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCInst I; 71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.setOpcode(Mips::JAL); 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.addOperand( 72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCOperand::CreateExpr(MCSymbolRefExpr::Create(Symbol, OutContext))); 72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitInstruction(I, getSubtargetInfo()); 722c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter} 723c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter 72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::EmitInstrReg(unsigned Opcode, unsigned Reg) { 72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCInst I; 72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.setOpcode(Opcode); 72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.addOperand(MCOperand::CreateReg(Reg)); 72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitInstruction(I, getSubtargetInfo()); 72936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 7305e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola 73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::EmitInstrRegReg(unsigned Opcode, unsigned Reg1, 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Reg2) { 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCInst I; 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 73536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Because of the current td files for Mips32, the operands for MTC1 73636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // appear backwards from their normal assembly order. It's not a trivial 73736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // change to fix this in the td file so we adjust for it here. 73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Opcode == Mips::MTC1) { 74036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Temp = Reg1; 74136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Reg1 = Reg2; 74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Reg2 = Temp; 74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.setOpcode(Opcode); 74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.addOperand(MCOperand::CreateReg(Reg1)); 74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.addOperand(MCOperand::CreateReg(Reg2)); 74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitInstruction(I, getSubtargetInfo()); 74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 7495e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola 75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::EmitInstrRegRegReg(unsigned Opcode, unsigned Reg1, 75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Reg2, unsigned Reg3) { 75236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCInst I; 75336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.setOpcode(Opcode); 75436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.addOperand(MCOperand::CreateReg(Reg1)); 75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.addOperand(MCOperand::CreateReg(Reg2)); 75636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I.addOperand(MCOperand::CreateReg(Reg3)); 75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitInstruction(I, getSubtargetInfo()); 75836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 759c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter 76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::EmitMovFPIntPair(unsigned MovOpc, unsigned Reg1, 76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Reg2, unsigned FPReg1, 76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned FPReg2, bool LE) { 76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!LE) { 76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned temp = Reg1; 76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Reg1 = Reg2; 76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Reg2 = temp; 76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitInstrRegReg(MovOpc, Reg1, FPReg1); 76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitInstrRegReg(MovOpc, Reg2, FPReg2); 77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 771dba14301f0098f9fc5c0d244bf334f55a6a21960Jack Carter 77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::EmitSwapFPIntParams(Mips16HardFloatInfo::FPParamVariant PV, 77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool LE, bool ToFP) { 77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines using namespace Mips16HardFloatInfo; 77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned MovOpc = ToFP ? Mips::MTC1 : Mips::MFC1; 77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (PV) { 77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case FSig: 77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitInstrRegReg(MovOpc, Mips::A0, Mips::F12); 77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case FFSig: 78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F14, LE); 78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case FDSig: 78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitInstrRegReg(MovOpc, Mips::A0, Mips::F12); 78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE); 78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DSig: 78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 78936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 79036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DDSig: 79136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 79236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::A2, Mips::A3, Mips::F14, Mips::F15, LE); 79336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 79436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DFSig: 79536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F12, Mips::F13, LE); 79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitInstrRegReg(MovOpc, Mips::A2, Mips::F14); 79736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 79836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case NoSig: 79936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 80036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 80136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 8025e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola 80336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid 80436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMipsAsmPrinter::EmitSwapFPIntRetval(Mips16HardFloatInfo::FPReturnVariant RV, 80536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool LE) { 80636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines using namespace Mips16HardFloatInfo; 80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned MovOpc = Mips::MFC1; 80836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (RV) { 80936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case FRet: 81036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitInstrRegReg(MovOpc, Mips::V0, Mips::F0); 81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 81236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DRet: 81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case CFRet: 81636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case CDRet: 81936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::V0, Mips::V1, Mips::F0, Mips::F1, LE); 82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitMovFPIntPair(MovOpc, Mips::A0, Mips::A1, Mips::F2, Mips::F3, LE); 82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 82236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case NoFPRet: 82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 82436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 82536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 8265e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola 82736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::EmitFPCallStub( 82836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *Symbol, const Mips16HardFloatInfo::FuncSignature *Signature) { 82936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *MSymbol = OutContext.GetOrCreateSymbol(StringRef(Symbol)); 83036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines using namespace Mips16HardFloatInfo; 83136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool LE = Subtarget->isLittle(); 83236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // .global xxxx 83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 83536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitSymbolAttribute(MSymbol, MCSA_Global); 83636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *RetType; 83736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 83836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // make the comment field identifying the return and parameter 83936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // types of the floating point stub 84036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // # Stub function to call rettype xxxx (params) 84136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Signature->RetSig) { 84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case FRet: 84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RetType = "float"; 84536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DRet: 84736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RetType = "double"; 84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 84936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case CFRet: 85036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RetType = "complex"; 85136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 85236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case CDRet: 85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RetType = "double complex"; 85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case NoFPRet: 85636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RetType = ""; 85736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 85836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 85936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *Parms; 86036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Signature->ParamSig) { 86136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case FSig: 86236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parms = "float"; 86336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 86436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case FFSig: 86536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parms = "float, float"; 86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case FDSig: 86836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parms = "float, double"; 86936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DSig: 87136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parms = "double"; 87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DDSig: 87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parms = "double, double"; 87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case DFSig: 87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parms = "double, float"; 87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case NoSig: 88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Parms = ""; 88136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.AddComment("\t# Stub function to call " + Twine(RetType) + " " + 88436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Twine(Symbol) + " (" + Twine(Parms) + ")"); 88536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 88636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // probably not necessary but we save and restore the current section state 88736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.PushSection(); 88936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 89036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // .section mips16.call.fpxxxx,"ax",@progbits 89136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 89236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSectionELF *M = OutContext.getELFSection( 89336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ".mips16.call.fp." + std::string(Symbol), ELF::SHT_PROGBITS, 89436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ELF::SHF_ALLOC | ELF::SHF_EXECINSTR, SectionKind::getText()); 895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OutStreamer.SwitchSection(M, nullptr); 89636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 89736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // .align 2 89836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitValueToAlignment(4); 90036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MipsTargetStreamer &TS = getTargetStreamer(); 90136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 90236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // .set nomips16 90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // .set nomicromips 90436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetNoMips16(); 90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetNoMicroMips(); 90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // .ent __call_stub_fp_xxxx 909cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // .type __call_stub_fp_xxxx,@function 91036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // __call_stub_fp_xxxx: 91136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 91236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::string x = "__call_stub_fp_" + std::string(Symbol); 91336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *Stub = OutContext.GetOrCreateSymbol(StringRef(x)); 91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveEnt(*Stub); 91536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *MType = 91636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutContext.GetOrCreateSymbol("__call_stub_fp_" + Twine(Symbol)); 91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitSymbolAttribute(MType, MCSA_ELF_TypeFunction); 91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitLabel(Stub); 91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // we just handle non pic for now. these function will not be 92136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // called otherwise. when the full stub generation is moved here 92236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // we need to deal with pic. 92336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 92436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Subtarget->getRelocationModel() == Reloc::PIC_) 92536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("should not be here if we are compiling pic"); 92636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveSetReorder(); 92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We need to add a MipsMCExpr class to MCTargetDesc to fully implement 92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // stubs without raw text but this current patch is for compiler generated 93036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // functions and they all return some value. 93136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The calling sequence for non pic is different in that case and we need 93236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // to implement %lo and %hi in order to handle the case of no return value 93336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // See the corresponding method in Mips16HardFloat for details. 93436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 93536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // mov the return address to S2. 93636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // we have no stack space to store it and we are about to make another call. 93736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We need to make sure that the enclosing function knows to save S2 93836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // This should have already been handled. 93936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 94036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Mov $18, $31 94136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 94236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitInstrRegRegReg(Mips::ADDu, Mips::S2, Mips::RA, Mips::ZERO); 94336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 94436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitSwapFPIntParams(Signature->ParamSig, LE, true); 94536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 94636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Jal xxxx 94736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 94836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitJal(MSymbol); 94936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 95036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // fix return values 95136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitSwapFPIntRetval(Signature->RetSig, LE); 95236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 95336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // do the return 95436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // if (Signature->RetSig == NoFPRet) 95536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // llvm_unreachable("should not be any stubs here with no return value"); 95636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // else 95736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitInstrReg(Mips::JR, Mips::S2); 95836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 95936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *Tmp = OutContext.CreateTempSymbol(); 96036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitLabel(Tmp); 96136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSymbolRefExpr *E = MCSymbolRefExpr::Create(Stub, OutContext); 96236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSymbolRefExpr *T = MCSymbolRefExpr::Create(Tmp, OutContext); 96336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *T_min_E = MCBinaryExpr::CreateSub(T, E, OutContext); 96436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.EmitELFSize(Stub, T_min_E); 96536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TS.emitDirectiveEnd(x); 96636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.PopSection(); 9675e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola} 9685e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindola 9695e195a4c8d8cd4498ab7e0aa16a3b6f273daf457Rafael Espindolavoid MipsAsmPrinter::EmitEndOfAsmFile(Module &M) { 97036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Emit needed stubs 97136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 97236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (std::map< 97336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *, 97436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const llvm::Mips16HardFloatInfo::FuncSignature *>::const_iterator 97536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines it = StubsNeeded.begin(); 97636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines it != StubsNeeded.end(); ++it) { 97736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const char *Symbol = it->first; 97836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const llvm::Mips16HardFloatInfo::FuncSignature *Signature = it->second; 97936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines EmitFPCallStub(Symbol, Signature); 98036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 98136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // return to the text section 98236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines OutStreamer.SwitchSection(OutContext.getObjectFileInfo()->getTextSection()); 983972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes} 984972f5896e417d8e81cf400083fab15a37b6d4277Bruno Cardoso Lopes 985c4f24eb584f6b4dba3caba2ed766c7c4bf1bf8afAkira Hatanakavoid MipsAsmPrinter::PrintDebugValueComment(const MachineInstr *MI, 986c4f24eb584f6b4dba3caba2ed766c7c4bf1bf8afAkira Hatanaka raw_ostream &OS) { 987c4f24eb584f6b4dba3caba2ed766c7c4bf1bf8afAkira Hatanaka // TODO: implement 988c4f24eb584f6b4dba3caba2ed766c7c4bf1bf8afAkira Hatanaka} 989c4f24eb584f6b4dba3caba2ed766c7c4bf1bf8afAkira Hatanaka 99036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Align all targets of indirect branches on bundle size. Used only if target 99136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// is NaCl. 99236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmPrinter::NaClAlignIndirectJumpTargets(MachineFunction &MF) { 99336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Align all blocks that are jumped to through jump table. 99436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MachineJumpTableInfo *JtInfo = MF.getJumpTableInfo()) { 99536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const std::vector<MachineJumpTableEntry> &JT = JtInfo->getJumpTables(); 99636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned I = 0; I < JT.size(); ++I) { 99736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const std::vector<MachineBasicBlock*> &MBBs = JT[I].MBBs; 99836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 99936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned J = 0; J < MBBs.size(); ++J) 100036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MBBs[J]->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 100136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 100236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 100336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 100436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If basic block address is taken, block can be target of indirect branch. 100536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 100636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MBB != E; ++MBB) { 100736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MBB->hasAddressTaken()) 100836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MBB->setAlignment(MIPS_NACL_BUNDLE_ALIGN); 100936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 101036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 101136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool MipsAsmPrinter::isLongBranchPseudo(int Opcode) const { 1013dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return (Opcode == Mips::LONG_BRANCH_LUi 1014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines || Opcode == Mips::LONG_BRANCH_ADDiu 1015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines || Opcode == Mips::LONG_BRANCH_DADDiu); 1016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 1017dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1018a96751fc8ff1cc9a225ffbba73de53e2b9e1ae35Bob Wilson// Force static initialization. 101981092dc20abe5253a5b4d48a75997baa84dde196Bruno Cardoso Lopesextern "C" void LLVMInitializeMipsAsmPrinter() { 10200c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmPrinter<MipsAsmPrinter> X(TheMipsTarget); 10210c795d61878156817cedbac51ec2921f2634c1a5Daniel Dunbar RegisterAsmPrinter<MipsAsmPrinter> Y(TheMipselTarget); 10222464810ac27af8dd8b11da7519b719c254854c19Akira Hatanaka RegisterAsmPrinter<MipsAsmPrinter> A(TheMips64Target); 10232464810ac27af8dd8b11da7519b719c254854c19Akira Hatanaka RegisterAsmPrinter<MipsAsmPrinter> B(TheMips64elTarget); 102451b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar} 1025