SparcInstrInfo.cpp revision c1a62834a2ad33a80ca2b1f3a549f4f7806cd320
17c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner//===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===//
2b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
3e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke//                     The LLVM Compiler Infrastructure
4e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7b5f662fa0314f7e7e690aae8ebff7136cc3a5ab0Misha Brukman//
8e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke//===----------------------------------------------------------------------===//
9e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke//
107c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner// This file contains the Sparc implementation of the TargetInstrInfo class.
11e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke//
12e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke//===----------------------------------------------------------------------===//
13e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke
147c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner#include "SparcInstrInfo.h"
15d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson#include "SparcSubtarget.h"
167c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner#include "Sparc.h"
17718cb665ca6ce2bc4d8e8479f46a45db91b49f86Owen Anderson#include "llvm/ADT/STLExtras.h"
18d68a07650cdb2e18f18f362ba533459aa10e01b6Dan Gohman#include "llvm/ADT/SmallVector.h"
19e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke#include "llvm/CodeGen/MachineInstrBuilder.h"
20db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner#include "llvm/CodeGen/MachineRegisterInfo.h"
21c25e7581b9b8088910da31702d4ca21c4734c6d7Torok Edwin#include "llvm/Support/ErrorHandling.h"
227c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner#include "SparcGenInstrInfo.inc"
23db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner#include "SparcMachineFunctionInfo.h"
241ddf475b6a3d748427546ab8f65a712c8eea3a0fChris Lattnerusing namespace llvm;
25e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke
267c90f73a1b06040d971a3dd95a491031ae6238d5Chris LattnerSparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST)
27641055225092833197efe8e5bce01d50bcf1daaeChris Lattner  : TargetInstrInfoImpl(SparcInsts, array_lengthof(SparcInsts)),
28d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson    RI(ST, *this), Subtarget(ST) {
29e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke}
30e785e531f4495068ee46cabd926939eec15a565aBrian Gaeke
315ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// isLoadFromStackSlot - If the specified machine instruction is a direct
325ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// load from a stack slot, return the virtual or physical register number of
335ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// the destination along with the FrameIndex of the loaded stack slot.  If
345ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// not, return 0.  This predicate must return 0 if the instruction has
355ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// any side effects other than loading from the stack slot.
36cbad42cfd1cc93a41ff26ea2e8895bfbc09f54f2Dan Gohmanunsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
377c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner                                             int &FrameIndex) const {
387c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner  if (MI->getOpcode() == SP::LDri ||
397c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner      MI->getOpcode() == SP::LDFri ||
407c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner      MI->getOpcode() == SP::LDDFri) {
41d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman    if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() &&
429a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner        MI->getOperand(2).getImm() == 0) {
438aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      FrameIndex = MI->getOperand(1).getIndex();
445ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner      return MI->getOperand(0).getReg();
455ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner    }
465ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner  }
475ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner  return 0;
485ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner}
495ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner
505ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// isStoreToStackSlot - If the specified machine instruction is a direct
515ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// store to a stack slot, return the virtual or physical register number of
525ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// the source reg along with the FrameIndex of the loaded stack slot.  If
535ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// not, return 0.  This predicate must return 0 if the instruction has
545ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner/// any side effects other than storing to the stack slot.
55cbad42cfd1cc93a41ff26ea2e8895bfbc09f54f2Dan Gohmanunsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
567c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner                                            int &FrameIndex) const {
577c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner  if (MI->getOpcode() == SP::STri ||
587c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner      MI->getOpcode() == SP::STFri ||
597c90f73a1b06040d971a3dd95a491031ae6238d5Chris Lattner      MI->getOpcode() == SP::STDFri) {
60d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman    if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() &&
619a1ceaedc282f0cae31f2723f4d6c00c7b88fe90Chris Lattner        MI->getOperand(1).getImm() == 0) {
628aa797aa51cd4ea1ec6f46f4891a6897944b75b2Chris Lattner      FrameIndex = MI->getOperand(0).getIndex();
635ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner      return MI->getOperand(2).getReg();
645ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner    }
655ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner  }
665ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner  return 0;
675ccc7225db0cb4d738045ade8e8c38d5345ac08aChris Lattner}
68e87146ace88464be4ea4f8869830642c40178f1fChris Lattner
69c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindarajustatic bool IsIntegerCC(unsigned CC)
70c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju{
71c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  return  (CC <= SPCC::ICC_VC);
72c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju}
73c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
74c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
75c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindarajustatic SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
76c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju{
77c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  switch(CC) {
78c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  default: llvm_unreachable("Unknown condition code");
79c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_NE:   return SPCC::ICC_E;
80c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_E:    return SPCC::ICC_NE;
81c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_G:    return SPCC::ICC_LE;
82c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_LE:   return SPCC::ICC_G;
83c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_GE:   return SPCC::ICC_L;
84c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_L:    return SPCC::ICC_GE;
85c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_GU:   return SPCC::ICC_LEU;
86c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_LEU:  return SPCC::ICC_GU;
87c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_CC:   return SPCC::ICC_CS;
88c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_CS:   return SPCC::ICC_CC;
89c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_POS:  return SPCC::ICC_NEG;
90c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_NEG:  return SPCC::ICC_POS;
91c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_VC:   return SPCC::ICC_VS;
92c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::ICC_VS:   return SPCC::ICC_VC;
93c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
94c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_U:    return SPCC::FCC_O;
95c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_O:    return SPCC::FCC_U;
96c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_G:    return SPCC::FCC_LE;
97c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_LE:   return SPCC::FCC_G;
98c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_UG:   return SPCC::FCC_ULE;
99c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_ULE:  return SPCC::FCC_UG;
100c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_L:    return SPCC::FCC_GE;
101c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_GE:   return SPCC::FCC_L;
102c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_UL:   return SPCC::FCC_UGE;
103c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_UGE:  return SPCC::FCC_UL;
104c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_LG:   return SPCC::FCC_UE;
105c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_UE:   return SPCC::FCC_LG;
106c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_NE:   return SPCC::FCC_E;
107c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  case SPCC::FCC_E:    return SPCC::FCC_NE;
108c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  }
109c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju}
110c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
111c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
112c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindarajubool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
113c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju                                   MachineBasicBlock *&TBB,
114c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju                                   MachineBasicBlock *&FBB,
115c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju                                   SmallVectorImpl<MachineOperand> &Cond,
116c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju                                   bool AllowModify) const
117c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju{
118c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
119c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  MachineBasicBlock::iterator I = MBB.end();
120c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  MachineBasicBlock::iterator UnCondBrIter = MBB.end();
121c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  while (I != MBB.begin()) {
122c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    --I;
123c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
124c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    if (I->isDebugValue())
125c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      continue;
126c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
127c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    //When we see a non-terminator, we are done
128c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    if (!isUnpredicatedTerminator(I))
129c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      break;
130c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
131c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    //Terminator is not a branch
132c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    if (!I->getDesc().isBranch())
133c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      return true;
134c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
135c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    //Handle Unconditional branches
136c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    if (I->getOpcode() == SP::BA) {
137c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      UnCondBrIter = I;
138c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
139c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      if (!AllowModify) {
140c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        TBB = I->getOperand(0).getMBB();
141c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        continue;
142c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      }
143c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
144c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      while (llvm::next(I) != MBB.end())
145c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        llvm::next(I)->eraseFromParent();
146c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
147c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      Cond.clear();
148c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      FBB = 0;
149c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
150c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
151c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        TBB = 0;
152c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        I->eraseFromParent();
153c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        I = MBB.end();
154c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        UnCondBrIter = MBB.end();
155c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        continue;
156c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      }
157c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
158c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      TBB = I->getOperand(0).getMBB();
159c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      continue;
160c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    }
161c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
162c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    unsigned Opcode = I->getOpcode();
163c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    if (Opcode != SP::BCOND && Opcode != SP::FBCOND)
164c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      return true; //Unknown Opcode
165c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
166c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    SPCC::CondCodes BranchCode = (SPCC::CondCodes)I->getOperand(1).getImm();
167c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
168c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    if (Cond.empty()) {
169c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
170c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      if (AllowModify && UnCondBrIter != MBB.end() &&
171c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju          MBB.isLayoutSuccessor(TargetBB)) {
172c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
173c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //Transform the code
174c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //
175c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //    brCC L1
176c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //    ba L2
177c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        // L1:
178c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //    ..
179c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        // L2:
180c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //
181c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        // into
182c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //
183c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //   brnCC L2
184c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        // L1:
185c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //   ...
186c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        // L2:
187c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        //
188c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        BranchCode = GetOppositeBranchCondition(BranchCode);
189c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        MachineBasicBlock::iterator OldInst = I;
190c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(Opcode))
191c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju          .addMBB(UnCondBrIter->getOperand(0).getMBB()).addImm(BranchCode);
192c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(SP::BA))
193c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju          .addMBB(TargetBB);
194c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        MBB.addSuccessor(TargetBB);
195c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        OldInst->eraseFromParent();
196c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        UnCondBrIter->eraseFromParent();
197c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
198c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        UnCondBrIter = MBB.end();
199c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        I = MBB.end();
200c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        continue;
201c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      }
202c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      FBB = TBB;
203c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      TBB = I->getOperand(0).getMBB();
204c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      Cond.push_back(MachineOperand::CreateImm(BranchCode));
205c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      continue;
206c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    }
207c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    //FIXME: Handle subsequent conditional branches
208c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    //For now, we can't handle multiple conditional branches
209c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    return true;
210c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  }
211c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  return false;
212c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju}
213c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
2146ae3626a4fda14e6250ac8d8ff487efb8952cdf7Evan Chengunsigned
2156ae3626a4fda14e6250ac8d8ff487efb8952cdf7Evan ChengSparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
2166ae3626a4fda14e6250ac8d8ff487efb8952cdf7Evan Cheng                             MachineBasicBlock *FBB,
2173bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings                             const SmallVectorImpl<MachineOperand> &Cond,
218c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju                             DebugLoc DL) const {
219c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  assert(TBB && "InsertBranch must not be told to insert a fallthrough");
220c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  assert((Cond.size() == 1 || Cond.size() == 0) &&
221c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju         "Sparc branch conditions should have one component!");
222c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
223c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  if (Cond.empty()) {
224c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    assert(!FBB && "Unconditional branch with multiple successors!");
225c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
226c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    return 1;
227c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  }
228c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
229c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  //Conditional branch
230c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  unsigned CC = Cond[0].getImm();
231c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
232c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  if (IsIntegerCC(CC))
233c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    BuildMI(&MBB, DL, get(SP::BCOND)).addMBB(TBB).addImm(CC);
234c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  else
235c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    BuildMI(&MBB, DL, get(SP::FBCOND)).addMBB(TBB).addImm(CC);
236c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  if (!FBB)
237c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    return 1;
238c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
239c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  BuildMI(&MBB, DL, get(SP::BA)).addMBB(FBB);
240c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  return 2;
241c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju}
242c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
243c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindarajuunsigned SparcInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const
244c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju{
245c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  MachineBasicBlock::iterator I = MBB.end();
246c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  unsigned Count = 0;
247c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  while (I != MBB.begin()) {
248c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    --I;
249c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
250c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    if (I->isDebugValue())
251c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      continue;
252c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
253c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    if (I->getOpcode() != SP::BA
254c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        && I->getOpcode() != SP::BCOND
255c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju        && I->getOpcode() != SP::FBCOND)
256c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju      break; // Not a branch
257c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju
258c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    I->eraseFromParent();
259c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    I = MBB.end();
260c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju    ++Count;
261c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  }
262c1a62834a2ad33a80ca2b1f3a549f4f7806cd320Venkatraman Govindaraju  return Count;
2633d7d39ab1549f5ab7a929ec18a3e6481862cf247Rafael Espindola}
264d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson
2658e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesenvoid SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
2668e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen                                 MachineBasicBlock::iterator I, DebugLoc DL,
2678e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen                                 unsigned DestReg, unsigned SrcReg,
2688e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen                                 bool KillSrc) const {
2698e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen  if (SP::IntRegsRegClass.contains(DestReg, SrcReg))
2708e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen    BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0)
2718e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen      .addReg(SrcReg, getKillRegState(KillSrc));
2728e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen  else if (SP::FPRegsRegClass.contains(DestReg, SrcReg))
2738e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen    BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg)
2748e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen      .addReg(SrcReg, getKillRegState(KillSrc));
2758e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen  else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg))
2768e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen    BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg)
2778e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen      .addReg(SrcReg, getKillRegState(KillSrc));
278d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson  else
2798e18a1a5cf4423dba9b8c53f2699299c514a9dc2Jakob Stoklund Olesen    llvm_unreachable("Impossible reg-to-reg copy");
280d10fd9791c20fd8368fa0ce94b626b769c6c8ba0Owen Anderson}
281f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson
282f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Andersonvoid SparcInstrInfo::
283f6372aa1cc568df19da7c5023e83c75aa9404a07Owen AndersonstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
284f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson                    unsigned SrcReg, bool isKill, int FI,
285746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                    const TargetRegisterClass *RC,
286746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                    const TargetRegisterInfo *TRI) const {
287c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
288d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling  if (I != MBB.end()) DL = I->getDebugLoc();
289d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling
290f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
291f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  if (RC == SP::IntRegsRegisterClass)
292d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)
293587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling      .addReg(SrcReg, getKillRegState(isKill));
294f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  else if (RC == SP::FPRegsRegisterClass)
295d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)
296587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling      .addReg(SrcReg,  getKillRegState(isKill));
297f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  else if (RC == SP::DFPRegsRegisterClass)
298d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)
299587daedce2d6c2b2d380b6a5843a6f8b6cfc79e4Bill Wendling      .addReg(SrcReg,  getKillRegState(isKill));
300f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  else
301c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Can't store this register to stack slot");
302f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson}
303f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson
304f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Andersonvoid SparcInstrInfo::
305f6372aa1cc568df19da7c5023e83c75aa9404a07Owen AndersonloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
306f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson                     unsigned DestReg, int FI,
307746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                     const TargetRegisterClass *RC,
308746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng                     const TargetRegisterInfo *TRI) const {
309c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc DL;
310d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling  if (I != MBB.end()) DL = I->getDebugLoc();
311d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling
312f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  if (RC == SP::IntRegsRegisterClass)
313d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0);
314f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  else if (RC == SP::FPRegsRegisterClass)
315d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0);
316f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  else if (RC == SP::DFPRegsRegisterClass)
317d1c321a89ab999b9bb602b0f398ecd4c2022262cBill Wendling    BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0);
318f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson  else
319c23197a26f34f559ea9797de51e187087c039c42Torok Edwin    llvm_unreachable("Can't load this register from stack slot");
320f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson}
321f6372aa1cc568df19da7c5023e83c75aa9404a07Owen Anderson
322db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattnerunsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const
323db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner{
324db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>();
325db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  unsigned GlobalBaseReg = SparcFI->getGlobalBaseReg();
326db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  if (GlobalBaseReg != 0)
327db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner    return GlobalBaseReg;
328db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner
329db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  // Insert the set of GlobalBaseReg into the first MBB of the function
330db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  MachineBasicBlock &FirstMBB = MF->front();
331db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  MachineBasicBlock::iterator MBBI = FirstMBB.begin();
332db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  MachineRegisterInfo &RegInfo = MF->getRegInfo();
333db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner
334db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  GlobalBaseReg = RegInfo.createVirtualRegister(&SP::IntRegsRegClass);
335db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner
336db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner
337c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner  DebugLoc dl;
338db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner
339db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
340db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  SparcFI->setGlobalBaseReg(GlobalBaseReg);
341db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner  return GlobalBaseReg;
342db486a6d5311944f61b92db9f6074944dbbdb242Chris Lattner}
343