blob: c2a6a963e0b0bb5ffa240cb6018f9a465cc92d80 [file] [log] [blame]
Chris Lattner5930d3d2005-11-16 22:59:19 +00001//===- X86ISelDAGToDAG.cpp - A DAG pattern matching inst selector for X86 -===//
Chris Lattner655e7df2005-11-16 01:54:32 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the Evan Cheng and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a DAG pattern matching instruction selector for X86,
11// converting from a legalized dag to a X86 dag.
12//
13//===----------------------------------------------------------------------===//
14
15#include "X86.h"
16#include "X86Subtarget.h"
17#include "X86ISelLowering.h"
18#include "llvm/CodeGen/MachineFunction.h"
19#include "llvm/CodeGen/SelectionDAGISel.h"
20#include "llvm/Target/TargetMachine.h"
21#include "llvm/Support/Debug.h"
22#include "llvm/ADT/Statistic.h"
23using namespace llvm;
24
25//===----------------------------------------------------------------------===//
26// Pattern Matcher Implementation
27//===----------------------------------------------------------------------===//
28
29namespace {
30 Statistic<>
31 NumFPKill("x86-codegen", "Number of FP_REG_KILL instructions added");
32
33 //===--------------------------------------------------------------------===//
34 /// ISel - X86 specific code to select X86 machine instructions for
35 /// SelectionDAG operations.
36 ///
37 class X86DAGToDAGISel : public SelectionDAGISel {
38 /// ContainsFPCode - Every instruction we select that uses or defines a FP
39 /// register should set this to true.
40 bool ContainsFPCode;
41
42 /// X86Lowering - This object fully describes how to lower LLVM code to an
43 /// X86-specific SelectionDAG.
44 X86TargetLowering X86Lowering;
45
46 /// Subtarget - Keep a pointer to the X86Subtarget around so that we can
47 /// make the right decision when generating code for different targets.
48 const X86Subtarget *Subtarget;
49 public:
50 X86DAGToDAGISel(TargetMachine &TM)
51 : SelectionDAGISel(X86Lowering), X86Lowering(TM) {
52 Subtarget = &TM.getSubtarget<X86Subtarget>();
53 }
54
55 virtual const char *getPassName() const {
56 return "X86 DAG->DAG Instruction Selection";
57 }
58
59 /// InstructionSelectBasicBlock - This callback is invoked by
60 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
61 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
62
63// Include the pieces autogenerated from the target description.
64#include "X86GenDAGISel.inc"
65
66 private:
67 SDOperand Select(SDOperand N);
68
69 /// getI16Imm - Return a target constant with the specified value, of type
70 /// i16.
71 inline SDOperand getI16Imm(unsigned Imm) {
72 return CurDAG->getTargetConstant(Imm, MVT::i16);
73 }
74
75 /// getI32Imm - Return a target constant with the specified value, of type
76 /// i32.
77 inline SDOperand getI32Imm(unsigned Imm) {
78 return CurDAG->getTargetConstant(Imm, MVT::i32);
79 }
80 };
81}
82
83/// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
84/// when it has created a SelectionDAG for us to codegen.
85void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
86 DEBUG(BB->dump());
87
88 // Codegen the basic block.
89 DAG.setRoot(Select(DAG.getRoot()));
90 DAG.RemoveDeadNodes();
91
92 // Emit machine code to BB.
93 ScheduleAndEmitDAG(DAG);
94}
95
96SDOperand X86DAGToDAGISel::Select(SDOperand Op) {
97 SDNode *N = Op.Val;
98 MVT::ValueType OpVT = Op.getValueType();
99 unsigned Opc;
100
101 if (N->getOpcode() >= ISD::BUILTIN_OP_END)
102 return Op; // Already selected.
103
104 switch (N->getOpcode()) {
105 default: break;
Chris Lattner655e7df2005-11-16 01:54:32 +0000106 case ISD::RET: {
107 SDOperand Chain = Select(N->getOperand(0)); // Token chain.
108 switch (N->getNumOperands()) {
109 default:
110 assert(0 && "Unknown return instruction!");
111 case 3:
112 assert(0 && "Not yet handled return instruction!");
113 break;
114 case 2: {
115 SDOperand Val = Select(N->getOperand(1));
116 switch (N->getOperand(1).getValueType()) {
117 default:
118 assert(0 && "All other types should have been promoted!!");
119 case MVT::i32:
120 Chain = CurDAG->getCopyToReg(Chain, X86::EAX, Val);
121 break;
122 case MVT::f32:
123 case MVT::f64:
124 assert(0 && "Not yet handled return instruction!");
125 break;
126 }
127 }
128 case 1:
129 break;
130 }
131 if (X86Lowering.getBytesToPopOnReturn() == 0)
132 CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain);
133 else
134 CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain,
135 getI16Imm(X86Lowering.getBytesToPopOnReturn()));
136
137 return SDOperand(N, 0);
138 }
139 }
140
141 return SelectCode(Op);
142}
143
144/// createX86ISelDag - This pass converts a legalized DAG into a
145/// X86-specific DAG, ready for instruction scheduling.
146///
147FunctionPass *llvm::createX86ISelDag(TargetMachine &TM) {
148 return new X86DAGToDAGISel(TM);
149}