#include "llvm/Target/TargetLowering.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
-#include <queue>
-#include <set>
using namespace llvm;
/// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine
const MSP430Subtarget &Subtarget;
public:
- MSP430DAGToDAGISel(MSP430TargetMachine &TM)
- : SelectionDAGISel(TM),
+ MSP430DAGToDAGISel(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel)
+ : SelectionDAGISel(TM, OptLevel),
Lowering(*TM.getTargetLowering()),
Subtarget(*TM.getSubtargetImpl()) { }
private:
SDNode *Select(SDValue Op);
- bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Disp, SDValue &Base);
+ bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp);
#ifndef NDEBUG
unsigned Indent;
/// createMSP430ISelDag - This pass converts a legalized DAG into a
/// MSP430-specific DAG, ready for instruction scheduling.
///
-FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM) {
- return new MSP430DAGToDAGISel(TM);
+FunctionPass *llvm::createMSP430ISelDag(MSP430TargetMachine &TM,
+ CodeGenOpt::Level OptLevel) {
+ return new MSP430DAGToDAGISel(TM, OptLevel);
}
+// FIXME: This is pretty dummy routine and needs to be rewritten in the future.
bool MSP430DAGToDAGISel::SelectAddr(SDValue Op, SDValue Addr,
- SDValue &Disp, SDValue &Base) {
- // We don't support frame index stuff yet.
- if (isa<FrameIndexSDNode>(Addr))
- return false;
-
- // Operand is a result from ADD with constant operand which fits into i16.
- if (Addr.getOpcode() == ISD::ADD) {
- if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
+ SDValue &Base, SDValue &Disp) {
+ // Try to match frame address first.
+ if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i16);
+ Disp = CurDAG->getTargetConstant(0, MVT::i16);
+ return true;
+ }
+
+ switch (Addr.getOpcode()) {
+ case ISD::ADD:
+ // Operand is a result from ADD with constant operand which fits into i16.
+ if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
uint64_t CVal = CN->getZExtValue();
// Offset should fit into 16 bits.
if (((CVal << 48) >> 48) == CVal) {
- // We don't support frame index stuff yet.
- if (isa<FrameIndexSDNode>(Addr.getOperand(0)))
- return false;
+ SDValue N0 = Addr.getOperand(0);
+ if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N0))
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i16);
+ else
+ Base = N0;
- Base = Addr.getOperand(0);
Disp = CurDAG->getTargetConstant(CVal, MVT::i16);
-
return true;
}
}
- }
+ break;
+ case MSP430ISD::Wrapper:
+ SDValue N0 = Addr.getOperand(0);
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N0)) {
+ Base = CurDAG->getTargetGlobalAddress(G->getGlobal(),
+ MVT::i16, G->getOffset());
+ Disp = CurDAG->getTargetConstant(0, MVT::i16);
+ return true;
+ } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(N0)) {
+ Base = CurDAG->getTargetExternalSymbol(E->getSymbol(), MVT::i16);
+ Disp = CurDAG->getTargetConstant(0, MVT::i16);
+ }
+ break;
+ };
Base = Addr;
Disp = CurDAG->getTargetConstant(0, MVT::i16);
void MSP430DAGToDAGISel::InstructionSelect() {
DEBUG(BB->dump());
- // Select target instructions for the DAG.
+ // Codegen the basic block.
+#ifndef NDEBUG
+ DOUT << "===== Instruction selection begins:\n";
+ Indent = 0;
+#endif
SelectRoot(*CurDAG);
+#ifndef NDEBUG
+ DOUT << "===== Instruction selection ends:\n";
+#endif
CurDAG->RemoveDeadNodes();
}
SDNode *MSP430DAGToDAGISel::Select(SDValue Op) {
SDNode *Node = Op.getNode();
+ DebugLoc dl = Op.getDebugLoc();
// Dump information about the Node being selected
#ifndef NDEBUG
return NULL;
}
- // Instruction Selection not handled by the auto-generated tablegen selection
- // should be handled here.
- // Something like this:
- // unsigned Opcode = Node->getOpcode();
- // switch (Opcode) {
- // default: break;
- // case ISD::Foo:
- // return SelectFoo(Node)
- // }
+ // Few custom selection stuff.
+ switch (Node->getOpcode()) {
+ default: break;
+ case ISD::FrameIndex: {
+ assert(Op.getValueType() == MVT::i16);
+ int FI = cast<FrameIndexSDNode>(Node)->getIndex();
+ SDValue TFI = CurDAG->getTargetFrameIndex(FI, MVT::i16);
+ if (Node->hasOneUse())
+ return CurDAG->SelectNodeTo(Node, MSP430::ADD16ri, MVT::i16,
+ TFI, CurDAG->getTargetConstant(0, MVT::i16));
+ return CurDAG->getTargetNode(MSP430::ADD16ri, dl, MVT::i16,
+ TFI, CurDAG->getTargetConstant(0, MVT::i16));
+ }
+ }
// Select the default instruction
SDNode *ResNode = SelectCode(Op);