From: Duraid Madina Date: Mon, 16 Jan 2006 14:33:04 +0000 (+0000) Subject: fixing divides: FP should now be 100%, and integers are fine too X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=76bb6ae211b1d4d656c182a0b9e8a6e8877ee8d0;p=oota-llvm.git fixing divides: FP should now be 100%, and integers are fine too unless you try to div/mod 0 by anything, in which case you will get some cute number, and not 0, which is bad. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25358 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/IA64/IA64ISelDAGToDAG.cpp b/lib/Target/IA64/IA64ISelDAGToDAG.cpp index 929e8f5af6d..fd585676cc9 100644 --- a/lib/Target/IA64/IA64ISelDAGToDAG.cpp +++ b/lib/Target/IA64/IA64ISelDAGToDAG.cpp @@ -183,6 +183,10 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) { SDOperand TmpF1, TmpF2, TmpF3, TmpF4, TmpF5, TmpF6, TmpF7, TmpF8; SDOperand TmpF9, TmpF10,TmpF11,TmpF12,TmpF13,TmpF14,TmpF15; SDOperand Result; + + // we'll need copies of F0 and F1 + SDOperand F0 = CurDAG->getRegister(IA64::F0, MVT::f64); + SDOperand F1 = CurDAG->getRegister(IA64::F1, MVT::f64); // OK, emit some code: @@ -200,12 +204,10 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) { TmpF4 = CurDAG->getTargetNode(IA64::FCVTXF, MVT::f64, TmpF2); Chain = TmpF4.getValue(1); } else { // is unsigned - if(isModulus) { /* unsigned integer divides do not need any fcvt.x*f* insns */ - TmpF3 = CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF1); - Chain = TmpF3.getValue(1); - TmpF4 = CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF2); - Chain = TmpF4.getValue(1); - } + TmpF3 = CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF1); + Chain = TmpF3.getValue(1); + TmpF4 = CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF2); + Chain = TmpF4.getValue(1); } } else { // this is an FP divide/remainder, so we 'leak' some temp @@ -226,10 +228,6 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) { TmpPR = TmpF5.getValue(1); Chain = TmpF5.getValue(2); - // we'll need copies of F0 and F1 - SDOperand F0 = CurDAG->getRegister(IA64::F0, MVT::f64); - SDOperand F1 = CurDAG->getRegister(IA64::F1, MVT::f64); - SDOperand minusB; if(isModulus) { // for remainders, it'll be handy to have // copies of -input_b @@ -276,7 +274,7 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) { // we two-address hack it. See the comment "for this to work..." on // page 48 of Intel application note #245415 Result = CurDAG->getTargetNode(IA64::TCFMADS0, MVT::f64, // d.p. s0 rndg! - TmpY3, TmpR0, TmpQ0, TmpPR); + TmpF5, TmpY3, TmpR0, TmpQ0, TmpPR); Chain = Result.getValue(1); return Result; // XXX: early exit! } else { // this is *not* an FP divide, so there's a bit left to do: @@ -290,13 +288,22 @@ SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) { TmpF4, TmpQ2, TmpF3, TmpPR); Chain = TmpR2.getValue(1); -// we want TmpQ3 to have the same target register as the frcpa, so -// we two-address hack it. See the comment "for this to work..." on -// page 48 of Intel application note #245415 - TmpQ3 = CurDAG->getTargetNode(IA64::TCFMAS1, MVT::f64, - TmpR2, TmpR2, TmpY2, TmpQ2, TmpPR); +// we want TmpQ3 to have the same target register as the frcpa? maybe we +// should two-address hack it. See the comment "for this to work..." on page +// 48 of Intel application note #245415 + TmpQ3 = CurDAG->getTargetNode(IA64::CFMAS1, MVT::f64, + TmpR2, TmpY2, TmpQ2, TmpPR); Chain = TmpQ3.getValue(1); - + + // FIXME: this is unfortunate :( + // the story is that the dest reg of the fnma above and the fma below it + // (and therefore the src of the fcvt.fx[u] below as well) cannot + // be the same register, or this code breaks if the first argument is + // zero. (e.g. without this hack, 0%8 yields -64, not 0.) +/* XXX: these two lines do nothing */ + SDOperand bogus = CurDAG->getTargetNode(IA64::IUSE, MVT::Other, TmpR2); + Chain = bogus.getValue(0); + if(isSigned) TmpQ = CurDAG->getTargetNode(IA64::FCVTFXTRUNCS1, MVT::f64, TmpQ3); else