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


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24094 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duraid Madina 2005-10-29 16:08:30 +00:00
parent 6e520d0ccf
commit 25d0a88eb8
2 changed files with 128 additions and 58 deletions

View File

@ -313,6 +313,13 @@ SDOperand IA64DAGToDAGISel::Select(SDOperand Op) {
CurDAG->getTargetFrameIndex(FI, MVT::i64)); 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: { case ISD::GlobalAddress: {
GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal(); GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64); SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64);

View File

@ -45,10 +45,33 @@ let PrintMethod = "printCallOperand" in
def is32ones : PatLeaf<(i64 imm), [{ def is32ones : PatLeaf<(i64 imm), [{
// is32ones predicate - True if the immediate is 0x00000000FFFFFFFF // is32ones predicate - True if the immediate is 0x00000000FFFFFFFF
// Used to create ZXT4s appropriately // Used to create ZXT4s appropriately
int64_t v = (int64_t)N->getValue(); uint64_t v = (uint64_t)N->getValue();
return (v == 0x00000000FFFFFFFFLL); 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), [{ def isSHLADDimm: PatLeaf<(i64 imm), [{
// isSHLADDimm predicate - True if the immediate is exactly 1, 2, 3 or 4 // isSHLADDimm predicate - True if the immediate is exactly 1, 2, 3 or 4
// - 0 is *not* okay. // - 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;;", def ZXT4 : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src), "zxt4 $dst = $src;;",
[(set GR:$dst, (and GR:$src, is32ones))]>; [(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), def ADD : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src1, GR:$src2),
"add $dst = $src1, $src2;;", "add $dst = $src1, $src2;;",
[(set GR:$dst, (add GR:$src1, GR:$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), def XMALD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
"xma.l $dst = $src1, $src2, $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 // pseudocode for integer multiplication
def : Pat<(mul GR:$src1, GR:$src2), def : Pat<(mul GR:$src1, GR:$src2),
(GETFSIGD (XMALD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>; (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) // TODO: addp4 (addp4 dst = src, r0 is a 32-bit add)
// has imm form, too // 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;;">; "($qp) cmp.eq $dst, p0 = r0, r0;;">;
/* our pseudocode for OR on predicates is: /* our pseudocode for OR on predicates is:
*
pC = pA OR pB pC = pA OR pB
------------- -------------
(pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA (pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA
;; ;;
(pB) cmp.eq pC,p0 = r0,r0 // if (pB) pC = 1 (pB) cmp.eq pC,p0 = r0,r0 // if (pB) pC = 1 */
*/ def bOR : Pat<(or PR:$src1, PR:$src2),
/* (TPCMPEQR0R0 (PCMPEQUNCR0R0 PR:$src1), PR:$src2)>;
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;;">;
}
*/
// FIXME: these are bogus // FIXME: these are bogus
def bOR : Pat<(or PR:$src1, PR:$src2),
(PCMPEQUNCR0R0 PR:$src1)>;
def bXOR : Pat<(xor PR:$src1, PR:$src2), def bXOR : Pat<(xor PR:$src1, PR:$src2),
(PCMPEQUNCR0R0 PR:$src1)>; (PCMPEQUNCR0R0 PR:$src1)>;
@ -389,47 +441,68 @@ def TPCMPIMM8NE : AForm<0x03, 0x0b,
def SUBIMM8 : AForm<0x03, 0x0b, (ops GR:$dst, s8imm:$imm, GR:$src2), def SUBIMM8 : AForm<0x03, 0x0b, (ops GR:$dst, s8imm:$imm, GR:$src2),
"sub $dst = $imm, $src2;;">; "sub $dst = $imm, $src2;;">;
def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), let isStore = 1 in {
def ST1 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
"st1 [$dstPtr] = $value;;">; "st1 [$dstPtr] = $value;;">;
def ST2 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), def ST2 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
"st2 [$dstPtr] = $value;;">; "st2 [$dstPtr] = $value;;">;
def ST4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), def ST4 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
"st4 [$dstPtr] = $value;;">; "st4 [$dstPtr] = $value;;">;
def ST8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value), def ST8 : AForm<0x03, 0x0b, (ops GR:$dstPtr, GR:$value),
"st8 [$dstPtr] = $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;;">;
}
def LD1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), let isLoad = 1 in {
def LD1 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
"ld1 $dst = [$srcPtr];;">; "ld1 $dst = [$srcPtr];;">;
def LD2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), def LD2 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
"ld2 $dst = [$srcPtr];;">; "ld2 $dst = [$srcPtr];;">;
def LD4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), def LD4 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
"ld4 $dst = [$srcPtr];;">; "ld4 $dst = [$srcPtr];;">;
def LD8 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr), def LD8 : AForm<0x03, 0x0b, (ops GR:$dst, GR:$srcPtr),
"ld8 $dst = [$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<0x03, 0x0b, (ops GR:$dst, GR:$src), "popcnt $dst = $src;;">; def POPCNT : AForm_DAG<0x03, 0x0b, (ops GR:$dst, GR:$src),
"popcnt $dst = $src;;",
[(set GR:$dst, (ctpop GR:$src))]>;
// some FP stuff: // some FP stuff: // TODO: single-precision stuff?
def FADD : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), def FADD : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
"fadd $dst = $src1, $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), def FADDS: AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
"fadd.s $dst = $src1, $src2;;">; "fadd.s $dst = $src1, $src2;;">;
def FSUB : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), def FSUB : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
"fsub $dst = $src1, $src2;;">; "fsub $dst = $src1, $src2;;",
def FMPY : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2), [(set FP:$dst, (fsub FP:$src1, FP:$src2))]>;
"fmpy $dst = $src1, $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), def FMOV : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src),
"mov $dst = $src;;">; // XXX: there _is_ no fmov "mov $dst = $src;;">; // XXX: there _is_ no fmov
def FMA : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), def FMA : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
"fma $dst = $src1, $src2, $src3;;">; "fma $dst = $src1, $src2, $src3;;",
def FMS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), [(set FP:$dst, (fadd (fmul FP:$src1, FP:$src2), FP:$src3))]>;
"fms $dst = $src1, $src2, $src3;;">; def FMS : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3),
def FNMA : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2, FP:$src3), "fms $dst = $src1, $src2, $src3;;",
"fnma $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), def FABS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src),
"fabs $dst = $src;;">; "fabs $dst = $src;;">;
def FNEG : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), def FNEG : AForm_DAG<0x03, 0x0b, (ops FP:$dst, FP:$src),
"fneg $dst = $src;;">; "fneg $dst = $src;;",
[(set FP:$dst, (fneg FP:$src))]>;
def FNEGABS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src), def FNEGABS : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src),
"fnegabs $dst = $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), def SETFSIG : AForm<0x03, 0x0b, (ops FP:$dst, GR:$src),
"setf.sig $dst = $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 { let isTerminator = 1, isBranch = 1 in {
def BRL_NOTCALL : RawForm<0x03, 0xb0, (ops i64imm:$dst), def BRL_NOTCALL : RawForm<0x03, 0xb0, (ops i64imm:$dst),
"(p0) brl.cond.sptk $dst;;">; "(p0) brl.cond.sptk $dst;;">;