1a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===-- MBlazeISelDAGToDAG.cpp - A dag to dag inst selector for MBlaze ----===// 2a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 3a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// The LLVM Compiler Infrastructure 4a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 5a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// This file is distributed under the University of Illinois Open Source 6a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// License. See LICENSE.TXT for details. 7a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 8a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 9a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 10a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// This file defines an instruction selector for the MBlaze target. 11a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 12a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 13a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 14a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#define DEBUG_TYPE "mblaze-isel" 15a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlaze.h" 16a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeMachineFunction.h" 17a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeRegisterInfo.h" 18a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeSubtarget.h" 19a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeTargetMachine.h" 20a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/GlobalValue.h" 21a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Instructions.h" 22a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Intrinsics.h" 23a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/CFG.h" 24a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Type.h" 25a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineConstantPool.h" 26a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineFunction.h" 27a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineFrameInfo.h" 28a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineInstrBuilder.h" 29a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineRegisterInfo.h" 30a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/SelectionDAGISel.h" 31a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Target/TargetMachine.h" 32a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/Debug.h" 33a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/ErrorHandling.h" 34a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/raw_ostream.h" 35a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckusing namespace llvm; 36a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 37a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 38a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// Instruction Selector Implementation 39a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 40a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 41a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 42a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// MBlazeDAGToDAGISel - MBlaze specific code to select MBlaze machine 43a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// instructions for SelectionDAG operations. 44a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 45a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Pecknamespace { 46a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 47a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckclass MBlazeDAGToDAGISel : public SelectionDAGISel { 48a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 49a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// TM - Keep a reference to MBlazeTargetMachine. 50a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MBlazeTargetMachine &TM; 51a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 52a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// Subtarget - Keep a pointer to the MBlazeSubtarget around so that we can 53a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// make the right decision when generating code for different targets. 54a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck const MBlazeSubtarget &Subtarget; 55a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 56a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckpublic: 57a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck explicit MBlazeDAGToDAGISel(MBlazeTargetMachine &tm) : 58a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SelectionDAGISel(tm), 59a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck TM(tm), Subtarget(tm.getSubtarget<MBlazeSubtarget>()) {} 60a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 61a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Pass Name 62a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck virtual const char *getPassName() const { 63a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return "MBlaze DAG->DAG Pattern Instruction Selection"; 64a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 65a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckprivate: 66a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Include the pieces autogenerated from the target description. 67a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck #include "MBlazeGenDAGISel.inc" 68a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 69a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// getTargetMachine - Return a reference to the TargetMachine, casted 70a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// to the target-specific type. 71a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck const MBlazeTargetMachine &getTargetMachine() { 72a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return static_cast<const MBlazeTargetMachine &>(TM); 73a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 74a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 75a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// getInstrInfo - Return a reference to the TargetInstrInfo, casted 76a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// to the target-specific type. 77a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck const MBlazeInstrInfo *getInstrInfo() { 78a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return getTargetMachine().getInstrInfo(); 79a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 80a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 81a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDNode *getGlobalBaseReg(); 82a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDNode *Select(SDNode *N); 83a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 84a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Address Selection 8552a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner bool SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index); 8652a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris Lattner bool SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base); 87a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 88a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // getI32Imm - Return a target constant with the specified value, of type i32. 89a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck inline SDValue getI32Imm(unsigned Imm) { 90a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return CurDAG->getTargetConstant(Imm, MVT::i32); 91a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 92a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck}; 93a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 94a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 95a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 96a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// isIntS32Immediate - This method tests to see if the node is either a 32-bit 97a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// or 64-bit immediate, and if the value can be accurately represented as a 98a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// sign extension from a 32-bit value. If so, this returns true and the 99a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// immediate. 100a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckstatic bool isIntS32Immediate(SDNode *N, int32_t &Imm) { 101a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned Opc = N->getOpcode(); 102a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (Opc != ISD::Constant) 103a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return false; 104a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 105a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Imm = (int32_t)cast<ConstantSDNode>(N)->getZExtValue(); 106a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (N->getValueType(0) == MVT::i32) 107a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return Imm == (int32_t)cast<ConstantSDNode>(N)->getZExtValue(); 108a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck else 109a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return Imm == (int64_t)cast<ConstantSDNode>(N)->getZExtValue(); 110a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 111a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 112a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckstatic bool isIntS32Immediate(SDValue Op, int32_t &Imm) { 113a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return isIntS32Immediate(Op.getNode(), Imm); 114a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 115a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 116a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 117a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// SelectAddressRegReg - Given the specified addressed, check to see if it 118a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// can be represented as an indexed [r+r] operation. Returns false if it 119a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// can be more efficiently represented with [r+imm]. 120a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckbool MBlazeDAGToDAGISel:: 12152a261b3c1391c5fec399ddeb3fc6ee9541e8790Chris LattnerSelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index) { 122a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (N.getOpcode() == ISD::FrameIndex) return false; 123a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (N.getOpcode() == ISD::TargetExternalSymbol || 124a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck N.getOpcode() == ISD::TargetGlobalAddress) 125a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return false; // direct calls. 126a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 127a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck int32_t imm = 0; 128a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) { 129a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (isIntS32Immediate(N.getOperand(1), imm)) 130a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return false; // r+i 131a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 132c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck if (N.getOperand(0).getOpcode() == ISD::TargetJumpTable || 133c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck N.getOperand(1).getOpcode() == ISD::TargetJumpTable) 134c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck return false; // jump tables. 135c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 13641400da31ead2f61d171381c0945dceddd8fc786Wesley Peck Base = N.getOperand(0); 13741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck Index = N.getOperand(1); 138a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return true; 139a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 140a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 141a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return false; 142a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 143a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 144a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// Returns true if the address N can be represented by a base register plus 145a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// a signed 32-bit displacement [r+imm], and if it is not better 146a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// represented as reg+reg. 147a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckbool MBlazeDAGToDAGISel:: 14841400da31ead2f61d171381c0945dceddd8fc786Wesley PeckSelectAddrRegImm(SDValue N, SDValue &Base, SDValue &Disp) { 149a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // If this can be more profitably realized as r+r, fail. 15041400da31ead2f61d171381c0945dceddd8fc786Wesley Peck if (SelectAddrRegReg(N, Base, Disp)) 151a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return false; 152a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 153a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) { 154a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck int32_t imm = 0; 155a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (isIntS32Immediate(N.getOperand(1), imm)) { 156a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Disp = CurDAG->getTargetConstant(imm, MVT::i32); 157a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) { 158a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType()); 159a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } else { 160a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Base = N.getOperand(0); 161a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 162a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return true; // [r+i] 163a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 164a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) { 165a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Loading from a constant address. 166a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck uint32_t Imm = CN->getZExtValue(); 167a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Disp = CurDAG->getTargetConstant(Imm, CN->getValueType(0)); 168a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Base = CurDAG->getRegister(MBlaze::R0, CN->getValueType(0)); 169a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return true; 170a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 171a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 172a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Disp = CurDAG->getTargetConstant(0, TM.getTargetLowering()->getPointerTy()); 173a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) 174a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType()); 175a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck else 176a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Base = N; 177a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return true; // [r+0] 178a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 179a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 180a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// getGlobalBaseReg - Output the instructions required to put the 181a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// GOT address into a register. 182a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDNode *MBlazeDAGToDAGISel::getGlobalBaseReg() { 183a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF); 184a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); 185a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 186a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 187a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// Select instructions not customized! Used for 188a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// expanded, promoted and normal instructions 189a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) { 190a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned Opcode = Node->getOpcode(); 191a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DebugLoc dl = Node->getDebugLoc(); 192a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 193a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // If we have a custom node, we already have selected! 1940a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck if (Node->isMachineOpcode()) 195a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return NULL; 196a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 197a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// 198a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Instruction Selection not handled by the auto-generated 199a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // tablegen selection should be handled here. 200a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// 2010a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck switch (Opcode) { 202a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck default: break; 203a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 204a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Get target GOT address. 205a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case ISD::GLOBAL_OFFSET_TABLE: 206a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return getGlobalBaseReg(); 207a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 208a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case ISD::FrameIndex: { 209a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue imm = CurDAG->getTargetConstant(0, MVT::i32); 210a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck int FI = dyn_cast<FrameIndexSDNode>(Node)->getIndex(); 211a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck EVT VT = Node->getValueType(0); 212a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT); 213a7c7b9dccba2c14a93f0f9a29490f1df4f9b4080Wesley Peck unsigned Opc = MBlaze::ADDIK; 214a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (Node->hasOneUse()) 215a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return CurDAG->SelectNodeTo(Node, Opc, VT, TFI, imm); 216a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return CurDAG->getMachineNode(Opc, dl, VT, TFI, imm); 217a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 218a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 219a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 220a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// Handle direct and indirect calls when using PIC. On PIC, when 221a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// GOT is smaller than about 64k (small code) the GA target is 222a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// loaded with only one instruction. Otherwise GA's target must 223a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// be loaded with 3 instructions. 224a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlazeISD::JmpLink: { 225a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (TM.getRelocationModel() == Reloc::PIC_) { 226a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue Chain = Node->getOperand(0); 227a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue Callee = Node->getOperand(1); 228a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue R20Reg = CurDAG->getRegister(MBlaze::R20, MVT::i32); 229a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue InFlag(0, 0); 230a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 2310a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck if ((isa<GlobalAddressSDNode>(Callee)) || 2320a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck (isa<ExternalSymbolSDNode>(Callee))) 233a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck { 234a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// Direct call for global addresses and external symbols 235a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue GPReg = CurDAG->getRegister(MBlaze::R15, MVT::i32); 236a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 237a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Use load to get GOT target 238a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue Ops[] = { Callee, GPReg, Chain }; 239a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue Load = SDValue(CurDAG->getMachineNode(MBlaze::LW, dl, 240a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MVT::i32, MVT::Other, Ops, 3), 0); 241a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = Load.getValue(1); 242a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 243a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Call target must be on T9 244a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Load, InFlag); 245a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } else 246a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck /// Indirect call 247a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Callee, InFlag); 248a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 249a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Emit Jump and Link Register 250a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDNode *ResNode = CurDAG->getMachineNode(MBlaze::BRLID, dl, MVT::Other, 251f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner MVT::Glue, R20Reg, Chain); 252a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = SDValue(ResNode, 0); 253a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck InFlag = SDValue(ResNode, 1); 254a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck ReplaceUses(SDValue(Node, 0), Chain); 255a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck ReplaceUses(SDValue(Node, 1), InFlag); 256a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return ResNode; 257a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 258a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 259a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 260a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 261a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Select the default instruction 262a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDNode *ResNode = SelectCode(Node); 263a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 2647c306da505e2d7f64e160890b274a47fa0740962Chris Lattner DEBUG(errs() << "=> "); 265a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (ResNode == NULL || ResNode == Node) 266a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DEBUG(Node->dump(CurDAG)); 267a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck else 268a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DEBUG(ResNode->dump(CurDAG)); 269a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DEBUG(errs() << "\n"); 270a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return ResNode; 271a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 272a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 273a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// createMBlazeISelDag - This pass converts a legalized DAG into a 274a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// MBlaze-specific DAG, ready for instruction scheduling. 275a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckFunctionPass *llvm::createMBlazeISelDag(MBlazeTargetMachine &TM) { 276a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return new MBlazeDAGToDAGISel(TM); 277a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 278