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