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 "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/CodeGen/SelectionDAG.h"
22 #include "llvm/CodeGen/SelectionDAGISel.h"
23 #include "llvm/Target/TargetOptions.h"
24 #include "llvm/Constants.h"
25 #include "llvm/DerivedTypes.h"
26 #include "llvm/GlobalValue.h"
27 #include "llvm/Intrinsics.h"
28 #include "llvm/LLVMContext.h"
29 #include "llvm/Support/Compiler.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/MathExtras.h"
33 #include "llvm/Support/raw_ostream.h"
39 //===--------------------------------------------------------------------===//
40 /// AlphaDAGToDAGISel - Alpha specific code to select Alpha machine
41 /// instructions for SelectionDAG operations.
42 class AlphaDAGToDAGISel
: public SelectionDAGISel
{
43 static const int64_t IMM_LOW
= -32768;
44 static const int64_t IMM_HIGH
= 32767;
45 static const int64_t IMM_MULT
= 65536;
46 static const int64_t IMM_FULLHIGH
= IMM_HIGH
+ IMM_HIGH
* IMM_MULT
;
47 static const int64_t IMM_FULLLOW
= IMM_LOW
+ IMM_LOW
* IMM_MULT
;
49 static int64_t get_ldah16(int64_t x
) {
50 int64_t y
= x
/ IMM_MULT
;
51 if (x
% IMM_MULT
> IMM_HIGH
)
56 static int64_t get_lda16(int64_t x
) {
57 return x
- get_ldah16(x
) * IMM_MULT
;
60 /// get_zapImm - Return a zap mask if X is a valid immediate for a zapnot
61 /// instruction (if not, return 0). Note that this code accepts partial
62 /// zap masks. For example (and LHS, 1) is a valid zap, as long we know
63 /// that the bits 1-7 of LHS are already zero. If LHS is non-null, we are
64 /// in checking mode. If LHS is null, we assume that the mask has already
65 /// been validated before.
66 uint64_t get_zapImm(SDValue LHS
, uint64_t Constant
) const {
67 uint64_t BitsToCheck
= 0;
69 for (unsigned i
= 0; i
!= 8; ++i
) {
70 if (((Constant
>> 8*i
) & 0xFF) == 0) {
74 if (((Constant
>> 8*i
) & 0xFF) == 0xFF) {
75 // If the entire byte is set, zapnot the byte.
76 } else if (LHS
.getNode() == 0) {
77 // Otherwise, if the mask was previously validated, we know its okay
78 // to zapnot this entire byte even though all the bits aren't set.
80 // Otherwise we don't know that the it's okay to zapnot this entire
81 // byte. Only do this iff we can prove that the missing bits are
82 // already null, so the bytezap doesn't need to really null them.
83 BitsToCheck
|= ~Constant
& (0xFF << 8*i
);
88 // If there are missing bits in a byte (for example, X & 0xEF00), check to
89 // see if the missing bits (0x1000) are already known zero if not, the zap
90 // isn't okay to do, as it won't clear all the required bits.
92 !CurDAG
->MaskedValueIsZero(LHS
,
93 APInt(LHS
.getValueSizeInBits(),
100 static uint64_t get_zapImm(uint64_t x
) {
102 for(int i
= 0; i
!= 8; ++i
) {
103 if ((x
& 0x00FF) == 0x00FF)
105 else if ((x
& 0x00FF) != 0)
113 static uint64_t getNearPower2(uint64_t x
) {
115 unsigned at
= CountLeadingZeros_64(x
);
116 uint64_t complow
= 1ULL << (63 - at
);
117 uint64_t comphigh
= 1ULL << (64 - at
);
118 //cerr << x << ":" << complow << ":" << comphigh << "\n";
119 if (abs64(complow
- x
) <= abs64(comphigh
- x
))
125 static bool chkRemNearPower2(uint64_t x
, uint64_t r
, bool swap
) {
126 uint64_t y
= getNearPower2(x
);
134 explicit AlphaDAGToDAGISel(AlphaTargetMachine
&TM
)
135 : SelectionDAGISel(TM
)
138 /// getI64Imm - Return a target constant with the specified value, of type
140 inline SDValue
getI64Imm(int64_t Imm
) {
141 return CurDAG
->getTargetConstant(Imm
, MVT::i64
);
144 // Select - Convert the specified operand from a target-independent to a
145 // target-specific node if it hasn't already been changed.
146 SDNode
*Select(SDNode
*N
);
148 virtual const char *getPassName() const {
149 return "Alpha DAG->DAG Pattern Instruction Selection";
152 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
153 /// inline asm expressions.
154 virtual bool SelectInlineAsmMemoryOperand(const SDValue
&Op
,
156 std::vector
<SDValue
> &OutOps
) {
158 switch (ConstraintCode
) {
159 default: return true;
165 OutOps
.push_back(Op0
);
169 // Include the pieces autogenerated from the target description.
170 #include "AlphaGenDAGISel.inc"
173 /// getTargetMachine - Return a reference to the TargetMachine, casted
174 /// to the target-specific type.
175 const AlphaTargetMachine
&getTargetMachine() {
176 return static_cast<const AlphaTargetMachine
&>(TM
);
179 /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
180 /// to the target-specific type.
181 const AlphaInstrInfo
*getInstrInfo() {
182 return getTargetMachine().getInstrInfo();
185 SDNode
*getGlobalBaseReg();
186 SDNode
*getGlobalRetAddr();
187 void SelectCALL(SDNode
*Op
);
192 /// getGlobalBaseReg - Output the instructions required to put the
193 /// GOT address into a register.
195 SDNode
*AlphaDAGToDAGISel::getGlobalBaseReg() {
196 unsigned GlobalBaseReg
= getInstrInfo()->getGlobalBaseReg(MF
);
197 return CurDAG
->getRegister(GlobalBaseReg
, TLI
.getPointerTy()).getNode();
200 /// getGlobalRetAddr - Grab the return address.
202 SDNode
*AlphaDAGToDAGISel::getGlobalRetAddr() {
203 unsigned GlobalRetAddr
= getInstrInfo()->getGlobalRetAddr(MF
);
204 return CurDAG
->getRegister(GlobalRetAddr
, TLI
.getPointerTy()).getNode();
207 // Select - Convert the specified operand from a target-independent to a
208 // target-specific node if it hasn't already been changed.
209 SDNode
*AlphaDAGToDAGISel::Select(SDNode
*N
) {
210 if (N
->isMachineOpcode())
211 return NULL
; // Already selected.
212 DebugLoc dl
= N
->getDebugLoc();
214 switch (N
->getOpcode()) {
220 case ISD::FrameIndex
: {
221 int FI
= cast
<FrameIndexSDNode
>(N
)->getIndex();
222 return CurDAG
->SelectNodeTo(N
, Alpha::LDA
, MVT::i64
,
223 CurDAG
->getTargetFrameIndex(FI
, MVT::i32
),
226 case ISD::GLOBAL_OFFSET_TABLE
:
227 return getGlobalBaseReg();
228 case AlphaISD::GlobalRetAddr
:
229 return getGlobalRetAddr();
231 case AlphaISD::DivCall
: {
232 SDValue Chain
= CurDAG
->getEntryNode();
233 SDValue N0
= N
->getOperand(0);
234 SDValue N1
= N
->getOperand(1);
235 SDValue N2
= N
->getOperand(2);
236 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R24
, N1
,
238 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R25
, N2
,
240 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R27
, N0
,
243 CurDAG
->getMachineNode(Alpha::JSRs
, dl
, MVT::Other
, MVT::Glue
,
244 Chain
, Chain
.getValue(1));
245 Chain
= CurDAG
->getCopyFromReg(Chain
, dl
, Alpha::R27
, MVT::i64
,
247 return CurDAG
->SelectNodeTo(N
, Alpha::BISr
, MVT::i64
, Chain
, Chain
);
250 case ISD::READCYCLECOUNTER
: {
251 SDValue Chain
= N
->getOperand(0);
252 return CurDAG
->getMachineNode(Alpha::RPCC
, dl
, MVT::i64
, MVT::Other
,
256 case ISD::Constant
: {
257 uint64_t uval
= cast
<ConstantSDNode
>(N
)->getZExtValue();
260 SDValue Result
= CurDAG
->getCopyFromReg(CurDAG
->getEntryNode(), dl
,
261 Alpha::R31
, MVT::i64
);
262 ReplaceUses(SDValue(N
, 0), Result
);
266 int64_t val
= (int64_t)uval
;
267 int32_t val32
= (int32_t)val
;
268 if (val
<= IMM_HIGH
+ IMM_HIGH
* IMM_MULT
&&
269 val
>= IMM_LOW
+ IMM_LOW
* IMM_MULT
)
270 break; //(LDAH (LDA))
271 if ((uval
>> 32) == 0 && //empty upper bits
272 val32
<= IMM_HIGH
+ IMM_HIGH
* IMM_MULT
)
273 // val32 >= IMM_LOW + IMM_LOW * IMM_MULT) //always true
274 break; //(zext (LDAH (LDA)))
275 //Else use the constant pool
276 ConstantInt
*C
= ConstantInt::get(
277 Type::getInt64Ty(*CurDAG
->getContext()), uval
);
278 SDValue CPI
= CurDAG
->getTargetConstantPool(C
, MVT::i64
);
279 SDNode
*Tmp
= CurDAG
->getMachineNode(Alpha::LDAHr
, dl
, MVT::i64
, CPI
,
280 SDValue(getGlobalBaseReg(), 0));
281 return CurDAG
->SelectNodeTo(N
, Alpha::LDQr
, MVT::i64
, MVT::Other
,
282 CPI
, SDValue(Tmp
, 0), CurDAG
->getEntryNode());
284 case ISD::TargetConstantFP
:
285 case ISD::ConstantFP
: {
286 ConstantFPSDNode
*CN
= cast
<ConstantFPSDNode
>(N
);
287 bool isDouble
= N
->getValueType(0) == MVT::f64
;
288 EVT T
= isDouble
? MVT::f64
: MVT::f32
;
289 if (CN
->getValueAPF().isPosZero()) {
290 return CurDAG
->SelectNodeTo(N
, isDouble
? Alpha::CPYST
: Alpha::CPYSS
,
291 T
, CurDAG
->getRegister(Alpha::F31
, T
),
292 CurDAG
->getRegister(Alpha::F31
, T
));
293 } else if (CN
->getValueAPF().isNegZero()) {
294 return CurDAG
->SelectNodeTo(N
, isDouble
? Alpha::CPYSNT
: Alpha::CPYSNS
,
295 T
, CurDAG
->getRegister(Alpha::F31
, T
),
296 CurDAG
->getRegister(Alpha::F31
, T
));
298 report_fatal_error("Unhandled FP constant type");
304 if (N
->getOperand(0).getNode()->getValueType(0).isFloatingPoint()) {
305 ISD::CondCode CC
= cast
<CondCodeSDNode
>(N
->getOperand(2))->get();
307 unsigned Opc
= Alpha::WTF
;
311 default: DEBUG(N
->dump(CurDAG
)); llvm_unreachable("Unknown FP comparison!");
312 case ISD::SETEQ
: case ISD::SETOEQ
: case ISD::SETUEQ
:
313 Opc
= Alpha::CMPTEQ
; break;
314 case ISD::SETLT
: case ISD::SETOLT
: case ISD::SETULT
:
315 Opc
= Alpha::CMPTLT
; break;
316 case ISD::SETLE
: case ISD::SETOLE
: case ISD::SETULE
:
317 Opc
= Alpha::CMPTLE
; break;
318 case ISD::SETGT
: case ISD::SETOGT
: case ISD::SETUGT
:
319 Opc
= Alpha::CMPTLT
; rev
= true; break;
320 case ISD::SETGE
: case ISD::SETOGE
: case ISD::SETUGE
:
321 Opc
= Alpha::CMPTLE
; rev
= true; break;
322 case ISD::SETNE
: case ISD::SETONE
: case ISD::SETUNE
:
323 Opc
= Alpha::CMPTEQ
; inv
= true; break;
325 Opc
= Alpha::CMPTUN
; inv
= true; break;
327 Opc
= Alpha::CMPTUN
; break;
329 SDValue tmp1
= N
->getOperand(rev
?1:0);
330 SDValue tmp2
= N
->getOperand(rev
?0:1);
331 SDNode
*cmp
= CurDAG
->getMachineNode(Opc
, dl
, MVT::f64
, tmp1
, tmp2
);
333 cmp
= CurDAG
->getMachineNode(Alpha::CMPTEQ
, dl
,
334 MVT::f64
, SDValue(cmp
, 0),
335 CurDAG
->getRegister(Alpha::F31
, MVT::f64
));
337 case ISD::SETUEQ
: case ISD::SETULT
: case ISD::SETULE
:
338 case ISD::SETUNE
: case ISD::SETUGT
: case ISD::SETUGE
:
340 SDNode
* cmp2
= CurDAG
->getMachineNode(Alpha::CMPTUN
, dl
, MVT::f64
,
342 cmp
= CurDAG
->getMachineNode(Alpha::ADDT
, dl
, MVT::f64
,
343 SDValue(cmp2
, 0), SDValue(cmp
, 0));
349 SDNode
* LD
= CurDAG
->getMachineNode(Alpha::FTOIT
, dl
,
350 MVT::i64
, SDValue(cmp
, 0));
351 return CurDAG
->getMachineNode(Alpha::CMPULT
, dl
, MVT::i64
,
352 CurDAG
->getRegister(Alpha::R31
, MVT::i64
),
358 ConstantSDNode
* SC
= NULL
;
359 ConstantSDNode
* MC
= NULL
;
360 if (N
->getOperand(0).getOpcode() == ISD::SRL
&&
361 (MC
= dyn_cast
<ConstantSDNode
>(N
->getOperand(1))) &&
362 (SC
= dyn_cast
<ConstantSDNode
>(N
->getOperand(0).getOperand(1)))) {
363 uint64_t sval
= SC
->getZExtValue();
364 uint64_t mval
= MC
->getZExtValue();
365 // If the result is a zap, let the autogened stuff handle it.
366 if (get_zapImm(N
->getOperand(0), mval
))
368 // given mask X, and shift S, we want to see if there is any zap in the
369 // mask if we play around with the botton S bits
370 uint64_t dontcare
= (~0ULL) >> (64 - sval
);
371 uint64_t mask
= mval
<< sval
;
373 if (get_zapImm(mask
| dontcare
))
374 mask
= mask
| dontcare
;
376 if (get_zapImm(mask
)) {
378 SDValue(CurDAG
->getMachineNode(Alpha::ZAPNOTi
, dl
, MVT::i64
,
379 N
->getOperand(0).getOperand(0),
380 getI64Imm(get_zapImm(mask
))), 0);
381 return CurDAG
->getMachineNode(Alpha::SRLr
, dl
, MVT::i64
, Z
,
390 return SelectCode(N
);
393 void AlphaDAGToDAGISel::SelectCALL(SDNode
*N
) {
394 //TODO: add flag stuff to prevent nondeturministic breakage!
396 SDValue Chain
= N
->getOperand(0);
397 SDValue Addr
= N
->getOperand(1);
398 SDValue InFlag
= N
->getOperand(N
->getNumOperands() - 1);
399 DebugLoc dl
= N
->getDebugLoc();
401 if (Addr
.getOpcode() == AlphaISD::GPRelLo
) {
402 SDValue GOT
= SDValue(getGlobalBaseReg(), 0);
403 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R29
, GOT
, InFlag
);
404 InFlag
= Chain
.getValue(1);
405 Chain
= SDValue(CurDAG
->getMachineNode(Alpha::BSR
, dl
, MVT::Other
,
406 MVT::Glue
, Addr
.getOperand(0),
409 Chain
= CurDAG
->getCopyToReg(Chain
, dl
, Alpha::R27
, Addr
, InFlag
);
410 InFlag
= Chain
.getValue(1);
411 Chain
= SDValue(CurDAG
->getMachineNode(Alpha::JSR
, dl
, MVT::Other
,
412 MVT::Glue
, Chain
, InFlag
), 0);
414 InFlag
= Chain
.getValue(1);
416 ReplaceUses(SDValue(N
, 0), Chain
);
417 ReplaceUses(SDValue(N
, 1), InFlag
);
421 /// createAlphaISelDag - This pass converts a legalized DAG into a
422 /// Alpha-specific DAG, ready for instruction scheduling.
424 FunctionPass
*llvm::createAlphaISelDag(AlphaTargetMachine
&TM
) {
425 return new AlphaDAGToDAGISel(TM
);