Path: blob/main/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp
35271 views
//===- XtensaISelDAGToDAG.cpp - A dag to dag inst selector for Xtensa -----===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file defines an instruction selector for the Xtensa target.9//10//===----------------------------------------------------------------------===//1112#include "Xtensa.h"13#include "XtensaTargetMachine.h"14#include "XtensaUtils.h"15#include "llvm/CodeGen/MachineFunction.h"16#include "llvm/CodeGen/MachineRegisterInfo.h"17#include "llvm/CodeGen/SelectionDAGISel.h"18#include "llvm/IR/DiagnosticInfo.h"19#include "llvm/Support/Debug.h"20#include "llvm/Support/raw_ostream.h"2122using namespace llvm;2324#define DEBUG_TYPE "xtensa-isel"2526namespace {2728class XtensaDAGToDAGISel : public SelectionDAGISel {29public:30XtensaDAGToDAGISel(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)31: SelectionDAGISel(TM, OptLevel) {}3233void Select(SDNode *Node) override;3435// For load/store instructions generate (base+offset) pair from36// memory address. The offset must be a multiple of scale argument.37bool selectMemRegAddr(SDValue Addr, SDValue &Base, SDValue &Offset,38int Scale) {39EVT ValTy = Addr.getValueType();4041// if Address is FI, get the TargetFrameIndex.42if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {43Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);44Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), ValTy);4546return true;47}4849if (TM.isPositionIndependent()) {50DiagnosticInfoUnsupported Diag(CurDAG->getMachineFunction().getFunction(),51"PIC relocations are not supported ",52Addr.getDebugLoc());53CurDAG->getContext()->diagnose(Diag);54}5556if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||57Addr.getOpcode() == ISD::TargetGlobalAddress))58return false;5960// Addresses of the form FI+const61bool Valid = false;62if (CurDAG->isBaseWithConstantOffset(Addr)) {63ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));64int64_t OffsetVal = CN->getSExtValue();6566Valid = isValidAddrOffset(Scale, OffsetVal);6768if (Valid) {69// If the first operand is a FI, get the TargetFI Node70if (FrameIndexSDNode *FIN =71dyn_cast<FrameIndexSDNode>(Addr.getOperand(0)))72Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);73else74Base = Addr.getOperand(0);7576Offset =77CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), ValTy);78return true;79}80}8182// Last case83Base = Addr;84Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), Addr.getValueType());85return true;86}8788bool selectMemRegAddrISH1(SDValue Addr, SDValue &Base, SDValue &Offset) {89return selectMemRegAddr(Addr, Base, Offset, 1);90}9192bool selectMemRegAddrISH2(SDValue Addr, SDValue &Base, SDValue &Offset) {93return selectMemRegAddr(Addr, Base, Offset, 2);94}9596bool selectMemRegAddrISH4(SDValue Addr, SDValue &Base, SDValue &Offset) {97return selectMemRegAddr(Addr, Base, Offset, 4);98}99100// Include the pieces autogenerated from the target description.101#include "XtensaGenDAGISel.inc"102}; // namespace103104class XtensaDAGToDAGISelLegacy : public SelectionDAGISelLegacy {105public:106static char ID;107108XtensaDAGToDAGISelLegacy(XtensaTargetMachine &TM, CodeGenOptLevel OptLevel)109: SelectionDAGISelLegacy(110ID, std::make_unique<XtensaDAGToDAGISel>(TM, OptLevel)) {}111112StringRef getPassName() const override {113return "Xtensa DAG->DAG Pattern Instruction Selection";114}115};116} // end anonymous namespace117118char XtensaDAGToDAGISelLegacy::ID = 0;119120FunctionPass *llvm::createXtensaISelDag(XtensaTargetMachine &TM,121CodeGenOptLevel OptLevel) {122return new XtensaDAGToDAGISelLegacy(TM, OptLevel);123}124125void XtensaDAGToDAGISel::Select(SDNode *Node) {126SDLoc DL(Node);127128// If we have a custom node, we already have selected!129if (Node->isMachineOpcode()) {130Node->setNodeId(-1);131return;132}133134SelectCode(Node);135}136137138