mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-02 16:56:39 +00:00
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:
parent
6e520d0ccf
commit
25d0a88eb8
@ -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);
|
||||
|
@ -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
|
||||
(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;;">;
|
||||
}
|
||||
*/
|
||||
def bOR : Pat<(or PR:$src1, PR:$src2),
|
||||
(TPCMPEQR0R0 (PCMPEQUNCR0R0 PR:$src1), PR:$src2)>;
|
||||
|
||||
// FIXME: these are bogus
|
||||
def bOR : Pat<(or PR:$src1, PR:$src2),
|
||||
(PCMPEQUNCR0R0 PR:$src1)>;
|
||||
|
||||
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;;">;
|
||||
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;;">;
|
||||
}
|
||||
|
||||
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];;">;
|
||||
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<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:
|
||||
def FADD : AForm<0x03, 0x0b, (ops FP:$dst, FP:$src1, FP:$src2),
|
||||
"fadd $dst = $src1, $src2;;">;
|
||||
// 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;;">;
|
||||
|
Loading…
Reference in New Issue
Block a user