diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
commit | cd749a9c07f1de2fb8affde90537efa4bc3e7c54 (patch) | |
tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /lib/Target/MSP430 | |
parent | 72621d11de5b873f1695f391eb95f0b336c3d2d4 (diff) | |
download | FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.zip FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.tar.gz |
Update llvm to r84119.
Diffstat (limited to 'lib/Target/MSP430')
22 files changed, 846 insertions, 286 deletions
diff --git a/lib/Target/MSP430/AsmPrinter/CMakeLists.txt b/lib/Target/MSP430/AsmPrinter/CMakeLists.txt new file mode 100644 index 0000000..6e66887 --- /dev/null +++ b/lib/Target/MSP430/AsmPrinter/CMakeLists.txt @@ -0,0 +1,6 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMMSP430AsmPrinter + MSP430AsmPrinter.cpp + ) +add_dependencies(LLVMMSP430AsmPrinter MSP430CodeGenTable_gen) diff --git a/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp new file mode 100644 index 0000000..852019f --- /dev/null +++ b/lib/Target/MSP430/AsmPrinter/MSP430AsmPrinter.cpp @@ -0,0 +1,281 @@ +//===-- MSP430AsmPrinter.cpp - MSP430 LLVM assembly writer ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to the MSP430 assembly language. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "MSP430.h" +#include "MSP430InstrInfo.h" +#include "MSP430MCAsmInfo.h" +#include "MSP430TargetMachine.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/DwarfWriter.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Mangler.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +STATISTIC(EmittedInsts, "Number of machine instrs printed"); + +namespace { + class VISIBILITY_HIDDEN MSP430AsmPrinter : public AsmPrinter { + public: + MSP430AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM, + const MCAsmInfo *MAI, bool V) + : AsmPrinter(O, TM, MAI, V) {} + + virtual const char *getPassName() const { + return "MSP430 Assembly Printer"; + } + + void printOperand(const MachineInstr *MI, int OpNum, + const char* Modifier = 0); + void printSrcMemOperand(const MachineInstr *MI, int OpNum, + const char* Modifier = 0); + void printCCOperand(const MachineInstr *MI, int OpNum); + void printInstruction(const MachineInstr *MI); // autogenerated. + static const char *getRegisterName(unsigned RegNo); + + void printMachineInstruction(const MachineInstr * MI); + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode); + bool PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNo, unsigned AsmVariant, + const char *ExtraCode); + + void emitFunctionHeader(const MachineFunction &MF); + bool runOnMachineFunction(MachineFunction &F); + + virtual void PrintGlobalVariable(const GlobalVariable *GV) { + // FIXME: No support for global variables? + } + + void getAnalysisUsage(AnalysisUsage &AU) const { + AsmPrinter::getAnalysisUsage(AU); + AU.setPreservesAll(); + } + }; +} // end of anonymous namespace + +#include "MSP430GenAsmWriter.inc" + + +void MSP430AsmPrinter::emitFunctionHeader(const MachineFunction &MF) { + const Function *F = MF.getFunction(); + + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM)); + + unsigned FnAlign = MF.getAlignment(); + EmitAlignment(FnAlign, F); + + switch (F->getLinkage()) { + default: llvm_unreachable("Unknown linkage type!"); + case Function::InternalLinkage: // Symbols default to internal. + case Function::PrivateLinkage: + case Function::LinkerPrivateLinkage: + break; + case Function::ExternalLinkage: + O << "\t.globl\t" << CurrentFnName << '\n'; + break; + case Function::LinkOnceAnyLinkage: + case Function::LinkOnceODRLinkage: + case Function::WeakAnyLinkage: + case Function::WeakODRLinkage: + O << "\t.weak\t" << CurrentFnName << '\n'; + break; + } + + printVisibility(CurrentFnName, F->getVisibility()); + + O << "\t.type\t" << CurrentFnName << ",@function\n" + << CurrentFnName << ":\n"; +} + +bool MSP430AsmPrinter::runOnMachineFunction(MachineFunction &MF) { + SetupMachineFunction(MF); + O << "\n\n"; + + // Print the 'header' of function + emitFunctionHeader(MF); + + // Print out code for the function. + for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); + I != E; ++I) { + // Print a label for the basic block. + EmitBasicBlockStart(I); + + for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); + II != E; ++II) + // Print the assembly for the instruction. + printMachineInstruction(II); + } + + if (MAI->hasDotTypeDotSizeDirective()) + O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n'; + + // We didn't modify anything + return false; +} + +void MSP430AsmPrinter::printMachineInstruction(const MachineInstr *MI) { + ++EmittedInsts; + + processDebugLoc(MI, true); + + // Call the autogenerated instruction printer routines. + printInstruction(MI); + + if (VerboseAsm && !MI->getDebugLoc().isUnknown()) + EmitComments(*MI); + O << '\n'; + + processDebugLoc(MI, false); +} + +void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum, + const char* Modifier) { + const MachineOperand &MO = MI->getOperand(OpNum); + switch (MO.getType()) { + case MachineOperand::MO_Register: + O << getRegisterName(MO.getReg()); + return; + case MachineOperand::MO_Immediate: + if (!Modifier || strcmp(Modifier, "nohash")) + O << '#'; + O << MO.getImm(); + return; + case MachineOperand::MO_MachineBasicBlock: + GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI); + return; + case MachineOperand::MO_GlobalAddress: { + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + std::string Name = Mang->getMangledName(MO.getGlobal()); + uint64_t Offset = MO.getOffset(); + + O << (isMemOp ? '&' : '#'); + if (Offset) + O << '(' << Offset << '+'; + + O << Name; + if (Offset) + O << ')'; + + return; + } + case MachineOperand::MO_ExternalSymbol: { + bool isMemOp = Modifier && !strcmp(Modifier, "mem"); + std::string Name(MAI->getGlobalPrefix()); + Name += MO.getSymbolName(); + + O << (isMemOp ? '&' : '#') << Name; + + return; + } + default: + llvm_unreachable("Not implemented yet!"); + } +} + +void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum, + const char* Modifier) { + const MachineOperand &Base = MI->getOperand(OpNum); + const MachineOperand &Disp = MI->getOperand(OpNum+1); + + if (Base.isGlobal()) + printOperand(MI, OpNum, "mem"); + else if (Disp.isImm() && !Base.getReg()) + printOperand(MI, OpNum); + else if (Base.getReg()) { + if (Disp.getImm()) { + printOperand(MI, OpNum + 1, "nohash"); + O << '('; + printOperand(MI, OpNum); + O << ')'; + } else { + O << '@'; + printOperand(MI, OpNum); + } + } else + llvm_unreachable("Unsupported memory operand"); +} + +void MSP430AsmPrinter::printCCOperand(const MachineInstr *MI, int OpNum) { + unsigned CC = MI->getOperand(OpNum).getImm(); + + switch (CC) { + default: + llvm_unreachable("Unsupported CC code"); + break; + case MSP430::COND_E: + O << "eq"; + break; + case MSP430::COND_NE: + O << "ne"; + break; + case MSP430::COND_HS: + O << "hs"; + break; + case MSP430::COND_LO: + O << "lo"; + break; + case MSP430::COND_GE: + O << "ge"; + break; + case MSP430::COND_L: + O << 'l'; + break; + } +} + +/// PrintAsmOperand - Print out an operand for an inline asm expression. +/// +bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, + const char *ExtraCode) { + // Does this asm operand have a single letter operand modifier? + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier. + + printOperand(MI, OpNo); + return false; +} + +bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, + unsigned OpNo, unsigned AsmVariant, + const char *ExtraCode) { + if (ExtraCode && ExtraCode[0]) { + return true; // Unknown modifier. + } + printSrcMemOperand(MI, OpNo); + return false; +} + +// Force static initialization. +extern "C" void LLVMInitializeMSP430AsmPrinter() { + RegisterAsmPrinter<MSP430AsmPrinter> X(TheMSP430Target); +} diff --git a/lib/Target/MSP430/AsmPrinter/Makefile b/lib/Target/MSP430/AsmPrinter/Makefile new file mode 100644 index 0000000..4f340c6 --- /dev/null +++ b/lib/Target/MSP430/AsmPrinter/Makefile @@ -0,0 +1,15 @@ +##===- lib/Target/MSP430/AsmPrinter/Makefile ---------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMMSP430AsmPrinter + +# Hack: we need to include 'main' MSP430 target directory to grab private headers +CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common diff --git a/lib/Target/MSP430/CMakeLists.txt b/lib/Target/MSP430/CMakeLists.txt index 6701773..60e0bb1 100644 --- a/lib/Target/MSP430/CMakeLists.txt +++ b/lib/Target/MSP430/CMakeLists.txt @@ -10,14 +10,14 @@ tablegen(MSP430GenDAGISel.inc -gen-dag-isel) tablegen(MSP430GenCallingConv.inc -gen-callingconv) tablegen(MSP430GenSubtarget.inc -gen-subtarget) -add_llvm_target(MSP430 - MSP430AsmPrinter.cpp - MSP430FrameInfo.cpp +add_llvm_target(MSP430CodeGen MSP430InstrInfo.cpp MSP430ISelDAGToDAG.cpp MSP430ISelLowering.cpp + MSP430MCAsmInfo.cpp MSP430RegisterInfo.cpp MSP430Subtarget.cpp - MSP430TargetAsmInfo.cpp MSP430TargetMachine.cpp ) + +target_link_libraries (LLVMMSP430CodeGen LLVMSelectionDAG) diff --git a/lib/Target/MSP430/MSP430.h b/lib/Target/MSP430/MSP430.h index fc13c9e..d9f5f86 100644 --- a/lib/Target/MSP430/MSP430.h +++ b/lib/Target/MSP430/MSP430.h @@ -20,13 +20,13 @@ namespace llvm { class MSP430TargetMachine; class FunctionPass; - class raw_ostream; + class formatted_raw_ostream; FunctionPass *createMSP430ISelDag(MSP430TargetMachine &TM, CodeGenOpt::Level OptLevel); - FunctionPass *createMSP430CodePrinterPass(raw_ostream &o, - MSP430TargetMachine &tm, - bool verbose); + + extern Target TheMSP430Target; + } // end namespace llvm; // Defines symbolic names for MSP430 registers. diff --git a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp index bf49ec0..4195a88 100644 --- a/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp +++ b/lib/Target/MSP430/MSP430ISelDAGToDAG.cpp @@ -28,8 +28,14 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/Statistic.h" + using namespace llvm; +STATISTIC(NumLoadMoved, "Number of loads moved below TokenFactor"); + /// MSP430DAGToDAGISel - MSP430 specific code to select MSP430 machine /// instructions for SelectionDAG operations. /// @@ -50,10 +56,15 @@ namespace { return "MSP430 DAG->DAG Pattern Instruction Selection"; } + virtual bool + SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, + std::vector<SDValue> &OutOps); + // Include the pieces autogenerated from the target description. #include "MSP430GenDAGISel.inc" private: + void PreprocessForRMW(); SDNode *Select(SDValue Op); bool SelectAddr(SDValue Op, SDValue Addr, SDValue &Base, SDValue &Disp); @@ -120,21 +131,155 @@ bool MSP430DAGToDAGISel::SelectAddr(SDValue Op, SDValue Addr, } +bool MSP430DAGToDAGISel:: +SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, + std::vector<SDValue> &OutOps) { + SDValue Op0, Op1; + switch (ConstraintCode) { + default: return true; + case 'm': // memory + if (!SelectAddr(Op, Op, Op0, Op1)) + return true; + break; + } + + OutOps.push_back(Op0); + OutOps.push_back(Op1); + return false; +} + +/// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand +/// and move load below the TokenFactor. Replace store's chain operand with +/// load's chain result. +/// Shamelessly stolen from X86. +static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load, + SDValue Store, SDValue TF) { + SmallVector<SDValue, 4> Ops; + bool isRMW = false; + SDValue TF0, TF1, NewTF; + for (unsigned i = 0, e = TF.getNode()->getNumOperands(); i != e; ++i) + if (Load.getNode() == TF.getOperand(i).getNode()) { + TF0 = Load.getOperand(0); + Ops.push_back(TF0); + } else { + TF1 = TF.getOperand(i); + Ops.push_back(TF1); + if (LoadSDNode* LD = dyn_cast<LoadSDNode>(TF1)) + isRMW = !LD->isVolatile(); + } + + if (isRMW && TF1.getOperand(0).getNode() == TF0.getNode()) + NewTF = TF0; + else + NewTF = CurDAG->UpdateNodeOperands(TF, &Ops[0], Ops.size()); + + SDValue NewLoad = CurDAG->UpdateNodeOperands(Load, NewTF, + Load.getOperand(1), + Load.getOperand(2)); + CurDAG->UpdateNodeOperands(Store, NewLoad.getValue(1), Store.getOperand(1), + Store.getOperand(2), Store.getOperand(3)); +} + +/// isRMWLoad - Return true if N is a load that's part of RMW sub-DAG. The chain +/// produced by the load must only be used by the store's chain operand, +/// otherwise this may produce a cycle in the DAG. +/// Shamelessly stolen from X86. FIXME: Should we make this function common? +static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address, + SDValue &Load) { + if (N.getOpcode() == ISD::BIT_CONVERT) + N = N.getOperand(0); + + LoadSDNode *LD = dyn_cast<LoadSDNode>(N); + if (!LD || LD->isVolatile()) + return false; + if (LD->getAddressingMode() != ISD::UNINDEXED) + return false; + + ISD::LoadExtType ExtType = LD->getExtensionType(); + if (ExtType != ISD::NON_EXTLOAD && ExtType != ISD::EXTLOAD) + return false; + + if (N.hasOneUse() && + LD->hasNUsesOfValue(1, 1) && + N.getOperand(1) == Address && + LD->isOperandOf(Chain.getNode())) { + Load = N; + return true; + } + return false; +} + +/// PreprocessForRMW - Preprocess the DAG to make instruction selection better. +/// Shamelessly stolen from X86. +void MSP430DAGToDAGISel::PreprocessForRMW() { + for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(), + E = CurDAG->allnodes_end(); I != E; ++I) { + if (!ISD::isNON_TRUNCStore(I)) + continue; + + SDValue Chain = I->getOperand(0); + if (Chain.getNode()->getOpcode() != ISD::TokenFactor) + continue; + + SDValue N1 = I->getOperand(1); // Value to store + SDValue N2 = I->getOperand(2); // Address of store + + if (!N1.hasOneUse()) + continue; + + bool RModW = false; + SDValue Load; + unsigned Opcode = N1.getNode()->getOpcode(); + switch (Opcode) { + case ISD::ADD: + case ISD::AND: + case ISD::OR: + case ISD::XOR: + case ISD::ADDC: + case ISD::ADDE: { + SDValue N10 = N1.getOperand(0); + SDValue N11 = N1.getOperand(1); + RModW = isRMWLoad(N10, Chain, N2, Load); + + if (!RModW && isRMWLoad(N11, Chain, N2, Load)) { + // Swap the operands, making the RMW load the first operand seems + // to help selection and prevent token chain loops. + N1 = CurDAG->UpdateNodeOperands(N1, N11, N10); + RModW = true; + } + break; + } + case ISD::SUB: + case ISD::SUBC: + case ISD::SUBE: { + SDValue N10 = N1.getOperand(0); + RModW = isRMWLoad(N10, Chain, N2, Load); + break; + } + } + + if (RModW) { + MoveBelowTokenFactor(CurDAG, Load, SDValue(I, 0), Chain); + ++NumLoadMoved; + } + } +} /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. void MSP430DAGToDAGISel::InstructionSelect() { + PreprocessForRMW(); + + DEBUG(errs() << "Selection DAG after RMW preprocessing:\n"); + DEBUG(CurDAG->dump()); + DEBUG(BB->dump()); // Codegen the basic block. -#ifndef NDEBUG - DOUT << "===== Instruction selection begins:\n"; - Indent = 0; -#endif + DEBUG(errs() << "===== Instruction selection begins:\n"); + DEBUG(Indent = 0); SelectRoot(*CurDAG); -#ifndef NDEBUG - DOUT << "===== Instruction selection ends:\n"; -#endif + DEBUG(errs() << "===== Instruction selection ends:\n"); CurDAG->RemoveDeadNodes(); } @@ -144,21 +289,17 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { DebugLoc dl = Op.getDebugLoc(); // Dump information about the Node being selected - #ifndef NDEBUG - DOUT << std::string(Indent, ' ') << "Selecting: "; + DEBUG(errs().indent(Indent) << "Selecting: "); DEBUG(Node->dump(CurDAG)); - DOUT << "\n"; - Indent += 2; - #endif + DEBUG(errs() << "\n"); + DEBUG(Indent += 2); // If we have a custom node, we already have selected! if (Node->isMachineOpcode()) { - #ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "== "; - DEBUG(Node->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; - #endif + DEBUG(errs().indent(Indent-2) << "== "; + Node->dump(CurDAG); + errs() << "\n"); + DEBUG(Indent -= 2); return NULL; } @@ -172,23 +313,21 @@ SDNode *MSP430DAGToDAGISel::Select(SDValue Op) { 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)); + return CurDAG->getMachineNode(MSP430::ADD16ri, dl, MVT::i16, + TFI, CurDAG->getTargetConstant(0, MVT::i16)); } } // Select the default instruction SDNode *ResNode = SelectCode(Op); - #ifndef NDEBUG - DOUT << std::string(Indent-2, ' ') << "=> "; + DEBUG(errs() << std::string(Indent-2, ' ') << "=> "); if (ResNode == NULL || ResNode == Op.getNode()) DEBUG(Op.getNode()->dump(CurDAG)); else DEBUG(ResNode->dump(CurDAG)); - DOUT << "\n"; - Indent -= 2; - #endif + DEBUG(errs() << "\n"); + DEBUG(Indent -= 2); return ResNode; } diff --git a/lib/Target/MSP430/MSP430ISelLowering.cpp b/lib/Target/MSP430/MSP430ISelLowering.cpp index 91a8663..b56f069 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -31,12 +31,16 @@ #include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/CodeGen/SelectionDAGISel.h" #include "llvm/CodeGen/ValueTypes.h" +#include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/VectorExtras.h" using namespace llvm; MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : - TargetLowering(tm), Subtarget(*tm.getSubtargetImpl()), TM(tm) { + TargetLowering(tm, new TargetLoweringObjectFileELF()), + Subtarget(*tm.getSubtargetImpl()), TM(tm) { // Set up the register classes. addRegisterClass(MVT::i8, MSP430::GR8RegisterClass); @@ -77,7 +81,6 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : setOperationAction(ISD::ROTR, MVT::i8, Expand); setOperationAction(ISD::ROTL, MVT::i16, Expand); setOperationAction(ISD::ROTR, MVT::i16, Expand); - setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::GlobalAddress, MVT::i16, Custom); setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom); setOperationAction(ISD::BR_JT, MVT::Other, Expand); @@ -92,6 +95,24 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : setOperationAction(ISD::SELECT_CC, MVT::i8, Custom); setOperationAction(ISD::SELECT_CC, MVT::i16, Custom); setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom); + setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand); + setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand); + + setOperationAction(ISD::CTTZ, MVT::i8, Expand); + setOperationAction(ISD::CTTZ, MVT::i16, Expand); + setOperationAction(ISD::CTLZ, MVT::i8, Expand); + setOperationAction(ISD::CTLZ, MVT::i16, Expand); + setOperationAction(ISD::CTPOP, MVT::i8, Expand); + setOperationAction(ISD::CTPOP, MVT::i16, Expand); + + setOperationAction(ISD::SHL_PARTS, MVT::i8, Expand); + setOperationAction(ISD::SHL_PARTS, MVT::i16, Expand); + setOperationAction(ISD::SRL_PARTS, MVT::i8, Expand); + setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand); + setOperationAction(ISD::SRA_PARTS, MVT::i8, Expand); + setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand); + + setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); // FIXME: Implement efficiently multiplication by a constant setOperationAction(ISD::MUL, MVT::i16, Expand); @@ -110,19 +131,16 @@ MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) : SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { switch (Op.getOpcode()) { - case ISD::FORMAL_ARGUMENTS: return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::SHL: // FALLTHROUGH case ISD::SRL: case ISD::SRA: return LowerShifts(Op, DAG); - case ISD::RET: return LowerRET(Op, DAG); - case ISD::CALL: return LowerCALL(Op, DAG); case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG); case ISD::BR_CC: return LowerBR_CC(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG); default: - assert(0 && "unimplemented operand"); + llvm_unreachable("unimplemented operand"); return SDValue(); } } @@ -133,32 +151,84 @@ unsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const { } //===----------------------------------------------------------------------===// +// MSP430 Inline Assembly Support +//===----------------------------------------------------------------------===// + +/// getConstraintType - Given a constraint letter, return the type of +/// constraint it is for this target. +TargetLowering::ConstraintType +MSP430TargetLowering::getConstraintType(const std::string &Constraint) const { + if (Constraint.size() == 1) { + switch (Constraint[0]) { + case 'r': + return C_RegisterClass; + default: + break; + } + } + return TargetLowering::getConstraintType(Constraint); +} + +std::pair<unsigned, const TargetRegisterClass*> +MSP430TargetLowering:: +getRegForInlineAsmConstraint(const std::string &Constraint, + EVT VT) const { + if (Constraint.size() == 1) { + // GCC Constraint Letters + switch (Constraint[0]) { + default: break; + case 'r': // GENERAL_REGS + if (VT == MVT::i8) + return std::make_pair(0U, MSP430::GR8RegisterClass); + + return std::make_pair(0U, MSP430::GR16RegisterClass); + } + } + + return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT); +} + +//===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// #include "MSP430GenCallingConv.inc" -SDValue MSP430TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, - SelectionDAG &DAG) { - unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue(); - switch (CC) { +SDValue +MSP430TargetLowering::LowerFormalArguments(SDValue Chain, + CallingConv::ID CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + switch (CallConv) { default: - assert(0 && "Unsupported calling convention"); + llvm_unreachable("Unsupported calling convention"); case CallingConv::C: case CallingConv::Fast: - return LowerCCCArguments(Op, DAG); + return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals); } } -SDValue MSP430TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - unsigned CallingConv = TheCall->getCallingConv(); - switch (CallingConv) { +SDValue +MSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { + + switch (CallConv) { default: - assert(0 && "Unsupported calling convention"); + llvm_unreachable("Unsupported calling convention"); case CallingConv::Fast: case CallingConv::C: - return LowerCCCCallTo(Op, DAG, CallingConv); + return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall, + Outs, Ins, dl, DAG, InVals); } } @@ -166,40 +236,46 @@ SDValue MSP430TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { /// generate load operations for arguments places on the stack. // FIXME: struct return stuff // FIXME: varargs -SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, - SelectionDAG &DAG) { +SDValue +MSP430TargetLowering::LowerCCCArguments(SDValue Chain, + CallingConv::ID CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> + &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { MachineFunction &MF = DAG.getMachineFunction(); MachineFrameInfo *MFI = MF.getFrameInfo(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); - SDValue Root = Op.getOperand(0); - bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0; - unsigned CC = MF.getFunction()->getCallingConv(); - DebugLoc dl = Op.getDebugLoc(); // Assign locations to all of the incoming arguments. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); - CCInfo.AnalyzeFormalArguments(Op.getNode(), CC_MSP430); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); + CCInfo.AnalyzeFormalArguments(Ins, CC_MSP430); assert(!isVarArg && "Varargs not supported yet"); - SmallVector<SDValue, 16> ArgValues; for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; if (VA.isRegLoc()) { // Arguments passed in registers - MVT RegVT = VA.getLocVT(); - switch (RegVT.getSimpleVT()) { - default: - cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " - << RegVT.getSimpleVT() - << "\n"; - abort(); + EVT RegVT = VA.getLocVT(); + switch (RegVT.getSimpleVT().SimpleTy) { + default: + { +#ifndef NDEBUG + errs() << "LowerFormalArguments Unhandled argument type: " + << RegVT.getSimpleVT().SimpleTy << "\n"; +#endif + llvm_unreachable(0); + } case MVT::i16: unsigned VReg = RegInfo.createVirtualRegister(MSP430::GR16RegisterClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); - SDValue ArgValue = DAG.getCopyFromReg(Root, dl, VReg, RegVT); + SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); // If this is an 8-bit value, it is really passed promoted to 16 // bits. Insert an assert[sz]ext to capture this, then truncate to the @@ -214,7 +290,7 @@ SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, if (VA.getLocInfo() != CCValAssign::Full) ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue); - ArgValues.push_back(ArgValue); + InVals.push_back(ArgValue); } } else { // Sanity check @@ -222,8 +298,8 @@ SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, // Load the argument to a virtual register unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; if (ObjSize > 2) { - cerr << "LowerFORMAL_ARGUMENTS Unhandled argument type: " - << VA.getLocVT().getSimpleVT() + errs() << "LowerFormalArguments Unhandled argument type: " + << VA.getLocVT().getSimpleVT().SimpleTy << "\n"; } // Create the frame index object for this incoming parameter... @@ -232,30 +308,29 @@ SDValue MSP430TargetLowering::LowerCCCArguments(SDValue Op, // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i16); - ArgValues.push_back(DAG.getLoad(VA.getLocVT(), dl, Root, FIN, - PseudoSourceValue::getFixedStack(FI), 0)); + InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, + PseudoSourceValue::getFixedStack(FI), 0)); } } - ArgValues.push_back(Root); - - // Return the new list of results. - return DAG.getNode(ISD::MERGE_VALUES, dl, Op.getNode()->getVTList(), - &ArgValues[0], ArgValues.size()).getValue(Op.getResNo()); + return Chain; } -SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { +SDValue +MSP430TargetLowering::LowerReturn(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG) { + // CCValAssign - represent the assignment of the return value to a location SmallVector<CCValAssign, 16> RVLocs; - unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv(); - bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); // CCState - Info about the registers and stack slot. - CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); - // Analize return values of ISD::RET - CCInfo.AnalyzeReturn(Op.getNode(), RetCC_MSP430); + // Analize return values. + CCInfo.AnalyzeReturn(Outs, RetCC_MSP430); // If this is the first return lowered for this function, add the regs to the // liveout set for the function. @@ -265,8 +340,6 @@ SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg()); } - // The chain is always operand #0 - SDValue Chain = Op.getOperand(0); SDValue Flag; // Copy the result values into the output registers. @@ -274,10 +347,8 @@ SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { CCValAssign &VA = RVLocs[i]; assert(VA.isRegLoc() && "Can only return in registers!"); - // ISD::RET => ret chain, (regnum1,val1), ... - // So i*2+1 index only the regnums Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), - Op.getOperand(i*2+1), Flag); + Outs[i].Val, Flag); // Guarantee that all emitted copies are stuck together, // avoiding something bad. @@ -294,19 +365,21 @@ SDValue MSP430TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) { /// LowerCCCCallTo - functions arguments are copied from virtual regs to /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. /// TODO: sret. -SDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, - unsigned CC) { - CallSDNode *TheCall = cast<CallSDNode>(Op.getNode()); - SDValue Chain = TheCall->getChain(); - SDValue Callee = TheCall->getCallee(); - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = Op.getDebugLoc(); - +SDValue +MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> + &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Analyze operands of the call, assigning locations to each operand. SmallVector<CCValAssign, 16> ArgLocs; - CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + ArgLocs, *DAG.getContext()); - CCInfo.AnalyzeCallOperands(TheCall, CC_MSP430); + CCInfo.AnalyzeCallOperands(Outs, CC_MSP430); // Get a count of how many bytes are to be pushed on the stack. unsigned NumBytes = CCInfo.getNextStackOffset(); @@ -322,12 +395,11 @@ SDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { CCValAssign &VA = ArgLocs[i]; - // Arguments start after the 5 first operands of ISD::CALL - SDValue Arg = TheCall->getArg(i); + SDValue Arg = Outs[i].Val; // Promote the value if needed. switch (VA.getLocInfo()) { - default: assert(0 && "Unknown loc info!"); + default: llvm_unreachable("Unknown loc info!"); case CCValAssign::Full: break; case CCValAssign::SExt: Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg); @@ -412,50 +484,43 @@ SDValue MSP430TargetLowering::LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, // Handle result values, copying them out of physregs into vregs that we // return. - return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG), - Op.getResNo()); + return LowerCallResult(Chain, InFlag, CallConv, isVarArg, Ins, dl, + DAG, InVals); } -/// LowerCallResult - Lower the result values of an ISD::CALL into the -/// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call -/// being lowered. Returns a SDNode with the same number of values as the -/// ISD::CALL. -SDNode* +/// LowerCallResult - Lower the result values of a call into the +/// appropriate copies out of appropriate physical registers. +/// +SDValue MSP430TargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, - CallSDNode *TheCall, - unsigned CallingConv, - SelectionDAG &DAG) { - bool isVarArg = TheCall->isVarArg(); - DebugLoc dl = TheCall->getDebugLoc(); + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals) { // Assign locations to each value returned by this call. SmallVector<CCValAssign, 16> RVLocs; - CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs); + CCState CCInfo(CallConv, isVarArg, getTargetMachine(), + RVLocs, *DAG.getContext()); - CCInfo.AnalyzeCallResult(TheCall, RetCC_MSP430); - SmallVector<SDValue, 8> ResultVals; + CCInfo.AnalyzeCallResult(Ins, RetCC_MSP430); // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), RVLocs[i].getValVT(), InFlag).getValue(1); InFlag = Chain.getValue(2); - ResultVals.push_back(Chain.getValue(0)); + InVals.push_back(Chain.getValue(0)); } - ResultVals.push_back(Chain); - - // Merge everything together with a MERGE_VALUES node. - return DAG.getNode(ISD::MERGE_VALUES, dl, TheCall->getVTList(), - &ResultVals[0], ResultVals.size()).getNode(); + return Chain; } SDValue MSP430TargetLowering::LowerShifts(SDValue Op, SelectionDAG &DAG) { unsigned Opc = Op.getOpcode(); SDNode* N = Op.getNode(); - MVT VT = Op.getValueType(); + EVT VT = Op.getValueType(); DebugLoc dl = N->getDebugLoc(); // We currently only lower shifts of constant argument. @@ -511,7 +576,7 @@ static SDValue EmitCMP(SDValue &LHS, SDValue &RHS, unsigned &TargetCC, // FIXME: Handle jump negative someday TargetCC = MSP430::COND_INVALID; switch (CC) { - default: assert(0 && "Invalid integer condition!"); + default: llvm_unreachable("Invalid integer condition!"); case ISD::SETEQ: TargetCC = MSP430::COND_E; // aka COND_Z break; @@ -585,7 +650,7 @@ SDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) { SDValue MSP430TargetLowering::LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) { SDValue Val = Op.getOperand(0); - MVT VT = Op.getValueType(); + EVT VT = Op.getValueType(); DebugLoc dl = Op.getDebugLoc(); assert(VT == MVT::i16 && "Only support i16 for now!"); @@ -616,7 +681,8 @@ const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const { MachineBasicBlock* MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const { + MachineBasicBlock *BB, + DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const { const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo(); DebugLoc dl = MI->getDebugLoc(); assert((MI->getOpcode() == MSP430::Select16 || @@ -646,6 +712,10 @@ MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, .addImm(MI->getOperand(3).getImm()); F->insert(I, copy0MBB); F->insert(I, copy1MBB); + // Inform sdisel of the edge changes. + for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(), + SE = BB->succ_end(); SI != SE; ++SI) + EM->insert(std::make_pair(*SI, copy1MBB)); // Update machine-CFG edges by transferring all successors of the current // block to the new block which will contain the Phi node for the select. copy1MBB->transferSuccessors(BB); diff --git a/lib/Target/MSP430/MSP430ISelLowering.h b/lib/Target/MSP430/MSP430ISelLowering.h index 4a90a0e..fdbc384 100644 --- a/lib/Target/MSP430/MSP430ISelLowering.h +++ b/lib/Target/MSP430/MSP430ISelLowering.h @@ -33,7 +33,7 @@ namespace llvm { /// Y = RRC X, rotate right via carry RRC, - /// CALL/TAILCALL - These operations represent an abstract call + /// CALL - These operations represent an abstract call /// instruction, which includes a bunch of information. CALL, @@ -77,10 +77,6 @@ namespace llvm { /// getFunctionAlignment - Return the Log2 alignment of this function. virtual unsigned getFunctionAlignment(const Function *F) const; - SDValue LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG); - SDValue LowerCALL(SDValue Op, SelectionDAG &DAG); - SDValue LowerRET(SDValue Op, SelectionDAG &DAG); - SDValue LowerCCCArguments(SDValue Op, SelectionDAG &DAG); SDValue LowerShifts(SDValue Op, SelectionDAG &DAG); SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG); SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG); @@ -88,16 +84,58 @@ namespace llvm { SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG); SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG); - SDValue LowerCCCCallTo(SDValue Op, SelectionDAG &DAG, - unsigned CC); - SDNode* LowerCallResult(SDValue Chain, SDValue InFlag, - CallSDNode *TheCall, - unsigned CallingConv, SelectionDAG &DAG); + TargetLowering::ConstraintType + getConstraintType(const std::string &Constraint) const; + std::pair<unsigned, const TargetRegisterClass*> + getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const; MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *BB) const; + MachineBasicBlock *BB, + DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const; private: + SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, + bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + SDValue LowerCCCArguments(SDValue Chain, + CallingConv::ID CallConv, + bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, + SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + SDValue LowerCallResult(SDValue Chain, SDValue InFlag, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerFormalArguments(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + virtual SDValue + LowerCall(SDValue Chain, SDValue Callee, + CallingConv::ID CallConv, bool isVarArg, bool isTailCall, + const SmallVectorImpl<ISD::OutputArg> &Outs, + const SmallVectorImpl<ISD::InputArg> &Ins, + DebugLoc dl, SelectionDAG &DAG, + SmallVectorImpl<SDValue> &InVals); + + virtual SDValue + LowerReturn(SDValue Chain, + CallingConv::ID CallConv, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + DebugLoc dl, SelectionDAG &DAG); + const MSP430Subtarget &Subtarget; const MSP430TargetMachine &TM; }; diff --git a/lib/Target/MSP430/MSP430InstrInfo.cpp b/lib/Target/MSP430/MSP430InstrInfo.cpp index 91112c3..37fbb6d 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.cpp +++ b/lib/Target/MSP430/MSP430InstrInfo.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; @@ -44,7 +45,7 @@ void MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, .addFrameIndex(FrameIdx).addImm(0) .addReg(SrcReg, getKillRegState(isKill)); else - assert(0 && "Cannot store this register to stack slot!"); + llvm_unreachable("Cannot store this register to stack slot!"); } void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, @@ -61,7 +62,7 @@ void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, BuildMI(MBB, MI, DL, get(MSP430::MOV8rm)) .addReg(DestReg).addFrameIndex(FrameIdx).addImm(0); else - assert(0 && "Cannot store this register to stack slot!"); + llvm_unreachable("Cannot store this register to stack slot!"); } bool MSP430InstrInfo::copyRegToReg(MachineBasicBlock &MBB, @@ -171,7 +172,7 @@ MSP430InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, // Conditional branch. unsigned Count = 0; - assert(0 && "Implement conditional branches!"); + llvm_unreachable("Implement conditional branches!"); return Count; } diff --git a/lib/Target/MSP430/MSP430InstrInfo.td b/lib/Target/MSP430/MSP430InstrInfo.td index 39c08e4..f7e0d2b 100644 --- a/lib/Target/MSP430/MSP430InstrInfo.td +++ b/lib/Target/MSP430/MSP430InstrInfo.td @@ -155,7 +155,7 @@ let isCall = 1 in let Defs = [R12W, R13W, R14W, R15W, SRW], Uses = [SPW] in { def CALLi : Pseudo<(outs), (ins i16imm:$dst, variable_ops), - "call\t${dst:call}", [(MSP430call imm:$dst)]>; + "call\t$dst", [(MSP430call imm:$dst)]>; def CALLr : Pseudo<(outs), (ins GR16:$dst, variable_ops), "call\t$dst", [(MSP430call GR16:$dst)]>; def CALLm : Pseudo<(outs), (ins memsrc:$dst, variable_ops), @@ -243,6 +243,13 @@ def MOV16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), "mov.w\t{$src, $dst}", [(store GR16:$src, addr:$dst)]>; +def MOV8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), + "mov.b\t{$src, $dst}", + [(store (i8 (load addr:$src)), addr:$dst)]>; +def MOV16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), + "mov.w\t{$src, $dst}", + [(store (i16 (load addr:$src)), addr:$dst)]>; + //===----------------------------------------------------------------------===// // Arithmetic Instructions @@ -671,30 +678,26 @@ def OR16rm : Pseudo<(outs GR16:$dst), (ins GR16:$src1, memsrc:$src2), let isTwoAddress = 0 in { def OR8mr : Pseudo<(outs), (ins memdst:$dst, GR8:$src), "bis.b\t{$src, $dst}", - [(store (or (load addr:$dst), GR8:$src), addr:$dst), - (implicit SRW)]>; + [(store (or (load addr:$dst), GR8:$src), addr:$dst)]>; def OR16mr : Pseudo<(outs), (ins memdst:$dst, GR16:$src), "bis.w\t{$src, $dst}", - [(store (or (load addr:$dst), GR16:$src), addr:$dst), - (implicit SRW)]>; + [(store (or (load addr:$dst), GR16:$src), addr:$dst)]>; def OR8mi : Pseudo<(outs), (ins memdst:$dst, i8imm:$src), "bis.b\t{$src, $dst}", - [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst), - (implicit SRW)]>; + [(store (or (load addr:$dst), (i8 imm:$src)), addr:$dst)]>; def OR16mi : Pseudo<(outs), (ins memdst:$dst, i16imm:$src), "bis.w\t{$src, $dst}", - [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst), - (implicit SRW)]>; + [(store (or (load addr:$dst), (i16 imm:$src)), addr:$dst)]>; def OR8mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), "bis.b\t{$src, $dst}", - [(store (or (load addr:$dst), (i8 (load addr:$src))), addr:$dst), - (implicit SRW)]>; + [(store (or (i8 (load addr:$dst)), + (i8 (load addr:$src))), addr:$dst)]>; def OR16mm : Pseudo<(outs), (ins memdst:$dst, memsrc:$src), "bis.w\t{$src, $dst}", - [(store (or (load addr:$dst), (i16 (load addr:$src))), addr:$dst), - (implicit SRW)]>; + [(store (or (i16 (load addr:$dst)), + (i16 (load addr:$src))), addr:$dst)]>; } } // isTwoAddress = 1 @@ -722,59 +725,6 @@ def CMP16im : Pseudo<(outs), (ins i16imm:$src1, memsrc:$src2), "cmp.w\t{$src1, $src2}", [(MSP430cmp (i16 imm:$src1), (load addr:$src2)), (implicit SRW)]>; -// FIXME: imm is allowed only on src operand, not on dst. - -//def CMP8ri : Pseudo<(outs), (ins GR8:$src1, i8imm:$src2), -// "cmp.b\t{$src1, $src2}", -// [(MSP430cmp GR8:$src1, imm:$src2), (implicit SRW)]>; -//def CMP16ri : Pseudo<(outs), (ins GR16:$src1, i16imm:$src2), -// "cmp.w\t{$src1, $src2}", -// [(MSP430cmp GR16:$src1, imm:$src2), (implicit SRW)]>; - -//def CMP8mi : Pseudo<(outs), (ins memsrc:$src1, i8imm:$src2), -// "cmp.b\t{$src1, $src2}", -// [(MSP430cmp (load addr:$src1), (i8 imm:$src2)), (implicit SRW)]>; -//def CMP16mi : Pseudo<(outs), (ins memsrc:$src1, i16imm:$src2), -// "cmp.w\t{$src1, $src2}", -// [(MSP430cmp (load addr:$src1), (i16 imm:$src2)), (implicit SRW)]>; - - -// Imm 0, +1, +2, +4, +8 are encoded via constant generator registers. -// That's why we can use them as dest operands. -// We don't define new class for them, since they would need special encoding -// in the future. - -def CMP8ri0 : Pseudo<(outs), (ins GR8:$src1), - "cmp.b\t{$src1, #0}", - [(MSP430cmp GR8:$src1, 0), (implicit SRW)]>; -def CMP16ri0: Pseudo<(outs), (ins GR16:$src1), - "cmp.w\t{$src1, #0}", - [(MSP430cmp GR16:$src1, 0), (implicit SRW)]>; -def CMP8ri1 : Pseudo<(outs), (ins GR8:$src1), - "cmp.b\t{$src1, #1}", - [(MSP430cmp GR8:$src1, 1), (implicit SRW)]>; -def CMP16ri1: Pseudo<(outs), (ins GR16:$src1), - "cmp.w\t{$src1, #1}", - [(MSP430cmp GR16:$src1, 1), (implicit SRW)]>; -def CMP8ri2 : Pseudo<(outs), (ins GR8:$src1), - "cmp.b\t{$src1, #2}", - [(MSP430cmp GR8:$src1, 2), (implicit SRW)]>; -def CMP16ri2: Pseudo<(outs), (ins GR16:$src1), - "cmp.w\t{$src1, #2}", - [(MSP430cmp GR16:$src1, 2), (implicit SRW)]>; -def CMP8ri4 : Pseudo<(outs), (ins GR8:$src1), - "cmp.b\t{$src1, #4}", - [(MSP430cmp GR8:$src1, 4), (implicit SRW)]>; -def CMP16ri4: Pseudo<(outs), (ins GR16:$src1), - "cmp.w\t{$src1, #4}", - [(MSP430cmp GR16:$src1, 4), (implicit SRW)]>; -def CMP8ri8 : Pseudo<(outs), (ins GR8:$src1), - "cmp.b\t{$src1, #8}", - [(MSP430cmp GR8:$src1, 8), (implicit SRW)]>; -def CMP16ri8: Pseudo<(outs), (ins GR16:$src1), - "cmp.w\t{$src1, #8}", - [(MSP430cmp GR16:$src1, 8), (implicit SRW)]>; - def CMP8rm : Pseudo<(outs), (ins GR8:$src1, memsrc:$src2), "cmp.b\t{$src1, $src2}", [(MSP430cmp GR8:$src1, (load addr:$src2)), (implicit SRW)]>; diff --git a/lib/Target/MSP430/MSP430MCAsmInfo.cpp b/lib/Target/MSP430/MSP430MCAsmInfo.cpp new file mode 100644 index 0000000..069313e --- /dev/null +++ b/lib/Target/MSP430/MSP430MCAsmInfo.cpp @@ -0,0 +1,20 @@ +//===-- MSP430MCAsmInfo.cpp - MSP430 asm properties -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declarations of the MSP430MCAsmInfo properties. +// +//===----------------------------------------------------------------------===// + +#include "MSP430MCAsmInfo.h" +using namespace llvm; + +MSP430MCAsmInfo::MSP430MCAsmInfo(const Target &T, const StringRef &TT) { + AlignmentIsInBytes = false; + AllowNameToStartWithDigit = true; +} diff --git a/lib/Target/MSP430/MSP430MCAsmInfo.h b/lib/Target/MSP430/MSP430MCAsmInfo.h new file mode 100644 index 0000000..8318029 --- /dev/null +++ b/lib/Target/MSP430/MSP430MCAsmInfo.h @@ -0,0 +1,28 @@ +//=====-- MSP430MCAsmInfo.h - MSP430 asm properties -----------*- C++ -*--====// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the declaration of the MSP430MCAsmInfo class. +// +//===----------------------------------------------------------------------===// + +#ifndef MSP430TARGETASMINFO_H +#define MSP430TARGETASMINFO_H + +#include "llvm/MC/MCAsmInfo.h" + +namespace llvm { + class Target; + class StringRef; + struct MSP430MCAsmInfo : public MCAsmInfo { + explicit MSP430MCAsmInfo(const Target &T, const StringRef &TT); + }; + +} // namespace llvm + +#endif diff --git a/lib/Target/MSP430/MSP430RegisterInfo.cpp b/lib/Target/MSP430/MSP430RegisterInfo.cpp index d40bac7..1a5893e 100644 --- a/lib/Target/MSP430/MSP430RegisterInfo.cpp +++ b/lib/Target/MSP430/MSP430RegisterInfo.cpp @@ -23,6 +23,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/ADT/BitVector.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; @@ -45,7 +46,7 @@ MSP430RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { return CalleeSavedRegs; } -const TargetRegisterClass* const* +const TargetRegisterClass *const * MSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { static const TargetRegisterClass * const CalleeSavedRegClasses[] = { &MSP430::GR16RegClass, &MSP430::GR16RegClass, @@ -58,8 +59,7 @@ MSP430RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { return CalleeSavedRegClasses; } -BitVector -MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const { +BitVector MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const { BitVector Reserved(getNumRegs()); // Mark 4 special registers as reserved. @@ -75,7 +75,8 @@ MSP430RegisterInfo::getReservedRegs(const MachineFunction &MF) const { return Reserved; } -const TargetRegisterClass* MSP430RegisterInfo::getPointerRegClass() const { +const TargetRegisterClass * +MSP430RegisterInfo::getPointerRegClass(unsigned Kind) const { return &MSP430::GR16RegClass; } @@ -146,9 +147,10 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MBB.erase(I); } -void +unsigned MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS) const { + int SPAdj, int *Value, + RegScavenger *RS) const { assert(SPAdj == 0 && "Unexpected"); unsigned i = 0; @@ -186,7 +188,7 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.getOperand(i).ChangeToRegister(BasePtr, false); if (Offset == 0) - return; + return 0; // We need to materialize the offset via add instruction. unsigned DstReg = MI.getOperand(0).getReg(); @@ -197,11 +199,12 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, BuildMI(MBB, next(II), dl, TII.get(MSP430::ADD16ri), DstReg) .addReg(DstReg).addImm(Offset); - return; + return 0; } MI.getOperand(i).ChangeToRegister(BasePtr, false); MI.getOperand(i+1).ChangeToImmediate(Offset); + return 0; } void @@ -291,7 +294,7 @@ void MSP430RegisterInfo::emitEpilogue(MachineFunction &MF, switch (RetOpcode) { case MSP430::RET: break; // These are ok default: - assert(0 && "Can only insert epilog into returning blocks"); + llvm_unreachable("Can only insert epilog into returning blocks"); } // Get the number of bytes to allocate from the FrameInfo @@ -310,7 +313,6 @@ void MSP430RegisterInfo::emitEpilogue(MachineFunction &MF, NumBytes = StackSize - CSSize; // Skip the callee-saved pop instructions. - MachineBasicBlock::iterator LastCSPop = MBBI; while (MBBI != MBB.begin()) { MachineBasicBlock::iterator PI = prior(MBBI); unsigned Opc = PI->getOpcode(); @@ -327,7 +329,16 @@ void MSP430RegisterInfo::emitEpilogue(MachineFunction &MF, // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); if (MFI->hasVarSizedObjects()) { - assert(0 && "Not implemented yet!"); + BuildMI(MBB, MBBI, DL, + TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW); + if (CSSize) { + MachineInstr *MI = + BuildMI(MBB, MBBI, DL, + TII.get(MSP430::SUB16ri), MSP430::SPW) + .addReg(MSP430::SPW).addImm(CSSize); + // The SRW implicit def is dead. + MI->getOperand(3).setIsDead(); + } } else { // adjust stack pointer back: SPW += numbytes if (NumBytes) { @@ -349,7 +360,7 @@ unsigned MSP430RegisterInfo::getFrameRegister(MachineFunction &MF) const { } int MSP430RegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { - assert(0 && "Not implemented yet!"); + llvm_unreachable("Not implemented yet!"); return 0; } diff --git a/lib/Target/MSP430/MSP430RegisterInfo.h b/lib/Target/MSP430/MSP430RegisterInfo.h index a210e36..5f3a216 100644 --- a/lib/Target/MSP430/MSP430RegisterInfo.h +++ b/lib/Target/MSP430/MSP430RegisterInfo.h @@ -40,7 +40,7 @@ public: getCalleeSavedRegClasses(const MachineFunction *MF = 0) const; BitVector getReservedRegs(const MachineFunction &MF) const; - const TargetRegisterClass* getPointerRegClass() const; + const TargetRegisterClass* getPointerRegClass(unsigned Kind = 0) const; bool hasFP(const MachineFunction &MF) const; bool hasReservedCallFrame(MachineFunction &MF) const; @@ -49,8 +49,9 @@ public: MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; - void eliminateFrameIndex(MachineBasicBlock::iterator II, - int SPAdj, RegScavenger *RS = NULL) const; + unsigned eliminateFrameIndex(MachineBasicBlock::iterator II, + int SPAdj, int *Value = NULL, + RegScavenger *RS = NULL) const; void emitPrologue(MachineFunction &MF) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; diff --git a/lib/Target/MSP430/MSP430Subtarget.cpp b/lib/Target/MSP430/MSP430Subtarget.cpp index ef9e103..1346cb9 100644 --- a/lib/Target/MSP430/MSP430Subtarget.cpp +++ b/lib/Target/MSP430/MSP430Subtarget.cpp @@ -14,12 +14,10 @@ #include "MSP430Subtarget.h" #include "MSP430.h" #include "MSP430GenSubtarget.inc" -#include "llvm/Target/TargetMachine.h" using namespace llvm; -MSP430Subtarget::MSP430Subtarget(const TargetMachine &TM, const Module &M, - const std::string &FS) { +MSP430Subtarget::MSP430Subtarget(const std::string &TT, const std::string &FS) { std::string CPU = "generic"; // Parse features string. diff --git a/lib/Target/MSP430/MSP430Subtarget.h b/lib/Target/MSP430/MSP430Subtarget.h index 96c8108..1070544 100644 --- a/lib/Target/MSP430/MSP430Subtarget.h +++ b/lib/Target/MSP430/MSP430Subtarget.h @@ -19,17 +19,14 @@ #include <string> namespace llvm { -class Module; -class TargetMachine; class MSP430Subtarget : public TargetSubtarget { bool ExtendedInsts; public: /// This constructor initializes the data members to match that - /// of the specified module. + /// of the specified triple. /// - MSP430Subtarget(const TargetMachine &TM, const Module &M, - const std::string &FS); + MSP430Subtarget(const std::string &TT, const std::string &FS); /// ParseSubtargetFeatures - Parses features string setting specified /// subtarget options. Definition of function is auto generated by tblgen. diff --git a/lib/Target/MSP430/MSP430TargetMachine.cpp b/lib/Target/MSP430/MSP430TargetMachine.cpp index dd09d43..5e21f8e 100644 --- a/lib/Target/MSP430/MSP430TargetMachine.cpp +++ b/lib/Target/MSP430/MSP430TargetMachine.cpp @@ -12,43 +12,30 @@ //===----------------------------------------------------------------------===// #include "MSP430.h" -#include "MSP430TargetAsmInfo.h" +#include "MSP430MCAsmInfo.h" #include "MSP430TargetMachine.h" -#include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Target/TargetAsmInfo.h" -#include "llvm/Target/TargetMachineRegistry.h" - +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/Target/TargetRegistry.h" using namespace llvm; -/// MSP430TargetMachineModule - Note that this is used on hosts that -/// cannot link in a library unless there are references into the -/// library. In particular, it seems that it is not possible to get -/// things to work on Win32 without this. Though it is unused, do not -/// remove it. -extern "C" int MSP430TargetMachineModule; -int MSP430TargetMachineModule = 0; - - -// Register the targets -static RegisterTarget<MSP430TargetMachine> -X("msp430", "MSP430 [experimental]"); - -// Force static initialization. -extern "C" void LLVMInitializeMSP430Target() { } +extern "C" void LLVMInitializeMSP430Target() { + // Register the target. + RegisterTargetMachine<MSP430TargetMachine> X(TheMSP430Target); + RegisterAsmInfo<MSP430MCAsmInfo> Z(TheMSP430Target); +} -MSP430TargetMachine::MSP430TargetMachine(const Module &M, +MSP430TargetMachine::MSP430TargetMachine(const Target &T, + const std::string &TT, const std::string &FS) : - Subtarget(*this, M, FS), + LLVMTargetMachine(T, TT), + Subtarget(TT, FS), // FIXME: Check TargetData string. DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"), InstrInfo(*this), TLInfo(*this), FrameInfo(TargetFrameInfo::StackGrowsDown, 2, -2) { } -const TargetAsmInfo *MSP430TargetMachine::createTargetAsmInfo() const { - return new MSP430TargetAsmInfo(*this); -} bool MSP430TargetMachine::addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel) { @@ -57,23 +44,3 @@ bool MSP430TargetMachine::addInstSelector(PassManagerBase &PM, return false; } -bool MSP430TargetMachine::addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, - raw_ostream &Out) { - // Output assembly language. - PM.add(createMSP430CodePrinterPass(Out, *this, Verbose)); - return false; -} - -unsigned MSP430TargetMachine::getModuleMatchQuality(const Module &M) { - std::string TT = M.getTargetTriple(); - - // We strongly match msp430 - if (TT.size() >= 6 && TT[0] == 'm' && TT[1] == 's' && TT[2] == 'p' && - TT[3] == '4' && TT[4] == '3' && TT[5] == '0') - return 20; - - return 0; -} - diff --git a/lib/Target/MSP430/MSP430TargetMachine.h b/lib/Target/MSP430/MSP430TargetMachine.h index d9ffa2b..d386140 100644 --- a/lib/Target/MSP430/MSP430TargetMachine.h +++ b/lib/Target/MSP430/MSP430TargetMachine.h @@ -37,11 +37,9 @@ class MSP430TargetMachine : public LLVMTargetMachine { // any MSP430 specific FrameInfo class. TargetFrameInfo FrameInfo; -protected: - virtual const TargetAsmInfo *createTargetAsmInfo() const; - public: - MSP430TargetMachine(const Module &M, const std::string &FS); + MSP430TargetMachine(const Target &T, const std::string &TT, + const std::string &FS); virtual const TargetFrameInfo *getFrameInfo() const { return &FrameInfo; } virtual const MSP430InstrInfo *getInstrInfo() const { return &InstrInfo; } @@ -57,10 +55,6 @@ public: } virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel); - virtual bool addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, bool Verbose, - raw_ostream &Out); - static unsigned getModuleMatchQuality(const Module &M); }; // MSP430TargetMachine. } // end namespace llvm diff --git a/lib/Target/MSP430/Makefile b/lib/Target/MSP430/Makefile index 45cb3aa..4b18bc9 100644 --- a/lib/Target/MSP430/Makefile +++ b/lib/Target/MSP430/Makefile @@ -7,7 +7,7 @@ # ##===----------------------------------------------------------------------===## LEVEL = ../../.. -LIBRARYNAME = LLVMMSP430 +LIBRARYNAME = LLVMMSP430CodeGen TARGET = MSP430 # Make sure that tblgen is run, first thing. @@ -17,5 +17,7 @@ BUILT_SOURCES = MSP430GenRegisterInfo.h.inc MSP430GenRegisterNames.inc \ MSP430GenDAGISel.inc MSP430GenCallingConv.inc \ MSP430GenSubtarget.inc +DIRS = AsmPrinter TargetInfo + include $(LEVEL)/Makefile.common diff --git a/lib/Target/MSP430/TargetInfo/CMakeLists.txt b/lib/Target/MSP430/TargetInfo/CMakeLists.txt new file mode 100644 index 0000000..1d408d0 --- /dev/null +++ b/lib/Target/MSP430/TargetInfo/CMakeLists.txt @@ -0,0 +1,7 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMMSP430Info + MSP430TargetInfo.cpp + ) + +add_dependencies(LLVMMSP430Info MSP430Table_gen) diff --git a/lib/Target/MSP430/TargetInfo/MSP430TargetInfo.cpp b/lib/Target/MSP430/TargetInfo/MSP430TargetInfo.cpp new file mode 100644 index 0000000..f9ca5c4 --- /dev/null +++ b/lib/Target/MSP430/TargetInfo/MSP430TargetInfo.cpp @@ -0,0 +1,20 @@ +//===-- MSP430TargetInfo.cpp - MSP430 Target Implementation ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MSP430.h" +#include "llvm/Module.h" +#include "llvm/Target/TargetRegistry.h" +using namespace llvm; + +Target llvm::TheMSP430Target; + +extern "C" void LLVMInitializeMSP430TargetInfo() { + RegisterTarget<Triple::msp430> + X(TheMSP430Target, "msp430", "MSP430 [experimental]"); +} diff --git a/lib/Target/MSP430/TargetInfo/Makefile b/lib/Target/MSP430/TargetInfo/Makefile new file mode 100644 index 0000000..abb08f2 --- /dev/null +++ b/lib/Target/MSP430/TargetInfo/Makefile @@ -0,0 +1,15 @@ +##===- lib/Target/MSP430/TargetInfo/Makefile ---------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMMSP430Info + +# Hack: we need to include 'main' target directory to grab private headers +CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common |