1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- MipsISelDAGToDAG.cpp - A dag to dag inst selector for Mips --------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file defines an instruction selector for the MIPS target. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define DEBUG_TYPE "mips-isel" 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "Mips.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MipsMachineFunction.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MipsRegisterInfo.h" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MipsSubtarget.h" 19894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "MipsTargetMachine.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/GlobalValue.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Instructions.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Intrinsics.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/CFG.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Type.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineConstantPool.h" 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h" 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFrameInfo.h" 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h" 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineRegisterInfo.h" 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/SelectionDAGISel.h" 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h" 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Instruction Selector Implementation 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// MipsDAGToDAGISel - MIPS specific code to select MIPS machine 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// instructions for SelectionDAG operations. 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace { 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass MipsDAGToDAGISel : public SelectionDAGISel { 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// TM - Keep a reference to MipsTargetMachine. 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MipsTargetMachine &TM; 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// make the right decision when generating code for different targets. 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MipsSubtarget &Subtarget; 5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman explicit MipsDAGToDAGISel(MipsTargetMachine &tm) : 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectionDAGISel(tm), 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {} 6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Pass Name 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman virtual const char *getPassName() const { 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return "MIPS DAG->DAG Pattern Instruction Selection"; 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanprivate: 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Include the pieces autogenerated from the target description. 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman #include "MipsGenDAGISel.inc" 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getTargetMachine - Return a reference to the TargetMachine, casted 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// to the target-specific type. 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MipsTargetMachine &getTargetMachine() { 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return static_cast<const MipsTargetMachine &>(TM); 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// getInstrInfo - Return a reference to the TargetInstrInfo, casted 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// to the target-specific type. 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MipsInstrInfo *getInstrInfo() { 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getTargetMachine().getInstrInfo(); 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *getGlobalBaseReg(); 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Select(SDNode *N); 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Complex Pattern. 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool SelectAddr(SDValue N, SDValue &Base, SDValue &Offset); 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // getI32Imm - Return a target constant with the specified 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // value, of type i32. 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman inline SDValue getI32Imm(unsigned Imm) { 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getTargetConstant(Imm, MVT::i32); 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman char ConstraintCode, 9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<SDValue> &OutOps); 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// getGlobalBaseReg - Output the instructions required to put the 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// GOT address into a register. 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode *MipsDAGToDAGISel::getGlobalBaseReg() { 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF); 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ComplexPattern used on MipsInstrInfo 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Used on Mips Load/Store instructions 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool MipsDAGToDAGISel:: 11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) { 11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ValTy = Addr.getValueType(); 11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned GPReg = ValTy == MVT::i32 ? Mips::GP : Mips::GP_64; 11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // if Address is FI, get the TargetFrameIndex. 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset = CurDAG->getTargetConstant(0, ValTy); 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // on PIC code Load GA 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TM.getRelocationModel() == Reloc::PIC_) { 12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Addr.getOpcode() == MipsISD::WrapperPIC) { 12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Base = CurDAG->getRegister(GPReg, ValTy); 12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset = Addr.getOperand(0); 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if ((Addr.getOpcode() == ISD::TargetExternalSymbol || 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Addr.getOpcode() == ISD::TargetGlobalAddress)) 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (Addr.getOpcode() == ISD::TargetGlobalTLSAddress) { 13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Base = CurDAG->getRegister(GPReg, ValTy); 13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset = Addr; 13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return true; 13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Addresses of the form FI+const or FI|const 14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (CurDAG->isBaseWithConstantOffset(Addr)) { 14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isInt<16>(CN->getSExtValue())) { 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If the first operand is a FI, get the TargetFI Node 14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> 14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (Addr.getOperand(0))) 15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Base = Addr.getOperand(0); 15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy); 15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return true; 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Operand is a result from an ADD. 16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Addr.getOpcode() == ISD::ADD) { 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // When loading from constant pools, load the lower address part in 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the instruction itself. Example, instead of: 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // lui $2, %hi($CPI1_0) 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // addiu $2, $2, %lo($CPI1_0) 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // lwc1 $f0, 0($2) 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Generate: 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // lui $2, %hi($CPI1_0) 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // lwc1 $f0, %lo($CPI1_0)($2) 16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if ((Addr.getOperand(0).getOpcode() == MipsISD::Hi || 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Addr.getOperand(0).getOpcode() == ISD::LOAD) && 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Addr.getOperand(1).getOpcode() == MipsISD::Lo) { 17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue LoVal = Addr.getOperand(1); 17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isa<ConstantPoolSDNode>(LoVal.getOperand(0)) || 17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isa<GlobalAddressSDNode>(LoVal.getOperand(0))) { 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = Addr.getOperand(0); 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Offset = LoVal.getOperand(0); 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Base = Addr; 18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset = CurDAG->getTargetConstant(0, ValTy); 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Select instructions not customized! Used for 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// expanded, promoted and normal instructions 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDNode* MipsDAGToDAGISel::Select(SDNode *Node) { 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opcode = Node->getOpcode(); 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Dump information about the Node being selected 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n"); 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we have a custom node, we already have selected! 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->isMachineOpcode()) { 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return NULL; 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Instruction Selection not handled by the auto-generated 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // tablegen selection should be handled here. 20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /// 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch(Opcode) { 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: break; 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::SUBE: 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ADDE: { 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InFlag = Node->getOperand(2), CmpLHS; 21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Opc = InFlag.getOpcode(); (void)Opc; 21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || 21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (Opc == ISD::SUBC || Opc == ISD::SUBE)) && 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn"); 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned MOp; 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Opcode == ISD::ADDE) { 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CmpLHS = InFlag.getValue(0); 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MOp = Mips::ADDu; 22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CmpLHS = InFlag.getOperand(0); 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MOp = Mips::SUBu; 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) }; 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = Node->getOperand(0); 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = Node->getOperand(1); 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = LHS.getValueType(); 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, dl, VT, Ops, 2); 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT, 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue(Carry,0), RHS); 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS, SDValue(AddCarry,0)); 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /// Mul with two results 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SMUL_LOHI: 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UMUL_LOHI: { 24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Node->getValueType(0) != MVT::i64 && 24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "64-bit multiplication with two results not handled."); 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op1 = Node->getOperand(0); 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op2 = Node->getOperand(1); 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Op; 24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT); 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDNode *Mul = CurDAG->getMachineNode(Op, dl, MVT::Glue, Op1, Op2); 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue InFlag = SDValue(Mul, 0); 25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, 25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT::Glue, InFlag); 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman InFlag = SDValue(Lo,1); 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Hi = CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag); 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!SDValue(Node, 0).use_empty()) 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceUses(SDValue(Node, 0), SDValue(Lo,0)); 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!SDValue(Node, 1).use_empty()) 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ReplaceUses(SDValue(Node, 1), SDValue(Hi,0)); 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return NULL; 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// Special Muls 26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::MUL: 27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Mips32 has a 32-bit three operand mul instruction. 27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Subtarget.hasMips32() && Node->getValueType(0) == MVT::i32) 27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MULHS: 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MULHU: { 27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert((Opcode == ISD::MUL || Node->getValueType(0) != MVT::i64) && 27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "64-bit MULH* not handled."); 27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT Ty = Node->getValueType(0); 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue MulOp1 = Node->getOperand(0); 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue MulOp2 = Node->getOperand(1); 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned MulOp = (Opcode == ISD::MULHU ? 28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Mips::MULTu : 28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (Ty == MVT::i32 ? Mips::MULT : Mips::DMULT)); 28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDNode *MulNode = CurDAG->getMachineNode(MulOp, dl, 28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MVT::Glue, MulOp1, MulOp2); 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InFlag = SDValue(MulNode, 0); 288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Opcode == ISD::MUL) { 29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Opc = (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64); 29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getMachineNode(Opc, dl, Ty, InFlag); 29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag); 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get target GOT address. 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::GLOBAL_OFFSET_TABLE: 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return getGlobalBaseReg(); 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ConstantFP: { 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node); 30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { 30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Mips::ZERO, MVT::i32); 30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CurDAG->getMachineNode(Mips::BuildPairF64, dl, MVT::f64, Zero, 30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Zero); 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MipsISD::ThreadPointer: { 31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SrcReg = Mips::HWR29; 31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned DestReg = Mips::V1; 31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDNode *Rdhwr = CurDAG->getMachineNode(Mips::RDHWR, Node->getDebugLoc(), 31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getValueType(0), CurDAG->getRegister(SrcReg, MVT::i32)); 31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg, 31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue(Rdhwr, 0)); 31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, MVT::i32); 32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ReplaceUses(SDValue(Node, 0), ResNode); 32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return ResNode.getNode(); 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Select the default instruction 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *ResNode = SelectCode(Node); 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "=> "); 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ResNode == NULL || ResNode == Node) 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(Node->dump(CurDAG)); 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(ResNode->dump(CurDAG)); 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "\n"); 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ResNode; 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool MipsDAGToDAGISel:: 33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::vector<SDValue> &OutOps) { 34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); 34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OutOps.push_back(Op); 34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return false; 34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// createMipsISelDag - This pass converts a legalized DAG into a 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// MIPS-specific DAG, ready for instruction scheduling. 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanFunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) { 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return new MipsDAGToDAGISel(TM); 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 350