1a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===-- MBlazeISelLowering.cpp - MBlaze DAG Lowering Implementation -------===// 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 the interfaces that MBlaze uses to lower LLVM code into a 11a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// selection DAG. 12a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 13a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 14a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 15a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#define DEBUG_TYPE "mblaze-lower" 16a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeISelLowering.h" 17a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeMachineFunction.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MBlazeSubtarget.h" 19a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeTargetMachine.h" 20a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeTargetObjectFile.h" 21a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/CallingConvLower.h" 22a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineFrameInfo.h" 23a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineFunction.h" 24a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineInstrBuilder.h" 25a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineRegisterInfo.h" 26a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/SelectionDAGISel.h" 27a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/ValueTypes.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/CallingConv.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/GlobalVariable.h" 320b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Intrinsics.h" 33a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/Debug.h" 34a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/ErrorHandling.h" 35a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/raw_ostream.h" 36a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckusing namespace llvm; 37a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 388397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peckstatic bool CC_MBlaze_AssignReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 398397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck CCValAssign::LocInfo &LocInfo, 408397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck ISD::ArgFlagsTy &ArgFlags, 418397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck CCState &State); 428397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 43a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckconst char *MBlazeTargetLowering::getTargetNodeName(unsigned Opcode) const { 44a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck switch (Opcode) { 45a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlazeISD::JmpLink : return "MBlazeISD::JmpLink"; 46a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlazeISD::GPRel : return "MBlazeISD::GPRel"; 47a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlazeISD::Wrap : return "MBlazeISD::Wrap"; 48a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlazeISD::ICmp : return "MBlazeISD::ICmp"; 49a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlazeISD::Ret : return "MBlazeISD::Ret"; 50a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlazeISD::Select_CC : return "MBlazeISD::Select_CC"; 51a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck default : return NULL; 52a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 53a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 54a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 55a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckMBlazeTargetLowering::MBlazeTargetLowering(MBlazeTargetMachine &TM) 56a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck : TargetLowering(TM, new MBlazeTargetObjectFile()) { 57a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Subtarget = &TM.getSubtarget<MBlazeSubtarget>(); 58a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 59a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // MBlaze does not have i1 type, so use i32 for 60a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // setcc operations results (slt, sgt, ...). 61a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setBooleanContents(ZeroOrOneBooleanContent); 6228b77e968d2b01fc9da724762bd8ddcd80650e32Duncan Sands setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct? 63a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 64a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Set up the register classes 65420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper addRegisterClass(MVT::i32, &MBlaze::GPRRegClass); 66a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (Subtarget->hasFPU()) { 67420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper addRegisterClass(MVT::f32, &MBlaze::GPRRegClass); 68a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::ConstantFP, MVT::f32, Legal); 69a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 70a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 71a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Floating point operations which are not supported 72a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FREM, MVT::f32, Expand); 7333390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich setOperationAction(ISD::FMA, MVT::f32, Expand); 74a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::UINT_TO_FP, MVT::i8, Expand); 75a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::UINT_TO_FP, MVT::i16, Expand); 76a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); 77a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); 78a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FP_ROUND, MVT::f32, Expand); 79a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FP_ROUND, MVT::f64, Expand); 80a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); 81a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); 82a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FSIN, MVT::f32, Expand); 83a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FCOS, MVT::f32, Expand); 848688a58c53b46d2dda9bf50dafd5195790a7ed58Evan Cheng setOperationAction(ISD::FSINCOS, MVT::f32, Expand); 85a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FPOWI, MVT::f32, Expand); 86a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FPOW, MVT::f32, Expand); 87a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FLOG, MVT::f32, Expand); 88a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FLOG2, MVT::f32, Expand); 89a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FLOG10, MVT::f32, Expand); 90a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::FEXP, MVT::f32, Expand); 91a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 92a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Load extented operations for i1 types must be promoted 93a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote); 94a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote); 95a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote); 96a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 974da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck // Sign extended loads must be expanded 984da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand); 994da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand); 1004da992aebada7445ef68a7b6b94676dd26e9d537Wesley Peck 101a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // MBlaze has no REM or DIVREM operations. 102a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::UREM, MVT::i32, Expand); 103a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SREM, MVT::i32, Expand); 104a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SDIVREM, MVT::i32, Expand); 105a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::UDIVREM, MVT::i32, Expand); 106a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 107a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // If the processor doesn't support multiply then expand it 108a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (!Subtarget->hasMul()) { 109a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::MUL, MVT::i32, Expand); 110a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 111a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 112a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // If the processor doesn't support 64-bit multiply then expand 113a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (!Subtarget->hasMul() || !Subtarget->hasMul64()) { 114a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::MULHS, MVT::i32, Expand); 115a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::MULHS, MVT::i64, Expand); 116a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::MULHU, MVT::i32, Expand); 117a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::MULHU, MVT::i64, Expand); 118a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 119a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 120a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // If the processor doesn't support division then expand 121a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (!Subtarget->hasDiv()) { 122a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::UDIV, MVT::i32, Expand); 123a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SDIV, MVT::i32, Expand); 124a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 125a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 126a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Expand unsupported conversions 127bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck setOperationAction(ISD::BITCAST, MVT::f32, Expand); 128bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck setOperationAction(ISD::BITCAST, MVT::i32, Expand); 129a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 130a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Expand SELECT_CC 131a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); 132a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 133a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // MBlaze doesn't have MUL_LOHI 134a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand); 135a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand); 136a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand); 137a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand); 138a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 139a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Used by legalize types to correctly generate the setcc result. 140a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Without this, every float setcc comes with a AND/OR with the result, 141a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // we don't want this, since the fpcmp result goes to a flag register, 142a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // which is used implicitly by brcond and select operations. 143a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32); 144a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck AddPromotedToType(ISD::SELECT, MVT::i1, MVT::i32); 145a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck AddPromotedToType(ISD::SELECT_CC, MVT::i1, MVT::i32); 146a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 147a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // MBlaze Custom Operations 148a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 149a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); 150a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::JumpTable, MVT::i32, Custom); 151a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 152a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 153c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // Variable Argument support 154c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck setOperationAction(ISD::VASTART, MVT::Other, Custom); 155c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck setOperationAction(ISD::VAEND, MVT::Other, Expand); 156c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck setOperationAction(ISD::VAARG, MVT::Other, Expand); 157c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck setOperationAction(ISD::VACOPY, MVT::Other, Expand); 158c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 159c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 160a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Operations not directly supported by MBlaze. 161a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); 162a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::BR_JT, MVT::Other, Expand); 1633ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard setOperationAction(ISD::BR_CC, MVT::f32, Expand); 1643ef5383b3537a420c5e2ab3e657c378e5185549dTom Stellard setOperationAction(ISD::BR_CC, MVT::i32, Expand); 165a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); 166a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::ROTL, MVT::i32, Expand); 167a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::ROTR, MVT::i32, Expand); 168a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); 169a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); 170a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); 171a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::CTLZ, MVT::i32, Expand); 17263974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand); 173a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::CTTZ, MVT::i32, Expand); 17463974b2144c87c962effdc0508c27643c8ad98b6Chandler Carruth setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand); 175a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::CTPOP, MVT::i32, Expand); 176a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::BSWAP, MVT::i32, Expand); 177a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 178a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // We don't have line number support yet. 179a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::EH_LABEL, MVT::Other, Expand); 180a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 181a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Use the default for now 182a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 183a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); 184a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 185a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // MBlaze doesn't have extending float->double load/store 186a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand); 187a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setTruncStoreAction(MVT::f64, MVT::f32, Expand); 188a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 189fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman setMinFunctionAlignment(2); 190fc5d305597ea6336d75bd7f3b741e8d57d6a5105Eli Friedman 191a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck setStackPointerRegisterToSaveRestore(MBlaze::R1); 192a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck computeRegisterProperties(); 193a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 194a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 19528b77e968d2b01fc9da724762bd8ddcd80650e32Duncan SandsEVT MBlazeTargetLowering::getSetCCResultType(EVT VT) const { 196a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return MVT::i32; 197a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 198a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 199d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MBlazeTargetLowering::LowerOperation(SDValue Op, 200d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 201a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck switch (Op.getOpcode()) 202a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck { 203a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case ISD::ConstantPool: return LowerConstantPool(Op, DAG); 204a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); 205a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); 206a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case ISD::JumpTable: return LowerJumpTable(Op, DAG); 207a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); 208c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck case ISD::VASTART: return LowerVASTART(Op, DAG); 209a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 210a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return SDValue(); 211a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 212a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 213a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 214a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// Lower helper functions 215a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 216af1d8ca44a18f304f207e209b3bdb94b590f86ffDan GohmanMachineBasicBlock* 217af1d8ca44a18f304f207e209b3bdb94b590f86ffDan GohmanMBlazeTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, 2186b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *MBB) 2196b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck const { 220a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck switch (MI->getOpcode()) { 221bc2198133a1836598b54b943420748e75d5dea94Craig Topper default: llvm_unreachable("Unexpected instr type to insert"); 2226b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 223a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlaze::ShiftRL: 224a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case MBlaze::ShiftRA: 2256b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::ShiftL: 2266b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck return EmitCustomShift(MI, MBB); 2276b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2286b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::Select_FCC: 2296b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::Select_CC: 2306b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck return EmitCustomSelect(MI, MBB); 2316b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2326b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::CAS32: 2336b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::SWP32: 2346b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAA32: 2356b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAS32: 2366b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAD32: 2376b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAO32: 2386b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAX32: 2396b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAN32: 2406b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck return EmitCustomAtomic(MI, MBB); 2416b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2426b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::MEMBARRIER: 2436b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // The Microblaze does not need memory barriers. Just delete the pseudo 2446b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // instruction and finish. 24514152b480d09c7ca912af7c06d00b0ff3912e4f5Dan Gohman MI->eraseFromParent(); 2466b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck return MBB; 2476b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck } 2486b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck} 2496b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2506b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley PeckMachineBasicBlock* 2516b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley PeckMBlazeTargetLowering::EmitCustomShift(MachineInstr *MI, 2526b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *MBB) const { 2536b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 2546b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck DebugLoc dl = MI->getDebugLoc(); 2556b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2566b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // To "insert" a shift left instruction, we actually have to insert a 2576b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // simple loop. The incoming instruction knows the destination vreg to 2586b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // set, the source vreg to operate over and the shift amount. 2596b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck const BasicBlock *LLVM_BB = MBB->getBasicBlock(); 2606b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineFunction::iterator It = MBB; 2616b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck ++It; 2626b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2636b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // start: 2646b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // andi samt, samt, 31 2656b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // beqid samt, finish 2666b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // add dst, src, r0 2676b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // loop: 2686b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // addik samt, samt, -1 2696b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // sra dst, dst 2706b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // bneid samt, loop 2716b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // nop 2726b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // finish: 2736b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineFunction *F = MBB->getParent(); 2746b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineRegisterInfo &R = F->getRegInfo(); 2756b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *loop = F->CreateMachineBasicBlock(LLVM_BB); 2766b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *finish = F->CreateMachineBasicBlock(LLVM_BB); 2776b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck F->insert(It, loop); 2786b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck F->insert(It, finish); 2796b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2807a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Update machine-CFG edges by transferring adding all successors and 2816b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // remaining instructions from the current block to the new block which 2826b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // will contain the Phi node for the select. 2836b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck finish->splice(finish->begin(), MBB, 2846b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck llvm::next(MachineBasicBlock::iterator(MI)), 2856b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MBB->end()); 2866b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck finish->transferSuccessorsAndUpdatePHIs(MBB); 2876b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2886b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // Add the true and fallthrough blocks as its successors. 2896b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MBB->addSuccessor(loop); 2906b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MBB->addSuccessor(finish); 2916b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 2926b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // Next, add the finish block as a successor of the loop block 2936b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck loop->addSuccessor(finish); 2946b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck loop->addSuccessor(loop); 2956b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 296420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned IAMT = R.createVirtualRegister(&MBlaze::GPRRegClass); 2976b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(MBB, dl, TII->get(MBlaze::ANDI), IAMT) 2986b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(2).getReg()) 2996b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addImm(31); 3006b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 301420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned IVAL = R.createVirtualRegister(&MBlaze::GPRRegClass); 3026b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(MBB, dl, TII->get(MBlaze::ADDIK), IVAL) 3036b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(1).getReg()) 3046b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addImm(0); 3056b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3066b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(MBB, dl, TII->get(MBlaze::BEQID)) 3076b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(IAMT) 3086b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addMBB(finish); 3096b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 310420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned DST = R.createVirtualRegister(&MBlaze::GPRRegClass); 311420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned NDST = R.createVirtualRegister(&MBlaze::GPRRegClass); 3126b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(loop, dl, TII->get(MBlaze::PHI), DST) 3136b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(IVAL).addMBB(MBB) 3146b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(NDST).addMBB(loop); 3156b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 316420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned SAMT = R.createVirtualRegister(&MBlaze::GPRRegClass); 317420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned NAMT = R.createVirtualRegister(&MBlaze::GPRRegClass); 3186b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(loop, dl, TII->get(MBlaze::PHI), SAMT) 3196b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(IAMT).addMBB(MBB) 3206b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(NAMT).addMBB(loop); 3216b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3226b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck if (MI->getOpcode() == MBlaze::ShiftL) 3236b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(loop, dl, TII->get(MBlaze::ADD), NDST).addReg(DST).addReg(DST); 3246b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck else if (MI->getOpcode() == MBlaze::ShiftRA) 3256b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(loop, dl, TII->get(MBlaze::SRA), NDST).addReg(DST); 3266b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck else if (MI->getOpcode() == MBlaze::ShiftRL) 3276b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST); 3286b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck else 3296b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck llvm_unreachable("Cannot lower unknown shift instruction"); 3306b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3316b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(loop, dl, TII->get(MBlaze::ADDIK), NAMT) 3326b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(SAMT) 3336b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addImm(-1); 3346b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3356b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(loop, dl, TII->get(MBlaze::BNEID)) 3366b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(NAMT) 3376b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addMBB(loop); 3386b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3396b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(*finish, finish->begin(), dl, 3406b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) 3416b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(IVAL).addMBB(MBB) 3426b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(NDST).addMBB(loop); 3436b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3446b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // The pseudo instruction is no longer needed so remove it 3456b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MI->eraseFromParent(); 3466b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck return finish; 3476b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck} 3486b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3496b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley PeckMachineBasicBlock* 3506b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley PeckMBlazeTargetLowering::EmitCustomSelect(MachineInstr *MI, 3516b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *MBB) const { 3526b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 3536b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck DebugLoc dl = MI->getDebugLoc(); 3546b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3556b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // To "insert" a SELECT_CC instruction, we actually have to insert the 3566b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // diamond control-flow pattern. The incoming instruction knows the 3576b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // destination vreg to set, the condition code register to branch on, the 3586b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // true/false values to select between, and a branch opcode to use. 3596b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck const BasicBlock *LLVM_BB = MBB->getBasicBlock(); 3606b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineFunction::iterator It = MBB; 3616b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck ++It; 3626b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3636b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // thisMBB: 3646b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // ... 3656b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // TrueVal = ... 3666b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // setcc r1, r2, r3 3676b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // bNE r1, r0, copy1MBB 3686b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // fallthrough --> copy0MBB 3696b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineFunction *F = MBB->getParent(); 3706b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *flsBB = F->CreateMachineBasicBlock(LLVM_BB); 3716b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *dneBB = F->CreateMachineBasicBlock(LLVM_BB); 3726b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3736b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck unsigned Opc; 3746b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck switch (MI->getOperand(4).getImm()) { 3756b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck default: llvm_unreachable("Unknown branch condition"); 3766b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlazeCC::EQ: Opc = MBlaze::BEQID; break; 3776b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlazeCC::NE: Opc = MBlaze::BNEID; break; 3786b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlazeCC::GT: Opc = MBlaze::BGTID; break; 3796b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlazeCC::LT: Opc = MBlaze::BLTID; break; 3806b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlazeCC::GE: Opc = MBlaze::BGEID; break; 3816b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlazeCC::LE: Opc = MBlaze::BLEID; break; 3826b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck } 3836b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3846b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck F->insert(It, flsBB); 3856b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck F->insert(It, dneBB); 3866b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3876b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // Transfer the remainder of MBB and its successor edges to dneBB. 3886b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck dneBB->splice(dneBB->begin(), MBB, 3896b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck llvm::next(MachineBasicBlock::iterator(MI)), 3906b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MBB->end()); 3916b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck dneBB->transferSuccessorsAndUpdatePHIs(MBB); 3926b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3936b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MBB->addSuccessor(flsBB); 3946b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MBB->addSuccessor(dneBB); 3956b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck flsBB->addSuccessor(dneBB); 3966b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 3976b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(MBB, dl, TII->get(Opc)) 3986b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(3).getReg()) 3996b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addMBB(dneBB); 4006b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4016b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // sinkMBB: 4026b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 4036b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // ... 4046b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck //BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) 4056b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // .addReg(MI->getOperand(1).getReg()).addMBB(flsBB) 4066b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // .addReg(MI->getOperand(2).getReg()).addMBB(BB); 4076b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4086b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(*dneBB, dneBB->begin(), dl, 4096b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck TII->get(MBlaze::PHI), MI->getOperand(0).getReg()) 4106b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(2).getReg()).addMBB(flsBB) 4116b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(1).getReg()).addMBB(MBB); 4126b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4136b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MI->eraseFromParent(); // The pseudo instruction is gone now. 4146b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck return dneBB; 4156b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck} 4166b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4176b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley PeckMachineBasicBlock* 4186b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley PeckMBlazeTargetLowering::EmitCustomAtomic(MachineInstr *MI, 4196b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *MBB) const { 4206b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck const TargetInstrInfo *TII = getTargetMachine().getInstrInfo(); 4216b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck DebugLoc dl = MI->getDebugLoc(); 4226b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4236b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // All atomic instructions on the Microblaze are implemented using the 4246b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // load-linked / store-conditional style atomic instruction sequences. 4256b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // Thus, all operations will look something like the following: 426471e4224809f51652c71f319532697a879a75a0dEric Christopher // 4276b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // start: 4286b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // lwx RV, RP, 0 4296b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // <do stuff> 4306b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // swx RV, RP, 0 4316b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // addic RC, R0, 0 4326b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // bneid RC, start 4336b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // 4346b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // exit: 4356b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // 4366b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // To "insert" a shift left instruction, we actually have to insert a 4376b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // simple loop. The incoming instruction knows the destination vreg to 4386b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // set, the source vreg to operate over and the shift amount. 4396b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck const BasicBlock *LLVM_BB = MBB->getBasicBlock(); 4406b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineFunction::iterator It = MBB; 4416b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck ++It; 4426b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4436b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // start: 4446b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // andi samt, samt, 31 4456b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // beqid samt, finish 4466b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // add dst, src, r0 4476b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // loop: 4486b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // addik samt, samt, -1 4496b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // sra dst, dst 4506b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // bneid samt, loop 4516b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // nop 4526b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // finish: 4536b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineFunction *F = MBB->getParent(); 4546b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineRegisterInfo &R = F->getRegInfo(); 4556b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4566b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // Create the start and exit basic blocks for the atomic operation 4576b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *start = F->CreateMachineBasicBlock(LLVM_BB); 4586b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *exit = F->CreateMachineBasicBlock(LLVM_BB); 4596b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck F->insert(It, start); 4606b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck F->insert(It, exit); 4616b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4627a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // Update machine-CFG edges by transferring adding all successors and 4636b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // remaining instructions from the current block to the new block which 4646b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // will contain the Phi node for the select. 4656b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck exit->splice(exit->begin(), MBB, llvm::next(MachineBasicBlock::iterator(MI)), 4666b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MBB->end()); 4676b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck exit->transferSuccessorsAndUpdatePHIs(MBB); 4686b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4696b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // Add the fallthrough block as its successors. 4706b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MBB->addSuccessor(start); 4716b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4726b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(start, dl, TII->get(MBlaze::LWX), MI->getOperand(0).getReg()) 4736b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(1).getReg()) 4746b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MBlaze::R0); 4756b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4766b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MachineBasicBlock *final = start; 4776b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck unsigned finalReg = 0; 4786b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4796b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck switch (MI->getOpcode()) { 4806b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck default: llvm_unreachable("Cannot lower unknown atomic instruction!"); 4816b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4826b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::SWP32: 4836b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck finalReg = MI->getOperand(2).getReg(); 4846b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck start->addSuccessor(exit); 4856b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck start->addSuccessor(start); 4866b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck break; 4876b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 4886b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAN32: 4896b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAX32: 4906b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAO32: 4916b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAD32: 4926b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAS32: 4936b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAA32: { 4946b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck unsigned opcode = 0; 4956b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck switch (MI->getOpcode()) { 4966b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck default: llvm_unreachable("Cannot lower unknown atomic load!"); 4976b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAA32: opcode = MBlaze::ADDIK; break; 4986b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAS32: opcode = MBlaze::RSUBIK; break; 4996b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAD32: opcode = MBlaze::AND; break; 5006b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAO32: opcode = MBlaze::OR; break; 5016b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAX32: opcode = MBlaze::XOR; break; 5026b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::LAN32: opcode = MBlaze::AND; break; 503a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 504a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 505420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper finalReg = R.createVirtualRegister(&MBlaze::GPRRegClass); 5066b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck start->addSuccessor(exit); 5076b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck start->addSuccessor(start); 5086b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 5096b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(start, dl, TII->get(opcode), finalReg) 5106b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(0).getReg()) 5116b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(2).getReg()); 5126b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 5136b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck if (MI->getOpcode() == MBlaze::LAN32) { 5146b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck unsigned tmp = finalReg; 515420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper finalReg = R.createVirtualRegister(&MBlaze::GPRRegClass); 5166b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(start, dl, TII->get(MBlaze::XORI), finalReg) 5176b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(tmp) 5186b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addImm(-1); 519a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 5206b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck break; 5216b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck } 5226b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 5236b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck case MBlaze::CAS32: { 5246b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck finalReg = MI->getOperand(3).getReg(); 5256b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck final = F->CreateMachineBasicBlock(LLVM_BB); 5266b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 5276b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck F->insert(It, final); 5286b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck start->addSuccessor(exit); 5296b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck start->addSuccessor(final); 5306b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck final->addSuccessor(exit); 5316b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck final->addSuccessor(start); 5326b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 533420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned CMP = R.createVirtualRegister(&MBlaze::GPRRegClass); 5346b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(start, dl, TII->get(MBlaze::CMP), CMP) 5356b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(0).getReg()) 5366b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(2).getReg()); 537a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 5386b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(start, dl, TII->get(MBlaze::BNEID)) 5396b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(CMP) 5406b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addMBB(exit); 5416b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 5426b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck final->moveAfter(start); 5436b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck exit->moveAfter(final); 5446b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck break; 545a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 546a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 5476b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 548420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper unsigned CHK = R.createVirtualRegister(&MBlaze::GPRRegClass); 5496b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(final, dl, TII->get(MBlaze::SWX)) 5506b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(finalReg) 5516b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MI->getOperand(1).getReg()) 5526b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MBlaze::R0); 5536b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 5546b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(final, dl, TII->get(MBlaze::ADDIC), CHK) 5556b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(MBlaze::R0) 5566b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addImm(0); 5576b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 5586b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck BuildMI(final, dl, TII->get(MBlaze::BNEID)) 5596b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addReg(CHK) 5606b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck .addMBB(start); 5616b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck 5626b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck // The pseudo instruction is no longer needed so remove it 5636b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck MI->eraseFromParent(); 5646b3bbb149f6a49c9ad9f763c353bc6e7b5c864a1Wesley Peck return exit; 565a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 566a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 567a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 568a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// Misc Lower Operation implementation 569a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 570a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 571a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 572d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MBlazeTargetLowering::LowerSELECT_CC(SDValue Op, 573d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 574a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue LHS = Op.getOperand(0); 575a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue RHS = Op.getOperand(1); 576a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue TrueVal = Op.getOperand(2); 577a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue FalseVal = Op.getOperand(3); 578a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DebugLoc dl = Op.getDebugLoc(); 579a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned Opc; 580a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 581a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue CompareFlag; 582a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (LHS.getValueType() == MVT::i32) { 583a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Opc = MBlazeISD::Select_CC; 584a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck CompareFlag = DAG.getNode(MBlazeISD::ICmp, dl, MVT::i32, LHS, RHS) 585a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck .getValue(1); 586a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } else { 5870a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck llvm_unreachable("Cannot lower select_cc with unknown type"); 588a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 5890a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck 590a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal, 591a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck CompareFlag); 592a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 593a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 594a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDValue MBlazeTargetLowering:: 595d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanLowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const { 596a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // FIXME there isn't actually debug info here 597a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DebugLoc dl = Op.getDebugLoc(); 59846510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 5990d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32); 600a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 601a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, GA); 602a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 603a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 604a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDValue MBlazeTargetLowering:: 605d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanLowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const { 606a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck llvm_unreachable("TLS not implemented for MicroBlaze."); 607a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 608a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 609a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDValue MBlazeTargetLowering:: 610d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanLowerJumpTable(SDValue Op, SelectionDAG &DAG) const { 611a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue ResNode; 612a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue HiPart; 613a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // FIXME there isn't actually debug info here 614a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DebugLoc dl = Op.getDebugLoc(); 615a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 616a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck EVT PtrVT = Op.getValueType(); 617a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); 618a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 6190a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, 0); 620a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, JTI); 621a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 622a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 623a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDValue MBlazeTargetLowering:: 624d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanLowerConstantPool(SDValue Op, SelectionDAG &DAG) const { 625a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue ResNode; 626a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op); 62746510a73e977273ec67747eb34cbdb43f815e451Dan Gohman const Constant *C = N->getConstVal(); 628a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DebugLoc dl = Op.getDebugLoc(); 629a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 630a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), 6310a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck N->getOffset(), 0); 632a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, CP); 633a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 634a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 635d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan GohmanSDValue MBlazeTargetLowering::LowerVASTART(SDValue Op, 636d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SelectionDAG &DAG) const { 6371e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman MachineFunction &MF = DAG.getMachineFunction(); 6381e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman MBlazeFunctionInfo *FuncInfo = MF.getInfo<MBlazeFunctionInfo>(); 6391e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman 640c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck DebugLoc dl = Op.getDebugLoc(); 6411e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), 6421e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman getPointerTy()); 643c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 644c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // vastart just stores the address of the VarArgsFrameIndex slot into the 645c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // memory location argument. 646c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue(); 6478026a9d3eef3ae30d4ec16a17b7d60d287ddf25dChris Lattner return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1), 6488026a9d3eef3ae30d4ec16a17b7d60d287ddf25dChris Lattner MachinePointerInfo(SV), 649c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck false, false, 0); 650c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck} 651c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 652a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 653a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// Calling Convention Implementation 654a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 655a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 656a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeGenCallingConv.inc" 657a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 6588397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peckstatic bool CC_MBlaze_AssignReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, 6598397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck CCValAssign::LocInfo &LocInfo, 6608397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck ISD::ArgFlagsTy &ArgFlags, 6618397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck CCState &State) { 662c5eaae4e9bc75b203b3a9922b480729bc4f340e2Craig Topper static const uint16_t ArgRegs[] = { 663c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck MBlaze::R5, MBlaze::R6, MBlaze::R7, 664c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck MBlaze::R8, MBlaze::R9, MBlaze::R10 665c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck }; 666c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 6678397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck const unsigned NumArgRegs = array_lengthof(ArgRegs); 6688397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck unsigned Reg = State.AllocateReg(ArgRegs, NumArgRegs); 6698397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck if (!Reg) return false; 670c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 6718397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck unsigned SizeInBytes = ValVT.getSizeInBits() >> 3; 6728397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck State.AllocateStack(SizeInBytes, SizeInBytes); 6738397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); 674c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 6758397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck return true; 676c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck} 677c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 678a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 679a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// Call Calling Convention Implementation 680a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 681a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 682a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// LowerCall - functions arguments are copied from virtual regs to 683a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. 684a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// TODO: isVarArg, isTailCall. 685a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDValue MBlazeTargetLowering:: 686d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin HolewinskiLowerCall(TargetLowering::CallLoweringInfo &CLI, 687d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 688d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SelectionDAG &DAG = CLI.DAG; 689d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski DebugLoc &dl = CLI.DL; 690d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<ISD::OutputArg, 32> &Outs = CLI.Outs; 691d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<SDValue, 32> &OutVals = CLI.OutVals; 692d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SmallVector<ISD::InputArg, 32> &Ins = CLI.Ins; 693d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Chain = CLI.Chain; 694d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski SDValue Callee = CLI.Callee; 695d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool &isTailCall = CLI.IsTailCall; 696d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski CallingConv::ID CallConv = CLI.CallConv; 697d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski bool isVarArg = CLI.IsVarArg; 698d2ea0e10cbd158c93fb870cdd03001b9cd1156b8Justin Holewinski 699c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // MBlaze does not yet support tail call optimization 700c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck isTailCall = false; 701c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 7028397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck // The MBlaze requires stack slots for arguments passed to var arg 7038397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck // functions even if they are passed in registers. 7048397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck bool needsRegArgSlots = isVarArg; 7058397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 706a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MachineFunction &MF = DAG.getMachineFunction(); 707a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 70816c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov const TargetFrameLowering &TFI = *MF.getTarget().getFrameLowering(); 709a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 710a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Analyze operands of the call, assigning locations to each operand. 711a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SmallVector<CCValAssign, 16> ArgLocs; 712471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 71356cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 7148397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck CCInfo.AnalyzeCallOperands(Outs, CC_MBlaze); 715a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 716a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Get a count of how many bytes are to be pushed on the stack. 717a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned NumBytes = CCInfo.getNextStackOffset(); 7188397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 7198397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck // Variable argument function calls require a minimum of 24-bytes of stack 7208397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck if (isVarArg && NumBytes < 24) NumBytes = 24; 7218397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 722a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true)); 723a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 724a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass; 725a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SmallVector<SDValue, 8> MemOpChains; 726a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 727a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Walk the register/memloc assignments, inserting copies/loads. 728a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 729a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck CCValAssign &VA = ArgLocs[i]; 7301e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sands MVT RegVT = VA.getLocVT(); 731c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman SDValue Arg = OutVals[i]; 732a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 733a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Promote the value if needed. 734a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck switch (VA.getLocInfo()) { 735a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck default: llvm_unreachable("Unknown loc info!"); 736a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case CCValAssign::Full: break; 737a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case CCValAssign::SExt: 738a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, RegVT, Arg); 739a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck break; 740a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case CCValAssign::ZExt: 741a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, RegVT, Arg); 742a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck break; 743a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case CCValAssign::AExt: 744a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Arg = DAG.getNode(ISD::ANY_EXTEND, dl, RegVT, Arg); 745a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck break; 746a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 747a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 748a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Arguments that can be passed on register must be kept at 749a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // RegsToPass vector 750a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (VA.isRegLoc()) { 751a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg)); 752a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } else { 753a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Register can't get to this point... 754a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck assert(VA.isMemLoc()); 755a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 7568397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck // Since we are alread passing values on the stack we don't 7578397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck // need to worry about creating additional slots for the 7588397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck // values passed via registers. 7598397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck needsRegArgSlots = false; 7608397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 761a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Create the frame index object for this incoming parameter 7628397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck unsigned ArgSize = VA.getValVT().getSizeInBits()/8; 7638397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck unsigned StackLoc = VA.getLocMemOffset() + 4; 7648397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck int FI = MFI->CreateFixedObject(ArgSize, StackLoc, true); 765a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 766a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue PtrOff = DAG.getFrameIndex(FI,getPointerTy()); 767a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 768a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // emit ISD::STORE whichs stores the 769a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // parameter value to a stack Location 7708026a9d3eef3ae30d4ec16a17b7d60d287ddf25dChris Lattner MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, 7718026a9d3eef3ae30d4ec16a17b7d60d287ddf25dChris Lattner MachinePointerInfo(), 772a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck false, false, 0)); 773a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 774a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 775a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 7768397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck // If we need to reserve stack space for the arguments passed via registers 7778397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck // then create a fixed stack object at the beginning of the stack. 7788397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck if (needsRegArgSlots && TFI.hasReservedCallFrame(MF)) 7798397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MFI->CreateFixedObject(28,0,true); 7808397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck 781a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Transform all store nodes into one single node because all store 782a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // nodes are independent of each other. 783a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (!MemOpChains.empty()) 784a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 785a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck &MemOpChains[0], MemOpChains.size()); 786a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 787a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Build a sequence of copy-to-reg nodes chained together with token 788a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // chain and flag operands which copy the outgoing args into registers. 7897a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // The InFlag in necessary since all emitted instructions must be 790a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // stuck together. 791a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue InFlag; 792a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 793a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, 794a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck RegsToPass[i].second, InFlag); 795a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck InFlag = Chain.getValue(1); 796a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 797a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 798a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every 799a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol 800a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // node so that legalize doesn't hack it. 801a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 8020d881dabc1a4e1aefad6dd38de166d8358285638Devang Patel Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, 8030a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck getPointerTy(), 0, 0); 804a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) 805a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Callee = DAG.getTargetExternalSymbol(S->getSymbol(), 8060a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck getPointerTy(), 0); 807a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 808a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // MBlazeJmpLink = #chain, #target_address, #opt_in_flags... 809a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // = Chain, Callee, Reg#1, Reg#2, ... 810a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // 811a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Returns a chain & a flag for retval copy to use. 812f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); 813a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SmallVector<SDValue, 8> Ops; 814a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Ops.push_back(Chain); 815a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Ops.push_back(Callee); 816a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 817a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Add argument registers to the end of the list so that they are 818a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // known live into the call. 819a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 820a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Ops.push_back(DAG.getRegister(RegsToPass[i].first, 821a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck RegsToPass[i].second.getValueType())); 822a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 823a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 824a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (InFlag.getNode()) 825a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Ops.push_back(InFlag); 826a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 827a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = DAG.getNode(MBlazeISD::JmpLink, dl, NodeTys, &Ops[0], Ops.size()); 828a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck InFlag = Chain.getValue(1); 829a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 830a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Create the CALLSEQ_END node. 831a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), 832a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DAG.getIntPtrConstant(0, true), InFlag); 833a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (!Ins.empty()) 834a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck InFlag = Chain.getValue(1); 835a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 836a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Handle result values, copying them out of physregs into vregs that we 837a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // return. 838a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return LowerCallResult(Chain, InFlag, CallConv, isVarArg, 839a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Ins, dl, DAG, InVals); 840a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 841a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 842a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// LowerCallResult - Lower the result values of a call into the 843a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// appropriate copies out of appropriate physical registers. 844a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDValue MBlazeTargetLowering:: 845a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckLowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, 846a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, 847a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DebugLoc dl, SelectionDAG &DAG, 848d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 849a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Assign locations to each value returned by this call. 850a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SmallVector<CCValAssign, 16> RVLocs; 851471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 85256cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), RVLocs, *DAG.getContext()); 853a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 854a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck CCInfo.AnalyzeCallResult(Ins, RetCC_MBlaze); 855a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 856a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Copy all of the result registers out of their specified physreg. 857a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck for (unsigned i = 0; i != RVLocs.size(); ++i) { 858a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), 859a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck RVLocs[i].getValVT(), InFlag).getValue(1); 860a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck InFlag = Chain.getValue(2); 861a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck InVals.push_back(Chain.getValue(0)); 8620a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck } 863a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 864a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return Chain; 865a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 866a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 867a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 868a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// Formal Arguments Calling Convention Implementation 869a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 870a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 871a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// LowerFormalArguments - transform physical registers into 872a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// virtual registers and generate load operations for 873a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// arguments places on the stack. 874a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDValue MBlazeTargetLowering:: 875a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckLowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 876a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck const SmallVectorImpl<ISD::InputArg> &Ins, 877a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DebugLoc dl, SelectionDAG &DAG, 878d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman SmallVectorImpl<SDValue> &InVals) const { 879a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MachineFunction &MF = DAG.getMachineFunction(); 880a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MachineFrameInfo *MFI = MF.getFrameInfo(); 881a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MBlazeFunctionInfo *MBlazeFI = MF.getInfo<MBlazeFunctionInfo>(); 882a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 883a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF); 8841e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman MBlazeFI->setVarArgsFrameIndex(0); 885c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 886c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // Used with vargs to acumulate store chains. 887c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck std::vector<SDValue> OutChains; 888c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 889c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // Keep track of the last register used for arguments 890c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck unsigned ArgRegEnd = 0; 891a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 892a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Assign locations to all of the incoming arguments. 893a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SmallVector<CCValAssign, 16> ArgLocs; 894471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 89556cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), ArgLocs, *DAG.getContext()); 896a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 8978397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck CCInfo.AnalyzeFormalArguments(Ins, CC_MBlaze); 898a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue StackPtr; 899a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 900a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { 901a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck CCValAssign &VA = ArgLocs[i]; 902a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 903a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Arguments stored on registers 904a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (VA.isRegLoc()) { 9051e96bab329eb23e4ce8a0dc3cc6b33a3f03d15bfDuncan Sands MVT RegVT = VA.getLocVT(); 906c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck ArgRegEnd = VA.getLocReg(); 90744d23825d61d530b8d562329ec8fc2d4f843bb8dCraig Topper const TargetRegisterClass *RC; 908a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 909a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (RegVT == MVT::i32) 910420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MBlaze::GPRRegClass; 911a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck else if (RegVT == MVT::f32) 912420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper RC = &MBlaze::GPRRegClass; 913a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck else 914a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck llvm_unreachable("RegVT not supported by LowerFormalArguments"); 915a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 916a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Transform the arguments stored on 917a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // physical registers into virtual ones 91868e6beeccc0b9ac2e8d3687a8a5b7d4b172edca1Devang Patel unsigned Reg = MF.addLiveIn(ArgRegEnd, RC); 919a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT); 920a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 921a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // If this is an 8 or 16-bit value, it has been passed promoted 922a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // to 32 bits. Insert an assert[sz]ext to capture this, then 923c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // truncate to the right size. If if is a floating point value 924c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // then convert to the correct type. 925a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (VA.getLocInfo() != CCValAssign::Full) { 926a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned Opcode = 0; 927a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (VA.getLocInfo() == CCValAssign::SExt) 928a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Opcode = ISD::AssertSext; 929a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck else if (VA.getLocInfo() == CCValAssign::ZExt) 930a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Opcode = ISD::AssertZext; 931a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (Opcode) 932a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck ArgValue = DAG.getNode(Opcode, dl, RegVT, ArgValue, 933a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck DAG.getValueType(VA.getValVT())); 934a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); 935a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 936a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 937a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck InVals.push_back(ArgValue); 938a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } else { // VA.isRegLoc() 939a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // sanity check 940a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck assert(VA.isMemLoc()); 941a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 942c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // The last argument is not a register 943c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck ArgRegEnd = 0; 944c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 945a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // The stack pointer offset is relative to the caller stack frame. 946a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Since the real stack size is unknown here, a negative SPOffset 947a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // is used so there's a way to adjust these offsets when the stack 948a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // size get known (on EliminateFrameIndex). A dummy SPOffset is 949a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // used instead of a direct negative address (which is recorded to 950a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // be used on emitPrologue) to avoid mis-calc of the first stack 951a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // offset on PEI::calculateFrameObjectOffsets. 952a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Arguments are always 32-bit. 953a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned ArgSize = VA.getLocVT().getSizeInBits()/8; 9548397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck unsigned StackLoc = VA.getLocMemOffset() + 4; 955ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng int FI = MFI->CreateFixedObject(ArgSize, 0, true); 9568397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFI->recordLoadArgsFI(FI, -StackLoc); 957eb1338233399dec17c4a7b88f5ec2866606d4bb0Wesley Peck MBlazeFI->recordLiveIn(FI); 958a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 959a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Create load nodes to retrieve arguments from the stack 960a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue FIN = DAG.getFrameIndex(FI, getPointerTy()); 961d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, 962d1c24ed81c43635d00ff099844a9d0614021a72bChris Lattner MachinePointerInfo::getFixedStack(FI), 963d752e0f7e64585839cb3a458ef52456eaebbea3cPete Cooper false, false, false, 0)); 964a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 965a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 966a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 967c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // To meet ABI, when VARARGS are passed on registers, the registers 968c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // must have their values written to the caller stack frame. If the last 9690a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck // argument was placed in the stack, there's no need to save any register. 970c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck if ((isVarArg) && ArgRegEnd) { 971c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck if (StackPtr.getNode() == 0) 972c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck StackPtr = DAG.getRegister(StackReg, getPointerTy()); 973c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 974c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // The last register argument that must be saved is MBlaze::R10 975420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper const TargetRegisterClass *RC = &MBlaze::GPRRegClass; 976c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 9778cb2d61bce5950df8e3b8dec481b88fb2eaa66d0Evan Cheng unsigned Begin = getMBlazeRegisterNumbering(MBlaze::R5); 9788cb2d61bce5950df8e3b8dec481b88fb2eaa66d0Evan Cheng unsigned Start = getMBlazeRegisterNumbering(ArgRegEnd+1); 9798cb2d61bce5950df8e3b8dec481b88fb2eaa66d0Evan Cheng unsigned End = getMBlazeRegisterNumbering(MBlaze::R10); 9808397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck unsigned StackLoc = Start - Begin + 1; 981c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 982c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck for (; Start <= End; ++Start, ++StackLoc) { 983617793d1d6fa28eb47d4fc04d265a6eace6c758cEvan Cheng unsigned Reg = getMBlazeRegisterFromNumbering(Start); 98468e6beeccc0b9ac2e8d3687a8a5b7d4b172edca1Devang Patel unsigned LiveReg = MF.addLiveIn(Reg, RC); 985c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, LiveReg, MVT::i32); 986c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 987ed2ae136d29dd36122d2476801e7d7a86e8301e3Evan Cheng int FI = MFI->CreateFixedObject(4, 0, true); 9888397be042766f1913ceaa2b3e6782de0322bbe6aWesley Peck MBlazeFI->recordStoreVarArgsFI(FI, -(StackLoc*4)); 989c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy()); 9908026a9d3eef3ae30d4ec16a17b7d60d287ddf25dChris Lattner OutChains.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, 9918026a9d3eef3ae30d4ec16a17b7d60d287ddf25dChris Lattner MachinePointerInfo(), 992c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck false, false, 0)); 993c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 994c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // Record the frame index of the first variable argument 995c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // which is a value necessary to VASTART. 9961e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman if (!MBlazeFI->getVarArgsFrameIndex()) 9971e93df6f0b5ee6e36d7ec18e6035f0f5a53e5ec6Dan Gohman MBlazeFI->setVarArgsFrameIndex(FI); 998c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck } 999c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck } 1000c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 10010a67d92938d77b6a8cde6e1676750264b274cebcWesley Peck // All stores are grouped in one node to allow the matching between 1002c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck // the size of Ins and InVals. This only happens when on varg functions 1003c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck if (!OutChains.empty()) { 1004c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck OutChains.push_back(Chain); 1005c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1006c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck &OutChains[0], OutChains.size()); 1007c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck } 1008c2bf2bbe93c7ce44bedc8485cc24927423404835Wesley Peck 1009a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return Chain; 1010a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 1011a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1012a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 1013a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// Return Value Calling Convention Implementation 1014a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 1015a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1016a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckSDValue MBlazeTargetLowering:: 1017a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckLowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, 1018a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck const SmallVectorImpl<ISD::OutputArg> &Outs, 1019c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman const SmallVectorImpl<SDValue> &OutVals, 1020d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman DebugLoc dl, SelectionDAG &DAG) const { 1021a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // CCValAssign - represent the assignment of 1022a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // the return value to a location 1023a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SmallVector<CCValAssign, 16> RVLocs; 1024a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1025a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // CCState - Info about the registers and stack slot. 1026471e4224809f51652c71f319532697a879a75a0dEric Christopher CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(), 102756cb2298663017eb77aa4f4dda8db7ecd1b58173Bill Wendling getTargetMachine(), RVLocs, *DAG.getContext()); 1028a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1029a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Analize return values. 1030a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck CCInfo.AnalyzeReturn(Outs, RetCC_MBlaze); 1031a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1032a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck SDValue Flag; 1033f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen SmallVector<SDValue, 4> RetOps(1, Chain); 1034f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen 1035f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen // If this function is using the interrupt_handler calling convention 1036f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen // then use "rtid r14, 0" otherwise use "rtsd r15, 8" 1037f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen unsigned Ret = (CallConv == CallingConv::MBLAZE_INTR) ? MBlazeISD::IRet 1038f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen : MBlazeISD::Ret; 1039f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen unsigned Reg = (CallConv == CallingConv::MBLAZE_INTR) ? MBlaze::R14 1040f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen : MBlaze::R15; 1041f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen RetOps.push_back(DAG.getRegister(Reg, MVT::i32)); 1042f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen 1043a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1044a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Copy the result values into the output registers. 1045a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck for (unsigned i = 0; i != RVLocs.size(); ++i) { 1046a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck CCValAssign &VA = RVLocs[i]; 1047a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck assert(VA.isRegLoc() && "Can only return in registers!"); 1048a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1049a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), 1050c9403659a98bf6487ab6fbf40b81628b5695c02eDan Gohman OutVals[i], Flag); 1051a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1052a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // guarantee that all emitted copies are 1053a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // stuck together, avoiding something bad 1054a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck Flag = Chain.getValue(1); 1055f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT())); 1056a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 1057a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1058f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen RetOps[0] = Chain; // Update chain. 1059dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 1060f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen // Add the flag if we have it. 1061a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (Flag.getNode()) 1062f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen RetOps.push_back(Flag); 1063dc9d87a9bbb5bc2ddaad7ab0db4aed82d88636c6Wesley Peck 1064f02138e6ec475dc0a3c0e6f664a068db3dc2c214Jakob Stoklund Olesen return DAG.getNode(Ret, dl, MVT::Other, &RetOps[0], RetOps.size()); 1065a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 1066a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1067a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 1068a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// MBlaze Inline Assembly Support 1069a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 1070a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1071a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// getConstraintType - Given a constraint letter, return the type of 1072a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// constraint it is for this target. 1073a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckMBlazeTargetLowering::ConstraintType MBlazeTargetLowering:: 1074a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckgetConstraintType(const std::string &Constraint) const 1075a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck{ 1076a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // MBlaze specific constrainy 1077a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // 1078a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // 'd' : An address register. Equivalent to r. 1079a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // 'y' : Equivalent to r; retained for 1080a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // backwards compatibility. 1081a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // 'f' : Floating Point registers. 1082a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (Constraint.size() == 1) { 1083a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck switch (Constraint[0]) { 1084a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck default : break; 1085a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case 'd': 1086a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case 'y': 1087a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case 'f': 1088a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return C_RegisterClass; 1089a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 1090a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 1091a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return TargetLowering::getConstraintType(Constraint); 1092a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 1093a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 109444ab89eb376af838d1123293a79975aede501464John Thompson/// Examine constraint type and operand type and determine a weight value. 109544ab89eb376af838d1123293a79975aede501464John Thompson/// This object must already have been set up with the operand type 109644ab89eb376af838d1123293a79975aede501464John Thompson/// and the current alternative constraint selected. 109744ab89eb376af838d1123293a79975aede501464John ThompsonTargetLowering::ConstraintWeight 109844ab89eb376af838d1123293a79975aede501464John ThompsonMBlazeTargetLowering::getSingleConstraintMatchWeight( 109944ab89eb376af838d1123293a79975aede501464John Thompson AsmOperandInfo &info, const char *constraint) const { 110044ab89eb376af838d1123293a79975aede501464John Thompson ConstraintWeight weight = CW_Invalid; 110144ab89eb376af838d1123293a79975aede501464John Thompson Value *CallOperandVal = info.CallOperandVal; 110244ab89eb376af838d1123293a79975aede501464John Thompson // If we don't have a value, we can't do a match, 110344ab89eb376af838d1123293a79975aede501464John Thompson // but allow it at the lowest weight. 110444ab89eb376af838d1123293a79975aede501464John Thompson if (CallOperandVal == NULL) 110544ab89eb376af838d1123293a79975aede501464John Thompson return CW_Default; 1106db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *type = CallOperandVal->getType(); 110744ab89eb376af838d1123293a79975aede501464John Thompson // Look at the constraint type. 110844ab89eb376af838d1123293a79975aede501464John Thompson switch (*constraint) { 110944ab89eb376af838d1123293a79975aede501464John Thompson default: 111044ab89eb376af838d1123293a79975aede501464John Thompson weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint); 1111a4a2a03c311e7a7b64bfba1ae714ae85f74999fdChandler Carruth break; 1112bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck case 'd': 1113bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck case 'y': 111444ab89eb376af838d1123293a79975aede501464John Thompson if (type->isIntegerTy()) 111544ab89eb376af838d1123293a79975aede501464John Thompson weight = CW_Register; 111644ab89eb376af838d1123293a79975aede501464John Thompson break; 111744ab89eb376af838d1123293a79975aede501464John Thompson case 'f': 111844ab89eb376af838d1123293a79975aede501464John Thompson if (type->isFloatTy()) 111944ab89eb376af838d1123293a79975aede501464John Thompson weight = CW_Register; 112044ab89eb376af838d1123293a79975aede501464John Thompson break; 112144ab89eb376af838d1123293a79975aede501464John Thompson } 112244ab89eb376af838d1123293a79975aede501464John Thompson return weight; 112344ab89eb376af838d1123293a79975aede501464John Thompson} 112444ab89eb376af838d1123293a79975aede501464John Thompson 1125193f7e2eb01943900779e51513d6f5e709326dfaEric Christopher/// Given a register class constraint, like 'r', if this corresponds directly 1126193f7e2eb01943900779e51513d6f5e709326dfaEric Christopher/// to an LLVM register class, return a register of 0 and the register class 1127193f7e2eb01943900779e51513d6f5e709326dfaEric Christopher/// pointer. 1128a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckstd::pair<unsigned, const TargetRegisterClass*> MBlazeTargetLowering:: 1129a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckgetRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const { 1130a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (Constraint.size() == 1) { 1131a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck switch (Constraint[0]) { 1132a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case 'r': 1133420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MBlaze::GPRRegClass); 1134193f7e2eb01943900779e51513d6f5e709326dfaEric Christopher // TODO: These can't possibly be right, but match what was in 1135193f7e2eb01943900779e51513d6f5e709326dfaEric Christopher // getRegClassForInlineAsmConstraint. 1136193f7e2eb01943900779e51513d6f5e709326dfaEric Christopher case 'd': 1137193f7e2eb01943900779e51513d6f5e709326dfaEric Christopher case 'y': 1138a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck case 'f': 1139a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (VT == MVT::f32) 1140420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper return std::make_pair(0U, &MBlaze::GPRRegClass); 1141a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 1142a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 1143a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); 1144a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 1145a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1146a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckbool MBlazeTargetLowering:: 1147a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckisOffsetFoldingLegal(const GlobalAddressSDNode *GA) const { 1148a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // The MBlaze target isn't yet aware of offsets. 1149a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return false; 1150a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 1151a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 1152a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckbool MBlazeTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const { 1153a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return VT != MVT::f32; 1154a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 1155