#define DEBUG_TYPE "mblaze-lower"
#include "MBlazeISelLowering.h"
#include "MBlazeMachineFunction.h"
+#include "MBlazeSubtarget.h"
#include "MBlazeTargetMachine.h"
#include "MBlazeTargetObjectFile.h"
-#include "MBlazeSubtarget.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Intrinsics.h"
-#include "llvm/CallingConv.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/IR/CallingConv.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
// MBlaze does not have i1 type, so use i32 for
// setcc operations results (slt, sgt, ...).
setBooleanContents(ZeroOrOneBooleanContent);
+ setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
// Set up the register classes
- addRegisterClass(MVT::i32, MBlaze::GPRRegisterClass);
+ addRegisterClass(MVT::i32, &MBlaze::GPRRegClass);
if (Subtarget->hasFPU()) {
- addRegisterClass(MVT::f32, MBlaze::GPRRegisterClass);
+ addRegisterClass(MVT::f32, &MBlaze::GPRRegClass);
setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
}
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
setOperationAction(ISD::FSIN, MVT::f32, Expand);
setOperationAction(ISD::FCOS, MVT::f32, Expand);
+ setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
setOperationAction(ISD::FPOWI, MVT::f32, Expand);
setOperationAction(ISD::FPOW, MVT::f32, Expand);
setOperationAction(ISD::FLOG, MVT::f32, Expand);
// Operations not directly supported by MBlaze.
setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
setOperationAction(ISD::BR_JT, MVT::Other, Expand);
- setOperationAction(ISD::BR_CC, MVT::Other, Expand);
+ setOperationAction(ISD::BR_CC, MVT::f32, Expand);
+ setOperationAction(ISD::BR_CC, MVT::i32, Expand);
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
setOperationAction(ISD::ROTL, MVT::i32, Expand);
setOperationAction(ISD::ROTR, MVT::i32, Expand);
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
setOperationAction(ISD::CTLZ, MVT::i32, Expand);
+ setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
+ setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
setOperationAction(ISD::BSWAP, MVT::i32, Expand);
computeRegisterProperties();
}
-MVT::SimpleValueType MBlazeTargetLowering::getSetCCResultType(EVT VT) const {
+EVT MBlazeTargetLowering::getSetCCResultType(LLVMContext &, EVT) const {
return MVT::i32;
}
MachineBasicBlock *MBB)
const {
switch (MI->getOpcode()) {
- default: assert(false && "Unexpected instr type to insert");
+ default: llvm_unreachable("Unexpected instr type to insert");
case MBlaze::ShiftRL:
case MBlaze::ShiftRA:
loop->addSuccessor(finish);
loop->addSuccessor(loop);
- unsigned IAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass);
+ unsigned IAMT = R.createVirtualRegister(&MBlaze::GPRRegClass);
BuildMI(MBB, dl, TII->get(MBlaze::ANDI), IAMT)
.addReg(MI->getOperand(2).getReg())
.addImm(31);
- unsigned IVAL = R.createVirtualRegister(MBlaze::GPRRegisterClass);
+ unsigned IVAL = R.createVirtualRegister(&MBlaze::GPRRegClass);
BuildMI(MBB, dl, TII->get(MBlaze::ADDIK), IVAL)
.addReg(MI->getOperand(1).getReg())
.addImm(0);
.addReg(IAMT)
.addMBB(finish);
- unsigned DST = R.createVirtualRegister(MBlaze::GPRRegisterClass);
- unsigned NDST = R.createVirtualRegister(MBlaze::GPRRegisterClass);
+ unsigned DST = R.createVirtualRegister(&MBlaze::GPRRegClass);
+ unsigned NDST = R.createVirtualRegister(&MBlaze::GPRRegClass);
BuildMI(loop, dl, TII->get(MBlaze::PHI), DST)
.addReg(IVAL).addMBB(MBB)
.addReg(NDST).addMBB(loop);
- unsigned SAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass);
- unsigned NAMT = R.createVirtualRegister(MBlaze::GPRRegisterClass);
+ unsigned SAMT = R.createVirtualRegister(&MBlaze::GPRRegClass);
+ unsigned NAMT = R.createVirtualRegister(&MBlaze::GPRRegClass);
BuildMI(loop, dl, TII->get(MBlaze::PHI), SAMT)
.addReg(IAMT).addMBB(MBB)
.addReg(NAMT).addMBB(loop);
case MBlaze::LAN32: opcode = MBlaze::AND; break;
}
- finalReg = R.createVirtualRegister(MBlaze::GPRRegisterClass);
+ finalReg = R.createVirtualRegister(&MBlaze::GPRRegClass);
start->addSuccessor(exit);
start->addSuccessor(start);
if (MI->getOpcode() == MBlaze::LAN32) {
unsigned tmp = finalReg;
- finalReg = R.createVirtualRegister(MBlaze::GPRRegisterClass);
+ finalReg = R.createVirtualRegister(&MBlaze::GPRRegClass);
BuildMI(start, dl, TII->get(MBlaze::XORI), finalReg)
.addReg(tmp)
.addImm(-1);
final->addSuccessor(exit);
final->addSuccessor(start);
- unsigned CMP = R.createVirtualRegister(MBlaze::GPRRegisterClass);
+ unsigned CMP = R.createVirtualRegister(&MBlaze::GPRRegClass);
BuildMI(start, dl, TII->get(MBlaze::CMP), CMP)
.addReg(MI->getOperand(0).getReg())
.addReg(MI->getOperand(2).getReg());
}
}
- unsigned CHK = R.createVirtualRegister(MBlaze::GPRRegisterClass);
+ unsigned CHK = R.createVirtualRegister(&MBlaze::GPRRegClass);
BuildMI(final, dl, TII->get(MBlaze::SWX))
.addReg(finalReg)
.addReg(MI->getOperand(1).getReg())
SDValue RHS = Op.getOperand(1);
SDValue TrueVal = Op.getOperand(2);
SDValue FalseVal = Op.getOperand(3);
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
unsigned Opc;
SDValue CompareFlag;
SDValue MBlazeTargetLowering::
LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
// FIXME there isn't actually debug info here
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32);
SDValue MBlazeTargetLowering::
LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
llvm_unreachable("TLS not implemented for MicroBlaze.");
- return SDValue(); // Not reached
}
SDValue MBlazeTargetLowering::
SDValue ResNode;
SDValue HiPart;
// FIXME there isn't actually debug info here
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
EVT PtrVT = Op.getValueType();
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
SDValue ResNode;
ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
const Constant *C = N->getConstVal();
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
N->getOffset(), 0);
MachineFunction &MF = DAG.getMachineFunction();
MBlazeFunctionInfo *FuncInfo = MF.getInfo<MBlazeFunctionInfo>();
- DebugLoc dl = Op.getDebugLoc();
+ SDLoc dl(Op);
SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
getPointerTy());
CCValAssign::LocInfo &LocInfo,
ISD::ArgFlagsTy &ArgFlags,
CCState &State) {
- static const unsigned ArgRegs[] = {
+ static const uint16_t ArgRegs[] = {
MBlaze::R5, MBlaze::R6, MBlaze::R7,
MBlaze::R8, MBlaze::R9, MBlaze::R10
};
/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
/// TODO: isVarArg, isTailCall.
SDValue MBlazeTargetLowering::
-LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
- bool isVarArg, bool &isTailCall,
- const SmallVectorImpl<ISD::OutputArg> &Outs,
- const SmallVectorImpl<SDValue> &OutVals,
- const SmallVectorImpl<ISD::InputArg> &Ins,
- DebugLoc dl, SelectionDAG &DAG,
+LowerCall(TargetLowering::CallLoweringInfo &CLI,
SmallVectorImpl<SDValue> &InVals) const {
+ SelectionDAG &DAG = CLI.DAG;
+ SDLoc dl = CLI.DL;
+ SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
+ SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
+ SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
+ SDValue Chain = CLI.Chain;
+ SDValue Callee = CLI.Callee;
+ bool &isTailCall = CLI.IsTailCall;
+ CallingConv::ID CallConv = CLI.CallConv;
+ bool isVarArg = CLI.IsVarArg;
+
// MBlaze does not yet support tail call optimization
isTailCall = false;
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
- getTargetMachine(), ArgLocs, *DAG.getContext());
+ getTargetMachine(), ArgLocs, *DAG.getContext());
CCInfo.AnalyzeCallOperands(Outs, CC_MBlaze);
// Get a count of how many bytes are to be pushed on the stack.
// Variable argument function calls require a minimum of 24-bytes of stack
if (isVarArg && NumBytes < 24) NumBytes = 24;
- Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
+ Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true),
+ dl);
SmallVector<std::pair<unsigned, SDValue>, 8> RegsToPass;
SmallVector<SDValue, 8> MemOpChains;
// Create the CALLSEQ_END node.
Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
- DAG.getIntPtrConstant(0, true), InFlag);
+ DAG.getIntPtrConstant(0, true), InFlag, dl);
if (!Ins.empty())
InFlag = Chain.getValue(1);
SDValue MBlazeTargetLowering::
LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv,
bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins,
- DebugLoc dl, SelectionDAG &DAG,
+ SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const {
// Assign locations to each value returned by this call.
SmallVector<CCValAssign, 16> RVLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
- getTargetMachine(), RVLocs, *DAG.getContext());
+ getTargetMachine(), RVLocs, *DAG.getContext());
CCInfo.AnalyzeCallResult(Ins, RetCC_MBlaze);
SDValue MBlazeTargetLowering::
LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::InputArg> &Ins,
- DebugLoc dl, SelectionDAG &DAG,
+ SDLoc dl, SelectionDAG &DAG,
SmallVectorImpl<SDValue> &InVals) const {
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
- getTargetMachine(), ArgLocs, *DAG.getContext());
+ getTargetMachine(), ArgLocs, *DAG.getContext());
CCInfo.AnalyzeFormalArguments(Ins, CC_MBlaze);
SDValue StackPtr;
if (VA.isRegLoc()) {
MVT RegVT = VA.getLocVT();
ArgRegEnd = VA.getLocReg();
- TargetRegisterClass *RC = 0;
+ const TargetRegisterClass *RC;
if (RegVT == MVT::i32)
- RC = MBlaze::GPRRegisterClass;
+ RC = &MBlaze::GPRRegClass;
else if (RegVT == MVT::f32)
- RC = MBlaze::GPRRegisterClass;
+ RC = &MBlaze::GPRRegClass;
else
llvm_unreachable("RegVT not supported by LowerFormalArguments");
SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN,
MachinePointerInfo::getFixedStack(FI),
- false, false, 0));
+ false, false, false, 0));
}
}
StackPtr = DAG.getRegister(StackReg, getPointerTy());
// The last register argument that must be saved is MBlaze::R10
- TargetRegisterClass *RC = MBlaze::GPRRegisterClass;
+ const TargetRegisterClass *RC = &MBlaze::GPRRegClass;
- unsigned Begin = MBlazeRegisterInfo::getRegisterNumbering(MBlaze::R5);
- unsigned Start = MBlazeRegisterInfo::getRegisterNumbering(ArgRegEnd+1);
- unsigned End = MBlazeRegisterInfo::getRegisterNumbering(MBlaze::R10);
+ unsigned Begin = getMBlazeRegisterNumbering(MBlaze::R5);
+ unsigned Start = getMBlazeRegisterNumbering(ArgRegEnd+1);
+ unsigned End = getMBlazeRegisterNumbering(MBlaze::R10);
unsigned StackLoc = Start - Begin + 1;
for (; Start <= End; ++Start, ++StackLoc) {
- unsigned Reg = MBlazeRegisterInfo::getRegisterFromNumbering(Start);
+ unsigned Reg = getMBlazeRegisterFromNumbering(Start);
unsigned LiveReg = MF.addLiveIn(Reg, RC);
SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, LiveReg, MVT::i32);
LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
const SmallVectorImpl<ISD::OutputArg> &Outs,
const SmallVectorImpl<SDValue> &OutVals,
- DebugLoc dl, SelectionDAG &DAG) const {
+ SDLoc dl, SelectionDAG &DAG) const {
// CCValAssign - represent the assignment of
// the return value to a location
SmallVector<CCValAssign, 16> RVLocs;
// CCState - Info about the registers and stack slot.
CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
- getTargetMachine(), RVLocs, *DAG.getContext());
+ getTargetMachine(), RVLocs, *DAG.getContext());
// Analize return values.
CCInfo.AnalyzeReturn(Outs, RetCC_MBlaze);
- // If this is the first return lowered for this function, add
- // the regs to the liveout set for the function.
- if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
- for (unsigned i = 0; i != RVLocs.size(); ++i)
- if (RVLocs[i].isRegLoc())
- DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
- }
-
SDValue Flag;
+ SmallVector<SDValue, 4> RetOps(1, Chain);
+
+ // If this function is using the interrupt_handler calling convention
+ // then use "rtid r14, 0" otherwise use "rtsd r15, 8"
+ unsigned Ret = (CallConv == CallingConv::MBLAZE_INTR) ? MBlazeISD::IRet
+ : MBlazeISD::Ret;
+ unsigned Reg = (CallConv == CallingConv::MBLAZE_INTR) ? MBlaze::R14
+ : MBlaze::R15;
+ RetOps.push_back(DAG.getRegister(Reg, MVT::i32));
+
// Copy the result values into the output registers.
for (unsigned i = 0; i != RVLocs.size(); ++i) {
// guarantee that all emitted copies are
// stuck together, avoiding something bad
Flag = Chain.getValue(1);
+ RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
}
- // If this function is using the interrupt_handler calling convention
- // then use "rtid r14, 0" otherwise use "rtsd r15, 8"
- unsigned Ret = (CallConv == llvm::CallingConv::MBLAZE_INTR) ? MBlazeISD::IRet
- : MBlazeISD::Ret;
- unsigned Reg = (CallConv == llvm::CallingConv::MBLAZE_INTR) ? MBlaze::R14
- : MBlaze::R15;
- SDValue DReg = DAG.getRegister(Reg, MVT::i32);
+ RetOps[0] = Chain; // Update chain.
+ // Add the flag if we have it.
if (Flag.getNode())
- return DAG.getNode(Ret, dl, MVT::Other, Chain, DReg, Flag);
+ RetOps.push_back(Flag);
- return DAG.getNode(Ret, dl, MVT::Other, Chain, DReg);
+ return DAG.getNode(Ret, dl, MVT::Other, &RetOps[0], RetOps.size());
}
//===----------------------------------------------------------------------===//
case 'y':
case 'f':
return C_RegisterClass;
- break;
}
}
return TargetLowering::getConstraintType(Constraint);
// but allow it at the lowest weight.
if (CallOperandVal == NULL)
return CW_Default;
- const Type *type = CallOperandVal->getType();
+ Type *type = CallOperandVal->getType();
// Look at the constraint type.
switch (*constraint) {
default:
/// to an LLVM register class, return a register of 0 and the register class
/// pointer.
std::pair<unsigned, const TargetRegisterClass*> MBlazeTargetLowering::
-getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const {
+getRegForInlineAsmConstraint(const std::string &Constraint, MVT VT) const {
if (Constraint.size() == 1) {
switch (Constraint[0]) {
case 'r':
- return std::make_pair(0U, MBlaze::GPRRegisterClass);
+ return std::make_pair(0U, &MBlaze::GPRRegClass);
// TODO: These can't possibly be right, but match what was in
// getRegClassForInlineAsmConstraint.
case 'd':
case 'y':
case 'f':
if (VT == MVT::f32)
- return std::make_pair(0U, MBlaze::GPRRegisterClass);
+ return std::make_pair(0U, &MBlaze::GPRRegClass);
}
}
return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);