1 //===-- AlphaISelDAGToDAG.cpp - Alpha pattern matching inst selector ------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines a pattern matching instruction selector for Alpha,
11 // converting from a legalized dag to a Alpha dag.
13 //===----------------------------------------------------------------------===//
16 #include "AlphaTargetMachine.h"
17 #include "AlphaISelLowering.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 #include "llvm/CodeGen/SelectionDAG.h"
23 #include "llvm/CodeGen/SelectionDAGISel.h"
24 #include "llvm/Target/TargetOptions.h"
25 #include "llvm/Constants.h"
26 #include "llvm/DerivedTypes.h"
27 #include "llvm/GlobalValue.h"
28 #include "llvm/Intrinsics.h"
29 #include "llvm/LLVMContext.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/raw_ostream.h"
40 //===--------------------------------------------------------------------===//
41 /// AlphaDAGToDAGISel - Alpha specific code to select Alpha machine
42 /// instructions for SelectionDAG operations.
43 class AlphaDAGToDAGISel
: public SelectionDAGISel
{
44 static const int64_t IMM_LOW
= -32768;
45 static const int64_t IMM_HIGH
= 32767;
46 static const int64_t IMM_MULT
= 65536;
47 static const int64_t IMM_FULLHIGH
= IMM_HIGH
+ IMM_HIGH
* IMM_MULT
;
48 static const int64_t IMM_FULLLOW
= IMM_LOW
+ IMM_LOW
* IMM_MULT
;
50 static int64_t get_ldah16(int64_t x
) {
51 int64_t y
= x
/ IMM_MULT
;
52 if (x
% IMM_MULT
> IMM_HIGH
)
57 static int64_t get_lda16(int64_t x
) {
58 return x
- get_ldah16(x
) * IMM_MULT
;
61 /// get_zapImm - Return a zap mask if X is a valid immediate for a zapnot
62 /// instruction (if not, return 0). Note that this code accepts partial
63 /// zap masks. For example (and LHS, 1) is a valid zap, as long we know
64 /// that the bits 1-7 of LHS are already zero. If LHS is non-null, we are
65 /// in checking mode. If LHS is null, we assume that the mask has already
66 /// been validated before.
67 uint64_t get_zapImm(SDValue LHS
, uint64_t Constant
) {
68 uint64_t BitsToCheck
= 0;
70 for (unsigned i
= 0; i
!= 8; ++i
) {
71 if (((Constant
>> 8*i
) & 0xFF) == 0) {
75 if (((Constant
>> 8*i
) & 0xFF) == 0xFF) {
76 // If the entire byte is set, zapnot the byte.
77 } else if (LHS
.getNode() == 0) {
78 // Otherwise, if the mask was previously validated, we know its okay
79 // to zapnot this entire byte even though all the bits aren't set.
81 // Otherwise we don't know that the it's okay to zapnot this entire
82 // byte. Only do this iff we can prove that the missing bits are
83 // already null, so the bytezap doesn't need to really null them.
84 BitsToCheck
|= ~Constant
& (0xFF << 8*i
);
89 // If there are missing bits in a byte (for example, X & 0xEF00), check to
90 // see if the missing bits (0x1000) are already known zero if not, the zap
91 // isn't okay to do, as it won't clear all the required bits.
93 !CurDAG
->MaskedValueIsZero(LHS
,
94 APInt(LHS
.getValueSizeInBits(),
101 static uint64_t get_zapImm(uint64_t x
) {
103 for(int i
= 0; i
!= 8; ++i
) {
104 if ((x
& 0x00FF) == 0x00FF)
106 else if ((x
& 0x00FF) != 0)
114 static uint64_t getNearPower2(uint64_t x
) {
116 unsigned at
= CountLeadingZeros_64(x
);
117 uint64_t complow
= 1 << (63 - at
);
118 uint64_t comphigh
= 1 << (64 - at
);
119 //cerr << x << ":" << complow << ":" << comphigh << "\n";
120 if (abs64(complow
- x
) <= abs64(comphigh
- x
))
126 static bool chkRemNearPower2(uint64_t x
, uint64_t r
, bool swap
) {
127 uint64_t y
= getNearPower2(x
);
134 static bool isFPZ(SDValue N
) {
135 ConstantFPSDNode
*CN
= dyn_cast
<ConstantFPSDNode
>(N
);
136 return (CN
&& (CN
->getValueAPF().isZero()));
138 static bool isFPZn(SDValue N
) {
139 ConstantFPSDNode
*CN
= dyn_cast
<ConstantFPSDNode
>(N
);
140 return (CN
&& CN
->getValueAPF().isNegZero());
142 static bool isFPZp(SDValue N
) {
143 ConstantFPSDNode
*CN
= dyn_cast
<ConstantFPSDNode
>(N
);
144 return (CN
&& CN
->getValueAPF().isPosZero());
148 explicit AlphaDAGToDAGISel(AlphaTargetMachine
&TM
)
149 : SelectionDAGISel(TM
)
152 /// getI64Imm - Return a target constant with the specified value, of type
154 inline SDValue
getI64Imm(int64_t Imm
) {
155 return CurDAG
->getTargetConstant(Imm
, MVT::i64
);
158 // Select - Convert the specified operand from a target-independent to a
159 // target-specific node if it hasn't already been changed.
160 SDNode
*Select(SDValue Op
);
162 /// InstructionSelect - This callback is invoked by
163 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
164 virtual void InstructionSelect();
166 virtual const char *getPassName() const {
167 return "Alpha DAG->DAG Pattern Instruction Selection";
170 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
171 /// inline asm expressions.
172 virtual bool SelectInlineAsmMemoryOperand(const SDValue
&Op
,
174 std::vector
<SDValue
> &OutOps
) {
176 switch (ConstraintCode
) {
177 default: return true;
183 OutOps
.push_back(Op0
);
187 // Include the pieces autogenerated from the target description.
188 #include "AlphaGenDAGISel.inc"
191 /// getTargetMachine - Return a reference to the TargetMachine, casted
192 /// to the target-specific type.
193 const AlphaTargetMachine
&getTargetMachine() {
194 return static_cast<const AlphaTargetMachine
&>(TM
);
197 /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
198 /// to the target-specific type.
199 const AlphaInstrInfo
*getInstrInfo() {
200 return getTargetMachine().getInstrInfo();
203 SDNode
*getGlobalBaseReg();
204 SDNode
*getGlobalRetAddr();
205 void SelectCALL(SDValue Op
);
210 /// getGlobalBaseReg - Output the instructions required to put the
211 /// GOT address into a register.
213 SDNode
*AlphaDAGToDAGISel::getGlobalBaseReg() {
214 unsigned GlobalBaseReg
= getInstrInfo()->getGlobalBaseReg(MF
);
215 return CurDAG
->getRegister(GlobalBaseReg
, TLI
.getPointerTy()).getNode();
218 /// getGlobalRetAddr - Grab the return address.
220 SDNode
*AlphaDAGToDAGISel::getGlobalRetAddr() {
221 unsigned GlobalRetAddr
= getInstrInfo()->getGlobalRetAddr(MF
);
222 return CurDAG
->getRegister(GlobalRetAddr
, TLI
.getPointerTy()).getNode();
225 /// InstructionSelect - This callback is invoked by
226 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
227 void AlphaDAGToDAGISel::InstructionSelect() {
230 // Select target instructions for the DAG.
232 CurDAG
->RemoveDeadNodes();
235 // Select - Convert the specified operand from a target-independent to a
236 // target-specific node if it hasn't already been changed.
237 SDNode
*AlphaDAGToDAGISel::Select(SDValue Op
) {
238 SDNode
*N
= Op
.getNode();
239 if (N
->isMachineOpcode()) {
240 return NULL
; // Already selected.
242 DebugLoc dl
= N
->getDebugLoc();
244 switch (N
->getOpcode()) {
250 case ISD::FrameIndex
: {
251 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
252 return CurDAG
->SelectNodeTo(N
, Alpha::LDA
, MVT::i64
,
253 CurDAG
->getTargetFrameIndex(FI
, MVT::i32
),
256 case ISD::GLOBAL_OFFSET_TABLE
:
257 return getGlobalBaseReg();
258 case AlphaISD::GlobalRetAddr
:
259 return getGlobalRetAddr();
261 case AlphaISD::DivCall
: {
262 SDValue Chain
= CurDAG
->getEntryNode();
263 SDValue N0
= Op
.getOperand(0);
264 SDValue N1
= Op
.getOperand(1);
265 SDValue N2
= Op
.getOperand(2);
266 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R24
, N1
,
268 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R25
, N2
,
270 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R27
, N0
,
273 CurDAG
->getTargetNode(Alpha::JSRs
, dl
, MVT::Other
, MVT::Flag
,
274 Chain
, Chain
.getValue(1));
275 Chain
= CurDAG
->getCopyFromReg(Chain
, dl
, Alpha::R27
, MVT::i64
,
277 return CurDAG
->SelectNodeTo(N
, Alpha::BISr
, MVT::i64
, Chain
, Chain
);
280 case ISD::READCYCLECOUNTER
: {
281 SDValue Chain
= N
->getOperand(0);
282 return CurDAG
->getTargetNode(Alpha::RPCC
, dl
, MVT::i64
, MVT::Other
,
286 case ISD::Constant
: {
287 uint64_t uval
= cast
<ConstantSDNode
>(N
)->getZExtValue();
290 SDValue Result
= CurDAG
->getCopyFromReg(CurDAG
->getEntryNode(), dl
,
291 Alpha::R31
, MVT::i64
);
292 ReplaceUses(Op
, Result
);
296 int64_t val
= (int64_t)uval
;
297 int32_t val32
= (int32_t)val
;
298 if (val
<= IMM_HIGH
+ IMM_HIGH
* IMM_MULT
&&
299 val
>= IMM_LOW
+ IMM_LOW
* IMM_MULT
)
300 break; //(LDAH (LDA))
301 if ((uval
>> 32) == 0 && //empty upper bits
302 val32
<= IMM_HIGH
+ IMM_HIGH
* IMM_MULT
)
303 // val32 >= IMM_LOW + IMM_LOW * IMM_MULT) //always true
304 break; //(zext (LDAH (LDA)))
305 //Else use the constant pool
306 ConstantInt
*C
= ConstantInt::get(
307 Type::getInt64Ty(*CurDAG
->getContext()), uval
);
308 SDValue CPI
= CurDAG
->getTargetConstantPool(C
, MVT::i64
);
309 SDNode
*Tmp
= CurDAG
->getTargetNode(Alpha::LDAHr
, dl
, MVT::i64
, CPI
,
310 SDValue(getGlobalBaseReg(), 0));
311 return CurDAG
->SelectNodeTo(N
, Alpha::LDQr
, MVT::i64
, MVT::Other
,
312 CPI
, SDValue(Tmp
, 0), CurDAG
->getEntryNode());
314 case ISD::TargetConstantFP
:
315 case ISD::ConstantFP
: {
316 ConstantFPSDNode
*CN
= cast
<ConstantFPSDNode
>(N
);
317 bool isDouble
= N
->getValueType(0) == MVT::f64
;
318 EVT T
= isDouble
? MVT::f64
: MVT::f32
;
319 if (CN
->getValueAPF().isPosZero()) {
320 return CurDAG
->SelectNodeTo(N
, isDouble
? Alpha::CPYST
: Alpha::CPYSS
,
321 T
, CurDAG
->getRegister(Alpha::F31
, T
),
322 CurDAG
->getRegister(Alpha::F31
, T
));
323 } else if (CN
->getValueAPF().isNegZero()) {
324 return CurDAG
->SelectNodeTo(N
, isDouble
? Alpha::CPYSNT
: Alpha::CPYSNS
,
325 T
, CurDAG
->getRegister(Alpha::F31
, T
),
326 CurDAG
->getRegister(Alpha::F31
, T
));
328 llvm_report_error("Unhandled FP constant type");
334 if (N
->getOperand(0).getNode()->getValueType(0).isFloatingPoint()) {
335 ISD::CondCode CC
= cast
<CondCodeSDNode
>(N
->getOperand(2))->get();
337 unsigned Opc
= Alpha::WTF
;
341 default: DEBUG(N
->dump(CurDAG
)); llvm_unreachable("Unknown FP comparison!");
342 case ISD::SETEQ
: case ISD::SETOEQ
: case ISD::SETUEQ
:
343 Opc
= Alpha::CMPTEQ
; break;
344 case ISD::SETLT
: case ISD::SETOLT
: case ISD::SETULT
:
345 Opc
= Alpha::CMPTLT
; break;
346 case ISD::SETLE
: case ISD::SETOLE
: case ISD::SETULE
:
347 Opc
= Alpha::CMPTLE
; break;
348 case ISD::SETGT
: case ISD::SETOGT
: case ISD::SETUGT
:
349 Opc
= Alpha::CMPTLT
; rev
= true; break;
350 case ISD::SETGE
: case ISD::SETOGE
: case ISD::SETUGE
:
351 Opc
= Alpha::CMPTLE
; rev
= true; break;
352 case ISD::SETNE
: case ISD::SETONE
: case ISD::SETUNE
:
353 Opc
= Alpha::CMPTEQ
; inv
= true; break;
355 Opc
= Alpha::CMPTUN
; inv
= true; break;
357 Opc
= Alpha::CMPTUN
; break;
359 SDValue tmp1
= N
->getOperand(rev
?1:0);
360 SDValue tmp2
= N
->getOperand(rev
?0:1);
361 SDNode
*cmp
= CurDAG
->getTargetNode(Opc
, dl
, MVT::f64
, tmp1
, tmp2
);
363 cmp
= CurDAG
->getTargetNode(Alpha::CMPTEQ
, dl
,
364 MVT::f64
, SDValue(cmp
, 0),
365 CurDAG
->getRegister(Alpha::F31
, MVT::f64
));
367 case ISD::SETUEQ
: case ISD::SETULT
: case ISD::SETULE
:
368 case ISD::SETUNE
: case ISD::SETUGT
: case ISD::SETUGE
:
370 SDNode
* cmp2
= CurDAG
->getTargetNode(Alpha::CMPTUN
, dl
, MVT::f64
,
372 cmp
= CurDAG
->getTargetNode(Alpha::ADDT
, dl
, MVT::f64
,
373 SDValue(cmp2
, 0), SDValue(cmp
, 0));
379 SDNode
* LD
= CurDAG
->getTargetNode(Alpha::FTOIT
, dl
,
380 MVT::i64
, SDValue(cmp
, 0));
381 return CurDAG
->getTargetNode(Alpha::CMPULT
, dl
, MVT::i64
,
382 CurDAG
->getRegister(Alpha::R31
, MVT::i64
),
388 ConstantSDNode
* SC
= NULL
;
389 ConstantSDNode
* MC
= NULL
;
390 if (N
->getOperand(0).getOpcode() == ISD::SRL
&&
391 (MC
= dyn_cast
<ConstantSDNode
>(N
->getOperand(1))) &&
392 (SC
= dyn_cast
<ConstantSDNode
>(N
->getOperand(0).getOperand(1)))) {
393 uint64_t sval
= SC
->getZExtValue();
394 uint64_t mval
= MC
->getZExtValue();
395 // If the result is a zap, let the autogened stuff handle it.
396 if (get_zapImm(N
->getOperand(0), mval
))
398 // given mask X, and shift S, we want to see if there is any zap in the
399 // mask if we play around with the botton S bits
400 uint64_t dontcare
= (~0ULL) >> (64 - sval
);
401 uint64_t mask
= mval
<< sval
;
403 if (get_zapImm(mask
| dontcare
))
404 mask
= mask
| dontcare
;
406 if (get_zapImm(mask
)) {
408 SDValue(CurDAG
->getTargetNode(Alpha::ZAPNOTi
, dl
, MVT::i64
,
409 N
->getOperand(0).getOperand(0),
410 getI64Imm(get_zapImm(mask
))), 0);
411 return CurDAG
->getTargetNode(Alpha::SRLr
, dl
, MVT::i64
, Z
,
420 return SelectCode(Op
);
423 void AlphaDAGToDAGISel::SelectCALL(SDValue Op
) {
424 //TODO: add flag stuff to prevent nondeturministic breakage!
426 SDNode
*N
= Op
.getNode();
427 SDValue Chain
= N
->getOperand(0);
428 SDValue Addr
= N
->getOperand(1);
429 SDValue InFlag
= N
->getOperand(N
->getNumOperands() - 1);
430 DebugLoc dl
= N
->getDebugLoc();
432 if (Addr
.getOpcode() == AlphaISD::GPRelLo
) {
433 SDValue GOT
= SDValue(getGlobalBaseReg(), 0);
434 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R29
, GOT
, InFlag
);
435 InFlag
= Chain
.getValue(1);
436 Chain
= SDValue(CurDAG
->getTargetNode(Alpha::BSR
, dl
, MVT::Other
,
437 MVT::Flag
, Addr
.getOperand(0),
440 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R27
, Addr
, InFlag
);
441 InFlag
= Chain
.getValue(1);
442 Chain
= SDValue(CurDAG
->getTargetNode(Alpha::JSR
, dl
, MVT::Other
,
443 MVT::Flag
, Chain
, InFlag
), 0);
445 InFlag
= Chain
.getValue(1);
447 ReplaceUses(Op
.getValue(0), Chain
);
448 ReplaceUses(Op
.getValue(1), InFlag
);
452 /// createAlphaISelDag - This pass converts a legalized DAG into a
453 /// Alpha-specific DAG, ready for instruction scheduling.
455 FunctionPass
*llvm::createAlphaISelDag(AlphaTargetMachine
&TM
) {
456 return new AlphaDAGToDAGISel(TM
);