aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Alpha/AlphaISelDAGToDAG.cpp65
-rw-r--r--lib/Target/Alpha/AlphaInstrInfo.td26
2 files changed, 70 insertions, 21 deletions
diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
index ed66592d40..51de4e6ba5 100644
--- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
+++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp
@@ -59,19 +59,57 @@ namespace {
return x - get_ldah16(x) * IMM_MULT;
}
+ /// get_zapImm - Return a zap mask if X is a valid immediate for a zapnot
+ /// instruction (if not, return 0). Note that this code accepts partial
+ /// zap masks. For example (and LHS, 1) is a valid zap, as long we know
+ /// that the bits 1-7 of LHS are already zero. If LHS is non-null, we are
+ /// in checking mode. If LHS is null, we assume that the mask has already
+ /// been validated before.
+ uint64_t get_zapImm(SDOperand LHS, uint64_t Constant) {
+ uint64_t BitsToCheck = 0;
+ unsigned Result = 0;
+ for (unsigned i = 0; i != 8; ++i) {
+ if (((Constant >> 8*i) & 0xFF) == 0) {
+ // nothing to do.
+ } else {
+ Result |= 1 << i;
+ if (((Constant >> 8*i) & 0xFF) == 0xFF) {
+ // If the entire byte is set, zapnot the byte.
+ } else if (LHS.Val == 0) {
+ // Otherwise, if the mask was previously validated, we know its okay
+ // to zapnot this entire byte even though all the bits aren't set.
+ } else {
+ // Otherwise we don't know that the it's okay to zapnot this entire
+ // byte. Only do this iff we can prove that the missing bits are
+ // already null, so the bytezap doesn't need to really null them.
+ BitsToCheck |= ~Constant & (0xFF << 8*i);
+ }
+ }
+ }
+
+ // If there are missing bits in a byte (for example, X & 0xEF00), check to
+ // see if the missing bits (0x1000) are already known zero if not, the zap
+ // isn't okay to do, as it won't clear all the required bits.
+ if (BitsToCheck &&
+ !getTargetLowering().MaskedValueIsZero(LHS, BitsToCheck))
+ return 0;
+
+ return Result;
+ }
+
static uint64_t get_zapImm(uint64_t x) {
- unsigned int build = 0;
- for(int i = 0; i < 8; ++i)
- {
- if ((x & 0x00FF) == 0x00FF)
- build |= 1 << i;
- else if ((x & 0x00FF) != 0)
- { build = 0; break; }
- x >>= 8;
- }
+ unsigned build = 0;
+ for(int i = 0; i != 8; ++i) {
+ if ((x & 0x00FF) == 0x00FF)
+ build |= 1 << i;
+ else if ((x & 0x00FF) != 0)
+ return 0;
+ x >>= 8;
+ }
return build;
}
-
+
+
static uint64_t getNearPower2(uint64_t x) {
if (!x) return 0;
unsigned at = CountLeadingZeros_64(x);
@@ -380,10 +418,11 @@ SDNode *AlphaDAGToDAGISel::Select(SDOperand Op) {
{
uint64_t sval = SC->getValue();
uint64_t mval = MC->getValue();
- if (get_zapImm(mval)) //the result is a zap, let the autogened stuff deal
+ // If the result is a zap, let the autogened stuff handle it.
+ if (get_zapImm(N->getOperand(0), mval))
break;
- // given mask X, and shift S, we want to see if there is any zap in the mask
- // if we play around with the botton S bits
+ // given mask X, and shift S, we want to see if there is any zap in the
+ // mask if we play around with the botton S bits
uint64_t dontcare = (~0ULL) >> (64 - sval);
uint64_t mask = mval << sval;
diff --git a/lib/Target/Alpha/AlphaInstrInfo.td b/lib/Target/Alpha/AlphaInstrInfo.td
index d63d0badff..3f897a76c8 100644
--- a/lib/Target/Alpha/AlphaInstrInfo.td
+++ b/lib/Target/Alpha/AlphaInstrInfo.td
@@ -59,8 +59,9 @@ def LL16 : SDNodeXForm<imm, [{ //lda part of constant
def LH16 : SDNodeXForm<imm, [{ //ldah part of constant (or more if too big)
return getI64Imm(get_ldah16(N->getValue()));
}]>;
-def iZAPX : SDNodeXForm<imm, [{ // get imm to ZAPi
- return getI64Imm(get_zapImm((uint64_t)N->getValue()));
+def iZAPX : SDNodeXForm<and, [{ // get imm to ZAPi
+ ConstantSDNode *RHS = cast<ConstantSDNode>(N->getOperand(1));
+ return getI64Imm(get_zapImm(SDOperand(), RHS->getValue()));
}]>;
def nearP2X : SDNodeXForm<imm, [{
return getI64Imm(Log2_64(getNearPower2((uint64_t)N->getValue())));
@@ -85,10 +86,15 @@ def immSExt16 : PatLeaf<(imm), [{ //imm fits in 16 bit sign extended field
def immSExt16int : PatLeaf<(imm), [{ //(int)imm fits in a 16 bit sign extended field
return ((int64_t)N->getValue() << 48) >> 48 == ((int64_t)N->getValue() << 32) >> 32;
}], SExt16>;
-def immZAP : PatLeaf<(imm), [{ //imm is good for zapi
- uint64_t build = get_zapImm((uint64_t)N->getValue());
- return build != 0;
-}], iZAPX>;
+
+def zappat : PatFrag<(ops node:$LHS), (and node:$LHS, imm:$L), [{
+ if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N->getOperand(1))) {
+ uint64_t build = get_zapImm(N->getOperand(0), (uint64_t)RHS->getValue());
+ return build != 0;
+ }
+ return false;
+}]>;
+
def immFPZ : PatLeaf<(fpimm), [{ //the only fpconstant nodes are +/- 0.0
return true;
}]>;
@@ -386,8 +392,12 @@ def XOR : OForm< 0x11, 0x40, "xor $RA,$RB,$RC",
def XORi : OFormL<0x11, 0x40, "xor $RA,$L,$RC",
[(set GPRC:$RC, (xor GPRC:$RA, immUExt8:$L))], s_ilog>;
-def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC",
- [(set GPRC:$RC, (and GPRC:$RA, immZAP:$L))], s_ishf>;
+def ZAPNOTi : OFormL<0x12, 0x31, "zapnot $RA,$L,$RC", [], s_ishf>;
+
+// Define the pattern that produces ZAPNOTi.
+def : Pat<(i64 (zappat GPRC:$RA):$imm),
+ (ZAPNOTi GPRC:$RA, (iZAPX GPRC:$imm))>;
+
//Comparison, int
//So this is a waste of what this instruction can do, but it still saves something