Rafael Espindola | 7bc59bc | 2006-05-14 22:18:28 +0000 | [diff] [blame^] | 1 | //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file was developed by Chris Lattner and is distributed under |
| 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file defines an instruction selector for the ARM target. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "ARM.h" |
| 15 | #include "ARMTargetMachine.h" |
| 16 | #include "llvm/DerivedTypes.h" |
| 17 | #include "llvm/Function.h" |
| 18 | #include "llvm/Intrinsics.h" |
| 19 | #include "llvm/CodeGen/MachineFrameInfo.h" |
| 20 | #include "llvm/CodeGen/MachineFunction.h" |
| 21 | #include "llvm/CodeGen/MachineInstrBuilder.h" |
| 22 | #include "llvm/CodeGen/SelectionDAG.h" |
| 23 | #include "llvm/CodeGen/SelectionDAGISel.h" |
| 24 | #include "llvm/CodeGen/SSARegMap.h" |
| 25 | #include "llvm/Target/TargetLowering.h" |
| 26 | #include "llvm/Support/Debug.h" |
| 27 | #include <iostream> |
| 28 | #include <set> |
| 29 | using namespace llvm; |
| 30 | |
| 31 | namespace ARMISD { |
| 32 | enum { |
| 33 | FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END, |
| 34 | RET_FLAG, |
| 35 | }; |
| 36 | } |
| 37 | |
| 38 | namespace { |
| 39 | class ARMTargetLowering : public TargetLowering { |
| 40 | public: |
| 41 | ARMTargetLowering(TargetMachine &TM); |
| 42 | virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); |
| 43 | |
| 44 | virtual std::pair<SDOperand, SDOperand> |
| 45 | LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, |
| 46 | unsigned CC, |
| 47 | bool isTailCall, SDOperand Callee, ArgListTy &Args, |
| 48 | SelectionDAG &DAG); |
| 49 | |
| 50 | }; |
| 51 | |
| 52 | } |
| 53 | |
| 54 | ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) |
| 55 | : TargetLowering(TM) { |
| 56 | setOperationAction(ISD::RET, MVT::Other, Custom); |
| 57 | } |
| 58 | |
| 59 | std::pair<SDOperand, SDOperand> |
| 60 | ARMTargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, |
| 61 | bool isVarArg, unsigned CC, |
| 62 | bool isTailCall, SDOperand Callee, |
| 63 | ArgListTy &Args, SelectionDAG &DAG) { |
| 64 | assert(0 && "Not implemented"); |
| 65 | } |
| 66 | |
| 67 | static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { |
| 68 | SDOperand Copy; |
| 69 | switch(Op.getNumOperands()) { |
| 70 | default: |
| 71 | assert(0 && "Do not know how to return this many arguments!"); |
| 72 | abort(); |
| 73 | case 1: |
| 74 | return SDOperand(); // ret void is legal |
| 75 | case 2: |
| 76 | Copy = DAG.getCopyToReg(Op.getOperand(0), ARM::R0, Op.getOperand(1), SDOperand()); |
| 77 | break; |
| 78 | } |
| 79 | |
| 80 | return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); |
| 81 | } |
| 82 | |
| 83 | SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { |
| 84 | switch (Op.getOpcode()) { |
| 85 | default: |
| 86 | assert(0 && "Should not custom lower this!"); |
| 87 | case ISD::RET: |
| 88 | return LowerRET(Op, DAG); |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | //===----------------------------------------------------------------------===// |
| 93 | // Instruction Selector Implementation |
| 94 | //===----------------------------------------------------------------------===// |
| 95 | |
| 96 | //===--------------------------------------------------------------------===// |
| 97 | /// ARMDAGToDAGISel - ARM specific code to select ARM machine |
| 98 | /// instructions for SelectionDAG operations. |
| 99 | /// |
| 100 | namespace { |
| 101 | class ARMDAGToDAGISel : public SelectionDAGISel { |
| 102 | ARMTargetLowering Lowering; |
| 103 | |
| 104 | public: |
| 105 | ARMDAGToDAGISel(TargetMachine &TM) |
| 106 | : SelectionDAGISel(Lowering), Lowering(TM) { |
| 107 | } |
| 108 | |
| 109 | void Select(SDOperand &Result, SDOperand Op); |
| 110 | virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); |
| 111 | |
| 112 | // Include the pieces autogenerated from the target description. |
| 113 | #include "ARMGenDAGISel.inc" |
| 114 | }; |
| 115 | |
| 116 | void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { |
| 117 | DEBUG(BB->dump()); |
| 118 | |
| 119 | DAG.setRoot(SelectRoot(DAG.getRoot())); |
| 120 | CodeGenMap.clear(); |
| 121 | DAG.RemoveDeadNodes(); |
| 122 | |
| 123 | ScheduleAndEmitDAG(DAG); |
| 124 | } |
| 125 | |
| 126 | void ARMDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) { |
| 127 | SelectCode(Result, Op); |
| 128 | } |
| 129 | |
| 130 | } // end anonymous namespace |
| 131 | |
| 132 | /// createARMISelDag - This pass converts a legalized DAG into a |
| 133 | /// ARM-specific DAG, ready for instruction scheduling. |
| 134 | /// |
| 135 | FunctionPass *llvm::createARMISelDag(TargetMachine &TM) { |
| 136 | return new ARMDAGToDAGISel(TM); |
| 137 | } |