blob: 15a28f22ab8bb5c4b77a3998f316732782dd9c09 [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) {
Chris Lattner4b486312005-12-17 08:15:09 +0000142 if (Op.getValueType() == MVT::i64) {
143 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
144 DAG.getConstant(1, MVT::i32));
145 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
146 DAG.getConstant(0, MVT::i32));
147 return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
148 } else {
149 return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
150 }
Chris Lattner6c18b102005-12-17 07:47:01 +0000151}
152
153SDOperand SparcV8TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
154 Value *VAListV, SelectionDAG &DAG) {
155 assert(0 && "Unimp");
156 abort();
157}
158
159std::pair<SDOperand,SDOperand>
160SparcV8TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
161 const Type *ArgTy, SelectionDAG &DAG) {
162 assert(0 && "Unimp");
163 abort();
164}
165
166std::pair<SDOperand, SDOperand>
167SparcV8TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
168 SelectionDAG &DAG) {
169 assert(0 && "Unimp");
170 abort();
171}
172
173//===----------------------------------------------------------------------===//
174// Instruction Selector Implementation
175//===----------------------------------------------------------------------===//
176
177//===--------------------------------------------------------------------===//
178/// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine
179/// instructions for SelectionDAG operations.
180///
181namespace {
182class SparcV8DAGToDAGISel : public SelectionDAGISel {
183 SparcV8TargetLowering V8Lowering;
184public:
185 SparcV8DAGToDAGISel(TargetMachine &TM)
186 : SelectionDAGISel(V8Lowering), V8Lowering(TM) {}
187
188 SDOperand Select(SDOperand Op);
189
190 /// InstructionSelectBasicBlock - This callback is invoked by
191 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
192 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
193
194 virtual const char *getPassName() const {
195 return "PowerPC DAG->DAG Pattern Instruction Selection";
196 }
197
198 // Include the pieces autogenerated from the target description.
199#include "SparcV8GenDAGISel.inc"
200};
201} // end anonymous namespace
202
203/// InstructionSelectBasicBlock - This callback is invoked by
204/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
205void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
206 DEBUG(BB->dump());
207
208 // Select target instructions for the DAG.
209 DAG.setRoot(Select(DAG.getRoot()));
210 CodeGenMap.clear();
211 DAG.RemoveDeadNodes();
212
213 // Emit machine code to BB.
214 ScheduleAndEmitDAG(DAG);
215}
216
217
218SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
219 SDNode *N = Op.Val;
220 if (N->getOpcode() >= ISD::BUILTIN_OP_END/* &&
221 N->getOpcode() < V8ISD::FIRST_NUMBER*/)
222 return Op; // Already selected.
223 // If this has already been converted, use it.
224 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
225 if (CGMI != CodeGenMap.end()) return CGMI->second;
226
227 switch (N->getOpcode()) {
228 default: break;
Chris Lattner4b486312005-12-17 08:15:09 +0000229 case ISD::RET: {
230 if (N->getNumOperands() == 2) {
231 SDOperand Chain = Select(N->getOperand(0)); // Token chain.
232 SDOperand Val = Select(N->getOperand(1));
233 if (N->getOperand(1).getValueType() == MVT::i32) {
234 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val);
235 } else if (N->getOperand(1).getValueType() == MVT::f32) {
236 Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val);
237 } else {
238 assert(N->getOperand(1).getValueType() == MVT::f64);
239 Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val);
240 }
241 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
242 } else if (N->getNumOperands() > 1) {
243 SDOperand Chain = Select(N->getOperand(0)); // Token chain.
244 assert(N->getOperand(1).getValueType() == MVT::i32 &&
245 N->getOperand(2).getValueType() == MVT::i32 &&
246 N->getNumOperands() == 3 && "Unknown two-register ret value!");
247 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(1)));
248 Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(2)));
249 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
250 }
251 break; // Generated code handles the void case.
252 }
Chris Lattner6c18b102005-12-17 07:47:01 +0000253 }
254
255 return SelectCode(Op);
256}
257
258
259/// createPPCISelDag - This pass converts a legalized DAG into a
260/// PowerPC-specific DAG, ready for instruction scheduling.
261///
262FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) {
263 return new SparcV8DAGToDAGISel(TM);
264}