AMDGPU: Add core backend files for R600/SI codegen v6
[oota-llvm.git] / lib / Target / AMDGPU / AMDGPUISelLowering.cpp
1 //===-- AMDGPUISelLowering.cpp - AMDGPU Common DAG lowering functions -----===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This is the parent TargetLowering class for hardware code gen targets.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "AMDGPUISelLowering.h"
15 #include "AMDILIntrinsicInfo.h"
16 #include "AMDGPUUtil.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18
19 using namespace llvm;
20
21 AMDGPUTargetLowering::AMDGPUTargetLowering(TargetMachine &TM) :
22   AMDILTargetLowering(TM)
23 {
24   // We need to custom lower some of the intrinsics
25   setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
26
27   setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
28   setOperationAction(ISD::SELECT_CC, MVT::i32, Custom);
29
30   // Library functions.  These default to Expand, but we have instructions
31   // for them.
32   setOperationAction(ISD::FCEIL,  MVT::f32, Legal);
33   setOperationAction(ISD::FEXP2,  MVT::f32, Legal);
34   setOperationAction(ISD::FRINT,  MVT::f32, Legal);
35
36   setOperationAction(ISD::UDIV, MVT::i32, Expand);
37   setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
38   setOperationAction(ISD::UREM, MVT::i32, Expand);
39 }
40
41 SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
42     const
43 {
44   switch (Op.getOpcode()) {
45   default: return AMDILTargetLowering::LowerOperation(Op, DAG);
46   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
47   case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
48   case ISD::UDIVREM: return LowerUDIVREM(Op, DAG);
49   }
50 }
51
52 SDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
53     SelectionDAG &DAG) const
54 {
55   unsigned IntrinsicID = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
56   DebugLoc DL = Op.getDebugLoc();
57   EVT VT = Op.getValueType();
58
59   switch (IntrinsicID) {
60     default: return Op;
61     case AMDGPUIntrinsic::AMDIL_abs:
62       return LowerIntrinsicIABS(Op, DAG);
63     case AMDGPUIntrinsic::AMDIL_exp:
64       return DAG.getNode(ISD::FEXP2, DL, VT, Op.getOperand(1));
65     case AMDGPUIntrinsic::AMDIL_fabs:
66       return DAG.getNode(ISD::FABS, DL, VT, Op.getOperand(1));
67     case AMDGPUIntrinsic::AMDGPU_lrp:
68       return LowerIntrinsicLRP(Op, DAG);
69     case AMDGPUIntrinsic::AMDIL_fraction:
70       return DAG.getNode(AMDGPUISD::FRACT, DL, VT, Op.getOperand(1));
71     case AMDGPUIntrinsic::AMDIL_mad:
72       return DAG.getNode(AMDILISD::MAD, DL, VT, Op.getOperand(1),
73                               Op.getOperand(2), Op.getOperand(3));
74     case AMDGPUIntrinsic::AMDIL_max:
75       return DAG.getNode(AMDGPUISD::FMAX, DL, VT, Op.getOperand(1),
76                                                   Op.getOperand(2));
77     case AMDGPUIntrinsic::AMDGPU_imax:
78       return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Op.getOperand(1),
79                                                   Op.getOperand(2));
80     case AMDGPUIntrinsic::AMDGPU_umax:
81       return DAG.getNode(AMDGPUISD::UMAX, DL, VT, Op.getOperand(1),
82                                                   Op.getOperand(2));
83     case AMDGPUIntrinsic::AMDIL_min:
84       return DAG.getNode(AMDGPUISD::FMIN, DL, VT, Op.getOperand(1),
85                                                   Op.getOperand(2));
86     case AMDGPUIntrinsic::AMDGPU_imin:
87       return DAG.getNode(AMDGPUISD::SMIN, DL, VT, Op.getOperand(1),
88                                                   Op.getOperand(2));
89     case AMDGPUIntrinsic::AMDGPU_umin:
90       return DAG.getNode(AMDGPUISD::UMIN, DL, VT, Op.getOperand(1),
91                                                   Op.getOperand(2));
92     case AMDGPUIntrinsic::AMDIL_round_nearest:
93       return DAG.getNode(ISD::FRINT, DL, VT, Op.getOperand(1));
94     case AMDGPUIntrinsic::AMDIL_round_posinf:
95       return DAG.getNode(ISD::FCEIL, DL, VT, Op.getOperand(1));
96   }
97 }
98
99 ///IABS(a) = SMAX(sub(0, a), a)
100 SDValue AMDGPUTargetLowering::LowerIntrinsicIABS(SDValue Op,
101     SelectionDAG &DAG) const
102 {
103
104   DebugLoc DL = Op.getDebugLoc();
105   EVT VT = Op.getValueType();
106   SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
107                                               Op.getOperand(1));
108
109   return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Neg, Op.getOperand(1));
110 }
111
112 /// Linear Interpolation
113 /// LRP(a, b, c) = muladd(a,  b, (1 - a) * c)
114 SDValue AMDGPUTargetLowering::LowerIntrinsicLRP(SDValue Op,
115     SelectionDAG &DAG) const
116 {
117   DebugLoc DL = Op.getDebugLoc();
118   EVT VT = Op.getValueType();
119   SDValue OneSubA = DAG.getNode(ISD::FSUB, DL, VT,
120                                 DAG.getConstantFP(1.0f, MVT::f32),
121                                 Op.getOperand(1));
122   SDValue OneSubAC = DAG.getNode(ISD::FMUL, DL, VT, OneSubA,
123                                                     Op.getOperand(3));
124   return DAG.getNode(AMDILISD::MAD, DL, VT, Op.getOperand(1),
125                                                Op.getOperand(2),
126                                                OneSubAC);
127 }
128
129 SDValue AMDGPUTargetLowering::LowerSELECT_CC(SDValue Op,
130     SelectionDAG &DAG) const
131 {
132   DebugLoc DL = Op.getDebugLoc();
133   EVT VT = Op.getValueType();
134
135   SDValue LHS = Op.getOperand(0);
136   SDValue RHS = Op.getOperand(1);
137   SDValue True = Op.getOperand(2);
138   SDValue False = Op.getOperand(3);
139   SDValue CC = Op.getOperand(4);
140   ISD::CondCode CCOpcode = cast<CondCodeSDNode>(CC)->get();
141   SDValue Temp;
142
143   // LHS and RHS are guaranteed to be the same value type
144   EVT CompareVT = LHS.getValueType();
145
146   // We need all the operands of SELECT_CC to have the same value type, so if
147   // necessary we need to convert LHS and RHS to be the same type True and
148   // False.  True and False are guaranteed to have the same type as this
149   // SELECT_CC node.
150
151   if (CompareVT !=  VT) {
152     ISD::NodeType ConversionOp = ISD::DELETED_NODE;
153     if (VT == MVT::f32 && CompareVT == MVT::i32) {
154       if (isUnsignedIntSetCC(CCOpcode)) {
155         ConversionOp = ISD::UINT_TO_FP;
156       } else {
157         ConversionOp = ISD::SINT_TO_FP;
158       }
159     } else if (VT == MVT::i32 && CompareVT == MVT::f32) {
160       ConversionOp = ISD::FP_TO_SINT;
161     } else {
162       // I don't think there will be any other type pairings.
163       assert(!"Unhandled operand type parings in SELECT_CC");
164     }
165     // XXX Check the value of LHS and RHS and avoid creating sequences like
166     // (FTOI (ITOF))
167     LHS = DAG.getNode(ConversionOp, DL, VT, LHS);
168     RHS = DAG.getNode(ConversionOp, DL, VT, RHS);
169   }
170
171   // If True is a hardware TRUE value and False is a hardware FALSE value or
172   // vice-versa we can handle this with a native instruction (SET* instructions).
173   if ((isHWTrueValue(True) && isHWFalseValue(False))) {
174     return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC);
175   }
176
177   // XXX If True is a hardware TRUE value and False is a hardware FALSE value,
178   // we can handle this with a native instruction, but we need to swap true
179   // and false and change the conditional.
180   if (isHWTrueValue(False) && isHWFalseValue(True)) {
181   }
182
183   // XXX Check if we can lower this to a SELECT or if it is supported by a native
184   // operation. (The code below does this but we don't have the Instruction
185   // selection patterns to do this yet.
186 #if 0
187   if (isZero(LHS) || isZero(RHS)) {
188     SDValue Cond = (isZero(LHS) ? RHS : LHS);
189     bool SwapTF = false;
190     switch (CCOpcode) {
191     case ISD::SETOEQ:
192     case ISD::SETUEQ:
193     case ISD::SETEQ:
194       SwapTF = true;
195       // Fall through
196     case ISD::SETONE:
197     case ISD::SETUNE:
198     case ISD::SETNE:
199       // We can lower to select
200       if (SwapTF) {
201         Temp = True;
202         True = False;
203         False = Temp;
204       }
205       // CNDE
206       return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False);
207     default:
208       // Supported by a native operation (CNDGE, CNDGT)
209       return DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, True, False, CC);
210     }
211   }
212 #endif
213
214   // If we make it this for it means we have no native instructions to handle
215   // this SELECT_CC, so we must lower it.
216   SDValue HWTrue, HWFalse;
217
218   if (VT == MVT::f32) {
219     HWTrue = DAG.getConstantFP(1.0f, VT);
220     HWFalse = DAG.getConstantFP(0.0f, VT);
221   } else if (VT == MVT::i32) {
222     HWTrue = DAG.getConstant(-1, VT);
223     HWFalse = DAG.getConstant(0, VT);
224   }
225   else {
226     assert(!"Unhandled value type in LowerSELECT_CC");
227   }
228
229   // Lower this unsupported SELECT_CC into a combination of two supported
230   // SELECT_CC operations.
231   SDValue Cond = DAG.getNode(ISD::SELECT_CC, DL, VT, LHS, RHS, HWTrue, HWFalse, CC);
232
233   return DAG.getNode(ISD::SELECT, DL, VT, Cond, True, False);
234 }
235
236
237 SDValue AMDGPUTargetLowering::LowerUDIVREM(SDValue Op,
238     SelectionDAG &DAG) const
239 {
240   DebugLoc DL = Op.getDebugLoc();
241   EVT VT = Op.getValueType();
242
243   SDValue Num = Op.getOperand(0);
244   SDValue Den = Op.getOperand(1);
245
246   SmallVector<SDValue, 8> Results;
247
248   // RCP =  URECIP(Den) = 2^32 / Den + e
249   // e is rounding error.
250   SDValue RCP = DAG.getNode(AMDGPUISD::URECIP, DL, VT, Den);
251
252   // RCP_LO = umulo(RCP, Den) */
253   SDValue RCP_LO = DAG.getNode(ISD::UMULO, DL, VT, RCP, Den);
254
255   // RCP_HI = mulhu (RCP, Den) */
256   SDValue RCP_HI = DAG.getNode(ISD::MULHU, DL, VT, RCP, Den);
257
258   // NEG_RCP_LO = -RCP_LO
259   SDValue NEG_RCP_LO = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
260                                                      RCP_LO);
261
262   // ABS_RCP_LO = (RCP_HI == 0 ? NEG_RCP_LO : RCP_LO)
263   SDValue ABS_RCP_LO = DAG.getSelectCC(DL, RCP_HI, DAG.getConstant(0, VT),
264                                            NEG_RCP_LO, RCP_LO,
265                                            ISD::SETEQ);
266   // Calculate the rounding error from the URECIP instruction
267   // E = mulhu(ABS_RCP_LO, RCP)
268   SDValue E = DAG.getNode(ISD::MULHU, DL, VT, ABS_RCP_LO, RCP);
269
270   // RCP_A_E = RCP + E
271   SDValue RCP_A_E = DAG.getNode(ISD::ADD, DL, VT, RCP, E);
272
273   // RCP_S_E = RCP - E
274   SDValue RCP_S_E = DAG.getNode(ISD::SUB, DL, VT, RCP, E);
275
276   // Tmp0 = (RCP_HI == 0 ? RCP_A_E : RCP_SUB_E)
277   SDValue Tmp0 = DAG.getSelectCC(DL, RCP_HI, DAG.getConstant(0, VT),
278                                      RCP_A_E, RCP_S_E,
279                                      ISD::SETEQ);
280   // Quotient = mulhu(Tmp0, Num)
281   SDValue Quotient = DAG.getNode(ISD::MULHU, DL, VT, Tmp0, Num);
282
283   // Num_S_Remainder = Quotient * Den
284   SDValue Num_S_Remainder = DAG.getNode(ISD::UMULO, DL, VT, Quotient, Den);
285
286   // Remainder = Num - Num_S_Remainder
287   SDValue Remainder = DAG.getNode(ISD::SUB, DL, VT, Num, Num_S_Remainder);
288
289   // Remainder_GE_Den = (Remainder >= Den ? -1 : 0)
290   SDValue Remainder_GE_Den = DAG.getSelectCC(DL, Remainder, Den,
291                                                  DAG.getConstant(-1, VT),
292                                                  DAG.getConstant(0, VT),
293                                                  ISD::SETGE);
294   // Remainder_GE_Zero = (Remainder >= 0 ? -1 : 0)
295   SDValue Remainder_GE_Zero = DAG.getSelectCC(DL, Remainder,
296                                                   DAG.getConstant(0, VT),
297                                                   DAG.getConstant(-1, VT),
298                                                   DAG.getConstant(0, VT),
299                                                   ISD::SETGE);
300   // Tmp1 = Remainder_GE_Den & Remainder_GE_Zero
301   SDValue Tmp1 = DAG.getNode(ISD::AND, DL, VT, Remainder_GE_Den,
302                                                Remainder_GE_Zero);
303
304   // Calculate Division result:
305
306   // Quotient_A_One = Quotient + 1
307   SDValue Quotient_A_One = DAG.getNode(ISD::ADD, DL, VT, Quotient,
308                                                          DAG.getConstant(1, VT));
309
310   // Quotient_S_One = Quotient - 1
311   SDValue Quotient_S_One = DAG.getNode(ISD::SUB, DL, VT, Quotient,
312                                                          DAG.getConstant(1, VT));
313
314   // Div = (Tmp1 == 0 ? Quotient : Quotient_A_One)
315   SDValue Div = DAG.getSelectCC(DL, Tmp1, DAG.getConstant(0, VT),
316                                      Quotient, Quotient_A_One, ISD::SETEQ);
317
318   // Div = (Remainder_GE_Zero == 0 ? Quotient_S_One : Div)
319   Div = DAG.getSelectCC(DL, Remainder_GE_Zero, DAG.getConstant(0, VT),
320                             Quotient_S_One, Div, ISD::SETEQ);
321
322   // Calculate Rem result:
323
324   // Remainder_S_Den = Remainder - Den
325   SDValue Remainder_S_Den = DAG.getNode(ISD::SUB, DL, VT, Remainder, Den);
326
327   // Remainder_A_Den = Remainder + Den
328   SDValue Remainder_A_Den = DAG.getNode(ISD::ADD, DL, VT, Remainder, Den);
329
330   // Rem = (Tmp1 == 0 ? Remainder : Remainder_S_Den)
331   SDValue Rem = DAG.getSelectCC(DL, Tmp1, DAG.getConstant(0, VT),
332                                     Remainder, Remainder_S_Den, ISD::SETEQ);
333
334   // Rem = (Remainder_GE_Zero == 0 ? Remainder_A_Den : Rem)
335   Rem = DAG.getSelectCC(DL, Remainder_GE_Zero, DAG.getConstant(0, VT),
336                             Remainder_A_Den, Rem, ISD::SETEQ);
337
338   DAG.ReplaceAllUsesWith(Op.getValue(0).getNode(), &Div);
339   DAG.ReplaceAllUsesWith(Op.getValue(1).getNode(), &Rem);
340
341   return Op;
342 }
343
344 //===----------------------------------------------------------------------===//
345 // Helper functions
346 //===----------------------------------------------------------------------===//
347
348 bool AMDGPUTargetLowering::isHWTrueValue(SDValue Op) const
349 {
350   if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
351     return CFP->isExactlyValue(1.0);
352   }
353   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
354     return C->isAllOnesValue();
355   }
356   return false;
357 }
358
359 bool AMDGPUTargetLowering::isHWFalseValue(SDValue Op) const
360 {
361   if (ConstantFPSDNode * CFP = dyn_cast<ConstantFPSDNode>(Op)) {
362     return CFP->getValueAPF().isZero();
363   }
364   if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
365     return C->isNullValue();
366   }
367   return false;
368 }
369
370 void AMDGPUTargetLowering::addLiveIn(MachineInstr * MI,
371     MachineFunction * MF, MachineRegisterInfo & MRI,
372     const TargetInstrInfo * TII, unsigned reg) const
373 {
374   AMDGPU::utilAddLiveIn(MF, MRI, TII, reg, MI->getOperand(0).getReg());
375 }
376
377 #define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
378
379 const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const
380 {
381   switch (Opcode) {
382   default: return AMDILTargetLowering::getTargetNodeName(Opcode);
383
384   NODE_NAME_CASE(FRACT)
385   NODE_NAME_CASE(FMAX)
386   NODE_NAME_CASE(SMAX)
387   NODE_NAME_CASE(UMAX)
388   NODE_NAME_CASE(FMIN)
389   NODE_NAME_CASE(SMIN)
390   NODE_NAME_CASE(UMIN)
391   NODE_NAME_CASE(URECIP)
392   }
393 }