radeon/llvm: Move lowering of ABS_i32 to ISel
[mesa.git] / src / gallium / drivers / radeon / 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
28 SDValue AMDGPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
29 const
30 {
31 switch (Op.getOpcode()) {
32 default: return AMDILTargetLowering::LowerOperation(Op, DAG);
33 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
34 }
35 }
36
37 SDValue AMDGPUTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
38 SelectionDAG &DAG) const
39 {
40 unsigned IntrinsicID = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
41 DebugLoc DL = Op.getDebugLoc();
42 EVT VT = Op.getValueType();
43
44 switch (IntrinsicID) {
45 default: return Op;
46 case AMDGPUIntrinsic::AMDIL_abs:
47 return LowerIntrinsicIABS(Op, DAG);
48 case AMDGPUIntrinsic::AMDIL_max:
49 return DAG.getNode(AMDGPUISD::FMAX, DL, VT, Op.getOperand(1),
50 Op.getOperand(2));
51 case AMDGPUIntrinsic::AMDGPU_imax:
52 return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Op.getOperand(1),
53 Op.getOperand(2));
54 case AMDGPUIntrinsic::AMDGPU_umax:
55 return DAG.getNode(AMDGPUISD::UMAX, DL, VT, Op.getOperand(1),
56 Op.getOperand(2));
57 }
58 }
59
60 ///IABS(a) = SMAX(sub(0, a), a)
61 SDValue AMDGPUTargetLowering::LowerIntrinsicIABS(SDValue Op,
62 SelectionDAG &DAG) const
63 {
64
65 DebugLoc DL = Op.getDebugLoc();
66 EVT VT = Op.getValueType();
67 SDValue Neg = DAG.getNode(ISD::SUB, DL, VT, DAG.getConstant(0, VT),
68 Op.getOperand(1));
69
70 return DAG.getNode(AMDGPUISD::SMAX, DL, VT, Neg, Op.getOperand(1));
71 }
72
73 void AMDGPUTargetLowering::addLiveIn(MachineInstr * MI,
74 MachineFunction * MF, MachineRegisterInfo & MRI,
75 const TargetInstrInfo * TII, unsigned reg) const
76 {
77 AMDGPU::utilAddLiveIn(MF, MRI, TII, reg, MI->getOperand(0).getReg());
78 }
79
80 #define NODE_NAME_CASE(node) case AMDGPUISD::node: return #node;
81
82 const char* AMDGPUTargetLowering::getTargetNodeName(unsigned Opcode) const
83 {
84 switch (Opcode) {
85 default: return AMDILTargetLowering::getTargetNodeName(Opcode);
86
87 NODE_NAME_CASE(FMAX)
88 NODE_NAME_CASE(SMAX)
89 NODE_NAME_CASE(UMAX)
90 }
91 }