//===-- VEISelLowering.cpp - VE DAG Lowering Implementation ---------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements the interfaces that VE uses to lower LLVM code into a // selection DAG. // //===----------------------------------------------------------------------===// #include "VEISelLowering.h" #include "VERegisterInfo.h" #include "VETargetMachine.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SelectionDAG.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/Module.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/KnownBits.h" using namespace llvm; #define DEBUG_TYPE "ve-lower" //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// #include "VEGenCallingConv.inc" bool VETargetLowering::CanLowerReturn( CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl &Outs, LLVMContext &Context) const { assert(!IsVarArg && "TODO implement var args"); assert(Outs.empty() && "TODO implement return values"); return true; // TODO support more than 'ret void' } SDValue VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Outs, const SmallVectorImpl &OutVals, const SDLoc &DL, SelectionDAG &DAG) const { assert(!IsVarArg && "TODO implement var args"); assert(Outs.empty() && "TODO implement return values"); assert(OutVals.empty() && "TODO implement return values"); SmallVector RetOps(1, Chain); RetOps[0] = Chain; // Update chain. return DAG.getNode(VEISD::RET_FLAG, DL, MVT::Other, RetOps); } SDValue VETargetLowering::LowerFormalArguments( SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, const SmallVectorImpl &Ins, const SDLoc &DL, SelectionDAG &DAG, SmallVectorImpl &InVals) const { assert(!IsVarArg && "TODO implement var args"); assert(Ins.empty() && "TODO implement input arguments"); return Chain; } // FIXME? Maybe this could be a TableGen attribute on some registers and // this table could be generated automatically from RegInfo. Register VETargetLowering::getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const { Register Reg = StringSwitch(RegName) .Case("sp", VE::SX11) // Stack pointer .Case("fp", VE::SX9) // Frame pointer .Case("sl", VE::SX8) // Stack limit .Case("lr", VE::SX10) // Link regsiter .Case("tp", VE::SX14) // Thread pointer .Case("outer", VE::SX12) // Outer regiser .Case("info", VE::SX17) // Info area register .Case("got", VE::SX15) // Global offset table register .Case("plt", VE::SX16) // Procedure linkage table register .Default(0); if (Reg) return Reg; report_fatal_error("Invalid register name global variable"); } //===----------------------------------------------------------------------===// // TargetLowering Implementation //===----------------------------------------------------------------------===// VETargetLowering::VETargetLowering(const TargetMachine &TM, const VESubtarget &STI) : TargetLowering(TM), Subtarget(&STI) { // Instructions which use registers as conditionals examine all the // bits (as does the pseudo SELECT_CC expansion). I don't think it // matters much whether it's ZeroOrOneBooleanContent, or // ZeroOrNegativeOneBooleanContent, so, arbitrarily choose the // former. setBooleanContents(ZeroOrOneBooleanContent); setBooleanVectorContents(ZeroOrOneBooleanContent); // Set up the register classes. addRegisterClass(MVT::i64, &VE::I64RegClass); setStackPointerRegisterToSaveRestore(VE::SX11); // Set function alignment to 16 bytes setMinFunctionAlignment(Align(16)); // VE stores all argument by 8 bytes alignment setMinStackArgumentAlignment(Align(8)); computeRegisterProperties(Subtarget->getRegisterInfo()); } const char *VETargetLowering::getTargetNodeName(unsigned Opcode) const { switch ((VEISD::NodeType)Opcode) { case VEISD::FIRST_NUMBER: break; case VEISD::RET_FLAG: return "VEISD::RET_FLAG"; } return nullptr; } EVT VETargetLowering::getSetCCResultType(const DataLayout &, LLVMContext &, EVT VT) const { return MVT::i64; }