5281 lines · cpp
1//===- MipsISelLowering.cpp - Mips DAG Lowering Implementation ------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines the interfaces that Mips uses to lower LLVM code into a10// selection DAG.11//12//===----------------------------------------------------------------------===//13 14#include "MipsISelLowering.h"15#include "MCTargetDesc/MipsBaseInfo.h"16#include "MCTargetDesc/MipsInstPrinter.h"17#include "MCTargetDesc/MipsMCTargetDesc.h"18#include "MipsCCState.h"19#include "MipsInstrInfo.h"20#include "MipsMachineFunction.h"21#include "MipsRegisterInfo.h"22#include "MipsSubtarget.h"23#include "MipsTargetMachine.h"24#include "MipsTargetObjectFile.h"25#include "llvm/ADT/APFloat.h"26#include "llvm/ADT/ArrayRef.h"27#include "llvm/ADT/SmallVector.h"28#include "llvm/ADT/Statistic.h"29#include "llvm/ADT/StringRef.h"30#include "llvm/ADT/StringSwitch.h"31#include "llvm/CodeGen/CallingConvLower.h"32#include "llvm/CodeGen/FunctionLoweringInfo.h"33#include "llvm/CodeGen/ISDOpcodes.h"34#include "llvm/CodeGen/MachineBasicBlock.h"35#include "llvm/CodeGen/MachineFrameInfo.h"36#include "llvm/CodeGen/MachineFunction.h"37#include "llvm/CodeGen/MachineInstr.h"38#include "llvm/CodeGen/MachineInstrBuilder.h"39#include "llvm/CodeGen/MachineJumpTableInfo.h"40#include "llvm/CodeGen/MachineMemOperand.h"41#include "llvm/CodeGen/MachineOperand.h"42#include "llvm/CodeGen/MachineRegisterInfo.h"43#include "llvm/CodeGen/SelectionDAG.h"44#include "llvm/CodeGen/SelectionDAGNodes.h"45#include "llvm/CodeGen/TargetFrameLowering.h"46#include "llvm/CodeGen/TargetInstrInfo.h"47#include "llvm/CodeGen/TargetRegisterInfo.h"48#include "llvm/CodeGen/ValueTypes.h"49#include "llvm/CodeGenTypes/MachineValueType.h"50#include "llvm/IR/CallingConv.h"51#include "llvm/IR/Constants.h"52#include "llvm/IR/DataLayout.h"53#include "llvm/IR/DebugLoc.h"54#include "llvm/IR/DerivedTypes.h"55#include "llvm/IR/Function.h"56#include "llvm/IR/GlobalValue.h"57#include "llvm/IR/Module.h"58#include "llvm/IR/Type.h"59#include "llvm/IR/Value.h"60#include "llvm/MC/MCContext.h"61#include "llvm/Support/Casting.h"62#include "llvm/Support/CodeGen.h"63#include "llvm/Support/CommandLine.h"64#include "llvm/Support/Compiler.h"65#include "llvm/Support/ErrorHandling.h"66#include "llvm/Support/MathExtras.h"67#include "llvm/Target/TargetMachine.h"68#include "llvm/Target/TargetOptions.h"69#include <algorithm>70#include <cassert>71#include <cctype>72#include <cstdint>73#include <deque>74#include <iterator>75#include <utility>76#include <vector>77 78using namespace llvm;79 80#define DEBUG_TYPE "mips-lower"81 82STATISTIC(NumTailCalls, "Number of tail calls");83 84static cl::opt<bool>85NoZeroDivCheck("mno-check-zero-division", cl::Hidden,86 cl::desc("MIPS: Don't trap on integer division by zero."),87 cl::init(false));88 89extern cl::opt<bool> EmitJalrReloc;90 91static const MCPhysReg Mips64DPRegs[8] = {92 Mips::D12_64, Mips::D13_64, Mips::D14_64, Mips::D15_64,93 Mips::D16_64, Mips::D17_64, Mips::D18_64, Mips::D19_6494};95 96// The MIPS MSA ABI passes vector arguments in the integer register set.97// The number of integer registers used is dependant on the ABI used.98MVT MipsTargetLowering::getRegisterTypeForCallingConv(LLVMContext &Context,99 CallingConv::ID CC,100 EVT VT) const {101 if (!VT.isVector())102 return getRegisterType(Context, VT);103 104 if (VT.isPow2VectorType() && VT.getVectorElementType().isRound())105 return Subtarget.isABI_O32() || VT.getSizeInBits() == 32 ? MVT::i32106 : MVT::i64;107 return getRegisterType(Context, VT.getVectorElementType());108}109 110unsigned MipsTargetLowering::getNumRegistersForCallingConv(LLVMContext &Context,111 CallingConv::ID CC,112 EVT VT) const {113 if (VT.isVector()) {114 if (VT.isPow2VectorType() && VT.getVectorElementType().isRound())115 return divideCeil(VT.getSizeInBits(), Subtarget.isABI_O32() ? 32 : 64);116 return VT.getVectorNumElements() *117 getNumRegisters(Context, VT.getVectorElementType());118 }119 return MipsTargetLowering::getNumRegisters(Context, VT);120}121 122unsigned MipsTargetLowering::getVectorTypeBreakdownForCallingConv(123 LLVMContext &Context, CallingConv::ID CC, EVT VT, EVT &IntermediateVT,124 unsigned &NumIntermediates, MVT &RegisterVT) const {125 if (VT.isPow2VectorType() && VT.getVectorElementType().isRound()) {126 IntermediateVT = getRegisterTypeForCallingConv(Context, CC, VT);127 RegisterVT = IntermediateVT.getSimpleVT();128 NumIntermediates = getNumRegistersForCallingConv(Context, CC, VT);129 return NumIntermediates;130 }131 IntermediateVT = VT.getVectorElementType();132 NumIntermediates = VT.getVectorNumElements();133 RegisterVT = getRegisterType(Context, IntermediateVT);134 return NumIntermediates * getNumRegisters(Context, IntermediateVT);135}136 137SDValue MipsTargetLowering::getGlobalReg(SelectionDAG &DAG, EVT Ty) const {138 MachineFunction &MF = DAG.getMachineFunction();139 MipsFunctionInfo *FI = MF.getInfo<MipsFunctionInfo>();140 return DAG.getRegister(FI->getGlobalBaseReg(MF), Ty);141}142 143SDValue MipsTargetLowering::getTargetNode(GlobalAddressSDNode *N, EVT Ty,144 SelectionDAG &DAG,145 unsigned Flag) const {146 return DAG.getTargetGlobalAddress(N->getGlobal(), SDLoc(N), Ty, 0, Flag);147}148 149SDValue MipsTargetLowering::getTargetNode(ExternalSymbolSDNode *N, EVT Ty,150 SelectionDAG &DAG,151 unsigned Flag) const {152 return DAG.getTargetExternalSymbol(N->getSymbol(), Ty, Flag);153}154 155SDValue MipsTargetLowering::getTargetNode(BlockAddressSDNode *N, EVT Ty,156 SelectionDAG &DAG,157 unsigned Flag) const {158 return DAG.getTargetBlockAddress(N->getBlockAddress(), Ty, 0, Flag);159}160 161SDValue MipsTargetLowering::getTargetNode(JumpTableSDNode *N, EVT Ty,162 SelectionDAG &DAG,163 unsigned Flag) const {164 return DAG.getTargetJumpTable(N->getIndex(), Ty, Flag);165}166 167SDValue MipsTargetLowering::getTargetNode(ConstantPoolSDNode *N, EVT Ty,168 SelectionDAG &DAG,169 unsigned Flag) const {170 return DAG.getTargetConstantPool(N->getConstVal(), Ty, N->getAlign(),171 N->getOffset(), Flag);172}173 174const char *MipsTargetLowering::getTargetNodeName(unsigned Opcode) const {175 switch ((MipsISD::NodeType)Opcode) {176 case MipsISD::FIRST_NUMBER: break;177 case MipsISD::JmpLink: return "MipsISD::JmpLink";178 case MipsISD::TailCall: return "MipsISD::TailCall";179 case MipsISD::Highest: return "MipsISD::Highest";180 case MipsISD::Higher: return "MipsISD::Higher";181 case MipsISD::Hi: return "MipsISD::Hi";182 case MipsISD::Lo: return "MipsISD::Lo";183 case MipsISD::GotHi: return "MipsISD::GotHi";184 case MipsISD::TlsHi: return "MipsISD::TlsHi";185 case MipsISD::GPRel: return "MipsISD::GPRel";186 case MipsISD::ThreadPointer: return "MipsISD::ThreadPointer";187 case MipsISD::Ret: return "MipsISD::Ret";188 case MipsISD::ERet: return "MipsISD::ERet";189 case MipsISD::EH_RETURN: return "MipsISD::EH_RETURN";190 case MipsISD::FAbs: return "MipsISD::FAbs";191 case MipsISD::FMS: return "MipsISD::FMS";192 case MipsISD::FPBrcond: return "MipsISD::FPBrcond";193 case MipsISD::FPCmp: return "MipsISD::FPCmp";194 case MipsISD::FSELECT: return "MipsISD::FSELECT";195 case MipsISD::MTC1_D64: return "MipsISD::MTC1_D64";196 case MipsISD::CMovFP_T: return "MipsISD::CMovFP_T";197 case MipsISD::CMovFP_F: return "MipsISD::CMovFP_F";198 case MipsISD::TruncIntFP: return "MipsISD::TruncIntFP";199 case MipsISD::MFHI: return "MipsISD::MFHI";200 case MipsISD::MFLO: return "MipsISD::MFLO";201 case MipsISD::MTLOHI: return "MipsISD::MTLOHI";202 case MipsISD::Mult: return "MipsISD::Mult";203 case MipsISD::Multu: return "MipsISD::Multu";204 case MipsISD::MAdd: return "MipsISD::MAdd";205 case MipsISD::MAddu: return "MipsISD::MAddu";206 case MipsISD::MSub: return "MipsISD::MSub";207 case MipsISD::MSubu: return "MipsISD::MSubu";208 case MipsISD::DivRem: return "MipsISD::DivRem";209 case MipsISD::DivRemU: return "MipsISD::DivRemU";210 case MipsISD::DivRem16: return "MipsISD::DivRem16";211 case MipsISD::DivRemU16: return "MipsISD::DivRemU16";212 case MipsISD::BuildPairF64: return "MipsISD::BuildPairF64";213 case MipsISD::ExtractElementF64: return "MipsISD::ExtractElementF64";214 case MipsISD::Wrapper: return "MipsISD::Wrapper";215 case MipsISD::DynAlloc: return "MipsISD::DynAlloc";216 case MipsISD::Sync: return "MipsISD::Sync";217 case MipsISD::Ext: return "MipsISD::Ext";218 case MipsISD::Ins: return "MipsISD::Ins";219 case MipsISD::CIns: return "MipsISD::CIns";220 case MipsISD::LWL: return "MipsISD::LWL";221 case MipsISD::LWR: return "MipsISD::LWR";222 case MipsISD::SWL: return "MipsISD::SWL";223 case MipsISD::SWR: return "MipsISD::SWR";224 case MipsISD::LDL: return "MipsISD::LDL";225 case MipsISD::LDR: return "MipsISD::LDR";226 case MipsISD::SDL: return "MipsISD::SDL";227 case MipsISD::SDR: return "MipsISD::SDR";228 case MipsISD::EXTP: return "MipsISD::EXTP";229 case MipsISD::EXTPDP: return "MipsISD::EXTPDP";230 case MipsISD::EXTR_S_H: return "MipsISD::EXTR_S_H";231 case MipsISD::EXTR_W: return "MipsISD::EXTR_W";232 case MipsISD::EXTR_R_W: return "MipsISD::EXTR_R_W";233 case MipsISD::EXTR_RS_W: return "MipsISD::EXTR_RS_W";234 case MipsISD::SHILO: return "MipsISD::SHILO";235 case MipsISD::MTHLIP: return "MipsISD::MTHLIP";236 case MipsISD::MULSAQ_S_W_PH: return "MipsISD::MULSAQ_S_W_PH";237 case MipsISD::MAQ_S_W_PHL: return "MipsISD::MAQ_S_W_PHL";238 case MipsISD::MAQ_S_W_PHR: return "MipsISD::MAQ_S_W_PHR";239 case MipsISD::MAQ_SA_W_PHL: return "MipsISD::MAQ_SA_W_PHL";240 case MipsISD::MAQ_SA_W_PHR: return "MipsISD::MAQ_SA_W_PHR";241 case MipsISD::DOUBLE_SELECT_I: return "MipsISD::DOUBLE_SELECT_I";242 case MipsISD::DOUBLE_SELECT_I64: return "MipsISD::DOUBLE_SELECT_I64";243 case MipsISD::DPAU_H_QBL: return "MipsISD::DPAU_H_QBL";244 case MipsISD::DPAU_H_QBR: return "MipsISD::DPAU_H_QBR";245 case MipsISD::DPSU_H_QBL: return "MipsISD::DPSU_H_QBL";246 case MipsISD::DPSU_H_QBR: return "MipsISD::DPSU_H_QBR";247 case MipsISD::DPAQ_S_W_PH: return "MipsISD::DPAQ_S_W_PH";248 case MipsISD::DPSQ_S_W_PH: return "MipsISD::DPSQ_S_W_PH";249 case MipsISD::DPAQ_SA_L_W: return "MipsISD::DPAQ_SA_L_W";250 case MipsISD::DPSQ_SA_L_W: return "MipsISD::DPSQ_SA_L_W";251 case MipsISD::DPA_W_PH: return "MipsISD::DPA_W_PH";252 case MipsISD::DPS_W_PH: return "MipsISD::DPS_W_PH";253 case MipsISD::DPAQX_S_W_PH: return "MipsISD::DPAQX_S_W_PH";254 case MipsISD::DPAQX_SA_W_PH: return "MipsISD::DPAQX_SA_W_PH";255 case MipsISD::DPAX_W_PH: return "MipsISD::DPAX_W_PH";256 case MipsISD::DPSX_W_PH: return "MipsISD::DPSX_W_PH";257 case MipsISD::DPSQX_S_W_PH: return "MipsISD::DPSQX_S_W_PH";258 case MipsISD::DPSQX_SA_W_PH: return "MipsISD::DPSQX_SA_W_PH";259 case MipsISD::MULSA_W_PH: return "MipsISD::MULSA_W_PH";260 case MipsISD::MULT: return "MipsISD::MULT";261 case MipsISD::MULTU: return "MipsISD::MULTU";262 case MipsISD::MADD_DSP: return "MipsISD::MADD_DSP";263 case MipsISD::MADDU_DSP: return "MipsISD::MADDU_DSP";264 case MipsISD::MSUB_DSP: return "MipsISD::MSUB_DSP";265 case MipsISD::MSUBU_DSP: return "MipsISD::MSUBU_DSP";266 case MipsISD::SHLL_DSP: return "MipsISD::SHLL_DSP";267 case MipsISD::SHRA_DSP: return "MipsISD::SHRA_DSP";268 case MipsISD::SHRL_DSP: return "MipsISD::SHRL_DSP";269 case MipsISD::SETCC_DSP: return "MipsISD::SETCC_DSP";270 case MipsISD::SELECT_CC_DSP: return "MipsISD::SELECT_CC_DSP";271 case MipsISD::VALL_ZERO: return "MipsISD::VALL_ZERO";272 case MipsISD::VANY_ZERO: return "MipsISD::VANY_ZERO";273 case MipsISD::VALL_NONZERO: return "MipsISD::VALL_NONZERO";274 case MipsISD::VANY_NONZERO: return "MipsISD::VANY_NONZERO";275 case MipsISD::VCEQ: return "MipsISD::VCEQ";276 case MipsISD::VCLE_S: return "MipsISD::VCLE_S";277 case MipsISD::VCLE_U: return "MipsISD::VCLE_U";278 case MipsISD::VCLT_S: return "MipsISD::VCLT_S";279 case MipsISD::VCLT_U: return "MipsISD::VCLT_U";280 case MipsISD::VEXTRACT_SEXT_ELT: return "MipsISD::VEXTRACT_SEXT_ELT";281 case MipsISD::VEXTRACT_ZEXT_ELT: return "MipsISD::VEXTRACT_ZEXT_ELT";282 case MipsISD::VNOR: return "MipsISD::VNOR";283 case MipsISD::VSHF: return "MipsISD::VSHF";284 case MipsISD::SHF: return "MipsISD::SHF";285 case MipsISD::ILVEV: return "MipsISD::ILVEV";286 case MipsISD::ILVOD: return "MipsISD::ILVOD";287 case MipsISD::ILVL: return "MipsISD::ILVL";288 case MipsISD::ILVR: return "MipsISD::ILVR";289 case MipsISD::PCKEV: return "MipsISD::PCKEV";290 case MipsISD::PCKOD: return "MipsISD::PCKOD";291 case MipsISD::INSVE: return "MipsISD::INSVE";292 }293 return nullptr;294}295 296MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,297 const MipsSubtarget &STI)298 : TargetLowering(TM, STI), Subtarget(STI), ABI(TM.getABI()) {299 // Mips does not have i1 type, so use i32 for300 // setcc operations results (slt, sgt, ...).301 setBooleanContents(ZeroOrOneBooleanContent);302 setBooleanVectorContents(ZeroOrNegativeOneBooleanContent);303 // The cmp.cond.fmt instruction in MIPS32r6/MIPS64r6 uses 0 and -1 like MSA304 // does. Integer booleans still use 0 and 1.305 if (Subtarget.hasMips32r6())306 setBooleanContents(ZeroOrOneBooleanContent,307 ZeroOrNegativeOneBooleanContent);308 309 // Load extented operations for i1 types must be promoted310 for (MVT VT : MVT::integer_valuetypes()) {311 setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote);312 setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote);313 setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);314 }315 316 // MIPS doesn't have extending float->double load/store. Set LoadExtAction317 // for f32, f16318 for (MVT VT : MVT::fp_valuetypes()) {319 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f32, Expand);320 setLoadExtAction(ISD::EXTLOAD, VT, MVT::f16, Expand);321 }322 323 // Set LoadExtAction for f16 vectors to Expand324 for (MVT VT : MVT::fp_fixedlen_vector_valuetypes()) {325 MVT F16VT = MVT::getVectorVT(MVT::f16, VT.getVectorNumElements());326 if (F16VT.isValid())327 setLoadExtAction(ISD::EXTLOAD, VT, F16VT, Expand);328 }329 330 setTruncStoreAction(MVT::f32, MVT::f16, Expand);331 setTruncStoreAction(MVT::f64, MVT::f16, Expand);332 333 setTruncStoreAction(MVT::f64, MVT::f32, Expand);334 335 // Used by legalize types to correctly generate the setcc result.336 // Without this, every float setcc comes with a AND/OR with the result,337 // we don't want this, since the fpcmp result goes to a flag register,338 // which is used implicitly by brcond and select operations.339 AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);340 341 // Mips Custom Operations342 setOperationAction(ISD::BR_JT, MVT::Other, Expand);343 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);344 setOperationAction(ISD::BlockAddress, MVT::i32, Custom);345 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);346 setOperationAction(ISD::JumpTable, MVT::i32, Custom);347 setOperationAction(ISD::ConstantPool, MVT::i32, Custom);348 setOperationAction(ISD::SELECT, MVT::f32, Custom);349 setOperationAction(ISD::SELECT, MVT::f64, Custom);350 setOperationAction(ISD::SELECT, MVT::i32, Custom);351 setOperationAction(ISD::SETCC, MVT::f32, Custom);352 setOperationAction(ISD::SETCC, MVT::f64, Custom);353 setOperationAction(ISD::BRCOND, MVT::Other, Custom);354 setOperationAction(ISD::FABS, MVT::f32, Custom);355 setOperationAction(ISD::FABS, MVT::f64, Custom);356 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);357 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);358 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);359 setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i32, Custom);360 setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i32, Custom);361 362 setOperationAction(ISD::STRICT_FSETCC, MVT::f32, Custom);363 setOperationAction(ISD::STRICT_FSETCCS, MVT::f32, Custom);364 setOperationAction(ISD::STRICT_FSETCC, MVT::f64, Custom);365 setOperationAction(ISD::STRICT_FSETCCS, MVT::f64, Custom);366 367 if (Subtarget.hasMips32r2() ||368 getTargetMachine().getTargetTriple().isOSLinux())369 setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom);370 371 // Lower fmin/fmax/fclass operations for MIPS R6.372 if (Subtarget.hasMips32r6()) {373 setOperationAction(ISD::FMINNUM_IEEE, MVT::f32, Legal);374 setOperationAction(ISD::FMAXNUM_IEEE, MVT::f32, Legal);375 setOperationAction(ISD::FMINNUM, MVT::f32, Legal);376 setOperationAction(ISD::FMAXNUM, MVT::f32, Legal);377 setOperationAction(ISD::FMINNUM_IEEE, MVT::f64, Legal);378 setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal);379 setOperationAction(ISD::FMINNUM, MVT::f64, Legal);380 setOperationAction(ISD::FMAXNUM, MVT::f64, Legal);381 setOperationAction(ISD::IS_FPCLASS, MVT::f32, Legal);382 setOperationAction(ISD::IS_FPCLASS, MVT::f64, Legal);383 setOperationAction(ISD::FCANONICALIZE, MVT::f32, Legal);384 setOperationAction(ISD::FCANONICALIZE, MVT::f64, Legal);385 } else {386 setOperationAction(ISD::FCANONICALIZE, MVT::f32, Custom);387 setOperationAction(ISD::FCANONICALIZE, MVT::f64, Custom);388 }389 390 if (Subtarget.isGP64bit()) {391 setOperationAction(ISD::GlobalAddress, MVT::i64, Custom);392 setOperationAction(ISD::BlockAddress, MVT::i64, Custom);393 setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);394 setOperationAction(ISD::JumpTable, MVT::i64, Custom);395 setOperationAction(ISD::ConstantPool, MVT::i64, Custom);396 setOperationAction(ISD::SELECT, MVT::i64, Custom);397 if (Subtarget.hasMips64r6()) {398 setOperationAction(ISD::LOAD, MVT::i64, Legal);399 setOperationAction(ISD::STORE, MVT::i64, Legal);400 } else {401 setOperationAction(ISD::LOAD, MVT::i64, Custom);402 setOperationAction(ISD::STORE, MVT::i64, Custom);403 }404 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);405 setOperationAction(ISD::STRICT_FP_TO_UINT, MVT::i64, Custom);406 setOperationAction(ISD::STRICT_FP_TO_SINT, MVT::i64, Custom);407 setOperationAction(ISD::SHL_PARTS, MVT::i64, Custom);408 setOperationAction(ISD::SRA_PARTS, MVT::i64, Custom);409 setOperationAction(ISD::SRL_PARTS, MVT::i64, Custom);410 }411 412 if (!Subtarget.isGP64bit()) {413 setOperationAction(ISD::SHL_PARTS, MVT::i32, Custom);414 setOperationAction(ISD::SRA_PARTS, MVT::i32, Custom);415 setOperationAction(ISD::SRL_PARTS, MVT::i32, Custom);416 }417 418 setOperationAction(ISD::EH_DWARF_CFA, MVT::i32, Custom);419 if (Subtarget.isGP64bit())420 setOperationAction(ISD::EH_DWARF_CFA, MVT::i64, Custom);421 422 setOperationAction(ISD::SDIV, MVT::i32, Expand);423 setOperationAction(ISD::SREM, MVT::i32, Expand);424 setOperationAction(ISD::UDIV, MVT::i32, Expand);425 setOperationAction(ISD::UREM, MVT::i32, Expand);426 setOperationAction(ISD::SDIV, MVT::i64, Expand);427 setOperationAction(ISD::SREM, MVT::i64, Expand);428 setOperationAction(ISD::UDIV, MVT::i64, Expand);429 setOperationAction(ISD::UREM, MVT::i64, Expand);430 431 // Operations not directly supported by Mips.432 setOperationAction(ISD::BR_CC, MVT::f32, Expand);433 setOperationAction(ISD::BR_CC, MVT::f64, Expand);434 setOperationAction(ISD::BR_CC, MVT::i32, Expand);435 setOperationAction(ISD::BR_CC, MVT::i64, Expand);436 setOperationAction(ISD::SELECT_CC, MVT::i32, Expand);437 setOperationAction(ISD::SELECT_CC, MVT::i64, Expand);438 setOperationAction(ISD::SELECT_CC, MVT::f32, Expand);439 setOperationAction(ISD::SELECT_CC, MVT::f64, Expand);440 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);441 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);442 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);443 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);444 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);445 446 if (Subtarget.hasCnMips()) {447 setOperationAction(ISD::CTPOP, MVT::i32, Legal);448 setOperationAction(ISD::CTPOP, MVT::i64, Legal);449 } else {450 setOperationAction(ISD::CTPOP, MVT::i32, Expand);451 setOperationAction(ISD::CTPOP, MVT::i64, Expand);452 }453 setOperationAction(ISD::CTTZ, MVT::i32, Expand);454 setOperationAction(ISD::CTTZ, MVT::i64, Expand);455 setOperationAction(ISD::ROTL, MVT::i32, Expand);456 setOperationAction(ISD::ROTL, MVT::i64, Expand);457 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);458 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);459 460 if (!Subtarget.hasMips32r2())461 setOperationAction(ISD::ROTR, MVT::i32, Expand);462 463 if (!Subtarget.hasMips64r2())464 setOperationAction(ISD::ROTR, MVT::i64, Expand);465 466 setOperationAction(ISD::FSIN, MVT::f32, Expand);467 setOperationAction(ISD::FSIN, MVT::f64, Expand);468 setOperationAction(ISD::FCOS, MVT::f32, Expand);469 setOperationAction(ISD::FCOS, MVT::f64, Expand);470 setOperationAction(ISD::FSINCOS, MVT::f32, Expand);471 setOperationAction(ISD::FSINCOS, MVT::f64, Expand);472 setOperationAction(ISD::FPOW, MVT::f32, Expand);473 setOperationAction(ISD::FPOW, MVT::f64, Expand);474 setOperationAction(ISD::FLOG, MVT::f32, Expand);475 setOperationAction(ISD::FLOG2, MVT::f32, Expand);476 setOperationAction(ISD::FLOG10, MVT::f32, Expand);477 setOperationAction(ISD::FEXP, MVT::f32, Expand);478 setOperationAction(ISD::FMA, MVT::f32, Expand);479 setOperationAction(ISD::FMA, MVT::f64, Expand);480 setOperationAction(ISD::FREM, MVT::f32, Expand);481 setOperationAction(ISD::FREM, MVT::f64, Expand);482 483 // Lower f16 conversion operations into library calls484 setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);485 setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);486 setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);487 setOperationAction(ISD::FP_TO_FP16, MVT::f64, Expand);488 489 setOperationAction(ISD::EH_RETURN, MVT::Other, Custom);490 491 setOperationAction(ISD::VASTART, MVT::Other, Custom);492 setOperationAction(ISD::VAARG, MVT::Other, Custom);493 setOperationAction(ISD::VACOPY, MVT::Other, Expand);494 setOperationAction(ISD::VAEND, MVT::Other, Expand);495 496 // Use the default for now497 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);498 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);499 500 if (!Subtarget.isGP64bit()) {501 setOperationAction(ISD::ATOMIC_LOAD, MVT::i64, Expand);502 setOperationAction(ISD::ATOMIC_STORE, MVT::i64, Expand);503 }504 505 if (!Subtarget.hasMips32r2()) {506 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand);507 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand);508 }509 510 // MIPS16 lacks MIPS32's clz and clo instructions.511 if (!Subtarget.hasMips32() || Subtarget.inMips16Mode())512 setOperationAction(ISD::CTLZ, MVT::i32, Expand);513 if (!Subtarget.hasMips64())514 setOperationAction(ISD::CTLZ, MVT::i64, Expand);515 516 if (!Subtarget.hasMips32r2())517 setOperationAction(ISD::BSWAP, MVT::i32, Expand);518 if (!Subtarget.hasMips64r2())519 setOperationAction(ISD::BSWAP, MVT::i64, Expand);520 521 if (Subtarget.isGP64bit() && Subtarget.hasMips64r6()) {522 setLoadExtAction(ISD::SEXTLOAD, MVT::i64, MVT::i32, Legal);523 setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, MVT::i32, Legal);524 setLoadExtAction(ISD::EXTLOAD, MVT::i64, MVT::i32, Legal);525 setTruncStoreAction(MVT::i64, MVT::i32, Legal);526 } else if (Subtarget.isGP64bit()) {527 setLoadExtAction(ISD::SEXTLOAD, MVT::i64, MVT::i32, Custom);528 setLoadExtAction(ISD::ZEXTLOAD, MVT::i64, MVT::i32, Custom);529 setLoadExtAction(ISD::EXTLOAD, MVT::i64, MVT::i32, Custom);530 setTruncStoreAction(MVT::i64, MVT::i32, Custom);531 }532 533 setOperationAction(ISD::TRAP, MVT::Other, Legal);534 535 setTargetDAGCombine({ISD::SDIVREM, ISD::UDIVREM, ISD::SELECT, ISD::AND,536 ISD::OR, ISD::ADD, ISD::SUB, ISD::AssertZext, ISD::SHL,537 ISD::SIGN_EXTEND});538 539 if (Subtarget.isGP64bit())540 setMaxAtomicSizeInBitsSupported(64);541 else542 setMaxAtomicSizeInBitsSupported(32);543 544 setMinFunctionAlignment(Subtarget.isGP64bit() ? Align(8) : Align(4));545 546 // The arguments on the stack are defined in terms of 4-byte slots on O32547 // and 8-byte slots on N32/N64.548 setMinStackArgumentAlignment((ABI.IsN32() || ABI.IsN64()) ? Align(8)549 : Align(4));550 551 setStackPointerRegisterToSaveRestore(ABI.IsN64() ? Mips::SP_64 : Mips::SP);552 553 MaxStoresPerMemcpy = 16;554 555 isMicroMips = Subtarget.inMicroMipsMode();556}557 558const MipsTargetLowering *559MipsTargetLowering::create(const MipsTargetMachine &TM,560 const MipsSubtarget &STI) {561 if (STI.inMips16Mode())562 return createMips16TargetLowering(TM, STI);563 564 return createMipsSETargetLowering(TM, STI);565}566 567// Create a fast isel object.568FastISel *569MipsTargetLowering::createFastISel(FunctionLoweringInfo &funcInfo,570 const TargetLibraryInfo *libInfo) const {571 const MipsTargetMachine &TM =572 static_cast<const MipsTargetMachine &>(funcInfo.MF->getTarget());573 574 // We support only the standard encoding [MIPS32,MIPS32R5] ISAs.575 bool UseFastISel = TM.Options.EnableFastISel && Subtarget.hasMips32() &&576 !Subtarget.hasMips32r6() && !Subtarget.inMips16Mode() &&577 !Subtarget.inMicroMipsMode();578 579 // Disable if either of the following is true:580 // We do not generate PIC, the ABI is not O32, XGOT is being used.581 if (!TM.isPositionIndependent() || !TM.getABI().IsO32() ||582 Subtarget.useXGOT())583 UseFastISel = false;584 585 return UseFastISel ? Mips::createFastISel(funcInfo, libInfo) : nullptr;586}587 588EVT MipsTargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &,589 EVT VT) const {590 if (!VT.isVector())591 return MVT::i32;592 return VT.changeVectorElementTypeToInteger();593}594 595static SDValue performDivRemCombine(SDNode *N, SelectionDAG &DAG,596 TargetLowering::DAGCombinerInfo &DCI,597 const MipsSubtarget &Subtarget) {598 if (DCI.isBeforeLegalizeOps())599 return SDValue();600 601 EVT Ty = N->getValueType(0);602 unsigned LO = (Ty == MVT::i32) ? Mips::LO0 : Mips::LO0_64;603 unsigned HI = (Ty == MVT::i32) ? Mips::HI0 : Mips::HI0_64;604 unsigned Opc = N->getOpcode() == ISD::SDIVREM ? MipsISD::DivRem16 :605 MipsISD::DivRemU16;606 SDLoc DL(N);607 608 SDValue DivRem = DAG.getNode(Opc, DL, MVT::Glue,609 N->getOperand(0), N->getOperand(1));610 SDValue InChain = DAG.getEntryNode();611 SDValue InGlue = DivRem;612 613 // insert MFLO614 if (N->hasAnyUseOfValue(0)) {615 SDValue CopyFromLo = DAG.getCopyFromReg(InChain, DL, LO, Ty,616 InGlue);617 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), CopyFromLo);618 InChain = CopyFromLo.getValue(1);619 InGlue = CopyFromLo.getValue(2);620 }621 622 // insert MFHI623 if (N->hasAnyUseOfValue(1)) {624 SDValue CopyFromHi = DAG.getCopyFromReg(InChain, DL,625 HI, Ty, InGlue);626 DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), CopyFromHi);627 }628 629 return SDValue();630}631 632static Mips::CondCode condCodeToFCC(ISD::CondCode CC) {633 switch (CC) {634 default: llvm_unreachable("Unknown fp condition code!");635 case ISD::SETEQ:636 case ISD::SETOEQ: return Mips::FCOND_OEQ;637 case ISD::SETUNE: return Mips::FCOND_UNE;638 case ISD::SETLT:639 case ISD::SETOLT: return Mips::FCOND_OLT;640 case ISD::SETGT:641 case ISD::SETOGT: return Mips::FCOND_OGT;642 case ISD::SETLE:643 case ISD::SETOLE: return Mips::FCOND_OLE;644 case ISD::SETGE:645 case ISD::SETOGE: return Mips::FCOND_OGE;646 case ISD::SETULT: return Mips::FCOND_ULT;647 case ISD::SETULE: return Mips::FCOND_ULE;648 case ISD::SETUGT: return Mips::FCOND_UGT;649 case ISD::SETUGE: return Mips::FCOND_UGE;650 case ISD::SETUO: return Mips::FCOND_UN;651 case ISD::SETO: return Mips::FCOND_OR;652 case ISD::SETNE:653 case ISD::SETONE: return Mips::FCOND_ONE;654 case ISD::SETUEQ: return Mips::FCOND_UEQ;655 }656}657 658/// This function returns true if the floating point conditional branches and659/// conditional moves which use condition code CC should be inverted.660static bool invertFPCondCodeUser(Mips::CondCode CC) {661 if (CC >= Mips::FCOND_F && CC <= Mips::FCOND_NGT)662 return false;663 664 assert((CC >= Mips::FCOND_T && CC <= Mips::FCOND_GT) &&665 "Illegal Condition Code");666 667 return true;668}669 670// Creates and returns an FPCmp node from a setcc node.671// Returns Op if setcc is not a floating point comparison.672static SDValue createFPCmp(SelectionDAG &DAG, const SDValue &Op) {673 // must be a SETCC node674 if (Op.getOpcode() != ISD::SETCC && Op.getOpcode() != ISD::STRICT_FSETCC &&675 Op.getOpcode() != ISD::STRICT_FSETCCS)676 return Op;677 678 SDValue LHS = Op.getOperand(0);679 680 if (!LHS.getValueType().isFloatingPoint())681 return Op;682 683 SDValue RHS = Op.getOperand(1);684 SDLoc DL(Op);685 686 // Assume the 3rd operand is a CondCodeSDNode. Add code to check the type of687 // node if necessary.688 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();689 690 return DAG.getNode(MipsISD::FPCmp, DL, MVT::Glue, LHS, RHS,691 DAG.getConstant(condCodeToFCC(CC), DL, MVT::i32));692}693 694// Creates and returns a CMovFPT/F node.695static SDValue createCMovFP(SelectionDAG &DAG, SDValue Cond, SDValue True,696 SDValue False, const SDLoc &DL) {697 ConstantSDNode *CC = cast<ConstantSDNode>(Cond.getOperand(2));698 bool invert = invertFPCondCodeUser((Mips::CondCode)CC->getSExtValue());699 SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32);700 701 return DAG.getNode((invert ? MipsISD::CMovFP_F : MipsISD::CMovFP_T), DL,702 True.getValueType(), True, FCC0, False, Cond);703}704 705static SDValue performSELECTCombine(SDNode *N, SelectionDAG &DAG,706 TargetLowering::DAGCombinerInfo &DCI,707 const MipsSubtarget &Subtarget) {708 if (DCI.isBeforeLegalizeOps())709 return SDValue();710 711 SDValue SetCC = N->getOperand(0);712 713 if ((SetCC.getOpcode() != ISD::SETCC) ||714 !SetCC.getOperand(0).getValueType().isInteger())715 return SDValue();716 717 SDValue False = N->getOperand(2);718 EVT FalseTy = False.getValueType();719 720 if (!FalseTy.isInteger())721 return SDValue();722 723 ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(False);724 725 // If the RHS (False) is 0, we swap the order of the operands726 // of ISD::SELECT (obviously also inverting the condition) so that we can727 // take advantage of conditional moves using the $0 register.728 // Example:729 // return (a != 0) ? x : 0;730 // load $reg, x731 // movz $reg, $0, a732 if (!FalseC)733 return SDValue();734 735 const SDLoc DL(N);736 737 if (!FalseC->getZExtValue()) {738 ISD::CondCode CC = cast<CondCodeSDNode>(SetCC.getOperand(2))->get();739 SDValue True = N->getOperand(1);740 741 SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0),742 SetCC.getOperand(1),743 ISD::getSetCCInverse(CC, SetCC.getValueType()));744 745 return DAG.getNode(ISD::SELECT, DL, FalseTy, SetCC, False, True);746 }747 748 // If both operands are integer constants there's a possibility that we749 // can do some interesting optimizations.750 SDValue True = N->getOperand(1);751 ConstantSDNode *TrueC = dyn_cast<ConstantSDNode>(True);752 753 if (!TrueC || !True.getValueType().isInteger())754 return SDValue();755 756 // We'll also ignore MVT::i64 operands as this optimizations proves757 // to be ineffective because of the required sign extensions as the result758 // of a SETCC operator is always MVT::i32 for non-vector types.759 if (True.getValueType() == MVT::i64)760 return SDValue();761 762 int64_t Diff = TrueC->getSExtValue() - FalseC->getSExtValue();763 764 // 1) (a < x) ? y : y-1765 // slti $reg1, a, x766 // addiu $reg2, $reg1, y-1767 if (Diff == 1)768 return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, False);769 770 // 2) (a < x) ? y-1 : y771 // slti $reg1, a, x772 // xor $reg1, $reg1, 1773 // addiu $reg2, $reg1, y-1774 if (Diff == -1) {775 ISD::CondCode CC = cast<CondCodeSDNode>(SetCC.getOperand(2))->get();776 SetCC = DAG.getSetCC(DL, SetCC.getValueType(), SetCC.getOperand(0),777 SetCC.getOperand(1),778 ISD::getSetCCInverse(CC, SetCC.getValueType()));779 return DAG.getNode(ISD::ADD, DL, SetCC.getValueType(), SetCC, True);780 }781 782 // Could not optimize.783 return SDValue();784}785 786static SDValue performCMovFPCombine(SDNode *N, SelectionDAG &DAG,787 TargetLowering::DAGCombinerInfo &DCI,788 const MipsSubtarget &Subtarget) {789 if (DCI.isBeforeLegalizeOps())790 return SDValue();791 792 SDValue ValueIfTrue = N->getOperand(0), ValueIfFalse = N->getOperand(2);793 794 ConstantSDNode *FalseC = dyn_cast<ConstantSDNode>(ValueIfFalse);795 if (!FalseC || FalseC->getZExtValue())796 return SDValue();797 798 // Since RHS (False) is 0, we swap the order of the True/False operands799 // (obviously also inverting the condition) so that we can800 // take advantage of conditional moves using the $0 register.801 // Example:802 // return (a != 0) ? x : 0;803 // load $reg, x804 // movz $reg, $0, a805 unsigned Opc = (N->getOpcode() == MipsISD::CMovFP_T) ? MipsISD::CMovFP_F :806 MipsISD::CMovFP_T;807 808 SDValue FCC = N->getOperand(1), Glue = N->getOperand(3);809 return DAG.getNode(Opc, SDLoc(N), ValueIfFalse.getValueType(),810 ValueIfFalse, FCC, ValueIfTrue, Glue);811}812 813static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG,814 TargetLowering::DAGCombinerInfo &DCI,815 const MipsSubtarget &Subtarget) {816 if (DCI.isBeforeLegalizeOps() || !Subtarget.hasExtractInsert())817 return SDValue();818 819 SDValue FirstOperand = N->getOperand(0);820 unsigned FirstOperandOpc = FirstOperand.getOpcode();821 SDValue Mask = N->getOperand(1);822 EVT ValTy = N->getValueType(0);823 SDLoc DL(N);824 825 uint64_t Pos = 0;826 unsigned SMPos, SMSize;827 ConstantSDNode *CN;828 SDValue NewOperand;829 unsigned Opc;830 831 // Op's second operand must be a shifted mask.832 if (!(CN = dyn_cast<ConstantSDNode>(Mask)) ||833 !isShiftedMask_64(CN->getZExtValue(), SMPos, SMSize))834 return SDValue();835 836 if (FirstOperandOpc == ISD::SRA || FirstOperandOpc == ISD::SRL) {837 // Pattern match EXT.838 // $dst = and ((sra or srl) $src , pos), (2**size - 1)839 // => ext $dst, $src, pos, size840 841 // The second operand of the shift must be an immediate.842 if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))))843 return SDValue();844 845 Pos = CN->getZExtValue();846 847 // Return if the shifted mask does not start at bit 0 or the sum of its size848 // and Pos exceeds the word's size.849 if (SMPos != 0 || Pos + SMSize > ValTy.getSizeInBits())850 return SDValue();851 852 Opc = MipsISD::Ext;853 NewOperand = FirstOperand.getOperand(0);854 } else if (FirstOperandOpc == ISD::SHL && Subtarget.hasCnMips()) {855 // Pattern match CINS.856 // $dst = and (shl $src , pos), mask857 // => cins $dst, $src, pos, size858 // mask is a shifted mask with consecutive 1's, pos = shift amount,859 // size = population count.860 861 // The second operand of the shift must be an immediate.862 if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))))863 return SDValue();864 865 Pos = CN->getZExtValue();866 867 if (SMPos != Pos || Pos >= ValTy.getSizeInBits() || SMSize >= 32 ||868 Pos + SMSize > ValTy.getSizeInBits())869 return SDValue();870 871 NewOperand = FirstOperand.getOperand(0);872 // SMSize is 'location' (position) in this case, not size.873 SMSize--;874 Opc = MipsISD::CIns;875 } else {876 // Pattern match EXT.877 // $dst = and $src, (2**size - 1) , if size > 16878 // => ext $dst, $src, pos, size , pos = 0879 880 // If the mask is <= 0xffff, andi can be used instead.881 if (CN->getZExtValue() <= 0xffff)882 return SDValue();883 884 // Return if the mask doesn't start at position 0.885 if (SMPos)886 return SDValue();887 888 Opc = MipsISD::Ext;889 NewOperand = FirstOperand;890 }891 return DAG.getNode(Opc, DL, ValTy, NewOperand,892 DAG.getConstant(Pos, DL, MVT::i32),893 DAG.getConstant(SMSize, DL, MVT::i32));894}895 896static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,897 TargetLowering::DAGCombinerInfo &DCI,898 const MipsSubtarget &Subtarget) {899 if (DCI.isBeforeLegalizeOps() || !Subtarget.hasExtractInsert())900 return SDValue();901 902 SDValue FirstOperand = N->getOperand(0), SecondOperand = N->getOperand(1);903 unsigned SMPos0, SMSize0, SMPos1, SMSize1;904 ConstantSDNode *CN, *CN1;905 906 if ((FirstOperand.getOpcode() == ISD::AND &&907 SecondOperand.getOpcode() == ISD::SHL) ||908 (FirstOperand.getOpcode() == ISD::SHL &&909 SecondOperand.getOpcode() == ISD::AND)) {910 // Pattern match INS.911 // $dst = or (and $src1, (2**size0 - 1)), (shl $src2, size0)912 // ==> ins $src1, $src2, pos, size, pos = size0, size = 32 - pos;913 // Or:914 // $dst = or (shl $src2, size0), (and $src1, (2**size0 - 1))915 // ==> ins $src1, $src2, pos, size, pos = size0, size = 32 - pos;916 SDValue AndOperand0 = FirstOperand.getOpcode() == ISD::AND917 ? FirstOperand.getOperand(0)918 : SecondOperand.getOperand(0);919 SDValue ShlOperand0 = FirstOperand.getOpcode() == ISD::AND920 ? SecondOperand.getOperand(0)921 : FirstOperand.getOperand(0);922 SDValue AndMask = FirstOperand.getOpcode() == ISD::AND923 ? FirstOperand.getOperand(1)924 : SecondOperand.getOperand(1);925 if (!(CN = dyn_cast<ConstantSDNode>(AndMask)) ||926 !isShiftedMask_64(CN->getZExtValue(), SMPos0, SMSize0))927 return SDValue();928 929 SDValue ShlShift = FirstOperand.getOpcode() == ISD::AND930 ? SecondOperand.getOperand(1)931 : FirstOperand.getOperand(1);932 if (!(CN = dyn_cast<ConstantSDNode>(ShlShift)))933 return SDValue();934 uint64_t ShlShiftValue = CN->getZExtValue();935 936 if (SMPos0 != 0 || SMSize0 != ShlShiftValue)937 return SDValue();938 939 SDLoc DL(N);940 EVT ValTy = N->getValueType(0);941 SMPos1 = ShlShiftValue;942 assert(SMPos1 < ValTy.getSizeInBits());943 SMSize1 = (ValTy == MVT::i64 ? 64 : 32) - SMPos1;944 return DAG.getNode(MipsISD::Ins, DL, ValTy, ShlOperand0,945 DAG.getConstant(SMPos1, DL, MVT::i32),946 DAG.getConstant(SMSize1, DL, MVT::i32), AndOperand0);947 }948 949 // See if Op's first operand matches (and $src1 , mask0).950 if (FirstOperand.getOpcode() != ISD::AND)951 return SDValue();952 953 // Pattern match INS.954 // $dst = or (and $src1 , mask0), (and (shl $src, pos), mask1),955 // where mask1 = (2**size - 1) << pos, mask0 = ~mask1956 // => ins $dst, $src, size, pos, $src1957 if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))) ||958 !isShiftedMask_64(~CN->getSExtValue(), SMPos0, SMSize0))959 return SDValue();960 961 // See if Op's second operand matches (and (shl $src, pos), mask1).962 if (SecondOperand.getOpcode() == ISD::AND &&963 SecondOperand.getOperand(0).getOpcode() == ISD::SHL) {964 965 if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand.getOperand(1))) ||966 !isShiftedMask_64(CN->getZExtValue(), SMPos1, SMSize1))967 return SDValue();968 969 // The shift masks must have the same position and size.970 if (SMPos0 != SMPos1 || SMSize0 != SMSize1)971 return SDValue();972 973 SDValue Shl = SecondOperand.getOperand(0);974 975 if (!(CN = dyn_cast<ConstantSDNode>(Shl.getOperand(1))))976 return SDValue();977 978 unsigned Shamt = CN->getZExtValue();979 980 // Return if the shift amount and the first bit position of mask are not the981 // same.982 EVT ValTy = N->getValueType(0);983 if ((Shamt != SMPos0) || (SMPos0 + SMSize0 > ValTy.getSizeInBits()))984 return SDValue();985 986 SDLoc DL(N);987 return DAG.getNode(MipsISD::Ins, DL, ValTy, Shl.getOperand(0),988 DAG.getConstant(SMPos0, DL, MVT::i32),989 DAG.getConstant(SMSize0, DL, MVT::i32),990 FirstOperand.getOperand(0));991 } else {992 // Pattern match DINS.993 // $dst = or (and $src, mask0), mask1994 // where mask0 = ((1 << SMSize0) -1) << SMPos0995 // => dins $dst, $src, pos, size996 if (~CN->getSExtValue() == ((((int64_t)1 << SMSize0) - 1) << SMPos0) &&997 ((SMSize0 + SMPos0 <= 64 && Subtarget.hasMips64r2()) ||998 (SMSize0 + SMPos0 <= 32))) {999 // Check if AND instruction has constant as argument1000 bool isConstCase = SecondOperand.getOpcode() != ISD::AND;1001 if (SecondOperand.getOpcode() == ISD::AND) {1002 if (!(CN1 = dyn_cast<ConstantSDNode>(SecondOperand->getOperand(1))))1003 return SDValue();1004 } else {1005 if (!(CN1 = dyn_cast<ConstantSDNode>(N->getOperand(1))))1006 return SDValue();1007 }1008 // Don't generate INS if constant OR operand doesn't fit into bits1009 // cleared by constant AND operand.1010 if (CN->getSExtValue() & CN1->getSExtValue())1011 return SDValue();1012 1013 SDLoc DL(N);1014 EVT ValTy = N->getOperand(0)->getValueType(0);1015 SDValue Const1;1016 SDValue SrlX;1017 if (!isConstCase) {1018 Const1 = DAG.getConstant(SMPos0, DL, MVT::i32);1019 SrlX = DAG.getNode(ISD::SRL, DL, SecondOperand->getValueType(0),1020 SecondOperand, Const1);1021 }1022 return DAG.getNode(1023 MipsISD::Ins, DL, N->getValueType(0),1024 isConstCase1025 ? DAG.getSignedConstant(CN1->getSExtValue() >> SMPos0, DL, ValTy)1026 : SrlX,1027 DAG.getConstant(SMPos0, DL, MVT::i32),1028 DAG.getConstant(ValTy.getSizeInBits() / 8 < 8 ? SMSize0 & 311029 : SMSize0,1030 DL, MVT::i32),1031 FirstOperand->getOperand(0));1032 }1033 return SDValue();1034 }1035}1036 1037static SDValue performMADD_MSUBCombine(SDNode *ROOTNode, SelectionDAG &CurDAG,1038 const MipsSubtarget &Subtarget) {1039 // ROOTNode must have a multiplication as an operand for the match to be1040 // successful.1041 if (ROOTNode->getOperand(0).getOpcode() != ISD::MUL &&1042 ROOTNode->getOperand(1).getOpcode() != ISD::MUL)1043 return SDValue();1044 1045 // In the case where we have a multiplication as the left operand of1046 // of a subtraction, we can't combine into a MipsISD::MSub node as the1047 // the instruction definition of msub(u) places the multiplication on1048 // on the right.1049 if (ROOTNode->getOpcode() == ISD::SUB &&1050 ROOTNode->getOperand(0).getOpcode() == ISD::MUL)1051 return SDValue();1052 1053 // We don't handle vector types here.1054 if (ROOTNode->getValueType(0).isVector())1055 return SDValue();1056 1057 // For MIPS64, madd / msub instructions are inefficent to use with 64 bit1058 // arithmetic. E.g.1059 // (add (mul a b) c) =>1060 // let res = (madd (mthi (drotr c 32))x(mtlo c) a b) in1061 // MIPS64: (or (dsll (mfhi res) 32) (dsrl (dsll (mflo res) 32) 32)1062 // or1063 // MIPS64R2: (dins (mflo res) (mfhi res) 32 32)1064 //1065 // The overhead of setting up the Hi/Lo registers and reassembling the1066 // result makes this a dubious optimzation for MIPS64. The core of the1067 // problem is that Hi/Lo contain the upper and lower 32 bits of the1068 // operand and result.1069 //1070 // It requires a chain of 4 add/mul for MIPS64R2 to get better code1071 // density than doing it naively, 5 for MIPS64. Additionally, using1072 // madd/msub on MIPS64 requires the operands actually be 32 bit sign1073 // extended operands, not true 64 bit values.1074 //1075 // FIXME: For the moment, disable this completely for MIPS64.1076 if (Subtarget.hasMips64())1077 return SDValue();1078 1079 SDValue Mult = ROOTNode->getOperand(0).getOpcode() == ISD::MUL1080 ? ROOTNode->getOperand(0)1081 : ROOTNode->getOperand(1);1082 1083 SDValue AddOperand = ROOTNode->getOperand(0).getOpcode() == ISD::MUL1084 ? ROOTNode->getOperand(1)1085 : ROOTNode->getOperand(0);1086 1087 // Transform this to a MADD only if the user of this node is the add.1088 // If there are other users of the mul, this function returns here.1089 if (!Mult.hasOneUse())1090 return SDValue();1091 1092 // maddu and madd are unusual instructions in that on MIPS64 bits 63..311093 // must be in canonical form, i.e. sign extended. For MIPS32, the operands1094 // of the multiply must have 32 or more sign bits, otherwise we cannot1095 // perform this optimization. We have to check this here as we're performing1096 // this optimization pre-legalization.1097 SDValue MultLHS = Mult->getOperand(0);1098 SDValue MultRHS = Mult->getOperand(1);1099 1100 bool IsSigned = MultLHS->getOpcode() == ISD::SIGN_EXTEND &&1101 MultRHS->getOpcode() == ISD::SIGN_EXTEND;1102 bool IsUnsigned = MultLHS->getOpcode() == ISD::ZERO_EXTEND &&1103 MultRHS->getOpcode() == ISD::ZERO_EXTEND;1104 1105 if (!IsSigned && !IsUnsigned)1106 return SDValue();1107 1108 // Initialize accumulator.1109 SDLoc DL(ROOTNode);1110 SDValue BottomHalf, TopHalf;1111 std::tie(BottomHalf, TopHalf) =1112 CurDAG.SplitScalar(AddOperand, DL, MVT::i32, MVT::i32);1113 SDValue ACCIn =1114 CurDAG.getNode(MipsISD::MTLOHI, DL, MVT::Untyped, BottomHalf, TopHalf);1115 1116 // Create MipsMAdd(u) / MipsMSub(u) node.1117 bool IsAdd = ROOTNode->getOpcode() == ISD::ADD;1118 unsigned Opcode = IsAdd ? (IsUnsigned ? MipsISD::MAddu : MipsISD::MAdd)1119 : (IsUnsigned ? MipsISD::MSubu : MipsISD::MSub);1120 SDValue MAddOps[3] = {1121 CurDAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Mult->getOperand(0)),1122 CurDAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Mult->getOperand(1)), ACCIn};1123 SDValue MAdd = CurDAG.getNode(Opcode, DL, MVT::Untyped, MAddOps);1124 1125 SDValue ResLo = CurDAG.getNode(MipsISD::MFLO, DL, MVT::i32, MAdd);1126 SDValue ResHi = CurDAG.getNode(MipsISD::MFHI, DL, MVT::i32, MAdd);1127 SDValue Combined =1128 CurDAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, ResLo, ResHi);1129 return Combined;1130}1131 1132static SDValue performSUBCombine(SDNode *N, SelectionDAG &DAG,1133 TargetLowering::DAGCombinerInfo &DCI,1134 const MipsSubtarget &Subtarget) {1135 // (sub v0 (mul v1, v2)) => (msub v1, v2, v0)1136 if (DCI.isBeforeLegalizeOps()) {1137 if (Subtarget.hasMips32() && !Subtarget.hasMips32r6() &&1138 !Subtarget.inMips16Mode() && N->getValueType(0) == MVT::i64)1139 return performMADD_MSUBCombine(N, DAG, Subtarget);1140 1141 return SDValue();1142 }1143 1144 return SDValue();1145}1146 1147static SDValue performADDCombine(SDNode *N, SelectionDAG &DAG,1148 TargetLowering::DAGCombinerInfo &DCI,1149 const MipsSubtarget &Subtarget) {1150 // (add v0 (mul v1, v2)) => (madd v1, v2, v0)1151 if (DCI.isBeforeLegalizeOps()) {1152 if (Subtarget.hasMips32() && !Subtarget.hasMips32r6() &&1153 !Subtarget.inMips16Mode() && N->getValueType(0) == MVT::i64)1154 return performMADD_MSUBCombine(N, DAG, Subtarget);1155 1156 return SDValue();1157 }1158 1159 // When loading from a jump table, push the Lo node to the position that1160 // allows folding it into a load immediate.1161 // (add v0, (add v1, abs_lo(tjt))) => (add (add v0, v1), abs_lo(tjt))1162 // (add (add abs_lo(tjt), v1), v0) => (add (add v0, v1), abs_lo(tjt))1163 SDValue InnerAdd = N->getOperand(1);1164 SDValue Index = N->getOperand(0);1165 if (InnerAdd.getOpcode() != ISD::ADD)1166 std::swap(InnerAdd, Index);1167 if (InnerAdd.getOpcode() != ISD::ADD)1168 return SDValue();1169 1170 SDValue Lo = InnerAdd.getOperand(0);1171 SDValue Other = InnerAdd.getOperand(1);1172 if (Lo.getOpcode() != MipsISD::Lo)1173 std::swap(Lo, Other);1174 1175 if ((Lo.getOpcode() != MipsISD::Lo) ||1176 (Lo.getOperand(0).getOpcode() != ISD::TargetJumpTable))1177 return SDValue();1178 1179 EVT ValTy = N->getValueType(0);1180 SDLoc DL(N);1181 1182 SDValue Add1 = DAG.getNode(ISD::ADD, DL, ValTy, Index, Other);1183 return DAG.getNode(ISD::ADD, DL, ValTy, Add1, Lo);1184}1185 1186static SDValue performSHLCombine(SDNode *N, SelectionDAG &DAG,1187 TargetLowering::DAGCombinerInfo &DCI,1188 const MipsSubtarget &Subtarget) {1189 // Pattern match CINS.1190 // $dst = shl (and $src , imm), pos1191 // => cins $dst, $src, pos, size1192 1193 if (DCI.isBeforeLegalizeOps() || !Subtarget.hasCnMips())1194 return SDValue();1195 1196 SDValue FirstOperand = N->getOperand(0);1197 unsigned FirstOperandOpc = FirstOperand.getOpcode();1198 SDValue SecondOperand = N->getOperand(1);1199 EVT ValTy = N->getValueType(0);1200 SDLoc DL(N);1201 1202 uint64_t Pos = 0;1203 unsigned SMPos, SMSize;1204 ConstantSDNode *CN;1205 SDValue NewOperand;1206 1207 // The second operand of the shift must be an immediate.1208 if (!(CN = dyn_cast<ConstantSDNode>(SecondOperand)))1209 return SDValue();1210 1211 Pos = CN->getZExtValue();1212 1213 if (Pos >= ValTy.getSizeInBits())1214 return SDValue();1215 1216 if (FirstOperandOpc != ISD::AND)1217 return SDValue();1218 1219 // AND's second operand must be a shifted mask.1220 if (!(CN = dyn_cast<ConstantSDNode>(FirstOperand.getOperand(1))) ||1221 !isShiftedMask_64(CN->getZExtValue(), SMPos, SMSize))1222 return SDValue();1223 1224 // Return if the shifted mask does not start at bit 0 or the sum of its size1225 // and Pos exceeds the word's size.1226 if (SMPos != 0 || SMSize > 32 || Pos + SMSize > ValTy.getSizeInBits())1227 return SDValue();1228 1229 NewOperand = FirstOperand.getOperand(0);1230 // SMSize is 'location' (position) in this case, not size.1231 SMSize--;1232 1233 return DAG.getNode(MipsISD::CIns, DL, ValTy, NewOperand,1234 DAG.getConstant(Pos, DL, MVT::i32),1235 DAG.getConstant(SMSize, DL, MVT::i32));1236}1237 1238static SDValue performSignExtendCombine(SDNode *N, SelectionDAG &DAG,1239 TargetLowering::DAGCombinerInfo &DCI,1240 const MipsSubtarget &Subtarget) {1241 if (DCI.Level != AfterLegalizeDAG || !Subtarget.isGP64bit()) {1242 return SDValue();1243 }1244 1245 SDValue N0 = N->getOperand(0);1246 EVT VT = N->getValueType(0);1247 1248 // Pattern match XOR.1249 // $dst = sign_extend (xor (trunc $src, i32), imm)1250 // => $dst = xor (signext_inreg $src, i32), imm1251 if (N0.getOpcode() == ISD::XOR &&1252 N0.getOperand(0).getOpcode() == ISD::TRUNCATE &&1253 N0.getOperand(1).getOpcode() == ISD::Constant) {1254 SDValue TruncateSource = N0.getOperand(0).getOperand(0);1255 auto *ConstantOperand = dyn_cast<ConstantSDNode>(N0->getOperand(1));1256 1257 SDValue FirstOperand =1258 DAG.getNode(ISD::SIGN_EXTEND_INREG, SDLoc(N0), VT, TruncateSource,1259 DAG.getValueType(N0.getOperand(0).getValueType()));1260 1261 int64_t ConstImm = ConstantOperand->getSExtValue();1262 return DAG.getNode(ISD::XOR, SDLoc(N0), VT, FirstOperand,1263 DAG.getConstant(ConstImm, SDLoc(N0), VT));1264 }1265 1266 return SDValue();1267}1268 1269SDValue MipsTargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI)1270 const {1271 SelectionDAG &DAG = DCI.DAG;1272 unsigned Opc = N->getOpcode();1273 1274 switch (Opc) {1275 default: break;1276 case ISD::SDIVREM:1277 case ISD::UDIVREM:1278 return performDivRemCombine(N, DAG, DCI, Subtarget);1279 case ISD::SELECT:1280 return performSELECTCombine(N, DAG, DCI, Subtarget);1281 case MipsISD::CMovFP_F:1282 case MipsISD::CMovFP_T:1283 return performCMovFPCombine(N, DAG, DCI, Subtarget);1284 case ISD::AND:1285 return performANDCombine(N, DAG, DCI, Subtarget);1286 case ISD::OR:1287 return performORCombine(N, DAG, DCI, Subtarget);1288 case ISD::ADD:1289 return performADDCombine(N, DAG, DCI, Subtarget);1290 case ISD::SHL:1291 return performSHLCombine(N, DAG, DCI, Subtarget);1292 case ISD::SUB:1293 return performSUBCombine(N, DAG, DCI, Subtarget);1294 case ISD::SIGN_EXTEND:1295 return performSignExtendCombine(N, DAG, DCI, Subtarget);1296 }1297 1298 return SDValue();1299}1300 1301bool MipsTargetLowering::isCheapToSpeculateCttz(Type *Ty) const {1302 return Subtarget.hasMips32();1303}1304 1305bool MipsTargetLowering::isCheapToSpeculateCtlz(Type *Ty) const {1306 return Subtarget.hasMips32();1307}1308 1309bool MipsTargetLowering::hasBitTest(SDValue X, SDValue Y) const {1310 // We can use ANDI+SLTIU as a bit test. Y contains the bit position.1311 // For MIPSR2 or later, we may be able to use the `ext` instruction or its'1312 // double-word variants.1313 if (auto *C = dyn_cast<ConstantSDNode>(Y))1314 return C->getAPIntValue().ule(15);1315 1316 return false;1317}1318 1319bool MipsTargetLowering::shouldFoldConstantShiftPairToMask(1320 const SDNode *N) const {1321 assert(((N->getOpcode() == ISD::SHL &&1322 N->getOperand(0).getOpcode() == ISD::SRL) ||1323 (N->getOpcode() == ISD::SRL &&1324 N->getOperand(0).getOpcode() == ISD::SHL)) &&1325 "Expected shift-shift mask");1326 1327 if (N->getOperand(0).getValueType().isVector())1328 return false;1329 return true;1330}1331 1332void1333MipsTargetLowering::ReplaceNodeResults(SDNode *N,1334 SmallVectorImpl<SDValue> &Results,1335 SelectionDAG &DAG) const {1336 return LowerOperationWrapper(N, Results, DAG);1337}1338 1339SDValue MipsTargetLowering::1340LowerOperation(SDValue Op, SelectionDAG &DAG) const1341{1342 switch (Op.getOpcode())1343 {1344 case ISD::BRCOND: return lowerBRCOND(Op, DAG);1345 case ISD::ConstantPool: return lowerConstantPool(Op, DAG);1346 case ISD::GlobalAddress: return lowerGlobalAddress(Op, DAG);1347 case ISD::BlockAddress: return lowerBlockAddress(Op, DAG);1348 case ISD::GlobalTLSAddress: return lowerGlobalTLSAddress(Op, DAG);1349 case ISD::JumpTable: return lowerJumpTable(Op, DAG);1350 case ISD::SELECT: return lowerSELECT(Op, DAG);1351 case ISD::SETCC: return lowerSETCC(Op, DAG);1352 case ISD::STRICT_FSETCC:1353 case ISD::STRICT_FSETCCS:1354 return lowerFSETCC(Op, DAG);1355 case ISD::VASTART: return lowerVASTART(Op, DAG);1356 case ISD::VAARG: return lowerVAARG(Op, DAG);1357 case ISD::FCOPYSIGN: return lowerFCOPYSIGN(Op, DAG);1358 case ISD::FABS: return lowerFABS(Op, DAG);1359 case ISD::FCANONICALIZE:1360 return lowerFCANONICALIZE(Op, DAG);1361 case ISD::FRAMEADDR: return lowerFRAMEADDR(Op, DAG);1362 case ISD::RETURNADDR: return lowerRETURNADDR(Op, DAG);1363 case ISD::EH_RETURN: return lowerEH_RETURN(Op, DAG);1364 case ISD::ATOMIC_FENCE: return lowerATOMIC_FENCE(Op, DAG);1365 case ISD::SHL_PARTS: return lowerShiftLeftParts(Op, DAG);1366 case ISD::SRA_PARTS: return lowerShiftRightParts(Op, DAG, true);1367 case ISD::SRL_PARTS: return lowerShiftRightParts(Op, DAG, false);1368 case ISD::LOAD: return lowerLOAD(Op, DAG);1369 case ISD::STORE: return lowerSTORE(Op, DAG);1370 case ISD::EH_DWARF_CFA: return lowerEH_DWARF_CFA(Op, DAG);1371 case ISD::STRICT_FP_TO_SINT:1372 case ISD::STRICT_FP_TO_UINT:1373 return lowerSTRICT_FP_TO_INT(Op, DAG);1374 case ISD::FP_TO_SINT: return lowerFP_TO_SINT(Op, DAG);1375 case ISD::READCYCLECOUNTER:1376 return lowerREADCYCLECOUNTER(Op, DAG);1377 }1378 return SDValue();1379}1380 1381//===----------------------------------------------------------------------===//1382// Lower helper functions1383//===----------------------------------------------------------------------===//1384 1385// addLiveIn - This helper function adds the specified physical register to the1386// MachineFunction as a live in value. It also creates a corresponding1387// virtual register for it.1388static unsigned1389addLiveIn(MachineFunction &MF, unsigned PReg, const TargetRegisterClass *RC)1390{1391 Register VReg = MF.getRegInfo().createVirtualRegister(RC);1392 MF.getRegInfo().addLiveIn(PReg, VReg);1393 return VReg;1394}1395 1396static MachineBasicBlock *insertDivByZeroTrap(MachineInstr &MI,1397 MachineBasicBlock &MBB,1398 const TargetInstrInfo &TII,1399 bool Is64Bit, bool IsMicroMips) {1400 if (NoZeroDivCheck)1401 return &MBB;1402 1403 // Insert instruction "teq $divisor_reg, $zero, 7".1404 MachineBasicBlock::iterator I(MI);1405 MachineInstrBuilder MIB;1406 MachineOperand &Divisor = MI.getOperand(2);1407 MIB = BuildMI(MBB, std::next(I), MI.getDebugLoc(),1408 TII.get(IsMicroMips ? Mips::TEQ_MM : Mips::TEQ))1409 .addReg(Divisor.getReg(), getKillRegState(Divisor.isKill()))1410 .addReg(Mips::ZERO)1411 .addImm(7);1412 1413 // Use the 32-bit sub-register if this is a 64-bit division.1414 if (Is64Bit)1415 MIB->getOperand(0).setSubReg(Mips::sub_32);1416 1417 // Clear Divisor's kill flag.1418 Divisor.setIsKill(false);1419 1420 // We would normally delete the original instruction here but in this case1421 // we only needed to inject an additional instruction rather than replace it.1422 1423 return &MBB;1424}1425 1426MachineBasicBlock *1427MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,1428 MachineBasicBlock *BB) const {1429 switch (MI.getOpcode()) {1430 default:1431 llvm_unreachable("Unexpected instr type to insert");1432 case Mips::ATOMIC_LOAD_ADD_I8:1433 return emitAtomicBinaryPartword(MI, BB, 1);1434 case Mips::ATOMIC_LOAD_ADD_I16:1435 return emitAtomicBinaryPartword(MI, BB, 2);1436 case Mips::ATOMIC_LOAD_ADD_I32:1437 return emitAtomicBinary(MI, BB);1438 case Mips::ATOMIC_LOAD_ADD_I64:1439 return emitAtomicBinary(MI, BB);1440 1441 case Mips::ATOMIC_LOAD_AND_I8:1442 return emitAtomicBinaryPartword(MI, BB, 1);1443 case Mips::ATOMIC_LOAD_AND_I16:1444 return emitAtomicBinaryPartword(MI, BB, 2);1445 case Mips::ATOMIC_LOAD_AND_I32:1446 return emitAtomicBinary(MI, BB);1447 case Mips::ATOMIC_LOAD_AND_I64:1448 return emitAtomicBinary(MI, BB);1449 1450 case Mips::ATOMIC_LOAD_OR_I8:1451 return emitAtomicBinaryPartword(MI, BB, 1);1452 case Mips::ATOMIC_LOAD_OR_I16:1453 return emitAtomicBinaryPartword(MI, BB, 2);1454 case Mips::ATOMIC_LOAD_OR_I32:1455 return emitAtomicBinary(MI, BB);1456 case Mips::ATOMIC_LOAD_OR_I64:1457 return emitAtomicBinary(MI, BB);1458 1459 case Mips::ATOMIC_LOAD_XOR_I8:1460 return emitAtomicBinaryPartword(MI, BB, 1);1461 case Mips::ATOMIC_LOAD_XOR_I16:1462 return emitAtomicBinaryPartword(MI, BB, 2);1463 case Mips::ATOMIC_LOAD_XOR_I32:1464 return emitAtomicBinary(MI, BB);1465 case Mips::ATOMIC_LOAD_XOR_I64:1466 return emitAtomicBinary(MI, BB);1467 1468 case Mips::ATOMIC_LOAD_NAND_I8:1469 return emitAtomicBinaryPartword(MI, BB, 1);1470 case Mips::ATOMIC_LOAD_NAND_I16:1471 return emitAtomicBinaryPartword(MI, BB, 2);1472 case Mips::ATOMIC_LOAD_NAND_I32:1473 return emitAtomicBinary(MI, BB);1474 case Mips::ATOMIC_LOAD_NAND_I64:1475 return emitAtomicBinary(MI, BB);1476 1477 case Mips::ATOMIC_LOAD_SUB_I8:1478 return emitAtomicBinaryPartword(MI, BB, 1);1479 case Mips::ATOMIC_LOAD_SUB_I16:1480 return emitAtomicBinaryPartword(MI, BB, 2);1481 case Mips::ATOMIC_LOAD_SUB_I32:1482 return emitAtomicBinary(MI, BB);1483 case Mips::ATOMIC_LOAD_SUB_I64:1484 return emitAtomicBinary(MI, BB);1485 1486 case Mips::ATOMIC_SWAP_I8:1487 return emitAtomicBinaryPartword(MI, BB, 1);1488 case Mips::ATOMIC_SWAP_I16:1489 return emitAtomicBinaryPartword(MI, BB, 2);1490 case Mips::ATOMIC_SWAP_I32:1491 return emitAtomicBinary(MI, BB);1492 case Mips::ATOMIC_SWAP_I64:1493 return emitAtomicBinary(MI, BB);1494 1495 case Mips::ATOMIC_CMP_SWAP_I8:1496 return emitAtomicCmpSwapPartword(MI, BB, 1);1497 case Mips::ATOMIC_CMP_SWAP_I16:1498 return emitAtomicCmpSwapPartword(MI, BB, 2);1499 case Mips::ATOMIC_CMP_SWAP_I32:1500 return emitAtomicCmpSwap(MI, BB);1501 case Mips::ATOMIC_CMP_SWAP_I64:1502 return emitAtomicCmpSwap(MI, BB);1503 1504 case Mips::ATOMIC_LOAD_MIN_I8:1505 return emitAtomicBinaryPartword(MI, BB, 1);1506 case Mips::ATOMIC_LOAD_MIN_I16:1507 return emitAtomicBinaryPartword(MI, BB, 2);1508 case Mips::ATOMIC_LOAD_MIN_I32:1509 return emitAtomicBinary(MI, BB);1510 case Mips::ATOMIC_LOAD_MIN_I64:1511 return emitAtomicBinary(MI, BB);1512 1513 case Mips::ATOMIC_LOAD_MAX_I8:1514 return emitAtomicBinaryPartword(MI, BB, 1);1515 case Mips::ATOMIC_LOAD_MAX_I16:1516 return emitAtomicBinaryPartword(MI, BB, 2);1517 case Mips::ATOMIC_LOAD_MAX_I32:1518 return emitAtomicBinary(MI, BB);1519 case Mips::ATOMIC_LOAD_MAX_I64:1520 return emitAtomicBinary(MI, BB);1521 1522 case Mips::ATOMIC_LOAD_UMIN_I8:1523 return emitAtomicBinaryPartword(MI, BB, 1);1524 case Mips::ATOMIC_LOAD_UMIN_I16:1525 return emitAtomicBinaryPartword(MI, BB, 2);1526 case Mips::ATOMIC_LOAD_UMIN_I32:1527 return emitAtomicBinary(MI, BB);1528 case Mips::ATOMIC_LOAD_UMIN_I64:1529 return emitAtomicBinary(MI, BB);1530 1531 case Mips::ATOMIC_LOAD_UMAX_I8:1532 return emitAtomicBinaryPartword(MI, BB, 1);1533 case Mips::ATOMIC_LOAD_UMAX_I16:1534 return emitAtomicBinaryPartword(MI, BB, 2);1535 case Mips::ATOMIC_LOAD_UMAX_I32:1536 return emitAtomicBinary(MI, BB);1537 case Mips::ATOMIC_LOAD_UMAX_I64:1538 return emitAtomicBinary(MI, BB);1539 1540 case Mips::PseudoSDIV:1541 case Mips::PseudoUDIV:1542 case Mips::DIV:1543 case Mips::DIVU:1544 case Mips::MOD:1545 case Mips::MODU:1546 return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false,1547 false);1548 case Mips::SDIV_MM_Pseudo:1549 case Mips::UDIV_MM_Pseudo:1550 case Mips::SDIV_MM:1551 case Mips::UDIV_MM:1552 case Mips::DIV_MMR6:1553 case Mips::DIVU_MMR6:1554 case Mips::MOD_MMR6:1555 case Mips::MODU_MMR6:1556 return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), false, true);1557 case Mips::PseudoDSDIV:1558 case Mips::PseudoDUDIV:1559 case Mips::DDIV:1560 case Mips::DDIVU:1561 case Mips::DMOD:1562 case Mips::DMODU:1563 return insertDivByZeroTrap(MI, *BB, *Subtarget.getInstrInfo(), true, false);1564 1565 case Mips::PseudoSELECT_I:1566 case Mips::PseudoSELECT_I64:1567 case Mips::PseudoSELECT_S:1568 case Mips::PseudoSELECT_D32:1569 case Mips::PseudoSELECT_D64:1570 return emitPseudoSELECT(MI, BB, false, Mips::BNE);1571 case Mips::PseudoSELECTFP_F_I:1572 case Mips::PseudoSELECTFP_F_I64:1573 case Mips::PseudoSELECTFP_F_S:1574 case Mips::PseudoSELECTFP_F_D32:1575 case Mips::PseudoSELECTFP_F_D64:1576 return emitPseudoSELECT(MI, BB, true, Mips::BC1F);1577 case Mips::PseudoSELECTFP_T_I:1578 case Mips::PseudoSELECTFP_T_I64:1579 case Mips::PseudoSELECTFP_T_S:1580 case Mips::PseudoSELECTFP_T_D32:1581 case Mips::PseudoSELECTFP_T_D64:1582 return emitPseudoSELECT(MI, BB, true, Mips::BC1T);1583 case Mips::PseudoD_SELECT_I:1584 case Mips::PseudoD_SELECT_I64:1585 return emitPseudoD_SELECT(MI, BB);1586 case Mips::LDR_W:1587 return emitLDR_W(MI, BB);1588 case Mips::LDR_D:1589 return emitLDR_D(MI, BB);1590 case Mips::STR_W:1591 return emitSTR_W(MI, BB);1592 case Mips::STR_D:1593 return emitSTR_D(MI, BB);1594 }1595}1596 1597// This function also handles Mips::ATOMIC_SWAP_I32 (when BinOpcode == 0), and1598// Mips::ATOMIC_LOAD_NAND_I32 (when Nand == true)1599MachineBasicBlock *1600MipsTargetLowering::emitAtomicBinary(MachineInstr &MI,1601 MachineBasicBlock *BB) const {1602 1603 MachineFunction *MF = BB->getParent();1604 MachineRegisterInfo &RegInfo = MF->getRegInfo();1605 const TargetInstrInfo *TII = Subtarget.getInstrInfo();1606 DebugLoc DL = MI.getDebugLoc();1607 1608 unsigned AtomicOp;1609 bool NeedsAdditionalReg = false;1610 switch (MI.getOpcode()) {1611 case Mips::ATOMIC_LOAD_ADD_I32:1612 AtomicOp = Mips::ATOMIC_LOAD_ADD_I32_POSTRA;1613 break;1614 case Mips::ATOMIC_LOAD_SUB_I32:1615 AtomicOp = Mips::ATOMIC_LOAD_SUB_I32_POSTRA;1616 break;1617 case Mips::ATOMIC_LOAD_AND_I32:1618 AtomicOp = Mips::ATOMIC_LOAD_AND_I32_POSTRA;1619 break;1620 case Mips::ATOMIC_LOAD_OR_I32:1621 AtomicOp = Mips::ATOMIC_LOAD_OR_I32_POSTRA;1622 break;1623 case Mips::ATOMIC_LOAD_XOR_I32:1624 AtomicOp = Mips::ATOMIC_LOAD_XOR_I32_POSTRA;1625 break;1626 case Mips::ATOMIC_LOAD_NAND_I32:1627 AtomicOp = Mips::ATOMIC_LOAD_NAND_I32_POSTRA;1628 break;1629 case Mips::ATOMIC_SWAP_I32:1630 AtomicOp = Mips::ATOMIC_SWAP_I32_POSTRA;1631 break;1632 case Mips::ATOMIC_LOAD_ADD_I64:1633 AtomicOp = Mips::ATOMIC_LOAD_ADD_I64_POSTRA;1634 break;1635 case Mips::ATOMIC_LOAD_SUB_I64:1636 AtomicOp = Mips::ATOMIC_LOAD_SUB_I64_POSTRA;1637 break;1638 case Mips::ATOMIC_LOAD_AND_I64:1639 AtomicOp = Mips::ATOMIC_LOAD_AND_I64_POSTRA;1640 break;1641 case Mips::ATOMIC_LOAD_OR_I64:1642 AtomicOp = Mips::ATOMIC_LOAD_OR_I64_POSTRA;1643 break;1644 case Mips::ATOMIC_LOAD_XOR_I64:1645 AtomicOp = Mips::ATOMIC_LOAD_XOR_I64_POSTRA;1646 break;1647 case Mips::ATOMIC_LOAD_NAND_I64:1648 AtomicOp = Mips::ATOMIC_LOAD_NAND_I64_POSTRA;1649 break;1650 case Mips::ATOMIC_SWAP_I64:1651 AtomicOp = Mips::ATOMIC_SWAP_I64_POSTRA;1652 break;1653 case Mips::ATOMIC_LOAD_MIN_I32:1654 AtomicOp = Mips::ATOMIC_LOAD_MIN_I32_POSTRA;1655 NeedsAdditionalReg = true;1656 break;1657 case Mips::ATOMIC_LOAD_MAX_I32:1658 AtomicOp = Mips::ATOMIC_LOAD_MAX_I32_POSTRA;1659 NeedsAdditionalReg = true;1660 break;1661 case Mips::ATOMIC_LOAD_UMIN_I32:1662 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I32_POSTRA;1663 NeedsAdditionalReg = true;1664 break;1665 case Mips::ATOMIC_LOAD_UMAX_I32:1666 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I32_POSTRA;1667 NeedsAdditionalReg = true;1668 break;1669 case Mips::ATOMIC_LOAD_MIN_I64:1670 AtomicOp = Mips::ATOMIC_LOAD_MIN_I64_POSTRA;1671 NeedsAdditionalReg = true;1672 break;1673 case Mips::ATOMIC_LOAD_MAX_I64:1674 AtomicOp = Mips::ATOMIC_LOAD_MAX_I64_POSTRA;1675 NeedsAdditionalReg = true;1676 break;1677 case Mips::ATOMIC_LOAD_UMIN_I64:1678 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I64_POSTRA;1679 NeedsAdditionalReg = true;1680 break;1681 case Mips::ATOMIC_LOAD_UMAX_I64:1682 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I64_POSTRA;1683 NeedsAdditionalReg = true;1684 break;1685 default:1686 llvm_unreachable("Unknown pseudo atomic for replacement!");1687 }1688 1689 Register OldVal = MI.getOperand(0).getReg();1690 Register Ptr = MI.getOperand(1).getReg();1691 Register Incr = MI.getOperand(2).getReg();1692 Register Scratch = RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));1693 1694 MachineBasicBlock::iterator II(MI);1695 1696 // The scratch registers here with the EarlyClobber | Define | Implicit1697 // flags is used to persuade the register allocator and the machine1698 // verifier to accept the usage of this register. This has to be a real1699 // register which has an UNDEF value but is dead after the instruction which1700 // is unique among the registers chosen for the instruction.1701 1702 // The EarlyClobber flag has the semantic properties that the operand it is1703 // attached to is clobbered before the rest of the inputs are read. Hence it1704 // must be unique among the operands to the instruction.1705 // The Define flag is needed to coerce the machine verifier that an Undef1706 // value isn't a problem.1707 // The Dead flag is needed as the value in scratch isn't used by any other1708 // instruction. Kill isn't used as Dead is more precise.1709 // The implicit flag is here due to the interaction between the other flags1710 // and the machine verifier.1711 1712 // For correctness purpose, a new pseudo is introduced here. We need this1713 // new pseudo, so that FastRegisterAllocator does not see an ll/sc sequence1714 // that is spread over >1 basic blocks. A register allocator which1715 // introduces (or any codegen infact) a store, can violate the expectations1716 // of the hardware.1717 //1718 // An atomic read-modify-write sequence starts with a linked load1719 // instruction and ends with a store conditional instruction. The atomic1720 // read-modify-write sequence fails if any of the following conditions1721 // occur between the execution of ll and sc:1722 // * A coherent store is completed by another process or coherent I/O1723 // module into the block of synchronizable physical memory containing1724 // the word. The size and alignment of the block is1725 // implementation-dependent.1726 // * A coherent store is executed between an LL and SC sequence on the1727 // same processor to the block of synchornizable physical memory1728 // containing the word.1729 //1730 1731 Register PtrCopy = RegInfo.createVirtualRegister(RegInfo.getRegClass(Ptr));1732 Register IncrCopy = RegInfo.createVirtualRegister(RegInfo.getRegClass(Incr));1733 1734 BuildMI(*BB, II, DL, TII->get(Mips::COPY), IncrCopy).addReg(Incr);1735 BuildMI(*BB, II, DL, TII->get(Mips::COPY), PtrCopy).addReg(Ptr);1736 1737 MachineInstrBuilder MIB =1738 BuildMI(*BB, II, DL, TII->get(AtomicOp))1739 .addReg(OldVal, RegState::Define | RegState::EarlyClobber)1740 .addReg(PtrCopy)1741 .addReg(IncrCopy)1742 .addReg(Scratch, RegState::Define | RegState::EarlyClobber |1743 RegState::Implicit | RegState::Dead);1744 if (NeedsAdditionalReg) {1745 Register Scratch2 =1746 RegInfo.createVirtualRegister(RegInfo.getRegClass(OldVal));1747 MIB.addReg(Scratch2, RegState::Define | RegState::EarlyClobber |1748 RegState::Implicit | RegState::Dead);1749 }1750 1751 MI.eraseFromParent();1752 1753 return BB;1754}1755 1756MachineBasicBlock *MipsTargetLowering::emitSignExtendToI32InReg(1757 MachineInstr &MI, MachineBasicBlock *BB, unsigned Size, unsigned DstReg,1758 unsigned SrcReg) const {1759 const TargetInstrInfo *TII = Subtarget.getInstrInfo();1760 const DebugLoc &DL = MI.getDebugLoc();1761 1762 if (Subtarget.hasMips32r2() && Size == 1) {1763 BuildMI(BB, DL, TII->get(Mips::SEB), DstReg).addReg(SrcReg);1764 return BB;1765 }1766 1767 if (Subtarget.hasMips32r2() && Size == 2) {1768 BuildMI(BB, DL, TII->get(Mips::SEH), DstReg).addReg(SrcReg);1769 return BB;1770 }1771 1772 MachineFunction *MF = BB->getParent();1773 MachineRegisterInfo &RegInfo = MF->getRegInfo();1774 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);1775 Register ScrReg = RegInfo.createVirtualRegister(RC);1776 1777 assert(Size < 32);1778 int64_t ShiftImm = 32 - (Size * 8);1779 1780 BuildMI(BB, DL, TII->get(Mips::SLL), ScrReg).addReg(SrcReg).addImm(ShiftImm);1781 BuildMI(BB, DL, TII->get(Mips::SRA), DstReg).addReg(ScrReg).addImm(ShiftImm);1782 1783 return BB;1784}1785 1786MachineBasicBlock *MipsTargetLowering::emitAtomicBinaryPartword(1787 MachineInstr &MI, MachineBasicBlock *BB, unsigned Size) const {1788 assert((Size == 1 || Size == 2) &&1789 "Unsupported size for EmitAtomicBinaryPartial.");1790 1791 MachineFunction *MF = BB->getParent();1792 MachineRegisterInfo &RegInfo = MF->getRegInfo();1793 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);1794 const bool ArePtrs64bit = ABI.ArePtrs64bit();1795 const TargetRegisterClass *RCp =1796 getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32);1797 const TargetInstrInfo *TII = Subtarget.getInstrInfo();1798 DebugLoc DL = MI.getDebugLoc();1799 1800 Register Dest = MI.getOperand(0).getReg();1801 Register Ptr = MI.getOperand(1).getReg();1802 Register Incr = MI.getOperand(2).getReg();1803 1804 Register AlignedAddr = RegInfo.createVirtualRegister(RCp);1805 Register ShiftAmt = RegInfo.createVirtualRegister(RC);1806 Register Mask = RegInfo.createVirtualRegister(RC);1807 Register Mask2 = RegInfo.createVirtualRegister(RC);1808 Register Incr2 = RegInfo.createVirtualRegister(RC);1809 Register MaskLSB2 = RegInfo.createVirtualRegister(RCp);1810 Register PtrLSB2 = RegInfo.createVirtualRegister(RC);1811 Register MaskUpper = RegInfo.createVirtualRegister(RC);1812 Register Scratch = RegInfo.createVirtualRegister(RC);1813 Register Scratch2 = RegInfo.createVirtualRegister(RC);1814 Register Scratch3 = RegInfo.createVirtualRegister(RC);1815 1816 unsigned AtomicOp = 0;1817 bool NeedsAdditionalReg = false;1818 switch (MI.getOpcode()) {1819 case Mips::ATOMIC_LOAD_NAND_I8:1820 AtomicOp = Mips::ATOMIC_LOAD_NAND_I8_POSTRA;1821 break;1822 case Mips::ATOMIC_LOAD_NAND_I16:1823 AtomicOp = Mips::ATOMIC_LOAD_NAND_I16_POSTRA;1824 break;1825 case Mips::ATOMIC_SWAP_I8:1826 AtomicOp = Mips::ATOMIC_SWAP_I8_POSTRA;1827 break;1828 case Mips::ATOMIC_SWAP_I16:1829 AtomicOp = Mips::ATOMIC_SWAP_I16_POSTRA;1830 break;1831 case Mips::ATOMIC_LOAD_ADD_I8:1832 AtomicOp = Mips::ATOMIC_LOAD_ADD_I8_POSTRA;1833 break;1834 case Mips::ATOMIC_LOAD_ADD_I16:1835 AtomicOp = Mips::ATOMIC_LOAD_ADD_I16_POSTRA;1836 break;1837 case Mips::ATOMIC_LOAD_SUB_I8:1838 AtomicOp = Mips::ATOMIC_LOAD_SUB_I8_POSTRA;1839 break;1840 case Mips::ATOMIC_LOAD_SUB_I16:1841 AtomicOp = Mips::ATOMIC_LOAD_SUB_I16_POSTRA;1842 break;1843 case Mips::ATOMIC_LOAD_AND_I8:1844 AtomicOp = Mips::ATOMIC_LOAD_AND_I8_POSTRA;1845 break;1846 case Mips::ATOMIC_LOAD_AND_I16:1847 AtomicOp = Mips::ATOMIC_LOAD_AND_I16_POSTRA;1848 break;1849 case Mips::ATOMIC_LOAD_OR_I8:1850 AtomicOp = Mips::ATOMIC_LOAD_OR_I8_POSTRA;1851 break;1852 case Mips::ATOMIC_LOAD_OR_I16:1853 AtomicOp = Mips::ATOMIC_LOAD_OR_I16_POSTRA;1854 break;1855 case Mips::ATOMIC_LOAD_XOR_I8:1856 AtomicOp = Mips::ATOMIC_LOAD_XOR_I8_POSTRA;1857 break;1858 case Mips::ATOMIC_LOAD_XOR_I16:1859 AtomicOp = Mips::ATOMIC_LOAD_XOR_I16_POSTRA;1860 break;1861 case Mips::ATOMIC_LOAD_MIN_I8:1862 AtomicOp = Mips::ATOMIC_LOAD_MIN_I8_POSTRA;1863 NeedsAdditionalReg = true;1864 break;1865 case Mips::ATOMIC_LOAD_MIN_I16:1866 AtomicOp = Mips::ATOMIC_LOAD_MIN_I16_POSTRA;1867 NeedsAdditionalReg = true;1868 break;1869 case Mips::ATOMIC_LOAD_MAX_I8:1870 AtomicOp = Mips::ATOMIC_LOAD_MAX_I8_POSTRA;1871 NeedsAdditionalReg = true;1872 break;1873 case Mips::ATOMIC_LOAD_MAX_I16:1874 AtomicOp = Mips::ATOMIC_LOAD_MAX_I16_POSTRA;1875 NeedsAdditionalReg = true;1876 break;1877 case Mips::ATOMIC_LOAD_UMIN_I8:1878 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I8_POSTRA;1879 NeedsAdditionalReg = true;1880 break;1881 case Mips::ATOMIC_LOAD_UMIN_I16:1882 AtomicOp = Mips::ATOMIC_LOAD_UMIN_I16_POSTRA;1883 NeedsAdditionalReg = true;1884 break;1885 case Mips::ATOMIC_LOAD_UMAX_I8:1886 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I8_POSTRA;1887 NeedsAdditionalReg = true;1888 break;1889 case Mips::ATOMIC_LOAD_UMAX_I16:1890 AtomicOp = Mips::ATOMIC_LOAD_UMAX_I16_POSTRA;1891 NeedsAdditionalReg = true;1892 break;1893 default:1894 llvm_unreachable("Unknown subword atomic pseudo for expansion!");1895 }1896 1897 // insert new blocks after the current block1898 const BasicBlock *LLVM_BB = BB->getBasicBlock();1899 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);1900 MachineFunction::iterator It = ++BB->getIterator();1901 MF->insert(It, exitMBB);1902 1903 // Transfer the remainder of BB and its successor edges to exitMBB.1904 exitMBB->splice(exitMBB->begin(), BB,1905 std::next(MachineBasicBlock::iterator(MI)), BB->end());1906 exitMBB->transferSuccessorsAndUpdatePHIs(BB);1907 1908 BB->addSuccessor(exitMBB, BranchProbability::getOne());1909 1910 // thisMBB:1911 // addiu masklsb2,$0,-4 # 0xfffffffc1912 // and alignedaddr,ptr,masklsb21913 // andi ptrlsb2,ptr,31914 // sll shiftamt,ptrlsb2,31915 // ori maskupper,$0,255 # 0xff1916 // sll mask,maskupper,shiftamt1917 // nor mask2,$0,mask1918 // sll incr2,incr,shiftamt1919 1920 int64_t MaskImm = (Size == 1) ? 255 : 65535;1921 BuildMI(BB, DL, TII->get(ABI.GetPtrAddiuOp()), MaskLSB2)1922 .addReg(ABI.GetNullPtr()).addImm(-4);1923 BuildMI(BB, DL, TII->get(ABI.GetPtrAndOp()), AlignedAddr)1924 .addReg(Ptr).addReg(MaskLSB2);1925 BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2)1926 .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0).addImm(3);1927 if (Subtarget.isLittle()) {1928 BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);1929 } else {1930 Register Off = RegInfo.createVirtualRegister(RC);1931 BuildMI(BB, DL, TII->get(Mips::XORi), Off)1932 .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2);1933 BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3);1934 }1935 BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper)1936 .addReg(Mips::ZERO).addImm(MaskImm);1937 BuildMI(BB, DL, TII->get(Mips::SLLV), Mask)1938 .addReg(MaskUpper).addReg(ShiftAmt);1939 BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);1940 BuildMI(BB, DL, TII->get(Mips::SLLV), Incr2).addReg(Incr).addReg(ShiftAmt);1941 1942 1943 // The purposes of the flags on the scratch registers is explained in1944 // emitAtomicBinary. In summary, we need a scratch register which is going to1945 // be undef, that is unique among registers chosen for the instruction.1946 1947 MachineInstrBuilder MIB =1948 BuildMI(BB, DL, TII->get(AtomicOp))1949 .addReg(Dest, RegState::Define | RegState::EarlyClobber)1950 .addReg(AlignedAddr)1951 .addReg(Incr2)1952 .addReg(Mask)1953 .addReg(Mask2)1954 .addReg(ShiftAmt)1955 .addReg(Scratch, RegState::EarlyClobber | RegState::Define |1956 RegState::Dead | RegState::Implicit)1957 .addReg(Scratch2, RegState::EarlyClobber | RegState::Define |1958 RegState::Dead | RegState::Implicit)1959 .addReg(Scratch3, RegState::EarlyClobber | RegState::Define |1960 RegState::Dead | RegState::Implicit);1961 if (NeedsAdditionalReg) {1962 Register Scratch4 = RegInfo.createVirtualRegister(RC);1963 MIB.addReg(Scratch4, RegState::EarlyClobber | RegState::Define |1964 RegState::Dead | RegState::Implicit);1965 }1966 1967 MI.eraseFromParent(); // The instruction is gone now.1968 1969 return exitMBB;1970}1971 1972// Lower atomic compare and swap to a pseudo instruction, taking care to1973// define a scratch register for the pseudo instruction's expansion. The1974// instruction is expanded after the register allocator as to prevent1975// the insertion of stores between the linked load and the store conditional.1976 1977MachineBasicBlock *1978MipsTargetLowering::emitAtomicCmpSwap(MachineInstr &MI,1979 MachineBasicBlock *BB) const {1980 1981 assert((MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ||1982 MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I64) &&1983 "Unsupported atomic pseudo for EmitAtomicCmpSwap.");1984 1985 const unsigned Size = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I32 ? 4 : 8;1986 1987 MachineFunction *MF = BB->getParent();1988 MachineRegisterInfo &MRI = MF->getRegInfo();1989 const TargetRegisterClass *RC = getRegClassFor(MVT::getIntegerVT(Size * 8));1990 const TargetInstrInfo *TII = Subtarget.getInstrInfo();1991 DebugLoc DL = MI.getDebugLoc();1992 1993 unsigned AtomicOp = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I321994 ? Mips::ATOMIC_CMP_SWAP_I32_POSTRA1995 : Mips::ATOMIC_CMP_SWAP_I64_POSTRA;1996 Register Dest = MI.getOperand(0).getReg();1997 Register Ptr = MI.getOperand(1).getReg();1998 Register OldVal = MI.getOperand(2).getReg();1999 Register NewVal = MI.getOperand(3).getReg();2000 2001 Register Scratch = MRI.createVirtualRegister(RC);2002 MachineBasicBlock::iterator II(MI);2003 2004 // We need to create copies of the various registers and kill them at the2005 // atomic pseudo. If the copies are not made, when the atomic is expanded2006 // after fast register allocation, the spills will end up outside of the2007 // blocks that their values are defined in, causing livein errors.2008 2009 Register PtrCopy = MRI.createVirtualRegister(MRI.getRegClass(Ptr));2010 Register OldValCopy = MRI.createVirtualRegister(MRI.getRegClass(OldVal));2011 Register NewValCopy = MRI.createVirtualRegister(MRI.getRegClass(NewVal));2012 2013 BuildMI(*BB, II, DL, TII->get(Mips::COPY), PtrCopy).addReg(Ptr);2014 BuildMI(*BB, II, DL, TII->get(Mips::COPY), OldValCopy).addReg(OldVal);2015 BuildMI(*BB, II, DL, TII->get(Mips::COPY), NewValCopy).addReg(NewVal);2016 2017 // The purposes of the flags on the scratch registers is explained in2018 // emitAtomicBinary. In summary, we need a scratch register which is going to2019 // be undef, that is unique among registers chosen for the instruction.2020 2021 BuildMI(*BB, II, DL, TII->get(AtomicOp))2022 .addReg(Dest, RegState::Define | RegState::EarlyClobber)2023 .addReg(PtrCopy, RegState::Kill)2024 .addReg(OldValCopy, RegState::Kill)2025 .addReg(NewValCopy, RegState::Kill)2026 .addReg(Scratch, RegState::EarlyClobber | RegState::Define |2027 RegState::Dead | RegState::Implicit);2028 2029 MI.eraseFromParent(); // The instruction is gone now.2030 2031 return BB;2032}2033 2034MachineBasicBlock *MipsTargetLowering::emitAtomicCmpSwapPartword(2035 MachineInstr &MI, MachineBasicBlock *BB, unsigned Size) const {2036 assert((Size == 1 || Size == 2) &&2037 "Unsupported size for EmitAtomicCmpSwapPartial.");2038 2039 MachineFunction *MF = BB->getParent();2040 MachineRegisterInfo &RegInfo = MF->getRegInfo();2041 const TargetRegisterClass *RC = getRegClassFor(MVT::i32);2042 const bool ArePtrs64bit = ABI.ArePtrs64bit();2043 const TargetRegisterClass *RCp =2044 getRegClassFor(ArePtrs64bit ? MVT::i64 : MVT::i32);2045 const TargetInstrInfo *TII = Subtarget.getInstrInfo();2046 DebugLoc DL = MI.getDebugLoc();2047 2048 Register Dest = MI.getOperand(0).getReg();2049 Register Ptr = MI.getOperand(1).getReg();2050 Register CmpVal = MI.getOperand(2).getReg();2051 Register NewVal = MI.getOperand(3).getReg();2052 2053 Register AlignedAddr = RegInfo.createVirtualRegister(RCp);2054 Register ShiftAmt = RegInfo.createVirtualRegister(RC);2055 Register Mask = RegInfo.createVirtualRegister(RC);2056 Register Mask2 = RegInfo.createVirtualRegister(RC);2057 Register ShiftedCmpVal = RegInfo.createVirtualRegister(RC);2058 Register ShiftedNewVal = RegInfo.createVirtualRegister(RC);2059 Register MaskLSB2 = RegInfo.createVirtualRegister(RCp);2060 Register PtrLSB2 = RegInfo.createVirtualRegister(RC);2061 Register MaskUpper = RegInfo.createVirtualRegister(RC);2062 Register MaskedCmpVal = RegInfo.createVirtualRegister(RC);2063 Register MaskedNewVal = RegInfo.createVirtualRegister(RC);2064 unsigned AtomicOp = MI.getOpcode() == Mips::ATOMIC_CMP_SWAP_I82065 ? Mips::ATOMIC_CMP_SWAP_I8_POSTRA2066 : Mips::ATOMIC_CMP_SWAP_I16_POSTRA;2067 2068 // The scratch registers here with the EarlyClobber | Define | Dead | Implicit2069 // flags are used to coerce the register allocator and the machine verifier to2070 // accept the usage of these registers.2071 // The EarlyClobber flag has the semantic properties that the operand it is2072 // attached to is clobbered before the rest of the inputs are read. Hence it2073 // must be unique among the operands to the instruction.2074 // The Define flag is needed to coerce the machine verifier that an Undef2075 // value isn't a problem.2076 // The Dead flag is needed as the value in scratch isn't used by any other2077 // instruction. Kill isn't used as Dead is more precise.2078 Register Scratch = RegInfo.createVirtualRegister(RC);2079 Register Scratch2 = RegInfo.createVirtualRegister(RC);2080 2081 // insert new blocks after the current block2082 const BasicBlock *LLVM_BB = BB->getBasicBlock();2083 MachineBasicBlock *exitMBB = MF->CreateMachineBasicBlock(LLVM_BB);2084 MachineFunction::iterator It = ++BB->getIterator();2085 MF->insert(It, exitMBB);2086 2087 // Transfer the remainder of BB and its successor edges to exitMBB.2088 exitMBB->splice(exitMBB->begin(), BB,2089 std::next(MachineBasicBlock::iterator(MI)), BB->end());2090 exitMBB->transferSuccessorsAndUpdatePHIs(BB);2091 2092 BB->addSuccessor(exitMBB, BranchProbability::getOne());2093 2094 // thisMBB:2095 // addiu masklsb2,$0,-4 # 0xfffffffc2096 // and alignedaddr,ptr,masklsb22097 // andi ptrlsb2,ptr,32098 // xori ptrlsb2,ptrlsb2,3 # Only for BE2099 // sll shiftamt,ptrlsb2,32100 // ori maskupper,$0,255 # 0xff2101 // sll mask,maskupper,shiftamt2102 // nor mask2,$0,mask2103 // andi maskedcmpval,cmpval,2552104 // sll shiftedcmpval,maskedcmpval,shiftamt2105 // andi maskednewval,newval,2552106 // sll shiftednewval,maskednewval,shiftamt2107 int64_t MaskImm = (Size == 1) ? 255 : 65535;2108 BuildMI(BB, DL, TII->get(ArePtrs64bit ? Mips::DADDiu : Mips::ADDiu), MaskLSB2)2109 .addReg(ABI.GetNullPtr()).addImm(-4);2110 BuildMI(BB, DL, TII->get(ArePtrs64bit ? Mips::AND64 : Mips::AND), AlignedAddr)2111 .addReg(Ptr).addReg(MaskLSB2);2112 BuildMI(BB, DL, TII->get(Mips::ANDi), PtrLSB2)2113 .addReg(Ptr, 0, ArePtrs64bit ? Mips::sub_32 : 0).addImm(3);2114 if (Subtarget.isLittle()) {2115 BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(PtrLSB2).addImm(3);2116 } else {2117 Register Off = RegInfo.createVirtualRegister(RC);2118 BuildMI(BB, DL, TII->get(Mips::XORi), Off)2119 .addReg(PtrLSB2).addImm((Size == 1) ? 3 : 2);2120 BuildMI(BB, DL, TII->get(Mips::SLL), ShiftAmt).addReg(Off).addImm(3);2121 }2122 BuildMI(BB, DL, TII->get(Mips::ORi), MaskUpper)2123 .addReg(Mips::ZERO).addImm(MaskImm);2124 BuildMI(BB, DL, TII->get(Mips::SLLV), Mask)2125 .addReg(MaskUpper).addReg(ShiftAmt);2126 BuildMI(BB, DL, TII->get(Mips::NOR), Mask2).addReg(Mips::ZERO).addReg(Mask);2127 BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedCmpVal)2128 .addReg(CmpVal).addImm(MaskImm);2129 BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedCmpVal)2130 .addReg(MaskedCmpVal).addReg(ShiftAmt);2131 BuildMI(BB, DL, TII->get(Mips::ANDi), MaskedNewVal)2132 .addReg(NewVal).addImm(MaskImm);2133 BuildMI(BB, DL, TII->get(Mips::SLLV), ShiftedNewVal)2134 .addReg(MaskedNewVal).addReg(ShiftAmt);2135 2136 // The purposes of the flags on the scratch registers are explained in2137 // emitAtomicBinary. In summary, we need a scratch register which is going to2138 // be undef, that is unique among the register chosen for the instruction.2139 2140 BuildMI(BB, DL, TII->get(AtomicOp))2141 .addReg(Dest, RegState::Define | RegState::EarlyClobber)2142 .addReg(AlignedAddr)2143 .addReg(Mask)2144 .addReg(ShiftedCmpVal)2145 .addReg(Mask2)2146 .addReg(ShiftedNewVal)2147 .addReg(ShiftAmt)2148 .addReg(Scratch, RegState::EarlyClobber | RegState::Define |2149 RegState::Dead | RegState::Implicit)2150 .addReg(Scratch2, RegState::EarlyClobber | RegState::Define |2151 RegState::Dead | RegState::Implicit);2152 2153 MI.eraseFromParent(); // The instruction is gone now.2154 2155 return exitMBB;2156}2157 2158SDValue MipsTargetLowering::lowerREADCYCLECOUNTER(SDValue Op,2159 SelectionDAG &DAG) const {2160 SmallVector<SDValue, 3> Results;2161 SDLoc DL(Op);2162 MachineFunction &MF = DAG.getMachineFunction();2163 unsigned RdhwrOpc, DestReg;2164 EVT PtrVT = getPointerTy(DAG.getDataLayout());2165 2166 if (PtrVT == MVT::i64) {2167 RdhwrOpc = Mips::RDHWR64;2168 DestReg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));2169 SDNode *Rdhwr = DAG.getMachineNode(RdhwrOpc, DL, MVT::i64, MVT::Glue,2170 DAG.getRegister(Mips::HWR2, MVT::i32),2171 DAG.getTargetConstant(0, DL, MVT::i32));2172 SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), DL, DestReg,2173 SDValue(Rdhwr, 0), SDValue(Rdhwr, 1));2174 SDValue ResNode =2175 DAG.getCopyFromReg(Chain, DL, DestReg, MVT::i64, Chain.getValue(1));2176 Results.push_back(ResNode);2177 Results.push_back(ResNode.getValue(1));2178 } else {2179 RdhwrOpc = Mips::RDHWR;2180 DestReg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i32));2181 SDNode *Rdhwr = DAG.getMachineNode(RdhwrOpc, DL, MVT::i32, MVT::Glue,2182 DAG.getRegister(Mips::HWR2, MVT::i32),2183 DAG.getTargetConstant(0, DL, MVT::i32));2184 SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), DL, DestReg,2185 SDValue(Rdhwr, 0), SDValue(Rdhwr, 1));2186 SDValue ResNode =2187 DAG.getCopyFromReg(Chain, DL, DestReg, MVT::i32, Chain.getValue(1));2188 Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, ResNode,2189 DAG.getConstant(0, DL, MVT::i32)));2190 Results.push_back(ResNode.getValue(1));2191 }2192 2193 return DAG.getMergeValues(Results, DL);2194}2195 2196SDValue MipsTargetLowering::lowerBRCOND(SDValue Op, SelectionDAG &DAG) const {2197 // The first operand is the chain, the second is the condition, the third is2198 // the block to branch to if the condition is true.2199 SDValue Chain = Op.getOperand(0);2200 SDValue Dest = Op.getOperand(2);2201 SDLoc DL(Op);2202 2203 assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());2204 SDValue CondRes = createFPCmp(DAG, Op.getOperand(1));2205 2206 // Return if flag is not set by a floating point comparison.2207 if (CondRes.getOpcode() != MipsISD::FPCmp)2208 return Op;2209 2210 SDValue CCNode = CondRes.getOperand(2);2211 Mips::CondCode CC = (Mips::CondCode)CCNode->getAsZExtVal();2212 unsigned Opc = invertFPCondCodeUser(CC) ? Mips::BRANCH_F : Mips::BRANCH_T;2213 SDValue BrCode = DAG.getConstant(Opc, DL, MVT::i32);2214 SDValue FCC0 = DAG.getRegister(Mips::FCC0, MVT::i32);2215 return DAG.getNode(MipsISD::FPBrcond, DL, Op.getValueType(), Chain, BrCode,2216 FCC0, Dest, CondRes);2217}2218 2219SDValue MipsTargetLowering::2220lowerSELECT(SDValue Op, SelectionDAG &DAG) const2221{2222 assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());2223 SDValue Cond = createFPCmp(DAG, Op.getOperand(0));2224 2225 // Return if flag is not set by a floating point comparison.2226 if (Cond.getOpcode() != MipsISD::FPCmp)2227 return Op;2228 2229 return createCMovFP(DAG, Cond, Op.getOperand(1), Op.getOperand(2),2230 SDLoc(Op));2231}2232 2233SDValue MipsTargetLowering::lowerSETCC(SDValue Op, SelectionDAG &DAG) const {2234 assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());2235 SDValue Cond = createFPCmp(DAG, Op);2236 2237 assert(Cond.getOpcode() == MipsISD::FPCmp &&2238 "Floating point operand expected.");2239 2240 SDLoc DL(Op);2241 SDValue True = DAG.getConstant(1, DL, MVT::i32);2242 SDValue False = DAG.getConstant(0, DL, MVT::i32);2243 2244 return createCMovFP(DAG, Cond, True, False, DL);2245}2246 2247SDValue MipsTargetLowering::lowerFSETCC(SDValue Op, SelectionDAG &DAG) const {2248 assert(!Subtarget.hasMips32r6() && !Subtarget.hasMips64r6());2249 2250 SDLoc DL(Op);2251 SDValue Chain = Op.getOperand(0);2252 SDValue LHS = Op.getOperand(1);2253 SDValue RHS = Op.getOperand(2);2254 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(3))->get();2255 2256 SDValue Cond = DAG.getNode(MipsISD::FPCmp, DL, MVT::Glue, LHS, RHS,2257 DAG.getConstant(condCodeToFCC(CC), DL, MVT::i32));2258 SDValue True = DAG.getConstant(1, DL, MVT::i32);2259 SDValue False = DAG.getConstant(0, DL, MVT::i32);2260 SDValue CMovFP = createCMovFP(DAG, Cond, True, False, DL);2261 2262 return DAG.getMergeValues({CMovFP, Chain}, DL);2263}2264 2265SDValue MipsTargetLowering::lowerGlobalAddress(SDValue Op,2266 SelectionDAG &DAG) const {2267 EVT Ty = Op.getValueType();2268 GlobalAddressSDNode *N = cast<GlobalAddressSDNode>(Op);2269 const GlobalValue *GV = N->getGlobal();2270 2271 if (GV->hasDLLImportStorageClass()) {2272 assert(Subtarget.isTargetWindows() &&2273 "Windows is the only supported COFF target");2274 return getDllimportVariable(2275 N, SDLoc(N), Ty, DAG, DAG.getEntryNode(),2276 MachinePointerInfo::getGOT(DAG.getMachineFunction()));2277 }2278 2279 if (!isPositionIndependent()) {2280 const MipsTargetObjectFile *TLOF =2281 static_cast<const MipsTargetObjectFile *>(2282 getTargetMachine().getObjFileLowering());2283 const GlobalObject *GO = GV->getAliaseeObject();2284 if (GO && TLOF->IsGlobalInSmallSection(GO, getTargetMachine()))2285 // %gp_rel relocation2286 return getAddrGPRel(N, SDLoc(N), Ty, DAG, ABI.IsN64());2287 2288 // %hi/%lo relocation2289 return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)2290 // %highest/%higher/%hi/%lo relocation2291 : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);2292 }2293 2294 // Every other architecture would use shouldAssumeDSOLocal in here, but2295 // mips is special.2296 // * In PIC code mips requires got loads even for local statics!2297 // * To save on got entries, for local statics the got entry contains the2298 // page and an additional add instruction takes care of the low bits.2299 // * It is legal to access a hidden symbol with a non hidden undefined,2300 // so one cannot guarantee that all access to a hidden symbol will know2301 // it is hidden.2302 // * Mips linkers don't support creating a page and a full got entry for2303 // the same symbol.2304 // * Given all that, we have to use a full got entry for hidden symbols :-(2305 if (GV->hasLocalLinkage())2306 return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64());2307 2308 if (Subtarget.useXGOT())2309 return getAddrGlobalLargeGOT(2310 N, SDLoc(N), Ty, DAG, MipsII::MO_GOT_HI16, MipsII::MO_GOT_LO16,2311 DAG.getEntryNode(),2312 MachinePointerInfo::getGOT(DAG.getMachineFunction()));2313 2314 return getAddrGlobal(2315 N, SDLoc(N), Ty, DAG,2316 (ABI.IsN32() || ABI.IsN64()) ? MipsII::MO_GOT_DISP : MipsII::MO_GOT,2317 DAG.getEntryNode(), MachinePointerInfo::getGOT(DAG.getMachineFunction()));2318}2319 2320SDValue MipsTargetLowering::lowerBlockAddress(SDValue Op,2321 SelectionDAG &DAG) const {2322 BlockAddressSDNode *N = cast<BlockAddressSDNode>(Op);2323 EVT Ty = Op.getValueType();2324 2325 if (!isPositionIndependent())2326 return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)2327 : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);2328 2329 return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64());2330}2331 2332SDValue MipsTargetLowering::2333lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const2334{2335 // If the relocation model is PIC, use the General Dynamic TLS Model or2336 // Local Dynamic TLS model, otherwise use the Initial Exec or2337 // Local Exec TLS Model.2338 2339 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);2340 if (DAG.getTarget().useEmulatedTLS())2341 return LowerToTLSEmulatedModel(GA, DAG);2342 2343 SDLoc DL(GA);2344 const GlobalValue *GV = GA->getGlobal();2345 EVT PtrVT = getPointerTy(DAG.getDataLayout());2346 2347 TLSModel::Model model = getTargetMachine().getTLSModel(GV);2348 2349 if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) {2350 // General Dynamic and Local Dynamic TLS Model.2351 unsigned Flag = (model == TLSModel::LocalDynamic) ? MipsII::MO_TLSLDM2352 : MipsII::MO_TLSGD;2353 2354 SDValue TGA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, Flag);2355 SDValue Argument = DAG.getNode(MipsISD::Wrapper, DL, PtrVT,2356 getGlobalReg(DAG, PtrVT), TGA);2357 unsigned PtrSize = PtrVT.getSizeInBits();2358 IntegerType *PtrTy = Type::getIntNTy(*DAG.getContext(), PtrSize);2359 2360 SDValue TlsGetAddr = DAG.getExternalSymbol("__tls_get_addr", PtrVT);2361 2362 ArgListTy Args;2363 Args.emplace_back(Argument, PtrTy);2364 2365 TargetLowering::CallLoweringInfo CLI(DAG);2366 CLI.setDebugLoc(DL)2367 .setChain(DAG.getEntryNode())2368 .setLibCallee(CallingConv::C, PtrTy, TlsGetAddr, std::move(Args));2369 std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);2370 2371 SDValue Ret = CallResult.first;2372 2373 if (model != TLSModel::LocalDynamic)2374 return Ret;2375 2376 SDValue TGAHi = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,2377 MipsII::MO_DTPREL_HI);2378 SDValue Hi = DAG.getNode(MipsISD::TlsHi, DL, PtrVT, TGAHi);2379 SDValue TGALo = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,2380 MipsII::MO_DTPREL_LO);2381 SDValue Lo = DAG.getNode(MipsISD::Lo, DL, PtrVT, TGALo);2382 SDValue Add = DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Ret);2383 return DAG.getNode(ISD::ADD, DL, PtrVT, Add, Lo);2384 }2385 2386 SDValue Offset;2387 if (model == TLSModel::InitialExec) {2388 // Initial Exec TLS Model2389 SDValue TGA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,2390 MipsII::MO_GOTTPREL);2391 TGA = DAG.getNode(MipsISD::Wrapper, DL, PtrVT, getGlobalReg(DAG, PtrVT),2392 TGA);2393 Offset =2394 DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), TGA, MachinePointerInfo());2395 } else {2396 // Local Exec TLS Model2397 assert(model == TLSModel::LocalExec);2398 SDValue TGAHi = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,2399 MipsII::MO_TPREL_HI);2400 SDValue TGALo = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0,2401 MipsII::MO_TPREL_LO);2402 SDValue Hi = DAG.getNode(MipsISD::TlsHi, DL, PtrVT, TGAHi);2403 SDValue Lo = DAG.getNode(MipsISD::Lo, DL, PtrVT, TGALo);2404 Offset = DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);2405 }2406 2407 SDValue ThreadPointer = DAG.getNode(MipsISD::ThreadPointer, DL, PtrVT);2408 return DAG.getNode(ISD::ADD, DL, PtrVT, ThreadPointer, Offset);2409}2410 2411SDValue MipsTargetLowering::2412lowerJumpTable(SDValue Op, SelectionDAG &DAG) const2413{2414 JumpTableSDNode *N = cast<JumpTableSDNode>(Op);2415 EVT Ty = Op.getValueType();2416 2417 if (!isPositionIndependent())2418 return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)2419 : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);2420 2421 return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64());2422}2423 2424SDValue MipsTargetLowering::2425lowerConstantPool(SDValue Op, SelectionDAG &DAG) const2426{2427 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);2428 EVT Ty = Op.getValueType();2429 2430 if (!isPositionIndependent()) {2431 const MipsTargetObjectFile *TLOF =2432 static_cast<const MipsTargetObjectFile *>(2433 getTargetMachine().getObjFileLowering());2434 2435 if (TLOF->IsConstantInSmallSection(DAG.getDataLayout(), N->getConstVal(),2436 getTargetMachine()))2437 // %gp_rel relocation2438 return getAddrGPRel(N, SDLoc(N), Ty, DAG, ABI.IsN64());2439 2440 return Subtarget.hasSym32() ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)2441 : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);2442 }2443 2444 return getAddrLocal(N, SDLoc(N), Ty, DAG, ABI.IsN32() || ABI.IsN64());2445}2446 2447SDValue MipsTargetLowering::lowerVASTART(SDValue Op, SelectionDAG &DAG) const {2448 MachineFunction &MF = DAG.getMachineFunction();2449 MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();2450 2451 SDLoc DL(Op);2452 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),2453 getPointerTy(MF.getDataLayout()));2454 2455 // vastart just stores the address of the VarArgsFrameIndex slot into the2456 // memory location argument.2457 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();2458 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),2459 MachinePointerInfo(SV));2460}2461 2462SDValue MipsTargetLowering::lowerVAARG(SDValue Op, SelectionDAG &DAG) const {2463 SDNode *Node = Op.getNode();2464 EVT VT = Node->getValueType(0);2465 SDValue Chain = Node->getOperand(0);2466 SDValue VAListPtr = Node->getOperand(1);2467 const Align Align =2468 llvm::MaybeAlign(Node->getConstantOperandVal(3)).valueOrOne();2469 const Value *SV = cast<SrcValueSDNode>(Node->getOperand(2))->getValue();2470 SDLoc DL(Node);2471 unsigned ArgSlotSizeInBytes = (ABI.IsN32() || ABI.IsN64()) ? 8 : 4;2472 2473 SDValue VAListLoad = DAG.getLoad(getPointerTy(DAG.getDataLayout()), DL, Chain,2474 VAListPtr, MachinePointerInfo(SV));2475 SDValue VAList = VAListLoad;2476 2477 // Re-align the pointer if necessary.2478 // It should only ever be necessary for 64-bit types on O32 since the minimum2479 // argument alignment is the same as the maximum type alignment for N32/N64.2480 //2481 // FIXME: We currently align too often. The code generator doesn't notice2482 // when the pointer is still aligned from the last va_arg (or pair of2483 // va_args for the i64 on O32 case).2484 if (Align > getMinStackArgumentAlignment()) {2485 VAList = DAG.getNode(2486 ISD::ADD, DL, VAList.getValueType(), VAList,2487 DAG.getConstant(Align.value() - 1, DL, VAList.getValueType()));2488 2489 VAList = DAG.getNode(ISD::AND, DL, VAList.getValueType(), VAList,2490 DAG.getSignedConstant(-(int64_t)Align.value(), DL,2491 VAList.getValueType()));2492 }2493 2494 // Increment the pointer, VAList, to the next vaarg.2495 auto &TD = DAG.getDataLayout();2496 unsigned ArgSizeInBytes =2497 TD.getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext()));2498 SDValue Tmp3 =2499 DAG.getNode(ISD::ADD, DL, VAList.getValueType(), VAList,2500 DAG.getConstant(alignTo(ArgSizeInBytes, ArgSlotSizeInBytes),2501 DL, VAList.getValueType()));2502 // Store the incremented VAList to the legalized pointer2503 Chain = DAG.getStore(VAListLoad.getValue(1), DL, Tmp3, VAListPtr,2504 MachinePointerInfo(SV));2505 2506 // In big-endian mode we must adjust the pointer when the load size is smaller2507 // than the argument slot size. We must also reduce the known alignment to2508 // match. For example in the N64 ABI, we must add 4 bytes to the offset to get2509 // the correct half of the slot, and reduce the alignment from 8 (slot2510 // alignment) down to 4 (type alignment).2511 if (!Subtarget.isLittle() && ArgSizeInBytes < ArgSlotSizeInBytes) {2512 unsigned Adjustment = ArgSlotSizeInBytes - ArgSizeInBytes;2513 VAList = DAG.getNode(ISD::ADD, DL, VAListPtr.getValueType(), VAList,2514 DAG.getIntPtrConstant(Adjustment, DL));2515 }2516 // Load the actual argument out of the pointer VAList2517 return DAG.getLoad(VT, DL, Chain, VAList, MachinePointerInfo());2518}2519 2520static SDValue lowerFCOPYSIGN32(SDValue Op, SelectionDAG &DAG,2521 bool HasExtractInsert) {2522 EVT TyX = Op.getOperand(0).getValueType();2523 EVT TyY = Op.getOperand(1).getValueType();2524 SDLoc DL(Op);2525 SDValue Const1 = DAG.getConstant(1, DL, MVT::i32);2526 SDValue Const31 = DAG.getConstant(31, DL, MVT::i32);2527 SDValue Res;2528 2529 // If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it2530 // to i32.2531 SDValue X = (TyX == MVT::f32) ?2532 DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(0)) :2533 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),2534 Const1);2535 SDValue Y = (TyY == MVT::f32) ?2536 DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(1)) :2537 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(1),2538 Const1);2539 2540 if (HasExtractInsert) {2541 // ext E, Y, 31, 1 ; extract bit31 of Y2542 // ins X, E, 31, 1 ; insert extracted bit at bit31 of X2543 SDValue E = DAG.getNode(MipsISD::Ext, DL, MVT::i32, Y, Const31, Const1);2544 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i32, E, Const31, Const1, X);2545 } else {2546 // sll SllX, X, 12547 // srl SrlX, SllX, 12548 // srl SrlY, Y, 312549 // sll SllY, SrlX, 312550 // or Or, SrlX, SllY2551 SDValue SllX = DAG.getNode(ISD::SHL, DL, MVT::i32, X, Const1);2552 SDValue SrlX = DAG.getNode(ISD::SRL, DL, MVT::i32, SllX, Const1);2553 SDValue SrlY = DAG.getNode(ISD::SRL, DL, MVT::i32, Y, Const31);2554 SDValue SllY = DAG.getNode(ISD::SHL, DL, MVT::i32, SrlY, Const31);2555 Res = DAG.getNode(ISD::OR, DL, MVT::i32, SrlX, SllY);2556 }2557 2558 if (TyX == MVT::f32)2559 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), Res);2560 2561 SDValue LowX = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,2562 Op.getOperand(0),2563 DAG.getConstant(0, DL, MVT::i32));2564 return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);2565}2566 2567static SDValue lowerFCOPYSIGN64(SDValue Op, SelectionDAG &DAG,2568 bool HasExtractInsert) {2569 unsigned WidthX = Op.getOperand(0).getValueSizeInBits();2570 unsigned WidthY = Op.getOperand(1).getValueSizeInBits();2571 EVT TyX = MVT::getIntegerVT(WidthX), TyY = MVT::getIntegerVT(WidthY);2572 SDLoc DL(Op);2573 SDValue Const1 = DAG.getConstant(1, DL, MVT::i32);2574 2575 // Bitcast to integer nodes.2576 SDValue X = DAG.getNode(ISD::BITCAST, DL, TyX, Op.getOperand(0));2577 SDValue Y = DAG.getNode(ISD::BITCAST, DL, TyY, Op.getOperand(1));2578 2579 if (HasExtractInsert) {2580 // ext E, Y, width(Y) - 1, 1 ; extract bit width(Y)-1 of Y2581 // ins X, E, width(X) - 1, 1 ; insert extracted bit at bit width(X)-1 of X2582 SDValue E = DAG.getNode(MipsISD::Ext, DL, TyY, Y,2583 DAG.getConstant(WidthY - 1, DL, MVT::i32), Const1);2584 2585 if (WidthX > WidthY)2586 E = DAG.getNode(ISD::ZERO_EXTEND, DL, TyX, E);2587 else if (WidthY > WidthX)2588 E = DAG.getNode(ISD::TRUNCATE, DL, TyX, E);2589 2590 SDValue I = DAG.getNode(MipsISD::Ins, DL, TyX, E,2591 DAG.getConstant(WidthX - 1, DL, MVT::i32), Const1,2592 X);2593 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), I);2594 }2595 2596 // (d)sll SllX, X, 12597 // (d)srl SrlX, SllX, 12598 // (d)srl SrlY, Y, width(Y)-12599 // (d)sll SllY, SrlX, width(Y)-12600 // or Or, SrlX, SllY2601 SDValue SllX = DAG.getNode(ISD::SHL, DL, TyX, X, Const1);2602 SDValue SrlX = DAG.getNode(ISD::SRL, DL, TyX, SllX, Const1);2603 SDValue SrlY = DAG.getNode(ISD::SRL, DL, TyY, Y,2604 DAG.getConstant(WidthY - 1, DL, MVT::i32));2605 2606 if (WidthX > WidthY)2607 SrlY = DAG.getNode(ISD::ZERO_EXTEND, DL, TyX, SrlY);2608 else if (WidthY > WidthX)2609 SrlY = DAG.getNode(ISD::TRUNCATE, DL, TyX, SrlY);2610 2611 SDValue SllY = DAG.getNode(ISD::SHL, DL, TyX, SrlY,2612 DAG.getConstant(WidthX - 1, DL, MVT::i32));2613 SDValue Or = DAG.getNode(ISD::OR, DL, TyX, SrlX, SllY);2614 return DAG.getNode(ISD::BITCAST, DL, Op.getOperand(0).getValueType(), Or);2615}2616 2617SDValue2618MipsTargetLowering::lowerFCOPYSIGN(SDValue Op, SelectionDAG &DAG) const {2619 if (Subtarget.isGP64bit())2620 return lowerFCOPYSIGN64(Op, DAG, Subtarget.hasExtractInsert());2621 2622 return lowerFCOPYSIGN32(Op, DAG, Subtarget.hasExtractInsert());2623}2624 2625SDValue MipsTargetLowering::lowerFABS32(SDValue Op, SelectionDAG &DAG,2626 bool HasExtractInsert) const {2627 SDLoc DL(Op);2628 SDValue Res, Const1 = DAG.getConstant(1, DL, MVT::i32);2629 2630 if (DAG.getTarget().Options.NoNaNsFPMath || Subtarget.inAbs2008Mode())2631 return DAG.getNode(MipsISD::FAbs, DL, Op.getValueType(), Op.getOperand(0));2632 2633 // If operand is of type f64, extract the upper 32-bit. Otherwise, bitcast it2634 // to i32.2635 SDValue X = (Op.getValueType() == MVT::f32)2636 ? DAG.getNode(ISD::BITCAST, DL, MVT::i32, Op.getOperand(0))2637 : DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,2638 Op.getOperand(0), Const1);2639 2640 // Clear MSB.2641 if (HasExtractInsert)2642 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i32,2643 DAG.getRegister(Mips::ZERO, MVT::i32),2644 DAG.getConstant(31, DL, MVT::i32), Const1, X);2645 else {2646 // TODO: Provide DAG patterns which transform (and x, cst)2647 // back to a (shl (srl x (clz cst)) (clz cst)) sequence.2648 SDValue SllX = DAG.getNode(ISD::SHL, DL, MVT::i32, X, Const1);2649 Res = DAG.getNode(ISD::SRL, DL, MVT::i32, SllX, Const1);2650 }2651 2652 if (Op.getValueType() == MVT::f32)2653 return DAG.getNode(ISD::BITCAST, DL, MVT::f32, Res);2654 2655 // FIXME: For mips32r2, the sequence of (BuildPairF64 (ins (ExtractElementF642656 // Op 1), $zero, 31 1) (ExtractElementF64 Op 0)) and the Op has one use, we2657 // should be able to drop the usage of mfc1/mtc1 and rewrite the register in2658 // place.2659 SDValue LowX =2660 DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32, Op.getOperand(0),2661 DAG.getConstant(0, DL, MVT::i32));2662 return DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64, LowX, Res);2663}2664 2665SDValue MipsTargetLowering::lowerFABS64(SDValue Op, SelectionDAG &DAG,2666 bool HasExtractInsert) const {2667 SDLoc DL(Op);2668 SDValue Res, Const1 = DAG.getConstant(1, DL, MVT::i32);2669 2670 if (DAG.getTarget().Options.NoNaNsFPMath || Subtarget.inAbs2008Mode())2671 return DAG.getNode(MipsISD::FAbs, DL, Op.getValueType(), Op.getOperand(0));2672 2673 // Bitcast to integer node.2674 SDValue X = DAG.getNode(ISD::BITCAST, DL, MVT::i64, Op.getOperand(0));2675 2676 // Clear MSB.2677 if (HasExtractInsert)2678 Res = DAG.getNode(MipsISD::Ins, DL, MVT::i64,2679 DAG.getRegister(Mips::ZERO_64, MVT::i64),2680 DAG.getConstant(63, DL, MVT::i32), Const1, X);2681 else {2682 SDValue SllX = DAG.getNode(ISD::SHL, DL, MVT::i64, X, Const1);2683 Res = DAG.getNode(ISD::SRL, DL, MVT::i64, SllX, Const1);2684 }2685 2686 return DAG.getNode(ISD::BITCAST, DL, MVT::f64, Res);2687}2688 2689SDValue MipsTargetLowering::lowerFABS(SDValue Op, SelectionDAG &DAG) const {2690 if ((ABI.IsN32() || ABI.IsN64()) && (Op.getValueType() == MVT::f64))2691 return lowerFABS64(Op, DAG, Subtarget.hasExtractInsert());2692 2693 return lowerFABS32(Op, DAG, Subtarget.hasExtractInsert());2694}2695 2696SDValue MipsTargetLowering::lowerFCANONICALIZE(SDValue Op,2697 SelectionDAG &DAG) const {2698 SDLoc DL(Op);2699 EVT VT = Op.getValueType();2700 SDValue Operand = Op.getOperand(0);2701 SDNodeFlags Flags = Op->getFlags();2702 2703 if (Flags.hasNoNaNs() || DAG.isKnownNeverNaN(Operand))2704 return Operand;2705 2706 SDValue Quiet = DAG.getNode(ISD::FADD, DL, VT, Operand, Operand);2707 return DAG.getSelectCC(DL, Operand, Operand, Quiet, Operand, ISD::SETUO);2708}2709 2710SDValue MipsTargetLowering::2711lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {2712 // check the depth2713 if (Op.getConstantOperandVal(0) != 0) {2714 DAG.getContext()->emitError(2715 "return address can be determined only for current frame");2716 return SDValue();2717 }2718 2719 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();2720 MFI.setFrameAddressIsTaken(true);2721 EVT VT = Op.getValueType();2722 SDLoc DL(Op);2723 SDValue FrameAddr = DAG.getCopyFromReg(2724 DAG.getEntryNode(), DL, ABI.IsN64() ? Mips::FP_64 : Mips::FP, VT);2725 return FrameAddr;2726}2727 2728SDValue MipsTargetLowering::lowerRETURNADDR(SDValue Op,2729 SelectionDAG &DAG) const {2730 // check the depth2731 if (Op.getConstantOperandVal(0) != 0) {2732 DAG.getContext()->emitError(2733 "return address can be determined only for current frame");2734 return SDValue();2735 }2736 2737 MachineFunction &MF = DAG.getMachineFunction();2738 MachineFrameInfo &MFI = MF.getFrameInfo();2739 MVT VT = Op.getSimpleValueType();2740 unsigned RA = ABI.IsN64() ? Mips::RA_64 : Mips::RA;2741 MFI.setReturnAddressIsTaken(true);2742 2743 // Return RA, which contains the return address. Mark it an implicit live-in.2744 Register Reg = MF.addLiveIn(RA, getRegClassFor(VT));2745 return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), Reg, VT);2746}2747 2748// An EH_RETURN is the result of lowering llvm.eh.return which in turn is2749// generated from __builtin_eh_return (offset, handler)2750// The effect of this is to adjust the stack pointer by "offset"2751// and then branch to "handler".2752SDValue MipsTargetLowering::lowerEH_RETURN(SDValue Op, SelectionDAG &DAG)2753 const {2754 MachineFunction &MF = DAG.getMachineFunction();2755 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();2756 2757 MipsFI->setCallsEhReturn();2758 SDValue Chain = Op.getOperand(0);2759 SDValue Offset = Op.getOperand(1);2760 SDValue Handler = Op.getOperand(2);2761 SDLoc DL(Op);2762 EVT Ty = ABI.IsN64() ? MVT::i64 : MVT::i32;2763 2764 // Store stack offset in V1, store jump target in V0. Glue CopyToReg and2765 // EH_RETURN nodes, so that instructions are emitted back-to-back.2766 unsigned OffsetReg = ABI.IsN64() ? Mips::V1_64 : Mips::V1;2767 unsigned AddrReg = ABI.IsN64() ? Mips::V0_64 : Mips::V0;2768 Chain = DAG.getCopyToReg(Chain, DL, OffsetReg, Offset, SDValue());2769 Chain = DAG.getCopyToReg(Chain, DL, AddrReg, Handler, Chain.getValue(1));2770 return DAG.getNode(MipsISD::EH_RETURN, DL, MVT::Other, Chain,2771 DAG.getRegister(OffsetReg, Ty),2772 DAG.getRegister(AddrReg, getPointerTy(MF.getDataLayout())),2773 Chain.getValue(1));2774}2775 2776SDValue MipsTargetLowering::lowerATOMIC_FENCE(SDValue Op,2777 SelectionDAG &DAG) const {2778 // FIXME: Need pseudo-fence for 'singlethread' fences2779 // FIXME: Set SType for weaker fences where supported/appropriate.2780 unsigned SType = 0;2781 SDLoc DL(Op);2782 return DAG.getNode(MipsISD::Sync, DL, MVT::Other, Op.getOperand(0),2783 DAG.getConstant(SType, DL, MVT::i32));2784}2785 2786SDValue MipsTargetLowering::lowerShiftLeftParts(SDValue Op,2787 SelectionDAG &DAG) const {2788 SDLoc DL(Op);2789 MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;2790 2791 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);2792 SDValue Shamt = Op.getOperand(2);2793 // if shamt < (VT.bits):2794 // lo = (shl lo, shamt)2795 // hi = (or (shl hi, shamt) (srl (srl lo, 1), (xor shamt, (VT.bits-1))))2796 // else:2797 // lo = 02798 // hi = (shl lo, shamt[4:0])2799 SDValue Not =2800 DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,2801 DAG.getConstant(VT.getSizeInBits() - 1, DL, MVT::i32));2802 SDValue ShiftRight1Lo = DAG.getNode(ISD::SRL, DL, VT, Lo,2803 DAG.getConstant(1, DL, VT));2804 SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, ShiftRight1Lo, Not);2805 SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, Hi, Shamt);2806 SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);2807 SDValue ShiftLeftLo = DAG.getNode(ISD::SHL, DL, VT, Lo, Shamt);2808 SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,2809 DAG.getConstant(VT.getSizeInBits(), DL, MVT::i32));2810 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond,2811 DAG.getConstant(0, DL, VT), ShiftLeftLo);2812 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftLeftLo, Or);2813 2814 SDValue Ops[2] = {Lo, Hi};2815 return DAG.getMergeValues(Ops, DL);2816}2817 2818SDValue MipsTargetLowering::lowerShiftRightParts(SDValue Op, SelectionDAG &DAG,2819 bool IsSRA) const {2820 SDLoc DL(Op);2821 SDValue Lo = Op.getOperand(0), Hi = Op.getOperand(1);2822 SDValue Shamt = Op.getOperand(2);2823 MVT VT = Subtarget.isGP64bit() ? MVT::i64 : MVT::i32;2824 2825 // if shamt < (VT.bits):2826 // lo = (or (shl (shl hi, 1), (xor shamt, (VT.bits-1))) (srl lo, shamt))2827 // if isSRA:2828 // hi = (sra hi, shamt)2829 // else:2830 // hi = (srl hi, shamt)2831 // else:2832 // if isSRA:2833 // lo = (sra hi, shamt[4:0])2834 // hi = (sra hi, 31)2835 // else:2836 // lo = (srl hi, shamt[4:0])2837 // hi = 02838 SDValue Not =2839 DAG.getNode(ISD::XOR, DL, MVT::i32, Shamt,2840 DAG.getConstant(VT.getSizeInBits() - 1, DL, MVT::i32));2841 SDValue ShiftLeft1Hi = DAG.getNode(ISD::SHL, DL, VT, Hi,2842 DAG.getConstant(1, DL, VT));2843 SDValue ShiftLeftHi = DAG.getNode(ISD::SHL, DL, VT, ShiftLeft1Hi, Not);2844 SDValue ShiftRightLo = DAG.getNode(ISD::SRL, DL, VT, Lo, Shamt);2845 SDValue Or = DAG.getNode(ISD::OR, DL, VT, ShiftLeftHi, ShiftRightLo);2846 SDValue ShiftRightHi = DAG.getNode(IsSRA ? ISD::SRA : ISD::SRL,2847 DL, VT, Hi, Shamt);2848 SDValue Cond = DAG.getNode(ISD::AND, DL, MVT::i32, Shamt,2849 DAG.getConstant(VT.getSizeInBits(), DL, MVT::i32));2850 SDValue Ext = DAG.getNode(ISD::SRA, DL, VT, Hi,2851 DAG.getConstant(VT.getSizeInBits() - 1, DL, VT));2852 2853 if (!(Subtarget.hasMips4() || Subtarget.hasMips32())) {2854 SDVTList VTList = DAG.getVTList(VT, VT);2855 return DAG.getNode(Subtarget.isGP64bit() ? MipsISD::DOUBLE_SELECT_I642856 : MipsISD::DOUBLE_SELECT_I,2857 DL, VTList, Cond, ShiftRightHi,2858 IsSRA ? Ext : DAG.getConstant(0, DL, VT), Or,2859 ShiftRightHi);2860 }2861 2862 Lo = DAG.getNode(ISD::SELECT, DL, VT, Cond, ShiftRightHi, Or);2863 Hi = DAG.getNode(ISD::SELECT, DL, VT, Cond,2864 IsSRA ? Ext : DAG.getConstant(0, DL, VT), ShiftRightHi);2865 2866 SDValue Ops[2] = {Lo, Hi};2867 return DAG.getMergeValues(Ops, DL);2868}2869 2870static SDValue createLoadLR(unsigned Opc, SelectionDAG &DAG, LoadSDNode *LD,2871 SDValue Chain, SDValue Src, unsigned Offset) {2872 SDValue Ptr = LD->getBasePtr();2873 EVT VT = LD->getValueType(0), MemVT = LD->getMemoryVT();2874 EVT BasePtrVT = Ptr.getValueType();2875 SDLoc DL(LD);2876 SDVTList VTList = DAG.getVTList(VT, MVT::Other);2877 2878 if (Offset)2879 Ptr = DAG.getNode(ISD::ADD, DL, BasePtrVT, Ptr,2880 DAG.getConstant(Offset, DL, BasePtrVT));2881 2882 SDValue Ops[] = { Chain, Ptr, Src };2883 return DAG.getMemIntrinsicNode(Opc, DL, VTList, Ops, MemVT,2884 LD->getMemOperand());2885}2886 2887// Expand an unaligned 32 or 64-bit integer load node.2888SDValue MipsTargetLowering::lowerLOAD(SDValue Op, SelectionDAG &DAG) const {2889 LoadSDNode *LD = cast<LoadSDNode>(Op);2890 EVT MemVT = LD->getMemoryVT();2891 2892 if (Subtarget.systemSupportsUnalignedAccess())2893 return Op;2894 2895 // Return if load is aligned or if MemVT is neither i32 nor i64.2896 if ((LD->getAlign().value() >= (MemVT.getSizeInBits() / 8)) ||2897 ((MemVT != MVT::i32) && (MemVT != MVT::i64)))2898 return SDValue();2899 2900 bool IsLittle = Subtarget.isLittle();2901 EVT VT = Op.getValueType();2902 ISD::LoadExtType ExtType = LD->getExtensionType();2903 SDValue Chain = LD->getChain(), Undef = DAG.getUNDEF(VT);2904 2905 assert((VT == MVT::i32) || (VT == MVT::i64));2906 2907 // Expand2908 // (set dst, (i64 (load baseptr)))2909 // to2910 // (set tmp, (ldl (add baseptr, 7), undef))2911 // (set dst, (ldr baseptr, tmp))2912 if ((VT == MVT::i64) && (ExtType == ISD::NON_EXTLOAD)) {2913 SDValue LDL = createLoadLR(MipsISD::LDL, DAG, LD, Chain, Undef,2914 IsLittle ? 7 : 0);2915 return createLoadLR(MipsISD::LDR, DAG, LD, LDL.getValue(1), LDL,2916 IsLittle ? 0 : 7);2917 }2918 2919 SDValue LWL = createLoadLR(MipsISD::LWL, DAG, LD, Chain, Undef,2920 IsLittle ? 3 : 0);2921 SDValue LWR = createLoadLR(MipsISD::LWR, DAG, LD, LWL.getValue(1), LWL,2922 IsLittle ? 0 : 3);2923 2924 // Expand2925 // (set dst, (i32 (load baseptr))) or2926 // (set dst, (i64 (sextload baseptr))) or2927 // (set dst, (i64 (extload baseptr)))2928 // to2929 // (set tmp, (lwl (add baseptr, 3), undef))2930 // (set dst, (lwr baseptr, tmp))2931 if ((VT == MVT::i32) || (ExtType == ISD::SEXTLOAD) ||2932 (ExtType == ISD::EXTLOAD))2933 return LWR;2934 2935 assert((VT == MVT::i64) && (ExtType == ISD::ZEXTLOAD));2936 2937 // Expand2938 // (set dst, (i64 (zextload baseptr)))2939 // to2940 // (set tmp0, (lwl (add baseptr, 3), undef))2941 // (set tmp1, (lwr baseptr, tmp0))2942 // (set tmp2, (shl tmp1, 32))2943 // (set dst, (srl tmp2, 32))2944 SDLoc DL(LD);2945 SDValue Const32 = DAG.getConstant(32, DL, MVT::i32);2946 SDValue SLL = DAG.getNode(ISD::SHL, DL, MVT::i64, LWR, Const32);2947 SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i64, SLL, Const32);2948 SDValue Ops[] = { SRL, LWR.getValue(1) };2949 return DAG.getMergeValues(Ops, DL);2950}2951 2952static SDValue createStoreLR(unsigned Opc, SelectionDAG &DAG, StoreSDNode *SD,2953 SDValue Chain, unsigned Offset) {2954 SDValue Ptr = SD->getBasePtr(), Value = SD->getValue();2955 EVT MemVT = SD->getMemoryVT(), BasePtrVT = Ptr.getValueType();2956 SDLoc DL(SD);2957 SDVTList VTList = DAG.getVTList(MVT::Other);2958 2959 if (Offset)2960 Ptr = DAG.getNode(ISD::ADD, DL, BasePtrVT, Ptr,2961 DAG.getConstant(Offset, DL, BasePtrVT));2962 2963 SDValue Ops[] = { Chain, Value, Ptr };2964 return DAG.getMemIntrinsicNode(Opc, DL, VTList, Ops, MemVT,2965 SD->getMemOperand());2966}2967 2968// Expand an unaligned 32 or 64-bit integer store node.2969static SDValue lowerUnalignedIntStore(StoreSDNode *SD, SelectionDAG &DAG,2970 bool IsLittle) {2971 SDValue Value = SD->getValue(), Chain = SD->getChain();2972 EVT VT = Value.getValueType();2973 2974 // Expand2975 // (store val, baseptr) or2976 // (truncstore val, baseptr)2977 // to2978 // (swl val, (add baseptr, 3))2979 // (swr val, baseptr)2980 if ((VT == MVT::i32) || SD->isTruncatingStore()) {2981 SDValue SWL = createStoreLR(MipsISD::SWL, DAG, SD, Chain,2982 IsLittle ? 3 : 0);2983 return createStoreLR(MipsISD::SWR, DAG, SD, SWL, IsLittle ? 0 : 3);2984 }2985 2986 assert(VT == MVT::i64);2987 2988 // Expand2989 // (store val, baseptr)2990 // to2991 // (sdl val, (add baseptr, 7))2992 // (sdr val, baseptr)2993 SDValue SDL = createStoreLR(MipsISD::SDL, DAG, SD, Chain, IsLittle ? 7 : 0);2994 return createStoreLR(MipsISD::SDR, DAG, SD, SDL, IsLittle ? 0 : 7);2995}2996 2997// Lower (store (fp_to_sint $fp) $ptr) to (store (TruncIntFP $fp), $ptr).2998static SDValue lowerFP_TO_SINT_STORE(StoreSDNode *SD, SelectionDAG &DAG,2999 bool SingleFloat) {3000 SDValue Val = SD->getValue();3001 3002 if (Val.getOpcode() != ISD::FP_TO_SINT ||3003 (Val.getValueSizeInBits() > 32 && SingleFloat))3004 return SDValue();3005 3006 EVT FPTy = EVT::getFloatingPointVT(Val.getValueSizeInBits());3007 SDValue Tr = DAG.getNode(MipsISD::TruncIntFP, SDLoc(Val), FPTy,3008 Val.getOperand(0));3009 return DAG.getStore(SD->getChain(), SDLoc(SD), Tr, SD->getBasePtr(),3010 SD->getPointerInfo(), SD->getAlign(),3011 SD->getMemOperand()->getFlags());3012}3013 3014SDValue MipsTargetLowering::lowerSTORE(SDValue Op, SelectionDAG &DAG) const {3015 StoreSDNode *SD = cast<StoreSDNode>(Op);3016 EVT MemVT = SD->getMemoryVT();3017 3018 // Lower unaligned integer stores.3019 if (!Subtarget.systemSupportsUnalignedAccess() &&3020 (SD->getAlign().value() < (MemVT.getSizeInBits() / 8)) &&3021 ((MemVT == MVT::i32) || (MemVT == MVT::i64)))3022 return lowerUnalignedIntStore(SD, DAG, Subtarget.isLittle());3023 3024 return lowerFP_TO_SINT_STORE(SD, DAG, Subtarget.isSingleFloat());3025}3026 3027SDValue MipsTargetLowering::lowerEH_DWARF_CFA(SDValue Op,3028 SelectionDAG &DAG) const {3029 3030 // Return a fixed StackObject with offset 0 which points to the old stack3031 // pointer.3032 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();3033 EVT ValTy = Op->getValueType(0);3034 int FI = MFI.CreateFixedObject(Op.getValueSizeInBits() / 8, 0, false);3035 return DAG.getFrameIndex(FI, ValTy);3036}3037 3038SDValue MipsTargetLowering::lowerFP_TO_SINT(SDValue Op,3039 SelectionDAG &DAG) const {3040 if (Op.getValueSizeInBits() > 32 && Subtarget.isSingleFloat())3041 return SDValue();3042 3043 EVT FPTy = EVT::getFloatingPointVT(Op.getValueSizeInBits());3044 SDValue Trunc = DAG.getNode(MipsISD::TruncIntFP, SDLoc(Op), FPTy,3045 Op.getOperand(0));3046 return DAG.getNode(ISD::BITCAST, SDLoc(Op), Op.getValueType(), Trunc);3047}3048 3049SDValue MipsTargetLowering::lowerSTRICT_FP_TO_INT(SDValue Op,3050 SelectionDAG &DAG) const {3051 assert(Op->isStrictFPOpcode());3052 SDValue SrcVal = Op.getOperand(1);3053 SDLoc Loc(Op);3054 3055 SDValue Result =3056 DAG.getNode(Op.getOpcode() == ISD::STRICT_FP_TO_SINT ? ISD::FP_TO_SINT3057 : ISD::FP_TO_UINT,3058 Loc, Op.getValueType(), SrcVal);3059 3060 return DAG.getMergeValues({Result, Op.getOperand(0)}, Loc);3061}3062 3063//===----------------------------------------------------------------------===//3064// Calling Convention Implementation3065//===----------------------------------------------------------------------===//3066 3067//===----------------------------------------------------------------------===//3068// TODO: Implement a generic logic using tblgen that can support this.3069// Mips O32 ABI rules:3070// ---3071// i32 - Passed in A0, A1, A2, A3 and stack3072// f32 - Only passed in f32 registers if no int reg has been used yet to hold3073// an argument. Otherwise, passed in A1, A2, A3 and stack.3074// f64 - Only passed in two aliased f32 registers if no int reg has been used3075// yet to hold an argument. Otherwise, use A2, A3 and stack. If A1 is3076// not used, it must be shadowed. If only A3 is available, shadow it and3077// go to stack.3078// vXiX - Received as scalarized i32s, passed in A0 - A3 and the stack.3079// vXf32 - Passed in either a pair of registers {A0, A1}, {A2, A3} or {A0 - A3}3080// with the remainder spilled to the stack.3081// vXf64 - Passed in either {A0, A1, A2, A3} or {A2, A3} and in both cases3082// spilling the remainder to the stack.3083//3084// For vararg functions, all arguments are passed in A0, A1, A2, A3 and stack.3085//===----------------------------------------------------------------------===//3086 3087static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,3088 CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags,3089 Type *OrigTy, CCState &State,3090 ArrayRef<MCPhysReg> F64Regs) {3091 const MipsSubtarget &Subtarget = static_cast<const MipsSubtarget &>(3092 State.getMachineFunction().getSubtarget());3093 3094 static const MCPhysReg IntRegs[] = { Mips::A0, Mips::A1, Mips::A2, Mips::A3 };3095 3096 static const MCPhysReg F32Regs[] = { Mips::F12, Mips::F14 };3097 3098 static const MCPhysReg FloatVectorIntRegs[] = { Mips::A0, Mips::A2 };3099 3100 // Do not process byval args here.3101 if (ArgFlags.isByVal())3102 return true;3103 3104 // Promote i8 and i163105 if (ArgFlags.isInReg() && !Subtarget.isLittle()) {3106 if (LocVT == MVT::i8 || LocVT == MVT::i16 || LocVT == MVT::i32) {3107 LocVT = MVT::i32;3108 if (ArgFlags.isSExt())3109 LocInfo = CCValAssign::SExtUpper;3110 else if (ArgFlags.isZExt())3111 LocInfo = CCValAssign::ZExtUpper;3112 else3113 LocInfo = CCValAssign::AExtUpper;3114 }3115 }3116 3117 // Promote i8 and i163118 if (LocVT == MVT::i8 || LocVT == MVT::i16) {3119 LocVT = MVT::i32;3120 if (ArgFlags.isSExt())3121 LocInfo = CCValAssign::SExt;3122 else if (ArgFlags.isZExt())3123 LocInfo = CCValAssign::ZExt;3124 else3125 LocInfo = CCValAssign::AExt;3126 }3127 3128 unsigned Reg;3129 3130 // f32 and f64 are allocated in A0, A1, A2, A3 when either of the following3131 // is true: function is vararg, argument is 3rd or higher, there is previous3132 // argument which is not f32 or f64.3133 bool AllocateFloatsInIntReg = State.isVarArg() || ValNo > 1 ||3134 State.getFirstUnallocated(F32Regs) != ValNo;3135 Align OrigAlign = ArgFlags.getNonZeroOrigAlign();3136 bool isI64 = (ValVT == MVT::i32 && OrigAlign == Align(8));3137 bool isVectorFloat = OrigTy->isVectorTy() && OrigTy->isFPOrFPVectorTy();3138 3139 // The MIPS vector ABI for floats passes them in a pair of registers3140 if (ValVT == MVT::i32 && isVectorFloat) {3141 // This is the start of an vector that was scalarized into an unknown number3142 // of components. It doesn't matter how many there are. Allocate one of the3143 // notional 8 byte aligned registers which map onto the argument stack, and3144 // shadow the register lost to alignment requirements.3145 if (ArgFlags.isSplit()) {3146 Reg = State.AllocateReg(FloatVectorIntRegs);3147 if (Reg == Mips::A2)3148 State.AllocateReg(Mips::A1);3149 else if (Reg == 0)3150 State.AllocateReg(Mips::A3);3151 } else {3152 // If we're an intermediate component of the split, we can just attempt to3153 // allocate a register directly.3154 Reg = State.AllocateReg(IntRegs);3155 }3156 } else if (ValVT == MVT::i32 ||3157 (ValVT == MVT::f32 && AllocateFloatsInIntReg)) {3158 Reg = State.AllocateReg(IntRegs);3159 // If this is the first part of an i64 arg,3160 // the allocated register must be either A0 or A2.3161 if (isI64 && (Reg == Mips::A1 || Reg == Mips::A3))3162 Reg = State.AllocateReg(IntRegs);3163 LocVT = MVT::i32;3164 } else if (ValVT == MVT::f64 && AllocateFloatsInIntReg) {3165 // Allocate int register and shadow next int register. If first3166 // available register is Mips::A1 or Mips::A3, shadow it too.3167 Reg = State.AllocateReg(IntRegs);3168 if (Reg == Mips::A1 || Reg == Mips::A3)3169 Reg = State.AllocateReg(IntRegs);3170 3171 if (Reg) {3172 LocVT = MVT::i32;3173 3174 State.addLoc(3175 CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));3176 MCRegister HiReg = State.AllocateReg(IntRegs);3177 assert(HiReg);3178 State.addLoc(3179 CCValAssign::getCustomReg(ValNo, ValVT, HiReg, LocVT, LocInfo));3180 return false;3181 }3182 } else if (ValVT.isFloatingPoint() && !AllocateFloatsInIntReg) {3183 // we are guaranteed to find an available float register3184 if (ValVT == MVT::f32) {3185 Reg = State.AllocateReg(F32Regs);3186 // Shadow int register3187 State.AllocateReg(IntRegs);3188 } else {3189 Reg = State.AllocateReg(F64Regs);3190 // Shadow int registers3191 MCRegister Reg2 = State.AllocateReg(IntRegs);3192 if (Reg2 == Mips::A1 || Reg2 == Mips::A3)3193 State.AllocateReg(IntRegs);3194 State.AllocateReg(IntRegs);3195 }3196 } else3197 llvm_unreachable("Cannot handle this ValVT.");3198 3199 if (!Reg) {3200 unsigned Offset = State.AllocateStack(ValVT.getStoreSize(), OrigAlign);3201 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));3202 } else3203 State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));3204 3205 return false;3206}3207 3208static bool CC_MipsO32_FP32(unsigned ValNo, MVT ValVT, MVT LocVT,3209 CCValAssign::LocInfo LocInfo,3210 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,3211 CCState &State) {3212 static const MCPhysReg F64Regs[] = { Mips::D6, Mips::D7 };3213 3214 return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State,3215 F64Regs);3216}3217 3218static bool CC_MipsO32_FP64(unsigned ValNo, MVT ValVT, MVT LocVT,3219 CCValAssign::LocInfo LocInfo,3220 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,3221 CCState &State) {3222 static const MCPhysReg F64Regs[] = { Mips::D12_64, Mips::D14_64 };3223 3224 return CC_MipsO32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State,3225 F64Regs);3226}3227 3228[[maybe_unused]] static bool CC_MipsO32(unsigned ValNo, MVT ValVT, MVT LocVT,3229 CCValAssign::LocInfo LocInfo,3230 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,3231 CCState &State);3232 3233#include "MipsGenCallingConv.inc"3234 3235 CCAssignFn *MipsTargetLowering::CCAssignFnForCall() const{3236 return CC_Mips_FixedArg;3237 }3238 3239 CCAssignFn *MipsTargetLowering::CCAssignFnForReturn() const{3240 return RetCC_Mips;3241 }3242//===----------------------------------------------------------------------===//3243// Call Calling Convention Implementation3244//===----------------------------------------------------------------------===//3245 3246SDValue MipsTargetLowering::passArgOnStack(SDValue StackPtr, unsigned Offset,3247 SDValue Chain, SDValue Arg,3248 const SDLoc &DL, bool IsTailCall,3249 SelectionDAG &DAG) const {3250 if (!IsTailCall) {3251 SDValue PtrOff =3252 DAG.getNode(ISD::ADD, DL, getPointerTy(DAG.getDataLayout()), StackPtr,3253 DAG.getIntPtrConstant(Offset, DL));3254 return DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo());3255 }3256 3257 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();3258 int FI = MFI.CreateFixedObject(Arg.getValueSizeInBits() / 8, Offset, false);3259 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));3260 return DAG.getStore(Chain, DL, Arg, FIN, MachinePointerInfo(), MaybeAlign(),3261 MachineMemOperand::MOVolatile);3262}3263 3264void MipsTargetLowering::3265getOpndList(SmallVectorImpl<SDValue> &Ops,3266 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,3267 bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,3268 bool IsCallReloc, CallLoweringInfo &CLI, SDValue Callee,3269 SDValue Chain) const {3270 // Insert node "GP copy globalreg" before call to function.3271 //3272 // R_MIPS_CALL* operators (emitted when non-internal functions are called3273 // in PIC mode) allow symbols to be resolved via lazy binding.3274 // The lazy binding stub requires GP to point to the GOT.3275 // Note that we don't need GP to point to the GOT for indirect calls3276 // (when R_MIPS_CALL* is not used for the call) because Mips linker generates3277 // lazy binding stub for a function only when R_MIPS_CALL* are the only relocs3278 // used for the function (that is, Mips linker doesn't generate lazy binding3279 // stub for a function whose address is taken in the program).3280 if (IsPICCall && !InternalLinkage && IsCallReloc) {3281 unsigned GPReg = ABI.IsN64() ? Mips::GP_64 : Mips::GP;3282 EVT Ty = ABI.IsN64() ? MVT::i64 : MVT::i32;3283 RegsToPass.push_back(std::make_pair(GPReg, getGlobalReg(CLI.DAG, Ty)));3284 }3285 3286 // Build a sequence of copy-to-reg nodes chained together with token3287 // chain and flag operands which copy the outgoing args into registers.3288 // The InGlue in necessary since all emitted instructions must be3289 // stuck together.3290 SDValue InGlue;3291 3292 for (auto &R : RegsToPass) {3293 Chain = CLI.DAG.getCopyToReg(Chain, CLI.DL, R.first, R.second, InGlue);3294 InGlue = Chain.getValue(1);3295 }3296 3297 // Add argument registers to the end of the list so that they are3298 // known live into the call.3299 for (auto &R : RegsToPass)3300 Ops.push_back(CLI.DAG.getRegister(R.first, R.second.getValueType()));3301 3302 // Add a register mask operand representing the call-preserved registers.3303 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();3304 const uint32_t *Mask =3305 TRI->getCallPreservedMask(CLI.DAG.getMachineFunction(), CLI.CallConv);3306 assert(Mask && "Missing call preserved mask for calling convention");3307 if (Subtarget.inMips16HardFloat()) {3308 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {3309 StringRef Sym = G->getGlobal()->getName();3310 Function *F = G->getGlobal()->getParent()->getFunction(Sym);3311 if (F && F->hasFnAttribute("__Mips16RetHelper")) {3312 Mask = MipsRegisterInfo::getMips16RetHelperMask();3313 }3314 }3315 }3316 Ops.push_back(CLI.DAG.getRegisterMask(Mask));3317 3318 if (InGlue.getNode())3319 Ops.push_back(InGlue);3320}3321 3322void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,3323 SDNode *Node) const {3324 switch (MI.getOpcode()) {3325 default:3326 return;3327 case Mips::JALR:3328 case Mips::JALRPseudo:3329 case Mips::JALR64:3330 case Mips::JALR64Pseudo:3331 case Mips::JALR16_MM:3332 case Mips::JALRC16_MMR6:3333 case Mips::TAILCALLREG:3334 case Mips::TAILCALLREG64:3335 case Mips::TAILCALLR6REG:3336 case Mips::TAILCALL64R6REG:3337 case Mips::TAILCALLREG_MM:3338 case Mips::TAILCALLREG_MMR6: {3339 if (!EmitJalrReloc ||3340 Subtarget.inMips16Mode() ||3341 !isPositionIndependent() ||3342 Node->getNumOperands() < 1 ||3343 Node->getOperand(0).getNumOperands() < 2) {3344 return;3345 }3346 // We are after the callee address, set by LowerCall().3347 // If added to MI, asm printer will emit .reloc R_MIPS_JALR for the3348 // symbol.3349 const SDValue TargetAddr = Node->getOperand(0).getOperand(1);3350 StringRef Sym;3351 if (const GlobalAddressSDNode *G =3352 dyn_cast_or_null<const GlobalAddressSDNode>(TargetAddr)) {3353 // We must not emit the R_MIPS_JALR relocation against data symbols3354 // since this will cause run-time crashes if the linker replaces the3355 // call instruction with a relative branch to the data symbol.3356 if (!isa<Function>(G->getGlobal())) {3357 LLVM_DEBUG(dbgs() << "Not adding R_MIPS_JALR against data symbol "3358 << G->getGlobal()->getName() << "\n");3359 return;3360 }3361 Sym = G->getGlobal()->getName();3362 }3363 else if (const ExternalSymbolSDNode *ES =3364 dyn_cast_or_null<const ExternalSymbolSDNode>(TargetAddr)) {3365 Sym = ES->getSymbol();3366 }3367 3368 if (Sym.empty())3369 return;3370 3371 MachineFunction *MF = MI.getParent()->getParent();3372 MCSymbol *S = MF->getContext().getOrCreateSymbol(Sym);3373 LLVM_DEBUG(dbgs() << "Adding R_MIPS_JALR against " << Sym << "\n");3374 MI.addOperand(MachineOperand::CreateMCSymbol(S, MipsII::MO_JALR));3375 }3376 }3377}3378 3379/// LowerCall - functions arguments are copied from virtual regs to3380/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.3381SDValue3382MipsTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,3383 SmallVectorImpl<SDValue> &InVals) const {3384 SelectionDAG &DAG = CLI.DAG;3385 SDLoc DL = CLI.DL;3386 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;3387 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;3388 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;3389 SDValue Chain = CLI.Chain;3390 SDValue Callee = CLI.Callee;3391 bool &IsTailCall = CLI.IsTailCall;3392 CallingConv::ID CallConv = CLI.CallConv;3393 bool IsVarArg = CLI.IsVarArg;3394 const CallBase *CB = CLI.CB;3395 3396 MachineFunction &MF = DAG.getMachineFunction();3397 MachineFrameInfo &MFI = MF.getFrameInfo();3398 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();3399 MipsFunctionInfo *FuncInfo = MF.getInfo<MipsFunctionInfo>();3400 bool IsPIC = isPositionIndependent();3401 3402 // Analyze operands of the call, assigning locations to each operand.3403 SmallVector<CCValAssign, 16> ArgLocs;3404 MipsCCState CCInfo(3405 CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs, *DAG.getContext(),3406 MipsCCState::getSpecialCallingConvForCallee(Callee.getNode(), Subtarget));3407 3408 const ExternalSymbolSDNode *ES =3409 dyn_cast_or_null<const ExternalSymbolSDNode>(Callee.getNode());3410 3411 // There is one case where CALLSEQ_START..CALLSEQ_END can be nested, which3412 // is during the lowering of a call with a byval argument which produces3413 // a call to memcpy. For the O32 case, this causes the caller to allocate3414 // stack space for the reserved argument area for the callee, then recursively3415 // again for the memcpy call. In the NEWABI case, this doesn't occur as those3416 // ABIs mandate that the callee allocates the reserved argument area. We do3417 // still produce nested CALLSEQ_START..CALLSEQ_END with zero space though.3418 //3419 // If the callee has a byval argument and memcpy is used, we are mandated3420 // to already have produced a reserved argument area for the callee for O32.3421 // Therefore, the reserved argument area can be reused for both calls.3422 //3423 // Other cases of calling memcpy cannot have a chain with a CALLSEQ_START3424 // present, as we have yet to hook that node onto the chain.3425 //3426 // Hence, the CALLSEQ_START and CALLSEQ_END nodes can be eliminated in this3427 // case. GCC does a similar trick, in that wherever possible, it calculates3428 // the maximum out going argument area (including the reserved area), and3429 // preallocates the stack space on entrance to the caller.3430 //3431 // FIXME: We should do the same for efficiency and space.3432 3433 // Note: The check on the calling convention below must match3434 // MipsABIInfo::GetCalleeAllocdArgSizeInBytes().3435 bool MemcpyInByVal = ES && StringRef(ES->getSymbol()) == "memcpy" &&3436 CallConv != CallingConv::Fast &&3437 Chain.getOpcode() == ISD::CALLSEQ_START;3438 3439 // Allocate the reserved argument area. It seems strange to do this from the3440 // caller side but removing it breaks the frame size calculation.3441 unsigned ReservedArgArea =3442 MemcpyInByVal ? 0 : ABI.GetCalleeAllocdArgSizeInBytes(CallConv);3443 CCInfo.AllocateStack(ReservedArgArea, Align(1));3444 3445 CCInfo.AnalyzeCallOperands(Outs, CC_Mips);3446 3447 // Get a count of how many bytes are to be pushed on the stack.3448 unsigned StackSize = CCInfo.getStackSize();3449 3450 // Call site info for function parameters tracking and call base type info.3451 MachineFunction::CallSiteInfo CSInfo;3452 // Set type id for call site info.3453 if (MF.getTarget().Options.EmitCallGraphSection && CB && CB->isIndirectCall())3454 CSInfo = MachineFunction::CallSiteInfo(*CB);3455 3456 // Check if it's really possible to do a tail call. Restrict it to functions3457 // that are part of this compilation unit.3458 bool InternalLinkage = false;3459 if (IsTailCall) {3460 IsTailCall = isEligibleForTailCallOptimization(3461 CCInfo, StackSize, *MF.getInfo<MipsFunctionInfo>());3462 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {3463 InternalLinkage = G->getGlobal()->hasInternalLinkage();3464 IsTailCall &= (InternalLinkage || G->getGlobal()->hasLocalLinkage() ||3465 G->getGlobal()->hasPrivateLinkage() ||3466 G->getGlobal()->hasHiddenVisibility() ||3467 G->getGlobal()->hasProtectedVisibility());3468 }3469 }3470 if (!IsTailCall && CLI.CB && CLI.CB->isMustTailCall())3471 report_fatal_error("failed to perform tail call elimination on a call "3472 "site marked musttail");3473 3474 if (IsTailCall)3475 ++NumTailCalls;3476 3477 // Chain is the output chain of the last Load/Store or CopyToReg node.3478 // ByValChain is the output chain of the last Memcpy node created for copying3479 // byval arguments to the stack.3480 unsigned StackAlignment = TFL->getStackAlignment();3481 StackSize = alignTo(StackSize, StackAlignment);3482 3483 if (!(IsTailCall || MemcpyInByVal))3484 Chain = DAG.getCALLSEQ_START(Chain, StackSize, 0, DL);3485 3486 SDValue StackPtr =3487 DAG.getCopyFromReg(Chain, DL, ABI.IsN64() ? Mips::SP_64 : Mips::SP,3488 getPointerTy(DAG.getDataLayout()));3489 std::deque<std::pair<unsigned, SDValue>> RegsToPass;3490 SmallVector<SDValue, 8> MemOpChains;3491 3492 CCInfo.rewindByValRegsInfo();3493 3494 // Walk the register/memloc assignments, inserting copies/loads.3495 for (unsigned i = 0, e = ArgLocs.size(), OutIdx = 0; i != e; ++i, ++OutIdx) {3496 SDValue Arg = OutVals[OutIdx];3497 CCValAssign &VA = ArgLocs[i];3498 MVT ValVT = VA.getValVT(), LocVT = VA.getLocVT();3499 ISD::ArgFlagsTy Flags = Outs[OutIdx].Flags;3500 bool UseUpperBits = false;3501 3502 // ByVal Arg.3503 if (Flags.isByVal()) {3504 unsigned FirstByValReg, LastByValReg;3505 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();3506 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);3507 3508 assert(Flags.getByValSize() &&3509 "ByVal args of size 0 should have been ignored by front-end.");3510 assert(ByValIdx < CCInfo.getInRegsParamsCount());3511 assert(!IsTailCall &&3512 "Do not tail-call optimize if there is a byval argument.");3513 passByValArg(Chain, DL, RegsToPass, MemOpChains, StackPtr, MFI, DAG, Arg,3514 FirstByValReg, LastByValReg, Flags, Subtarget.isLittle(),3515 VA);3516 CCInfo.nextInRegsParam();3517 continue;3518 }3519 3520 // Promote the value if needed.3521 switch (VA.getLocInfo()) {3522 default:3523 llvm_unreachable("Unknown loc info!");3524 case CCValAssign::Full:3525 if (VA.isRegLoc()) {3526 if ((ValVT == MVT::f32 && LocVT == MVT::i32) ||3527 (ValVT == MVT::f64 && LocVT == MVT::i64) ||3528 (ValVT == MVT::i64 && LocVT == MVT::f64))3529 Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg);3530 else if (ValVT == MVT::f64 && LocVT == MVT::i32) {3531 SDValue Lo = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,3532 Arg, DAG.getConstant(0, DL, MVT::i32));3533 SDValue Hi = DAG.getNode(MipsISD::ExtractElementF64, DL, MVT::i32,3534 Arg, DAG.getConstant(1, DL, MVT::i32));3535 if (!Subtarget.isLittle())3536 std::swap(Lo, Hi);3537 3538 assert(VA.needsCustom());3539 3540 Register LocRegLo = VA.getLocReg();3541 Register LocRegHigh = ArgLocs[++i].getLocReg();3542 RegsToPass.push_back(std::make_pair(LocRegLo, Lo));3543 RegsToPass.push_back(std::make_pair(LocRegHigh, Hi));3544 continue;3545 }3546 }3547 break;3548 case CCValAssign::BCvt:3549 Arg = DAG.getNode(ISD::BITCAST, DL, LocVT, Arg);3550 break;3551 case CCValAssign::SExtUpper:3552 UseUpperBits = true;3553 [[fallthrough]];3554 case CCValAssign::SExt:3555 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, LocVT, Arg);3556 break;3557 case CCValAssign::ZExtUpper:3558 UseUpperBits = true;3559 [[fallthrough]];3560 case CCValAssign::ZExt:3561 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, LocVT, Arg);3562 break;3563 case CCValAssign::AExtUpper:3564 UseUpperBits = true;3565 [[fallthrough]];3566 case CCValAssign::AExt:3567 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, LocVT, Arg);3568 break;3569 }3570 3571 if (UseUpperBits) {3572 unsigned ValSizeInBits = Outs[OutIdx].ArgVT.getSizeInBits();3573 unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();3574 Arg = DAG.getNode(3575 ISD::SHL, DL, VA.getLocVT(), Arg,3576 DAG.getConstant(LocSizeInBits - ValSizeInBits, DL, VA.getLocVT()));3577 }3578 3579 // Arguments that can be passed on register must be kept at3580 // RegsToPass vector3581 if (VA.isRegLoc()) {3582 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));3583 3584 // If the parameter is passed through reg $D, which splits into3585 // two physical registers, avoid creating call site info.3586 if (Mips::AFGR64RegClass.contains(VA.getLocReg()))3587 continue;3588 3589 // Collect CSInfo about which register passes which parameter.3590 const TargetOptions &Options = DAG.getTarget().Options;3591 if (Options.EmitCallSiteInfo)3592 CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);3593 3594 continue;3595 }3596 3597 // Register can't get to this point...3598 assert(VA.isMemLoc());3599 3600 // emit ISD::STORE whichs stores the3601 // parameter value to a stack Location3602 MemOpChains.push_back(passArgOnStack(StackPtr, VA.getLocMemOffset(),3603 Chain, Arg, DL, IsTailCall, DAG));3604 }3605 3606 // Transform all store nodes into one single node because all store3607 // nodes are independent of each other.3608 if (!MemOpChains.empty())3609 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, MemOpChains);3610 3611 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every3612 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol3613 // node so that legalize doesn't hack it.3614 3615 EVT Ty = Callee.getValueType();3616 bool GlobalOrExternal = false, IsCallReloc = false;3617 3618 // The long-calls feature is ignored in case of PIC.3619 // While we do not support -mshared / -mno-shared properly,3620 // ignore long-calls in case of -mabicalls too.3621 if (!Subtarget.isABICalls() && !IsPIC) {3622 // If the function should be called using "long call",3623 // get its address into a register to prevent using3624 // of the `jal` instruction for the direct call.3625 if (auto *N = dyn_cast<ExternalSymbolSDNode>(Callee)) {3626 if (Subtarget.useLongCalls())3627 Callee = Subtarget.hasSym32()3628 ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)3629 : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);3630 } else if (auto *N = dyn_cast<GlobalAddressSDNode>(Callee)) {3631 bool UseLongCalls = Subtarget.useLongCalls();3632 // If the function has long-call/far/near attribute3633 // it overrides command line switch pased to the backend.3634 if (auto *F = dyn_cast<Function>(N->getGlobal())) {3635 if (F->hasFnAttribute("long-call"))3636 UseLongCalls = true;3637 else if (F->hasFnAttribute("short-call"))3638 UseLongCalls = false;3639 }3640 if (UseLongCalls)3641 Callee = Subtarget.hasSym32()3642 ? getAddrNonPIC(N, SDLoc(N), Ty, DAG)3643 : getAddrNonPICSym64(N, SDLoc(N), Ty, DAG);3644 }3645 }3646 3647 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {3648 if (Subtarget.isTargetCOFF() &&3649 G->getGlobal()->hasDLLImportStorageClass()) {3650 assert(Subtarget.isTargetWindows() &&3651 "Windows is the only supported COFF target");3652 auto PtrInfo = MachinePointerInfo();3653 Callee = DAG.getLoad(Ty, DL, Chain,3654 getDllimportSymbol(G, SDLoc(G), Ty, DAG), PtrInfo);3655 } else if (IsPIC) {3656 const GlobalValue *Val = G->getGlobal();3657 InternalLinkage = Val->hasInternalLinkage();3658 3659 if (InternalLinkage)3660 Callee = getAddrLocal(G, DL, Ty, DAG, ABI.IsN32() || ABI.IsN64());3661 else if (Subtarget.useXGOT()) {3662 Callee = getAddrGlobalLargeGOT(G, DL, Ty, DAG, MipsII::MO_CALL_HI16,3663 MipsII::MO_CALL_LO16, Chain,3664 FuncInfo->callPtrInfo(MF, Val));3665 IsCallReloc = true;3666 } else {3667 Callee = getAddrGlobal(G, DL, Ty, DAG, MipsII::MO_GOT_CALL, Chain,3668 FuncInfo->callPtrInfo(MF, Val));3669 IsCallReloc = true;3670 }3671 } else3672 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), DL,3673 getPointerTy(DAG.getDataLayout()), 0,3674 MipsII::MO_NO_FLAG);3675 GlobalOrExternal = true;3676 }3677 else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {3678 const char *Sym = S->getSymbol();3679 3680 if (!IsPIC) // static3681 Callee = DAG.getTargetExternalSymbol(3682 Sym, getPointerTy(DAG.getDataLayout()), MipsII::MO_NO_FLAG);3683 else if (Subtarget.useXGOT()) {3684 Callee = getAddrGlobalLargeGOT(S, DL, Ty, DAG, MipsII::MO_CALL_HI16,3685 MipsII::MO_CALL_LO16, Chain,3686 FuncInfo->callPtrInfo(MF, Sym));3687 IsCallReloc = true;3688 } else { // PIC3689 Callee = getAddrGlobal(S, DL, Ty, DAG, MipsII::MO_GOT_CALL, Chain,3690 FuncInfo->callPtrInfo(MF, Sym));3691 IsCallReloc = true;3692 }3693 3694 GlobalOrExternal = true;3695 }3696 3697 SmallVector<SDValue, 8> Ops(1, Chain);3698 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);3699 3700 getOpndList(Ops, RegsToPass, IsPIC, GlobalOrExternal, InternalLinkage,3701 IsCallReloc, CLI, Callee, Chain);3702 3703 if (IsTailCall) {3704 MF.getFrameInfo().setHasTailCall();3705 SDValue Ret = DAG.getNode(MipsISD::TailCall, DL, MVT::Other, Ops);3706 DAG.addCallSiteInfo(Ret.getNode(), std::move(CSInfo));3707 return Ret;3708 }3709 3710 Chain = DAG.getNode(MipsISD::JmpLink, DL, NodeTys, Ops);3711 SDValue InGlue = Chain.getValue(1);3712 3713 DAG.addCallSiteInfo(Chain.getNode(), std::move(CSInfo));3714 3715 // Create the CALLSEQ_END node in the case of where it is not a call to3716 // memcpy.3717 if (!(MemcpyInByVal)) {3718 Chain = DAG.getCALLSEQ_END(Chain, StackSize, 0, InGlue, DL);3719 InGlue = Chain.getValue(1);3720 }3721 3722 // Handle result values, copying them out of physregs into vregs that we3723 // return.3724 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, DL, DAG,3725 InVals, CLI);3726}3727 3728/// LowerCallResult - Lower the result values of a call into the3729/// appropriate copies out of appropriate physical registers.3730SDValue MipsTargetLowering::LowerCallResult(3731 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,3732 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,3733 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals,3734 TargetLowering::CallLoweringInfo &CLI) const {3735 // Assign locations to each value returned by this call.3736 SmallVector<CCValAssign, 16> RVLocs;3737 MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,3738 *DAG.getContext());3739 3740 CCInfo.AnalyzeCallResult(Ins, RetCC_Mips);3741 3742 // Copy all of the result registers out of their specified physreg.3743 for (unsigned i = 0; i != RVLocs.size(); ++i) {3744 CCValAssign &VA = RVLocs[i];3745 assert(VA.isRegLoc() && "Can only return in registers!");3746 3747 SDValue Val = DAG.getCopyFromReg(Chain, DL, RVLocs[i].getLocReg(),3748 RVLocs[i].getLocVT(), InGlue);3749 Chain = Val.getValue(1);3750 InGlue = Val.getValue(2);3751 3752 if (VA.isUpperBitsInLoc()) {3753 unsigned ValSizeInBits = Ins[i].ArgVT.getSizeInBits();3754 unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();3755 unsigned Shift =3756 VA.getLocInfo() == CCValAssign::ZExtUpper ? ISD::SRL : ISD::SRA;3757 Val = DAG.getNode(3758 Shift, DL, VA.getLocVT(), Val,3759 DAG.getConstant(LocSizeInBits - ValSizeInBits, DL, VA.getLocVT()));3760 }3761 3762 switch (VA.getLocInfo()) {3763 default:3764 llvm_unreachable("Unknown loc info!");3765 case CCValAssign::Full:3766 break;3767 case CCValAssign::BCvt:3768 Val = DAG.getNode(ISD::BITCAST, DL, VA.getValVT(), Val);3769 break;3770 case CCValAssign::AExt:3771 case CCValAssign::AExtUpper:3772 Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val);3773 break;3774 case CCValAssign::ZExt:3775 case CCValAssign::ZExtUpper:3776 Val = DAG.getNode(ISD::AssertZext, DL, VA.getLocVT(), Val,3777 DAG.getValueType(VA.getValVT()));3778 Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val);3779 break;3780 case CCValAssign::SExt:3781 case CCValAssign::SExtUpper:3782 Val = DAG.getNode(ISD::AssertSext, DL, VA.getLocVT(), Val,3783 DAG.getValueType(VA.getValVT()));3784 Val = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), Val);3785 break;3786 }3787 3788 InVals.push_back(Val);3789 }3790 3791 return Chain;3792}3793 3794static SDValue UnpackFromArgumentSlot(SDValue Val, const CCValAssign &VA,3795 EVT ArgVT, const SDLoc &DL,3796 SelectionDAG &DAG) {3797 MVT LocVT = VA.getLocVT();3798 EVT ValVT = VA.getValVT();3799 3800 // Shift into the upper bits if necessary.3801 switch (VA.getLocInfo()) {3802 default:3803 break;3804 case CCValAssign::AExtUpper:3805 case CCValAssign::SExtUpper:3806 case CCValAssign::ZExtUpper: {3807 unsigned ValSizeInBits = ArgVT.getSizeInBits();3808 unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();3809 unsigned Opcode =3810 VA.getLocInfo() == CCValAssign::ZExtUpper ? ISD::SRL : ISD::SRA;3811 Val = DAG.getNode(3812 Opcode, DL, VA.getLocVT(), Val,3813 DAG.getConstant(LocSizeInBits - ValSizeInBits, DL, VA.getLocVT()));3814 break;3815 }3816 }3817 3818 // If this is an value smaller than the argument slot size (32-bit for O32,3819 // 64-bit for N32/N64), it has been promoted in some way to the argument slot3820 // size. Extract the value and insert any appropriate assertions regarding3821 // sign/zero extension.3822 switch (VA.getLocInfo()) {3823 default:3824 llvm_unreachable("Unknown loc info!");3825 case CCValAssign::Full:3826 break;3827 case CCValAssign::AExtUpper:3828 case CCValAssign::AExt:3829 Val = DAG.getNode(ISD::TRUNCATE, DL, ValVT, Val);3830 break;3831 case CCValAssign::SExtUpper:3832 case CCValAssign::SExt:3833 Val = DAG.getNode(ISD::AssertSext, DL, LocVT, Val, DAG.getValueType(ValVT));3834 Val = DAG.getNode(ISD::TRUNCATE, DL, ValVT, Val);3835 break;3836 case CCValAssign::ZExtUpper:3837 case CCValAssign::ZExt:3838 Val = DAG.getNode(ISD::AssertZext, DL, LocVT, Val, DAG.getValueType(ValVT));3839 Val = DAG.getNode(ISD::TRUNCATE, DL, ValVT, Val);3840 break;3841 case CCValAssign::BCvt:3842 Val = DAG.getNode(ISD::BITCAST, DL, ValVT, Val);3843 break;3844 }3845 3846 return Val;3847}3848 3849//===----------------------------------------------------------------------===//3850// Formal Arguments Calling Convention Implementation3851//===----------------------------------------------------------------------===//3852/// LowerFormalArguments - transform physical registers into virtual registers3853/// and generate load operations for arguments places on the stack.3854SDValue MipsTargetLowering::LowerFormalArguments(3855 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,3856 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,3857 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {3858 MachineFunction &MF = DAG.getMachineFunction();3859 MachineFrameInfo &MFI = MF.getFrameInfo();3860 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();3861 3862 MipsFI->setVarArgsFrameIndex(0);3863 3864 // Used with vargs to acumulate store chains.3865 std::vector<SDValue> OutChains;3866 3867 // Assign locations to all of the incoming arguments.3868 SmallVector<CCValAssign, 16> ArgLocs;3869 MipsCCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,3870 *DAG.getContext());3871 CCInfo.AllocateStack(ABI.GetCalleeAllocdArgSizeInBytes(CallConv), Align(1));3872 const Function &Func = DAG.getMachineFunction().getFunction();3873 Function::const_arg_iterator FuncArg = Func.arg_begin();3874 3875 if (Func.hasFnAttribute("interrupt") && !Func.arg_empty())3876 report_fatal_error(3877 "Functions with the interrupt attribute cannot have arguments!");3878 3879 CCInfo.AnalyzeFormalArguments(Ins, CC_Mips_FixedArg);3880 MipsFI->setFormalArgInfo(CCInfo.getStackSize(),3881 CCInfo.getInRegsParamsCount() > 0);3882 3883 unsigned CurArgIdx = 0;3884 CCInfo.rewindByValRegsInfo();3885 3886 for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {3887 CCValAssign &VA = ArgLocs[i];3888 if (Ins[InsIdx].isOrigArg()) {3889 std::advance(FuncArg, Ins[InsIdx].getOrigArgIndex() - CurArgIdx);3890 CurArgIdx = Ins[InsIdx].getOrigArgIndex();3891 }3892 EVT ValVT = VA.getValVT();3893 ISD::ArgFlagsTy Flags = Ins[InsIdx].Flags;3894 bool IsRegLoc = VA.isRegLoc();3895 3896 if (Flags.isByVal()) {3897 assert(Ins[InsIdx].isOrigArg() && "Byval arguments cannot be implicit");3898 unsigned FirstByValReg, LastByValReg;3899 unsigned ByValIdx = CCInfo.getInRegsParamsProcessed();3900 CCInfo.getInRegsParamInfo(ByValIdx, FirstByValReg, LastByValReg);3901 3902 assert(Flags.getByValSize() &&3903 "ByVal args of size 0 should have been ignored by front-end.");3904 assert(ByValIdx < CCInfo.getInRegsParamsCount());3905 copyByValRegs(Chain, DL, OutChains, DAG, Flags, InVals, &*FuncArg,3906 FirstByValReg, LastByValReg, VA, CCInfo);3907 CCInfo.nextInRegsParam();3908 continue;3909 }3910 3911 // Arguments stored on registers3912 if (IsRegLoc) {3913 MVT RegVT = VA.getLocVT();3914 Register ArgReg = VA.getLocReg();3915 const TargetRegisterClass *RC = getRegClassFor(RegVT);3916 3917 // Transform the arguments stored on3918 // physical registers into virtual ones3919 unsigned Reg = addLiveIn(DAG.getMachineFunction(), ArgReg, RC);3920 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegVT);3921 3922 ArgValue =3923 UnpackFromArgumentSlot(ArgValue, VA, Ins[InsIdx].ArgVT, DL, DAG);3924 3925 // Handle floating point arguments passed in integer registers and3926 // long double arguments passed in floating point registers.3927 if ((RegVT == MVT::i32 && ValVT == MVT::f32) ||3928 (RegVT == MVT::i64 && ValVT == MVT::f64) ||3929 (RegVT == MVT::f64 && ValVT == MVT::i64))3930 ArgValue = DAG.getNode(ISD::BITCAST, DL, ValVT, ArgValue);3931 else if (ABI.IsO32() && RegVT == MVT::i32 &&3932 ValVT == MVT::f64) {3933 assert(VA.needsCustom() && "Expected custom argument for f64 split");3934 CCValAssign &NextVA = ArgLocs[++i];3935 unsigned Reg2 =3936 addLiveIn(DAG.getMachineFunction(), NextVA.getLocReg(), RC);3937 SDValue ArgValue2 = DAG.getCopyFromReg(Chain, DL, Reg2, RegVT);3938 if (!Subtarget.isLittle())3939 std::swap(ArgValue, ArgValue2);3940 ArgValue = DAG.getNode(MipsISD::BuildPairF64, DL, MVT::f64,3941 ArgValue, ArgValue2);3942 }3943 3944 InVals.push_back(ArgValue);3945 } else { // VA.isRegLoc()3946 MVT LocVT = VA.getLocVT();3947 3948 assert(!VA.needsCustom() && "unexpected custom memory argument");3949 3950 // Only arguments pased on the stack should make it here. 3951 assert(VA.isMemLoc());3952 3953 // The stack pointer offset is relative to the caller stack frame.3954 int FI = MFI.CreateFixedObject(LocVT.getSizeInBits() / 8,3955 VA.getLocMemOffset(), true);3956 3957 // Create load nodes to retrieve arguments from the stack3958 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));3959 SDValue ArgValue = DAG.getLoad(3960 LocVT, DL, Chain, FIN,3961 MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), FI));3962 OutChains.push_back(ArgValue.getValue(1));3963 3964 ArgValue =3965 UnpackFromArgumentSlot(ArgValue, VA, Ins[InsIdx].ArgVT, DL, DAG);3966 3967 InVals.push_back(ArgValue);3968 }3969 }3970 3971 for (unsigned i = 0, e = ArgLocs.size(), InsIdx = 0; i != e; ++i, ++InsIdx) {3972 3973 if (ArgLocs[i].needsCustom()) {3974 ++i;3975 continue;3976 }3977 3978 // The mips ABIs for returning structs by value requires that we copy3979 // the sret argument into $v0 for the return. Save the argument into3980 // a virtual register so that we can access it from the return points.3981 if (Ins[InsIdx].Flags.isSRet()) {3982 unsigned Reg = MipsFI->getSRetReturnReg();3983 if (!Reg) {3984 Reg = MF.getRegInfo().createVirtualRegister(3985 getRegClassFor(ABI.IsN64() ? MVT::i64 : MVT::i32));3986 MipsFI->setSRetReturnReg(Reg);3987 }3988 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[i]);3989 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain);3990 break;3991 }3992 }3993 3994 if (IsVarArg)3995 writeVarArgRegs(OutChains, Chain, DL, DAG, CCInfo);3996 3997 // All stores are grouped in one node to allow the matching between3998 // the size of Ins and InVals. This only happens when on varg functions3999 if (!OutChains.empty()) {4000 OutChains.push_back(Chain);4001 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, OutChains);4002 }4003 4004 return Chain;4005}4006 4007//===----------------------------------------------------------------------===//4008// Return Value Calling Convention Implementation4009//===----------------------------------------------------------------------===//4010 4011bool4012MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,4013 MachineFunction &MF, bool IsVarArg,4014 const SmallVectorImpl<ISD::OutputArg> &Outs,4015 LLVMContext &Context, const Type *RetTy) const {4016 SmallVector<CCValAssign, 16> RVLocs;4017 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);4018 return CCInfo.CheckReturn(Outs, RetCC_Mips);4019}4020 4021bool MipsTargetLowering::shouldSignExtendTypeInLibCall(Type *Ty,4022 bool IsSigned) const {4023 if ((ABI.IsN32() || ABI.IsN64()) && Ty->isIntegerTy(32))4024 return true;4025 4026 return IsSigned;4027}4028 4029SDValue4030MipsTargetLowering::LowerInterruptReturn(SmallVectorImpl<SDValue> &RetOps,4031 const SDLoc &DL,4032 SelectionDAG &DAG) const {4033 MachineFunction &MF = DAG.getMachineFunction();4034 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();4035 4036 MipsFI->setISR();4037 4038 return DAG.getNode(MipsISD::ERet, DL, MVT::Other, RetOps);4039}4040 4041SDValue4042MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,4043 bool IsVarArg,4044 const SmallVectorImpl<ISD::OutputArg> &Outs,4045 const SmallVectorImpl<SDValue> &OutVals,4046 const SDLoc &DL, SelectionDAG &DAG) const {4047 // CCValAssign - represent the assignment of4048 // the return value to a location4049 SmallVector<CCValAssign, 16> RVLocs;4050 MachineFunction &MF = DAG.getMachineFunction();4051 4052 // CCState - Info about the registers and stack slot.4053 MipsCCState CCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext());4054 4055 // Analyze return values.4056 CCInfo.AnalyzeReturn(Outs, RetCC_Mips);4057 4058 SDValue Glue;4059 SmallVector<SDValue, 4> RetOps(1, Chain);4060 4061 // Copy the result values into the output registers.4062 for (unsigned i = 0; i != RVLocs.size(); ++i) {4063 SDValue Val = OutVals[i];4064 CCValAssign &VA = RVLocs[i];4065 assert(VA.isRegLoc() && "Can only return in registers!");4066 bool UseUpperBits = false;4067 4068 switch (VA.getLocInfo()) {4069 default:4070 llvm_unreachable("Unknown loc info!");4071 case CCValAssign::Full:4072 break;4073 case CCValAssign::BCvt:4074 Val = DAG.getNode(ISD::BITCAST, DL, VA.getLocVT(), Val);4075 break;4076 case CCValAssign::AExtUpper:4077 UseUpperBits = true;4078 [[fallthrough]];4079 case CCValAssign::AExt:4080 Val = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Val);4081 break;4082 case CCValAssign::ZExtUpper:4083 UseUpperBits = true;4084 [[fallthrough]];4085 case CCValAssign::ZExt:4086 Val = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Val);4087 break;4088 case CCValAssign::SExtUpper:4089 UseUpperBits = true;4090 [[fallthrough]];4091 case CCValAssign::SExt:4092 Val = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Val);4093 break;4094 }4095 4096 if (UseUpperBits) {4097 unsigned ValSizeInBits = Outs[i].ArgVT.getSizeInBits();4098 unsigned LocSizeInBits = VA.getLocVT().getSizeInBits();4099 Val = DAG.getNode(4100 ISD::SHL, DL, VA.getLocVT(), Val,4101 DAG.getConstant(LocSizeInBits - ValSizeInBits, DL, VA.getLocVT()));4102 }4103 4104 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), Val, Glue);4105 4106 // Guarantee that all emitted copies are stuck together with flags.4107 Glue = Chain.getValue(1);4108 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));4109 }4110 4111 // The mips ABIs for returning structs by value requires that we copy4112 // the sret argument into $v0 for the return. We saved the argument into4113 // a virtual register in the entry block, so now we copy the value out4114 // and into $v0.4115 if (MF.getFunction().hasStructRetAttr()) {4116 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();4117 unsigned Reg = MipsFI->getSRetReturnReg();4118 4119 if (!Reg)4120 llvm_unreachable("sret virtual register not created in the entry block");4121 SDValue Val =4122 DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy(DAG.getDataLayout()));4123 unsigned V0 = ABI.IsN64() ? Mips::V0_64 : Mips::V0;4124 4125 Chain = DAG.getCopyToReg(Chain, DL, V0, Val, Glue);4126 Glue = Chain.getValue(1);4127 RetOps.push_back(DAG.getRegister(V0, getPointerTy(DAG.getDataLayout())));4128 }4129 4130 RetOps[0] = Chain; // Update chain.4131 4132 // Add the glue if we have it.4133 if (Glue.getNode())4134 RetOps.push_back(Glue);4135 4136 // ISRs must use "eret".4137 if (DAG.getMachineFunction().getFunction().hasFnAttribute("interrupt"))4138 return LowerInterruptReturn(RetOps, DL, DAG);4139 4140 // Standard return on Mips is a "jr $ra"4141 return DAG.getNode(MipsISD::Ret, DL, MVT::Other, RetOps);4142}4143 4144//===----------------------------------------------------------------------===//4145// Mips Inline Assembly Support4146//===----------------------------------------------------------------------===//4147 4148/// getConstraintType - Given a constraint letter, return the type of4149/// constraint it is for this target.4150MipsTargetLowering::ConstraintType4151MipsTargetLowering::getConstraintType(StringRef Constraint) const {4152 // Mips specific constraints4153 // GCC config/mips/constraints.md4154 //4155 // 'd' : An address register. Equivalent to r4156 // unless generating MIPS16 code.4157 // 'y' : Equivalent to r; retained for4158 // backwards compatibility.4159 // 'c' : A register suitable for use in an indirect4160 // jump. This will always be $25 for -mabicalls.4161 // 'l' : The lo register. 1 word storage.4162 // 'x' : The hilo register pair. Double word storage.4163 if (Constraint.size() == 1) {4164 switch (Constraint[0]) {4165 default : break;4166 case 'd':4167 case 'y':4168 case 'f':4169 case 'c':4170 case 'l':4171 case 'x':4172 return C_RegisterClass;4173 case 'R':4174 return C_Memory;4175 }4176 }4177 4178 if (Constraint == "ZC")4179 return C_Memory;4180 4181 return TargetLowering::getConstraintType(Constraint);4182}4183 4184/// Examine constraint type and operand type and determine a weight value.4185/// This object must already have been set up with the operand type4186/// and the current alternative constraint selected.4187TargetLowering::ConstraintWeight4188MipsTargetLowering::getSingleConstraintMatchWeight(4189 AsmOperandInfo &info, const char *constraint) const {4190 ConstraintWeight weight = CW_Invalid;4191 Value *CallOperandVal = info.CallOperandVal;4192 // If we don't have a value, we can't do a match,4193 // but allow it at the lowest weight.4194 if (!CallOperandVal)4195 return CW_Default;4196 Type *type = CallOperandVal->getType();4197 // Look at the constraint type.4198 switch (*constraint) {4199 default:4200 weight = TargetLowering::getSingleConstraintMatchWeight(info, constraint);4201 break;4202 case 'd':4203 case 'y':4204 if (type->isIntegerTy())4205 weight = CW_Register;4206 break;4207 case 'f': // FPU or MSA register4208 if (Subtarget.hasMSA() && type->isVectorTy() &&4209 type->getPrimitiveSizeInBits().getFixedValue() == 128)4210 weight = CW_Register;4211 else if (type->isFloatTy())4212 weight = CW_Register;4213 break;4214 case 'c': // $25 for indirect jumps4215 case 'l': // lo register4216 case 'x': // hilo register pair4217 if (type->isIntegerTy())4218 weight = CW_SpecificReg;4219 break;4220 case 'I': // signed 16 bit immediate4221 case 'J': // integer zero4222 case 'K': // unsigned 16 bit immediate4223 case 'L': // signed 32 bit immediate where lower 16 bits are 04224 case 'N': // immediate in the range of -65535 to -1 (inclusive)4225 case 'O': // signed 15 bit immediate (+- 16383)4226 case 'P': // immediate in the range of 65535 to 1 (inclusive)4227 if (isa<ConstantInt>(CallOperandVal))4228 weight = CW_Constant;4229 break;4230 case 'R':4231 weight = CW_Memory;4232 break;4233 }4234 return weight;4235}4236 4237/// This is a helper function to parse a physical register string and split it4238/// into non-numeric and numeric parts (Prefix and Reg). The first boolean flag4239/// that is returned indicates whether parsing was successful. The second flag4240/// is true if the numeric part exists.4241static std::pair<bool, bool> parsePhysicalReg(StringRef C, StringRef &Prefix,4242 unsigned long long &Reg) {4243 if (C.front() != '{' || C.back() != '}')4244 return std::make_pair(false, false);4245 4246 // Search for the first numeric character.4247 StringRef::const_iterator I, B = C.begin() + 1, E = C.end() - 1;4248 I = std::find_if(B, E, isdigit);4249 4250 Prefix = StringRef(B, I - B);4251 4252 // The second flag is set to false if no numeric characters were found.4253 if (I == E)4254 return std::make_pair(true, false);4255 4256 // Parse the numeric characters.4257 return std::make_pair(!getAsUnsignedInteger(StringRef(I, E - I), 10, Reg),4258 true);4259}4260 4261EVT MipsTargetLowering::getTypeForExtReturn(LLVMContext &Context, EVT VT,4262 ISD::NodeType) const {4263 bool Cond = !Subtarget.isABI_O32() && VT.getSizeInBits() == 32;4264 EVT MinVT = getRegisterType(Cond ? MVT::i64 : MVT::i32);4265 return VT.bitsLT(MinVT) ? MinVT : VT;4266}4267 4268std::pair<unsigned, const TargetRegisterClass *> MipsTargetLowering::4269parseRegForInlineAsmConstraint(StringRef C, MVT VT) const {4270 const TargetRegisterInfo *TRI =4271 Subtarget.getRegisterInfo();4272 const TargetRegisterClass *RC;4273 StringRef Prefix;4274 unsigned long long Reg;4275 4276 std::pair<bool, bool> R = parsePhysicalReg(C, Prefix, Reg);4277 4278 if (!R.first)4279 return std::make_pair(0U, nullptr);4280 4281 if ((Prefix == "hi" || Prefix == "lo")) { // Parse hi/lo.4282 // No numeric characters follow "hi" or "lo".4283 if (R.second)4284 return std::make_pair(0U, nullptr);4285 4286 RC = TRI->getRegClass(Prefix == "hi" ?4287 Mips::HI32RegClassID : Mips::LO32RegClassID);4288 return std::make_pair(*(RC->begin()), RC);4289 } else if (Prefix.starts_with("$msa")) {4290 // Parse $msa(ir|csr|access|save|modify|request|map|unmap)4291 4292 // No numeric characters follow the name.4293 if (R.second)4294 return std::make_pair(0U, nullptr);4295 4296 Reg = StringSwitch<unsigned long long>(Prefix)4297 .Case("$msair", Mips::MSAIR)4298 .Case("$msacsr", Mips::MSACSR)4299 .Case("$msaaccess", Mips::MSAAccess)4300 .Case("$msasave", Mips::MSASave)4301 .Case("$msamodify", Mips::MSAModify)4302 .Case("$msarequest", Mips::MSARequest)4303 .Case("$msamap", Mips::MSAMap)4304 .Case("$msaunmap", Mips::MSAUnmap)4305 .Default(0);4306 4307 if (!Reg)4308 return std::make_pair(0U, nullptr);4309 4310 RC = TRI->getRegClass(Mips::MSACtrlRegClassID);4311 return std::make_pair(Reg, RC);4312 }4313 4314 if (!R.second)4315 return std::make_pair(0U, nullptr);4316 4317 if (Prefix == "$f") { // Parse $f0-$f31.4318 // If the targets is single float only, always select 32-bit registers,4319 // otherwise if the size of FP registers is 64-bit or Reg is an even number,4320 // select the 64-bit register class. Otherwise, select the 32-bit register4321 // class.4322 if (VT == MVT::Other) {4323 if (Subtarget.isSingleFloat())4324 VT = MVT::f32;4325 else4326 VT = (Subtarget.isFP64bit() || !(Reg % 2)) ? MVT::f64 : MVT::f32;4327 }4328 4329 RC = getRegClassFor(VT);4330 4331 if (RC == &Mips::AFGR64RegClass) {4332 assert(Reg % 2 == 0);4333 Reg >>= 1;4334 }4335 } else if (Prefix == "$fcc") // Parse $fcc0-$fcc7.4336 RC = TRI->getRegClass(Mips::FCCRegClassID);4337 else if (Prefix == "$w") { // Parse $w0-$w31.4338 RC = getRegClassFor((VT == MVT::Other) ? MVT::v16i8 : VT);4339 } else { // Parse $0-$31.4340 assert(Prefix == "$");4341 RC = getRegClassFor((VT == MVT::Other) ? MVT::i32 : VT);4342 }4343 4344 assert(Reg < RC->getNumRegs());4345 return std::make_pair(*(RC->begin() + Reg), RC);4346}4347 4348/// Given a register class constraint, like 'r', if this corresponds directly4349/// to an LLVM register class, return a register of 0 and the register class4350/// pointer.4351std::pair<unsigned, const TargetRegisterClass *>4352MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,4353 StringRef Constraint,4354 MVT VT) const {4355 if (Constraint.size() == 1) {4356 switch (Constraint[0]) {4357 case 'd': // Address register. Same as 'r' unless generating MIPS16 code.4358 case 'y': // Same as 'r'. Exists for compatibility.4359 case 'r':4360 if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 ||4361 VT == MVT::i1) ||4362 (VT == MVT::f32 && Subtarget.useSoftFloat())) {4363 if (Subtarget.inMips16Mode())4364 return std::make_pair(0U, &Mips::CPU16RegsRegClass);4365 return std::make_pair(0U, &Mips::GPR32RegClass);4366 }4367 if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat()) ||4368 (VT == MVT::f64 && Subtarget.isSingleFloat())) &&4369 !Subtarget.isGP64bit())4370 return std::make_pair(0U, &Mips::GPR32RegClass);4371 if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat()) ||4372 (VT == MVT::f64 && Subtarget.isSingleFloat())) &&4373 Subtarget.isGP64bit())4374 return std::make_pair(0U, &Mips::GPR64RegClass);4375 // This will generate an error message4376 return std::make_pair(0U, nullptr);4377 case 'f': // FPU or MSA register4378 if (VT == MVT::v16i8)4379 return std::make_pair(0U, &Mips::MSA128BRegClass);4380 else if (VT == MVT::v8i16 || VT == MVT::v8f16)4381 return std::make_pair(0U, &Mips::MSA128HRegClass);4382 else if (VT == MVT::v4i32 || VT == MVT::v4f32)4383 return std::make_pair(0U, &Mips::MSA128WRegClass);4384 else if (VT == MVT::v2i64 || VT == MVT::v2f64)4385 return std::make_pair(0U, &Mips::MSA128DRegClass);4386 else if (VT == MVT::f32)4387 return std::make_pair(0U, &Mips::FGR32RegClass);4388 else if ((VT == MVT::f64) && (!Subtarget.isSingleFloat())) {4389 if (Subtarget.isFP64bit())4390 return std::make_pair(0U, &Mips::FGR64RegClass);4391 return std::make_pair(0U, &Mips::AFGR64RegClass);4392 }4393 break;4394 case 'c': // register suitable for indirect jump4395 if (VT == MVT::i32)4396 return std::make_pair((unsigned)Mips::T9, &Mips::GPR32RegClass);4397 if (VT == MVT::i64)4398 return std::make_pair((unsigned)Mips::T9_64, &Mips::GPR64RegClass);4399 // This will generate an error message4400 return std::make_pair(0U, nullptr);4401 case 'l': // use the `lo` register to store values4402 // that are no bigger than a word4403 if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8)4404 return std::make_pair((unsigned)Mips::LO0, &Mips::LO32RegClass);4405 return std::make_pair((unsigned)Mips::LO0_64, &Mips::LO64RegClass);4406 case 'x': // use the concatenated `hi` and `lo` registers4407 // to store doubleword values4408 // Fixme: Not triggering the use of both hi and low4409 // This will generate an error message4410 return std::make_pair(0U, nullptr);4411 }4412 }4413 4414 if (!Constraint.empty()) {4415 std::pair<unsigned, const TargetRegisterClass *> R;4416 R = parseRegForInlineAsmConstraint(Constraint, VT);4417 4418 if (R.second)4419 return R;4420 }4421 4422 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);4423}4424 4425/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops4426/// vector. If it is invalid, don't add anything to Ops.4427void MipsTargetLowering::LowerAsmOperandForConstraint(SDValue Op,4428 StringRef Constraint,4429 std::vector<SDValue> &Ops,4430 SelectionDAG &DAG) const {4431 SDLoc DL(Op);4432 SDValue Result;4433 4434 // Only support length 1 constraints for now.4435 if (Constraint.size() > 1)4436 return;4437 4438 char ConstraintLetter = Constraint[0];4439 switch (ConstraintLetter) {4440 default: break; // This will fall through to the generic implementation4441 case 'I': // Signed 16 bit constant4442 // If this fails, the parent routine will give an error4443 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {4444 EVT Type = Op.getValueType();4445 int64_t Val = C->getSExtValue();4446 if (isInt<16>(Val)) {4447 Result = DAG.getSignedTargetConstant(Val, DL, Type);4448 break;4449 }4450 }4451 return;4452 case 'J': // integer zero4453 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {4454 EVT Type = Op.getValueType();4455 int64_t Val = C->getZExtValue();4456 if (Val == 0) {4457 Result = DAG.getTargetConstant(0, DL, Type);4458 break;4459 }4460 }4461 return;4462 case 'K': // unsigned 16 bit immediate4463 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {4464 EVT Type = Op.getValueType();4465 uint64_t Val = C->getZExtValue();4466 if (isUInt<16>(Val)) {4467 Result = DAG.getTargetConstant(Val, DL, Type);4468 break;4469 }4470 }4471 return;4472 case 'L': // signed 32 bit immediate where lower 16 bits are 04473 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {4474 EVT Type = Op.getValueType();4475 int64_t Val = C->getSExtValue();4476 if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)){4477 Result = DAG.getSignedTargetConstant(Val, DL, Type);4478 break;4479 }4480 }4481 return;4482 case 'N': // immediate in the range of -65535 to -1 (inclusive)4483 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {4484 EVT Type = Op.getValueType();4485 int64_t Val = C->getSExtValue();4486 if ((Val >= -65535) && (Val <= -1)) {4487 Result = DAG.getSignedTargetConstant(Val, DL, Type);4488 break;4489 }4490 }4491 return;4492 case 'O': // signed 15 bit immediate4493 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {4494 EVT Type = Op.getValueType();4495 int64_t Val = C->getSExtValue();4496 if ((isInt<15>(Val))) {4497 Result = DAG.getSignedTargetConstant(Val, DL, Type);4498 break;4499 }4500 }4501 return;4502 case 'P': // immediate in the range of 1 to 65535 (inclusive)4503 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {4504 EVT Type = Op.getValueType();4505 int64_t Val = C->getSExtValue();4506 if ((Val <= 65535) && (Val >= 1)) {4507 Result = DAG.getTargetConstant(Val, DL, Type);4508 break;4509 }4510 }4511 return;4512 }4513 4514 if (Result.getNode()) {4515 Ops.push_back(Result);4516 return;4517 }4518 4519 TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);4520}4521 4522bool MipsTargetLowering::isLegalAddressingMode(const DataLayout &DL,4523 const AddrMode &AM, Type *Ty,4524 unsigned AS,4525 Instruction *I) const {4526 // No global is ever allowed as a base.4527 if (AM.BaseGV)4528 return false;4529 4530 switch (AM.Scale) {4531 case 0: // "r+i" or just "i", depending on HasBaseReg.4532 break;4533 case 1:4534 if (!AM.HasBaseReg) // allow "r+i".4535 break;4536 return false; // disallow "r+r" or "r+r+i".4537 default:4538 return false;4539 }4540 4541 return true;4542}4543 4544bool4545MipsTargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {4546 // The Mips target isn't yet aware of offsets.4547 return false;4548}4549 4550EVT MipsTargetLowering::getOptimalMemOpType(4551 LLVMContext &Context, const MemOp &Op,4552 const AttributeList &FuncAttributes) const {4553 if (Subtarget.hasMips64())4554 return MVT::i64;4555 4556 return MVT::i32;4557}4558 4559bool MipsTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,4560 bool ForCodeSize) const {4561 if (VT != MVT::f32 && VT != MVT::f64)4562 return false;4563 if (Imm.isNegZero())4564 return false;4565 return Imm.isZero();4566}4567 4568bool MipsTargetLowering::isLegalICmpImmediate(int64_t Imm) const {4569 return isInt<16>(Imm);4570}4571 4572bool MipsTargetLowering::isLegalAddImmediate(int64_t Imm) const {4573 return isInt<16>(Imm);4574}4575 4576unsigned MipsTargetLowering::getJumpTableEncoding() const {4577 if (!isPositionIndependent())4578 return MachineJumpTableInfo::EK_BlockAddress;4579 if (ABI.IsN64())4580 return MachineJumpTableInfo::EK_GPRel64BlockAddress;4581 return MachineJumpTableInfo::EK_GPRel32BlockAddress;4582}4583 4584SDValue MipsTargetLowering::getPICJumpTableRelocBase(SDValue Table,4585 SelectionDAG &DAG) const {4586 if (!isPositionIndependent())4587 return Table;4588 return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy(DAG.getDataLayout()));4589}4590 4591bool MipsTargetLowering::useSoftFloat() const {4592 return Subtarget.useSoftFloat();4593}4594 4595void MipsTargetLowering::copyByValRegs(4596 SDValue Chain, const SDLoc &DL, std::vector<SDValue> &OutChains,4597 SelectionDAG &DAG, const ISD::ArgFlagsTy &Flags,4598 SmallVectorImpl<SDValue> &InVals, const Argument *FuncArg,4599 unsigned FirstReg, unsigned LastReg, const CCValAssign &VA,4600 MipsCCState &State) const {4601 MachineFunction &MF = DAG.getMachineFunction();4602 MachineFrameInfo &MFI = MF.getFrameInfo();4603 unsigned GPRSizeInBytes = Subtarget.getGPRSizeInBytes();4604 unsigned NumRegs = LastReg - FirstReg;4605 unsigned RegAreaSize = NumRegs * GPRSizeInBytes;4606 unsigned FrameObjSize = std::max(Flags.getByValSize(), RegAreaSize);4607 int FrameObjOffset;4608 ArrayRef<MCPhysReg> ByValArgRegs = ABI.GetByValArgRegs();4609 4610 if (RegAreaSize)4611 FrameObjOffset =4612 (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) -4613 (int)((ByValArgRegs.size() - FirstReg) * GPRSizeInBytes);4614 else4615 FrameObjOffset = VA.getLocMemOffset();4616 4617 // Create frame object.4618 EVT PtrTy = getPointerTy(DAG.getDataLayout());4619 // Make the fixed object stored to mutable so that the load instructions4620 // referencing it have their memory dependencies added.4621 // Set the frame object as isAliased which clears the underlying objects4622 // vector in ScheduleDAGInstrs::buildSchedGraph() resulting in addition of all4623 // stores as dependencies for loads referencing this fixed object.4624 int FI = MFI.CreateFixedObject(FrameObjSize, FrameObjOffset, false, true);4625 SDValue FIN = DAG.getFrameIndex(FI, PtrTy);4626 InVals.push_back(FIN);4627 4628 if (!NumRegs)4629 return;4630 4631 // Copy arg registers.4632 MVT RegTy = MVT::getIntegerVT(GPRSizeInBytes * 8);4633 const TargetRegisterClass *RC = getRegClassFor(RegTy);4634 4635 for (unsigned I = 0; I < NumRegs; ++I) {4636 unsigned ArgReg = ByValArgRegs[FirstReg + I];4637 unsigned VReg = addLiveIn(MF, ArgReg, RC);4638 unsigned Offset = I * GPRSizeInBytes;4639 SDValue StorePtr = DAG.getNode(ISD::ADD, DL, PtrTy, FIN,4640 DAG.getConstant(Offset, DL, PtrTy));4641 SDValue Store = DAG.getStore(Chain, DL, DAG.getRegister(VReg, RegTy),4642 StorePtr, MachinePointerInfo(FuncArg, Offset));4643 OutChains.push_back(Store);4644 }4645}4646 4647// Copy byVal arg to registers and stack.4648void MipsTargetLowering::passByValArg(4649 SDValue Chain, const SDLoc &DL,4650 std::deque<std::pair<unsigned, SDValue>> &RegsToPass,4651 SmallVectorImpl<SDValue> &MemOpChains, SDValue StackPtr,4652 MachineFrameInfo &MFI, SelectionDAG &DAG, SDValue Arg, unsigned FirstReg,4653 unsigned LastReg, const ISD::ArgFlagsTy &Flags, bool isLittle,4654 const CCValAssign &VA) const {4655 unsigned ByValSizeInBytes = Flags.getByValSize();4656 unsigned OffsetInBytes = 0; // From beginning of struct4657 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();4658 Align Alignment =4659 std::min(Flags.getNonZeroByValAlign(), Align(RegSizeInBytes));4660 EVT PtrTy = getPointerTy(DAG.getDataLayout()),4661 RegTy = MVT::getIntegerVT(RegSizeInBytes * 8);4662 unsigned NumRegs = LastReg - FirstReg;4663 4664 if (NumRegs) {4665 ArrayRef<MCPhysReg> ArgRegs = ABI.GetByValArgRegs();4666 bool LeftoverBytes = (NumRegs * RegSizeInBytes > ByValSizeInBytes);4667 unsigned I = 0;4668 4669 // Copy words to registers.4670 for (; I < NumRegs - LeftoverBytes; ++I, OffsetInBytes += RegSizeInBytes) {4671 SDValue LoadPtr = DAG.getNode(ISD::ADD, DL, PtrTy, Arg,4672 DAG.getConstant(OffsetInBytes, DL, PtrTy));4673 SDValue LoadVal = DAG.getLoad(RegTy, DL, Chain, LoadPtr,4674 MachinePointerInfo(), Alignment);4675 MemOpChains.push_back(LoadVal.getValue(1));4676 unsigned ArgReg = ArgRegs[FirstReg + I];4677 RegsToPass.push_back(std::make_pair(ArgReg, LoadVal));4678 }4679 4680 // Return if the struct has been fully copied.4681 if (ByValSizeInBytes == OffsetInBytes)4682 return;4683 4684 // Copy the remainder of the byval argument with sub-word loads and shifts.4685 if (LeftoverBytes) {4686 SDValue Val;4687 4688 for (unsigned LoadSizeInBytes = RegSizeInBytes / 2, TotalBytesLoaded = 0;4689 OffsetInBytes < ByValSizeInBytes; LoadSizeInBytes /= 2) {4690 unsigned RemainingSizeInBytes = ByValSizeInBytes - OffsetInBytes;4691 4692 if (RemainingSizeInBytes < LoadSizeInBytes)4693 continue;4694 4695 // Load subword.4696 SDValue LoadPtr = DAG.getNode(ISD::ADD, DL, PtrTy, Arg,4697 DAG.getConstant(OffsetInBytes, DL,4698 PtrTy));4699 SDValue LoadVal = DAG.getExtLoad(4700 ISD::ZEXTLOAD, DL, RegTy, Chain, LoadPtr, MachinePointerInfo(),4701 MVT::getIntegerVT(LoadSizeInBytes * 8), Alignment);4702 MemOpChains.push_back(LoadVal.getValue(1));4703 4704 // Shift the loaded value.4705 unsigned Shamt;4706 4707 if (isLittle)4708 Shamt = TotalBytesLoaded * 8;4709 else4710 Shamt = (RegSizeInBytes - (TotalBytesLoaded + LoadSizeInBytes)) * 8;4711 4712 SDValue Shift = DAG.getNode(ISD::SHL, DL, RegTy, LoadVal,4713 DAG.getConstant(Shamt, DL, MVT::i32));4714 4715 if (Val.getNode())4716 Val = DAG.getNode(ISD::OR, DL, RegTy, Val, Shift);4717 else4718 Val = Shift;4719 4720 OffsetInBytes += LoadSizeInBytes;4721 TotalBytesLoaded += LoadSizeInBytes;4722 Alignment = std::min(Alignment, Align(LoadSizeInBytes));4723 }4724 4725 unsigned ArgReg = ArgRegs[FirstReg + I];4726 RegsToPass.push_back(std::make_pair(ArgReg, Val));4727 return;4728 }4729 }4730 4731 // Copy remainder of byval arg to it with memcpy.4732 unsigned MemCpySize = ByValSizeInBytes - OffsetInBytes;4733 SDValue Src = DAG.getNode(ISD::ADD, DL, PtrTy, Arg,4734 DAG.getConstant(OffsetInBytes, DL, PtrTy));4735 SDValue Dst = DAG.getNode(ISD::ADD, DL, PtrTy, StackPtr,4736 DAG.getIntPtrConstant(VA.getLocMemOffset(), DL));4737 Chain = DAG.getMemcpy(4738 Chain, DL, Dst, Src, DAG.getConstant(MemCpySize, DL, PtrTy),4739 Align(Alignment), /*isVolatile=*/false, /*AlwaysInline=*/false,4740 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(), MachinePointerInfo());4741 MemOpChains.push_back(Chain);4742}4743 4744void MipsTargetLowering::writeVarArgRegs(std::vector<SDValue> &OutChains,4745 SDValue Chain, const SDLoc &DL,4746 SelectionDAG &DAG,4747 CCState &State) const {4748 ArrayRef<MCPhysReg> ArgRegs = ABI.getVarArgRegs(Subtarget.isGP64bit());4749 unsigned Idx = State.getFirstUnallocated(ArgRegs);4750 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();4751 MVT RegTy = MVT::getIntegerVT(RegSizeInBytes * 8);4752 const TargetRegisterClass *RC = getRegClassFor(RegTy);4753 MachineFunction &MF = DAG.getMachineFunction();4754 MachineFrameInfo &MFI = MF.getFrameInfo();4755 MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>();4756 4757 // Offset of the first variable argument from stack pointer.4758 int VaArgOffset;4759 4760 if (ArgRegs.size() == Idx)4761 VaArgOffset = alignTo(State.getStackSize(), RegSizeInBytes);4762 else {4763 VaArgOffset =4764 (int)ABI.GetCalleeAllocdArgSizeInBytes(State.getCallingConv()) -4765 (int)(RegSizeInBytes * (ArgRegs.size() - Idx));4766 }4767 4768 // Record the frame index of the first variable argument4769 // which is a value necessary to VASTART.4770 int FI = MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset, true);4771 MipsFI->setVarArgsFrameIndex(FI);4772 4773 // Copy the integer registers that have not been used for argument passing4774 // to the argument register save area. For O32, the save area is allocated4775 // in the caller's stack frame, while for N32/64, it is allocated in the4776 // callee's stack frame.4777 for (unsigned I = Idx; I < ArgRegs.size();4778 ++I, VaArgOffset += RegSizeInBytes) {4779 unsigned Reg = addLiveIn(MF, ArgRegs[I], RC);4780 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, Reg, RegTy);4781 FI = MFI.CreateFixedObject(RegSizeInBytes, VaArgOffset, true);4782 SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));4783 SDValue Store =4784 DAG.getStore(Chain, DL, ArgValue, PtrOff, MachinePointerInfo());4785 cast<StoreSDNode>(Store.getNode())->getMemOperand()->setValue(4786 (Value *)nullptr);4787 OutChains.push_back(Store);4788 }4789}4790 4791void MipsTargetLowering::HandleByVal(CCState *State, unsigned &Size,4792 Align Alignment) const {4793 const TargetFrameLowering *TFL = Subtarget.getFrameLowering();4794 4795 assert(Size && "Byval argument's size shouldn't be 0.");4796 4797 Alignment = std::min(Alignment, TFL->getStackAlign());4798 4799 unsigned FirstReg = 0;4800 unsigned NumRegs = 0;4801 4802 if (State->getCallingConv() != CallingConv::Fast) {4803 unsigned RegSizeInBytes = Subtarget.getGPRSizeInBytes();4804 ArrayRef<MCPhysReg> IntArgRegs = ABI.GetByValArgRegs();4805 // FIXME: The O32 case actually describes no shadow registers.4806 const MCPhysReg *ShadowRegs =4807 ABI.IsO32() ? IntArgRegs.data() : Mips64DPRegs;4808 4809 // We used to check the size as well but we can't do that anymore since4810 // CCState::HandleByVal() rounds up the size after calling this function.4811 assert(4812 Alignment >= Align(RegSizeInBytes) &&4813 "Byval argument's alignment should be a multiple of RegSizeInBytes.");4814 4815 FirstReg = State->getFirstUnallocated(IntArgRegs);4816 4817 // If Alignment > RegSizeInBytes, the first arg register must be even.4818 // FIXME: This condition happens to do the right thing but it's not the4819 // right way to test it. We want to check that the stack frame offset4820 // of the register is aligned.4821 if ((Alignment > RegSizeInBytes) && (FirstReg % 2)) {4822 State->AllocateReg(IntArgRegs[FirstReg], ShadowRegs[FirstReg]);4823 ++FirstReg;4824 }4825 4826 // Mark the registers allocated.4827 Size = alignTo(Size, RegSizeInBytes);4828 for (unsigned I = FirstReg; Size > 0 && (I < IntArgRegs.size());4829 Size -= RegSizeInBytes, ++I, ++NumRegs)4830 State->AllocateReg(IntArgRegs[I], ShadowRegs[I]);4831 }4832 4833 State->addInRegsParamInfo(FirstReg, FirstReg + NumRegs);4834}4835 4836MachineBasicBlock *MipsTargetLowering::emitPseudoSELECT(MachineInstr &MI,4837 MachineBasicBlock *BB,4838 bool isFPCmp,4839 unsigned Opc) const {4840 assert(!(Subtarget.hasMips4() || Subtarget.hasMips32()) &&4841 "Subtarget already supports SELECT nodes with the use of"4842 "conditional-move instructions.");4843 4844 const TargetInstrInfo *TII =4845 Subtarget.getInstrInfo();4846 DebugLoc DL = MI.getDebugLoc();4847 4848 // To "insert" a SELECT instruction, we actually have to insert the4849 // diamond control-flow pattern. The incoming instruction knows the4850 // destination vreg to set, the condition code register to branch on, the4851 // true/false values to select between, and a branch opcode to use.4852 const BasicBlock *LLVM_BB = BB->getBasicBlock();4853 MachineFunction::iterator It = ++BB->getIterator();4854 4855 // thisMBB:4856 // ...4857 // TrueVal = ...4858 // setcc r1, r2, r34859 // bNE r1, r0, copy1MBB4860 // fallthrough --> copy0MBB4861 MachineBasicBlock *thisMBB = BB;4862 MachineFunction *F = BB->getParent();4863 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);4864 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);4865 F->insert(It, copy0MBB);4866 F->insert(It, sinkMBB);4867 4868 // Transfer the remainder of BB and its successor edges to sinkMBB.4869 sinkMBB->splice(sinkMBB->begin(), BB,4870 std::next(MachineBasicBlock::iterator(MI)), BB->end());4871 sinkMBB->transferSuccessorsAndUpdatePHIs(BB);4872 4873 // Next, add the true and fallthrough blocks as its successors.4874 BB->addSuccessor(copy0MBB);4875 BB->addSuccessor(sinkMBB);4876 4877 if (isFPCmp) {4878 // bc1[tf] cc, sinkMBB4879 BuildMI(BB, DL, TII->get(Opc))4880 .addReg(MI.getOperand(1).getReg())4881 .addMBB(sinkMBB);4882 } else {4883 // bne rs, $0, sinkMBB4884 BuildMI(BB, DL, TII->get(Opc))4885 .addReg(MI.getOperand(1).getReg())4886 .addReg(Mips::ZERO)4887 .addMBB(sinkMBB);4888 }4889 4890 // copy0MBB:4891 // %FalseValue = ...4892 // # fallthrough to sinkMBB4893 BB = copy0MBB;4894 4895 // Update machine-CFG edges4896 BB->addSuccessor(sinkMBB);4897 4898 // sinkMBB:4899 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]4900 // ...4901 BB = sinkMBB;4902 4903 BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())4904 .addReg(MI.getOperand(2).getReg())4905 .addMBB(thisMBB)4906 .addReg(MI.getOperand(3).getReg())4907 .addMBB(copy0MBB);4908 4909 MI.eraseFromParent(); // The pseudo instruction is gone now.4910 4911 return BB;4912}4913 4914MachineBasicBlock *4915MipsTargetLowering::emitPseudoD_SELECT(MachineInstr &MI,4916 MachineBasicBlock *BB) const {4917 assert(!(Subtarget.hasMips4() || Subtarget.hasMips32()) &&4918 "Subtarget already supports SELECT nodes with the use of"4919 "conditional-move instructions.");4920 4921 const TargetInstrInfo *TII = Subtarget.getInstrInfo();4922 DebugLoc DL = MI.getDebugLoc();4923 4924 // D_SELECT substitutes two SELECT nodes that goes one after another and4925 // have the same condition operand. On machines which don't have4926 // conditional-move instruction, it reduces unnecessary branch instructions4927 // which are result of using two diamond patterns that are result of two4928 // SELECT pseudo instructions.4929 const BasicBlock *LLVM_BB = BB->getBasicBlock();4930 MachineFunction::iterator It = ++BB->getIterator();4931 4932 // thisMBB:4933 // ...4934 // TrueVal = ...4935 // setcc r1, r2, r34936 // bNE r1, r0, copy1MBB4937 // fallthrough --> copy0MBB4938 MachineBasicBlock *thisMBB = BB;4939 MachineFunction *F = BB->getParent();4940 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);4941 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);4942 F->insert(It, copy0MBB);4943 F->insert(It, sinkMBB);4944 4945 // Transfer the remainder of BB and its successor edges to sinkMBB.4946 sinkMBB->splice(sinkMBB->begin(), BB,4947 std::next(MachineBasicBlock::iterator(MI)), BB->end());4948 sinkMBB->transferSuccessorsAndUpdatePHIs(BB);4949 4950 // Next, add the true and fallthrough blocks as its successors.4951 BB->addSuccessor(copy0MBB);4952 BB->addSuccessor(sinkMBB);4953 4954 // bne rs, $0, sinkMBB4955 BuildMI(BB, DL, TII->get(Mips::BNE))4956 .addReg(MI.getOperand(2).getReg())4957 .addReg(Mips::ZERO)4958 .addMBB(sinkMBB);4959 4960 // copy0MBB:4961 // %FalseValue = ...4962 // # fallthrough to sinkMBB4963 BB = copy0MBB;4964 4965 // Update machine-CFG edges4966 BB->addSuccessor(sinkMBB);4967 4968 // sinkMBB:4969 // %Result = phi [ %TrueValue, thisMBB ], [ %FalseValue, copy0MBB ]4970 // ...4971 BB = sinkMBB;4972 4973 // Use two PHI nodes to select two reults4974 BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(0).getReg())4975 .addReg(MI.getOperand(3).getReg())4976 .addMBB(thisMBB)4977 .addReg(MI.getOperand(5).getReg())4978 .addMBB(copy0MBB);4979 BuildMI(*BB, BB->begin(), DL, TII->get(Mips::PHI), MI.getOperand(1).getReg())4980 .addReg(MI.getOperand(4).getReg())4981 .addMBB(thisMBB)4982 .addReg(MI.getOperand(6).getReg())4983 .addMBB(copy0MBB);4984 4985 MI.eraseFromParent(); // The pseudo instruction is gone now.4986 4987 return BB;4988}4989 4990// FIXME? Maybe this could be a TableGen attribute on some registers and4991// this table could be generated automatically from RegInfo.4992Register4993MipsTargetLowering::getRegisterByName(const char *RegName, LLT VT,4994 const MachineFunction &MF) const {4995 // The Linux kernel uses $28 and sp.4996 if (Subtarget.isGP64bit()) {4997 Register Reg = StringSwitch<Register>(RegName)4998 .Case("$28", Mips::GP_64)4999 .Case("sp", Mips::SP_64)5000 .Default(Register());5001 return Reg;5002 }5003 5004 Register Reg = StringSwitch<Register>(RegName)5005 .Case("$28", Mips::GP)5006 .Case("sp", Mips::SP)5007 .Default(Register());5008 return Reg;5009}5010 5011MachineBasicBlock *MipsTargetLowering::emitLDR_W(MachineInstr &MI,5012 MachineBasicBlock *BB) const {5013 MachineFunction *MF = BB->getParent();5014 MachineRegisterInfo &MRI = MF->getRegInfo();5015 const TargetInstrInfo *TII = Subtarget.getInstrInfo();5016 const bool IsLittle = Subtarget.isLittle();5017 DebugLoc DL = MI.getDebugLoc();5018 5019 Register Dest = MI.getOperand(0).getReg();5020 Register Address = MI.getOperand(1).getReg();5021 unsigned Imm = MI.getOperand(2).getImm();5022 5023 MachineBasicBlock::iterator I(MI);5024 5025 if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {5026 // Mips release 6 can load from adress that is not naturally-aligned.5027 Register Temp = MRI.createVirtualRegister(&Mips::GPR32RegClass);5028 BuildMI(*BB, I, DL, TII->get(Mips::LW))5029 .addDef(Temp)5030 .addUse(Address)5031 .addImm(Imm);5032 BuildMI(*BB, I, DL, TII->get(Mips::FILL_W)).addDef(Dest).addUse(Temp);5033 } else {5034 // Mips release 5 needs to use instructions that can load from an unaligned5035 // memory address.5036 Register LoadHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);5037 Register LoadFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);5038 Register Undef = MRI.createVirtualRegister(&Mips::GPR32RegClass);5039 BuildMI(*BB, I, DL, TII->get(Mips::IMPLICIT_DEF)).addDef(Undef);5040 BuildMI(*BB, I, DL, TII->get(Mips::LWR))5041 .addDef(LoadHalf)5042 .addUse(Address)5043 .addImm(Imm + (IsLittle ? 0 : 3))5044 .addUse(Undef);5045 BuildMI(*BB, I, DL, TII->get(Mips::LWL))5046 .addDef(LoadFull)5047 .addUse(Address)5048 .addImm(Imm + (IsLittle ? 3 : 0))5049 .addUse(LoadHalf);5050 BuildMI(*BB, I, DL, TII->get(Mips::FILL_W)).addDef(Dest).addUse(LoadFull);5051 }5052 5053 MI.eraseFromParent();5054 return BB;5055}5056 5057MachineBasicBlock *MipsTargetLowering::emitLDR_D(MachineInstr &MI,5058 MachineBasicBlock *BB) const {5059 MachineFunction *MF = BB->getParent();5060 MachineRegisterInfo &MRI = MF->getRegInfo();5061 const TargetInstrInfo *TII = Subtarget.getInstrInfo();5062 const bool IsLittle = Subtarget.isLittle();5063 DebugLoc DL = MI.getDebugLoc();5064 5065 Register Dest = MI.getOperand(0).getReg();5066 Register Address = MI.getOperand(1).getReg();5067 unsigned Imm = MI.getOperand(2).getImm();5068 5069 MachineBasicBlock::iterator I(MI);5070 5071 if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {5072 // Mips release 6 can load from adress that is not naturally-aligned.5073 if (Subtarget.isGP64bit()) {5074 Register Temp = MRI.createVirtualRegister(&Mips::GPR64RegClass);5075 BuildMI(*BB, I, DL, TII->get(Mips::LD))5076 .addDef(Temp)5077 .addUse(Address)5078 .addImm(Imm);5079 BuildMI(*BB, I, DL, TII->get(Mips::FILL_D)).addDef(Dest).addUse(Temp);5080 } else {5081 Register Wtemp = MRI.createVirtualRegister(&Mips::MSA128WRegClass);5082 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);5083 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);5084 BuildMI(*BB, I, DL, TII->get(Mips::LW))5085 .addDef(Lo)5086 .addUse(Address)5087 .addImm(Imm + (IsLittle ? 0 : 4));5088 BuildMI(*BB, I, DL, TII->get(Mips::LW))5089 .addDef(Hi)5090 .addUse(Address)5091 .addImm(Imm + (IsLittle ? 4 : 0));5092 BuildMI(*BB, I, DL, TII->get(Mips::FILL_W)).addDef(Wtemp).addUse(Lo);5093 BuildMI(*BB, I, DL, TII->get(Mips::INSERT_W), Dest)5094 .addUse(Wtemp)5095 .addUse(Hi)5096 .addImm(1);5097 }5098 } else {5099 // Mips release 5 needs to use instructions that can load from an unaligned5100 // memory address.5101 Register LoHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);5102 Register LoFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);5103 Register LoUndef = MRI.createVirtualRegister(&Mips::GPR32RegClass);5104 Register HiHalf = MRI.createVirtualRegister(&Mips::GPR32RegClass);5105 Register HiFull = MRI.createVirtualRegister(&Mips::GPR32RegClass);5106 Register HiUndef = MRI.createVirtualRegister(&Mips::GPR32RegClass);5107 Register Wtemp = MRI.createVirtualRegister(&Mips::MSA128WRegClass);5108 BuildMI(*BB, I, DL, TII->get(Mips::IMPLICIT_DEF)).addDef(LoUndef);5109 BuildMI(*BB, I, DL, TII->get(Mips::LWR))5110 .addDef(LoHalf)5111 .addUse(Address)5112 .addImm(Imm + (IsLittle ? 0 : 7))5113 .addUse(LoUndef);5114 BuildMI(*BB, I, DL, TII->get(Mips::LWL))5115 .addDef(LoFull)5116 .addUse(Address)5117 .addImm(Imm + (IsLittle ? 3 : 4))5118 .addUse(LoHalf);5119 BuildMI(*BB, I, DL, TII->get(Mips::IMPLICIT_DEF)).addDef(HiUndef);5120 BuildMI(*BB, I, DL, TII->get(Mips::LWR))5121 .addDef(HiHalf)5122 .addUse(Address)5123 .addImm(Imm + (IsLittle ? 4 : 3))5124 .addUse(HiUndef);5125 BuildMI(*BB, I, DL, TII->get(Mips::LWL))5126 .addDef(HiFull)5127 .addUse(Address)5128 .addImm(Imm + (IsLittle ? 7 : 0))5129 .addUse(HiHalf);5130 BuildMI(*BB, I, DL, TII->get(Mips::FILL_W)).addDef(Wtemp).addUse(LoFull);5131 BuildMI(*BB, I, DL, TII->get(Mips::INSERT_W), Dest)5132 .addUse(Wtemp)5133 .addUse(HiFull)5134 .addImm(1);5135 }5136 5137 MI.eraseFromParent();5138 return BB;5139}5140 5141MachineBasicBlock *MipsTargetLowering::emitSTR_W(MachineInstr &MI,5142 MachineBasicBlock *BB) const {5143 MachineFunction *MF = BB->getParent();5144 MachineRegisterInfo &MRI = MF->getRegInfo();5145 const TargetInstrInfo *TII = Subtarget.getInstrInfo();5146 const bool IsLittle = Subtarget.isLittle();5147 DebugLoc DL = MI.getDebugLoc();5148 5149 Register StoreVal = MI.getOperand(0).getReg();5150 Register Address = MI.getOperand(1).getReg();5151 unsigned Imm = MI.getOperand(2).getImm();5152 5153 MachineBasicBlock::iterator I(MI);5154 5155 if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {5156 // Mips release 6 can store to adress that is not naturally-aligned.5157 Register BitcastW = MRI.createVirtualRegister(&Mips::MSA128WRegClass);5158 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);5159 BuildMI(*BB, I, DL, TII->get(Mips::COPY)).addDef(BitcastW).addUse(StoreVal);5160 BuildMI(*BB, I, DL, TII->get(Mips::COPY_S_W))5161 .addDef(Tmp)5162 .addUse(BitcastW)5163 .addImm(0);5164 BuildMI(*BB, I, DL, TII->get(Mips::SW))5165 .addUse(Tmp)5166 .addUse(Address)5167 .addImm(Imm);5168 } else {5169 // Mips release 5 needs to use instructions that can store to an unaligned5170 // memory address.5171 Register Tmp = MRI.createVirtualRegister(&Mips::GPR32RegClass);5172 BuildMI(*BB, I, DL, TII->get(Mips::COPY_S_W))5173 .addDef(Tmp)5174 .addUse(StoreVal)5175 .addImm(0);5176 BuildMI(*BB, I, DL, TII->get(Mips::SWR))5177 .addUse(Tmp)5178 .addUse(Address)5179 .addImm(Imm + (IsLittle ? 0 : 3));5180 BuildMI(*BB, I, DL, TII->get(Mips::SWL))5181 .addUse(Tmp)5182 .addUse(Address)5183 .addImm(Imm + (IsLittle ? 3 : 0));5184 }5185 5186 MI.eraseFromParent();5187 5188 return BB;5189}5190 5191MachineBasicBlock *MipsTargetLowering::emitSTR_D(MachineInstr &MI,5192 MachineBasicBlock *BB) const {5193 MachineFunction *MF = BB->getParent();5194 MachineRegisterInfo &MRI = MF->getRegInfo();5195 const TargetInstrInfo *TII = Subtarget.getInstrInfo();5196 const bool IsLittle = Subtarget.isLittle();5197 DebugLoc DL = MI.getDebugLoc();5198 5199 Register StoreVal = MI.getOperand(0).getReg();5200 Register Address = MI.getOperand(1).getReg();5201 unsigned Imm = MI.getOperand(2).getImm();5202 5203 MachineBasicBlock::iterator I(MI);5204 5205 if (Subtarget.hasMips32r6() || Subtarget.hasMips64r6()) {5206 // Mips release 6 can store to adress that is not naturally-aligned.5207 if (Subtarget.isGP64bit()) {5208 Register BitcastD = MRI.createVirtualRegister(&Mips::MSA128DRegClass);5209 Register Lo = MRI.createVirtualRegister(&Mips::GPR64RegClass);5210 BuildMI(*BB, I, DL, TII->get(Mips::COPY))5211 .addDef(BitcastD)5212 .addUse(StoreVal);5213 BuildMI(*BB, I, DL, TII->get(Mips::COPY_S_D))5214 .addDef(Lo)5215 .addUse(BitcastD)5216 .addImm(0);5217 BuildMI(*BB, I, DL, TII->get(Mips::SD))5218 .addUse(Lo)5219 .addUse(Address)5220 .addImm(Imm);5221 } else {5222 Register BitcastW = MRI.createVirtualRegister(&Mips::MSA128WRegClass);5223 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);5224 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);5225 BuildMI(*BB, I, DL, TII->get(Mips::COPY))5226 .addDef(BitcastW)5227 .addUse(StoreVal);5228 BuildMI(*BB, I, DL, TII->get(Mips::COPY_S_W))5229 .addDef(Lo)5230 .addUse(BitcastW)5231 .addImm(0);5232 BuildMI(*BB, I, DL, TII->get(Mips::COPY_S_W))5233 .addDef(Hi)5234 .addUse(BitcastW)5235 .addImm(1);5236 BuildMI(*BB, I, DL, TII->get(Mips::SW))5237 .addUse(Lo)5238 .addUse(Address)5239 .addImm(Imm + (IsLittle ? 0 : 4));5240 BuildMI(*BB, I, DL, TII->get(Mips::SW))5241 .addUse(Hi)5242 .addUse(Address)5243 .addImm(Imm + (IsLittle ? 4 : 0));5244 }5245 } else {5246 // Mips release 5 needs to use instructions that can store to an unaligned5247 // memory address.5248 Register Bitcast = MRI.createVirtualRegister(&Mips::MSA128WRegClass);5249 Register Lo = MRI.createVirtualRegister(&Mips::GPR32RegClass);5250 Register Hi = MRI.createVirtualRegister(&Mips::GPR32RegClass);5251 BuildMI(*BB, I, DL, TII->get(Mips::COPY)).addDef(Bitcast).addUse(StoreVal);5252 BuildMI(*BB, I, DL, TII->get(Mips::COPY_S_W))5253 .addDef(Lo)5254 .addUse(Bitcast)5255 .addImm(0);5256 BuildMI(*BB, I, DL, TII->get(Mips::COPY_S_W))5257 .addDef(Hi)5258 .addUse(Bitcast)5259 .addImm(1);5260 BuildMI(*BB, I, DL, TII->get(Mips::SWR))5261 .addUse(Lo)5262 .addUse(Address)5263 .addImm(Imm + (IsLittle ? 0 : 3));5264 BuildMI(*BB, I, DL, TII->get(Mips::SWL))5265 .addUse(Lo)5266 .addUse(Address)5267 .addImm(Imm + (IsLittle ? 3 : 0));5268 BuildMI(*BB, I, DL, TII->get(Mips::SWR))5269 .addUse(Hi)5270 .addUse(Address)5271 .addImm(Imm + (IsLittle ? 4 : 7));5272 BuildMI(*BB, I, DL, TII->get(Mips::SWL))5273 .addUse(Hi)5274 .addUse(Address)5275 .addImm(Imm + (IsLittle ? 7 : 4));5276 }5277 5278 MI.eraseFromParent();5279 return BB;5280}5281