110 lines
4.0 KiB
C++
110 lines
4.0 KiB
C++
//===-- TMS34010ISelLowering.cpp - TMS34010 DAG lowering ------------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "TMS34010ISelLowering.h"
|
|
#include "TMS34010.h"
|
|
#include "TMS34010Subtarget.h"
|
|
#include "TMS34010TargetMachine.h"
|
|
#include "llvm/CodeGen/CallingConvLower.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
using namespace llvm;
|
|
|
|
TMS34010TargetLowering::TMS34010TargetLowering(const TargetMachine &TM,
|
|
const TMS34010Subtarget &STI)
|
|
: TargetLowering(TM, STI) {
|
|
addRegisterClass(MVT::i32, &TMS34010::ARegsRegClass);
|
|
|
|
// MOVB is an 8-bit sign-extending load and an 8-bit truncating store.
|
|
// M1 only needs signed char, so a zero-extending byte load has no pattern.
|
|
setLoadExtAction(ISD::SEXTLOAD, MVT::i32, MVT::i8, Legal);
|
|
setTruncStoreAction(MVT::i32, MVT::i8, Legal);
|
|
|
|
computeRegisterProperties(STI.getRegisterInfo());
|
|
|
|
setBooleanContents(ZeroOrOneBooleanContent);
|
|
setBooleanVectorContents(ZeroOrOneBooleanContent);
|
|
setMinFunctionAlignment(Align(2));
|
|
setPrefFunctionAlignment(Align(2));
|
|
setMaxAtomicSizeInBitsSupported(0);
|
|
}
|
|
|
|
SDValue TMS34010TargetLowering::LowerFormalArguments(
|
|
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
|
|
const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
|
|
SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
|
|
MachineFunction &MF = DAG.getMachineFunction();
|
|
MachineRegisterInfo &RegInfo = MF.getRegInfo();
|
|
|
|
static const MCPhysReg ArgRegs[] = {TMS34010::A0, TMS34010::A1, TMS34010::A2,
|
|
TMS34010::A3};
|
|
|
|
if (Ins.size() > std::size(ArgRegs))
|
|
report_fatal_error("M1 supports at most four register arguments", false);
|
|
|
|
SmallVector<CCValAssign, 4> ArgLocs;
|
|
CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext());
|
|
|
|
for (unsigned i = 0, e = Ins.size(); i != e; ++i) {
|
|
MVT VT = Ins[i].VT;
|
|
if (VT != MVT::i32)
|
|
report_fatal_error(
|
|
"M1 supports only 32-bit scalar and pointer arguments", false);
|
|
CCInfo.addLoc(
|
|
CCValAssign::getReg(i, VT, ArgRegs[i], VT, CCValAssign::Full));
|
|
}
|
|
|
|
for (const CCValAssign &VA : ArgLocs) {
|
|
Register VReg = RegInfo.createVirtualRegister(&TMS34010::ARegsRegClass);
|
|
RegInfo.addLiveIn(VA.getLocReg(), VReg);
|
|
InVals.push_back(
|
|
DAG.getCopyFromReg(Chain, DL, VReg, VA.getLocVT()));
|
|
}
|
|
|
|
return Chain;
|
|
}
|
|
|
|
SDValue TMS34010TargetLowering::LowerCall(
|
|
TargetLowering::CallLoweringInfo &CLI,
|
|
SmallVectorImpl<SDValue> &InVals) const {
|
|
report_fatal_error("M1 has no calls; M2 adds the TI ABI", false);
|
|
}
|
|
|
|
bool TMS34010TargetLowering::CanLowerReturn(
|
|
CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
|
|
const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
|
|
const Type *RetTy) const {
|
|
if (Outs.empty())
|
|
return true;
|
|
return Outs.size() == 1 && Outs[0].VT == MVT::i32;
|
|
}
|
|
|
|
SDValue TMS34010TargetLowering::LowerReturn(
|
|
SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
|
|
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
|
const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
|
|
SelectionDAG &DAG) const {
|
|
if (Outs.empty())
|
|
return DAG.getNode(TMS34010ISD::RET_GLUE, DL, MVT::Other, Chain);
|
|
|
|
if (Outs.size() != 1 || Outs[0].VT != MVT::i32)
|
|
report_fatal_error(
|
|
"M1 supports only a 32-bit scalar or pointer return value", false);
|
|
|
|
SDValue Glue;
|
|
Chain = DAG.getCopyToReg(Chain, DL, TMS34010::A0, OutVals[0], Glue);
|
|
Glue = Chain.getValue(1);
|
|
|
|
SmallVector<SDValue, 3> RetOps(1, Chain);
|
|
RetOps.push_back(DAG.getRegister(TMS34010::A0, MVT::i32));
|
|
RetOps.push_back(Glue);
|
|
return DAG.getNode(TMS34010ISD::RET_GLUE, DL, MVT::Other, RetOps);
|
|
}
|