blob: fcc07c29f5b01711dd544f1ddc2b77eff8038f78 [file] [log] [blame]
Chris Lattner6c18b102005-12-17 07:47:01 +00001//===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===//
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 V8 target
11//
12//===----------------------------------------------------------------------===//
13
14#include "SparcV8.h"
15#include "SparcV8TargetMachine.h"
Chris Lattnera01b7572005-12-17 08:03:24 +000016#include "llvm/Function.h"
17#include "llvm/CodeGen/MachineFunction.h"
Chris Lattner6c18b102005-12-17 07:47:01 +000018#include "llvm/CodeGen/SelectionDAG.h"
19#include "llvm/CodeGen/SelectionDAGISel.h"
Chris Lattnera01b7572005-12-17 08:03:24 +000020#include "llvm/CodeGen/SSARegMap.h"
Chris Lattner6c18b102005-12-17 07:47:01 +000021#include "llvm/Target/TargetLowering.h"
22#include "llvm/Support/Debug.h"
23#include <iostream>
24using namespace llvm;
25
26//===----------------------------------------------------------------------===//
27// TargetLowering Implementation
28//===----------------------------------------------------------------------===//
29
30namespace {
31 class SparcV8TargetLowering : public TargetLowering {
32 public:
33 SparcV8TargetLowering(TargetMachine &TM);
34
35 virtual std::vector<SDOperand>
36 LowerArguments(Function &F, SelectionDAG &DAG);
37 virtual std::pair<SDOperand, SDOperand>
38 LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
39 unsigned CC,
40 bool isTailCall, SDOperand Callee, ArgListTy &Args,
41 SelectionDAG &DAG);
42
43 virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
44 SelectionDAG &DAG);
45 virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
46 Value *VAListV, SelectionDAG &DAG);
47 virtual std::pair<SDOperand,SDOperand>
48 LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
49 const Type *ArgTy, SelectionDAG &DAG);
50 virtual std::pair<SDOperand, SDOperand>
51 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
52 SelectionDAG &DAG);
53 };
54}
55
56SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
57 : TargetLowering(TM) {
58
59 // Set up the register classes.
60 addRegisterClass(MVT::i32, V8::IntRegsRegisterClass);
61 addRegisterClass(MVT::f32, V8::FPRegsRegisterClass);
62 addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass);
63
64 computeRegisterProperties();
65}
66
67std::vector<SDOperand>
68SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
Chris Lattnera01b7572005-12-17 08:03:24 +000069 MachineFunction &MF = DAG.getMachineFunction();
70 SSARegMap *RegMap = MF.getSSARegMap();
71 std::vector<SDOperand> ArgValues;
72
73 static const unsigned GPR[] = {
74 V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5
75 };
76 unsigned ArgNo = 0;
77 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
78 MVT::ValueType ObjectVT = getValueType(I->getType());
79 assert(ArgNo < 6 && "Only args in regs for now");
80
81 switch (ObjectVT) {
82 default: assert(0 && "Unhandled argument type!");
83 // TODO: MVT::i64 & FP
84 case MVT::i1:
85 case MVT::i8:
86 case MVT::i16:
87 case MVT::i32: {
88 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
89 MF.addLiveIn(GPR[ArgNo++], VReg);
90 SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
91 DAG.setRoot(Arg.getValue(1));
92 if (ObjectVT != MVT::i32) {
93 unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext
94 : ISD::AssertZext;
95 Arg = DAG.getNode(AssertOp, MVT::i32, Arg,
96 DAG.getValueType(ObjectVT));
97 Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg);
98 }
99 ArgValues.push_back(Arg);
100 }
101 }
102 }
103
104 assert(!F.isVarArg() && "Unimp");
105
106 // Finally, inform the code generator which regs we return values in.
107 switch (getValueType(F.getReturnType())) {
108 default: assert(0 && "Unknown type!");
109 case MVT::isVoid: break;
110 case MVT::i1:
111 case MVT::i8:
112 case MVT::i16:
113 case MVT::i32:
114 MF.addLiveOut(V8::I0);
115 break;
116 case MVT::i64:
117 MF.addLiveOut(V8::I0);
118 MF.addLiveOut(V8::I1);
119 break;
120 case MVT::f32:
121 MF.addLiveOut(V8::F0);
122 break;
123 case MVT::f64:
124 MF.addLiveOut(V8::D0);
125 break;
126 }
127
128 return ArgValues;
Chris Lattner6c18b102005-12-17 07:47:01 +0000129}
130
131std::pair<SDOperand, SDOperand>
132SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
133 bool isVarArg, unsigned CC,
134 bool isTailCall, SDOperand Callee,
135 ArgListTy &Args, SelectionDAG &DAG) {
136 assert(0 && "Unimp");
137 abort();
138}
139
140SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
141 SelectionDAG &DAG) {
142 assert(0 && "Unimp");
143 abort();
144}
145
146SDOperand SparcV8TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
147 Value *VAListV, SelectionDAG &DAG) {
148 assert(0 && "Unimp");
149 abort();
150}
151
152std::pair<SDOperand,SDOperand>
153SparcV8TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
154 const Type *ArgTy, SelectionDAG &DAG) {
155 assert(0 && "Unimp");
156 abort();
157}
158
159std::pair<SDOperand, SDOperand>
160SparcV8TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
161 SelectionDAG &DAG) {
162 assert(0 && "Unimp");
163 abort();
164}
165
166//===----------------------------------------------------------------------===//
167// Instruction Selector Implementation
168//===----------------------------------------------------------------------===//
169
170//===--------------------------------------------------------------------===//
171/// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine
172/// instructions for SelectionDAG operations.
173///
174namespace {
175class SparcV8DAGToDAGISel : public SelectionDAGISel {
176 SparcV8TargetLowering V8Lowering;
177public:
178 SparcV8DAGToDAGISel(TargetMachine &TM)
179 : SelectionDAGISel(V8Lowering), V8Lowering(TM) {}
180
181 SDOperand Select(SDOperand Op);
182
183 /// InstructionSelectBasicBlock - This callback is invoked by
184 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
185 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
186
187 virtual const char *getPassName() const {
188 return "PowerPC DAG->DAG Pattern Instruction Selection";
189 }
190
191 // Include the pieces autogenerated from the target description.
192#include "SparcV8GenDAGISel.inc"
193};
194} // end anonymous namespace
195
196/// InstructionSelectBasicBlock - This callback is invoked by
197/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
198void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
199 DEBUG(BB->dump());
200
201 // Select target instructions for the DAG.
202 DAG.setRoot(Select(DAG.getRoot()));
203 CodeGenMap.clear();
204 DAG.RemoveDeadNodes();
205
206 // Emit machine code to BB.
207 ScheduleAndEmitDAG(DAG);
208}
209
210
211SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
212 SDNode *N = Op.Val;
213 if (N->getOpcode() >= ISD::BUILTIN_OP_END/* &&
214 N->getOpcode() < V8ISD::FIRST_NUMBER*/)
215 return Op; // Already selected.
216 // If this has already been converted, use it.
217 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
218 if (CGMI != CodeGenMap.end()) return CGMI->second;
219
220 switch (N->getOpcode()) {
221 default: break;
222 }
223
224 return SelectCode(Op);
225}
226
227
228/// createPPCISelDag - This pass converts a legalized DAG into a
229/// PowerPC-specific DAG, ready for instruction scheduling.
230///
231FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) {
232 return new SparcV8DAGToDAGISel(TM);
233}