blob: 35db9297f74b7505e69a633c6cee5c3eadfd9b9a [file] [log] [blame]
Chris Lattner655e7df2005-11-16 01:54:32 +00001//===-- X86ISelPattern.cpp - A DAG pattern matching inst selector for X86 -===//
2//
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;
106 case ISD::Constant: {
107 switch (OpVT) {
108 default: assert(0 && "Cannot use constants of this type!");
109 case MVT::i1:
110 case MVT::i8: Opc = X86::MOV8ri; break;
111 case MVT::i16: Opc = X86::MOV16ri; break;
112 case MVT::i32: Opc = X86::MOV32ri; break;
113 }
114 unsigned CVal = cast<ConstantSDNode>(N)->getValue();
115 SDOperand Op1 = CurDAG->getTargetConstant(CVal, OpVT);
116 CurDAG->SelectNodeTo(N, Opc, OpVT, Op1);
117 return Op;
118 }
119
120 case ISD::RET: {
121 SDOperand Chain = Select(N->getOperand(0)); // Token chain.
122 switch (N->getNumOperands()) {
123 default:
124 assert(0 && "Unknown return instruction!");
125 case 3:
126 assert(0 && "Not yet handled return instruction!");
127 break;
128 case 2: {
129 SDOperand Val = Select(N->getOperand(1));
130 switch (N->getOperand(1).getValueType()) {
131 default:
132 assert(0 && "All other types should have been promoted!!");
133 case MVT::i32:
134 Chain = CurDAG->getCopyToReg(Chain, X86::EAX, Val);
135 break;
136 case MVT::f32:
137 case MVT::f64:
138 assert(0 && "Not yet handled return instruction!");
139 break;
140 }
141 }
142 case 1:
143 break;
144 }
145 if (X86Lowering.getBytesToPopOnReturn() == 0)
146 CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain);
147 else
148 CurDAG->SelectNodeTo(N, X86::RET, MVT::Other, Chain,
149 getI16Imm(X86Lowering.getBytesToPopOnReturn()));
150
151 return SDOperand(N, 0);
152 }
153 }
154
155 return SelectCode(Op);
156}
157
158/// createX86ISelDag - This pass converts a legalized DAG into a
159/// X86-specific DAG, ready for instruction scheduling.
160///
161FunctionPass *llvm::createX86ISelDag(TargetMachine &TM) {
162 return new X86DAGToDAGISel(TM);
163}