aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDuraid Madina <duraid@octopus.com.au>2005-10-29 16:08:30 +0000
committerDuraid Madina <duraid@octopus.com.au>2005-10-29 16:08:30 +0000
commit7abaf906e22a7172648cd4aba753e61132912556 (patch)
tree824d9a7e9c36f55ad23926bda3ec4aada52718be
parent42f905691e92e4b7f10a824db5a35aaa54455b9b (diff)
downloadllvm-7abaf906e22a7172648cd4aba753e61132912556.zip
llvm-7abaf906e22a7172648cd4aba753e61132912556.tar.gz
llvm-7abaf906e22a7172648cd4aba753e61132912556.tar.bz2
add some FP stuff, some mix.* stuff, and constant pool support to the
DAG instruction selector, which should be destroyed one day (in the pattern isel also) since ia64 can pack any constant in the instruction stream llvm-svn: 24094
-rw-r--r--llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp7
-rw-r--r--llvm/lib/Target/IA64/IA64InstrInfo.td185
2 files changed, 131 insertions, 61 deletions
diff --git a/llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp b/llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp
index 54fd065..a22c6b1 100644
--- a/llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/IA64/IA64ISelDAGToDAG.cpp
@@ -313,6 +313,13 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
CurDAG->getTargetFrameIndex(FI, MVT::i64));
}
+ case ISD::ConstantPool: {
+ Constant *C = cast<ConstantPoolSDNode>(N)->get();
+ SDOperand CPI = CurDAG->getTargetConstantPool(C, MVT::i64);
+ return CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, // ?
+ CurDAG->getRegister(IA64::r1, MVT::i64), CPI);
+ }
+
case ISD::GlobalAddress: {
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64);
diff --git a/llvm/lib/Target/IA64/IA64InstrInfo.td b/llvm/lib/Target/IA64/IA64InstrInfo.td
index bd3042a..a6b8f77 100644
--- a/llvm/lib/Target/IA64/IA64InstrInfo.td
+++ b/llvm/lib/Target/IA64/IA64InstrInfo.td
@@ -45,10 +45,33 @@ let PrintMethod = "printCallOperand" in
def is32ones : PatLeaf<(i64 imm), [{
// is32ones predicate - True if the immediate is 0x00000000FFFFFFFF
// Used to create ZXT4s appropriately
- int64_t v = (int64_t)N->getValue();
+ uint64_t v = (uint64_t)N->getValue();
return (v == 0x00000000FFFFFFFFLL);
}]>;
+// isMIXable predicates - True if the immediate is
+// 0xFF00FF00FF00FF00, 0x00FF00FF00FF00FF
+// etc, through 0x00000000FFFFFFFF
+// Used to test for the suitability of mix*
+def isMIX1Lable: PatLeaf<(i64 imm), [{
+ return((uint64_t)N->getValue()==0xFF00FF00FF00FF00LL);
+}]>;
+def isMIX1Rable: PatLeaf<(i64 imm), [{
+ return((uint64_t)N->getValue()==0x00FF00FF00FF00FFLL);
+}]>;
+def isMIX2Lable: PatLeaf<(i64 imm), [{
+ return((uint64_t)N->getValue()==0xFFFF0000FFFF0000LL);
+}]>;
+def isMIX2Rable: PatLeaf<(i64 imm), [{
+ return((uint64_t)N->getValue()==0x0000FFFF0000FFFFLL);
+}]>;
+def isMIX4Lable: PatLeaf<(i64 imm), [{
+ return((uint64_t)N->getValue()==0xFFFFFFFF00000000LL);
+}]>;
+def isMIX4Rable: PatLeaf<(i64 imm), [{
+ return((uint64_t)N->getValue()==0x00000000FFFFFFFFLL);
+}]>;
+
def isSHLADDimm: PatLeaf<(i64 imm), [{
// isSHLADDimm predicate - True if the immediate is exactly 1, 2, 3 or 4
// - 0 is *not* okay.
@@ -83,6 +106,37 @@ def SXT4 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "sxt4 $dst = $src;;",
def ZXT4 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt4 $dst = $src;;",
[(set GR:$dst, (and GR:$src, is32ones))]>;
+// fixme: shrs vs shru?
+def MIX1L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2),
+ "mix1.l $dst = $src1, $src2;;",
+ [(set GR:$dst, (or (and GR:$src1, isMIX1Lable),
+ (and (srl GR:$src2, 8), isMIX1Lable)))]>;
+
+def MIX2L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2),
+ "mix2.l $dst = $src1, $src2;;",
+ [(set GR:$dst, (or (and GR:$src1, isMIX2Lable),
+ (and (srl GR:$src2, 16), isMIX2Lable)))]>;
+
+def MIX4L : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2),
+ "mix4.l $dst = $src1, $src2;;",
+ [(set GR:$dst, (or (and GR:$src1, isMIX4Lable),
+ (and (srl GR:$src2, 32), isMIX4Lable)))]>;
+
+def MIX1R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2),
+ "mix1.r $dst = $src1, $src2;;",
+ [(set GR:$dst, (or (and (shl GR:$src1, 8), isMIX1Rable),
+ (and GR:$src2, isMIX1Rable)))]>;
+
+def MIX2R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2),
+ "mix2.r $dst = $src1, $src2;;",
+ [(set GR:$dst, (or (and (shl GR:$src1, 16), isMIX2Rable),
+ (and GR:$src2, isMIX2Rable)))]>;
+
+def MIX4R : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2),
+ "mix4.r $dst = $src1, $src2;;",
+ [(set GR:$dst, (or (and (shl GR:$src1, 32), isMIX4Rable),
+ (and GR:$src2, isMIX4Rable)))]>;
+
def ADD : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2),
"add $dst = $src1, $src2;;",
[(set GR:$dst, (add GR:$src1, GR:$src2))]>;
@@ -122,10 +176,20 @@ def SETFSIGD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, GR:$src),
def XMALD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
"xma.l $dst = $src1, $src2, $src3;;",
[]>;
+def XMAHD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
+ "xma.h $dst = $src1, $src2, $src3;;",
+ []>;
+def XMAHUD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
+ "xma.hu $dst = $src1, $src2, $src3;;",
+ []>;
// pseudocode for integer multiplication
def : Pat<(mul GR:$src1, GR:$src2),
(GETFSIGD (XMALD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>;
+def : Pat<(mulhs GR:$src1, GR:$src2),
+ (GETFSIGD (XMAHD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>;
+def : Pat<(mulhu GR:$src1, GR:$src2),
+ (GETFSIGD (XMAHUD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>;
// TODO: addp4 (addp4 dst = src, r0 is a 32-bit add)
// has imm form, too
@@ -160,28 +224,16 @@ def TPCMPEQR0R0 : AForm<0x03, 0x0b, (ops PR:$dst, PR:$bogus, PR:$qp),
"($qp) cmp.eq $dst, p0 = r0, r0;;">;
/* our pseudocode for OR on predicates is:
- *
-
pC = pA OR pB
-------------
-
(pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA
;;
-(pB) cmp.eq pC,p0 = r0,r0 // if (pB) pC = 1
-
-*/
-/*
-let isTwoAddress = 1 in {
- def TPCMPEQ : AForm<0x03, 0x0b,
- (ops PR:$dst, PR:$src2, GR:$src3, GR:$src4, PR:$qp),
- "($qp) cmp.eq $dst, p0 = $src3, $src4;;">;
-}
-*/
+(pB) cmp.eq pC,p0 = r0,r0 // if (pB) pC = 1 */
-// FIXME: these are bogus
def bOR : Pat<(or PR:$src1, PR:$src2),
- (PCMPEQUNCR0R0 PR:$src1)>;
+ (TPCMPEQR0R0 (PCMPEQUNCR0R0 PR:$src1), PR:$src2)>;
+// FIXME: these are bogus
def bXOR : Pat<(xor PR:$src1, PR:$src2),
(PCMPEQUNCR0R0 PR:$src1)>;
@@ -389,47 +441,68 @@ def TPCMPIMM8NE : AForm<0x03, 0x0b,
def SUBIMM8 : AForm<0x03, 0x0b, (ops GR:$dst, s8imm:$imm, GR:$src2),
"sub $dst = $imm, $src2;;">;
-def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
- "st1 [$dstPtr] = $value;;">;
-def ST2 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
- "st2 [$dstPtr] = $value;;">;
-def ST4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
- "st4 [$dstPtr] = $value;;">;
-def ST8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
- "st8 [$dstPtr] = $value;;">;
-
-def LD1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
- "ld1 $dst = [$srcPtr];;">;
-def LD2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
- "ld2 $dst = [$srcPtr];;">;
-def LD4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
- "ld4 $dst = [$srcPtr];;">;
-def LD8 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
- "ld8 $dst = [$srcPtr];;">;
-
-def POPCNT : AForm<0x03, 0x0b, (ops GR:$dst, GR:$src), "popcnt $dst = $src;;">;
-
-// some FP stuff:
-def FADD : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
- "fadd $dst = $src1, $src2;;">;
+let isStore = 1 in {
+ def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
+ "st1 [$dstPtr] = $value;;">;
+ def ST2 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
+ "st2 [$dstPtr] = $value;;">;
+ def ST4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
+ "st4 [$dstPtr] = $value;;">;
+ def ST8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
+ "st8 [$dstPtr] = $value;;">;
+ def STF4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value),
+ "stfs [$dstPtr] = $value;;">;
+ def STF8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value),
+ "stfd [$dstPtr] = $value;;">;
+}
+
+let isLoad = 1 in {
+ def LD1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
+ "ld1 $dst = [$srcPtr];;">;
+ def LD2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
+ "ld2 $dst = [$srcPtr];;">;
+ def LD4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
+ "ld4 $dst = [$srcPtr];;">;
+ def LD8 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
+ "ld8 $dst = [$srcPtr];;">;
+ def LDF4 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr),
+ "ldfs $dst = [$srcPtr];;">;
+ def LDF8 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr),
+ "ldfd $dst = [$srcPtr];;">;
+}
+
+def POPCNT : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src),
+ "popcnt $dst = $src;;",
+ [(set GR:$dst, (ctpop GR:$src))]>;
+
+// some FP stuff: // TODO: single-precision stuff?
+def FADD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
+ "fadd $dst = $src1, $src2;;",
+ [(set FP:$dst, (fadd FP:$src1, FP:$src2))]>;
def FADDS: AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
"fadd.s $dst = $src1, $src2;;">;
-def FSUB : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
- "fsub $dst = $src1, $src2;;">;
-def FMPY : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
- "fmpy $dst = $src1, $src2;;">;
+def FSUB : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
+ "fsub $dst = $src1, $src2;;",
+ [(set FP:$dst, (fsub FP:$src1, FP:$src2))]>;
+def FMPY : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
+ "fmpy $dst = $src1, $src2;;",
+ [(set FP:$dst, (fmul FP:$src1, FP:$src2))]>;
def FMOV : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src),
"mov $dst = $src;;">; // XXX: there _is_ no fmov
-def FMA : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
- "fma $dst = $src1, $src2, $src3;;">;
-def FMS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
- "fms $dst = $src1, $src2, $src3;;">;
-def FNMA : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
- "fnma $dst = $src1, $src2, $src3;;">;
+def FMA : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
+ "fma $dst = $src1, $src2, $src3;;",
+ [(set FP:$dst, (fadd (fmul FP:$src1, FP:$src2), FP:$src3))]>;
+def FMS : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
+ "fms $dst = $src1, $src2, $src3;;",
+ [(set FP:$dst, (fsub (fmul FP:$src1, FP:$src2), FP:$src3))]>;
+def FNMA : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
+ "fnma $dst = $src1, $src2, $src3;;",
+ [(set FP:$dst, (fneg (fadd (fmul FP:$src1, FP:$src2), FP:$src3)))]>;
def FABS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src),
"fabs $dst = $src;;">;
-def FNEG : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src),
- "fneg $dst = $src;;">;
+def FNEG : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src),
+ "fneg $dst = $src;;",
+ [(set FP:$dst, (fneg FP:$src))]>;
def FNEGABS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src),
"fnegabs $dst = $src;;">;
@@ -480,16 +553,6 @@ def GETFSIG : AForm<0x03, 0x0b, (ops GR:$dst, FP:$src),
def SETFSIG : AForm<0x03, 0x0b, (ops FP:$dst, GR:$src),
"setf.sig $dst = $src;;">;
-def LDF4 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr),
- "ldfs $dst = [$srcPtr];;">;
-def LDF8 : AForm<0x03, 0x0b, (ops FP:$dst, GR:$srcPtr),
- "ldfd $dst = [$srcPtr];;">;
-
-def STF4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value),
- "stfs [$dstPtr] = $value;;">;
-def STF8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, FP:$value),
- "stfd [$dstPtr] = $value;;">;
-
let isTerminator = 1, isBranch = 1 in {
def BRL_NOTCALL : RawForm<0x03, 0xb0, (ops i64imm:$dst),
"(p0) brl.cond.sptk $dst;;">;