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 (abs(complow
- x
) <= abs(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 MachineFunction
*MF
= BB
->getParent();
215 unsigned GlobalBaseReg
= getInstrInfo()->getGlobalBaseReg(MF
);
216 return CurDAG
->getRegister(GlobalBaseReg
, TLI
.getPointerTy()).getNode();
219 /// getGlobalRetAddr - Grab the return address.
221 SDNode
*AlphaDAGToDAGISel::getGlobalRetAddr() {
222 MachineFunction
*MF
= BB
->getParent();
223 unsigned GlobalRetAddr
= getInstrInfo()->getGlobalRetAddr(MF
);
224 return CurDAG
->getRegister(GlobalRetAddr
, TLI
.getPointerTy()).getNode();
227 /// InstructionSelect - This callback is invoked by
228 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
229 void AlphaDAGToDAGISel::InstructionSelect() {
232 // Select target instructions for the DAG.
234 CurDAG
->RemoveDeadNodes();
237 // Select - Convert the specified operand from a target-independent to a
238 // target-specific node if it hasn't already been changed.
239 SDNode
*AlphaDAGToDAGISel::Select(SDValue Op
) {
240 SDNode
*N
= Op
.getNode();
241 if (N
->isMachineOpcode()) {
242 return NULL
; // Already selected.
244 DebugLoc dl
= N
->getDebugLoc();
246 switch (N
->getOpcode()) {
252 case ISD::FrameIndex
: {
253 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
254 return CurDAG
->SelectNodeTo(N
, Alpha::LDA
, MVT::i64
,
255 CurDAG
->getTargetFrameIndex(FI
, MVT::i32
),
258 case ISD::GLOBAL_OFFSET_TABLE
:
259 return getGlobalBaseReg();
260 case AlphaISD::GlobalRetAddr
:
261 return getGlobalRetAddr();
263 case AlphaISD::DivCall
: {
264 SDValue Chain
= CurDAG
->getEntryNode();
265 SDValue N0
= Op
.getOperand(0);
266 SDValue N1
= Op
.getOperand(1);
267 SDValue N2
= Op
.getOperand(2);
268 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R24
, N1
,
270 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R25
, N2
,
272 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R27
, N0
,
275 CurDAG
->getTargetNode(Alpha::JSRs
, dl
, MVT::Other
, MVT::Flag
,
276 Chain
, Chain
.getValue(1));
277 Chain
= CurDAG
->getCopyFromReg(Chain
, dl
, Alpha::R27
, MVT::i64
,
279 return CurDAG
->SelectNodeTo(N
, Alpha::BISr
, MVT::i64
, Chain
, Chain
);
282 case ISD::READCYCLECOUNTER
: {
283 SDValue Chain
= N
->getOperand(0);
284 return CurDAG
->getTargetNode(Alpha::RPCC
, dl
, MVT::i64
, MVT::Other
,
288 case ISD::Constant
: {
289 uint64_t uval
= cast
<ConstantSDNode
>(N
)->getZExtValue();
292 SDValue Result
= CurDAG
->getCopyFromReg(CurDAG
->getEntryNode(), dl
,
293 Alpha::R31
, MVT::i64
);
294 ReplaceUses(Op
, Result
);
298 int64_t val
= (int64_t)uval
;
299 int32_t val32
= (int32_t)val
;
300 if (val
<= IMM_HIGH
+ IMM_HIGH
* IMM_MULT
&&
301 val
>= IMM_LOW
+ IMM_LOW
* IMM_MULT
)
302 break; //(LDAH (LDA))
303 if ((uval
>> 32) == 0 && //empty upper bits
304 val32
<= IMM_HIGH
+ IMM_HIGH
* IMM_MULT
)
305 // val32 >= IMM_LOW + IMM_LOW * IMM_MULT) //always true
306 break; //(zext (LDAH (LDA)))
307 //Else use the constant pool
308 ConstantInt
*C
= CurDAG
->getContext()->getConstantInt(Type::Int64Ty
, uval
);
309 SDValue CPI
= CurDAG
->getTargetConstantPool(C
, MVT::i64
);
310 SDNode
*Tmp
= CurDAG
->getTargetNode(Alpha::LDAHr
, dl
, MVT::i64
, CPI
,
311 SDValue(getGlobalBaseReg(), 0));
312 return CurDAG
->SelectNodeTo(N
, Alpha::LDQr
, MVT::i64
, MVT::Other
,
313 CPI
, SDValue(Tmp
, 0), CurDAG
->getEntryNode());
315 case ISD::TargetConstantFP
:
316 case ISD::ConstantFP
: {
317 ConstantFPSDNode
*CN
= cast
<ConstantFPSDNode
>(N
);
318 bool isDouble
= N
->getValueType(0) == MVT::f64
;
319 MVT T
= isDouble
? MVT::f64
: MVT::f32
;
320 if (CN
->getValueAPF().isPosZero()) {
321 return CurDAG
->SelectNodeTo(N
, isDouble
? Alpha::CPYST
: Alpha::CPYSS
,
322 T
, CurDAG
->getRegister(Alpha::F31
, T
),
323 CurDAG
->getRegister(Alpha::F31
, T
));
324 } else if (CN
->getValueAPF().isNegZero()) {
325 return CurDAG
->SelectNodeTo(N
, isDouble
? Alpha::CPYSNT
: Alpha::CPYSNS
,
326 T
, CurDAG
->getRegister(Alpha::F31
, T
),
327 CurDAG
->getRegister(Alpha::F31
, T
));
329 llvm_report_error("Unhandled FP constant type");
335 if (N
->getOperand(0).getNode()->getValueType(0).isFloatingPoint()) {
336 ISD::CondCode CC
= cast
<CondCodeSDNode
>(N
->getOperand(2))->get();
338 unsigned Opc
= Alpha::WTF
;
342 default: DEBUG(N
->dump(CurDAG
)); llvm_unreachable("Unknown FP comparison!");
343 case ISD::SETEQ
: case ISD::SETOEQ
: case ISD::SETUEQ
:
344 Opc
= Alpha::CMPTEQ
; break;
345 case ISD::SETLT
: case ISD::SETOLT
: case ISD::SETULT
:
346 Opc
= Alpha::CMPTLT
; break;
347 case ISD::SETLE
: case ISD::SETOLE
: case ISD::SETULE
:
348 Opc
= Alpha::CMPTLE
; break;
349 case ISD::SETGT
: case ISD::SETOGT
: case ISD::SETUGT
:
350 Opc
= Alpha::CMPTLT
; rev
= true; break;
351 case ISD::SETGE
: case ISD::SETOGE
: case ISD::SETUGE
:
352 Opc
= Alpha::CMPTLE
; rev
= true; break;
353 case ISD::SETNE
: case ISD::SETONE
: case ISD::SETUNE
:
354 Opc
= Alpha::CMPTEQ
; inv
= true; break;
356 Opc
= Alpha::CMPTUN
; inv
= true; break;
358 Opc
= Alpha::CMPTUN
; break;
360 SDValue tmp1
= N
->getOperand(rev
?1:0);
361 SDValue tmp2
= N
->getOperand(rev
?0:1);
362 SDNode
*cmp
= CurDAG
->getTargetNode(Opc
, dl
, MVT::f64
, tmp1
, tmp2
);
364 cmp
= CurDAG
->getTargetNode(Alpha::CMPTEQ
, dl
,
365 MVT::f64
, SDValue(cmp
, 0),
366 CurDAG
->getRegister(Alpha::F31
, MVT::f64
));
368 case ISD::SETUEQ
: case ISD::SETULT
: case ISD::SETULE
:
369 case ISD::SETUNE
: case ISD::SETUGT
: case ISD::SETUGE
:
371 SDNode
* cmp2
= CurDAG
->getTargetNode(Alpha::CMPTUN
, dl
, MVT::f64
,
373 cmp
= CurDAG
->getTargetNode(Alpha::ADDT
, dl
, MVT::f64
,
374 SDValue(cmp2
, 0), SDValue(cmp
, 0));
380 SDNode
* LD
= CurDAG
->getTargetNode(Alpha::FTOIT
, dl
,
381 MVT::i64
, SDValue(cmp
, 0));
382 return CurDAG
->getTargetNode(Alpha::CMPULT
, dl
, MVT::i64
,
383 CurDAG
->getRegister(Alpha::R31
, MVT::i64
),
389 if (N
->getValueType(0).isFloatingPoint() &&
390 (N
->getOperand(0).getOpcode() != ISD::SETCC
||
391 !N
->getOperand(0).getOperand(1).getValueType().isFloatingPoint())) {
392 //This should be the condition not covered by the Patterns
393 //FIXME: Don't have SelectCode die, but rather return something testable
394 // so that things like this can be caught in fall though code
396 bool isDouble
= N
->getValueType(0) == MVT::f64
;
397 SDValue cond
= N
->getOperand(0);
398 SDValue TV
= N
->getOperand(1);
399 SDValue FV
= N
->getOperand(2);
401 SDNode
* LD
= CurDAG
->getTargetNode(Alpha::ITOFT
, dl
, MVT::f64
, cond
);
402 return CurDAG
->getTargetNode(isDouble
?Alpha::FCMOVNET
:Alpha::FCMOVNES
,
403 dl
, MVT::f64
, FV
, TV
, SDValue(LD
,0));
408 ConstantSDNode
* SC
= NULL
;
409 ConstantSDNode
* MC
= NULL
;
410 if (N
->getOperand(0).getOpcode() == ISD::SRL
&&
411 (MC
= dyn_cast
<ConstantSDNode
>(N
->getOperand(1))) &&
412 (SC
= dyn_cast
<ConstantSDNode
>(N
->getOperand(0).getOperand(1)))) {
413 uint64_t sval
= SC
->getZExtValue();
414 uint64_t mval
= MC
->getZExtValue();
415 // If the result is a zap, let the autogened stuff handle it.
416 if (get_zapImm(N
->getOperand(0), mval
))
418 // given mask X, and shift S, we want to see if there is any zap in the
419 // mask if we play around with the botton S bits
420 uint64_t dontcare
= (~0ULL) >> (64 - sval
);
421 uint64_t mask
= mval
<< sval
;
423 if (get_zapImm(mask
| dontcare
))
424 mask
= mask
| dontcare
;
426 if (get_zapImm(mask
)) {
428 SDValue(CurDAG
->getTargetNode(Alpha::ZAPNOTi
, dl
, MVT::i64
,
429 N
->getOperand(0).getOperand(0),
430 getI64Imm(get_zapImm(mask
))), 0);
431 return CurDAG
->getTargetNode(Alpha::SRLr
, dl
, MVT::i64
, Z
,
440 return SelectCode(Op
);
443 void AlphaDAGToDAGISel::SelectCALL(SDValue Op
) {
444 //TODO: add flag stuff to prevent nondeturministic breakage!
446 SDNode
*N
= Op
.getNode();
447 SDValue Chain
= N
->getOperand(0);
448 SDValue Addr
= N
->getOperand(1);
449 SDValue
InFlag(0,0); // Null incoming flag value.
450 DebugLoc dl
= N
->getDebugLoc();
452 std::vector
<SDValue
> CallOperands
;
453 std::vector
<MVT
> TypeOperands
;
456 for(int i
= 2, e
= N
->getNumOperands(); i
< e
; ++i
) {
457 TypeOperands
.push_back(N
->getOperand(i
).getValueType());
458 CallOperands
.push_back(N
->getOperand(i
));
460 int count
= N
->getNumOperands() - 2;
462 static const unsigned args_int
[] = {Alpha::R16
, Alpha::R17
, Alpha::R18
,
463 Alpha::R19
, Alpha::R20
, Alpha::R21
};
464 static const unsigned args_float
[] = {Alpha::F16
, Alpha::F17
, Alpha::F18
,
465 Alpha::F19
, Alpha::F20
, Alpha::F21
};
467 for (int i
= 6; i
< count
; ++i
) {
468 unsigned Opc
= Alpha::WTF
;
469 if (TypeOperands
[i
].isInteger()) {
471 } else if (TypeOperands
[i
] == MVT::f32
) {
473 } else if (TypeOperands
[i
] == MVT::f64
) {
476 llvm_unreachable("Unknown operand");
478 SDValue Ops
[] = { CallOperands
[i
], getI64Imm((i
- 6) * 8),
479 CurDAG
->getCopyFromReg(Chain
, dl
, Alpha::R30
, MVT::i64
),
481 Chain
= SDValue(CurDAG
->getTargetNode(Opc
, dl
, MVT::Other
, Ops
, 4), 0);
483 for (int i
= 0; i
< std::min(6, count
); ++i
) {
484 if (TypeOperands
[i
].isInteger()) {
485 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, args_int
[i
],
486 CallOperands
[i
], InFlag
);
487 InFlag
= Chain
.getValue(1);
488 } else if (TypeOperands
[i
] == MVT::f32
|| TypeOperands
[i
] == MVT::f64
) {
489 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, args_float
[i
],
490 CallOperands
[i
], InFlag
);
491 InFlag
= Chain
.getValue(1);
493 llvm_unreachable("Unknown operand");
496 // Finally, once everything is in registers to pass to the call, emit the
498 if (Addr
.getOpcode() == AlphaISD::GPRelLo
) {
499 SDValue GOT
= SDValue(getGlobalBaseReg(), 0);
500 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R29
, GOT
, InFlag
);
501 InFlag
= Chain
.getValue(1);
502 Chain
= SDValue(CurDAG
->getTargetNode(Alpha::BSR
, dl
, MVT::Other
,
503 MVT::Flag
, Addr
.getOperand(0),
506 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R27
, Addr
, InFlag
);
507 InFlag
= Chain
.getValue(1);
508 Chain
= SDValue(CurDAG
->getTargetNode(Alpha::JSR
, dl
, MVT::Other
,
509 MVT::Flag
, Chain
, InFlag
), 0);
511 InFlag
= Chain
.getValue(1);
513 std::vector
<SDValue
> CallResults
;
515 switch (N
->getValueType(0).getSimpleVT()) {
516 default: llvm_unreachable("Unexpected ret value!");
517 case MVT::Other
: break;
519 Chain
= CurDAG
->getCopyFromReg(Chain
, dl
,
520 Alpha::R0
, MVT::i64
, InFlag
).getValue(1);
521 CallResults
.push_back(Chain
.getValue(0));
524 Chain
= CurDAG
->getCopyFromReg(Chain
, dl
,
525 Alpha::F0
, MVT::f32
, InFlag
).getValue(1);
526 CallResults
.push_back(Chain
.getValue(0));
529 Chain
= CurDAG
->getCopyFromReg(Chain
, dl
,
530 Alpha::F0
, MVT::f64
, InFlag
).getValue(1);
531 CallResults
.push_back(Chain
.getValue(0));
535 CallResults
.push_back(Chain
);
536 for (unsigned i
= 0, e
= CallResults
.size(); i
!= e
; ++i
)
537 ReplaceUses(Op
.getValue(i
), CallResults
[i
]);
541 /// createAlphaISelDag - This pass converts a legalized DAG into a
542 /// Alpha-specific DAG, ready for instruction scheduling.
544 FunctionPass
*llvm::createAlphaISelDag(AlphaTargetMachine
&TM
) {
545 return new AlphaDAGToDAGISel(TM
);